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             print("Can not load STypeShortName.plist.")
74             return []
75     }
76     
77     return array
78 }()
79
80 private let levelUpExps: [Int] = {
81     
82     guard let url = Bundle.main.url(forResource: "LevelUpExp", withExtension: "plist"),
83         let array = NSArray(contentsOf: url) as? [Int] else {
84             
85             print("Can not load LevelUpExp.plist.")
86             return []
87     }
88     
89     return array
90 }()
91
92 extension Ship {
93     
94     @objc override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
95         
96         switch key {
97             
98         case #keyPath(name): return [#keyPath(ship_id)]
99             
100         case #keyPath(shortTypeName): return [#keyPath(ship_id)]
101             
102         case #keyPath(next): return [#keyPath(exp)]
103             
104         case #keyPath(status): return [#keyPath(nowhp), #keyPath(maxhp)]
105         
106         case #keyPath(planColor): return [#keyPath(sally_area)]
107             
108         case #keyPath(isMaxKaryoku): return [#keyPath(karyoku_1), #keyPath(kyouka_0)]
109             
110         case #keyPath(isMaxRaisou): return [#keyPath(raisou_1), #keyPath(kyouka_1)]
111             
112         case #keyPath(isMaxTaiku): return [#keyPath(taiku_1), #keyPath(kyouka_2)]
113             
114         case #keyPath(isMaxSoukou): return [#keyPath(soukou_1), #keyPath(kyouka_3)]
115             
116         case #keyPath(isMaxLucky): return [#keyPath(lucky_1), #keyPath(kyouka_4)]
117             
118         case #keyPath(upgradeLevel): return [#keyPath(ship_id)]
119             
120         case #keyPath(upgradeExp): return [#keyPath(exp)]
121             
122         case #keyPath(steelRequiredInRepair): return [#keyPath(nowhp)]
123             
124         case #keyPath(fuelRequiredInRepair): return [#keyPath(nowhp)]
125             
126         case #keyPath(seiku): return [#keyPath(slot_0), #keyPath(slot_1), #keyPath(slot_2), #keyPath(slot_3), #keyPath(slot_4),
127                                       #keyPath(onslot_0), #keyPath(onslot_1), #keyPath(onslot_2), #keyPath(onslot_3), #keyPath(onslot_4)]
128             
129         default: return []
130             
131         }
132     }
133     
134     @objc dynamic var name: String { return master_ship.name }
135     
136     @objc dynamic var shortTypeName: String? {
137         
138         let index = master_ship.stype.id - 1
139         
140         guard case 0..<shortSTypeNames.count = index else { return nil }
141         
142         return shortSTypeNames[index]
143     }
144     
145     @objc dynamic var next: NSNumber? {
146         
147         guard case 0..<levelUpExps.count = lv else { return nil }
148         
149         if lv == 99 { return nil }
150         
151         let nextExp = levelUpExps[lv]
152         
153         if lv < 99 { return (nextExp - exp) as NSNumber }
154         
155         return (1_000_000 + nextExp - exp) as NSNumber
156     }
157     
158     @objc dynamic var status: Int {
159         
160         let stat = Double(nowhp) / Double(maxhp)
161         
162         if stat <= 0.25 { return 3 }
163         if stat <= 0.5 { return 2 }
164         if stat <= 0.75 { return 1 }
165         
166         return 0
167     }
168     
169     @objc dynamic var planColor: NSColor {
170         
171         if !UserDefaults.standard[.showsPlanColor] { return NSColor.controlTextColor }
172         
173         guard let sally = sally_area else { return .controlTextColor }
174         
175         switch sally {
176         case 1: return UserDefaults.standard[.plan01Color]
177         case 2: return UserDefaults.standard[.plan02Color]
178         case 3: return UserDefaults.standard[.plan03Color]
179         case 4: return UserDefaults.standard[.plan04Color]
180         case 5: return UserDefaults.standard[.plan05Color]
181         case 6: return UserDefaults.standard[.plan06Color]
182         default: return .controlTextColor
183         }
184     }
185 }
186
187
188 extension Ship {
189     
190     @objc dynamic var maxBull: Int { return master_ship.bull_max }
191     @objc dynamic var maxFuel: Int { return master_ship.fuel_max }
192     
193     @objc dynamic var isMaxKaryoku: Bool {
194         
195         let initial = master_ship.houg_0
196         let max = karyoku_1
197         let growth = kyouka_0
198         
199         return initial + growth >= max
200     }
201     
202     @objc dynamic var isMaxRaisou: Bool {
203         
204         let initial = master_ship.raig_0
205         let max = raisou_1
206         let growth = kyouka_1
207         
208         return initial + growth >= max
209     }
210     
211     @objc dynamic var isMaxTaiku: Bool {
212         
213         let initial = master_ship.tyku_0
214         let max = taiku_1
215         let growth = kyouka_2
216         
217         return initial + growth >= max
218     }
219     
220     @objc dynamic var isMaxSoukou: Bool {
221         
222         let initial = master_ship.souk_0
223         let max = soukou_1
224         let growth = kyouka_3
225         
226         return initial + growth >= max
227     }
228     
229     @objc dynamic var isMaxLucky: Bool {
230         
231         let initial = master_ship.luck_0
232         let max = lucky_1
233         let growth = kyouka_4
234         
235         return initial + growth >= max
236     }
237     
238     @objc dynamic var upgradeLevel: Int { return master_ship.afterlv }
239     
240     @objc dynamic var upgradeExp: NSNumber? {
241         
242         let upgradeLv = upgradeLevel
243         
244         if upgradeLv <= 0 { return nil }
245         if levelUpExps.count < upgradeLv { return nil }
246         
247         let upExp = levelUpExps[upgradeLv - 1] - exp
248         
249         return upExp < 0 ? 0 : upExp as NSNumber
250     }
251     
252     @objc dynamic var guardEscaped: Bool {
253         
254         let store = TemporaryDataStore.default
255         
256         guard let _ = store.ensuredGuardEscaped(byShipId: id) else { return false }
257         
258         return true
259     }
260     
261     @objc dynamic var steelRequiredInRepair: Int {
262         
263         return Int(Double(maxFuel) * 0.06 * Double(maxhp - nowhp))
264     }
265     
266     @objc dynamic var fuelRequiredInRepair: Int {
267         
268         return Int(Double(maxFuel) * 0.032 * Double(maxhp - nowhp))
269     }
270 }
271
272 extension Ship {
273     
274     func setItem(_ id: Int, to slot: Int) {
275         
276         switch slot {
277         case 0: slot_0 = id
278         case 1: slot_1 = id
279         case 2: slot_2 = id
280         case 3: slot_3 = id
281         case 4: slot_4 = id
282         default: fatalError("Ship: setItem out of bounds.")
283         }
284     }
285     
286     func slotItemId(_ index: Int) -> Int {
287         
288         switch index {
289         case 0: return slot_0
290         case 1: return slot_1
291         case 2: return slot_2
292         case 3: return slot_3
293         case 4: return slot_4
294         default: return 0
295         }
296     }
297     
298     func slotItemCount(_ index: Int) -> Int {
299         
300         switch index {
301         case 0: return onslot_0
302         case 1: return onslot_1
303         case 2: return onslot_2
304         case 3: return onslot_3
305         case 4: return onslot_4
306         default: return 0
307         }
308     }
309     
310     func slotItemMax(_ index: Int) -> Int {
311         
312         switch index {
313         case 0: return master_ship.maxeq_0
314         case 1: return master_ship.maxeq_1
315         case 2: return master_ship.maxeq_2
316         case 3: return master_ship.maxeq_3
317         case 4: return master_ship.maxeq_4
318         default: return 0
319         }
320     }
321     
322     func slotItem(_ index: Int) -> SlotItem? {
323         
324         return ServerDataStore.default.slotItem(by: slotItemId(index))
325     }
326     
327     @objc dynamic var totalEquipment: Int {
328         
329         return (0...4).map(slotItemMax).reduce(0, +)
330     }
331     
332     @objc dynamic var seiku: Int {
333         
334         return SeikuCalclator(ship: self).seiku
335     }
336     
337 }