2 // ChangeHenseiCommand.swift
5 // Created by Hori,Masaki on 2017/01/09.
6 // Copyright © 2017年 Hori,Masaki. All rights reserved.
11 enum ChangeHenseiType: Int {
16 case removeAllWithoutFlagship
19 extension Notification.Name {
21 static let HenseiDidChange = Notification.Name("com.masakih.KCD.Notification.HenseiDidChange")
24 final class HenseiDidChangeUserInfo: NSObject {
26 let type: ChangeHenseiType
32 let replaceFleetNumber: Int?
33 let replacePosition: Int?
34 let replaceShipID: Int?
36 required init(type: ChangeHenseiType,
40 replaceFleetNumber: Int? = nil,
41 replacePosition: Int? = nil,
42 replaceShipID: Int? = nil) {
45 self.fleetNumber = fleetNumber
46 self.position = position
48 self.replaceFleetNumber = replaceFleetNumber
49 self.replacePosition = replacePosition
50 self.replaceShipID = replaceShipID
56 final class ChangeHenseiCommand: JSONCommand {
58 static let userInfoKey = "HenseiDidChangeUserInfoKey"
60 override class func canExecuteAPI(_ api: String) -> Bool {
62 if api == "/kcsapi/api_req_hensei/change" { return true }
68 // ship_id > 0 : 艦娘のID append or replace
69 // ship_id == -1 : remove.
70 // ship_id == -2 : remove all without flag ship.
71 override func execute() {
73 guard let deckNumber = parameter["api_id"].int,
74 let shipId = parameter["api_ship_id"].int,
75 let shipIndex = parameter["api_ship_idx"].int else {
77 print("parameter is wrong")
83 excludeShipsWithoutFlagShip(deckNumber: deckNumber)
84 notify(type: .removeAllWithoutFlagship)
89 let store = ServerDataStore.oneTimeEditor()
90 let decks = store.decksSortedById()
91 let shipIds = decks.flatMap { deck in (0..<6).map { deck.shipId(of: $0) ?? -1 } }
94 let currentIndex = shipIds.index(of: shipId)
95 let shipDeckNumber = currentIndex.map { $0 / 6 } ?? -1
96 let shipDeckIndex = currentIndex.map { $0 % 6 } ?? -1
98 // 配置しようとする位置に今配置されている艦娘
99 let replaceIndex = (deckNumber - 1) * 6 + shipIndex
101 guard case 0..<shipIds.count = replaceIndex else { return }
103 let replaceShipId = shipIds[replaceIndex]
106 guard case 0..<decks.count = (deckNumber - 1) else { return }
108 decks[deckNumber - 1].setShip(id: shipId, for: shipIndex)
111 if currentIndex != nil, shipId != -1, case 0..<decks.count = shipDeckNumber {
113 decks[shipDeckNumber].setShip(id: replaceShipId, for: shipDeckIndex)
116 packFleet(store: store)
119 if currentIndex != nil, shipId == -1 {
121 notify(type: .remove,
122 fleetNumber: deckNumber,
124 shipID: replaceShipId)
126 } else if currentIndex != nil {
128 notify(type: .replace,
129 fleetNumber: deckNumber,
132 replaceFleetNumber: shipDeckNumber + 1,
133 replacePosition: shipDeckIndex,
134 replaceShipID: replaceShipId)
138 notify(type: .append,
139 fleetNumber: deckNumber,
145 private func excludeShipsWithoutFlagShip(deckNumber: Int) {
147 let store = ServerDataStore.oneTimeEditor()
149 guard let deck = store.deck(by: deckNumber) else {
151 print("Deck not found")
155 (1..<6).forEach { deck.setShip(id: -1, for: $0) }
158 private func packFleet(store: ServerDataStore) {
160 store.decksSortedById()
163 var needsPack = false
166 let shipId = deck.shipId(of: $0)
167 // TODO: うまいことする 強制アンラップを消す
168 if (shipId == nil || shipId! == -1), !needsPack {
176 deck.setShip(id: shipId!, for: $0 - 1)
177 if $0 == 5 { deck.setShip(id: -1, for: 5) }
183 private func notify(type: ChangeHenseiType,
184 fleetNumber: Int = 0,
187 replaceFleetNumber: Int? = nil,
188 replacePosition: Int? = nil,
189 replaceShipID: Int? = nil) {
191 let userInfo = HenseiDidChangeUserInfo(type: type,
192 fleetNumber: fleetNumber,
195 replaceFleetNumber: replaceFleetNumber,
196 replacePosition: replacePosition,
197 replaceShipID: replaceShipID)
198 NotificationCenter.default
199 .post(name: .HenseiDidChange,
201 userInfo: [ChangeHenseiCommand.userInfoKey: userInfo])