OSDN Git Service

バージョンを1.9b33に更新
[kcd/KCD.git] / KCD / CalculateDamageCommand.swift
1 //
2 //  CalculateDamageCommand.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/01/15.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10 import SwiftyJSON
11
12 enum BattleType {
13     
14     case normal
15     case combinedAir
16     case combinedWater
17     case eachCombinedAir
18     case eachCombinedWater
19     case enemyCombined
20 }
21
22 enum DamageControlID: Int {
23     
24     case damageControl = 42
25     case goddes = 43
26 }
27
28 final class CalculateDamageCommand: JSONCommand {
29     
30     override func execute() {
31         
32         guard let battleApi = BattleAPI(rawValue: api) else { return }
33         
34         switch battleApi {
35         case .battle, .airBattle, .ldAirBattle:
36             normalBattle(battleType: .normal)
37             
38         case .combinedEcBattle:
39             enemyCombinedBattle(battleType: .enemyCombined)
40             
41         case .combinedBattle, .combinedAirBattle:
42             combinedAirBattle(battleType: .combinedAir)
43             
44         case .combinedBattleWater, .combinedLdAirBattle:
45             normalBattle(battleType: .combinedWater)
46             
47         case .combinedEachBattle:
48             eachAirBattle(battleType: .eachCombinedAir)
49             
50         case .combinedEachBattleWater:
51             normalBattle(battleType: .eachCombinedWater)
52             
53         case .combinedEachNightToDay:
54             eachNightToDayBattle(battleType: .normal)
55             
56         case .midnightBattle, .midnightSpMidnight:
57             midnightBattle(battleType: .normal)
58             
59         case .combinedMidnightBattle, .combinedSpMidnight:
60             midnightBattle(battleType: .combinedAir)
61             
62         case .combinedEcMidnightBattle:
63             midnightBattle(battleType: .eachCombinedAir)
64             
65         case .battleResult, .combinedBattleResult:
66             applyDamage()
67             resetDamage()
68         }
69     }
70     
71     func normalBattle(battleType: BattleType) {
72         
73         updateBattleCell()
74         DamageCalculator(json, battleType).calculateBattle()
75     }
76     
77     func combinedAirBattle(battleType: BattleType) {
78         
79         updateBattleCell()
80         DamageCalculator(json, battleType).calcCombinedBattleAir()
81     }
82     
83     func eachAirBattle(battleType: BattleType) {
84         
85         updateBattleCell()
86         DamageCalculator(json, battleType).calcEachBattleAir()
87     }
88     
89     func eachNightToDayBattle(battleType: BattleType) {
90         
91         updateBattleCell()
92         DamageCalculator(json, battleType).calcEachNightToDay()
93     }
94     
95     func enemyCombinedBattle(battleType: BattleType) {
96         
97         updateBattleCell()
98         DamageCalculator(json, battleType).calcEnemyCombinedBattle()
99     }
100     
101     func midnightBattle(battleType: BattleType) {
102         
103         DamageCalculator(json, battleType).calcMidnight()
104     }
105 }
106
107 extension CalculateDamageCommand {
108     
109     func resetDamage() {
110         
111         let store = TemporaryDataStore.oneTimeEditor()
112         
113         store.damages().forEach(store.delete)
114     }
115     
116     func applyDamage() {
117         
118         let store = TemporaryDataStore.oneTimeEditor()
119         
120         let totalDamages = store.sortedDamagesById()
121         
122         let aStore = ServerDataStore.oneTimeEditor()
123         
124         Debug.excute(level: .debug) {
125             
126             print("-------")
127             
128             totalDamages.forEach {
129                 
130                 guard let ship = aStore.ship(by: $0.shipID) else { return }
131                 
132                 if ship.nowhp != $0.hp {
133                     
134                     print("\(ship.name)(\(ship.id)),HP \(ship.nowhp) -> \($0.hp)")
135                 }
136             }
137             
138             
139             print("------- End Battle")
140         }
141         
142         // 第二艦隊単独出撃で正しくデータが反映されるように逆順にして計算
143         totalDamages.reversed().forEach {
144             
145             guard let ship = aStore.ship(by: $0.shipID) else { return }
146             
147             ship.nowhp = $0.hp
148             
149             if $0.useDamageControl { removeFirstDamageControl(of: ship) }
150         }
151         
152     }
153     
154     func updateBattleCell() {
155         
156         let store = TemporaryDataStore.default
157         
158         guard let battle = store.battle() else { return Logger.shared.log("Battle is invalid.") }
159         
160         battle.battleCell = (battle.no == 0 ? nil : battle.no as NSNumber)
161         
162         Debug.excute(level: .debug) {
163             
164             print("Enter Cell ------- ")
165             
166             if let seiku = json["api_data"]["api_kouku"]["api_stage1"]["api_disp_seiku"].int {
167                 
168                 switch seiku {
169                 case 0: print("制空権 均衡")
170                 case 1: print("制空権 確保")
171                 case 2: print("制空権 優勢")
172                 case 3: print("制空権 劣勢")
173                 case 4: print("制空権 喪失")
174                 default: break
175                 }
176             }
177             
178             if let intercept = json["api_data"]["api_formation"][2].int {
179                 
180                 switch intercept {
181                 case 1: print("交戦形態 同航戦")
182                 case 2: print("交戦形態 反航戦")
183                 case 3: print("交戦形態 T字戦有利")
184                 case 4: print("交戦形態 T字戦不利")
185                 default: break
186                 }
187             }
188         }
189     }
190     
191     func removeFirstDamageControl(of ship: Ship) {
192         
193         let store = ServerDataStore.default
194         
195         let (item, damageControl) = ship
196             .equippedItem
197             .lazy
198             .flatMap { $0 as? SlotItem }
199             .map { ($0, store.masterSlotItemID(by: $0.id)) }
200             .map { ($0.0, DamageControlID(rawValue: $0.1)) }
201             .filter { $0.1 != nil }
202             .first ?? (nil, nil)
203         
204         if let validDamageControl = damageControl {
205             
206             switch validDamageControl {
207             case .damageControl: break
208                 
209             case .goddes:
210                 ship.fuel = ship.maxFuel
211                 ship.bull = ship.maxBull
212             }
213             
214             guard let equiped = ship.equippedItem.array as? [SlotItem] else { return }
215                 
216             ship.equippedItem = NSOrderedSet(array: equiped.filter { $0 != item })
217             
218             return
219         }
220         
221         // check extra slot
222         let exItemId = store.masterSlotItemID(by: ship.slot_ex)
223         
224         guard let exType = DamageControlID(rawValue: exItemId) else { return }
225         
226         switch exType {
227         case .damageControl: break
228             
229         case .goddes:
230             ship.fuel = ship.maxFuel
231             ship.bull = ship.maxBull
232         }
233         
234         ship.slot_ex = -1
235     }
236 }