var id = _shipInventry.MaxId + 1;\r
var ships = nowhps.Zip(maxhps,\r
(now, max) => new ShipStatus {Id = id++, NowHp = now, MaxHp = max}).ToArray();\r
- _shipInfo.Fleets[deck].Deck = (from ship in ships select ship.Id).ToArray();\r
_shipInventry.Add(ships);\r
+ _shipInfo.Fleets[deck].Deck = (from ship in ships select ship.Id).ToArray();\r
foreach (var entry in ships.Zip(slots, (ship, slot) => new {ship, slot}))\r
{\r
entry.ship.Slot = _itemInfo.InjectItems(entry.slot.Take(5));\r
{\r
var sniffer = new Sniffer();\r
SniffLogFile(sniffer, "nightbattlepower_001");\r
- var ships = sniffer.Fleets[0].Ships;\r
+ var ships = sniffer.Fleets[0].ActualShips;\r
PAssert.That(() =>\r
ships.Select(ship => (int)(ship.NightBattlePower * 100))\r
.SequenceEqual(new[] {11202, 14985, 20092, 17354}));\r
int deckId = BattleInfo.DeckId(_battle);\r
if (_battle.api_f_nowhps_combined())\r
{\r
- var main = _shipInfo.Fleets[0].Deck;\r
- var guard = _shipInfo.Fleets[1].Deck;\r
- return main.Zip(guard, (m, g) =>\r
+ var mainShips = _shipInfo.Fleets[0].Ships;\r
+ var guardShips = _shipInfo.Fleets[1].Ships;\r
+ return mainShips.Zip(guardShips, (main, guard) =>\r
{\r
- if (m == -1 && g == -1)\r
+ if (main.Empty && guard.Empty)\r
return ",";\r
var name = "";\r
var hp = "";\r
- if (m != -1)\r
+ if (!main.Empty)\r
{\r
- var sm = _shipInfo.GetStatus(m);\r
- name = $"{sm.Name}(Lv{sm.Level})";\r
- hp = $"{sm.NowHp}/{sm.MaxHp}";\r
+ name = $"{main.Name}(Lv{main.Level})";\r
+ hp = $"{main.NowHp}/{main.MaxHp}";\r
}\r
name += "・";\r
hp += "・";\r
- if (g != -1)\r
+ if (!guard.Empty)\r
{\r
- var sg = _shipInfo.GetStatus(g);\r
- name += $"{sg.Name}(Lv{sg.Level})";\r
- hp += $"{sg.NowHp}/{sg.MaxHp}";\r
+ name += $"{guard.Name}(Lv{guard.Level})";\r
+ hp += $"{guard.NowHp}/{guard.MaxHp}";\r
}\r
return name + "," + hp;\r
}).ToList();\r
}\r
- var deck = _shipInfo.Fleets[deckId].Deck;\r
- if (deck.Length > 6)\r
+ var ships = _shipInfo.Fleets[deckId].Ships;\r
+ if (ships.Count > 6)\r
{\r
var result = new List<string>();\r
- for (var i = 0; i < 12 - deck.Length; i++)\r
+ for (var i = 0; i < 12 - ships.Count; i++)\r
{\r
- var s = _shipInfo.GetStatus(deck[i]);\r
- result.Add($"{s.Name}(Lv{s.Level}),{s.NowHp}/{s.MaxHp}");\r
+ var ship = ships[i];\r
+ result.Add($"{ship.Name}(Lv{ship.Level}),{ship.NowHp}/{ship.MaxHp}");\r
}\r
- for (var i = 0; i < deck.Length - 6; i++)\r
+ for (var i = 0; i < ships.Count - 6; i++)\r
{\r
- var s1 = _shipInfo.GetStatus(deck[12 - deck.Length + i]);\r
- var s2 = _shipInfo.GetStatus(deck[6 + i]);\r
+ var s1 = ships[12 - ships.Count + i];\r
+ var s2 = ships[6 + i];\r
result.Add(\r
$"{s1.Name}(Lv{s1.Level})・{s2.Name}(Lv{s2.Level})," +\r
$"{s1.NowHp}/{s1.MaxHp}・{s2.NowHp}/{s2.MaxHp}");\r
}\r
return result;\r
}\r
- return deck.Select(id =>\r
+ return ships.Select(ship =>\r
{\r
- if (id == -1)\r
+ if (ship.Empty)\r
return ",";\r
- var s = _shipInfo.GetStatus(id);\r
- return $"{s.Name}(Lv{s.Level}),{s.NowHp}/{s.MaxHp}";\r
+ return $"{ship.Name}(Lv{ship.Level}),{ship.NowHp}/{ship.MaxHp}";\r
}).ToList();\r
}\r
\r
{\r
return result.Select(s => s.Empty ? "," : $"{s.Name},{s.NowHp}/{s.MaxHp}").ToList();\r
}\r
- var main = result;\r
- var guard = _battleInfo.Result.Enemy.Guard.Concat(Enumerable.Repeat(new ShipStatus(), 6)).Take(6);\r
- return main.Zip(guard, (m, g) =>\r
+ var mainShips = result;\r
+ var guardShips = _battleInfo.Result.Enemy.Guard.Concat(Enumerable.Repeat(new ShipStatus(), 6)).Take(6);\r
+ return mainShips.Zip(guardShips, (main, guard) =>\r
{\r
- if (m.Empty && g.Empty)\r
+ if (main.Empty && guard.Empty)\r
return ",";\r
var name = "";\r
var hp = "";\r
- if (!m.Empty)\r
+ if (!main.Empty)\r
{\r
- name = $"{m.Name}";\r
- hp = $"{m.NowHp}/{m.MaxHp}";\r
+ name = $"{main.Name}";\r
+ hp = $"{main.NowHp}/{main.MaxHp}";\r
}\r
name += "・";\r
hp += "・";\r
- if (!g.Empty)\r
+ if (!guard.Empty)\r
{\r
- name += $"{g.Name}";\r
- hp += $"{g.NowHp}/{g.MaxHp}";\r
+ name += $"{guard.Name}";\r
+ hp += $"{guard.NowHp}/{guard.MaxHp}";\r
}\r
return name + "," + hp;\r
}).ToList();\r
var ship1 = Secretary();\r
var ship2 = "";\r
var ships = _shipInfo.Fleets[0].Ships;\r
- if (ships.Length >= 2)\r
+ if (!ships[1].Empty)\r
ship2 = ships[1].Name + "(" + ships[1].Level + ")";\r
_writer("改修報告書",\r
FormatDateTime(now) + "," +\r
if (!_listForm.Visible)\r
return;\r
var idx = (int)((Control)sender).Tag;\r
- var ships = _sniffer.Fleets[_currentFleet].Ships;\r
- if (ships.Length <= idx)\r
+ var ships = _sniffer.Fleets[_currentFleet].ActualShips;\r
+ if (ships.Count <= idx)\r
return;\r
_listForm.ShowShip(ships[idx].Id);\r
}\r
private void UpdatePanelShipInfo()\r
{\r
var fleets = _sniffer.Fleets;\r
- var ships = fleets[_currentFleet].Ships;\r
- panel7Ships.Visible = ships.Length == 7;\r
+ var ships = fleets[_currentFleet].ActualShips;\r
+ panel7Ships.Visible = ships.Count == 7;\r
_mainLabels.SetShipLabels(ships);\r
if (!_sniffer.IsCombinedFleet)\r
_combinedFleet = false;\r
labelFleet1.Text = _combinedFleet ? "連合" : "第一";\r
panelCombinedFleet.Visible = _combinedFleet;\r
if (_combinedFleet)\r
- _mainLabels.SetCombinedShipLabels(fleets[0].Ships, fleets[1].Ships);\r
+ _mainLabels.SetCombinedShipLabels(fleets[0].ActualShips, fleets[1].ActualShips);\r
for (var i = 0; i < _labelCheckFleets.Length; i++)\r
_labelCheckFleets[i].Visible = _currentFleet == i;\r
UpdateAkashiTimer();\r
{\r
if (_config.UsePresetAkashi)\r
UpdatePresetAkashiTimer();\r
- _mainLabels.SetAkashiTimer(_sniffer.Fleets[_currentFleet].Ships,\r
+ _mainLabels.SetAkashiTimer(_sniffer.Fleets[_currentFleet].ActualShips,\r
_sniffer.AkashiTimer.GetTimers(_currentFleet));\r
}\r
\r
\r
private class RepairStatus\r
{\r
- private ShipStatus[] _target = new ShipStatus[0];\r
- private int[] _deck = new int[0];\r
+ private IReadOnlyList<ShipStatus> _target = new ShipStatus[0];\r
+ private IReadOnlyList<int> _deck = new int[0];\r
private TimeSpan FirstRepairTime => TimeSpan.FromMinutes(20);\r
\r
private bool PassedFirstRepairTime(DateTime start, DateTime prev, DateTime now) =>\r
TimeSpan.FromMinutes(Math.Ceiling(ship.RepairTime.TotalMinutes / (ship.MaxHp - ship.NowHp) * damage));\r
\r
\r
- public int[] Deck\r
+ public IReadOnlyList<int> Deck\r
{\r
set => _deck = value;\r
}\r
\r
private void CheckFleet(Fleet fleet)\r
{\r
- var deck = fleet.Deck.ToArray();\r
+ var deck = fleet.Deck;\r
+ var ships = fleet.Ships;\r
var repair = _repairStatuses[fleet.Number];\r
- var fs = _shipInfo.GetStatus(deck[0]);\r
repair.State = State.Continue;\r
- if (!fs.Spec.IsRepairShip)\r
+ if (!ships[0].Spec.IsRepairShip)\r
{\r
repair.UpdateTarget(new ShipStatus[0]);\r
repair.Deck = deck;\r
repair.State = State.Reset;\r
repair.Deck = deck;\r
}\r
- var target = RepairTarget(deck);\r
+ var target = RepairTarget(ships);\r
if (repair.IsRepaired(target))\r
repair.State = State.Reset;\r
repair.UpdateTarget(target);\r
}\r
\r
- private ShipStatus[] RepairTarget(int[] deck)\r
+ private ShipStatus[] RepairTarget(IReadOnlyList<ShipStatus> ships)\r
{\r
- var fs = _shipInfo.GetStatus(deck[0]);\r
+ var fs = ships[0];\r
if (!fs.Spec.IsRepairShip || _dockInfo.InNDock(fs.Id) || fs.DamageLevel >= ShipStatus.Damage.Half)\r
return new ShipStatus[0];\r
var cap = fs.Slot.Count(item => item.Spec.IsRepairFacility) + 2;\r
* - 入渠中の艦娘は終わったときに回復扱いされないようNowHp=MaxHpに\r
* - 中破以上でNowHp=MaxHpにすると回復扱いされるのでNowHp=MaxHp=0に\r
*/\r
- return (from id in deck.Take(cap)\r
- let s = (ShipStatus)_shipInfo.GetStatus(id).Clone()\r
+ return (from ship in ships.Take(cap)\r
+ let s = (ShipStatus)ship.Clone()\r
let full = new ShipStatus {NowHp = s.MaxHp, MaxHp = s.MaxHp}\r
let zero = new ShipStatus()\r
- select _dockInfo.InNDock(id) ? full : s.DamageLevel >= ShipStatus.Damage.Half ? zero : s).ToArray();\r
+ select _dockInfo.InNDock(s.Id) ? full : s.DamageLevel >= ShipStatus.Damage.Half ? zero : s).ToArray();\r
}\r
\r
public RepairSpan[] GetTimers(int fleet)\r
\r
public bool CheckPresetRepairing()\r
=> _presetDeck.Decks.Where(deck => deck != null)\r
- .Any(deck => RepairTarget(deck).Any(s => s.NowHp < s.MaxHp));\r
+ .Any(deck => RepairTarget(deck.Select(id => _shipInfo.GetShip(id)).ToArray()).Any(s => s.NowHp < s.MaxHp));\r
\r
public Notice[] GetNotice(DateTime prev, DateTime now)\r
{\r
_shipInfo.SaveBattleStartStatus();\r
var fleets = _shipInfo.Fleets;\r
_fleet = fleets[DeckId(json)];\r
- FlagshipRecovery(request, _fleet.Ships[0]);\r
- _friend = Record.Setup(_fleet.Ships, practice);\r
+ FlagshipRecovery(request, _fleet.ActualShips[0]);\r
+ _friend = Record.Setup(_fleet.ActualShips, practice);\r
_guard = json.api_f_nowhps_combined()\r
- ? Record.Setup(fleets[1].Ships, practice)\r
+ ? Record.Setup(fleets[1].ActualShips, practice)\r
: new Record[0];\r
_enemy = Record.Setup((int[])json.api_e_nowhps,\r
((int[])json.api_ship_ke).Select(_shipInfo.GetSpec).ToArray(),\r
};\r
}\r
\r
- private void FlagshipRecovery(string request, ShipStatus flagship)\r
+ private void FlagshipRecovery(string request, ShipStatus flagship)\r
{\r
var type = int.Parse(HttpUtility.ParseQueryString(request)["api_recovery_type"] ?? "0");\r
switch (type)\r
public void InspectBattleResult(dynamic json)\r
{\r
BattleState = BattleState.Result;\r
+ if (_friend == null)\r
+ return;\r
ShowResult(!_lastCell);\r
_shipInfo.SaveBattleResult();\r
_shipInfo.DropShipId = json.api_get_ship() ? (int)json.api_get_ship.api_ship_id : -1;\r
SetEscapeShips(json);\r
}\r
\r
- private void VerifyResultRank(dynamic json)\r
- {\r
- if (_friend == null)\r
- return;\r
- if (!json.api_win_rank())\r
- return;\r
- var assumed = "PSABCDE"[(int)ResultRank];\r
- if (assumed == 'P')\r
- assumed = 'S';\r
- var actual = ((string)json.api_win_rank)[0];\r
- DisplayedResultRank.Assumed = assumed;\r
- DisplayedResultRank.Actual = actual;\r
- }\r
-\r
public void InspectPracticeResult(dynamic json)\r
{\r
BattleState = BattleState.Result;\r
+ if (_friend == null)\r
+ return;\r
ShowResult(false);\r
VerifyResultRank(json);\r
CleanupResult();\r
return;\r
var fleets = _shipInfo.Fleets;\r
var ships = _guard.Length > 0\r
- ? fleets[0].Ships.Concat(fleets[1].Ships)\r
- : _fleet.Ships;\r
+ ? fleets[0].ActualShips.Concat(fleets[1].ActualShips)\r
+ : _fleet.ActualShips;\r
foreach (var entry in ships.Zip(_friend.Concat(_guard), (ship, now) => new {ship, now}))\r
entry.now.UpdateShipStatus(entry.ship);\r
if (warnDamagedShip)\r
_shipInfo.ClearBadlyDamagedShips();\r
}\r
\r
+ private void VerifyResultRank(dynamic json)\r
+ {\r
+ if (!json.api_win_rank())\r
+ return;\r
+ var assumed = "PSABCDE"[(int)ResultRank];\r
+ if (assumed == 'P')\r
+ assumed = 'S';\r
+ var actual = ((string)json.api_win_rank)[0];\r
+ DisplayedResultRank.Assumed = assumed;\r
+ DisplayedResultRank.Actual = actual;\r
+ }\r
+\r
public void SetEscapeShips(dynamic json)\r
{\r
_escapingShips.Clear();\r
public string Name => _status.Name;\r
public int StartHp { get; private set; }\r
\r
- public static Record[] Setup(ShipStatus[] ships, bool practice) =>\r
+ public static Record[] Setup(IEnumerable<ShipStatus> ships, bool practice) =>\r
(from s in ships\r
select new Record {_status = (ShipStatus)s.Clone(), _practice = practice, StartHp = s.NowHp}).ToArray();\r
\r
- public static Record[] Setup(int[] nowhps, ShipSpec[] ships, ItemSpec[][] slots, bool practice)\r
+ public static Record[] Setup(int[] nowhps, ShipSpec[] specs, ItemSpec[][] slots, bool practice)\r
{\r
return Enumerable.Range(0, nowhps.Length).Select(i =>\r
new Record\r
StartHp = nowhps[i],\r
_status = new ShipStatus\r
{\r
- Id = ships[i].Id,\r
+ Id = specs[i].Id,\r
NowHp = nowhps[i],\r
MaxHp = nowhps[i],\r
- Spec = ships[i],\r
+ Spec = specs[i],\r
Slot = slots[i].Select(spec => new ItemStatus {Id = spec.Id, Spec = spec}).ToArray(),\r
SlotEx = new ItemStatus(0)\r
},\r
// See the License for the specific language governing permissions and\r
// limitations under the License.\r
\r
+using System;\r
+using System.Collections.Generic;\r
using System.Linq;\r
using static System.Math;\r
\r
\r
public class Fleet\r
{\r
- private readonly ShipInfo _shipInfo;\r
+ private readonly ShipInventry _shipInventry;\r
+ private readonly Func<int> _getHqLevel;\r
+ private int[] _deck = Enumerable.Repeat(-1, ShipInfo.MemberCount).ToArray();\r
public int Number { get; }\r
public FleetState State { get; set; }\r
public CombinedType CombinedType { get; set; }\r
- public int[] Deck { get; set; } = Enumerable.Repeat(-1, ShipInfo.MemberCount).ToArray();\r
- public ShipStatus[] Ships => Deck.Where(id => id != -1).Select(_shipInfo.GetStatus).ToArray();\r
+ public IReadOnlyList<ShipStatus> Ships { get; private set; }\r
+ public IReadOnlyList<ShipStatus> ActualShips { get; private set; }\r
\r
- public Fleet(ShipInfo shipInfo, int number)\r
+ public Fleet(ShipInventry shipInventry, int number, Func<int> getHqLevel)\r
{\r
- _shipInfo = shipInfo;\r
+ _shipInventry = shipInventry;\r
Number = number;\r
+ _getHqLevel = getHqLevel;\r
+ Ships = _deck.Select(id => new ShipStatus()).ToArray();\r
+ ActualShips = new ShipStatus[0];\r
+ }\r
+\r
+ public IReadOnlyList<int> Deck\r
+ {\r
+ get => _deck;\r
+ set\r
+ {\r
+ _deck = value.ToArray();\r
+ SetDeck();\r
+ }\r
+ }\r
+\r
+ public void SetDeck()\r
+ {\r
+ foreach (var ship in Ships)\r
+ {\r
+ ship.Fleet = null;\r
+ ship.DeckIndex = -1;\r
+ }\r
+ Ships = _deck.Select((id, idx) =>\r
+ {\r
+ var ship = _shipInventry[id];\r
+ if (ship.Empty)\r
+ return ship;\r
+ ship.DeckIndex = id;\r
+ ship.Fleet = this;\r
+ return ship;\r
+ }).ToArray();\r
+ ActualShips = Ships.Where(ship => !ship.Empty).ToArray();\r
+ }\r
+\r
+ public int SetShip(int index, int shipId)\r
+ {\r
+ var prev = _deck[index];\r
+ _deck[index] = shipId;\r
+ SetDeck();\r
+ return prev;\r
+ }\r
+\r
+ public void WithdrowShip(int index)\r
+ {\r
+ if (index == -1) // 旗艦以外解除\r
+ {\r
+ for (var i = 1; i < _deck.Length; i++)\r
+ _deck[i] = -1;\r
+ SetDeck();\r
+ return;\r
+ }\r
+ var dst = index;\r
+ for (var src = index + 1; src < _deck.Length; src++)\r
+ {\r
+ if (_deck[src] != -1)\r
+ _deck[dst++] = _deck[src];\r
+ }\r
+ for (; dst < _deck.Length; dst++)\r
+ _deck[dst] = -1;\r
+ SetDeck();\r
}\r
\r
public ChargeStatus ChargeStatus\r
{\r
get\r
{\r
- var fs = new ChargeStatus(_shipInfo.GetStatus(Deck[0]));\r
- var others = (from id in Deck.Skip(1) select new ChargeStatus(_shipInfo.GetStatus(id))).Aggregate(\r
+ var fs = new ChargeStatus(Ships[0]);\r
+ var others = (from ship in Ships.Skip(1) select new ChargeStatus(ship)).Aggregate(\r
(result, next) => new ChargeStatus(Max(result.Fuel, next.Fuel), Max(result.Bull, next.Bull)));\r
return new ChargeStatus(fs.Fuel != 0 ? fs.Fuel : others.Fuel + 5,\r
fs.Bull != 0 ? fs.Bull : others.Bull + 5);\r
}\r
\r
public int[] FighterPower\r
- => Ships.Where(ship => !ship.Escaped).SelectMany(ship =>\r
+ => ActualShips.Where(ship => !ship.Escaped).SelectMany(ship =>\r
ship.Slot.Zip(ship.OnSlot, (slot, onslot) => slot.CalcFighterPower(onslot)))\r
.Aggregate(new[] {0, 0}, (prev, cur) => new[] {prev[0] + cur[0], prev[1] + cur[1]});\r
\r
public double ContactTriggerRate\r
- => Ships.Where(ship => !ship.Escaped).SelectMany(ship =>\r
+ => ActualShips.Where(ship => !ship.Escaped).SelectMany(ship =>\r
ship.Slot.Zip(ship.OnSlot, (slot, onslot) =>\r
slot.Spec.ContactTriggerRate * slot.Spec.LoS * Sqrt(onslot))).Sum();\r
\r
{\r
var result = 0.0;\r
var emptyBonus = 6;\r
- foreach (var s in Ships.Where(s => !s.Escaped))\r
+ foreach (var s in ActualShips.Where(s => !s.Escaped))\r
{\r
emptyBonus--;\r
var itemLoS = 0;\r
}\r
result += Sqrt(s.LoS - itemLoS);\r
}\r
- return result > 0 ? result - Ceiling(_shipInfo.HqLevel * 0.4) + emptyBonus * 2 : 0.0;\r
+ return result > 0 ? result - Ceiling(_getHqLevel() * 0.4) + emptyBonus * 2 : 0.0;\r
}\r
\r
public double DaihatsuBonus\r
// See the License for the specific language governing permissions and\r
// limitations under the License.\r
\r
-using System;\r
using System.Collections.Generic;\r
using System.Linq;\r
using KancolleSniffer.Util;\r
public const int FleetCount = 4;\r
public const int MemberCount = 6;\r
\r
- private readonly Fleet[] _fleets;\r
+ private readonly IReadOnlyList<Fleet> _fleets;\r
private readonly ShipMaster _shipMaster;\r
private readonly ShipInventry _shipInventry;\r
private readonly ItemInventry _itemInventry;\r
private readonly List<int> _escapedShips = new List<int>();\r
private ShipStatus[] _battleResult = new ShipStatus[0];\r
private readonly NumEquipsChecker _numEquipsChecker = new NumEquipsChecker();\r
+ private int _hqLevel;\r
public AlarmCounter Counter { get; }\r
- public int HqLevel { get; private set; }\r
public ShipStatusPair[] BattleResultDiff { get; private set; } = new ShipStatusPair[0];\r
public bool IsBattleResultError => BattleResultDiff.Length > 0;\r
public ShipStatus[] BattleStartStatus { get; private set; } = new ShipStatus[0];\r
{\r
_shipMaster = shipMaster;\r
_shipInventry = shipInventry;\r
- _fleets = Enumerable.Range(0, FleetCount).Select((x, i) => new Fleet(this, i)).ToArray();\r
+ _fleets = Enumerable.Range(0, FleetCount).Select((x, i) => new Fleet(_shipInventry, i, () => _hqLevel)).ToArray();\r
_itemInventry = itemInventry;\r
Counter = new AlarmCounter(() => _shipInventry.Count){Margin = 4};\r
}\r
_escapedShips.Clear();\r
for (var i = 0; i < FleetCount; i++)\r
_fleets[i].State = FleetState.Port;\r
- InspectDeck(json.api_deck_port);\r
- InspectShipData(json.api_ship);\r
+ InspectShipDataAndDeck(json.api_ship, json.api_deck_port);\r
InspectBasic(json.api_basic);\r
if (json.api_combined_flag())\r
_fleets[0].CombinedType = _fleets[1].CombinedType = (CombinedType)(int)json.api_combined_flag;\r
}\r
else if (json.api_data()) // ship2\r
{\r
- InspectDeck(json.api_data_deck);\r
- InspectShipData(json.api_data);\r
+ InspectShipDataAndDeck(json.api_data, json.api_data_deck);\r
}\r
else if (json.api_ship_data()) // ship3とship_deck\r
{\r
- InspectDeck(json.api_deck_data);\r
- InspectShipData(json.api_ship_data);\r
+ InspectShipDataAndDeck(json.api_ship_data, json.api_deck_data);\r
VerifyBattleResult();\r
// ship_deckでドロップ艦を反映する\r
if (DropShipId != -1)\r
_itemInventry.InflateCount(num);\r
}\r
}\r
- else if (json.api_ship()) // getshipとpowerup\r
+ else if (json.api_ship()) // getship\r
{\r
InspectShipData(new[] {json.api_ship});\r
}\r
public void SaveBattleResult()\r
{\r
_battleResult = _fleets.Where(fleet =>\r
- fleet.State >= FleetState.Sortie && !GetStatus(fleet.Deck[0]).Spec.IsRepairShip)\r
- .SelectMany(fleet => fleet.Deck.Select(GetStatus)).ToArray();\r
+ fleet.State >= FleetState.Sortie && !fleet.Ships[0].Spec.IsRepairShip)\r
+ .SelectMany(fleet => fleet.Ships).ToArray();\r
}\r
\r
private void VerifyBattleResult()\r
{\r
BattleResultDiff = (from assumed in _battleResult\r
- let actual = GetStatus(assumed.Id)\r
+ let actual = GetShip(assumed.Id)\r
where !assumed.Escaped && assumed.NowHp != actual.NowHp\r
select new ShipStatusPair(assumed, actual)).ToArray();\r
_battleResult = new ShipStatus[0];\r
public void SaveBattleStartStatus()\r
{\r
BattleStartStatus = _fleets.Where(fleet => fleet.State >= FleetState.Sortie)\r
- .SelectMany(fleet => fleet.Deck.Select(id => (ShipStatus)GetStatus(id).Clone())).ToArray();\r
+ .SelectMany(fleet => fleet.Ships.Select(ship => (ShipStatus)ship.Clone())).ToArray();\r
+ }\r
+\r
+ private void InspectShipDataAndDeck(dynamic ship, dynamic deck)\r
+ {\r
+ InspectShipData(ship);\r
+ InspectDeck(deck); // FleetのDeckを設定した時点でShipStatusを取得するので必ずdeckが後\r
}\r
\r
public void InspectDeck(dynamic json)\r
\r
private void InspectBasic(dynamic json)\r
{\r
- HqLevel = (int)json.api_level;\r
+ _hqLevel = (int)json.api_level;\r
Counter.Max = (int)json.api_max_chara;\r
}\r
\r
public void InspectChange(string request)\r
{\r
var values = HttpUtility.ParseQueryString(request);\r
- var fleet = _fleets[int.Parse(values["api_id"]) - 1];\r
- var idx = int.Parse(values["api_ship_idx"]);\r
- var ship = int.Parse(values["api_ship_id"]);\r
+ var dstFleet = _fleets[int.Parse(values["api_id"]) - 1];\r
+ var dstIdx = int.Parse(values["api_ship_idx"]);\r
+ var shipId = int.Parse(values["api_ship_id"]);\r
\r
- if (idx == -1)\r
- {\r
- var deck = fleet.Deck;\r
- for (var i = 1; i < deck.Length; i++)\r
- deck[i] = -1;\r
- return;\r
- }\r
- if (ship == -1)\r
+ if (dstIdx == -1 || shipId == -1) // 解除\r
{\r
- WithdrowShip(fleet, idx);\r
+ dstFleet.WithdrowShip(dstIdx);\r
return;\r
}\r
- var of = FindFleet(ship, out var oi);\r
- var orig = fleet.Deck[idx];\r
- fleet.Deck[idx] = ship;\r
- if (of == null)\r
+ var srcFleet = FindFleet(shipId, out var srcIdx);\r
+ var prevShipId = dstFleet.SetShip(dstIdx, shipId);\r
+ if (srcFleet == null)\r
return;\r
// 入れ替えの場合\r
- if ((of.Deck[oi] = orig) == -1)\r
- WithdrowShip(of, oi);\r
+ srcFleet.SetShip(srcIdx, prevShipId);\r
+ if (prevShipId == -1)\r
+ srcFleet.WithdrowShip(srcIdx);\r
}\r
\r
private Fleet FindFleet(int ship, out int idx)\r
{\r
foreach (var fleet in _fleets)\r
{\r
- idx = Array.FindIndex(fleet.Deck, id => id == ship);\r
+ idx = fleet.Deck.ToList().IndexOf(ship);\r
if (idx < 0)\r
continue;\r
return fleet;\r
return null;\r
}\r
\r
- private void WithdrowShip(Fleet fleet, int idx)\r
- {\r
- var deck = fleet.Deck;\r
- var j = idx;\r
- for (var i = idx + 1; i < deck.Length; i++)\r
- {\r
- if (deck[i] != -1)\r
- deck[j++] = deck[i];\r
- }\r
- for (; j < deck.Length; j++)\r
- deck[j] = -1;\r
- }\r
-\r
public void InspectPowerup(string request, dynamic json)\r
{\r
var values = HttpUtility.ParseQueryString(request);\r
return;\r
_itemInventry.Remove(ships.SelectMany(id => _shipInventry[id].Slot));\r
_shipInventry.Remove(ships);\r
- InspectDeck(json.api_deck);\r
- InspectShip(json);\r
+ InspectShipDataAndDeck(new[]{json.api_ship}, json.api_deck);\r
}\r
\r
public void InspectSlotExchange(string request, dynamic json)\r
public void InspectSlotDeprive(dynamic json)\r
{\r
InspectShipData(new[] {json.api_ship_data.api_set_ship, json.api_ship_data.api_unset_ship});\r
+ foreach (var fleet in _fleets)\r
+ fleet.SetDeck(); // ShipStatusの差し替え\r
}\r
\r
public void InspectDestroyShip(string request, dynamic json)\r
{\r
var values = HttpUtility.ParseQueryString(request);\r
var delitem = int.Parse(values["api_slot_dest_flag"] ?? "0") == 1;\r
- foreach (var id in values["api_ship_id"].Split(',').Select(int.Parse))\r
+ foreach (var shipId in values["api_ship_id"].Split(',').Select(int.Parse))\r
{\r
if (delitem)\r
- _itemInventry.Remove(_shipInventry[id].AllSlot);\r
- var of = FindFleet(id, out var oi);\r
- if (of != null)\r
- WithdrowShip(of, oi);\r
- _shipInventry.Remove(id);\r
+ _itemInventry.Remove(_shipInventry[shipId].AllSlot);\r
+ var srcFleet = FindFleet(shipId, out var srcIdx);\r
+ srcFleet?.WithdrowShip(srcIdx);\r
+ _shipInventry.Remove(shipId);\r
}\r
}\r
\r
_fleets[fleet].State = FleetState.Practice;\r
}\r
\r
- public Fleet[] Fleets => _fleets;\r
+ public IReadOnlyList<Fleet> Fleets => _fleets;\r
\r
- public ShipStatus GetStatus(int id) => FillUp(_shipInventry[id]);\r
-\r
- private ShipStatus FillUp(ShipStatus ship)\r
- {\r
- if (ship.Empty)\r
- return ship;\r
- ship.Fleet = FindFleet(ship.Id, out var idx);\r
- ship.DeckIndex = idx;\r
- return ship;\r
- }\r
+ public ShipStatus GetShip(int id) => _shipInventry[id];\r
\r
public void SetItemHolder()\r
{\r
\r
public ShipSpec GetSpec(int id) => _shipMaster.GetSpec(id);\r
\r
- public ShipStatus[] ShipList => _shipInventry.AllShips.Select(FillUp).ToArray();\r
+ public ShipStatus[] ShipList => _shipInventry.AllShips.ToArray();\r
\r
public ShipStatus[] GetRepairList(DockInfo dockInfo)\r
=> (from s in ShipList\r
{\r
BadlyDamagedShips =\r
(from s in _fleets.Where(fleet => fleet.State == FleetState.Sortie)\r
- .SelectMany(fleet => fleet.Deck.Where(id => id != -1).Select(GetStatus))\r
+ .SelectMany(fleet => fleet.ActualShips)\r
where !s.Escaped && s.DamageLevel == ShipStatus.Damage.Badly &&\r
!(s.Fleet.CombinedType != 0 && s.Fleet.Number == 1 && s.DeckIndex == 0) // 第二艦隊の旗艦を除く\r
select s.Name).ToArray();\r
\r
public IReadOnlyList<ItemStatus> Slot\r
{\r
- get => _slot.Select(item => GetItem(item)).ToList();\r
- set => _slot = value.ToList();\r
+ get => _slot.Select(item => GetItem(item)).ToArray();\r
+ set => _slot = value.ToArray();\r
}\r
\r
public ItemStatus SlotEx\r
\r
public AlarmCounter ShipCounter => _shipInfo.Counter;\r
\r
- public Fleet[] Fleets => _shipInfo.Fleets;\r
+ public IReadOnlyList<Fleet> Fleets => _shipInfo.Fleets;\r
\r
public ShipInfo.ShipStatusPair[] BattleResultStatusDiff => _shipInfo.BattleResultDiff;\r
\r
var sb = new StringBuilder();\r
var fn = new[] {"第一艦隊", "第二艦隊", "第三艦隊", "第四艦隊"};\r
sb.Append(fn[fleet] + "\r\n");\r
- sb.Append(string.Concat(from s in target.Ships\r
+ sb.Append(string.Concat(from s in target.ActualShips\r
select ($"{s.Name} Lv{s.Level} " +\r
string.Join(",",\r
from item in s.AllSlot\r
if (fleet.Number != 0)\r
sb.Append(",");\r
sb.Append($"\"f{fleet.Number + 1}\":{{");\r
- var ships = fleet.Ships;\r
- for (var s = 0; s < ships.Length; s++)\r
+ var ships = fleet.ActualShips;\r
+ for (var s = 0; s < ships.Count; s++)\r
{\r
if (s != 0)\r
sb.Append(",");\r
var fn = new[] {"第一艦隊", "第二艦隊", "第三艦隊", "第四艦隊"};\r
foreach (var fleet in sniffer.Fleets)\r
{\r
- var ships = fleet.Ships;\r
+ var ships = fleet.ActualShips;\r
var rawForFleet = ships.Sum(ship => ship.EffectiveAntiAirForFleet);\r
var forFleet = new[] {1.0, 1.2, 1.6}.Select(r => (int)(rawForFleet * r) * 2 / 1.3).ToArray();\r
_table.Add(new Record\r
foreach (var fleet in sniffer.Fleets)\r
{\r
var total = new Total();\r
- var ships = new List<Record>();\r
- foreach (var s in fleet.Ships)\r
+ var shipRecords = new List<Record>();\r
+ foreach (var ship in fleet.ActualShips)\r
{\r
var equips = new List<Record>();\r
- for (var i = 0; i < s.Slot.Count; i++)\r
+ for (var i = 0; i < ship.Slot.Count; i++)\r
{\r
- var item = s.Slot[i];\r
- var onslot = s.OnSlot[i];\r
- var max = s.Spec.MaxEq[i];\r
+ var item = ship.Slot[i];\r
+ var onslot = ship.OnSlot[i];\r
+ var max = ship.Spec.MaxEq[i];\r
if (item.Empty)\r
continue;\r
var airspec = "";\r
Color = item.Spec.Color\r
});\r
}\r
- if (s.SlotEx.Id > 0)\r
+ if (ship.SlotEx.Id > 0)\r
{\r
- var item = s.SlotEx;\r
+ var item = ship.SlotEx;\r
equips.Add(new Record {Equip = GenEquipString(item), Color = item.Spec.Color});\r
}\r
- total.Add(s);\r
- var fire = s.EffectiveFirepower;\r
- var subm = s.EffectiveAntiSubmarine;\r
- var torp = s.EffectiveTorpedo;\r
- var night = s.NightBattlePower;\r
- var oasa = s.CanOpeningAntiSubmarineAttack ? "*" : "";\r
- var ship = new Record\r
+ total.Add(ship);\r
+ var fire = ship.EffectiveFirepower;\r
+ var subm = ship.EffectiveAntiSubmarine;\r
+ var torp = ship.EffectiveTorpedo;\r
+ var night = ship.NightBattlePower;\r
+ var oasa = ship.CanOpeningAntiSubmarineAttack ? "*" : "";\r
+ var record = new Record\r
{\r
- Ship = (s.Escaped ? "[避]" : "") + s.Name + " Lv" + s.Level,\r
- Ship2 = $"燃{s.EffectiveFuelMax} 弾{s.EffectiveBullMax}",\r
- Id = s.Id,\r
+ Ship = (ship.Escaped ? "[避]" : "") + ship.Name + " Lv" + ship.Level,\r
+ Ship2 = $"燃{ship.EffectiveFuelMax} 弾{ship.EffectiveBullMax}",\r
+ Id = ship.Id,\r
Spec = HideIfZero("砲", fire) + HideIfZero(" 潜", subm) + oasa,\r
Spec2 = (HideIfZero("雷", torp) + HideIfZero(" 夜", night)).TrimStart(' ')\r
};\r
- if (ship.Spec == "")\r
+ if (record.Spec == "")\r
{\r
- ship.Spec = ship.Spec2;\r
- ship.Spec2 = "";\r
+ record.Spec = record.Spec2;\r
+ record.Spec2 = "";\r
}\r
- ships.Add(ship);\r
- ships.AddRange(equips);\r
+ shipRecords.Add(record);\r
+ shipRecords.AddRange(equips);\r
}\r
var daihatsu = fleet.DaihatsuBonus;\r
var tp = fleet.TransportPoint;\r
? ""\r
: $"\r\nTP:S{(int)tp} A{(int)(tp * 0.7)}")\r
});\r
- list.AddRange(ships);\r
+ list.AddRange(shipRecords);\r
}\r
if (sniffer.BaseAirCorps != null)\r
{\r
label.ToggleHpPercent();\r
}\r
\r
- public void SetShipLabels(ShipStatus[] statuses)\r
+ public void SetShipLabels(IReadOnlyList<ShipStatus> ships)\r
{\r
- SetShipLabels(statuses, statuses.Length == 7 ? _shipLabels7 : _shiplabels);\r
+ SetShipLabels(ships, ships.Count == 7 ? _shipLabels7 : _shiplabels);\r
}\r
\r
- public void SetShipLabels(ShipStatus[] statuses, ShipLabel[][] shipLabels)\r
+ public void SetShipLabels(IReadOnlyList<ShipStatus> ships, ShipLabel[][] shipLabels)\r
{\r
for (var i = 0; i < shipLabels.Length; i++)\r
{\r
var labels = shipLabels[i];\r
- var s = i < statuses.Length ? statuses[i] : null;\r
- labels[0].SetHp(s);\r
- labels[1].SetCond(s);\r
- labels[2].SetLevel(s);\r
- labels[3].SetExpToNext(s);\r
- labels[4].SetName(s, ShipNameWidth.MainPanel);\r
+ var ship = i < ships.Count ? ships[i] : null;\r
+ labels[0].SetHp(ship);\r
+ labels[1].SetCond(ship);\r
+ labels[2].SetLevel(ship);\r
+ labels[3].SetExpToNext(ship);\r
+ labels[4].SetName(ship, ShipNameWidth.MainPanel);\r
}\r
}\r
\r
parent.ResumeLayout();\r
}\r
\r
- public void SetCombinedShipLabels(ShipStatus[] first, ShipStatus[] second)\r
+ public void SetCombinedShipLabels(IReadOnlyList<ShipStatus> first, IReadOnlyList<ShipStatus> second)\r
{\r
for (var i = 0; i < _combinedLabels.Length; i++)\r
{\r
var idx = i % ShipInfo.MemberCount;\r
- var statuses = i < ShipInfo.MemberCount ? first : second;\r
+ var ships = i < ShipInfo.MemberCount ? first : second;\r
var labels = _combinedLabels[i];\r
- var s = idx < statuses.Length ? statuses[idx] : null;\r
+ var s = idx < ships.Count ? ships[idx] : null;\r
labels[0].SetHp(s);\r
labels[1].SetCond(s);\r
labels[2].SetName(s, ShipNameWidth.Combined);\r
}\r
}\r
\r
- public void SetAkashiTimer(ShipStatus[] statuses, AkashiTimer.RepairSpan[] timers)\r
+ public void SetAkashiTimer(IReadOnlyList<ShipStatus> ships, AkashiTimer.RepairSpan[] timers)\r
{\r
- if (statuses.Length == 7)\r
+ if (ships.Count == 7)\r
{\r
- SetAkashiTimer(statuses, timers, _akashiTimers7, _shipLabels7);\r
+ SetAkashiTimer(ships, timers, _akashiTimers7, _shipLabels7);\r
}\r
else\r
{\r
- SetAkashiTimer(statuses, timers, _akashiTimers, _shiplabels);\r
+ SetAkashiTimer(ships, timers, _akashiTimers, _shiplabels);\r
}\r
}\r
\r
- public void SetAkashiTimer(ShipStatus[] statuses, AkashiTimer.RepairSpan[] timers, ShipLabel[] timerLabels,\r
+ public void SetAkashiTimer(IReadOnlyList<ShipStatus> ships, AkashiTimer.RepairSpan[] timers, ShipLabel[] timerLabels,\r
ShipLabel[][] shipLabels)\r
{\r
var shortest = -1;\r
continue;\r
}\r
var timer = timers[i];\r
- var stat = statuses[i];\r
+ var stat = ships[i];\r
label.Visible = true;\r
label.Text = timer.Span.ToString(@"mm\:ss");\r
label.ForeColor = Control.DefaultForeColor;\r
var raw = _expTable[Min(s1, _expTable.Length) - 1] / 100.0 +\r
_expTable[Min(s2, _expTable.Length) - 1] / 300.0;\r
var exp = raw >= 500 ? 500 + (int)Sqrt(raw - 500) : (int)raw;\r
- var bonus = 1 + TrainingCruiserBonus(_shipInfo.Fleets[0].Ships);\r
+ var bonus = 1 + TrainingCruiserBonus(_shipInfo.Fleets[0].ActualShips);\r
Text += $"獲得経験値 : {(int)(exp * bonus)}\r\nS勝利 : {(int)((int)(exp * 1.2) * bonus)}";\r
}\r
\r
- private double TrainingCruiserBonus(ShipStatus[] fleet)\r
+ private double TrainingCruiserBonus(IReadOnlyList<ShipStatus> fleet)\r
{\r
if (fleet[0].Spec.IsTrainingCruiser)\r
{\r