From 4c9d83c7cb6dd05a674ca137fd2abe99414e6db6 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Mon, 1 Jun 2020 17:27:13 +0200 Subject: [PATCH] Add localRoundData Send boosts --- .../GoldWars/Components/TimerComponent.swift | 2 +- GoldWars/GoldWars/DataService.swift | 26 ++++++----- GoldWars/GoldWars/Entities/HUD.swift | 4 +- GoldWars/GoldWars/GameCenterManager.swift | 4 +- GoldWars/GoldWars/MultiplayerNetwork.swift | 8 ++-- .../GoldWars/RoundCalculatorService.swift | 45 ++++++++++++++----- 6 files changed, 59 insertions(+), 30 deletions(-) diff --git a/GoldWars/GoldWars/Components/TimerComponent.swift b/GoldWars/GoldWars/Components/TimerComponent.swift index fc6df85..a799b69 100644 --- a/GoldWars/GoldWars/Components/TimerComponent.swift +++ b/GoldWars/GoldWars/Components/TimerComponent.swift @@ -57,7 +57,7 @@ class TimerComponent: GKComponent { self.labelNode.text = "Synching" RoundCalculatorService.sharedInstance.resetNumberOfAttacksAndFormats() if !MultiplayerNetwork.sharedInstance.isSending { - MultiplayerNetwork.sharedInstance.sendPlayerMoves(playerMoves: DataService.sharedInstance.localPlayerMoves) + MultiplayerNetwork.sharedInstance.sendPlayerMoves(localRoundData: DataService.sharedInstance.localRoundData!) } if !RoundCalculatorService.sharedInstance.isCalculating && DataService.sharedInstance.didReceiveAllData() diff --git a/GoldWars/GoldWars/DataService.swift b/GoldWars/GoldWars/DataService.swift index 93fba09..910cb9e 100644 --- a/GoldWars/GoldWars/DataService.swift +++ b/GoldWars/GoldWars/DataService.swift @@ -12,6 +12,12 @@ struct PlayerMove: Codable { var unitCount: Int } +struct LocalRoundData: Codable { + var localPlayerMoves: [PlayerMove] + var hasAttackBoost: Bool + var hasDefenceBoost: Bool +} + class SnapshotModel: Codable { var baseEntites: [BaseEntityModel] @@ -24,22 +30,18 @@ class BaseEntityModel: Codable { let baseId: Int var unitCount: Int var ownership: String? - var hasAttackBoost: Bool - var hasDefenceBoost: Bool init(baseId: Int, unitCount: Int, ownership: String?, hasAttackBoost: Bool, hasDefenceBoost: Bool) { self.baseId = baseId self.unitCount = unitCount self.ownership = ownership - self.hasAttackBoost = hasAttackBoost - self.hasDefenceBoost = hasDefenceBoost } } class DataService { static let sharedInstance = DataService() - var localPlayerMoves: [PlayerMove] = [] - var remotePlayerMoves: [String: [PlayerMove]] = [:] + var localRoundData: LocalRoundData? + var remotePlayerMoves: [String: LocalRoundData] = [:] var snapshotModel: SnapshotModel? var hostingPlayer = GameCenterManager.sharedInstance.hostingPlayer @@ -47,18 +49,18 @@ class DataService { var entityManager = EntityManager.gameEMInstance func addMove(playerMove: PlayerMove) { - var equalMove = localPlayerMoves.filter { (ele) -> Bool in + var equalMove = localRoundData?.localPlayerMoves.filter { (ele) -> Bool in ele.fromBase == playerMove.fromBase && ele.toBase == playerMove.toBase } - if equalMove.count == 1 { - equalMove[0].unitCount = Int(equalMove[0].unitCount) + Int(playerMove.unitCount) + if equalMove!.count == 1 { + equalMove![0].unitCount = Int(equalMove![0].unitCount) + Int(playerMove.unitCount) } else { - self.localPlayerMoves.append(playerMove) + self.localRoundData?.localPlayerMoves.append(playerMove) } } - func addRemotePlayerMoves(playerName: String, playerMoves: [PlayerMove]) { - self.remotePlayerMoves[playerName] = playerMoves + func addRemotePlayerMoves(playerName: String, localRoundData: LocalRoundData) { + self.remotePlayerMoves[playerName] = localRoundData } func didReceiveAllData() -> Bool { diff --git a/GoldWars/GoldWars/Entities/HUD.swift b/GoldWars/GoldWars/Entities/HUD.swift index 3b71497..633b61b 100644 --- a/GoldWars/GoldWars/Entities/HUD.swift +++ b/GoldWars/GoldWars/Entities/HUD.swift @@ -44,14 +44,14 @@ class HUD: GKEntity { text: "Def", isEnabled: true, position: CGPoint(x: EntityManager.gameEMInstance.scene.size.width * 0.85, y: EntityManager.gameEMInstance.scene.size.height * 0.1), - onButtonPress: {EntityManager.gameEMInstance.getBasesByTeam(for: .team2).forEach({base in base.hasDefenseBoost = true})} + onButtonPress: {DataService.sharedInstance.localRoundData?.hasDefenceBoost = true} ) atkSkill = SingeClickButtonNode( textureName: "yellow_circle", text: "Atk", isEnabled: true, position: CGPoint(x: EntityManager.gameEMInstance.scene.size.width * 0.95, y: EntityManager.gameEMInstance.scene.size.height * 0.1), - onButtonPress: {EntityManager.gameEMInstance.getBasesByTeam(for: .team2).forEach({base in base.hasAttackBoost = true})} + onButtonPress: {DataService.sharedInstance.localRoundData?.hasAttackBoost = true} ) super.init() hostLabel.position = CGPoint(x: size.width * 0.02, y: size.height * 0.95) diff --git a/GoldWars/GoldWars/GameCenterManager.swift b/GoldWars/GoldWars/GameCenterManager.swift index 7571212..8b7ab1e 100644 --- a/GoldWars/GoldWars/GameCenterManager.swift +++ b/GoldWars/GoldWars/GameCenterManager.swift @@ -122,8 +122,8 @@ final class GameCenterManager: NSObject, GKMatchmakerViewControllerDelegate ,GKM break } } - if let playerMoves = try? jsonDecoder.decode([PlayerMove].self, from: data) { - DataService.sharedInstance.addRemotePlayerMoves(playerName: player.displayName, playerMoves: playerMoves) + if let roundData = try? jsonDecoder.decode(LocalRoundData.self, from: data) { + DataService.sharedInstance.addRemotePlayerMoves(playerName: player.displayName, localRoundData: roundData) } if let snapshotModel = try? jsonDecoder.decode(SnapshotModel.self, from: data) { DataService.sharedInstance.snapshotModel = snapshotModel diff --git a/GoldWars/GoldWars/MultiplayerNetwork.swift b/GoldWars/GoldWars/MultiplayerNetwork.swift index 89b1479..bd9f9eb 100644 --- a/GoldWars/GoldWars/MultiplayerNetwork.swift +++ b/GoldWars/GoldWars/MultiplayerNetwork.swift @@ -36,13 +36,15 @@ class MultiplayerNetwork{ } } - func sendPlayerMoves(playerMoves: [PlayerMove]) { + func sendPlayerMoves(localRoundData: LocalRoundData) { if GameCenterManager.sharedInstance.isServer == false { self.isSending = true let encoder = JSONEncoder() - let encoded = (try? encoder.encode(playerMoves))! + let encoded = (try? encoder.encode(localRoundData))! sendDataToHost(data: encoded) - DataService.sharedInstance.localPlayerMoves.removeAll() + DataService.sharedInstance.localRoundData!.localPlayerMoves.removeAll() + DataService.sharedInstance.localRoundData!.hasAttackBoost = false + DataService.sharedInstance.localRoundData!.hasDefenceBoost = false } } diff --git a/GoldWars/GoldWars/RoundCalculatorService.swift b/GoldWars/GoldWars/RoundCalculatorService.swift index 60894d4..337af11 100644 --- a/GoldWars/GoldWars/RoundCalculatorService.swift +++ b/GoldWars/GoldWars/RoundCalculatorService.swift @@ -16,6 +16,9 @@ class RoundCalculatorService { let ATK_BOOST_MULTIPLICATOR = 1.1 let DEF_BOOST_MULTIPLICATOR = 1.1 + // TODO: Better data structure + var boosts: [String: (Bool, Bool)] = [:] // First bool is atk boost, second is def boost + var entityManager = EntityManager.gameEMInstance var isCalculating = false @@ -76,27 +79,35 @@ class RoundCalculatorService { let sortedPotentionalCombinedForces = combinePotentionalForces.sorted { $0.1.unitCount > $1.1.unitCount } var playerMoveWithMaxUnits = sortedPotentionalCombinedForces[0] - playerMoveWithMaxUnits.value.unitCount = Int(Double(playerMoveWithMaxUnits.value.unitCount) * ((currentSnapshotModel?.baseEntites[playerMoveWithMaxUnits.value.fromBase].hasAttackBoost)! ? ATK_BOOST_MULTIPLICATOR : 1)) + if playerMovesByBase.count >= 2 { var playerMoveWithSecMaxUnits = sortedPotentionalCombinedForces[1] - playerMoveWithSecMaxUnits.value.unitCount = Int(Double(playerMoveWithSecMaxUnits.value.unitCount) * ((currentSnapshotModel?.baseEntites[playerMoveWithSecMaxUnits.value.fromBase].hasAttackBoost)! ? ATK_BOOST_MULTIPLICATOR : 1)) - playerMoveWithMaxUnits.value.unitCount -= playerMoveWithSecMaxUnits.value.unitCount // Apply Boost + if boosts[playerMoveWithMaxUnits.key]!.0 { + playerMoveWithMaxUnits.value.unitCount = Int(Double(playerMoveWithMaxUnits.value.unitCount) * ATK_BOOST_MULTIPLICATOR) + } + if boosts[playerMoveWithSecMaxUnits.key]!.0 { + playerMoveWithSecMaxUnits.value.unitCount = Int(Double(playerMoveWithSecMaxUnits.value.unitCount) * ATK_BOOST_MULTIPLICATOR) + } + playerMoveWithMaxUnits.value.unitCount -= playerMoveWithSecMaxUnits.value.unitCount } for base in currentSnapshotModel!.baseEntites { if base.baseId == playerMoveWithMaxUnits.value.toBase { - base.unitCount = Int(Double(base.unitCount) * (base.hasDefenceBoost ? DEF_BOOST_MULTIPLICATOR : 1)) if base.ownership == nil { - base.unitCount += playerMoveWithMaxUnits.value.unitCount // Apply Boost + base.unitCount += playerMoveWithMaxUnits.value.unitCount base.ownership = playerMoveWithMaxUnits.value.unitCount == 0 ? nil : playerMoveWithMaxUnits.key } else { + if boosts[base.ownership!]!.1 { + base.unitCount = Int(Double(base.unitCount) * DEF_BOOST_MULTIPLICATOR) + } if base.unitCount < playerMoveWithMaxUnits.value.unitCount { - base.unitCount = playerMoveWithMaxUnits.value.unitCount - base.unitCount // Apply Boost + base.unitCount = playerMoveWithMaxUnits.value.unitCount - base.unitCount base.ownership = playerMoveWithMaxUnits.key } else if (base.unitCount == playerMoveWithMaxUnits.value.unitCount) { base.ownership = nil + base.unitCount = 0 } else { - base.unitCount -= playerMoveWithMaxUnits.value.unitCount // Apply Boost + base.unitCount -= playerMoveWithMaxUnits.value.unitCount } } } @@ -104,7 +115,9 @@ class RoundCalculatorService { } baseSpecificMoves.removeValue(forKey: baseId) } - DataService.sharedInstance.localPlayerMoves.removeAll() + DataService.sharedInstance.localRoundData?.localPlayerMoves.removeAll() + DataService.sharedInstance.localRoundData?.hasAttackBoost = false + DataService.sharedInstance.localRoundData?.hasDefenceBoost = false MultiplayerNetwork.sharedInstance.sendSnapshotModelToPlayers() DataService.sharedInstance.snapshotModel = currentSnapshotModel entityManager.updateSnapshotModel(snapshotModel: currentSnapshotModel!) @@ -119,11 +132,21 @@ class RoundCalculatorService { // collect moves from remote player for playerMove in DataService.sharedInstance.remotePlayerMoves { - allPlayerMoves[playerMove.key] = playerMove.value + allPlayerMoves[playerMove.key] = playerMove.value.localPlayerMoves } + boosts[GameCenterManager.sharedInstance.hostingPlayer!.displayName] = ( + DataService.sharedInstance.localRoundData!.hasAttackBoost, + DataService.sharedInstance.localRoundData!.hasDefenceBoost + ) + + boosts[GameCenterManager.sharedInstance.peerPlayer!.displayName] = ( + DataService.sharedInstance.remotePlayerMoves[GameCenterManager.sharedInstance.peerPlayer!.displayName]!.hasAttackBoost, + DataService.sharedInstance.remotePlayerMoves[GameCenterManager.sharedInstance.peerPlayer!.displayName]!.hasDefenceBoost + ) + // collect moves from local player - allPlayerMoves[GKLocalPlayer.local.displayName] = DataService.sharedInstance.localPlayerMoves + allPlayerMoves[GKLocalPlayer.local.displayName] = DataService.sharedInstance.localRoundData?.localPlayerMoves var baseSpecificMoves: [Int: [String: [PlayerMove]]] = [:] @@ -141,6 +164,8 @@ class RoundCalculatorService { } } + DataService.sharedInstance.remotePlayerMoves.removeAll() + return baseSpecificMoves }