OSDN Git Service

9月29日の更新に対応した
[kcd/KCD.git] / KCD / DocksViewController.swift
1 //
2 //  DocksViewController.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2016/12/25.
6 //  Copyright © 2016年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 final class DocksViewController: MainTabVIewItemViewController {
12     
13     deinit {
14         
15         [NSBindingName(#keyPath(deck2Time)), NSBindingName(#keyPath(mission2Name)),
16          NSBindingName(#keyPath(deck3Time)), NSBindingName(#keyPath(mission3Name)),
17          NSBindingName(#keyPath(deck4Time)), NSBindingName(#keyPath(mission4Name))]
18             .forEach { unbind($0) }
19         [NSBindingName(#keyPath(nDock1Time)), NSBindingName(#keyPath(nDock1ShipName)),
20          NSBindingName(#keyPath(nDock2Time)), NSBindingName(#keyPath(nDock2ShipName)),
21          NSBindingName(#keyPath(nDock3Time)), NSBindingName(#keyPath(nDock3ShipName)),
22          NSBindingName(#keyPath(nDock4Time)), NSBindingName(#keyPath(nDock4ShipName))]
23             .forEach { unbind($0) }
24         [NSBindingName(#keyPath(kDock1Time)), NSBindingName(#keyPath(kDock2Time)),
25          NSBindingName(#keyPath(kDock3Time)), NSBindingName(#keyPath(kDock4Time))]
26             .forEach { unbind($0) }
27         
28         ["selection", "selection.no", "content.battleCell"]
29             .forEach {
30             battleContoller.removeObserver(self, forKeyPath: $0)
31         }
32     }
33     
34     @objc let managedObjectContext = ServerDataStore.default.context
35     @objc let battleManagedObjectController = TemporaryDataStore.default.context
36     let questListViewController = QuestListViewController()
37     
38     let missionStates = (2...4).flatMap { MissionStatus(number: $0) }
39     let ndockStatus = (1...4).flatMap { NyukyoDockStatus(number: $0) }
40     let kdockStatus = (1...4).flatMap { KenzoDockStatus(number: $0) }
41     
42     @objc var nDock1Time: NSNumber?
43     @objc var nDock2Time: NSNumber?
44     @objc var nDock3Time: NSNumber?
45     @objc var nDock4Time: NSNumber?
46     
47     @objc var nDock1ShipName: String?
48     @objc var nDock2ShipName: String?
49     @objc var nDock3ShipName: String?
50     @objc var nDock4ShipName: String?
51     
52     @objc var kDock1Time: NSNumber?
53     @objc var kDock2Time: NSNumber?
54     @objc var kDock3Time: NSNumber?
55     @objc var kDock4Time: NSNumber?
56     
57     @objc var deck2Time: NSNumber?
58     @objc var deck3Time: NSNumber?
59     @objc var deck4Time: NSNumber?
60     
61     @objc var mission2Name: String?
62     @objc var mission3Name: String?
63     @objc var mission4Name: String?
64     
65     @IBOutlet var battleContoller: NSObjectController!
66     @IBOutlet weak var questListViewPlaceholder: NSView!
67     @IBOutlet weak var cellNumberField: NSTextField!
68     
69     override var nibName: NSNib.Name {
70         
71         return .nibName(instanceOf: self)
72     }
73     
74     var battle: Battle? {
75         
76         return TemporaryDataStore.default.battle()
77     }
78     
79     @objc var cellNumber: Int {
80         
81         return battleContoller.value(forKeyPath: "content.no") as? Int ?? 0
82     }
83     
84     var battleCellNumber: Int {
85         
86         return battleContoller.value(forKeyPath: "content.battleCell") as? Int ?? 0
87     }
88     
89     var isBossCell: Bool {
90         
91         return battleContoller.value(forKeyPath: "content.isBossCell") as? Bool ?? false
92     }
93     
94     var fleetName: String? {
95         
96         guard let deckId = battleContoller.value(forKeyPath: "content.deckId") as? Int
97             else { return nil }
98         
99         return ServerDataStore.default.deck(by: deckId)?.name
100     }
101     
102     var areaNumber: String? {
103         
104         let mapArea: String = {
105             
106             guard let mapArea = battleContoller.value(forKeyPath: "content.mapArea") as? Int
107                 else { return "" }
108             
109             if mapArea > 10 { return "E" }
110             
111             return "\(mapArea)"
112         }()
113         
114         guard mapArea != "" else { return nil }
115         
116         guard let mapInfo = battleContoller.value(forKeyPath: "content.mapInfo") as? Int
117             else { return "" }
118         
119         return "\(mapArea)-\(mapInfo)"
120     }
121     
122     var areaName: String? {
123         
124         guard let mapArea = battleContoller.value(forKeyPath: "content.mapArea") as? Int,
125             let mapInfo = battleContoller.value(forKeyPath: "content.mapInfo") as? Int
126             else { return nil }
127         
128         return ServerDataStore.default.mapInfo(area: mapArea, no: mapInfo)?.name
129     }
130     
131     @objc var sortieString: String? {
132         
133         guard let fleetName = self.fleetName,
134             let areaName = self.areaName,
135             let areaNumber = self.areaNumber
136             else { return nil }
137         
138         if battleCellNumber == 0 {
139             
140             let format = NSLocalizedString("%@ in sortie into %@ (%@)", comment: "Sortie")
141             
142             return String(format: format, arguments: [fleetName, areaName, areaNumber])
143         }
144         if isBossCell {
145             
146             let format = NSLocalizedString("%@ battle against the enemy main fleet at %@ war zone in %@ (%@) now", comment: "Sortie")
147             
148             return String(format: format, arguments: [fleetName, battleCellNumber as NSNumber, areaName, areaNumber])
149         }
150         
151         let format = NSLocalizedString("%@ battle at %@ war zone in %@ (%@) now", comment: "Sortie")
152         
153         return String(format: format, arguments: [fleetName, battleCellNumber as NSNumber, areaName, areaNumber])
154     }
155     
156     override func viewDidLoad() {
157         
158         super.viewDidLoad()
159         
160         setupStatus()
161         
162         AppDelegate.shared.addCounterUpdate {
163             
164             self.missionStates.forEach { $0.update() }
165             self.kdockStatus.forEach { $0.update() }
166             self.ndockStatus.forEach { $0.update() }
167         }
168         
169         questListViewController.view.frame = questListViewPlaceholder.frame
170         questListViewController.view.autoresizingMask = questListViewPlaceholder.autoresizingMask
171         questListViewPlaceholder.superview?.replaceSubview(questListViewPlaceholder, with: questListViewController.view)
172         
173         ["selection", "selection.no", "content.battleCell"]
174             .forEach {
175                 battleContoller.addObserver(self, forKeyPath: $0, context: nil)
176         }
177         
178         #if DEBUG
179             cellNumberField.isHidden = false
180         #endif
181     }
182     
183     override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
184         
185         if keyPath == "selection" || keyPath == "content.battleCell" {
186             
187             notifyChangeValue(forKey: #keyPath(sortieString))
188             
189             return
190         }
191         
192         if keyPath == "selection.no" {
193             
194             notifyChangeValue(forKey: #keyPath(cellNumber))
195             
196             return
197         }
198         
199         super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
200     }
201     
202     private func setupStatus() {
203         
204         let missionKeys = [
205             (#keyPath(deck2Time), #keyPath(mission2Name)),
206             (#keyPath(deck3Time), #keyPath(mission3Name)),
207             (#keyPath(deck4Time), #keyPath(mission4Name))
208         ]
209         zip(missionStates, missionKeys).forEach {
210             
211             bind(NSBindingName(rawValue: $0.1.0), to: $0.0, withKeyPath: #keyPath(MissionStatus.time), options: nil)
212             bind(NSBindingName(rawValue: $0.1.1), to: $0.0, withKeyPath: #keyPath(MissionStatus.name), options: nil)
213         }
214         
215         let ndockKeys = [
216             (#keyPath(nDock1Time), #keyPath(nDock1ShipName)),
217             (#keyPath(nDock2Time), #keyPath(nDock2ShipName)),
218             (#keyPath(nDock3Time), #keyPath(nDock3ShipName)),
219             (#keyPath(nDock4Time), #keyPath(nDock4ShipName))
220         ]
221         zip(ndockStatus, ndockKeys).forEach {
222             
223             bind(NSBindingName(rawValue: $0.1.0), to: $0.0, withKeyPath: #keyPath(MissionStatus.time), options: nil)
224             bind(NSBindingName(rawValue: $0.1.1), to: $0.0, withKeyPath: #keyPath(MissionStatus.name), options: nil)
225         }
226         
227         let kdockKeys = [#keyPath(kDock1Time), #keyPath(kDock2Time), #keyPath(kDock3Time), #keyPath(kDock4Time)]
228         zip(kdockStatus, kdockKeys).forEach {
229             
230             bind(NSBindingName(rawValue: $0.1), to: $0.0, withKeyPath: #keyPath(MissionStatus.time), options: nil)
231         }
232     }
233     
234 }