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 ships = deck[0..<Deck.maxShipCount]
163 (0..<Deck.maxShipCount).forEach {
165 let shipId = ships.first?.id ?? -1
166 deck.setShip(id: shipId, for: $0)
167 if !ships.isEmpty { ships.removeFirst() }
172 private func notify(type: ChangeHenseiType,
173 fleetNumber: Int = 0,
176 replaceFleetNumber: Int? = nil,
177 replacePosition: Int? = nil,
178 replaceShipID: Int? = nil) {
180 let userInfo = HenseiDidChangeUserInfo(type: type,
181 fleetNumber: fleetNumber,
184 replaceFleetNumber: replaceFleetNumber,
185 replacePosition: replacePosition,
186 replaceShipID: replaceShipID)
187 NotificationCenter.default
188 .post(name: .HenseiDidChange,
190 userInfo: [ChangeHenseiCommand.userInfoKey: userInfo])