-------------------------------------------------- -- Nexus Tower Armory Combat Challenge Server script -- -- updated - 8/11/11 - mrb... updated audio GUIDs -------------------------------------------------- local currencyLOT = 3039 local currencyCost = 1 local gameTime = 30.0 local preConVar = "166" local startSound = "{a477f897-30da-4b15-8fce-895c6547adae}" local stopSound = "{a832b9c5-b000-4c97-820a-2a7d1e68dd9d}" local timerSound = "{79b38431-4fc7-403b-8ede-eaff700a7ab0}" local timerLowSound = "{0e1f1284-e1c4-42ed-8ef9-93e8756948f8}" local scoreSound = "{cfdade40-3d97-4cf5-b53c-862e0b84c1a1}" -- target dummy lots local tTargets = { 13556, 13556, 13764, 13764, 13765, 13765, 13766, 13766, 13767, 13767, 13768, 13768, 13830, 13769, 13769, 13770, 13830, 13770, 13771, 13771, 13830, 13772} -- bomb = 13830 -- update missions keep the dmg in order from lowest to highest local tMissions = { {mission = 1010, dmg = 25}, {mission = 1340, dmg = 100}, {mission = 1341, dmg = 240}, {mission = 1342, dmg = 290}, } -- print function that only works in an internal build function debugPrint(self, text) if self:GetVersioningInfo().bIsInternal then print(text) end end function onStartup(self, msg) self:SetVar("TargetNumber", 1) end function notifyHitOrHealResult(self, other, msg) if msg.receiver:GetID() ~= other:GetID() or msg.dealer:GetID() == self:GetID() then return end if self:GetVar('playerID') and self:GetNetworkVar("bInUse") then local player = GAMEOBJ:GetObjectByID(self:GetVar('playerID')) local totalDmg = self:GetNetworkVar("totalDmg") or 0 local dmg = msg.lifeDamageDealt + msg.armorDamageDealt totalDmg = totalDmg + dmg self:SetNetworkVar("totalDmg", totalDmg) -- play the score audio self:PlayNDAudioEmitter{m_NDAudioEventGUID = scoreSound} end end function notifyDie(self, other, msg) -- if the target died as a result of the hit spawn a new one and cancel the lua notification if msg.killerID:GetID() ~= self:GetID() then self:SendLuaNotificationCancel{requestTarget = other, messageName = "HitOrHealResult"} self:SendLuaNotificationCancel{requestTarget = other, messageName = "Die"} SpawnTargetDummy(self) end end function onUse(self,msg) if not msg.user:GetFlag{iFlagID = 115}.bFlag then -- tell the users client script that the UI is open self:NotifyClientObject{name = "UI_Open", paramObj = msg.user, rerouteID = msg.user} end end function onCheckUseRequirements(self, msg) local check = msg.objIDUser:CheckListOfPreconditionsFromLua{PreconditionsToCheck = preConVar, requestingID = self} -- dont let the playe use this if the minigame is active or they dont meet the precondition check. if not check.bPass or self:GetNetworkVar("bInUse") then msg.bCanUse = false end return msg end function onMessageBoxRespond(self,msg) if msg.identifier == "PlayButton" and msg.iButton == 1 then -- player hit the yes button so start the minigame self:SetNetworkVar("bInUse", true) self:SetVar("playerID", "|" .. msg.sender:GetID()) -- take the activity cost msg.sender:RemoveItemFromInventory{ iObjTemplate = currencyLOT, iStackCount = currencyCost} -- play the start audio self:PlayNDAudioEmitter{m_NDAudioEventGUID = startSound} -- add start delay timer self:ActivityTimerSet{name = "start_delay", updateInterval = 2, duration = 2} msg.sender:ShowActivityCountdown() -- tell the clients to start the ui self:SetNetworkVar("toggle", true) elseif msg.identifier == "CloseButton" then -- tell the client that the player closed the UI self:NotifyClientObject{name = "UI_Close", paramObj = msg.sender, rerouteID = msg.sender, param1 = 1} end end function onFireEventServerSide(self, msg) local player = GAMEOBJ:GetObjectByID(msg.args) if player:Exists() then -- tell the client that the messagebox is closed self:NotifyClientObject{name = "UI_Close", paramObj = player, rerouteID = player} end end function SpawnTargetDummy(self) if not self:GetVar("playerID") then return end -- get the lot of the next target object local dummyNum = self:GetVar("TargetNumber") or 1 -- if we're at the end of the list then spawn the last target again local dummyLOT = tTargets[dummyNum] or tTargets[table.maxn(tTargets)] -- get the rotation/position to place the target. local mypos = self:GetPosition().pos local myRot = self:GetRotation() local config = { } -- spawn the target RESMGR:LoadObject { objectTemplate = dummyLOT, x= mypos.x, y= mypos.y, z= mypos.z, rw= myRot.w, rx= myRot.x, ry= myRot.y , rz = myRot.z, configData = config, owner = self } end function SetAttackImmunity(objID, bTurnOn) local state = "PUSH" if not bTurnOn then state = "POP" end objID:SetStatusImmunity{ StateChangeType = state, bImmuneToSpeed = true, bImmuneToBasicAttack = true, bImmuneToDOT = true} end function onChildLoaded(self, msg) --get the current target number and increment it by 1 local targetNum = self:GetVar("TargetNumber") or 1 self:SetVar("TargetNumber", targetNum + 1) local animTime = msg.childID:GetAnimationTime{animationID = "spawn"}.time or 0 if animTime > 0 then SetAttackImmunity(msg.childID, true) -- add clear attack immunity timer self:ActivityTimerSet{name = "clear_" .. msg.childID:GetID(), updateInterval = animTime, duration = animTime} end -- Make immune to move/teleport behaviors msg.childID:SetStatusImmunity{ StateChangeType = "PUSH", bImmuneToPullToPoint = true, bImmuneToKnockback = true} -- Make immune to knockbacks and pulls -- rotate the target to face the player msg.childID:RotateObject{rotation = {x = 0, y = math.rad(180), z = 0}} -- request lua notification of the child and set the child ID self:SendLuaNotificationRequest{requestTarget = msg.childID, messageName = "HitOrHealResult"} self:SendLuaNotificationRequest{requestTarget = msg.childID, messageName = "Die"} self:SetVar("currentTargetID", msg.childID) msg.childID:AddObjectToGroup{group = "targets_"..self:GetID()} end function resetGame(self) local totalDmg = self:GetNetworkVar("totalDmg") or 0 local playerID = self:GetVar("playerID") or 0 local player = GAMEOBJ:GetObjectByID(playerID) for k, missionSet in ipairs(tMissions) do --Damage checks for quest and switching the dummies if totalDmg >= missionSet.dmg then player:UpdateMissionTask{taskType = "complete", value = missionSet.mission, value2 = 1, target = self} player:TeamNotifyUpdateMissionTask{originalUpdatee = player, taskType = "complete", value = missionSet.mission, value2 = 1, target = self} else break end end -- reset the game variables self:SetVar("TargetNumber", 1) self:SetVar('playerID', false) self:SetNetworkVar("totalDmg", false) self:SetNetworkVar("update_time", 0) local targetObjs = self:GetObjectsInGroup{ group = "targets_"..self:GetID(), ignoreSpawners = true }.objects for k, obj in ipairs(targetObjs) do -- kill the current target if one exists if obj:Exists() then obj:RequestDie{killerID = self, killType = "SILENT"} end end end function onActivityTimerUpdate(self, msg) if msg.name == "game_tick" then self:SetNetworkVar("update_time", math.ceil(msg.timeRemaining)) local soundGUID = timerSound if msg.timeRemaining <= 3 then soundGUID = timerLowSound end -- play the timer audio self:PlayNDAudioEmitter{m_NDAudioEventGUID = soundGUID} end end function onActivityTimerDone(self, msg) if msg.name == "start_delay" then -- add start delay timer self:ActivityTimerSet{name = "game_tick", updateInterval = 1, duration = gameTime} -- spawn the first target SpawnTargetDummy(self) -- set total time for the UI clock self:SetNetworkVar("totalTime", gameTime) elseif string.starts(msg.name, "clear_") then local targetID = split(msg.name, "_")[2] or 0 local target = GAMEOBJ:GetObjectByID(targetID) if target:Exists() then SetAttackImmunity(target, false) end elseif msg.name == "game_tick" then --local player = GAMEOBJ:GetObjectByID(self:GetVar('playerID')) -- if player:Exists() then --local score = self:GetNetworkVar("totalDmg") or 0 -- player:DisplayTooltip{strText = "You did " .. score .. " points of damage in " .. gameTime .. " seconds." , bShow = true, strImageName ="textures/ui/tooltips/NT_Armory_Dummy.dds"} -- end resetGame(self) -- play the stop audio self:PlayNDAudioEmitter{m_NDAudioEventGUID = stopSound} -- add start delay timer self:ActivityTimerSet{name = "reset_tick", updateInterval = 5, duration = 5} elseif msg.name == "reset_tick" then -- turn off the 3dUI and make the minigame interactable again self:SetNetworkVar("toggle", false) self:SetNetworkVar("bInUse", false) end end function split(str, pat) local t = {} -- creates a table of strings based on the passed in pattern string.gsub(str .. pat, "(.-)" .. pat, function(result) table.insert(t, result) end) return t end function string.starts(String,Start) -- finds if a string starts with a giving string. return string.sub(String,1,string.len(Start))==Start end