spawns = {} SPAWN_DATA = {} CONSTANTS = {} waves = {} PLAYER_SCORE = {} EFFECTS = {} ACTORS = {} STORECONSTANTS = {} m_totalscore = 0 -------------------------------------------------------------- -- Startup -------------------------------------------------------------- function onStartup(self) -- set game state resetVars(self) LOCALS["GameStarted"] = false self:SetVar("timelimit", waves[1].timeLimit) m_totalscore = 0 end function setCONSTANTS( self,spawns,SPAWN_DATA,CONSTANTS , waves, PLAYER_SCORE, EFFECTS , ACTORS, STORECONSTANTS) spawns = spawns SPAWN_DATA = SPAWN_DATA CONSTANTS = CONSTANTS waves = waves PLAYER_SCORE = PLAYER_SCORE EFFECTS = EFFECTS ACTORS = ACTORS STORECONSTANTS = STORECONSTANTS self:SetVar("CONSTANTS", CONSTANTS) self:SetVar("Matrix", 1) end -------------------------------------------------------------- -- Helper Functions -------------------------------------------------------------- -------------------------------------------------------------- -- play effects on all effects in the scene -------------------------------------------------------------- function PlaySceneEffect(effectName) -- trigger effects on effect objects for effectID = 1, #EFFECTS do local effect = GAMEOBJ:GetObjectByID(EFFECTS[effectID]) effect:PlayFXEffect{ effectType = effectName } end end -------------------------------------------------------------- -- play animations on all actors in the scene, and others -------------------------------------------------------------- function PlaySceneAnimation(anim, bPlayCannon, bPlayPlayer) -- play animation on actors for actorID = 1, #ACTORS do local actor = GAMEOBJ:GetObjectByID(ACTORS[actorID]) actor:PlayAnimation{ animationID = anim } end -- play on cannon if (bPlayCannon == true) then local cannon = getObjectByName("cannonObject") cannon:PlayAnimation{ animationID = anim } end -- play on player if (bPlayPlayer == true) then local player = getObjectByName("activityPlayer") player:PlayAnimation{ animationID = anim } end end -------------------------------------------------------------- -- return if template is a valid actor -------------------------------------------------------------- function IsValidActor(templateID) for actors = 1, #STORECONSTANTS["VALID_ACTORS"] do if (templateID == STORECONSTANTS["VALID_ACTORS"][actors]) then return true end end return false end -------------------------------------------------------------- -- return if template is a valid effect -------------------------------------------------------------- function IsValidEffect(templateID) for effects = 1, #STORECONSTANTS["VALID_EFFECTS"] do if (templateID == STORECONSTANTS["VALID_EFFECTS"][effects]) then return true end end return false end -------------------------------------------------------------- -- put the player in the cannon, does not start the cannon -------------------------------------------------------------- function enterCannon(self) -- get the cannon local cannon = getObjectByName("cannonObject") self:NotifyClientZoneObject{ name= "HideScoreBoard"} -- get the player local player = getObjectByName("activityPlayer") -- if we have both start it if ((cannon) and (player)) then cannon:RequestActivityEnter{bStart = false, userID = player} self:NotifyClientZoneObject{ name= "ReSetSuperCharge" } self:NotifyClientZoneObject{ name= "showloadingUI"} end end function spawnNewModel(self) if self:GetVar("currentReward") ~= -1 then local rewards = self:GetVar("rewards") if rewards and rewards[1] ~= -1 then table.insert(rewards, self:GetVar("currentReward")) else rewards = {self:GetVar("currentReward")} end self:SetVar("rewards",rewards) self:NotifyClientZoneObject{name = "rewardAdded", param1 = self:GetVar("currentReward")} end local obj = self:GetObjectsInGroup{ignoreSpawners=true,group= CONSTANTS["Reward_Model_GrpName"]}.objects if(#obj > 0) then for index, rewardObj in pairs(obj) do local items = GAMEOBJ:RollLoot(CONSTANTS["Score_LootMatrix_"..self:GetVar("Matrix")], getObjectByName("activityPlayer")) for LOT,count in pairs(items) do rewardObj:SetModelToBuild{templateID=LOT} self:SetVar("currentReward", LOT) end end end end -------------------------------------------------------------- -- try to start the game -------------------------------------------------------------- function startGame(self) -- clear score self:NotifyClientZoneObject{ name= "game_timelimit" , param1 = waves[1].timeLimit} getObjectByName("cannonObject"):NotifyObject{ name= "GetLeaderData"} self:NotifyClientZoneObject{ name= "ReSetSuperCharge"} self:NotifyClientZoneObject{ name= "Audio_Start_Intro"} self:NotifyClientZoneObject{ name= "ShowSuper"} self:SetVar("currentReward", -1) -- get the cannon local cannon = getObjectByName("cannonObject") local obj = self:GetObjectsInGroup{ignoreSpawners=true,group= CONSTANTS["Reward_Model_GrpName"]}.objects for i, j in pairs(obj) do j:SetModelToBuild{templateID=-1} end self:NotifyClientZoneObject{ name= "StoredCannon", paramaObj = cannon} self:SetVar("NumberOfCharges", 0 ) local idString = self:GetID() -- get the player local player = getObjectByName("activityPlayer") -- if we have both start it if ((cannon) and (player)) then -- put the player in if we have to, otherwise start if ((cannon:GetActivityUser().userID):GetID() ~= player:GetID()) then ----print("wrong player") self:NotifyClientZoneObject{ name= "Clear", param1= 0} else ----print("starting game") self:NotifyClientZoneObject{ name= "Clear", param1=0} cannon:ActivityStart{ rerouteID = player } end DoGameStartup(self) end spawnNewModel(self) end -------------------------------------------------------------- -- try to stop the game -------------------------------------------------------------- function stopGame(self, bCanceling) self:NotifyClientZoneObject{ name= "ReSetSuperCharge"} self:NotifyClientZoneObject{ name= "HideSuper"} ----print("STOPING GAME ******************************************") -- get the cannon local cannon = getObjectByName("cannonObject") -- get the player local player = getObjectByName("activityPlayer") -- if we have both stop it if we need to, but dont exit if ((cannon) and (player)) then -- Now retrieve everything form the cannon. We have the score here so we do the rest here too local streak = cannon:GetVar("m_maxStreak") local misses = cannon:GetVar("m_misses") local fired = cannon:GetVar("m_shotsFired") cannon:SetActivityUserData{ userID = player, typeIndex = 0, value = m_totalscore } cannon:SetActivityUserData{ userID = player, typeIndex = 1, value = streak } local percentage = 0 if (fired > 0) then percentage = (fired-misses) / fired end cannon:SetActivityUserData{ userID = player, typeIndex = 2, value = percentage } -- Tell the leaderboard to store everything cannon:UpdateActivityLeaderboard{ userID = player } cannon:ActivityStop{rerouteID = player, bExit = false, bUserCanceled = bCanceling} self:NotifyClientZoneObject{ name= "Clear", param1= 0} self:SetVar("Mym_totalscore", m_totalscore) m_totalscore= 0 getObjectByName( "Cannon_Timer"):NotifyObject{ name = "Stop" } DoGameShutdown(self) -- if we are not exiting, shwo the summary and allow for retry if (bCanceling == false) then showSummaryDialog(self, fired, fired-misses, streak) end awardModels(self:GetVar("rewards"), player) end end function awardModels(rewards, player) if rewards and rewards[1] ~= -1 then for index, reward in pairs(rewards) do player:AddItemToInventory{iObjTemplate = reward, invType = 5 --[[5 is INVENTORY_MODEL--]] } end end end function resetVars(self) LOCALS["SpawnNum"] = 0 LOCALS["CurSpawnNum"] = 0 LOCALS["ThisWave"] = 0 LOCALS["GameScore"] = 0 LOCALS["GameTime"] = 0 LOCALS["GameStarted"] = false self:SetVar("StreakBonus",0) self:SetVar("StopCharge", false ) self:SetVar("NumberOfCharges", 0 ) self:SetVar("LastSuperTotal", nil ) self:SetVar("SuperCharged", "notCharged") self:SetVar("WaveStatus", true) self:SetVar("Matrix", 1) self:SetVar("currentReward", -1) self:SetVar("rewards", {-1}) -- reset scores for waveNum = 1, tonumber(STORECONSTANTS["NUM_WAVES"]) do PLAYER_SCORE[waveNum] = 0 end end -------------------------------------------------------------- -- handle all the game startup data -------------------------------------------------------------- function DoGameStartup(self) --showSummaryDialog(self) -- set game state and vars resetVars(self) LOCALS["GameStarted"] = true self:NotifyClientZoneObject{ name= "Clear"} -- start the first wave LOCALS["ThisWave"] = 1 if CONSTANTS["FIRST_WAVE_START_TIME"] < 1 then CONSTANTS["FIRST_WAVE_START_TIME"] = 1 end GAMEOBJ:GetTimer():AddTimerWithCancel( CONSTANTS["FIRST_WAVE_START_TIME"], "SpawnWave1",self ) -- Scene animations and wave number DISABLED for start, we use 3/2/1/Go instead -- play wave animation on actors, cannon, and player --PlaySceneAnimation("wave" .. LOCALS["ThisWave"], true, true) -- display wave number to player --DisplayWaveNumberToPlayer(self, LOCALS["ThisWave"]) -- set the cannon reticule back to start end -------------------------------------------------------------- -- handle all the game shutdown data -------------------------------------------------------------- function DoGameShutdown(self) ----print("DoGameShutdown GAME ******************************************") ----print("game shutdown") LOCALS["GameStarted"] = false -- cancel all timers GAMEOBJ:GetTimer():CancelAllTimers( self ) -- despawn all spawns DestroyAllSpawns(self) end -------------------------------------------------------------- -- Remove the player from the zone -------------------------------------------------------------- function RemovePlayerFromZone(self, player) player:ServerSetUserCtrlCompPause{bPaused = false} -- UNCOMMENT to go back to the other zone player:TransferToLastNonInstance{ playerID = player, bUseLastPosition = true } end -------------------------------------------------------------- -- Get a random path -------------------------------------------------------------- function GetRandomPath(spawn) -- pick a random local ran = math.random(1,#spawn.path) return spawn.path[ran] end -------------------------------------------------------------- -- spawn an object for the game -------------------------------------------------------------- function SpawnObject(num, spawn, self, bSpawnNow) -- get the current spawn number local spawnNum = IncrementVarAndReturn("SpawnNum") -- save the spawn data for the object when it is loaded local SpawnData = {sdTemplate = spawn.id, sdRespawn = spawn.bRespawn, sdSpeed = spawn.speed, sdScore = spawn.score, sdPath = GetRandomPath(spawn), sdnum = num, sdChangeSpeed = spawn.bChangeSpeed, sdSpeedChance = spawn.speedChangeChance, sdMinSpeed = spawn.minSpeed, sdMaxSpeed = spawn.maxSpeed, sdMovingPlat = spawn.bMovingPlatform, sdDespawnTime = spawn.despawnTime, sdTimeScore = spawn.timeScore, bSpawned = false} -- store the data SPAWN_DATA[tonumber(spawnNum)] = SpawnData -- set the timer to spawn the object local timerName = "DoSpawn" .. spawnNum -- spawn now and use initial spawn times if (bSpawnNow == true) then if (spawn.initSpawnTimeMin > 0 and spawn.initSpawnTimeMax > 0) then local ranSpawnTime = (math.random() * (spawn.initSpawnTimeMax - spawn.initSpawnTimeMin)) + spawn.initSpawnTimeMin ----print ("init spawning with time " .. ranSpawnTime) if ranSpawnTime < 1 then ranSpawnTime = 1 end GAMEOBJ:GetTimer():AddTimerWithCancel( ranSpawnTime, timerName, self ) else GAMEOBJ:GetTimer():AddTimerWithCancel( 1, timerName, self ) end -- respawn, use respawn times elseif (spawn.bRespawn == true) then -- pick a random spawn time local ranSpawnTime = (math.random() * (spawn.maxTime - spawn.minTime)) + spawn.minTime if ranSpawnTime < 1 then ranSpawnTime = 1 end GAMEOBJ:GetTimer():AddTimerWithCancel( ranSpawnTime, timerName, self ) end end -------------------------------------------------------------- -- destroys all spawns -------------------------------------------------------------- function DestroyAllSpawns(self) local maxSpawnNum = LOCALS["CurSpawnNum"] for spawn = 1, maxSpawnNum do -- @TODO: (Optimize this) local spawnObject = getObjectByName("spawnObject" .. spawn) if (spawnObject) then if (spawnObject:Exists() and not spawnObject:IsDead().bDead) then ----print("removing spawn object " .. spawn) spawnObject:Die{killerID = spawnObject, killType = "SILENT"} end end end -- reset vars LOCALS["SpawnNum"] = 0 LOCALS["CurSpawnNum"] = 0 end -------------------------------------------------------------- -- sends a message to display the current wave text to player -------------------------------------------------------------- function DisplayWaveNumberToPlayer(self, waveNum) -- @TODO: (Optimize) local player = getObjectByName("activityPlayer") if (player) then player:ShowFlashingText{text = waves[tonumber(waveNum)].waveStr} self:NotifyClientZoneObject{ name= "wave", param1= waveNum} end end -------------------------------------------------------------- -- look through spawn data to find the most recent data -- that matches the template, returns nil or data -------------------------------------------------------------- function GetLatestSpawnDataByTemplate(self,templateID) local spawnNum = LOCALS["SpawnNum"] while (spawnNum > 0) do -- get the data local SpawnData = SPAWN_DATA[tonumber(spawnNum)] -- check spawn flag and template if (SpawnData.bSpawned == false and templateID == SpawnData.sdTemplate) then -- set spawned flag SpawnData.bSpawned = true -- re-save data SPAWN_DATA[tonumber(spawnNum)] = SpawnData -- return the good data return SpawnData end -- try prev spawn data spawnNum = spawnNum - 1 end return nil end -------------------------------------------------------------- -- show the summary dialog -------------------------------------------------------------- function showSummaryDialog(self, shots, kills, streak) local cannon = getObjectByName("cannonObject") -- get player local player = getObjectByName("activityPlayer") if (player) then -- do summary dialog -- Wave Score local score = m_totalScore local r = cannon:GetActivityReward{ playerID = player} local rstring = (r.rewardMoney..","..r.rewardItem1Name..","..r.rewardItem1Image..","..r.rewardItem1StackSize..","..r.rewardItem2Name..","..r.rewardItem2Image..","..r.rewardItem2StackSize) local rscore = ( self:GetVar("Mym_totalscore")..","..PLAYER_SCORE[1]..","..PLAYER_SCORE[2]..","..PLAYER_SCORE[3]..","..shots..","..kills..","..streak ) self:NotifyClientZoneObject{ name= "UI_Score", paramStr = rscore} self:NotifyClientZoneObject{ name= "UI_Rewards", paramStr = rstring} self:NotifyClientZoneObject{ name= "Audio_Final_Wave_Done"} cannon:NotifyObject{ name= "Cannon_Reset"} if (cannon) then cannon:RequestActivitySummaryLeaderboardData{ user = player, queryType = 7} end end end -------------------------------------------------------------- -- Add more time to the current wave timer -------------------------------------------------------------- function AddTimeToWave(self, timeToAdd) -- get wave number local waveNum = LOCALS["ThisWave"] -- check on next wave waveNum = waveNum + 1 -- get correct timer name local timerName = "GameOver" if (waveNum <= STORECONSTANTS["NUM_WAVES"]) then timerName = "SpawnWave" .. waveNum end -- get the time left local theTime = GAMEOBJ:GetTimer():GetTime(timerName,self ) if (theTime > 0.0) then -- cancel timer and add a new one with more time GAMEOBJ:GetTimer():CancelTimer(timerName, self) theTime = theTime + timeToAdd if theTime < 0 then theTime = 0.1 end GAMEOBJ:GetTimer():AddTimerWithCancel( theTime, timerName, self ) -- get the cannon local cannon = getObjectByName("cannonObject") cannon:AddActivityTime{ rerouteID = getObjectByName("activityPlayer"), timeToAdd = timeToAdd } end end function RecordPlayerWaveScore(self) -- get wave number local waveNum = tonumber(LOCALS["ThisWave"]) if (waveNum > 0) then -- get total current score local score = m_totalscore -- to get the wave score we must subtract prior waves from it for waves = 1, waveNum - 1 do score = score - PLAYER_SCORE[waves] end -- store the new score PLAYER_SCORE[waveNum] = score -- ----print("*************** SCORE? "..PLAYER_SCORE[waveNum]) end end -------------------------------------------------------------- -- Game Message Handlers -------------------------------------------------------------- -------------------------------------------------------------- -- Timers -------------------------------------------------------------- onTimerDone = function(self, msg) if msg.name == "endGameBuffer" then local cannonballs = self:GetObjectsInGroup{ group = "cannonball" }.objects if #cannonballs >= 1 then GAMEOBJ:GetTimer():AddTimerWithCancel( 1, "endGameBuffer", self ) else RecordPlayerWaveScore(self) stopGame(self, false) getObjectByName("Cannon_Timer"):NotifyObject{ name = "Stop" } end end -- parse the name to get out the wave number -- use the wave number to select the spawns -- of format "SpawnWaveXXX" where XXX is the spawn number --print ("Timer finished"..msg.name) if (string.starts(msg.name,"SpawnWave")) then if (LOCALS["GameStarted"] == true) then self:SetVar("WaveStatus", true) if LOCALS["ThisWave"] ~= 1 and self:GetVar("StopCharge" ) == true then getObjectByName("Cannon_Timer"):NotifyObject{ name = "ResetCharge" } end cannonTimer = getObjectByName("Cannon_Timer") -- cancel all timers GAMEOBJ:GetTimer():CancelAllTimers( self ) cannonTimer:NotifyObject{ name = "Start" } -- store this wave number waveNum = LOCALS["ThisWave"] self:SetVar("ThisWave", waveNum) ----print("Spawning Wave " .. waveNum) -- DestroyAllSpawns(self) -- setup spawns for wave for k,v in pairs(spawns[tonumber(waveNum)]) do SpawnObject(k,v,self,true) end -- move to the next wave --waveNum = waveNum + 1 -- there are no more waves left -- so stop game after this wave if (tonumber(waveNum) >= STORECONSTANTS["NUM_WAVES"]) then GAMEOBJ:GetTimer():AddTimerWithCancel( waves[tonumber(waveNum)].timeLimit , "GameOver", self ) else local myTimer = waves[tonumber(waveNum)].timeLimit -- setup next wave GAMEOBJ:GetTimer():AddTimerWithCancel( myTimer, "EndWave" .. waveNum,self ) end local cannon = getObjectByName("cannonObject") local player = getObjectByName("activityPlayer") if cannon and player then cannon:StartActivityTime{ rerouteID = player, startTime = waves[tonumber(waveNum)].timeLimit } cannon:ActivityPause{ rerouteID = player, bPause = false } end end end -- called when a wave ends, contains the number of the next wave if (string.starts(msg.name,"EndWave")) then if (LOCALS["GameStarted"] == true) then self:SetVar("WaveStatus", false) -- get rid of current spawns --DestroyAllSpawns(self) getObjectByName("Cannon_Timer"):NotifyObject{ name = "Stop" } -- cancel all timers GAMEOBJ:GetTimer():CancelAllTimers( self ) -- record the score RecordPlayerWaveScore(self) -- get the wave number from the rest of the string local waveNum = string.sub(msg.name,8) -- store the next wave number waveNum = tonumber(waveNum) + 1 LOCALS["ThisWave"] = waveNum -- @TODO: Do whatever we need to during the pause, wave begins after pause -- play wave animation on actors, cannon, and player PlaySceneAnimation("wave" .. LOCALS["ThisWave"], true, true) -- display wave number to player DisplayWaveNumberToPlayer(self, waveNum) -- there are no more waves left -- so stop game after this wave if (waveNum > STORECONSTANTS["NUM_WAVES"]) then -- setup next wave GAMEOBJ:GetTimer():AddTimerWithCancel( 0.1, "GameOver", self ) else -- setup next wave GAMEOBJ:GetTimer():AddTimerWithCancel( CONSTANTS["IN_BETWEEN_WAVE_PAUSE"], "SpawnWave" .. waveNum,self ) end local player = getObjectByName("activityPlayer") local cannon = getObjectByName("cannonObject") if player and cannon then cannon:ActivityPause{rerouteID = player, bPause = true} end end end -- parse the name to get out the spawn number -- use the spawn number to select the template id -- load the object -- of format "DoSpawnXXX" where XXX is the spawn number if (string.starts(msg.name,"DoSpawn")) then if (LOCALS["GameStarted"] == true) then -- get the spawn number from the rest of the string local spawnNum = string.sub(msg.name,8) -- get the template out of the spawn data local SpawnData = SPAWN_DATA[tonumber(spawnNum)] local templateID = SpawnData.sdTemplate ----print("spawning " .. spawnNum) -- get the position of the first waypoint local startPos = GAMEOBJ:GetWaypointPos( SpawnData.sdPath, 1 ) local config = {{"spawndata", SpawnData},{"streakmod", CONSTANTS["STREAK_MOD"]},{"streakbonus", STORECONSTANTS["STREAK_BONUS"]}, {"wave", LOCALS["ThisWave"]} , {"custom_script_server", "scripts/ai/ACT/SG_TARGET.lua" },{"custom_script_client", "scripts/client/ai/SG_TARGET_CLIENT.lua" }} -- load the object in the world RESMGR:LoadObject { objectTemplate = templateID, bIsSmashable = true, x = startPos.x, y = startPos.y, z = startPos.z, owner = self, configData = config} end end -- end the game if (msg.name == "GameOver") then -- Send buffer timer here local player = getObjectByName("activityPlayer") local cannon = getObjectByName("cannonObject") local cannonballs = self:GetObjectsInGroup{ group = "cannonball" }.objects cannon:ActivityPause{ rerouteID = player, bPause = true } if #cannonballs >= 1 then GAMEOBJ:GetTimer():AddTimerWithCancel( 1, "endGameBuffer", self ) else RecordPlayerWaveScore(self) stopGame(self, false) getObjectByName("Cannon_Timer"):NotifyObject{ name = "Stop" } end end end -------------------------------------------------------------- -- Called when a Child is loaded -------------------------------------------------------------- function onChildLoaded(self, msg) -- look through spawn data to find the most recent data -- that matches the template local SpawnData = GetLatestSpawnDataByTemplate(self,msg.templateID) if (SpawnData) then local curSpawnNum = IncrementVarAndReturn("CurSpawnNum") -- store spawn for use later storeObjectByName("spawnObject" .. curSpawnNum, msg.childID) -- store who the parent is storeParent(self, msg.childID) -- store the spawn data in the child (@TODO: Need to Optimize) msg.childID:SetVar("SpawnData", SpawnData) if (SpawnData.sdMovingPlat == true) then msg.childID:SetPathingSpeed{ speed = SpawnData.sdSpeed } msg.childID:SetCurrentPath{ pathName = SpawnData.sdPath, startPoint = 0 } else -- assign child's waypoint msg.childID:SetVar("attached_path",SpawnData.sdPath) msg.childID:SetVar("attached_path_start",0) local startpos = GAMEOBJ:GetWaypointPos( SpawnData.sdPath, 1 ) msg.childID:SetPosition{pos = startpos} -- start child on path msg.childID:FollowWaypoints() msg.childID:SetPathingSpeed{ speed = SpawnData.sdSpeed } end else end end -------------------------------------------------------------- -- Called when Player Loads into Zone -------------------------------------------------------------- function mainPlayerLoaded(self, msg) self:NotifyClientZoneObject{ name= "Clear"} ----print ("Player Entered: " .. msg.playerID:GetName().name) -- stun and move player to level start location -- @TODO: Sometimes this teleport works and sometimes it does not.....ghosting distance? local player = msg.playerID player:ServerSetUserCtrlCompPause{bPaused = true} player:CancelMission{ missionID = 30 } if (LOCALS["GameStarted"] == false) then -- get the player local player = getObjectByName("activityPlayer") -- store the player for later use if (player == nil) then storeObjectByName("activityPlayer", msg.playerID) end end end -------------------------------------------------------------- -- Sent from an object after loading into zone -------------------------------------------------------------- function mainObjectLoaded(self, msg) -- Cannon Object Loaded if (msg.templateID == CONSTANTS["CANNON_TEMPLATEID"]) then -- store the cannon object for use later storeObjectByName("cannonObject", msg.objectID) msg.objectID:NotifyObject{ name= "SetParams"} if (LOCALS["GameStarted"] == false) then -- try to put hte player in the cannon enterCannon(self) end -- check for actors elseif ( IsValidActor(msg.templateID) == true ) then -- store the actor local nextActor = #ACTORS + 1 ACTORS[nextActor] = msg.objectID:GetID() -- check for effects elseif ( IsValidEffect(msg.templateID) == true ) then -- store the actor local nextEffect = #EFFECTS + 1 EFFECTS[nextEffect] = msg.objectID:GetID() end end -------------------------------------------------------------- -- Sent from the cannon to get a score for the player -------------------------------------------------------------- function onDoCalculateActivityRating(self, msg) -- save the score and time for later use -- LOCALS["GameScore"] = msg.fValue1 -- LOCALS["GameTime"] = msg.fValue2 -- LOCALS["NumShots"] = msg.fValue3 -- shots fired -- LOCALS["NumKills"] = msg.fValue4 -- targets hit -- LOCALS["MaxStreak"] = msg.fValue5 -- max streak -- also return the score as the result for the activity msg.outActivityRating = m_totalscore return msg end -------------------------------------------------------------- -- Sent from a player when responding from a messagebox -------------------------------------------------------------- function onMessageBoxRespond(self, msg) -- make sure this is the right player local player = getObjectByName("activityPlayer") if (player:GetID() == msg.sender:GetID()) then if msg.identifier == "Scoreboardinfo" then strText = "Retry?" -- show the summary message box player:DisplayMessageBox{bShow = true, imageID = 2, callbackClient = GAMEOBJ:GetZoneControlID(), text = strText, identifier = "Shooting_Gallery_Retry"} else -- User wants to retry or is closing the big help to start the game if ((msg.iButton == 1 and msg.identifier == "Shooting_Gallery_Retry") or (msg.identifier == "SG1")) then self:NotifyClientZoneObject{ name= "Clear", param1=0} startGame(self) -- User wants to quit elseif (msg.iButton == 0 and msg.identifier == "Shooting_Gallery_Retry") then -- called before we leave the cannon, so we can trigger a loading screen -- as soon as possible. Should still remove player from cannon on server self:NotifyClientZoneObject{ name= "exit"} RemovePlayerFromZone(self, player) -- get the cannon and exit local cannon = getObjectByName("cannonObject") if (cannon) then cannon:RequestActivityExit{userID = player, bUserCancel = false} end end if (msg.iButton == 1 and msg.identifier == "Shooting_Gallery_Exit") then self:NotifyClientZoneObject{ name= "exit"} RemovePlayerFromZone(self, player) -- get the cannon and exit local cannon = getObjectByName("cannonObject") if (cannon) then cannon:RequestActivityExit{userID = player, bUserCancel = false} end end end end end -------------------------------------------------------------- -- Sent from the spawn objects on death -------------------------------------------------------------- function onUpdateMissionTask(self, msg) -- We get these forwarded to us by the cannon ball if msg.taskType == "kill" then local points = msg.target:GetActivityPoints{}.points if (points < 0) then self:NotifyClientZoneObject{ name= "hitFriend"} end -- Show the text above the head of the object if (points ~= 0) then local player = getObjectByName("activityPlayer") -- cannon:NotifyClientShootingGalleryScore{rerouteID = player, target = msg.target, score=points} end -- If we have a bonus, use it local bonus = self:GetVar("StreakBonus") if (bonus > 0) and (points > 0) then points = points + points * bonus end m_totalscore = m_totalscore + points local cannon = getObjectByName("cannonObject") cannon:NotifyClientObject{ name = "updateScore", param1 = m_totalscore } self:NotifyClientZoneObject{ name= "updatescore", param1= tonumber(m_totalscore)} if self:GetVar("LastSuperTotal") then scScore = m_totalscore - self:GetVar("LastSuperTotal") else scScore = m_totalscore end local chargeAmount = CONSTANTS["ChargedPoints"] / 100 * 3 barScore = (scScore / chargeAmount) barMode = round((barScore * 3),0) if (barMode >= 100 and self:GetVar("StopCharge") == false ) then barMode = 100 self:SetVar("StopCharge", true ) self:SetVar("SuperCharged", "ChargedTimer") self:SetVar("NumberOfCharges", self:GetVar("NumberOfCharges") + 1 ) getObjectByName("Cannon_Timer"):NotifyObject{ name = "StartCharge" } self:NotifyClientZoneObject{ name= "SuperChargeBar", paramStr = tostring(barMode) } end if self:GetVar("StopCharge") == false then self:NotifyClientZoneObject{ name= "SuperChargeBar", paramStr = tostring(barMode) } end if self:GetVar("Matrix") <= 5 then local RewardAmount = self:GetVar("CONSTANTS.Score_Reward_"..self:GetVar("Matrix")) / 100 * 3 rewardS = (m_totalscore / RewardAmount) rewardF = round((rewardS * 3),0) if rewardF > 100 then rewardF = 100 end self:NotifyClientZoneObject{ name= "modelPercent", paramStr = rewardF } end if (rewardF > 0 and rewardF < 200) and self:GetVar("Matrix") <= 5 then local obj = self:GetObjectsInGroup{ignoreSpawners=true,group = CONSTANTS["Reward_Model_GrpName"] }.objects --RWS for i, object in pairs(obj) do object:SpawnModelBricks{amount=(rewardF/100),pos=msg.target:GetPosition().pos} if rewardF >= 100 then spawnNewModel(self) self:SetVar("Matrix" , self:GetVar("Matrix") + 1 ) end end end self:NotifyClientZoneObject{ name= "beatHighScore", paramStr = tostring(m_totalscore) } checkSpawn(self, msg.target) end end function checkSpawn(self, target) local waveNum = tonumber(LOCALS["ThisWave"]) if (LOCALS["GameStarted"] == true) and (waveNum) and (waveNum > 0) then -- get the spawn data (@TODO: Need to Optimize) local spawnData =target:GetVar("SpawnData") -- spawn the right object if (spawnData) and (spawnData.sdRespawn == true) and (target:GetVar("wave") == LOCALS["ThisWave"]) then SpawnObject(spawnData.sdnum,spawns[waveNum][spawnData.sdnum],self,false) end end end function ResetChargedScore(self) barMode = 0 self:SetVar("LastSuperTotal", m_totalscore) self:SetVar("SuperCharged", "notCharged") end -------------------------------------------------------------- -- User is exiting via cancel -------------------------------------------------------------- function onRequestActivityExit(self, msg) if (msg.bUserCancel == true) then stopGame(self,msg.bUserCancel) RemovePlayerFromZone(self, msg.userID) self:NotifyClientZoneObject{ name= "showloadingUI"} local cannon = getObjectByName("cannonObject") cannon:NotifyObject{ name= "Cannon_Reset"} end end -------------------------------------------------------------- -- Cannon is firing -------------------------------------------------------------- function mainShootingGalleryFire(self, msg) -- play fire animation on actors PlaySceneAnimation("fire", false, false) PlaySceneEffect("fire") end function mainNotifyObject(self, msg) if msg.name == "Cannon_Timer" then storeObjectByName( "Cannon_Timer", msg.ObjIDSender ) end if msg.name == "SetPointBonus" then self:SetVar("StreakBonus", msg.param1) end if msg.name == "ResetCharge" then self:SetVar("LastSuperTotal",m_totalscore ) end -- if msg.name =="shotsFired" then -- -- LOCALS["NumShots"] = msg.param1 -- shots fired -- -- -- end -- if msg.name =="totalHit" then -- -- LOCALS["NumKills"] = msg.param1 -- targets hit -- -- end -- if msg.name == "ResetStopCharge" then self:SetVar("NumberOfCharges", 0 ) self:SetVar("StopCharge", false ) end if (msg.name == "FinishedPath") then checkSpawn(self, msg.ObjIDSender) end end function onActivityStateChangeRequest(self,msg) if (msg.wsStringValue == 'clientready') then -- put the player in the cannon enterCannon(self) elseif (msg.iNumValue1 == 1000) then -- retry startGame(self) elseif (msg.iNumValue1 == 7777) then -- qurriey local cannon = getObjectByName("cannonObject") cannon:NotifyObject{ name= "GetLeaderData"} elseif (msg.iNumValue1 == 2000) then -- exit local player = getObjectByName("activityPlayer") strText = "Exit?" -- show the summary message box player:DisplayMessageBox{bShow = true, imageID = 1, callbackClient = GAMEOBJ:GetZoneControlID(), text = strText, identifier = "Shooting_Gallery_Exit"} -- self:NotifyClientZoneObject{ name= "HideLeaderBoardUI"} -- RemovePlayerFromZone(self, player) -- get the cannon and exit -- local cannon = getObjectByName("cannonObject") -- if (cannon) then -- cannon:RequestActivityExit{userID = player, bUserCancel = false} -- self:NotifyClientZoneObject{ name= "Audio_Exit"} -- self:NotifyClientZoneObject{ name= "exit"} -- end elseif (msg.iNumValue1 == 1200) then -- play self:NotifyClientZoneObject{ name= "HideLeaderBoardUI"} startGame(self) elseif (msg.iNumValue1 == 1800) then -- how to play self:NotifyClientZoneObject{ name= "ToggleMenuHowto"} end end function mainPlayerExit( self, msg) -- set game state resetVars(self) LOCALS["GameStarted"] = false self:NotifyClientZoneObject{ name= "exit"} if getObjectByName("cannonObject") then local cannon = getObjectByName("cannonObject") cannon:NotifyObject{ name= "Cannon_Reset"} end end