}
// swiftlint:eable variable_name
-fileprivate let shortSTypeNames: [String] = {
+private let shortSTypeNames: [String] = {
guard let url = Bundle.main.url(forResource: "STypeShortName", withExtension: "plist"),
- let array = NSArray(contentsOf: url) as? [String]
- else {
+ let array = NSArray(contentsOf: url) as? [String] else {
+
print("Can not load STypeShortName.plist.")
return []
}
return array
}()
-fileprivate let levelUpExps: [Int] = {
+private let levelUpExps: [Int] = {
guard let url = Bundle.main.url(forResource: "LevelUpExp", withExtension: "plist"),
- let array = NSArray(contentsOf: url) as? [Int]
- else {
+ let array = NSArray(contentsOf: url) as? [Int] else {
+
print("Can not load LevelUpExp.plist.")
return []
}
return ["ship_id"]
}
- dynamic var name: String { return master_ship.name }
+ @objc dynamic var name: String { return master_ship.name }
class func keyPathsForValuesAffectingShortTypeName() -> Set<String> {
return ["ship_id"]
}
- dynamic var shortTypeName: String? {
+ @objc dynamic var shortTypeName: String? {
let index = master_ship.stype.id - 1
- guard case 0..<shortSTypeNames.count = index
- else { return nil }
+ guard case 0..<shortSTypeNames.count = index else { return nil }
return shortSTypeNames[index]
}
return ["exp"]
}
- dynamic var next: NSNumber? {
+ @objc dynamic var next: NSNumber? {
- guard case 0..<levelUpExps.count = lv
- else { return nil }
+ guard case 0..<levelUpExps.count = lv else { return nil }
if lv == 99 { return nil }
return ["nowhp", "maxph"]
}
- dynamic var status: Int {
+ @objc dynamic var status: Int {
- let n = Double(nowhp)
- let m = Double(maxhp)
- let stat = n / m
+ let stat = Double(nowhp) / Double(maxhp)
if stat <= 0.25 { return 3 }
if stat <= 0.5 { return 2 }
return 0
}
- class func keyPathsForValuesAffectingStatusColor() -> Set<String> {
-
- return ["status"]
- }
- dynamic var statusColor: NSColor {
-
- switch status {
- case 0: return NSColor.controlTextColor
- case 1: return NSColor.yellow
- case 2: return NSColor.orange
- case 3: return NSColor.red
- default: fatalError("status is unknown value")
- }
- }
-
-// class func keyPathsForValuesAffectingConditionColor() -> Set<String> {
-// return ["cond"]
-// }
- dynamic var conditionColor: NSColor { return NSColor.controlTextColor }
-
class func keyPathsForValuesAffectingPlanColor() -> Set<String> {
return ["sally_area"]
}
- dynamic var planColor: NSColor {
+ @objc dynamic var planColor: NSColor {
if !UserDefaults.standard[.showsPlanColor] { return NSColor.controlTextColor }
- guard let sally = sally_area
- else { return NSColor.controlTextColor }
+ guard let sally = sally_area else { return .controlTextColor }
switch sally {
case 1: return UserDefaults.standard[.plan01Color]
extension Ship {
- dynamic var maxBull: Int { return master_ship.bull_max }
- dynamic var maxFuel: Int { return master_ship.fuel_max }
+ @objc dynamic var maxBull: Int { return master_ship.bull_max }
+ @objc dynamic var maxFuel: Int { return master_ship.fuel_max }
class func keyPathsForValuesAffectingIsMaxKaryoku() -> Set<String> {
return ["karyoku_1", "kyouka_0"]
}
- dynamic var isMaxKaryoku: Bool {
+ @objc dynamic var isMaxKaryoku: Bool {
let initial = master_ship.houg_0
let max = karyoku_1
return ["raisou_1", "kyouka_1"]
}
- dynamic var isMaxRaisou: Bool {
+ @objc dynamic var isMaxRaisou: Bool {
let initial = master_ship.raig_0
let max = raisou_1
return ["taiku_1", "kyouka_2"]
}
- dynamic var isMaxTaiku: Bool {
+ @objc dynamic var isMaxTaiku: Bool {
let initial = master_ship.tyku_0
let max = taiku_1
return ["soukou_1", "kyouka_3"]
}
- dynamic var isMaxSoukou: Bool {
+ @objc dynamic var isMaxSoukou: Bool {
let initial = master_ship.souk_0
let max = soukou_1
return ["lucky_1", "kyouka_4"]
}
- dynamic var isMaxLucky: Bool {
+ @objc dynamic var isMaxLucky: Bool {
let initial = master_ship.luck_0
let max = lucky_1
return ["ship_id"]
}
- dynamic var upgradeLevel: Int { return master_ship.afterlv }
+ @objc dynamic var upgradeLevel: Int { return master_ship.afterlv }
class func keyPathsForValuesAffectingUpgradeExp() -> Set<String> {
return ["exp"]
}
- dynamic var upgradeExp: NSNumber? {
+ @objc dynamic var upgradeExp: NSNumber? {
let upgradeLv = upgradeLevel
return upExp < 0 ? 0 : upExp as NSNumber
}
- dynamic var guardEscaped: Bool {
+ @objc dynamic var guardEscaped: Bool {
let store = TemporaryDataStore.default
- guard let _ = store.ensuredGuardEscaped(byShipId: id)
- else { return false }
+ guard let _ = store.ensuredGuardEscaped(byShipId: id) else { return false }
return true
}
return ["nowhp"]
}
- dynamic var steelRequiredInRepair: Int {
+ @objc dynamic var steelRequiredInRepair: Int {
return Int(Double(maxFuel) * 0.06 * Double(maxhp - nowhp))
}
return ["nowhp"]
}
- dynamic var fuelRequiredInRepair: Int {
+ @objc dynamic var fuelRequiredInRepair: Int {
return Int(Double(maxFuel) * 0.032 * Double(maxhp - nowhp))
}
}
-
-fileprivate let seikuEffectiveTypes: [Int] = [6, 7, 8, 11, 45, 56, 57, 58]
-
-fileprivate let fighterTypes: [Int] = [6]
-fileprivate let bomberTypes: [Int] = [7]
-fileprivate let attackerTypes: [Int] = [8]
-fileprivate let floatplaneBomberTypes: [Int] = [11]
-fileprivate let floatplaneFighterTypes: [Int] = [45]
-fileprivate let jetFighter: [Int] = [56]
-fileprivate let jetBomberTypes: [Int] = [57]
-fileprivate let jetAttackerTypes: [Int] = [58]
-
-fileprivate let allPlaneTypes: [Int] = [6, 7, 8, 9, 10, 11, 25, 26, 41, 45, 56, 57, 58, 59]
-
-fileprivate let fighterBonus: [Double] = [0, 0, 2, 5, 9, 14, 14, 22]
-fileprivate let bomberBonus: [Double] = [0, 0, 0, 0, 0, 0, 0, 0]
-fileprivate let attackerBonus: [Double] = [0, 0, 0, 0, 0, 0, 0, 0]
-fileprivate let floatplaneBomberBonus: [Double] = [0, 0, 1, 1, 1, 3, 3, 6]
-fileprivate let floatplaneFighterBonus: [Double] = [0, 0, 2, 5, 9, 14, 14, 22]
-fileprivate let jetBomberBonus: [Double] = [0, 0, 0, 0, 0, 0, 0, 0]
-
-// sqrt 0, 1, 2.5, 4, 5.5, 7, 8.5, 10
-fileprivate let bonus: [Double] = [0, 1.000, 1.581, 2.000, 2.345, 2.645, 2.915, 3.162]
-
-
extension Ship {
- private func slotItemCount(_ index: Int) -> Int {
+ func setItem(_ id: Int, to slot: Int) {
- switch index {
- case 0: return onslot_0
- case 1: return onslot_1
- case 2: return onslot_2
- case 3: return onslot_3
- case 4: return onslot_4
- default: return 0
+ switch slot {
+ case 0: slot_0 = id
+ case 1: slot_1 = id
+ case 2: slot_2 = id
+ case 3: slot_3 = id
+ case 4: slot_4 = id
+ default: fatalError("Ship: setItem out of bounds.")
}
}
- private func slotItemId(_ index: Int) -> Int {
+ func slotItemId(_ index: Int) -> Int {
switch index {
case 0: return slot_0
}
}
- func setItem(_ id: Int, for slot: Int) {
+ func slotItemCount(_ index: Int) -> Int {
- switch slot {
- case 0: slot_0 = id
- case 1: slot_1 = id
- case 2: slot_2 = id
- case 3: slot_3 = id
- case 4: slot_4 = id
- default: fatalError("Ship: setItem out of bounds.")
+ switch index {
+ case 0: return onslot_0
+ case 1: return onslot_1
+ case 2: return onslot_2
+ case 3: return onslot_3
+ case 4: return onslot_4
+ default: return 0
}
}
- private func slotItemMax(_ index: Int) -> Int {
+ func slotItemMax(_ index: Int) -> Int {
switch index {
case 0: return master_ship.maxeq_0
}
}
- private func slotItem(_ index: Int) -> SlotItem? {
+ func slotItem(_ index: Int) -> SlotItem? {
return ServerDataStore.default.slotItem(by: slotItemId(index))
}
- private func typeBonus(_ type: Int) -> [Double]? {
-
- switch type {
- case let t where fighterTypes.contains(t): return fighterBonus
- case let t where bomberTypes.contains(t): return bomberBonus
- case let t where attackerTypes.contains(t): return attackerBonus
- case let t where floatplaneBomberTypes.contains(t): return floatplaneBomberBonus
- case let t where floatplaneFighterTypes.contains(t): return floatplaneFighterBonus
- case let t where jetBomberTypes.contains(t): return jetBomberBonus
- default: return nil
- }
- }
-
- private func normalSeiku(_ index: Int) -> Double {
-
- let itemCount = slotItemCount(index)
-
- if itemCount == 0 { return 0 }
-
- guard let item = slotItem(index)
- else { return 0 }
-
- let type2 = item.master_slotItem.type_2
-
- guard seikuEffectiveTypes.contains(type2)
- else { return 0 }
-
- let taiku = Double(item.master_slotItem.tyku)
- let lv = Double(item.level)
- let rate = bomberTypes.contains(type2) ? 0.25 : 0.2
-
- return (taiku + lv * rate) * sqrt(Double(itemCount))
-
- }
-
- private func extraSeiku(_ index: Int) -> Double {
-
- let itemCount = slotItemCount(index)
-
- if itemCount == 0 { return 0 }
-
- guard let item = slotItem(index)
- else { return 0 }
-
- let type2 = item.master_slotItem.type_2
-
- guard let typeBonus = typeBonus(type2)
- else { return 0 }
-
- let airLevel = item.alv
-
- return typeBonus[airLevel] + bonus[airLevel]
- }
-
- private func seiku(_ index: Int) -> Int {
-
- return Int(normalSeiku(index) + extraSeiku(index))
- }
-
- dynamic var totalEquipment: Int {
+ @objc dynamic var totalEquipment: Int {
return (0...4).map(slotItemMax).reduce(0, +)
}
return ["slot_0", "slot_1", "slot_2", "slot_3", "slot_4",
"onslot_0", "onslot_1", "onslot_2", "onslot_3", "onslot_4"]
}
- dynamic var seiku: Int {
-
- return (0...4).map(normalSeiku).map { Int($0) }.reduce(0, +)
- }
-
- var extraSeiku: Int {
-
- return (0...4).map(extraSeiku).map { Int($0) }.reduce(0, +)
- }
-
- class func keyPathsForValuesAffectingTotalSeiku() -> Set<String> {
-
- return ["seiku"]
- }
- var totalSeiku: Int {
-
- return (0...4).map(seiku).reduce(0, +)
- }
-
- var totalDrums: Int {
-
- return (0...4).flatMap(slotItem).filter { $0.slotitem_id == 75 }.count
- }
-
- // MARK: - Plane count strings
- private enum PlaneState {
-
- case cannotEquip
- case notEquip(Int)
- case equiped(Int, Int)
- }
-
- private func planState(_ index: Int) -> PlaneState {
-
- let itemId = slotItemId(index)
- let maxCount = slotItemMax(index)
+ @objc dynamic var seiku: Int {
- if maxCount == 0 { return .cannotEquip }
- if itemId == -1 { return .notEquip(maxCount) }
-
- if let item = slotItem(index),
- allPlaneTypes.contains(item.master_slotItem.type_2) {
-
- return .equiped(slotItemCount(index), maxCount)
- }
-
- return .notEquip(maxCount)
+ return SeikuCalclator(ship: self).seiku
}
- private func planeString(_ index: Int) -> String? {
-
- switch planState(index) {
- case .cannotEquip:
- return nil
- case .notEquip(let max):
- return "\(max)"
- case .equiped(let count, let max):
- return "\(count)/\(max)"
- }
- }
-
- class func keyPathsForValuesAffectingPlaneString0() -> Set<String> {
-
- return ["onslot_0", "master_ship.maxeq_0", "equippedItem"]
- }
- dynamic var planeString0: String? { return planeString(0) }
-
- class func keyPathsForValuesAffectingPlaneString1() -> Set<String> {
-
- return ["onslot_1", "master_ship.maxeq_1", "equippedItem"]
- }
- dynamic var planeString1: String? { return planeString(1) }
-
- class func keyPathsForValuesAffectingPlaneString2() -> Set<String> {
-
- return ["onslot_2", "master_ship.maxeq_2", "equippedItem"]
- }
- dynamic var planeString2: String? { return planeString(2) }
-
- class func keyPathsForValuesAffectingPlaneString3() -> Set<String> {
-
- return ["onslot_3", "master_ship.maxeq_3", "equippedItem"]
- }
- dynamic var planeString3: String? { return planeString(3) }
-
- class func keyPathsForValuesAffectingPlaneString4() -> Set<String> {
-
- return ["onslot_4", "master_ship.maxeq_4", "equippedItem"]
- }
- dynamic var planeString4: String? { return planeString(4) }
-
- // MARK: - Plane count string color
- private func planeStringColor(_ index: Int) -> NSColor {
- switch planState(index) {
- case .cannotEquip: return NSColor.controlTextColor
- case .notEquip: return NSColor.disabledControlTextColor
- case .equiped: return NSColor.controlTextColor
- }
- }
-
- class func keyPathsForValuesAffectingPlaneString0Color() -> Set<String> {
-
- return ["onslot_0", "master_ship.maxeq_0", "equippedItem"]
- }
- dynamic var planeString0Color: NSColor { return planeStringColor(0) }
-
- class func keyPathsForValuesAffectingPlaneString1Color() -> Set<String> {
-
- return ["onslot_1", "master_ship.maxeq_1", "equippedItem"]
- }
- dynamic var planeString1Color: NSColor { return planeStringColor(1) }
-
- class func keyPathsForValuesAffectingPlaneString2Color() -> Set<String> {
-
- return ["onslot_2", "master_ship.maxeq_2", "equippedItem"]
- }
- dynamic var planeString2Color: NSColor { return planeStringColor(2) }
-
- class func keyPathsForValuesAffectingPlaneString3Color() -> Set<String> {
-
- return ["onslot_3", "master_ship.maxeq_3", "equippedItem"]
- }
- dynamic var planeString3Color: NSColor { return planeStringColor(3) }
-
- class func keyPathsForValuesAffectingPlaneString4Color() -> Set<String> {
-
- return ["onslot_4", "master_ship.maxeq_4", "equippedItem"]
- }
- dynamic var planeString4Color: NSColor { return planeStringColor(4) }
}