OSDN Git Service

関数名を変更
[kcd/KCD.git] / KCD / Ship.swift
1 //
2 //  [
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/01/29.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 // swiftlint:disable variable_name
12 final class Ship: KCManagedObject {
13     
14     @NSManaged dynamic var bull: Int
15     @NSManaged dynamic var cond: Int
16     @NSManaged dynamic var exp: Int
17     @NSManaged dynamic var fleet: NSNumber?
18     @NSManaged dynamic var fuel: Int
19     @NSManaged dynamic var id: Int
20     @NSManaged dynamic var kaihi_0: Int
21     @NSManaged dynamic var kaihi_1: NSNumber?
22     @NSManaged dynamic var karyoku_0: Int
23     @NSManaged dynamic var karyoku_1: Int
24     @NSManaged dynamic var kyouka_0: Int
25     @NSManaged dynamic var kyouka_1: Int
26     @NSManaged dynamic var kyouka_2: Int
27     @NSManaged dynamic var kyouka_3: Int
28     @NSManaged dynamic var kyouka_4: Int
29     @NSManaged dynamic var locked: Int
30     @NSManaged dynamic var locked_equip: NSNumber?
31     @NSManaged dynamic var lucky_0: Int
32     @NSManaged dynamic var lucky_1: Int
33     @NSManaged dynamic var lv: Int
34     @NSManaged dynamic var maxhp: Int
35     @NSManaged dynamic var ndock_time: NSNumber?
36     @NSManaged dynamic var nowhp: Int
37     @NSManaged dynamic var onslot_0: Int
38     @NSManaged dynamic var onslot_1: Int
39     @NSManaged dynamic var onslot_2: Int
40     @NSManaged dynamic var onslot_3: Int
41     @NSManaged dynamic var onslot_4: Int
42     @NSManaged dynamic var raisou_0: Int
43     @NSManaged dynamic var raisou_1: Int
44     @NSManaged dynamic var sakuteki_0: Int
45     @NSManaged dynamic var sakuteki_1: NSNumber?
46     @NSManaged dynamic var sally_area: NSNumber?
47     @NSManaged dynamic var ship_id: Int
48     @NSManaged dynamic var slot_0: Int
49     @NSManaged dynamic var slot_1: Int
50     @NSManaged dynamic var slot_2: Int
51     @NSManaged dynamic var slot_3: Int
52     @NSManaged dynamic var slot_4: Int
53     @NSManaged dynamic var slot_ex: Int
54     @NSManaged dynamic var sortno: NSNumber?
55     @NSManaged dynamic var soukou_0: Int
56     @NSManaged dynamic var soukou_1: Int
57     @NSManaged dynamic var srate: NSNumber?
58     @NSManaged dynamic var taiku_0: Int
59     @NSManaged dynamic var taiku_1: Int
60     @NSManaged dynamic var taisen_0: Int
61     @NSManaged dynamic var taisen_1: NSNumber?
62     @NSManaged dynamic var equippedItem: NSOrderedSet
63     @NSManaged dynamic var master_ship: MasterShip
64     @NSManaged dynamic var extraItem: SlotItem?
65 }
66 // swiftlint:eable variable_name
67
68 private let shortSTypeNames: [String] = {
69     
70     guard let url = Bundle.main.url(forResource: "STypeShortName", withExtension: "plist"),
71         let array = NSArray(contentsOf: url) as? [String] else {
72             
73             return Logger.shared.log("Can not load STypeShortName.plist.", value: [])
74     }
75     
76     return array
77 }()
78
79 private let levelUpExps: [Int] = {
80     
81     guard let url = Bundle.main.url(forResource: "LevelUpExp", withExtension: "plist"),
82         let array = NSArray(contentsOf: url) as? [Int] else {
83             
84             return Logger.shared.log("Can not load LevelUpExp.plist.", value: [])
85     }
86     
87     return array
88 }()
89
90 extension Ship {
91     
92     @objc override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
93         
94         switch key {
95             
96         case #keyPath(name): return [#keyPath(ship_id)]
97             
98         case #keyPath(shortTypeName): return [#keyPath(ship_id)]
99             
100         case #keyPath(next): return [#keyPath(exp)]
101             
102         case #keyPath(status): return [#keyPath(nowhp), #keyPath(maxhp)]
103         
104         case #keyPath(planColor): return [#keyPath(sally_area)]
105             
106         case #keyPath(isMaxKaryoku): return [#keyPath(karyoku_1), #keyPath(kyouka_0)]
107             
108         case #keyPath(isMaxRaisou): return [#keyPath(raisou_1), #keyPath(kyouka_1)]
109             
110         case #keyPath(isMaxTaiku): return [#keyPath(taiku_1), #keyPath(kyouka_2)]
111             
112         case #keyPath(isMaxSoukou): return [#keyPath(soukou_1), #keyPath(kyouka_3)]
113             
114         case #keyPath(isMaxLucky): return [#keyPath(lucky_1), #keyPath(kyouka_4)]
115             
116         case #keyPath(upgradeLevel): return [#keyPath(ship_id)]
117             
118         case #keyPath(upgradeExp): return [#keyPath(exp)]
119             
120         case #keyPath(steelRequiredInRepair): return [#keyPath(nowhp)]
121             
122         case #keyPath(fuelRequiredInRepair): return [#keyPath(nowhp)]
123             
124         case #keyPath(seiku): return [#keyPath(slot_0), #keyPath(slot_1), #keyPath(slot_2), #keyPath(slot_3), #keyPath(slot_4),
125                                       #keyPath(onslot_0), #keyPath(onslot_1), #keyPath(onslot_2), #keyPath(onslot_3), #keyPath(onslot_4)]
126             
127         default: return []
128             
129         }
130     }
131     
132     @objc dynamic var name: String { return master_ship.name }
133     
134     @objc dynamic var shortTypeName: String? {
135         
136         let index = master_ship.stype.id - 1
137         
138         guard case 0..<shortSTypeNames.count = index else { return nil }
139         
140         return shortSTypeNames[index]
141     }
142     
143     @objc dynamic var next: NSNumber? {
144         
145         guard case 0..<levelUpExps.count = lv else { return nil }
146         
147         if lv == 99 { return nil }
148         
149         let nextExp = levelUpExps[lv]
150         
151         if lv < 99 { return (nextExp - exp) as NSNumber }
152         
153         return (1_000_000 + nextExp - exp) as NSNumber
154     }
155     
156     @objc dynamic var status: Int {
157         
158         let stat = Double(nowhp) / Double(maxhp)
159         
160         if stat <= 0.25 { return 3 }
161         if stat <= 0.5 { return 2 }
162         if stat <= 0.75 { return 1 }
163         
164         return 0
165     }
166     
167     @objc dynamic var planColor: NSColor {
168         
169         if !UserDefaults.standard[.showsPlanColor] { return .controlTextColor }
170         
171         guard let sally = sally_area else { return .controlTextColor }
172         
173         switch sally {
174         case 1: return UserDefaults.standard[.plan01Color]
175         case 2: return UserDefaults.standard[.plan02Color]
176         case 3: return UserDefaults.standard[.plan03Color]
177         case 4: return UserDefaults.standard[.plan04Color]
178         case 5: return UserDefaults.standard[.plan05Color]
179         case 6: return UserDefaults.standard[.plan06Color]
180         default: return .controlTextColor
181         }
182     }
183 }
184
185
186 extension Ship {
187     
188     @objc dynamic var maxBull: Int { return master_ship.bull_max }
189     @objc dynamic var maxFuel: Int { return master_ship.fuel_max }
190     
191     @objc dynamic var isMaxKaryoku: Bool {
192         
193         let initial = master_ship.houg_0
194         let max = karyoku_1
195         let growth = kyouka_0
196         
197         return initial + growth >= max
198     }
199     
200     @objc dynamic var isMaxRaisou: Bool {
201         
202         let initial = master_ship.raig_0
203         let max = raisou_1
204         let growth = kyouka_1
205         
206         return initial + growth >= max
207     }
208     
209     @objc dynamic var isMaxTaiku: Bool {
210         
211         let initial = master_ship.tyku_0
212         let max = taiku_1
213         let growth = kyouka_2
214         
215         return initial + growth >= max
216     }
217     
218     @objc dynamic var isMaxSoukou: Bool {
219         
220         let initial = master_ship.souk_0
221         let max = soukou_1
222         let growth = kyouka_3
223         
224         return initial + growth >= max
225     }
226     
227     @objc dynamic var isMaxLucky: Bool {
228         
229         let initial = master_ship.luck_0
230         let max = lucky_1
231         let growth = kyouka_4
232         
233         return initial + growth >= max
234     }
235     
236     @objc dynamic var upgradeLevel: Int { return master_ship.afterlv }
237     
238     @objc dynamic var upgradeExp: NSNumber? {
239         
240         let upgradeLv = upgradeLevel
241         
242         if upgradeLv <= 0 { return nil }
243         if levelUpExps.count < upgradeLv { return nil }
244         
245         let upExp = levelUpExps[upgradeLv - 1] - exp
246         
247         return upExp < 0 ? 0 : upExp as NSNumber
248     }
249     
250     @objc dynamic var guardEscaped: Bool {
251         
252         let store = TemporaryDataStore.default
253         
254         guard let _ = store.ensuredGuardEscaped(byShipId: id) else { return false }
255         
256         return true
257     }
258     
259     @objc dynamic var steelRequiredInRepair: Int {
260         
261         return Int(Double(maxFuel) * 0.06 * Double(maxhp - nowhp))
262     }
263     
264     @objc dynamic var fuelRequiredInRepair: Int {
265         
266         return Int(Double(maxFuel) * 0.032 * Double(maxhp - nowhp))
267     }
268 }
269
270 extension Ship {
271     
272     func setItem(_ id: Int, to slot: Int) {
273         
274         switch slot {
275         case 0: slot_0 = id
276         case 1: slot_1 = id
277         case 2: slot_2 = id
278         case 3: slot_3 = id
279         case 4: slot_4 = id
280         default: fatalError("Ship: setItem out of bounds.")
281         }
282     }
283     
284     func slotItemId(_ index: Int) -> Int {
285         
286         switch index {
287         case 0: return slot_0
288         case 1: return slot_1
289         case 2: return slot_2
290         case 3: return slot_3
291         case 4: return slot_4
292         default: return 0
293         }
294     }
295     
296     func slotItemCount(_ index: Int) -> Int {
297         
298         switch index {
299         case 0: return onslot_0
300         case 1: return onslot_1
301         case 2: return onslot_2
302         case 3: return onslot_3
303         case 4: return onslot_4
304         default: return 0
305         }
306     }
307     
308     func slotItemMax(_ index: Int) -> Int {
309         
310         switch index {
311         case 0: return master_ship.maxeq_0
312         case 1: return master_ship.maxeq_1
313         case 2: return master_ship.maxeq_2
314         case 3: return master_ship.maxeq_3
315         case 4: return master_ship.maxeq_4
316         default: return 0
317         }
318     }
319     
320     func slotItem(_ index: Int) -> SlotItem? {
321         
322         return ServerDataStore.default.slotItem(by: slotItemId(index))
323     }
324     
325     @objc dynamic var totalEquipment: Int {
326         
327         return (0...4).map(slotItemMax).reduce(0, +)
328     }
329     
330     @objc dynamic var seiku: Int {
331         
332         return SeikuCalclator(ship: self).seiku
333     }
334     
335 }