* Impl. combined forces attack
* Minor refactoring * Fixed component updates on updating entities from snapshot * Fixed mapping for incoming player moves
This commit is contained in:
parent
de5929d070
commit
1571a1e786
@ -48,10 +48,10 @@ class TimerComponent: GKComponent {
|
|||||||
if !MultiplayerNetwork.sharedInstance.isSending {
|
if !MultiplayerNetwork.sharedInstance.isSending {
|
||||||
MultiplayerNetwork.sharedInstance.sendPlayerMoves(playerMoves: DataService.sharedInstance.localPlayerMoves)
|
MultiplayerNetwork.sharedInstance.sendPlayerMoves(playerMoves: DataService.sharedInstance.localPlayerMoves)
|
||||||
}
|
}
|
||||||
if !RoundCalculatorServie.sharedInstance.isCalculating
|
if !RoundCalculatorService.sharedInstance.isCalculating
|
||||||
&& DataService.sharedInstance.didReceiveAllData()
|
&& DataService.sharedInstance.didReceiveAllData()
|
||||||
&& MatchmakingHelper.sharedInstance.isServer {
|
&& MatchmakingHelper.sharedInstance.isServer {
|
||||||
RoundCalculatorServie.sharedInstance.calculateRound()
|
RoundCalculatorService.sharedInstance.calculateRound()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,17 +109,17 @@ class EntityManager {
|
|||||||
let base = (entity as! Base)
|
let base = (entity as! Base)
|
||||||
|
|
||||||
if base.changeOwnership {
|
if base.changeOwnership {
|
||||||
if let component = entity.component(ofType: TeamComponent.self) {
|
//FIX-ME: Find a way to update the Component without deleting it upfront
|
||||||
component.player = entities[0].component(ofType: TeamComponent.self)!.player
|
//TODO: outsource component handling to a generic function
|
||||||
component.team = entities[0].component(ofType: TeamComponent.self)!.team
|
base.removeComponent(ofType: TeamComponent.self)
|
||||||
} else {
|
base.addComponent(TeamComponent(
|
||||||
base.addComponent(TeamComponent(
|
team: (entities[0] as! Base).component(ofType: TeamComponent.self)!.team,
|
||||||
team: (entities[0] as! Base).component(ofType: TeamComponent.self)!.team,
|
player: (entities[0] as! Base).component(ofType: TeamComponent.self)!.player,
|
||||||
player: (entities[0] as! Base).component(ofType: TeamComponent.self)!.player,
|
position: (base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)!
|
||||||
position: (base.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)!
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
scene.addChild(base.component(ofType: TeamComponent.self)!.fire)
|
)
|
||||||
|
if let fire = entity.component(ofType: TeamComponent.self)?.fire{
|
||||||
|
scene.addChild(fire)
|
||||||
}
|
}
|
||||||
base.changeOwnership = false
|
base.changeOwnership = false
|
||||||
}
|
}
|
||||||
@ -131,8 +131,6 @@ class EntityManager {
|
|||||||
for entity in bases{
|
for entity in bases{
|
||||||
let base = entity as! Base
|
let base = entity as! Base
|
||||||
let snapBase = self.getSnapshotBaseById(baseId: base.baseID, snapshotModel: snapshotModel)
|
let snapBase = self.getSnapshotBaseById(baseId: base.baseID, snapshotModel: snapshotModel)
|
||||||
print("in updateSnap -> Entity \(base)")
|
|
||||||
print("in updateSnap -> snapBase \(snapBase)")
|
|
||||||
var getOwnerBySnapBase: GKPlayer? = nil
|
var getOwnerBySnapBase: GKPlayer? = nil
|
||||||
base.unitCount = snapBase.unitCount
|
base.unitCount = snapBase.unitCount
|
||||||
|
|
||||||
@ -142,24 +140,19 @@ class EntityManager {
|
|||||||
if getOwnerBySnapBase != nil {
|
if getOwnerBySnapBase != nil {
|
||||||
base.changeOwnership = true
|
base.changeOwnership = true
|
||||||
base.ownershipPlayer = getOwnerBySnapBase
|
base.ownershipPlayer = getOwnerBySnapBase
|
||||||
if let component = entity.component(ofType: TeamComponent.self) {
|
//FIX-ME: Find a way to update the Component without deleting it upfront
|
||||||
component.player = getOwnerBySnapBase!
|
//TODO: outsource component handling to a generic function
|
||||||
component.team = getTeamByPlayer(playerName: snapBase.ownership!)
|
entity.removeComponent(ofType: TeamComponent.self)
|
||||||
} else {
|
entity.addComponent(TeamComponent(
|
||||||
entity.addComponent(TeamComponent(
|
team: getTeamByPlayer(playerName: snapBase.ownership!),
|
||||||
team: getTeamByPlayer(playerName: snapBase.ownership!),
|
player: getOwnerBySnapBase!,
|
||||||
player: getOwnerBySnapBase!,
|
position: (entity.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)!
|
||||||
position: (entity.component(ofType: DefaultBaseComponent.self)?.spriteNode.position)!
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
if let fire = entity.component(ofType: TeamComponent.self)?.fire{
|
)
|
||||||
scene.addChild(fire)
|
if let fire = entity.component(ofType: TeamComponent.self)?.fire{
|
||||||
}
|
scene.addChild(fire)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
print("nach updateSnap -> Entity \(base)")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,6 @@ class MatchmakingHelper: NSObject, GKMatchmakerViewControllerDelegate, GKMatchDe
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let snapshotModel = try? jsonDecoder.decode(SnapshotModel.self, from: data) {
|
if let snapshotModel = try? jsonDecoder.decode(SnapshotModel.self, from: data) {
|
||||||
print("received data package -> \(snapshotModel)")
|
|
||||||
DataService.sharedInstance.snapshotModel = snapshotModel
|
DataService.sharedInstance.snapshotModel = snapshotModel
|
||||||
EntityManager.sharedInstance.updateSnapshotModel(snapshotModel: snapshotModel)
|
EntityManager.sharedInstance.updateSnapshotModel(snapshotModel: snapshotModel)
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import GameKit
|
|||||||
|
|
||||||
class MultiplayerNetwork{
|
class MultiplayerNetwork{
|
||||||
static let sharedInstance = MultiplayerNetwork()
|
static let sharedInstance = MultiplayerNetwork()
|
||||||
|
|
||||||
var isSending = false
|
var isSending = false
|
||||||
|
|
||||||
func sendData(data: Data) {
|
func sendData(data: Data) {
|
||||||
@ -20,25 +21,20 @@ class MultiplayerNetwork{
|
|||||||
do {
|
do {
|
||||||
try multiplayerMatch.sendData(toAllPlayers: data, with: .reliable)
|
try multiplayerMatch.sendData(toAllPlayers: data, with: .reliable)
|
||||||
} catch {
|
} catch {
|
||||||
print("Tim war am Werk")
|
//TODO: Add logging
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendDataToHost(data: Data) {
|
func sendDataToHost(data: Data) {
|
||||||
let mmHelper = MatchmakingHelper.sharedInstance
|
let mmHelper = MatchmakingHelper.sharedInstance
|
||||||
for player in mmHelper.mpMatch!.players {
|
|
||||||
print(player.displayName)
|
|
||||||
}
|
|
||||||
print(DataService.sharedInstance.gameHost!.playerName)
|
|
||||||
|
|
||||||
let hostGKPlayer = MatchmakingHelper.sharedInstance.mpMatch?.players.filter{ $0.displayName == DataService.sharedInstance.gameHost!.playerName}[0]
|
let hostGKPlayer = MatchmakingHelper.sharedInstance.mpMatch?.players.filter{ $0.displayName == DataService.sharedInstance.gameHost!.playerName}[0]
|
||||||
|
|
||||||
if let multiplayerMatch = mmHelper.mpMatch{
|
if let multiplayerMatch = mmHelper.mpMatch{
|
||||||
do {
|
do {
|
||||||
try multiplayerMatch.send(data, to: [hostGKPlayer!], dataMode: .reliable)
|
try multiplayerMatch.send(data, to: [hostGKPlayer!], dataMode: .reliable)
|
||||||
} catch {
|
} catch {
|
||||||
print("Tim war mal wieder am Werk der Krasse")
|
//TODO: Add logging
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -59,10 +55,8 @@ class MultiplayerNetwork{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func sendSnapshotModelToPlayers() {
|
func sendSnapshotModelToPlayers() {
|
||||||
print("sending snapshot -> \(DataService.sharedInstance.snapshotModel)")
|
|
||||||
let encoder = JSONEncoder()
|
let encoder = JSONEncoder()
|
||||||
let encoded = (try? encoder.encode(DataService.sharedInstance.snapshotModel))!
|
let encoded = (try? encoder.encode(DataService.sharedInstance.snapshotModel))!
|
||||||
print("sending package -> \(encoded)")
|
|
||||||
sendData(data: encoded)
|
sendData(data: encoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,93 +6,97 @@
|
|||||||
// Copyright © 2020 SP2. All rights reserved.
|
// Copyright © 2020 SP2. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
|
||||||
import GameKit
|
import GameKit
|
||||||
import os
|
import os
|
||||||
|
|
||||||
class RoundCalculatorServie {
|
class RoundCalculatorService {
|
||||||
static let sharedInstance = RoundCalculatorServie()
|
static let sharedInstance = RoundCalculatorService()
|
||||||
var isCalculating = false
|
static let LOG = OSLog.init(subsystem: "Round Calculator", category: "RoundCalculatorService")
|
||||||
|
|
||||||
var allPlayerMoves: [String: [PlayerMove]] = [:]
|
var allPlayerMoves: [String: [PlayerMove]] = [:]
|
||||||
var baseSpecificMoves: [Int: [String: PlayerMove]] = [:]
|
var baseSpecificMoves: [Int: [String: [PlayerMove]]] = [:]
|
||||||
|
|
||||||
|
var isCalculating = false
|
||||||
|
|
||||||
func calculateRound() {
|
func calculateRound() {
|
||||||
os_log("Started calculating Round", log: OSLog.default, type: .info)
|
os_log("Started calculating Round", log: RoundCalculatorService.LOG, type: .info)
|
||||||
let startTime = CFAbsoluteTimeGetCurrent()
|
|
||||||
isCalculating = true
|
isCalculating = true
|
||||||
|
let currentSnapshotModel = DataService.sharedInstance.snapshotModel
|
||||||
|
|
||||||
var currentSnapshotModel = DataService.sharedInstance.snapshotModel
|
for playerMove in DataService.sharedInstance.remotePlayerMoves {
|
||||||
|
addPlayerMove(playerName: playerMove.key, playerMoves: playerMove.value)
|
||||||
// TODO: smarter way?
|
|
||||||
for entry in DataService.sharedInstance.remotePlayerMoves {
|
|
||||||
addPlayerMove(playerName: entry.key, playerMoves: entry.value)
|
|
||||||
}
|
}
|
||||||
addPlayerMove(playerName: GKLocalPlayer.local.displayName, playerMoves: DataService.sharedInstance.localPlayerMoves)
|
addPlayerMove(playerName: GKLocalPlayer.local.displayName, playerMoves: DataService.sharedInstance.localPlayerMoves)
|
||||||
|
|
||||||
for entry in allPlayerMoves {
|
for playerMove in allPlayerMoves {
|
||||||
for move in entry.value {
|
for move in playerMove.value {
|
||||||
mapPlayerMoveToAttackedBase(playerName: entry.key, playerMove: move)
|
mapPlayerMoveToAttackedBase(playerName: playerMove.key, playerMove: move)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO-END:
|
|
||||||
|
|
||||||
|
// TODO: Refactor to a less complex way
|
||||||
// TODO: Refactor -> O(n*3n^2) to maybe O(n*3n)
|
|
||||||
// We might not need to map and iterate over toBase
|
|
||||||
for (key, value) in baseSpecificMoves {
|
for (key, value) in baseSpecificMoves {
|
||||||
let baseId = key
|
let baseId = key
|
||||||
var playerMovesByBase = value
|
var playerMovesByBase = value
|
||||||
let targetBase = currentSnapshotModel?.baseEntites.filter { $0.baseId == baseId }[0]
|
let targetBase = currentSnapshotModel?.baseEntites.filter { $0.baseId == baseId }[0]
|
||||||
let possiblyOwnershipMoves = playerMovesByBase.filter { $0.key == targetBase?.ownership}
|
let possiblyOwnershipMoves = playerMovesByBase.filter { $0.key == targetBase?.ownership}
|
||||||
|
|
||||||
for (playerName, playerMove) in possiblyOwnershipMoves {
|
for (playerName, playerMoves) in possiblyOwnershipMoves {
|
||||||
for base in currentSnapshotModel!.baseEntites {
|
for playerMove in playerMoves {
|
||||||
if base.baseId == playerMove.fromBase {
|
for base in currentSnapshotModel!.baseEntites {
|
||||||
base.unitCount -= playerMove.unitCount
|
if base.baseId == playerMove.fromBase {
|
||||||
}
|
base.unitCount -= playerMove.unitCount
|
||||||
if base.baseId == playerMove.toBase {
|
}
|
||||||
base.unitCount += playerMove.unitCount
|
if base.baseId == playerMove.toBase {
|
||||||
|
base.unitCount += playerMove.unitCount
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
playerMovesByBase.removeValue(forKey: playerName)
|
playerMovesByBase.removeValue(forKey: playerName)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (_, playerMove) in playerMovesByBase {
|
for (_, playerMoves) in playerMovesByBase {
|
||||||
for base in currentSnapshotModel!.baseEntites {
|
for playerMove in playerMoves {
|
||||||
if base.baseId == playerMove.fromBase {
|
for base in currentSnapshotModel!.baseEntites {
|
||||||
base.unitCount -= playerMove.unitCount
|
if base.baseId == playerMove.fromBase {
|
||||||
|
base.unitCount -= playerMove.unitCount
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let sorted = playerMovesByBase.sorted { (e1: (key: String, value: PlayerMove), e2: (key: String, value: PlayerMove)) -> Bool in
|
var combinePotentionalForces: [String: PlayerMove] = [:]
|
||||||
e1.value.unitCount > e2.value.unitCount
|
|
||||||
|
for playerMoves in playerMovesByBase {
|
||||||
|
combinePotentionalForces[playerMoves.key] = PlayerMove(fromBase: playerMoves.value[0].fromBase, toBase: playerMoves.value[0].toBase, unitCount: 0)
|
||||||
|
for move in playerMoves.value {
|
||||||
|
combinePotentionalForces[playerMoves.key]!.unitCount += move.unitCount
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var max = sorted[0]
|
let sortedPotentionalCombinedForces = combinePotentionalForces.sorted { $0.1.unitCount > $1.1.unitCount }
|
||||||
if sorted.count == 2 {
|
|
||||||
let secMax = sorted[1]
|
var playerMoveWithMaxUnits = sortedPotentionalCombinedForces[0]
|
||||||
max.value.unitCount -= secMax.value.unitCount
|
if playerMovesByBase.count >= 2 {
|
||||||
|
let playerMoveWithSecMaxUnits = sortedPotentionalCombinedForces[1]
|
||||||
|
playerMoveWithMaxUnits.value.unitCount -= playerMoveWithSecMaxUnits.value.unitCount
|
||||||
}
|
}
|
||||||
|
|
||||||
for base in currentSnapshotModel!.baseEntites {
|
for base in currentSnapshotModel!.baseEntites {
|
||||||
if base.baseId == max.value.toBase {
|
if base.baseId == playerMoveWithMaxUnits.value.toBase {
|
||||||
base.unitCount += max.value.unitCount
|
base.unitCount += playerMoveWithMaxUnits.value.unitCount
|
||||||
if max.value.unitCount == 0 {
|
if playerMoveWithMaxUnits.value.unitCount == 0 {
|
||||||
base.ownership = nil
|
base.ownership = nil
|
||||||
} else {
|
} else {
|
||||||
base.ownership = max.key
|
base.ownership = playerMoveWithMaxUnits.key
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
baseSpecificMoves.removeValue(forKey: baseId)
|
baseSpecificMoves.removeValue(forKey: baseId)
|
||||||
}
|
}
|
||||||
MultiplayerNetwork.sharedInstance.sendSnapshotModelToPlayers()
|
MultiplayerNetwork.sharedInstance.sendSnapshotModelToPlayers()
|
||||||
EntityManager.sharedInstance.updateSnapshotModel(snapshotModel: currentSnapshotModel!)
|
EntityManager.sharedInstance.updateSnapshotModel(snapshotModel: currentSnapshotModel!)
|
||||||
let calcTime = CFAbsoluteTimeGetCurrent() - startTime
|
os_log("Finished calculating Round", log: RoundCalculatorService.LOG, type: .info)
|
||||||
os_log("Finished calculating Round in %@", log: OSLog.default, type: .info)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func addPlayerMove(playerName: String, playerMoves: [PlayerMove]) {
|
func addPlayerMove(playerName: String, playerMoves: [PlayerMove]) {
|
||||||
@ -101,17 +105,18 @@ class RoundCalculatorServie {
|
|||||||
|
|
||||||
func mapPlayerMoveToAttackedBase(playerName: String, playerMove: PlayerMove) {
|
func mapPlayerMoveToAttackedBase(playerName: String, playerMove: PlayerMove) {
|
||||||
if self.baseSpecificMoves.keys.contains(playerMove.toBase) {
|
if self.baseSpecificMoves.keys.contains(playerMove.toBase) {
|
||||||
var playerMovesForSameBase = self.baseSpecificMoves[playerMove.toBase]!
|
if (self.baseSpecificMoves[playerMove.toBase]?.keys.contains(playerName))!{
|
||||||
if playerMovesForSameBase.keys.contains(playerName) {
|
self.baseSpecificMoves[playerMove.toBase]?[playerName]?.append(playerMove)
|
||||||
playerMovesForSameBase[playerName] = playerMove
|
} else {
|
||||||
|
self.baseSpecificMoves[playerMove.toBase]?.merge([playerName: [playerMove]]){(current, _) in current}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.baseSpecificMoves[playerMove.toBase] = [playerName: playerMove]
|
self.baseSpecificMoves[playerMove.toBase] = [playerName: [playerMove]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolvePlayerMove(playerMove: PlayerMove, unitCount: Int, ownership: String?, resolveType: String) {
|
func resolvePlayerMove(playerMove: PlayerMove, unitCount: Int, ownership: String?, resolveType: String) {
|
||||||
//outsource playermoves || tnx, remove, add(with calc)
|
//TODO: outsource playermoves
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ class SoundManager {
|
|||||||
do {
|
do {
|
||||||
audioPlayer = try AVAudioPlayer(contentsOf: backgroundMainMenuAudio!)
|
audioPlayer = try AVAudioPlayer(contentsOf: backgroundMainMenuAudio!)
|
||||||
} catch {
|
} catch {
|
||||||
print("Datei nicht gefunden!")
|
//TODO: Add logging
|
||||||
}
|
}
|
||||||
audioPlayer.numberOfLoops = -1
|
audioPlayer.numberOfLoops = -1
|
||||||
audioPlayer.prepareToPlay()
|
audioPlayer.prepareToPlay()
|
||||||
|
Loading…
Reference in New Issue
Block a user