var sniffer = new Sniffer();\r
SniffLogFile(sniffer, "damecon_001");\r
AssertEqualBattleResult(sniffer, new[] {30, 1, 3}, "戦闘前");\r
- PAssert.That(() => sniffer.GetShipStatuses(0)[1].Slot.SequenceEqual(new[] {2, 4593, -1, -1, -1}), "ダメコンを二つ装備");\r
+ PAssert.That(() => sniffer.GetShipStatuses(0)[1].Slot.Select(item => item.Id).\r
+ SequenceEqual(new[] {2, 4593, -1, -1, -1}), "ダメコンを二つ装備");\r
PAssert.That(() => sniffer.Battle.ResultRank == BattleResultRank.S, "判定はS勝利");\r
SniffLogFile(sniffer, "damecon_002");\r
AssertEqualBattleResult(sniffer, new[] {30, 1, 3}, "戦闘後");\r
- PAssert.That(() => sniffer.GetShipStatuses(0)[1].Slot.SequenceEqual(new[] {-1, 4593, -1, -1, -1}), "ダメコンを一つ消費");\r
+ PAssert.That(() => sniffer.GetShipStatuses(0)[1].Slot.Select(item => item.Id).\r
+ SequenceEqual(new[] {-1, 4593, -1, -1, -1}), "ダメコンを一つ消費");\r
}\r
\r
/// <summary>\r
{\r
var sniffer = new Sniffer();\r
SniffLogFile(sniffer, "damecon_003");\r
- PAssert.That(() => sniffer.GetShipStatuses(0)[5].SlotEx == 10306, "戦闘前");\r
+ PAssert.That(() => sniffer.GetShipStatuses(0)[5].SlotEx.Id == 10306, "戦闘前");\r
SniffLogFile(sniffer, "damecon_004");\r
- PAssert.That(() => sniffer.GetShipStatuses(0)[5].SlotEx == -1, "戦闘後");\r
+ PAssert.That(() => sniffer.GetShipStatuses(0)[5].SlotEx.Id == -1, "戦闘後");\r
}\r
\r
/// <summary>\r
public class AkashiTimer\r
{\r
private readonly ShipInfo _shipInfo;\r
- private readonly ItemInfo _itemInfo;\r
private readonly DockInfo _dockInfo;\r
private readonly RepairStatus[] _repairStatuses = new RepairStatus[ShipInfo.FleetCount];\r
private DateTime _start;\r
public string Completed { get; set; }\r
}\r
\r
- public AkashiTimer(ShipInfo ship, ItemInfo item, DockInfo dock)\r
+ public AkashiTimer(ShipInfo ship, DockInfo dock)\r
{\r
_shipInfo = ship;\r
- _itemInfo = item;\r
_dockInfo = dock;\r
for (var i = 0; i < _repairStatuses.Length; i++)\r
_repairStatuses[i] = new RepairStatus();\r
{\r
var deck = _shipInfo.GetDeck(fleet);\r
var repair = _repairStatuses[fleet];\r
- var fs = deck[0];\r
- if (!_shipInfo[fs].Name.StartsWith("明石") || _dockInfo.InNDock(fs) || _shipInfo.InMission(fleet))\r
+ var fs = _shipInfo.GetStatus(deck[0]);\r
+ if (!fs.Name.StartsWith("明石") || _dockInfo.InNDock(fs.Id) || _shipInfo.InMission(fleet))\r
{\r
repair.Invalidate();\r
return false;\r
repair.Invalidate();\r
}\r
repair.Deck = deck.ToArray();\r
- var cap = _shipInfo[fs].Slot.Count(id => _itemInfo.GetName(id) == "艦艇修理施設") + 2;\r
+ var cap = fs.Slot.Count(item => item.Spec.Name == "艦艇修理施設") + 2;\r
var target = deck.Take(cap).Select(id =>\r
{\r
/*\r
* - 中破以上の艦娘\r
* 出撃中の損傷で小破以下から中破以上になったのを回復と誤認しないためにHPを0に\r
*/\r
- var s = _shipInfo[id];\r
+ var s = _shipInfo.GetStatus(id);\r
var full = new ShipStatus {NowHp = s.MaxHp, MaxHp = s.MaxHp};\r
var zero = new ShipStatus();\r
return _dockInfo.InNDock(id)\r
_friend = Record.Setup(\r
nowhps, (int[])json.api_maxhps,\r
fstats.Select(s => s.Slot).ToArray(),\r
- fstats.Select(s => s.SlotEx).ToArray(),\r
- _itemInfo);\r
+ fstats.Select(s => s.SlotEx).ToArray());\r
_enemyHp = nowhps.Skip(7).TakeWhile(hp => hp != -1).ToArray();\r
_enemyStartHp = (int[])_enemyHp.Clone();\r
EnemyResultStatus =\r
(int[])json.api_nowhps_combined,\r
(int[])json.api_maxhps_combined,\r
gstats.Select(s => s.Slot).ToArray(),\r
- gstats.Select(s => s.SlotEx).ToArray(),\r
- _itemInfo);\r
+ gstats.Select(s => s.SlotEx).ToArray());\r
}\r
else\r
{\r
\r
private class Record\r
{\r
- private ItemInfo _itemInfo;\r
private int _maxHp;\r
- private int[] _slot;\r
- private int _slotEx;\r
+ private ItemStatus[] _slot;\r
+ private ItemStatus _slotEx;\r
public int NowHp;\r
public int StartHp;\r
public int Damage;\r
\r
- public static Record[] Setup(int[] rawHp, int[] rawMax, int[][] slots, int[] slotEx, ItemInfo itemInfo)\r
+ public static Record[] Setup(int[] rawHp, int[] rawMax, ItemStatus[][] slots, ItemStatus[] slotEx)\r
{\r
var hp = rawHp.Skip(1).Take(6).TakeWhile(h => h != -1).ToArray();\r
var max = rawMax.Skip(1).Take(6).TakeWhile(h => h != -1).ToArray();\r
_maxHp = max[i],\r
_slot = slots[i].ToArray(),\r
_slotEx = slotEx[i],\r
- _itemInfo = itemInfo\r
};\r
}\r
return r;\r
}\r
Damage += NowHp;\r
NowHp = 0;\r
- var idex = _slotEx == 0 ? -1 : _itemInfo.GetItemId(_slotEx);\r
- if (idex == 42) // ダメコン\r
+ if (_slotEx.Spec.Id == 42) // ダメコン\r
{\r
- _slotEx = -1;\r
+ _slotEx = new ItemStatus();\r
NowHp = (int)(_maxHp * 0.2);\r
return;\r
}\r
- if (idex == 43) // 女神\r
+ if (_slotEx.Spec.Id == 43) // 女神\r
{\r
- _slotEx = -1;\r
+ _slotEx = new ItemStatus();\r
NowHp = _maxHp;\r
return;\r
}\r
for (var j = 0; j < _slot.Length; j++)\r
{\r
- var id = _itemInfo.GetItemId(_slot[j]);\r
+ var id = _slot[j].Spec.Id;\r
if (id == 42) // ダメコン\r
{\r
- _slot[j] = -1;\r
+ _slot[j] = new ItemStatus();\r
NowHp = (int)(_maxHp * 0.2);\r
break;\r
}\r
if (id == 43) // 女神\r
{\r
- _slot[j] = -1;\r
+ _slot[j] = new ItemStatus();\r
NowHp = _maxHp;\r
break;\r
}\r
var values = HttpUtility.ParseQueryString(request);\r
var id = int.Parse(values["api_ship_id"]);\r
int fuel, steal;\r
- _shipInfo[id].CalcMaterialsToRepair(out fuel, out steal);\r
+ _shipInfo.GetStatus(id).CalcMaterialsToRepair(out fuel, out steal);\r
_materialInfo.SubMaterial(Material.Fuel, fuel);\r
_materialInfo.SubMaterial(Material.Steal, steal);\r
if (int.Parse(values["api_highspeed"]) == 0)\r
\r
public NameAndTimer[] NDock\r
=> _ndoc.Zip(_ndocTimers,\r
- (id, timer) => new NameAndTimer {Name = id == 0 ? "" : _shipInfo[id].Name, Timer = timer}).ToArray();\r
+ (id, timer) => new NameAndTimer {Name = id == 0 ? "" : _shipInfo.GetStatus(id).Name, Timer = timer}).ToArray();\r
\r
public bool InNDock(int id) => _ndoc.Any(n => n == id); // 空のドックのidは0\r
\r
var equips = new List<EquipColumn>();\r
for (var i = 0; i < s.Slot.Length; i++)\r
{\r
- var slot = s.Slot[i];\r
+ var item = s.Slot[i];\r
var onslot = s.OnSlot[i];\r
var max = s.Spec.MaxEq[i];\r
- if (slot == -1)\r
+ if (item.Id == -1)\r
continue;\r
- var item = sniffer.Item.GetStatus(slot);\r
if (item.Spec.Name == "ドラム缶(輸送用)")\r
drum++;\r
var airspec = "";\r
Color = item.Spec.Color\r
});\r
}\r
- if (s.SlotEx > 0)\r
+ if (s.SlotEx.Id > 0)\r
{\r
- var item = sniffer.Item.GetStatus(s.SlotEx);\r
+ var item = s.SlotEx;\r
equips.Add(new EquipColumn {Equip = item.Spec.Name, Color = item.Spec.Color});\r
}\r
if (drum != 0)\r
\r
public class ItemStatus\r
{\r
- public ItemSpec Spec { get; set; }\r
+ public int Id { get; set; }\r
+ public ItemSpec Spec { get; set; } = new ItemSpec();\r
public int Level { get; set; }\r
public int Alv { get; set; }\r
public ShipStatus Ship { get; set; }\r
\r
public ItemStatus()\r
{\r
- Spec = new ItemSpec();\r
- Ship = new ShipStatus();\r
+ Id = -1;\r
+ }\r
+\r
+ public ItemStatus(int id)\r
+ {\r
+ Id = id == 0 ? -1 : id;\r
}\r
\r
public int AlvBonus\r
}\r
foreach (var entry in json)\r
{\r
- _itemInfo[(int)entry.api_id] = new ItemStatus\r
+ var id = (int)entry.api_id;\r
+ _itemInfo[id] = new ItemStatus(id)\r
{\r
Spec = _itemSpecs[(int)entry.api_slotitem_id],\r
Level = entry.api_level() ? (int)entry.api_level : 0,\r
DeleteItems(((int[])json.api_use_slot_id));\r
}\r
\r
- public void DeleteItems(int[] ids)\r
+ public void DeleteItems(ItemStatus[] items)\r
+ {\r
+ DeleteItems(items.Select(item => item.Id));\r
+ }\r
+\r
+ private void DeleteItems(IEnumerable<int> ids)\r
{\r
foreach (var id in ids.Where(id => id != -1))\r
{\r
foreach (var s in shipList)\r
{\r
foreach (var id in s.Slot)\r
- _itemInfo[id].Ship = s;\r
- if (s.SlotEx != 0)\r
- _itemInfo[s.SlotEx].Ship = s;\r
+ _itemInfo[id.Id].Ship = s;\r
+ _itemInfo[s.SlotEx.Id].Ship = s;\r
}\r
return (from e in _itemInfo where e.Key != -1 select e.Value).ToArray();\r
}\r
{\r
if (id == -1)\r
return ",";\r
- var s = _shipInfo[id];\r
+ var s = _shipInfo.GetStatus(id);\r
return $"{s.Name}(Lv{s.Level}),{s.NowHp}/{s.MaxHp}";\r
}));\r
var estatus = _battleInfo.EnemyResultStatus;\r
public int Fuel { get; set; }\r
public int Bull { get; set; }\r
public int[] OnSlot { get; set; }\r
- public int[] Slot { get; set; }\r
- public int SlotEx { get; set; }\r
+ public ItemStatus[] Slot { get; set; }\r
+ public ItemStatus SlotEx { get; set; }\r
public int LoS { get; set; }\r
public int Firepower { get; set; }\r
public int AntiSubmarine { get; set; }\r
Id = -1;\r
Spec = new ShipSpec();\r
OnSlot = new int[0];\r
- Slot = new int[0];\r
+ Slot = new ItemStatus[0];\r
+ SlotEx = new ItemStatus();\r
}\r
\r
public enum Damage\r
return 0;\r
if (!Spec.IsAircraftCarrier)\r
return Firepower + 5;\r
- var specs = (from id in Slot\r
- let spec = _itemInfo.GetStatus(id).Spec\r
+ var specs = (from item in Slot\r
+ let spec = _itemInfo.GetStatus(item.Id).Spec\r
where spec.IsAircraft\r
select new {torpedo = spec.Torpedo, bomber = spec.Bomber}).ToArray();\r
var torpedo = specs.Sum(s => s.torpedo);\r
var aircraft = 0;\r
var all = 0;\r
var vanilla = AntiSubmarine;\r
- foreach (var spec in Slot.Select(id => _itemInfo.GetStatus(id).Spec))\r
+ foreach (var spec in Slot.Select(item => _itemInfo.GetStatus(item.Id).Spec))\r
{\r
vanilla -= spec.AntiSubmarine;\r
if (spec.IsReconSeaplane) // 水偵は除外\r
Fuel = (int)entry.api_fuel,\r
Bull = (int)entry.api_bull,\r
OnSlot = (int[])entry.api_onslot,\r
- Slot = (int[])entry.api_slot,\r
- SlotEx = entry.api_slot_ex() ? (int)entry.api_slot_ex : 0,\r
+ Slot = ((int[])entry.api_slot).Select(id => new ItemStatus(id)).ToArray(),\r
+ SlotEx = entry.api_slot_ex() ? new ItemStatus((int)entry.api_slot_ex) : new ItemStatus(),\r
LoS = (int)entry.api_sakuteki[0],\r
Firepower = (int)entry.api_karyoku[0],\r
AntiSubmarine = (int)entry.api_taisen[0]\r
\r
public ShipStatus[] GetShipStatuses(int fleet)\r
{\r
- return _decks[fleet].Where(id => id != -1).Select(id =>\r
- {\r
- var s = _shipInfo[id];\r
- s.Escaped = _escapedShips.Contains(id);\r
- return s;\r
- }).ToArray();\r
+ return _decks[fleet].Where(id => id != -1).Select(GetStatus).ToArray();\r
}\r
\r
public int[] GetDeck(int fleet) => _decks[fleet];\r
\r
- public ShipStatus this[int idx] => _shipInfo[idx];\r
+ public ShipStatus GetStatus(int id)\r
+ {\r
+ var s = _shipInfo[id];\r
+ s.Slot = (from item in s.Slot select _itemInfo.GetStatus(item.Id)).ToArray();\r
+ s.SlotEx = _itemInfo.GetStatus(s.SlotEx.Id);\r
+ s.Escaped = _escapedShips.Contains(id);\r
+ return s;\r
+ }\r
\r
public ShipSpec GetSpec(int id) => _shipMaster[id];\r
\r
=> GetShipStatuses(fleet).Where(s => !s.Escaped).SelectMany(ship =>\r
ship.Slot.Zip(ship.OnSlot, (slot, onslot) =>\r
{\r
- var item = _itemInfo.GetStatus(slot);\r
+ var item = _itemInfo.GetStatus(slot.Id);\r
if (!item.Spec.CanAirCombat)\r
return 0;\r
var bonus = onslot != 0 && withBonus ? item.AlvBonus : 0;\r
foreach (var s in _decks[fleet].Select(id => _shipInfo[id]))\r
{\r
var items = 0;\r
- foreach (var spec in s.Slot.Select(id => _itemInfo.GetStatus(id).Spec))\r
+ foreach (var spec in s.Slot.Select(item => _itemInfo.GetStatus(item.Id).Spec))\r
{\r
items += spec.LoS;\r
result += spec.LoS * spec.LoSScaleFactor();\r
_shipInfo = new ShipInfo(_itemInfo);\r
_conditionTimer = new ConditionTimer(_shipInfo);\r
_dockInfo = new DockInfo(_shipInfo, _materialInfo);\r
- _akashiTimer = new AkashiTimer(_shipInfo, _itemInfo, _dockInfo);\r
+ _akashiTimer = new AkashiTimer(_shipInfo, _dockInfo);\r
_battleInfo = new BattleInfo(_shipInfo, _itemInfo);\r
_logger = new Logger(_shipInfo, _itemInfo, _battleInfo);\r
_haveState = new List<IHaveState> {_achievement, _materialInfo, _conditionTimer, _exMapInfo};\r