-------------------------------------------------------------- -- L_CASTLE_DEFENSE_TST_CLIENT.lua -- Client side test script for Castle Defense prototyping. -- created abeechler ... 8/5/11 -------------------------------------------------------------- -- 13925 Castle Corner Inner 2 9499 3 4210 -- 13926 Castle Gate 2 9503 3 4214 -- 13927 Castle Tower 2 9507 3 4218 -- 13928 Castle Wall Bridge 2 9508 3 4219 -- 13929 Castle Wall Straight 2 9514 3 4225 -- 13930 Castle Wall T 2 9517 3 4228 -- 13931 Castle Wall Tower With Top -- 13932 Castle Wall Widening 2 9520 3 4231 -- 14202 Castle Wall Tower With Top QB -- 14206 Castle Corner Inner QB -- 14207 Castle Gate QB -- 14208 Castle Tower QB -- 14209 Castle Wall Bridge QB -- 14210 Castle Wall Straight QB -- 14211 Castle Wall T QB -- 14213 Castle Wall Widening QB -- 16131 Center Object -------------------------------------------------------------- -- Generic Survival Instance Client Zone Script: Including this -- file gives the custom functions for the Survival game. -- updated mrb... 12/8/10 - updates for UI bugs -------------------------------------------------------------- -------------------------------------------------------------- -- Includes -------------------------------------------------------------- require('o_mis') require('ai/L_ACTIVITY_MANAGER') --////////////////////////////////////////////////////////////////////////////////// -- local variables local teamScoreBoard = {} local tMedalsSolo = { {name = Localize("Missions_467_name"), score = 300}, -- 467; Survivor {name = Localize("Missions_468_name"), score = 600} } -- 468; Ultimate Survivor local tMedals = { {name = Localize("Missions_392_name"), score = 60}, -- 392; Outwit {name = Localize("Missions_393_name"), score = 180}, -- 393; Outplay {name = Localize("Missions_394_name"), score = 300}, -- 394; Outlast {name = Localize("Missions_395_name"), score = 420}, -- 395; Survivalist {name = Localize("Missions_396_name"), score = 480}, -- 396; Be Prepared! {name = Localize("Missions_397_name"), score = 540}, -- 397; Paramedics! {name = Localize("Missions_398_name"), score = 600}, } -- 398; Unstoppable! local bFirstTime = true local checkMission = 479 -- earn your sentinel badge local checkMissionTime = 60 -- earn your sentinel badge time --------------------------------------------------------------- -- Startup of the object --------------------------------------------------------------- function string.starts(String,Start) return string.sub(String,1,string.len(Start))==Start end function playerInit(self) print("PLAYER INIT") local player = GAMEOBJ:GetObjectByID(GAMEOBJ:GetLocalCharID()) UI:SendMessage( "pushGameState", {{"state", "Survival"}}) -- set player to auto-respawn --player:SetPlayerAllowedRespawn{dontPromptForRespawn=true} -- add player to the ui UI:SendMessage( "UpdateSurvivalSummary", {{"user", player }} ) freezePlayer(player) UI:SendMessage( "ToggleActivityCloseButton", { {"bShow", true}, {"GameObject", self}, {"MessageName", "toLua"}, {"senderID", player} } ) local tempTable = { nameVar = player:GetName().name, timeVar = 0, scoreVar = 0, bConfirm = false } self:SetVar("bInit", true) teamScoreBoard = checkScoreBoardTable(self, tempTable) showScoreBoard(self) UI:SendMessage( "UpdateSurvivalSummary", {{"countdownTime", " " }} ) end function onPlayerReady(self) --print('onPlayerReady ' .. tostring(GAMEOBJ:GetObjectByID(GAMEOBJ:GetLocalCharID()):GetPlayerReady().bIsReady)) if not GAMEOBJ:GetObjectByID(GAMEOBJ:GetLocalCharID()):GetPlayerReady().bIsReady then --print('Try_Ready_Again') GAMEOBJ:GetTimer():AddTimerWithCancel( 0.1 , "Try_Ready_Again", self ) else playerInit(self) end end function checkScoreBoardTable(self, tScoreBoard, bRemoveTable) local tTemp = {} local isUsed = false for k,v in ipairs(teamScoreBoard) do if v.nameVar ~= Localize("SURVIVAL_NO_PLAYER") and v.nameVar ~= tScoreBoard.nameVar and v.nameVar ~= '' then table.insert(tTemp,v) --print('add old player to used table ' .. v.nameVar) end if v.nameVar == tScoreBoard.nameVar then if not bRemoveTable then for key,val in pairs(tScoreBoard) do if tostring(val) == tostring(-1) then tScoreBoard[key] = v[key] end end else isUsed = true end end end if not isUsed then table.insert(tTemp,tScoreBoard) --print('add new player to used table ' .. tScoreBoard.nameVar) end table.sort(tTemp, function(a,b) return a.nameVarb.timeVar end) end self:SetVar("playerNum", table.maxn(tTemp)) while table.maxn(tTemp) < 4 do local tempName = "" --if table.maxn(tTemp) < self:GetNetworkVar("NumberOfPlayers") then if table.maxn(tTemp) < 6 then tempName = Localize("SURVIVAL_NO_PLAYER") end table.insert(tTemp, { nameVar = "", timeVar = 0, scoreVar = 0, bConfirm = false}) end return tTemp end function SecondsToClock(sSeconds) local nSeconds = tonumber(sSeconds) if nSeconds == 0 or not nSeconds then return "--" else nHours = string.format("%01.f", math.floor(nSeconds/3600)); nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours*60))); nSecs = string.format("%02.f", math.floor(nSeconds - nHours*3600 - nMins *60)); if nHours ~= "0" then return nHours..":"..nMins..":"..nSecs end return nMins..":"..nSecs end end function numToString(iNum) if bFirstTime and (iNum == 0 or iNum == nil) then return "--" end return tostring(iNum) end function showScoreBoard(self, bUpdateOnly) p = teamScoreBoard if not p or not self:GetVar("bInit") then return end local messageName = "UpdateSurvivalSummary" local messageArgs = {{ "p1_check", p[1].bConfirm }, -- checkmarks { "p2_check", p[2].bConfirm }, { "p3_check", p[3].bConfirm }, { "p4_check", p[4].bConfirm }, { "p1_name", p[1].nameVar }, -- names { "p2_name", p[2].nameVar }, { "p3_name", p[3].nameVar }, { "p4_name", p[4].nameVar }, { "p1_time", SecondsToClock(p[1].timeVar) }, -- times { "p2_time", SecondsToClock(p[2].timeVar) }, { "p3_time", SecondsToClock(p[3].timeVar) }, { "p4_time", SecondsToClock(p[4].timeVar) }, { "p5_time", SecondsToClock(p[1].timeVar) }, { "p1_score", numToString(p[1].scoreVar) }, -- score { "p2_score", numToString(p[2].scoreVar) }, { "p3_score", numToString(p[3].scoreVar) }, { "p4_score", numToString(p[4].scoreVar) }, { "p5_score", numToString(p[1].scoreVar + p[3].scoreVar + p[2].scoreVar + p[4].scoreVar) }} --for k,v in ipairs(p) do print("**"..p[k].nameVar) end if not bUpdateOnly then -- Hide timer ui UI:SendMessage( "ToggleSurvivalScoreboard", {{"visible", false }}) messageName = "ToggleSurvivalSummary" table.insert(messageArgs, { "visible", true }) end -- Show UI UI:SendMessage(messageName, messageArgs ) UI:SendMessage( "ToggleSurvivalScoreboard", {{"visible", false }} ) end function freezePlayer(self, bFreeze) local playerID = GAMEOBJ:GetObjectByID(GAMEOBJ:GetLocalCharID()) local eChangeType = "POP" --if bFreeze and not self:GetNetworkVar('wavesStarted') then if bFreeze then if playerID:IsDead().bDead then --print('frozen') GAMEOBJ:GetTimer():AddTimerWithCancel( 0.1 , "Try_Freeze_Again", self ) return elseif not playerID:GetStunned().bCanMove then return end eChangeType = "PUSH" end playerID:SetStunned{ StateChangeType = eChangeType, bCantMove = true, bCantAttack = true, bCantInteract = true } --print('Player ' .. playerID:GetName().name .. ' ' .. eChangeType .. ' is frozen: ' .. tostring(self:GetVar('frozen')) .. ' ' .. tostring(playerID:GetStunned().bCanMove)) if playerID:GetStunned().bCanMove and eChangeType == "PUSH" then --print(playerID:GetName().name .. ' is still able to move') GAMEOBJ:GetTimer():AddTimerWithCancel( 0.1, "Try_Freeze_Again", self ) end end function onNotifyClientObject(self, msg) if msg.name == "ToggleLeaderBoard" and msg.paramObj:GetID() == GAMEOBJ:GetControlledID():GetID() then UI:SendMessage("ToggleLeaderboard", { {"id", msg.param1}, {"visible", true}, {"nextOnly", true} } ) end end ---------------------------------------------------------------- ---- variables serialized from the server ---------------------------------------------------------------- function onScriptNetworkVarUpdate(self, msg) local player = GAMEOBJ:GetObjectByID(GAMEOBJ:GetLocalCharID()) -- these need to happen first for k,v in pairs(msg.tableOfVars) do -- check to see if we have the correct message and deal with it if string.starts(k,"Update_ScoreBoard_Players") then local tempPlayer = GAMEOBJ:GetObjectByID(v) if tempPlayer:Exists() then --print("** Update_ScoreBoard_Players " .. tempPlayer:GetName().name) local tempTable = { nameVar = tempPlayer:GetName().name, timeVar = 0, scoreVar = 0, bConfirm = false } teamScoreBoard = checkScoreBoardTable(self, tempTable) UI:SendMessage( "UpdateSurvivalSummary", {{"countdownTime", " " }} ) end elseif string.starts(k,"PlayerConfirm_ScoreBoard") then local tempPlayer = GAMEOBJ:GetObjectByID(v) if tempPlayer:Exists() then --print("** PlayerConfirm_ScoreBoard " .. tempPlayer:GetName().name) local tempTable = { nameVar = tempPlayer:GetName().name, timeVar = -1, scoreVar = -1, bConfirm = true } teamScoreBoard = checkScoreBoardTable(self, tempTable) showScoreBoard(self, true) end elseif k == "Update_Default_Start_Timer" then if self:GetVar("displayDeath") then -- rampart change @TODO -- UI:SendMessage( "UpdateSurvivalScoreboard", {{"iplayerName", "Next Round In"}, -- {"itime", SecondsToClock( v )} } ) end if v == 0 then UI:SendMessage( "UpdateSurvivalSummary", { {"visible", true}, {"countdownTime", v }, { "p1_check", true }, -- checkmarks { "p2_check", true }, { "p3_check", true }, { "p4_check", true } } ) else UI:SendMessage( "UpdateSurvivalSummary", {{"visible", true}, {"countdownTime", v }} ) end elseif k == "Update_TimerNOTMATCHRAMPART" then -- @TODO RAMPART if self:GetVar("displayDeath") then -- @todo rampart change -- UI:SendMessage( "UpdateSurvivalScoreboard", {{"iplayerName", Localize("SURVIVAL_DEAD_LEFT_SIDE_NAME_PLATE")}, -- {"itime", SecondsToClock( v )} } ) else if not self:GetVar("bShowedPlayer") then setNextHighScore(self) end -- rampart @todo --if self:GetVar("HoldingTopScore") then -- UI:SendMessage( "UpdateSurvivalScoreboard", {{"itime", SecondsToClock( v ) }, -- {"inextbesttime", SecondsToClock(v) }, -- {"inextbestname", player:GetName().name } } ) -- else -- UI:SendMessage( "UpdateSurvivalScoreboard", {{"itime", SecondsToClock( v ) } }) -- checkNextHighScore(self, v) -- end end end end for k,v in pairs(msg.tableOfVars) do -- check to see if we have the correct message and deal with it if k == "Show_ScoreBoard" then if bFirstTime then --print("--> Show_ScoreBoard " .. player:GetName().name) showScoreBoard(self) end freezePlayer(self, true) -- clear game vars self:SetVar("HoldingTopScore", false) self:SetVar("NextBest", false ) self:SetVar("NextBestName", false) self:SetVar("bShowedPlayer", false) self:SetVar("FoundPlayer", false ) elseif k == "Exit_Waves" then local tempPlayer = GAMEOBJ:GetObjectByID(v) local tempTable = { nameVar = tempPlayer:GetName().name, timeVar = 0, scoreVar = 0, bConfirm = false} if player:GetID() == v then break end if #teamScoreBoard > 0 then teamScoreBoard = checkScoreBoardTable(self, tempTable, true) showScoreBoard(self, true) end elseif k == "Start_Wave_Message" then self:SetVar("displayDeath", false) -- @TODO removed as a test for rampart --UI:SendMessage("ToggleLeaderboard", { {"id", v},{"visible", false} } ) player:ShowActivityCountdown() --UI:SendMessage( "UpdateSurvivalScoreboard", {{"itime", "00:00"},{"iplayerName", player:GetName().name}} ) bFirstTime = false freezePlayer(self) elseif k == "Clear_Scoreboard" then UI:SendMessage( "UpdateSurvivalSummary", { {"countdownTime", " " }, {"p1_check", false }, {"p2_check", false }, {"p3_check", false }, {"p4_check", false }} ) -- remove ui timer UI:SendMessage( "ToggleSurvivalSummary", { {"visible", false },} ) -- add ui timer -- @TODO rampart -- UI:SendMessage( "ToggleSurvivalScoreboard", {{"visible", true }, {"itime", "00:00"}} ) teamScoreBoard = {} end end end function onNotifyClientZoneObject(self, msg) if msg.name == "Update_ScoreBoard" then if not msg.paramObj:Exists() then return end --print('update player ' .. msg.paramObj:GetName().name) local tempTable = { nameVar = msg.paramObj:GetName().name, timeVar = msg.param1, scoreVar = tonumber(msg.paramStr), bConfirm = false } teamScoreBoard = checkScoreBoardTable(self, tempTable) end end function ExitBox(self, player) print("EXIT BOX") local player = GAMEOBJ:GetObjectByID(GAMEOBJ:GetLocalCharID()) if player:Exists() then local text = Localize("SURVIVAL_EXIT_QUESTION") --if self:GetNetworkVar("wavesStarted") then text = Localize("SURVIVAL_PLAYING_EXIT_QUESTION") -- "Your time will not be recorded if you exit before the game is over. Exit anyway?" --end -- display exit box player:DisplayMessageBox{bShow = true, imageID = 1, text = text, callbackClient = self, identifier = "Exit_Question"} end end ---------------------------------------------------------------- -- Sent from a player when responding from a messagebox ---------------------------------------------------------------- function onMessageBoxRespond(self, msg) if msg.identifier == "LeaderboardNext" then -- when the player hits the next button on the survival leaderboard UI:SendMessage( "popGameState", {{"state", "SurvivalLeaderboard"}}) self:SetVar("displayDeath", false) showScoreBoard(self) elseif msg.identifier == "ActivityCloseButtonPressed" and msg.iButton == -1 then -- when the player hits the activity close button, the x in the top right ExitBox(self, player) elseif msg.identifier == "Exit" and msg.iButton == 1 then -- when the player hits the exit button on the survival summary UI ExitBox(self, player) elseif msg.identifier == "Exit_Question" and msg.iButton == 1 then -- when the player hit's the check box on the exit question message box clear all the survival UI elements UI:SendMessage( "ToggleActivityCloseButton", {{"bShow", false}} ) UI:SendMessage("ToggleSurvivalSummary", {{"visible", false }}) UI:SendMessage( "ToggleSurvivalScoreboard", {{"visible", false }} ) UI:SendMessage("ToggleLeaderboard", { {"id", msg.identifier},{"visible", false} } ) UI:SendMessage( "popGameState", {{"state", "Survival"}} ) UI:SendMessage( "popGameState", {{"state", "SurvivalLeaderboard"}}) end end function onSendActivitySummaryLeaderboardData(self, msg) --print('Activity Summary Sent to client Zone') if (msg) then self:SetVar("HoldingTopScore", false) local player = GAMEOBJ:GetObjectByID(GAMEOBJ:GetLocalCharID()) local MaxCount = msg.leaderboardData["Result[0].RowCount"] or 0 local tableValues = {} for i = 0, MaxCount do local name = msg.leaderboardData["Result[0].Row["..i.."].name"] table.insert(tableValues, name) table.insert(tableValues, msg.leaderboardData["Result[0].Row["..i.."].Time"]) if msg.leaderboardData["Result[0].Row["..i.."].Relationship"] then if msg.leaderboardData["Result[0].Row["..i.."].Relationship"] ~= 0 then self:SetVar("FoundFriendGuild", true ) end end -- found the player so dont record the other values if name == player:GetName().name then self:SetVar("FoundPlayer", true ) break end end self:SetVar("bShowedPlayer", false) self:SetVar("NextBest", false) self:SetVar("NextBestName", false) self:SetVar("LeaderTable", tableValues) setNextHighScore(self) end end function setNextHighScore(self, iScore) local player = GAMEOBJ:GetObjectByID(GAMEOBJ:GetLocalCharID()) local name_value = 0 local score_value = 0 local name = 0 local score = 0 local tableValues = self:GetVar("LeaderTable") or {} local curName = self:GetVar("NextBestName") local playerScore = 0 if not curName then curName = player:GetName().name end for testName = 1, table.maxn(tableValues) do if tableValues[testName] == curName then name = testName score = (testName + 1) if name ~= 1 then name_value = (testName - 2) score_value = (testName - 1) elseif name_value == 3 then name_value = 1 score_value = 2 elseif name_value == 1 then name_value = 1 score_value = 2 end end if tableValues[testName] == player:GetName().name then playerScore = tableValues[(testName + 1)] end end local uiName = tableValues[name] or player:GetName().name local uiScore = tableValues[score] or playerScore local uiNextName = tableValues[name_value] or player:GetName().name local uiNextScore = tableValues[score_value] or playerScore if not self:GetVar("bShowedPlayer") then uiNextName = uiName uiNextScore = uiScore end if not iScore then iScore = 0 end local tempMedals = tMedals if self:GetVar("playerNum") == 1 then tempMedals = tMedalsSolo end local highestScore = tableValues[2] or 0 local missionCheck = player:GetMissionState{missionID = checkMission}.missionState < 4 and iScore < checkMissionTime if missionCheck then uiNextName = Localize("Missions_479_name") uiNextScore = checkMissionTime elseif iScore >= math.floor(highestScore) or not self:GetVar("FoundPlayer") then local pass = false for k,v in ipairs(tempMedals) do if iScore < v.score then uiNextName = v.name uiNextScore = v.score pass = true break end end if not pass then self:SetVar("HoldingTopScore", true) uiNextName = player:GetName().name uiNextScore = iScore end end if not self:GetVar("displayDeath") then local messageName = "UpdateSurvivalScoreboard" if self:GetVar("bShowedPlayer") then UI:SendMessage(messageName, { {"visible", true }, {"iplayerName", player:GetName().name}, {"inextbesttime", SecondsToClock(uiNextScore) }, {"inextbestname", tostring(uiNextName) } } ) end end self:SetVar("NextBest", math.floor(uiNextScore) ) self:SetVar("NextBestName", uiNextName ) self:SetVar("bShowedPlayer", true) end function checkNextHighScore(self, iScore) if not iScore or not self:GetVar('NextBest') then return end if iScore >= self:GetVar('NextBest') then setNextHighScore(self, iScore) end end function onTimerDone(self, msg) if msg.name == "Try_Freeze_Again" then freezePlayer(self, true) elseif msg.name == "Try_Ready_Again" then PlayerReady(self) end end