OSDN Git Service

スクリーンショットリストが真っ白になってしまう問題を修正
[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 .midnightBattle, .midnightSpMidnight:
54             midnightBattle(battleType: .normal)
55             
56         case .combinedMidnightBattle, .combinedSpMidnight:
57             midnightBattle(battleType: .combinedAir)
58             
59         case .combinedEcMidnightBattle:
60             midnightBattle(battleType: .eachCombinedAir)
61             
62         case .battleResult, .combinedBattleResult:
63             applyDamage()
64             resetDamage()
65         }
66     }
67     
68     func normalBattle(battleType: BattleType) {
69         
70         updateBattleCell()
71         DamageCalculator(json, battleType).calculateBattle()
72     }
73     
74     func combinedAirBattle(battleType: BattleType) {
75         
76         updateBattleCell()
77         DamageCalculator(json, battleType).calcCombinedBattleAir()
78     }
79     
80     func eachAirBattle(battleType: BattleType) {
81         
82         updateBattleCell()
83         DamageCalculator(json, battleType).calcEachBattleAir()
84     }
85     
86     func enemyCombinedBattle(battleType: BattleType) {
87         
88         updateBattleCell()
89         DamageCalculator(json, battleType).calcEnemyCombinedBattle()
90     }
91     
92     func midnightBattle(battleType: BattleType) {
93         
94         DamageCalculator(json, battleType).calcMidnight()
95     }
96 }
97
98 extension CalculateDamageCommand {
99     
100     func resetDamage() {
101         
102         let store = TemporaryDataStore.oneTimeEditor()
103         
104         store.damages().forEach(store.delete)
105     }
106     
107     func applyDamage() {
108         
109         let store = TemporaryDataStore.oneTimeEditor()
110         
111         let totalDamages = store.sortedDamagesById()
112         
113         guard totalDamages.count == 12 else {
114             
115             return Logger.shared.log("Damages count is invalid. count is \(totalDamages.count).")
116         }
117         
118         let aStore = ServerDataStore.oneTimeEditor()
119         
120         // 第二艦隊単独出撃で正しくデータが反映されるように逆順にして計算
121         totalDamages.reversed().forEach {
122             
123             guard let ship = aStore.ship(by: $0.shipID) else { return }
124             
125             if ship.nowhp != $0.hp {
126                 
127                 Debug.print("\(ship.name)(\(ship.id)),HP \(ship.nowhp) -> \($0.hp)", level: .debug)
128             }
129             
130             ship.nowhp = $0.hp
131             
132             if $0.useDamageControl { removeFirstDamageControl(of: ship) }
133         }
134         
135         Debug.print("------- End Battle", level: .debug)
136     }
137     
138     func updateBattleCell() {
139         
140         let store = TemporaryDataStore.default
141         
142         guard let battle = store.battle() else {
143             
144             return Logger.shared.log("Battle is invalid.")
145         }
146         
147         battle.battleCell = (battle.no == 0 ? nil : battle.no as NSNumber)
148         
149         Debug.excute(level: .debug) {
150             
151             print("Enter Cell ------- ")
152             
153             if let seiku = json["api_data"]["api_kouku"]["api_stage1"]["api_disp_seiku"].int {
154                 
155                 switch seiku {
156                 case 0: print("制空権 均衡")
157                 case 1: print("制空権 確保")
158                 case 2: print("制空権 優勢")
159                 case 3: print("制空権 劣勢")
160                 case 4: print("制空権 喪失")
161                 default: break
162                 }
163             }
164             
165             if let intercept = json["api_data"]["api_formation"][2].int {
166                 
167                 switch intercept {
168                 case 1: print("交戦形態 同航戦")
169                 case 2: print("交戦形態 反航戦")
170                 case 3: print("交戦形態 T字戦有利")
171                 case 4: print("交戦形態 T字戦不利")
172                 default: break
173                 }
174             }
175         }
176     }
177     
178     func removeFirstDamageControl(of ship: Ship) {
179         
180         let store = ServerDataStore.default
181         
182         let (item, damageControl) = ship
183             .equippedItem
184             .lazy
185             .flatMap { $0 as? SlotItem }
186             .map { ($0, store.masterSlotItemID(by: $0.id)) }
187             .map { ($0.0, DamageControlID(rawValue: $0.1)) }
188             .filter { $0.1 != nil }
189             .first ?? (nil, nil)
190         
191         if let validDamageControl = damageControl {
192             
193             switch validDamageControl {
194             case .damageControl: break
195                 
196             case .goddes:
197                 ship.fuel = ship.maxFuel
198                 ship.bull = ship.maxBull
199             }
200             
201             guard let equiped = ship.equippedItem.array as? [SlotItem] else { return }
202                 
203             ship.equippedItem = NSOrderedSet(array: equiped.filter { $0 != item })
204             
205             return
206         }
207         
208         // check extra slot
209         let exItemId = store.masterSlotItemID(by: ship.slot_ex)
210         
211         guard let exType = DamageControlID(rawValue: exItemId) else { return }
212         
213         switch exType {
214         case .damageControl: break
215             
216         case .goddes:
217             ship.fuel = ship.maxFuel
218             ship.bull = ship.maxBull
219         }
220         
221         ship.slot_ex = -1
222     }
223 }