OSDN Git Service

objc用のプロパティを削除
[kcd/KCD.git] / KCD / ChangeHenseiCommand.swift
1 //
2 //  ChangeHenseiCommand.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/01/09.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 enum ChangeHenseiType: Int {
12     case append
13     case replace
14     case remove
15     case removeAllWithoutFlagship
16 }
17
18 extension Notification.Name {
19     static let HenseiDidChange = Notification.Name("com.masakih.KCD.Notification.HenseiDidChange")
20 }
21
22 class HenseiDidChangeUserInfo: NSObject {
23     let type: ChangeHenseiType
24     
25     let fleetNumber: Int
26     let position: Int
27     let shipID: Int
28     
29     let replaceFleetNumber: Int?
30     let replacePosition: Int?
31     let replaceShipID: Int?
32     
33     required init(type: ChangeHenseiType,
34                   fleetNumber: Int,
35                   position: Int,
36                   shipID: Int,
37                   replaceFleetNumber: Int? = nil,
38                   replacePosition: Int? = nil,
39                   replaceShipID: Int? = nil) {
40         self.type = type
41         self.fleetNumber = fleetNumber
42         self.position = position
43         self.shipID = shipID
44         self.replaceFleetNumber = replaceFleetNumber
45         self.replacePosition = replacePosition
46         self.replaceShipID = replaceShipID
47         super.init()
48     }
49 }
50
51 class ChangeHenseiCommand: JSONCommand {
52     static let userInfoKey = "HenseiDidChangeUserInfoKey"
53     
54     override class func canExecuteAPI(_ api: String) -> Bool {
55         if api == "/kcsapi/api_req_hensei/change" { return true }
56         return false
57     }
58     
59     // api_ship_id の値
60     // ship_id > 0 : 艦娘のID append or replace
61     // ship_id == -1 : remove.
62     // ship_id == -2 : remove all without flag ship.
63     override func execute() {
64         guard let deckNumber = arguments["api_id"].flatMap({ Int($0) }),
65             let shipId = arguments["api_ship_id"].flatMap({ Int($0) }),
66             let shipIndex = arguments["api_ship_idx"].flatMap({ Int($0) })
67             else { return print("parameter is wrong") }
68         if shipId == -2 {
69             excludeShipsWithoutFlagShip(deckNumber: deckNumber)
70             notify(type: .removeAllWithoutFlagship)
71             return
72         }
73         let store = ServerDataStore.oneTimeEditor()
74         let decks = store.decksSortedById()
75         let shipIds = decks.flatMap { deck in (0..<6).map { deck.shipId(of: $0) ?? -1 } }
76         
77         // すでに編成されているか? どこに?
78         let currentIndex = shipIds.index(of: shipId)
79         let shipDeckNumber = currentIndex.map { $0 / 6 } ?? -1
80         let shipDeckIndex = currentIndex.map { $0 % 6 } ?? -1
81         
82         // 配置しようとする位置に今配置されている艦娘
83         let replaceIndex = (deckNumber - 1) * 6 + shipIndex
84         guard 0..<shipIds.count ~= replaceIndex else { return }
85         let replaceShipId = shipIds[replaceIndex]
86         
87         // 艦隊に配備
88         guard 0..<decks.count ~= (deckNumber - 1) else { return }
89         decks[deckNumber - 1].setShip(id: shipId, for: shipIndex)
90         
91         // 入れ替え
92         if currentIndex != nil, shipId != -1, 0..<decks.count ~= shipDeckNumber {
93             decks[shipDeckNumber].setShip(id: replaceShipId, for: shipDeckIndex)
94         }
95         
96         packFleet(store: store)
97         
98         // Notify
99         if currentIndex != nil, shipId == -1 {
100             notify(type: .remove,
101                    fleetNumber: deckNumber,
102                    position: shipIndex,
103                    shipID: replaceShipId)
104         } else if currentIndex != nil {
105             notify(type: .replace,
106                    fleetNumber: deckNumber,
107                    position: shipIndex,
108                    shipID: shipId,
109                    replaceFleetNumber: shipDeckNumber + 1,
110                    replacePosition: shipDeckIndex,
111                    replaceShipID: replaceShipId)
112         } else {
113             notify(type: .append,
114                    fleetNumber: deckNumber,
115                    position: shipIndex,
116                    shipID: shipId)
117         }
118     }
119     
120     private func excludeShipsWithoutFlagShip(deckNumber: Int) {
121         let store = ServerDataStore.oneTimeEditor()
122         guard let deck = store.deck(byId: deckNumber)
123             else { return print("Deck not found") }
124         (1..<6).forEach { deck.setShip(id: -1, for: $0) }
125     }
126     
127     private func packFleet(store: ServerDataStore) {
128         store.decksSortedById()
129             .forEach { (deck) in
130                 var needsPack = false
131                 (0..<6).forEach {
132                     let shipId = deck.shipId(of: $0)
133                     if (shipId == nil || shipId! == -1) && !needsPack {
134                         needsPack = true
135                         return
136                     }
137                     if needsPack {
138                         deck.setShip(id: shipId!, for: $0 - 1)
139                         if $0 == 5 { deck.setShip(id: -1, for: 5) }
140                     }
141                 }
142         }
143     }
144     
145     private func notify(type: ChangeHenseiType,
146                         fleetNumber: Int = 0,
147                         position: Int = 0,
148                         shipID: Int = 0,
149                         replaceFleetNumber: Int? = nil,
150                         replacePosition: Int? = nil,
151                         replaceShipID: Int? = nil) {
152         let userInfo = HenseiDidChangeUserInfo(type: type,
153                                                fleetNumber: fleetNumber,
154                                                position: position,
155                                                shipID: shipID,
156                                                replaceFleetNumber: replaceFleetNumber,
157                                                replacePosition: replacePosition,
158                                                replaceShipID: replaceShipID)
159         NotificationCenter.default
160             .post(name: .HenseiDidChange,
161                   object: self,
162                   userInfo: [ChangeHenseiCommand.userInfoKey: userInfo])
163     }
164 }