\r
public void InspectBattle(string url, string request, dynamic json)\r
{\r
- if (json.api_formation())\r
- Formation = ((dynamic[])json.api_formation).Select(f => f is string ? (int)int.Parse(f) : (int)f)\r
- .ToArray();\r
- AirControlLevel = CheckAirControlLevel(json);\r
+ SetFormation(json);\r
+ SetAirControlLevel(json);\r
SetSupportType(json);\r
- ShowResult(false); // 昼戦の結果を夜戦のときに表示する\r
- SetupResult(request, json, url.Contains("practice"));\r
- FighterPower = CalcFighterPower();\r
- EnemyFighterPower = CalcEnemyFighterPower(json);\r
+ ClearDamagedShipWarning();\r
+ ShowResult(); // 昼戦の結果を夜戦のときに表示する\r
+ SetupDamageRecord(request, json, url.Contains("practice"));\r
+ SetFighterPower();\r
+ SetEnemyFighterPower();\r
BattleState = url.Contains("sp_midnight") ? BattleState.SpNight :\r
url.Contains("midnight") ? BattleState.Night : BattleState.Day;\r
CalcDamage(json);\r
SetResult();\r
}\r
\r
- public static int DeckId(dynamic json)\r
+ private void SetFormation(dynamic json)\r
+ {\r
+ if (json.api_formation())\r
+ Formation = (int[])json.api_formation;\r
+ }\r
+\r
+ private void SetAirControlLevel(dynamic json)\r
+ {\r
+ AirControlLevel = -1;\r
+ if (!json.api_kouku())\r
+ return;\r
+ var stage1 = json.api_kouku.api_stage1;\r
+ if (stage1 == null || stage1.api_f_count == 0 && stage1.api_e_count == 0)\r
+ return;\r
+ AirControlLevel = (int)stage1.api_disp_seiku;\r
+ }\r
+\r
+ private void SetSupportType(dynamic json)\r
{\r
- if (json.api_dock_id()) // 昼戦はtypoしている\r
- return (int)json.api_dock_id - 1;\r
- if (json.api_deck_id is string) // 通常の夜戦と連合艦隊(味方のみ)では文字列\r
- return int.Parse(json.api_deck_id) - 1;\r
- return (int)json.api_deck_id - 1;\r
+ SupportType = json.api_support_flag() ? (int)json.api_support_flag :\r
+ json.api_n_support_flag() ? (int)json.api_n_support_flag : 0;\r
}\r
\r
- private void SetupResult(string request, dynamic json, bool practice)\r
+ private void SetupDamageRecord(string request, dynamic json, bool practice)\r
{\r
if (_friend != null)\r
return;\r
_shipInfo.SaveBattleStartStatus();\r
- var fleets = _shipInfo.Fleets;\r
- _fleet = fleets[DeckId(json)];\r
+ SetupFriendDamageRecord(request, json, practice);\r
+ SetupEnemyDamageRecord(json, practice);\r
+ }\r
+\r
+ private void SetupFriendDamageRecord(string request, dynamic json, bool practice)\r
+ {\r
+ _fleet = _shipInfo.Fleets[(int)json.api_deck_id - 1];\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].ActualShips, practice)\r
+ ? Record.Setup(_shipInfo.Fleets[1].ActualShips, practice)\r
: new Record[0];\r
+ }\r
+\r
+ private void SetupEnemyDamageRecord(dynamic json, bool practice)\r
+ {\r
_enemy = Record.Setup((int[])json.api_e_nowhps,\r
- ((int[])json.api_ship_ke).Select(_shipInfo.GetSpec).ToArray(),\r
- ((int[][])json.api_eSlot).Select(slot => slot.Select(_itemInfo.GetSpecByItemId).ToArray()).ToArray(),\r
- practice);\r
+ EnemyShipSpecs(json.api_ship_ke),\r
+ EnemySlots(json.api_eSlot), practice);\r
_enemyGuard = json.api_ship_ke_combined()\r
? Record.Setup((int[])json.api_e_nowhps_combined,\r
- ((int[])json.api_ship_ke_combined).Select(_shipInfo.GetSpec).ToArray(),\r
- ((int[][])json.api_eSlot_combined).Select(slot => slot.Select(_itemInfo.GetSpecByItemId).ToArray())\r
- .ToArray(), practice)\r
+ EnemyShipSpecs(json.api_ship_ke_combined),\r
+ EnemySlots(json.api_eSlot_combined), practice)\r
: new Record[0];\r
}\r
\r
+ private ShipSpec[] EnemyShipSpecs(dynamic ships)\r
+ {\r
+ return ((int[])ships).Select(_shipInfo.GetSpec).ToArray();\r
+ }\r
+\r
+ private ItemSpec[][] EnemySlots(dynamic slots)\r
+ {\r
+ return ((int[][])slots).Select(slot => slot.Select(_itemInfo.GetSpecByItemId).ToArray()).ToArray();\r
+ }\r
+\r
private void SetResult()\r
{\r
Result = new BattleResult\r
_lastCell = false;\r
}\r
\r
- private int CheckAirControlLevel(dynamic json)\r
- {\r
- if (!json.api_kouku())\r
- return -1;\r
- var stage1 = json.api_kouku.api_stage1;\r
- if (stage1 == null)\r
- return -1;\r
- if (stage1.api_f_count == 0 && stage1.api_e_count == 0)\r
- return -1;\r
- return (int)stage1.api_disp_seiku;\r
- }\r
-\r
- private void SetSupportType(dynamic json)\r
- {\r
- SupportType = json.api_support_flag() ? (int)json.api_support_flag :\r
- json.api_n_support_flag() ? (int)json.api_n_support_flag : 0;\r
- }\r
-\r
- private int[] CalcFighterPower()\r
+ private void SetFighterPower()\r
{\r
var fleets = _shipInfo.Fleets;\r
- if (_guard.Length > 0 && _enemyGuard.Length > 0)\r
- return fleets[0].FighterPower.Zip(fleets[1].FighterPower, (a, b) => a + b).ToArray();\r
- return _fleet.FighterPower;\r
+ FighterPower = _guard.Length > 0 && _enemyGuard.Length > 0\r
+ ? fleets[0].FighterPower.Zip(fleets[1].FighterPower, (a, b) => a + b).ToArray()\r
+ : _fleet.FighterPower;\r
}\r
\r
- private EnemyFighterPower CalcEnemyFighterPower(dynamic json)\r
+ private void SetEnemyFighterPower()\r
{\r
- var result = new EnemyFighterPower();\r
- var ships = (int[])json.api_ship_ke;\r
- if (json.api_ship_ke_combined() && _guard.Length > 0)\r
- ships = ships.Concat((int[])json.api_ship_ke_combined).ToArray();\r
- var maxEq = ships.SelectMany(id =>\r
- {\r
- var r = _shipInfo.GetSpec(id).MaxEq;\r
- if (r != null)\r
- return r;\r
- result.HasUnknown = true;\r
- return new int[5];\r
- });\r
- var equips = ((int[][])json.api_eSlot).SelectMany(x => x);\r
- if (json.api_eSlot_combined() && _guard.Length > 0)\r
- equips = equips.Concat(((int[][])json.api_eSlot_combined).SelectMany(x => x));\r
- foreach (var entry in from slot in equips.Zip(maxEq, (id, max) => new {id, max})\r
- let spec = _itemInfo.GetSpecByItemId(slot.id)\r
- let perSlot = (int)Floor(spec.AntiAir * Sqrt(slot.max))\r
- select new {spec, perSlot})\r
+ EnemyFighterPower = new EnemyFighterPower();\r
+ foreach (var record in _guard.Length == 0 ? _enemy : _enemy.Concat(_enemyGuard))\r
{\r
- if (entry.spec.CanAirCombat)\r
- result.AirCombat += entry.perSlot;\r
- if (entry.spec.IsAircraft)\r
- result.Interception += entry.perSlot;\r
+ var ship = record.SnapShot;\r
+ if (ship.Spec.MaxEq == null)\r
+ {\r
+ EnemyFighterPower.HasUnknown = true;\r
+ continue;\r
+ }\r
+ foreach (var entry in ship.Slot.Zip(ship.Spec.MaxEq, (item, maxEq) => new {item.Spec, maxEq}))\r
+ {\r
+ var perSlot = (int)Floor(entry.Spec.AntiAir * Sqrt(entry.maxEq));\r
+ if (entry.Spec.CanAirCombat)\r
+ EnemyFighterPower.AirCombat += perSlot;\r
+ if (entry.Spec.IsAircraft)\r
+ EnemyFighterPower.Interception += perSlot;\r
+ }\r
}\r
- return result;\r
}\r
\r
private void CalcDamage(dynamic json)\r
{\r
PhaseName = phaseName,\r
AirControlLevel = json.api_stage1.api_disp_seiku() ? (int)json.api_stage1.api_disp_seiku : 0,\r
- Stage1 = new AirBattleResult.StageResult\r
- {\r
- FriendCount = (int)json.api_stage1.api_f_count,\r
- FriendLost = (int)json.api_stage1.api_f_lostcount,\r
- EnemyCount = (int)json.api_stage1.api_e_count,\r
- EnemyLost = (int)json.api_stage1.api_e_lostcount\r
- },\r
+ Stage1 = CreateStageResult(json.api_stage1),\r
Stage2 = json.api_stage2 == null\r
- ? new AirBattleResult.StageResult\r
- {\r
- FriendCount = 0,\r
- FriendLost = 0,\r
- EnemyCount = 0,\r
- EnemyLost = 0\r
- }\r
- : new AirBattleResult.StageResult\r
- {\r
- FriendCount = (int)json.api_stage2.api_f_count,\r
- FriendLost = (int)json.api_stage2.api_f_lostcount,\r
- EnemyCount = (int)json.api_stage2.api_e_count,\r
- EnemyLost = (int)json.api_stage2.api_e_lostcount\r
- }\r
+ ? new AirBattleResult.StageResult()\r
+ : CreateStageResult(json.api_stage2),\r
+ AirFire = CreateAirFireResult(json)\r
};\r
- if (json.api_stage2 != null && json.api_stage2.api_air_fire())\r
- {\r
- var airFire = json.api_stage2.api_air_fire;\r
- var idx = (int)airFire.api_idx;\r
- result.AirFire = new AirBattleResult.AirFireResult\r
- {\r
- ShipName = idx < _friend.Length ? _friend[idx].Name : _guard[idx - 6].Name,\r
- Kind = (int)airFire.api_kind,\r
- Items = ((int[])airFire.api_use_items).Select(id => _itemInfo.GetSpecByItemId(id).Name).ToArray()\r
- };\r
- }\r
AirBattleResults.Add(result);\r
}\r
\r
+ private AirBattleResult.StageResult CreateStageResult(dynamic stage)\r
+ {\r
+ return new AirBattleResult.StageResult\r
+ {\r
+ FriendCount = (int)stage.api_f_count,\r
+ FriendLost = (int)stage.api_f_lostcount,\r
+ EnemyCount = (int)stage.api_e_count,\r
+ EnemyLost = (int)stage.api_e_lostcount\r
+ };\r
+ }\r
+\r
+ private AirBattleResult.AirFireResult CreateAirFireResult(dynamic json)\r
+ {\r
+ if (json.api_stage2 == null || !json.api_stage2.api_air_fire())\r
+ return null;\r
+ var airFire = json.api_stage2.api_air_fire;\r
+ var idx = (int)airFire.api_idx;\r
+ return new AirBattleResult.AirFireResult\r
+ {\r
+ ShipName = idx < _friend.Length ? _friend[idx].Name : _guard[idx - 6].Name,\r
+ Kind = (int)airFire.api_kind,\r
+ Items = ((int[])airFire.api_use_items).Select(id => _itemInfo.GetSpecByItemId(id).Name).ToArray()\r
+ };\r
+ }\r
+\r
private void CalcKoukuDamage(dynamic json)\r
{\r
if (json.api_stage3() && json.api_stage3 != null)\r
\r
public BothRecord(Record[] friend, Record[] guard, Record[] enemy, Record[] enemyGuard)\r
{\r
- _records = new[] { new Record[12], new Record[12] };\r
+ _records = new[] {new Record[12], new Record[12]};\r
Array.Copy(friend, _records[1], friend.Length);\r
Array.Copy(guard, 0, _records[1], 6, guard.Length);\r
Array.Copy(enemy, _records[0], enemy.Length);\r
BattleState = BattleState.Result;\r
if (_friend == null)\r
return;\r
- ShowResult(!_lastCell);\r
+ ShowResult();\r
+ if (!_lastCell)\r
+ SetDamagedShipWarning();\r
_shipInfo.SaveBattleResult();\r
_shipInfo.DropShipId = json.api_get_ship() ? (int)json.api_get_ship.api_ship_id : -1;\r
VerifyResultRank(json);\r
BattleState = BattleState.Result;\r
if (_friend == null)\r
return;\r
- ShowResult(false);\r
+ ShowResult();\r
VerifyResultRank(json);\r
CleanupResult();\r
}\r
\r
- private void ShowResult(bool warnDamagedShip = true)\r
+ private void ShowResult()\r
{\r
if (_friend == null)\r
return;\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.SetBadlyDamagedShips();\r
- else\r
- _shipInfo.ClearBadlyDamagedShips();\r
+ }\r
+\r
+ private void SetDamagedShipWarning()\r
+ {\r
+ _shipInfo.SetBadlyDamagedShips();\r
+ }\r
+\r
+ private void ClearDamagedShipWarning()\r
+ {\r
+ _shipInfo.ClearBadlyDamagedShips();\r
}\r
\r
private void VerifyResultRank(dynamic json)\r
public int StartHp { get; private set; }\r
\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
+ (from s in ships\r
+ select new Record {_status = (ShipStatus)s.Clone(), _practice = practice, StartHp = s.NowHp})\r
+ .ToArray();\r
\r
public static Record[] Setup(int[] nowHps, ShipSpec[] specs, ItemSpec[][] slots, bool practice)\r
{\r
\r
private BattleResultRank CalcLdResultRank()\r
{\r
- var combined = _friend.Concat(_guard).Where(r => !r.Escaped).ToArray();\r
- var friendGauge = combined.Sum(r => r.StartHp - r.NowHp);\r
- var friendGaugeRate = Floor((double)friendGauge / combined.Sum(r => r.StartHp) * 100);\r
+ var friend = new ResultRankParams(_friend.Concat(_guard).ToArray());\r
\r
- if (friendGauge <= 0)\r
+ if (friend.Gauge <= 0)\r
return BattleResultRank.P;\r
- if (friendGaugeRate < 10)\r
+ if (friend.GaugeRate < 10)\r
return BattleResultRank.A;\r
- if (friendGaugeRate < 20)\r
+ if (friend.GaugeRate < 20)\r
return BattleResultRank.B;\r
- if (friendGaugeRate < 50)\r
+ if (friend.GaugeRate < 50)\r
return BattleResultRank.C;\r
- if (friendGaugeRate < 80)\r
+ if (friend.GaugeRate < 80)\r
return BattleResultRank.D;\r
return BattleResultRank.E;\r
}\r
\r
private BattleResultRank CalcResultRank()\r
{\r
- var friend = _friend.Concat(_guard).ToArray();\r
- var enemy = _enemy.Concat(_enemyGuard).ToArray();\r
-\r
- var friendCount = friend.Length;\r
- var friendStartHpTotal = 0;\r
- var friendNowHpTotal = 0;\r
- var friendSunk = 0;\r
- foreach (var ship in friend)\r
+ var friend = new ResultRankParams(_friend.Concat(_guard).ToArray());\r
+ var enemy = new ResultRankParams(_enemy.Concat(_enemyGuard).ToArray());\r
+ if (friend.Sunk == 0 && enemy.Sunk == enemy.Count)\r
{\r
- if (ship.Escaped)\r
- continue;\r
- friendStartHpTotal += ship.StartHp;\r
- friendNowHpTotal += ship.NowHp;\r
- if (ship.NowHp == 0)\r
- friendSunk++;\r
- }\r
- var friendGaugeRate = (int)((double)(friendStartHpTotal - friendNowHpTotal) / friendStartHpTotal * 100);\r
-\r
- var enemyCount = enemy.Length;\r
- var enemyStartHpTotal = enemy.Sum(r => r.StartHp);\r
- var enemyNowHpTotal = enemy.Sum(r => r.NowHp);\r
- var enemySunk = enemy.Count(r => r.NowHp == 0);\r
- var enemyGaugeRate = (int)((double)(enemyStartHpTotal - enemyNowHpTotal) / enemyStartHpTotal * 100);\r
-\r
- if (friendSunk == 0 && enemySunk == enemyCount)\r
- {\r
- if (friendNowHpTotal >= friendStartHpTotal)\r
+ if (friend.Gauge <= 0)\r
return BattleResultRank.P;\r
return BattleResultRank.S;\r
}\r
- if (friendSunk == 0 && enemySunk >= (int)(enemyCount * 0.7) && enemyCount > 1)\r
+ if (friend.Sunk == 0 && enemy.Sunk >= (int)(enemy.Count * 0.7) && enemy.Count > 1)\r
return BattleResultRank.A;\r
- if (friendSunk < enemySunk && enemy[0].NowHp == 0)\r
+ if (friend.Sunk < enemy.Sunk && _enemy[0].NowHp == 0)\r
return BattleResultRank.B;\r
- if (friendCount == 1 && friend[0].DamageLevel == ShipStatus.Damage.Badly)\r
+ if (friend.Count == 1 && _friend[0].DamageLevel == ShipStatus.Damage.Badly)\r
return BattleResultRank.D;\r
- if (enemyGaugeRate > friendGaugeRate * 2.5)\r
+ if (enemy.GaugeRate > friend.GaugeRate * 2.5)\r
return BattleResultRank.B;\r
- if (enemyGaugeRate > friendGaugeRate * 0.9)\r
+ if (enemy.GaugeRate > friend.GaugeRate * 0.9)\r
return BattleResultRank.C;\r
- if (friendCount > 1 && friendCount - 1 == friendSunk)\r
+ if (friend.Count > 1 && friend.Count - 1 == friend.Sunk)\r
return BattleResultRank.E;\r
return BattleResultRank.D;\r
}\r
\r
+ private class ResultRankParams\r
+ {\r
+ public readonly int Count;\r
+ public readonly int Sunk;\r
+ public readonly int Gauge;\r
+ public readonly int GaugeRate;\r
+\r
+ public ResultRankParams(Record[] records)\r
+ {\r
+ var staying = records.Where(r => !r.Escaped).ToArray();\r
+ Count = records.Length;\r
+ Sunk = staying.Count(r => r.NowHp == 0);\r
+ Gauge = staying.Sum(r => r.StartHp - r.NowHp);\r
+ GaugeRate = (int)((double)Gauge / records.Sum(r => r.StartHp) * 100);\r
+ }\r
+ }\r
+\r
/// <summary>\r
/// テスト専用\r
/// </summary>\r