2 // CalculateDamageCommand.swift
5 // Created by Hori,Masaki on 2017/01/15.
6 // Copyright © 2017年 Hori,Masaki. All rights reserved.
18 case eachCombinedWater
22 enum DamageControlID: Int {
24 case damageControl = 42
28 final class CalculateDamageCommand: JSONCommand {
30 override func execute() {
34 case .battle, .airBattle, .ldAirBattle:
35 normalBattle(battleType: .normal)
37 case .combinedEcBattle:
38 enemyCombinedBattle(battleType: .enemyCombined)
40 case .combinedBattle, .combinedAirBattle:
41 combinedAirBattle(battleType: .combinedAir)
43 case .combinedBattleWater, .combinedLdAirBattle:
44 normalBattle(battleType: .combinedWater)
46 case .combinedEachBattle:
47 eachAirBattle(battleType: .eachCombinedAir)
49 case .combinedEachBattleWater:
50 normalBattle(battleType: .eachCombinedWater)
52 case .combinedEachNightToDay:
53 eachNightToDayBattle(battleType: .normal)
55 case .midnightBattle, .midnightSpMidnight:
56 midnightBattle(battleType: .normal)
58 case .combinedMidnightBattle, .combinedSpMidnight:
59 midnightBattle(battleType: .combinedAir)
61 case .combinedEcMidnightBattle:
62 midnightBattle(battleType: .eachCombinedAir)
64 case .battleResult, .combinedBattleResult:
68 default: return Logger.shared.log("Missing API: \(apiResponse.api)")
72 func normalBattle(battleType: BattleType) {
75 DamageCalculator(json, battleType).calculateBattle()
78 func combinedAirBattle(battleType: BattleType) {
81 DamageCalculator(json, battleType).calcCombinedBattleAir()
84 func eachAirBattle(battleType: BattleType) {
87 DamageCalculator(json, battleType).calcEachBattleAir()
90 func eachNightToDayBattle(battleType: BattleType) {
93 DamageCalculator(json, battleType).calcEachNightToDay()
96 func enemyCombinedBattle(battleType: BattleType) {
99 DamageCalculator(json, battleType).calcEnemyCombinedBattle()
102 func midnightBattle(battleType: BattleType) {
104 DamageCalculator(json, battleType).calcMidnight()
108 extension CalculateDamageCommand {
112 let store = TemporaryDataStore.oneTimeEditor()
114 store.sync { store.damages().forEach(store.delete) }
119 let store = TemporaryDataStore.oneTimeEditor()
121 let totalDamages = store.sync { store.sortedDamagesById() }
123 let aStore = ServerDataStore.default
125 Debug.excute(level: .debug) {
130 totalDamages.forEach { damage in
132 let shipId = damage.shipID
133 guard let ship = aStore.sync(execute: { aStore.ship(by: shipId) }) else { return }
135 let damagedHp = damage.hp
137 if ship.nowhp != damagedHp {
139 print("\(ship.name)(\(ship.id)),HP \(ship.nowhp) -> \(damagedHp)")
145 print("------- End Battle")
148 // 第二艦隊単独出撃で正しくデータが反映されるように逆順にして計算
150 totalDamages.reversed().forEach { damage in
152 let shipId = damage.shipID
153 guard let ship = aStore.sync(execute: { aStore.ship(by: shipId) }) else { return }
155 let damagedHp = damage.hp
156 aStore.sync { ship.nowhp = damagedHp }
158 if damage.useDamageControl { self.removeFirstDamageControl(of: shipId) }
163 func updateBattleCell() {
165 let store = TemporaryDataStore.default
167 guard let battle = store.sync(execute: { store.battle() }) else {
169 return Logger.shared.log("Battle is invalid.")
172 store.sync { battle.battleCell = (battle.no == 0 ? nil : battle.no as NSNumber) }
174 Debug.excute(level: .debug) {
176 print("Enter Cell ------- ")
178 if let seiku = json["api_data"]["api_kouku"]["api_stage1"]["api_disp_seiku"].int {
181 case 0: print("制空権 均衡")
182 case 1: print("制空権 確保")
183 case 2: print("制空権 優勢")
184 case 3: print("制空権 劣勢")
185 case 4: print("制空権 喪失")
190 if let intercept = json["api_data"]["api_formation"][2].int {
193 case 1: print("交戦形態 同航戦")
194 case 2: print("交戦形態 反航戦")
195 case 3: print("交戦形態 T字戦有利")
196 case 4: print("交戦形態 T字戦不利")
203 func removeFirstDamageControl(of shipId: Int) {
205 let store = ServerDataStore.oneTimeEditor()
208 guard let ship = store.ship(by: shipId) else { return }
210 let (item, damageControl) = ship
213 .compactMap { $0 as? SlotItem }
214 .map { ($0, store.masterSlotItemID(by: $0.id)) }
215 .map { ($0.0, DamageControlID(rawValue: $0.1)) }
216 .filter { $0.1 != nil }
219 if let validDamageControl = damageControl {
221 switch validDamageControl {
222 case .damageControl: break
225 ship.fuel = ship.maxFuel
226 ship.bull = ship.maxBull
229 guard let equiped = ship.equippedItem.array as? [SlotItem] else { return }
231 ship.equippedItem = NSOrderedSet(array: equiped.filter { $0 != item })
237 let exItemId = store.sync { store.masterSlotItemID(by: ship.slot_ex) }
239 guard let exType = DamageControlID(rawValue: exItemId) else { return }
242 case .damageControl: break
245 ship.fuel = ship.maxFuel
246 ship.bull = ship.maxBull