-------------------------------------------------------------- -- Generic Survival Instance Server Zone Script: requiring this -- file gives the custom functions for the Survival game. -- -- updated mrb... 7/18/11 - updated for solo missions -------------------------------------------------------------- -------------------------------------------------------------- -- Includes -------------------------------------------------------------- require('ai/ACT/L_ACT_GENERIC_ACTIVITY_MGR') --////////////////////////////////////////////////////////////////////////////////// -- Script only local variables local gGamestate = { tPlayers = {}, -- players who have entered the game tWaitingPlayers = {}, -- players who haven't accepted yet iNumberOfPlayers = 0, -- number of players given from ZoneLoadedInfo iCurrentSpawned = 0, -- currently spawned enemies iTotalSpawned = 0, -- total number of spawned mobs iWaveNum = 1, -- current wave number } --////////////////////////////////////////////////////////////////////////////////// -- helper function that prints out a variable to the log function dumpVar(name,var,indent) if not self:GetVersioningInfo().bIsInternal then return end -- only do this print on internal builds if( indent == nil ) then indent = "" end if( type(var) == "table" ) then print( indent .. name .. " is a table with " .. table.maxn(var) .. " entries:" ) local i,v = next(var) while i do dumpVar(i,v,indent .. " ") i, v = next(var, i) end else local startOfLine = indent .. name .. " is " if( type(var) == "userdata" ) then if( type(var.GetID) == "function" ) then print( startOfLine .. "an object proxy with ID = " .. var:GetID() ) else print( startOfLine .. "unknown userdata" ) end elseif( var == nil ) then print( startOfLine .. "nil" ) elseif( var == true ) then print( startOfLine .. "true" ) elseif( var == false ) then print( startOfLine .. "false" ) else print( startOfLine .. "a(n) " .. type(var) .. " with value = " .. var ) end end end function onZoneLoadedInfo(self, msg) -- set the number of players that should be coming into the game self:SetNetworkVar('NumberOfPlayers', msg.maxPlayersSoft) end ---------------------------------------------------------------- -- Startup of the object ---------------------------------------------------------------- function baseStartup(self, newMsg) -- Initialize the pseudo random number generator and return math.randomseed( os.time() ) self:SetVar('playersAccepted', 0) self:SetVar('playersReady', false) end function playerConfirmed(self) local playersConfirmed = {} for k,v in ipairs(gGamestate.tPlayers) do local bPass = false for key,value in ipairs(gGamestate.tWaitingPlayers) do if value == v then bPass = true end end if not bPass then table.insert(playersConfirmed, v) end end self:SetNetworkVar('PlayerConfirm_ScoreBoard', playersConfirmed) end ---------------------------------------------------------------- -- Player has loaded into the map ---------------------------------------------------------------- function basePlayerLoaded(self, msg, newMsg) local playerID = msg.playerID:GetID() -- set player to auto-respawn msg.playerID:SetPlayerAllowedRespawn{dontPromptForRespawn = true} msg.playerID:PlayerSetCameraCyclingMode{ cyclingMode = ALLOW_CYCLE_TEAMMATES, bAllowCyclingWhileDeadOnly = true } -- adding the players to the gGamestate tables table.insert(gGamestate.tPlayers, playerID) table.insert(gGamestate.tWaitingPlayers, playerID) -- setting up player ui self:SetNetworkVar('Define_Player_To_UI', playerID) -- freeze the player movement/controls if not self:GetNetworkVar('wavesStarted') then -- updating the scoreboard for the new players self:SetNetworkVar('Update_ScoreBoard_Players', gGamestate.tPlayers) if gConstants.introCelebration then self:SetNetworkVar("WatchingIntro", gConstants.introCelebration .. "_" .. playerID) else self:SetNetworkVar('Show_ScoreBoard', true) end end -- move players to correct spawn locations SetPlayerSpawnPoints(self) if not self:GetNetworkVar('wavesStarted') then playerConfirmed(self) else local player = msg.playerID if not playerID then return end table.insert(gGamestate.tWaitingPlayers, playerID) UpdatePlayer(self, player) GetLeaderboardData(self, player, self:GetActivityID().activityID, 1) --set player stats to max player:SetHealth{health = player:GetMaxHealth{}.health} --print('max health = ' .. playerID:GetMaxHealth{}.health) player:SetArmor{armor = player:GetMaxArmor{}.armor} player:SetImagination{imagination = player:GetMaxImagination{}.imagination} end end ---------------------------------------------------------------- -- Player has exited the map ---------------------------------------------------------------- function basePlayerExit(self, msg, newMsg) local playerNum = 0 --print('player ' .. msg.playerID:GetName().name .. ' has exited') for i = 1, table.maxn(gGamestate.tPlayers) do if gGamestate.tPlayers[i] == msg.playerID:GetID() then playerNum = i end end if playerNum ~= 0 then table.remove(gGamestate.tPlayers, playerNum) -- set player to not auto-respawn msg.playerID:SetPlayerAllowedRespawn{dontPromptForRespawn=false} end playerNum = 0 for k,v in ipairs(gGamestate.tWaitingPlayers) do if msg.playerID:GetID() == v then playerNum = k end end if playerNum ~= 0 then table.remove(gGamestate.tWaitingPlayers, playerNum) end if not self:GetNetworkVar('wavesStarted') then playerConfirmed(self) --print('num of players left waiting: ' .. table.maxn(gGamestate.tWaitingPlayers)) if table.maxn(gGamestate.tPlayers) == 0 then return end if table.maxn(gGamestate.tWaitingPlayers) == 0 then --print('All players have accepted') ActivityTimerStopAllTimers(self) ActivityTimerStart(self, 'AllAcceptedDelay', 1, gConstants.startDelay) --(timerName, updateTime, stopTime) elseif table.maxn(gGamestate.tPlayers) > table.maxn(gGamestate.tWaitingPlayers) then if not self:GetVar('AcceptedDelayStarted') then self:SetVar('AcceptedDelayStarted', true) ActivityTimerStart(self, 'AcceptedDelay', 1, gConstants.acceptedDelay ) --(timerName, updateTime, stopTime) end end else UpdatePlayer(self, msg.playerID, true) if checkAllPlayersDead() then GameOver(self) end end SetActivityValue(self, msg.playerID, 1, 0) SetActivityValue(self, msg.playerID, 2, 0) local numPlayers = self:GetNetworkVar('NumberOfPlayers') self:SetNetworkVar('NumberOfPlayers', numPlayers - 1) end ---------------------------------------------------------------- -- Received a fire event messaged from someplace on the server ---------------------------------------------------------------- function baseFireEvent(self,msg, newMsg) if msg.args == 'start' then StartWaves(self) elseif msg.args == 'DeactivateRewards' then --print('fireevent DeactivateRewards') spawnerResetT(tSpawnerNetworks.rewardNetworks) end end ---------------------------------------------------------------- -- A player had died ---------------------------------------------------------------- function basePlayerDied(self, msg, newMsg) local curTime = ActivityTimerGetCurrentTime(self, 'ClockTick') local finalTime = GetActivityValue(self, msg.playerID, 1) --ActivityTimerGetCurrentTime(self, 'ClockTick') local finalWave = GetActivityValue(self, msg.playerID, 2) -- tell the client that the player has died and do GameOver self:NotifyClientZoneObject{name = 'Player_Died', paramObj = msg.playerID, rerouteID = msg.playerID, param1 = finalTime, param2 = finalWave, paramStr = tostring(checkAllPlayersDead())} -- if not self:GetNetworkVar("wavesStarted") then msg.playerID:Resurrect() return end GameOver(self) end ---------------------------------------------------------------- -- This is called when players hit the UI to exit or stop the game. ---------------------------------------------------------------- function baseMessageBoxRespond(self, msg, newMsg) if (msg.identifier == "RePlay" ) then --print("************* RePlay *************"..msg.sender:GetName().name) PlayerAccepted(self, msg.sender) playerConfirmed(self) elseif (msg.identifier == "Exit_Question" ) and msg.iButton == 1 then --print("************* Exit *************"..msg.sender:GetName().name) ResetStats(msg.sender) self:SetNetworkVar('Exit_Waves', msg.sender:GetID()) if returnLoc then -- send player to a specific location msg.sender:TransferToLastNonInstance{ playerID = msg.sender, bUseLastPosition = false, pos_x = returnLoc.x, pos_y = returnLoc.y, pos_z = returnLoc.z, rot_x = returnLoc.rx, rot_y = returnLoc.ry, rot_z = returnLoc.rz, rot_w = returnLoc.rw} else msg.sender:TransferToLastNonInstance{ playerID = msg.sender, bUseLastPosition = true} end end end ---------------------------------------------------------------- -- Custom function: Checks to see if all players have accepted, -- if they have then the game is started. ---------------------------------------------------------------- function PlayerAccepted(self, playerID) local playerNum = 0 -- check to see if the player who accepted is in the waiting players table for k,v in ipairs(gGamestate.tWaitingPlayers) do if playerID:GetID() == v then playerNum = k break end end if playerNum == 0 then return end table.remove(gGamestate.tWaitingPlayers, playerNum) --print('num of players left waiting: ' .. table.maxn(gGamestate.tWaitingPlayers)) if table.maxn(gGamestate.tWaitingPlayers) == 0 and table.maxn(gGamestate.tPlayers) >= self:GetNetworkVar('NumberOfPlayers') then --print('All players have accepted') ActivityTimerStopAllTimers(self) ActivityTimerStart(self, 'AllAcceptedDelay', 1, gConstants.startDelay) --(timerName, updateTime, stopTime) else if not self:GetVar('AcceptedDelayStarted') then self:SetVar('AcceptedDelayStarted', true) ActivityTimerStart(self, 'AcceptedDelay', 1, gConstants.acceptedDelay) --(timerName, updateTime, stopTime) end end end function ResetStats(playerID) -- set the player's imag, health and armor to full if playerID:Exists() then --set player stats to max --print('health = ' .. playerID:GetHealth{}.health) --print('armor = ' .. playerID:GetArmor{}.armor) --print('imagination = ' .. playerID:GetImagination{}.imagination) playerID:SetHealth{health = playerID:GetMaxHealth{}.health} playerID:SetArmor{armor = playerID:GetMaxArmor{}.armor} playerID:SetImagination{imagination = playerID:GetMaxImagination{}.imagination} --print('new health = ' .. playerID:GetHealth{}.health) --print('new armor = ' .. playerID:GetArmor{}.armor) --print('new imagination = ' .. playerID:GetImagination{}.imagination) --print('new imagination = ' .. playerID:GetImagination{}.imagination) end end ---------------------------------------------------------------- -- Custom function: Starts the game. ---------------------------------------------------------------- function StartWaves(self) SetupActivity(self, 4) self:SetNetworkVar("WatchingIntro", false) self:SetVar('playersReady', true) self:SetVar('baseMobSetNum', 1) self:SetVar('randMobSetNum', 1) self:SetVar('AcceptedDelayStarted', false) gGamestate.tWaitingPlayers = {} -- loop through the players and get them ready for the game to start for k,v in ipairs(gGamestate.tPlayers) do local playerID = GAMEOBJ:GetObjectByID(v) if not playerID then return end table.insert(gGamestate.tWaitingPlayers, v) UpdatePlayer(self, playerID) GetLeaderboardData(self, playerID, self:GetActivityID().activityID, 1) ResetStats(playerID) if not self:GetVar('firstTimeDone') then --remove the activity cost from the player as they load into the map local takeCost = self:ChargeActivityCost{user = playerID}.bSucceeded --print('cost taken for: ' .. playerID:GetName().name .. ' = ' .. tostring(takeCost)) end end self:SetVar('firstTimeDone', true) -- needed to get rewards -- taskType = DB name for series of achievments, target = activityID, value1 = what it will evaluate local sTaskType = 'survival_time_team' if table.maxn(gGamestate.tPlayers) == 1 then sTaskType = 'survival_time_solo' end self:SetVar('missionType', sTaskType) self:SetNetworkVar('wavesStarted', true) self:SetNetworkVar('Start_Wave_Message', "Start!") end ---------------------------------------------------------------- -- Custom function: Happens when all players have died, this -- stops all running processes and resets gGamestate variables ---------------------------------------------------------------- function GameOver(self, bWon) if not checkAllPlayersDead() and not bWon then return end ActivityTimerStopAllTimers(self) -- reset ticks gGamestate.iWaveNum = 1 -- current wave number gGamestate.iTotalSpawned = 0 -- number of mobs smashed gGamestate.iCurrentSpawned = 0 self:SetNetworkVar('wavesStarted', false) self:SetNetworkVar("Start_Cool_Down", false) SetPlayerSpawnPoints(self) clearSpawners() for k,v in ipairs(gGamestate.tPlayers) do local playerID = GAMEOBJ:GetObjectByID(v) if not playerID then return end local timeVar = GetActivityValue(self, playerID, 1) local scoreVar = GetActivityValue(self, playerID, 0) local waveVar = GetActivityValue(self, playerID, 2) self:NotifyClientZoneObject{name = 'Update_ScoreBoard', paramObj = playerID, paramStr = tostring(waveVar), param1 = timeVar} if bWon then SetPlayerSpawnPoints(self) self:SetNetworkVar('Show_ScoreBoard', true) else playerID:Resurrect() end local sTaskType = self:GetVar('missionType') or 'survival_time_team' playerID:UpdateMissionTask{ taskType = sTaskType, value = timeVar, value2 = self:GetActivityID().activityID} -- target = self, -- update mission 479 if the player is on it and has lasted 60 seconds local misState = playerID:GetMissionState{missionID = 479}.missionState if misState > 1 and misState < 4 and timeVar >= 60 then playerID:UpdateMissionTask{taskType = "complete", value = 479, value2 = 1, target = self} end -- this is to have everyone get their own time at the end of the match StopActivity(self, playerID, waveVar, timeVar, scoreVar) --print('***************************') --print('send update mission task') --print(playerID:GetName().name .. ' ' .. self:GetName().name) --print(sTaskType) --print(self:GetLOT().objtemplate) --print(timeVar) --print('***************************') end end ---------------------------------------------------------------- -- Custom function: If the game has ended and the player won ---------------------------------------------------------------- function GameWon(self) -- kill the activity timers ActivityTimerStopAllTimers(self) local resetTime = wavePreloads[gGamestate.iWaveNum - 1].winDelay or 30 -- start the reset timer ActivityTimerStart(self, 'GameOver_Win', 1, resetTime) --(timerName, updateTime, stopTime) self:SetNetworkVar('Start_Timed_Wave', {resetTime, gGamestate.iWaveNum - 1}) end ---------------------------------------------------------------- -- Called when the player is resurrected ---------------------------------------------------------------- function basePlayerResurrected(self, msg, newMsg) self:NotifyClientZoneObject{name = 'Player_Res', paramObj = msg.playerID, rerouteID = msg.playerID} if self:GetNetworkVar("wavesStarted") then return end -- tell the client to show the scoreboard self:SetNetworkVar('Show_ScoreBoard', true) TelePlayerToSpawnPoint(self, msg.playerID) end ---------------------------------------------------------------- -- Custom function: Checks to see if all the players are dead, -- then stops the game. ---------------------------------------------------------------- function checkAllPlayersDead() -- loop through the players and see if they are all dead for k,v in ipairs(gGamestate.tPlayers) do local playerID = GAMEOBJ:GetObjectByID(v) if playerID:Exists() then if not playerID:IsDead().bDead then return false end end end return true end ---------------------------------------------------------------- -- Teleports the players to the correct locations for the start of the game ---------------------------------------------------------------- function SetPlayerSpawnPoints(self) -- looop through the players and teleprot them to the correct positions for k,v in ipairs(gGamestate.tPlayers) do local playerID = GAMEOBJ:GetObjectByID(v) TelePlayerToSpawnPoint(self, playerID, k) end end ---------------------------------------------------------------- -- Teleports the players to the correct locations for the start of the game ---------------------------------------------------------------- function TelePlayerToSpawnPoint(self, playerID, spawnNum) if playerID:Exists() then if not spawnNum then for k,v in ipairs(gGamestate.tPlayers) do if playerID:GetID() == v then spawnNum = k end end end local spawnObj = self:GetObjectsInGroup{ group = 'P' .. spawnNum .. '_Spawn', ignoreSpawners = true }.objects[1] if spawnObj then local pos = spawnObj:GetPosition().pos local rot = spawnObj:GetRotation() playerID:Teleport{pos = pos, x = rot.x, y = rot.y, z = rot.z, w = rot.w, bSetRotation = true} end end end ---------------------------------------------------------------- -- Custom function: Spawns mobs on a spawner network, Now... ---------------------------------------------------------------- function spawnNow(spawnerName, spawnNum, spawnLOT) local spawner = LEVEL:GetSpawnerByName(spawnerName) if spawner then --print('*** Spawn Now!!') -- set the LOT to spawn if it's sent to the function if spawnLOT then spawner:SpawnerSetSpawnTemplateID{iObjTemplate = spawnLOT} end -- set the number of LOT's to spawn if it's sent to the function if spawnNum then spawner:SpawnerSetMaxToSpawn{iNum = spawnNum} spawner:SpawnerSetNumToMaintain{uiNum = spawnNum} end -- activate and reset the spawner network spawner:SpawnerActivate() spawner:SpawnerReset() end end ---------------------------------------------------------------- -- Custom function: Decides how to spawn mobs ---------------------------------------------------------------- function spawnWave(self) -- dont do this if the minigame hasn't started if not self:GetNetworkVar('wavesStarted') then return end local spawnNum = gGamestate.iWaveNum local waveLoad = wavePreloads[spawnNum] -- there is no wavePreload for this spawnNum end game and print warning if not waveLoad then if self:GetVersioningInfo().bIsInternal then -- only do this print on internal builds print("** missing waveLoad **") end GameOver(self, true) return end --print("** starting wave #" .. gGamestate.iWaveNum .. " **") if waveLoad.winDelay then -- if we have a winDelay this is the last wave -- tell clients to display win message self:SetNetworkVar('Won_Wave', gGamestate.iWaveNum) -- if we dont want to wait for the notify from some object (treasureChest) then do end the game if not waveLoad.winNotify then GameWon(self) end for k,playerID in ipairs(gGamestate.tPlayers) do local player = GAMEOBJ:GetObjectByID(playerID) if player:Exists() then if player:IsDead().bDead then player:Resurrect() end end end else -- if we have an optTime start the timer for the next wave if waveLoad.optTime then --print("Wave time = " .. waveLoad.optTime) ActivityTimerStart(self, 'TimedWave', 1, waveLoad.optTime) --(timerName, updateTime, stopTime) self:SetNetworkVar('Start_Timed_Wave', {waveLoad.optTime, gGamestate.iWaveNum}) else -- display new wave message self:SetNetworkVar('New_Wave', gGamestate.iWaveNum) end end -- if we have an optional event send it out to the eventGroup if waveLoad.optEvent then -- see if we have an optEvent to override the global eventGroup local groupName = waveLoad.optEventGroup or gGamestate.eventGroup if groupName then -- get the objects in the group local group = GAMEOBJ:GetObjectsInGroup{group = groupName, ignoreSpawners = true} -- fireEvent to each object in the group for k,obj in ipairs(group) do obj:FireEvent{senderID = self, args = waveLoad.optEvent} end end end -- if we have a celebration to play then do that if waveLoad.optCelebration then self:SetNetworkVar('startCelebration', waveLoad.optCelebration) end -- if we have a celebration to play then do that if waveLoad.optCinematic then local cineTime = LEVEL:GetCinematicInfo(waveLoad.optCinematic) or 0 -- if we have a valid cinematic then start the cinematicDone timer and tell the client to play it if cineTime > 0 then ActivityTimerStart(self, "cinematicDone", cineTime, cineTime) self:SetNetworkVar('startCinematic', waveLoad.optCinematic) end end -- reset the current spawned # of Objs gGamestate.iCurrentSpawned = 0 -- spawn the mobs on the spawners based on the waveLoad for k,tMob in ipairs(waveLoad) do if tMob.name then spawnNow(tMob.name, tMob.num, tMob.LOT) local num = tMob.num or 1 gGamestate.iCurrentSpawned = gGamestate.iCurrentSpawned + num end end -- increment the waveNum and set the current spawned gGamestate.iWaveNum = gGamestate.iWaveNum + 1 --print("** Spawned Enemies = " .. gGamestate.iCurrentSpawned) gGamestate.iTotalSpawned = gGamestate.iTotalSpawned + gGamestate.iCurrentSpawned self:SetNetworkVar("numRemaining", gGamestate.iCurrentSpawned) end ---------------------------------------------------------------- -- Custom function: Clears the spawner networks ---------------------------------------------------------------- function clearSpawners() --search through the list of spawner names and clear them for k,name in pairs(spawnerNames) do local spawner = LEVEL:GetSpawnerByName(name) if spawner then spawner:SpawnerDestroyObjects() spawner:SpawnerDeactivate() spawner:SpawnerReset() end end end ---------------------------------------------------------------- -- Received a notify object message ---------------------------------------------------------------- function UpdateSpawnedEnemies(self, enemy, score) if not self:GetNetworkVar("wavesStarted") then return end gGamestate.iCurrentSpawned = gGamestate.iCurrentSpawned - 1 --print("currentSpawned = " .. gGamestate.iCurrentSpawned) if enemy:Exists() then -- check to make sure the player is in the activity if enemy:IsCharacter().isChar and IsPlayerInActivity(self, enemy) then -- update kill score UpdateActivityValue(self, enemy, 0, score) end end if gGamestate.iCurrentSpawned < 1 then local nextWave = gGamestate.iWaveNum local curTime = ActivityTimerGetCurrentTime(self, 'ClockTick') local curWave = gGamestate.iWaveNum-1 -- if there's no more waves then we won and dont want to store out info for the last wave if nextWave >= table.maxn(wavePreloads) then -- if we dont want to wait for the notify from some object (treasureChest) then do end the game if not wavePreloads[nextWave] then GameWon(self) return false end -- kill the activity timers ActivityTimerStopAllTimers(self) -- update the timer with the current time self:SetNetworkVar('Update_Timer', curTime) end ActivityTimerStart(self, 'WaveCompleteDelay', gConstants.waveCompleteDelay, gConstants.waveCompleteDelay) --(timerName, updateTime, stopTime) --print("*** Next round in " .. gConstants.waveTime .. " seconds ***") -- set player score for k,playerID in ipairs(gGamestate.tPlayers) do local player = GAMEOBJ:GetObjectByID(playerID) if player:Exists() then SetActivityValue(self, player, 1, curTime) SetActivityValue(self, player, 2, curWave) local waveMissions = wavePreloads[curWave].updateMissions or {} for k, missionID in ipairs(waveMissions) do player:UpdateMissionTask{taskType = "complete", value = missionID, value2 = 1, target = self} end -- update solo missions when there is only one player if table.maxn(gGamestate.tPlayers) == 1 then local waveSoloMissions = wavePreloads[curWave].soloUpdateMissions or {} for k, missionID in ipairs(waveSoloMissions) do player:UpdateMissionTask{taskType = "complete", value = missionID, value2 = 1, target = self} end end end end self:SetNetworkVar('Wave_Complete', {curWave, curTime}) return true end self:SetNetworkVar("numRemaining", gGamestate.iCurrentSpawned) return false end function UpdateMissionForAllPlayers(self, missionID) for k,playerID in ipairs(gGamestate.tPlayers) do local player = GAMEOBJ:GetObjectByID(playerID) if player:Exists() then player:UpdateMissionTask{taskType = "complete", value = missionID, value2 = 1, target = self} end end end ---------------------------------------------------------------- -- When activity is stopped this is needed to update the leaderboard. ---------------------------------------------------------------- function baseDoCalculateActivityRating(self, msg) msg.outActivityRating = msg.fValue2 return msg end -- activity timers ---------------------------------------------------------------- -- When ActivityTimerUpdate is sent, basically when a timer hits it updateInterval. ---------------------------------------------------------------- function onActivityTimerUpdate(self, msg) if msg.name == "AcceptedDelay" then --print('update delay timer to ' .. math.ceil(msg.timeRemaining)) self:SetNetworkVar('Update_Default_Start_Timer', math.ceil(msg.timeRemaining)) elseif msg.name == "ClockTick" then self:SetNetworkVar('Update_Timer', msg.timeElapsed) elseif msg.name == "NextWaveTick" or msg.name == "TimedWave" or msg.name == "GameOver_Win" then self:SetNetworkVar('Update_Cool_Down', math.ceil(msg.timeRemaining)) end end ---------------------------------------------------------------- -- When ActivityTimerDone is sent, basically when the activity timer has reached it's duration. -- TODO: make the waves not respawn until all the mobs in a wave are dead ---------------------------------------------------------------- function onActivityTimerDone(self, msg) if msg.name == "AcceptedDelay" then --or msg.name == "AllAcceptedDelay" --print('update delay timer to 0') self:SetNetworkVar('Update_Default_Start_Timer', 0) ActivityTimerStart(self, 'AllAcceptedDelay', 1, 1) elseif msg.name == "AllAcceptedDelay" then --or msg.name == "AllAcceptedDelay" --print('accepted delay *******************************') self:SetNetworkVar('Clear_Scoreboard', true) ActivityTimerStart(self, 'StartDelay', 4, 4) --(timerName, updateTime, stopTime) StartWaves(self) elseif msg.name == "StartDelay" then --print('adding in timers *******************************') ActivityTimerStart(self, 'ClockTick', 1) --(timerName, updateTime, stopTime) spawnWave(self) ActivityTimerStart(self, 'PlaySpawnSound', 3, 3) --(timerName, updateTime, stopTime) elseif msg.name == "PlaySpawnSound" then -- play war horn sound for k,v in ipairs(gGamestate.tPlayers) do GAMEOBJ:GetObjectByID(v):PlayNDAudioEmitter{m_NDAudioEventGUID = '{ca36045d-89df-4e96-a317-1e152d226b69}'} end elseif msg.name == "NextWaveTick" then self:SetNetworkVar("Start_Cool_Down", false) spawnWave(self) elseif msg.name == "WaveCompleteDelay" then self:SetNetworkVar('Start_Cool_Down', gConstants.waveTime) ActivityTimerStart(self, 'NextWaveTick', 1, gConstants.waveTime) --(timerName, updateTime, stopTime) elseif msg.name == "TimedWave" then ActivityTimerStart(self, 'WaveCompleteDelay', gConstants.waveCompleteDelay, gConstants.waveCompleteDelay) --(timerName, updateTime, stopTime) local curTime = ActivityTimerGetCurrentTime(self, 'ClockTick') local curWave = gGamestate.iWaveNum-1 self:SetNetworkVar('Wave_Complete', {curWave, curTime}) elseif msg.name == "GameOver_Win" then GameOver(self, true) elseif msg.name == "cinematicDone" then local bossObjs = self:GetObjectsInGroup{ group = 'boss', ignoreSpawners = true }.objects for k, obj in ipairs(bossObjs) do obj:NotifyObject{ObjIDSender = self, name = "startAI"} end end end