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 return Logger.shared.log("parameter is wrong")
82 excludeShipsWithoutFlagShip(deckNumber: deckNumber)
83 notify(type: .removeAllWithoutFlagship)
88 let store = ServerDataStore.oneTimeEditor()
89 let decks = store.decksSortedById()
90 let shipIds = decks.flatMap { deck in (0..<6).map { deck.shipId(of: $0) ?? -1 } }
93 let currentIndex = shipIds.index(of: shipId)
94 let shipDeckNumber = currentIndex.map { $0 / 6 } ?? -1
95 let shipDeckIndex = currentIndex.map { $0 % 6 } ?? -1
97 // 配置しようとする位置に今配置されている艦娘
98 let replaceIndex = (deckNumber - 1) * 6 + shipIndex
100 guard case 0..<shipIds.count = replaceIndex else { return }
102 let replaceShipId = shipIds[replaceIndex]
105 guard case 0..<decks.count = (deckNumber - 1) else { return }
107 decks[deckNumber - 1].setShip(id: shipId, for: shipIndex)
110 if currentIndex != nil, shipId != -1, case 0..<decks.count = shipDeckNumber {
112 decks[shipDeckNumber].setShip(id: replaceShipId, for: shipDeckIndex)
115 packFleet(store: store)
118 if currentIndex != nil, shipId == -1 {
120 notify(type: .remove,
121 fleetNumber: deckNumber,
123 shipID: replaceShipId)
125 } else if currentIndex != nil {
127 notify(type: .replace,
128 fleetNumber: deckNumber,
131 replaceFleetNumber: shipDeckNumber + 1,
132 replacePosition: shipDeckIndex,
133 replaceShipID: replaceShipId)
137 notify(type: .append,
138 fleetNumber: deckNumber,
144 private func excludeShipsWithoutFlagShip(deckNumber: Int) {
146 let store = ServerDataStore.oneTimeEditor()
148 guard let deck = store.deck(by: deckNumber) else {
150 return Logger.shared.log("Deck not found")
153 (1..<6).forEach { deck.setShip(id: -1, for: $0) }
156 private func packFleet(store: ServerDataStore) {
158 store.decksSortedById()
161 var needsPack = false
164 let shipId = deck.shipId(of: $0)
165 // TODO: うまいことする 強制アンラップを消す
166 if (shipId == nil || shipId! == -1), !needsPack {
174 deck.setShip(id: shipId!, for: $0 - 1)
175 if $0 == 5 { deck.setShip(id: -1, for: 5) }
181 private func notify(type: ChangeHenseiType,
182 fleetNumber: Int = 0,
185 replaceFleetNumber: Int? = nil,
186 replacePosition: Int? = nil,
187 replaceShipID: Int? = nil) {
189 let userInfo = HenseiDidChangeUserInfo(type: type,
190 fleetNumber: fleetNumber,
193 replaceFleetNumber: replaceFleetNumber,
194 replacePosition: replacePosition,
195 replaceShipID: replaceShipID)
196 NotificationCenter.default
197 .post(name: .HenseiDidChange,
199 userInfo: [ChangeHenseiCommand.userInfoKey: userInfo])