Skip to content

Commit

Permalink
Merge branch 'main' into feature/achievements-engine
Browse files Browse the repository at this point in the history
  • Loading branch information
sp4ce-cowboy authored Apr 14, 2024
2 parents 3eef3e8 + 268d370 commit d13d61e
Show file tree
Hide file tree
Showing 23 changed files with 266 additions and 115 deletions.
12 changes: 12 additions & 0 deletions TowerForge/TowerForge.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
3CAC4A712BB6AB3100A5D22E /* TFLabelNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CAC4A702BB6AB3100A5D22E /* TFLabelNode.swift */; };
3CAC4A732BB6B61C00A5D22E /* PlayerRenderStage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CAC4A722BB6B61C00A5D22E /* PlayerRenderStage.swift */; };
3CAC4A752BB6BDD500A5D22E /* HealthRenderStage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CAC4A742BB6BDD500A5D22E /* HealthRenderStage.swift */; };
3CBE72F92BC8D63500CC446A /* RemoteKillEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CBE72F82BC8D63500CC446A /* RemoteKillEvent.swift */; };
3CBE72FF2BC8D66C00CC446A /* RemotePowerupEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CBE72FE2BC8D66C00CC446A /* RemotePowerupEvent.swift */; };
3CBE73012BC8D69A00CC446A /* RemoteLifeEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CBE73002BC8D69A00CC446A /* RemoteLifeEvent.swift */; };
3CBECF892BBE9797005EF39B /* TFNetworkCoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CBECF882BBE9797005EF39B /* TFNetworkCoder.swift */; };
3CBECF8C2BBE9A41005EF39B /* TFRemoteEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CBECF8B2BBE9A41005EF39B /* TFRemoteEvent.swift */; };
3CBECF8E2BBE9EAC005EF39B /* RemoteSpawnEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CBECF8D2BBE9EAC005EF39B /* RemoteSpawnEvent.swift */; };
Expand Down Expand Up @@ -288,6 +291,9 @@
3CAC4A702BB6AB3100A5D22E /* TFLabelNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TFLabelNode.swift; sourceTree = "<group>"; };
3CAC4A722BB6B61C00A5D22E /* PlayerRenderStage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerRenderStage.swift; sourceTree = "<group>"; };
3CAC4A742BB6BDD500A5D22E /* HealthRenderStage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HealthRenderStage.swift; sourceTree = "<group>"; };
3CBE72F82BC8D63500CC446A /* RemoteKillEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteKillEvent.swift; sourceTree = "<group>"; };
3CBE72FE2BC8D66C00CC446A /* RemotePowerupEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemotePowerupEvent.swift; sourceTree = "<group>"; };
3CBE73002BC8D69A00CC446A /* RemoteLifeEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteLifeEvent.swift; sourceTree = "<group>"; };
3CBECF882BBE9797005EF39B /* TFNetworkCoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TFNetworkCoder.swift; sourceTree = "<group>"; };
3CBECF8B2BBE9A41005EF39B /* TFRemoteEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TFRemoteEvent.swift; sourceTree = "<group>"; };
3CBECF8D2BBE9EAC005EF39B /* RemoteSpawnEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteSpawnEvent.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -573,7 +579,10 @@
children = (
3CBECF8B2BBE9A41005EF39B /* TFRemoteEvent.swift */,
3CBECF8D2BBE9EAC005EF39B /* RemoteSpawnEvent.swift */,
3CBE72F82BC8D63500CC446A /* RemoteKillEvent.swift */,
3CBE73002BC8D69A00CC446A /* RemoteLifeEvent.swift */,
3CD37AA62BBEC5EF00222D8A /* BaseRemoteEvent.swift */,
3CBE72FE2BC8D66C00CC446A /* RemotePowerupEvent.swift */,
);
path = RemoteEvents;
sourceTree = "<group>";
Expand Down Expand Up @@ -1478,6 +1487,7 @@
5240D0912BAF3453004F1486 /* Life.swift in Sources */,
52A794192BBC630F0083C976 /* RoomData.swift in Sources */,
BA82C7632BCBBB2A000515A0 /* Double+Extensions.swift in Sources */,
3CBE72F92BC8D63500CC446A /* RemoteKillEvent.swift in Sources */,
52DF5FAE2BA32B2300135367 /* GameScene.swift in Sources */,
52578B822BA61AAF00B4D76C /* PositionComponent.swift in Sources */,
9BC60BC82BB9BE6D001A6737 /* DisabledEvent.swift in Sources */,
Expand Down Expand Up @@ -1571,6 +1581,7 @@
52A7941B2BBC726E0083C976 /* GameRoomViewController.swift in Sources */,
52DD8F952BC5208900D96BAB /* SurvivalGameMode.swift in Sources */,
527A07862BB411FB00CD9D08 /* GameOverScene.swift in Sources */,
3CBE72FF2BC8D66C00CC446A /* RemotePowerupEvent.swift in Sources */,
3C9955B12BA4ACA100D33FA5 /* Bullet.swift in Sources */,
3CA829C62BB719A500D8E72A /* ButtonRenderStage.swift in Sources */,
3CE9514F2BAC8936008B2785 /* TFRenderer.swift in Sources */,
Expand Down Expand Up @@ -1616,6 +1627,7 @@
3CD37AA32BBEC0F900222D8A /* FirebaseRemoteEventPublisher.swift in Sources */,
3CAC4A6B2BB6992F00A5D22E /* TFNode.swift in Sources */,
BA82C7732BCBF657000515A0 /* MetadataManager.swift in Sources */,
3CBE73012BC8D69A00CC446A /* RemoteLifeEvent.swift in Sources */,
3CAC4A6D2BB6A13B00A5D22E /* PositionRenderStage.swift in Sources */,
3CE951672BAEAB0E008B2785 /* ContactSystem.swift in Sources */,
529190E32BBFB59B001D8821 /* StatePopupNode.swift in Sources */,
Expand Down
2 changes: 0 additions & 2 deletions TowerForge/TowerForge/GameModule/Events/ConcurrentEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,12 @@ import Foundation

struct ConcurrentEvent: TFEvent {
var timestamp: TimeInterval
var entityId: UUID

private let event1: TFEvent
private let event2: TFEvent

init(_ event1: TFEvent, _ event2: TFEvent) {
self.timestamp = event1.timestamp
self.entityId = event1.entityId
self.event1 = event1
self.event2 = event2
}
Expand Down
4 changes: 3 additions & 1 deletion TowerForge/TowerForge/GameModule/Events/EventManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ class EventManager {
var eventHandler: [TFEventTypeWrapper: [EventHandler]]
private(set) var remoteEventManager: RemoteEventManager?
private(set) var currentPlayer: GamePlayer?
private(set) var isHost = true

init(roomId: RoomId? = nil, currentPlayer: GamePlayer? = nil) {
init(roomId: RoomId? = nil, isHost: Bool = true, currentPlayer: GamePlayer? = nil) {
eventTransformations = []
eventQueue = []
eventHandler = [:]
Expand All @@ -25,6 +26,7 @@ class EventManager {
let subscriber = FirebaseRemoteEventSubscriber(roomId: roomId, eventManager: self)
self.remoteEventManager = RemoteEventManager(publisher: publisher, subscriber: subscriber)
self.currentPlayer = currentPlayer
self.isHost = isHost
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,8 @@ import Foundation

struct DisabledEvent: TFEvent {
let timestamp: TimeInterval
let entityId: UUID

init(on entityId: UUID = UUID(), at timestamp: TimeInterval = .zero) {
self.entityId = entityId
init(at timestamp: TimeInterval = .zero) {
self.timestamp = timestamp
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,11 @@ import Foundation

struct LifeEvent: TFEvent {
let timestamp: TimeInterval
let entityId: UUID
let lifeDecrease: Int
let player: Player

init(on entityId: UUID, at timestamp: TimeInterval, reduceBy: Int, player: Player) {
init(at timestamp: TimeInterval, reduceBy: Int, player: Player) {
self.timestamp = timestamp
self.entityId = entityId
self.lifeDecrease = reduceBy
self.player = player
}
Expand Down
1 change: 0 additions & 1 deletion TowerForge/TowerForge/GameModule/Events/TFEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ extension TFEventTypeWrapper: Hashable {

protocol TFEvent {
var timestamp: TimeInterval { get }
var entityId: UUID { get }
func execute(in target: EventTarget) -> EventOutput

}
Expand Down
4 changes: 2 additions & 2 deletions TowerForge/TowerForge/GameModule/GameEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ class GameEngine: AbstractGameEngine {

init(entityManager: EntityManager = EntityManager(),
systemManager: SystemManager = SystemManager(),
roomId: RoomId? = nil, currentPlayer: GamePlayer? = nil) {
roomId: RoomId? = nil, isHost: Bool = true, currentPlayer: GamePlayer? = nil) {
self.entityManager = entityManager
self.systemManager = systemManager
self.eventManager = EventManager(roomId: roomId, currentPlayer: currentPlayer)
self.eventManager = EventManager(roomId: roomId, isHost: isHost, currentPlayer: currentPlayer)
self.setupTeam()
self.setupGame()
}
Expand Down
13 changes: 6 additions & 7 deletions TowerForge/TowerForge/GameModule/GameWorld.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class GameWorld {
// Need to ensure that width is a multiple of 1024 - unit selection node height
static let worldSize = CGSize(width: 2_472, height: 1_024)

private unowned var scene: GameScene?
private var gameEngine: AbstractGameEngine
private var gameMode: GameMode
private var selectionNode: UnitSelectionNode
Expand All @@ -22,20 +21,20 @@ class GameWorld {
private let worldBounds: CGRect
private var popup: StatePopupNode
private var statisticsEngine = StatisticsEngine()

unowned var scene: GameScene? { didSet { setUpScene() } }
unowned var delegate: SceneManagerDelegate?
unowned var statePopupDelegate: StatePopupDelegate? { didSet { popup.delegate = statePopupDelegate } }

init(scene: GameScene?, screenSize: CGRect, mode: Mode,
gameRoom: GameRoom? = nil, currentPlayer: GamePlayer? = nil) {
self.scene = scene
init(screenSize: CGRect, mode: Mode, roomId: RoomId? = nil,
isHost: Bool = true, currentPlayer: GamePlayer? = nil) {
worldBounds = CGRect(origin: screenSize.origin, size: GameWorld.worldSize)
gameEngine = GameEngine(roomId: gameRoom?.roomId, currentPlayer: currentPlayer)
gameEngine = GameEngine(roomId: roomId, isHost: isHost, currentPlayer: currentPlayer)
gameMode = GameModeFactory.createGameMode(mode: mode, eventManager: gameEngine.eventManager)
selectionNode = UnitSelectionNode()
powerUpSelectionNode = PowerUpSelectionNode(eventManager: gameEngine.eventManager)
grid = Grid(screenSize: worldBounds)
popup = StatePopupNode()
renderer = TFRenderer(target: self, scene: scene)

setUp()
}
Expand Down Expand Up @@ -69,12 +68,12 @@ class GameWorld {
}

private func setUpScene() {
renderer = TFRenderer(target: self, scene: scene)
scene?.setBounds(worldBounds)
if let scene = self.scene {
grid.generateTileMap(scene: scene)
}
renderer?.renderMessage("Game Starts")

}

private func setUpGameEngine() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ class InvulnerabilityPowerUp: EventTransformation {
return event
}

return DisabledEvent(on: damageEvent.entityId, at: damageEvent.timestamp)
return DisabledEvent()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,18 @@ class HealthSystem: TFSystem {

healthComponent.adjustHealth(amount: hp)

if healthComponent.currentHealth <= 0 {
guard healthComponent.currentHealth <= 0 else {
return
}

guard let currentPlayer = eventManager.currentPlayer else {
eventManager.add(KillEvent(on: currentEntity.id, at: CACurrentMediaTime(), player: playerComponent.player))
return
}

if eventManager.isHost {
let remoteRemoveEvent = RemoteKillEvent(id: entityId, player: playerComponent.player, source: currentPlayer)
eventManager.add(remoteRemoveEvent)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,19 @@ class PositionSystem: TFSystem {
guard let playerComponent = entity.component(ofType: PlayerComponent.self) else {
return
}
// TODO: Might need some change
if entity is BaseUnit {
eventManager.add(LifeEvent(on: entity.id, at: CACurrentMediaTime(),
reduceBy: 1, player: playerComponent.player))
}

eventManager.add(RemoveEvent(on: entity.id, at: CACurrentMediaTime()))

guard entity is BaseUnit else {
return
}

guard let player = eventManager.currentPlayer else {
return eventManager.add(LifeEvent(at: CACurrentMediaTime(), reduceBy: 1, player: playerComponent.player))
}

if eventManager.isHost {
eventManager.add(RemoteLifeEvent(reduceBy: 1, player: playerComponent.player, source: player))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class HomeSystem: TFSystem {
return eventManager.add(spawnEvent)
}

// Report spawn to which will propogate to all players evenly
// Report spawn to network which will propogate to all players evenly
let spawnEvent = RemoteSpawnEvent(ofType: type, location: snapPosition, player: currentPlayer)
eventManager.add(spawnEvent)
}
Expand Down
26 changes: 16 additions & 10 deletions TowerForge/TowerForge/GameViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ class GameViewController: UIViewController {
private var gameRankProvider: GameRankProvider?
var gameMode: Mode?
var isPaused = false
var gameRoom: GameRoom?
var roomId: RoomId?
var isHost = true
var currentPlayer: GamePlayer?

@IBOutlet private var gamePopupButton: UIButton!
Expand All @@ -24,6 +25,8 @@ class GameViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = true
AchievementManager.incrementTotalGamesStarted()
AudioManager.shared.playBackground()
showGameLevelScene()

Expand All @@ -38,6 +41,7 @@ class GameViewController: UIViewController {

override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.navigationController?.isNavigationBarHidden = false
AudioManager.shared.pauseBackground()
gameWorld = nil
}
Expand All @@ -55,9 +59,10 @@ class GameViewController: UIViewController {
}

private func setUpGameWorld(scene: GameScene) {
self.gameWorld = GameWorld(scene: scene, screenSize: self.view.frame,
self.gameWorld = GameWorld(screenSize: self.view.frame,
mode: self.gameMode ?? .captureTheFlag,
gameRoom: gameRoom, currentPlayer: currentPlayer)
roomId: roomId, isHost: isHost, currentPlayer: currentPlayer)
self.gameWorld?.scene = scene
self.gameWorld?.delegate = self
self.gameWorld?.statePopupDelegate = self
}
Expand All @@ -75,13 +80,14 @@ extension GameViewController: SceneUpdateDelegate {

extension GameViewController: SceneManagerDelegate {
func showMenuScene() {
guard let mainMenuViewController =
self.storyboard?.instantiateViewController(withIdentifier: "MainMenuViewController")
as? MainMenuViewController else {
return
}

self.present(mainMenuViewController, animated: true, completion: nil)
if let targetVC = navigationController?.viewControllers.first(where: { $0 is MainMenuViewController }) {
navigationController?.popToViewController(targetVC, animated: true)
return
}
if let targetVC = storyboard?
.instantiateViewController(withIdentifier: "MainMenuViewController") as? MainMenuViewController {
present(targetVC, animated: true)
}
}
func showLevelScene() {
// TODO : to implement after Keith is done
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// RemoteKillEvent.swift
// TowerForge
//
// Created by Zheng Ze on 12/4/24.
//

import Foundation

class RemoteKillEvent: TFRemoteEvent {
let type: String
let timeStamp: TimeInterval
let source: UserPlayerId

let id: UUID
let targetIsSource: Bool

init(id: UUID, player: Player, source: GamePlayer) {
self.type = String(describing: RemoteKillEvent.self)
self.timeStamp = Date().timeIntervalSince1970
self.source = source.userPlayerId

self.id = id
self.targetIsSource = player == .ownPlayer
}

func unpack(into eventManager: EventManager, for gamePlayer: UserPlayerId) {
let player: Player = (gamePlayer == source) == targetIsSource ? .ownPlayer : .oppositePlayer // XOR
let killEvent = KillEvent(on: id, at: timeStamp, player: player)
eventManager.add(killEvent)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// RemoteLifeEvent.swift
// TowerForge
//
// Created by Zheng Ze on 12/4/24.
//

import Foundation

class RemoteLifeEvent: TFRemoteEvent {
let type: String
let timeStamp: TimeInterval
let source: UserPlayerId

let reduceBy: Int
let targetIsSource: Bool

init(reduceBy: Int, player: Player, source: GamePlayer) {
self.type = String(describing: RemoteLifeEvent.self)
self.timeStamp = Date().timeIntervalSince1970
self.source = source.userPlayerId

self.reduceBy = reduceBy
self.targetIsSource = player == .ownPlayer
}

func unpack(into eventManager: EventManager, for gamePlayer: UserPlayerId) {
let player: Player = (gamePlayer == source) == targetIsSource ? .ownPlayer : .oppositePlayer
let lifeEvent = LifeEvent(at: timeStamp, reduceBy: reduceBy, player: player)
eventManager.add(lifeEvent)
}
}
Loading

0 comments on commit d13d61e

Please sign in to comment.