--L_ACT_CANNON.lua -- Server Side -------------------------------------------------------------- -- Includes -------------------------------------------------------------- require('o_mis') CONSTANTS = {} -------------------------------------------------------------- -- Startup -------------------------------------------------------------- function onStartup(self) GAMEOBJ:GetZoneControlID():NotifyObject{ name = "Cannon_Timer",ObjIDSender= self} -- default the instance vars self:SetVar("initVelVec",{x = 0, y = 0, z = 0}) -- set the parameters of the shooting gallery -- send an object loaded message to the ZoneControl object GAMEOBJ:GetZoneControlID():ObjectLoaded{objectID = self, templateID = self:GetLOT().objtemplate} -------------------------------------------------------------- -- Constants -------------------------------------------------------------- local zoneID = GAMEOBJ:GetZoneControlID() CONSTANTS["CANNON_SUPER_CHARGE"] = zoneID:GetVar("CONSTANTS.CANNON_SUPER_CHARGE") CONSTANTS["CANNON_PROJECTILE"] = zoneID:GetVar("CONSTANTS.CANNON_PROJECTILE") CONSTANTS["CANNON_SKILL"] = zoneID:GetVar("CONSTANTS.CANNON_SKILL") CONSTANTS["CANNON_SUPERCHARGE_SKILL"] = zoneID:GetVar("CONSTANTS.CANNON_SUPERCHARGE_SKILL") -- Default Skill ID for the projectile CONSTANTS["IMPACT_SKILLID"] = zoneID:GetVar("CONSTANTS.IMPACT_SKILLID") -- Make sure we store our score CONSTANTS["CANNON_USE_LEADERBOARDS"] = zoneID:GetVar("CONSTANTS.CANNON_USE_LEADERBOARDS") -- Something CONSTANTS["CANNON_FOV"] = zoneID:GetVar("CONSTANTS.CANNON_FOV") -- template for the projectile CONSTANTS["PROJECTILE_TEMPLATEID"] = zoneID:GetVar("CONSTANTS.PROJECTILE_TEMPLATEID") -- offset to place the player during the activity CONSTANTS["CANNON_PLAYER_OFFSET"] = {x = zoneID:GetVar("CONSTANTS.CANNON_PLAYER_OFFSETx"), y = zoneID:GetVar("CONSTANTS.CANNON_PLAYER_OFFSETy"), z = zoneID:GetVar("CONSTANTS.CANNON_PLAYER_OFFSETz")} -- velocity of the projectile -- max distance = (v^2 / g) where v = velocity and g = the effect of gravity from the database. -- original value = 100. changed to 140 CONSTANTS["CANNON_VELOCITY"] = zoneID:GetVar("CONSTANTS.CANNON_VELOCITY") -- Minimum distance that the cannon can hit CONSTANTS["CANNON_MIN_DISTANCE"] = zoneID:GetVar("CONSTANTS.CANNON_MIN_DISTANCE") -- cooldown time for firing CONSTANTS["CANNON_REFIRE_RATE"] = zoneID:GetVar("CONSTANTS.CANNON_REFIRE_RATE") -- muzzle offset CONSTANTS["CANNON_BARREL_OFFSET"] = {x = zoneID:GetVar("CONSTANTS.CANNON_BARREL_OFFSETx"), y = zoneID:GetVar("CONSTANTS.CANNON_BARREL_OFFSETy"), z = zoneID:GetVar("CONSTANTS.CANNON_BARREL_OFFSETz")} -- cannon time out for activity CONSTANTS["CANNON_TIMEOUT"] = zoneID:GetVar("CONSTANTS.CANNON_TIMEOUT") self:SetVar("ImpactSkillID",CONSTANTS["IMPACT_SKILLID"]) self:SetShootingGalleryParams{ playerPosOffset = CONSTANTS["CANNON_PLAYER_OFFSET"], projectileVelocity = CONSTANTS["CANNON_VELOCITY"], cooldown = CONSTANTS["CANNON_REFIRE_RATE"], muzzlePosOffset = CONSTANTS["CANNON_BARREL_OFFSET"], minDistance = CONSTANTS["CANNON_MIN_DISTANCE"], timeLimit = CONSTANTS["CANNON_TIMEOUT"], cameraFOV = CONSTANTS["CANNON_FOV"], bUseLeaderboards = CONSTANTS["CANNON_USE_LEADERBOARDS"] } -- Load a timer??? --local config = { {"renderDisabled",true }, {"bla", "foo"} } -- RESMGR:LoadObject { objectTemplate = CANNON_TIMER , x= -967 , y= 229 , z= 4.46 , owner = self, configData = config } self:SetVar("mHit", 0) self:SetVar("chargeUI", 100) self:SetVar("charge_count", 10) self:SetVar("charge_keep", 0 ) self:SetVar("SC_ACTIVE", false) -- Make sure the client version has this self:SetNetworkVar("initialskill", CONSTANTS["CANNON_SKILL"] ) resetVars(self) end function resetVars(self) self:SetVar("m_shotsFired",0) self:SetVar("m_maxStreak",0) self:SetVar("m_misses",0) self:SetVar("m_curStreak",0) self:SetVar("m_targetsHit",0) self:SetVar("m_killsSinceLastShot",0) end -------------------------------------------------------------- -- Gets the current activity user or returns nil -------------------------------------------------------------- function getActivityUser(self) local targetID = self:GetActivityUser().userID if (targetID == 0 or targetID == nil) then return nil else return targetID end end -------------------------------------------------------------- -- Called after loading a projectile -------------------------------------------------------------- function onChildLoaded(self, msg) -- if we loaded a projectile, fire it if msg.templateID == CONSTANTS["PROJECTILE_TEMPLATEID"] then -- store who the parent is self:SetVar("parent", msg.childID) local ballObj = msg.childID -- get the skill for the projectile local skill = self:GetVar("ImpactSkillID") if (ballObj) and (getActivityUser(self)) and (skill) then -- store values in the projectile ballObj:SetVar("My_Faction", getActivityUser(self):GetFaction().faction) storeObjectByName(ballObj, "Player", getActivityUser(self)) -- set the skill ballObj:SetActiveProjectileSkill{ skillID = skill } -- store the velocity local vec = self:GetVar("initVelVec") -- set projectile params if (vec.x ~= 0 and vec.y ~= 0 and vec.z ~= 0) then ballObj:SetProjectileParams{initVel = vec, iProjectileType = 1, fLifeTime = 10.0, owner = self} end end end end -------------------------------------------------------------- -- Called when the client wants to fire -------------------------------------------------------------- function onShootingGalleryFire(self, msg) -- calculate firing parameters local params = self:CalculateFiringParameters{targetPos = msg.targetPos, bUseHighArc = false} local vec = params.outVelVector if (vec.x ~= 0 and vec.y ~= 0 and vec.z ~= 0) then -- save off the velocity self:SetVar("initVelVec",vec) -- spawn the projectile -- local spawnPos = params.outSpawnPos --self:CastSkill{skillID = 228}--, optionalTargetID = msg.objId} -- RESMGR:LoadObject { -- objectTemplate = CONSTANTS["PROJECTILE_TEMPLATEID"], -- x = spawnPos.x, -- y = spawnPos.y, -- z = spawnPos.z, -- rw = 1, -- owner = self -- } self:SetVar("m_shotsFired", self:GetVar("m_shotsFired") + 1) local player = getActivityUser(self) self:PlayFXEffect{effectType = "onfire", ignoreID = player} self:PlayFXEffect{effectType = "onfire2", ignoreID = player} player:PlayFXEffect{effectType = "SG-fire", ignoreID = player} -- @TODO: rename this to a better message? -- Tell the zone control we just fired GAMEOBJ:GetZoneControlID():ShootingGalleryFire() end end -------------------------------------------------------------- -- Called when getting the cannon's faction -------------------------------------------------------------- function onGetFaction(self, msg) -- return the user's faction if (getActivityUser(self)) then msg.faction = getActivityUser(self):GetFaction().faction return msg end end -------------------------------------------------------------- -- Calculate the activity rating -------------------------------------------------------------- function onDoCalculateActivityRating(self, msg) -- Send the request to the zone control local newMsg = GAMEOBJ:GetZoneControlID():DoCalculateActivityRating() -- { -- fValue1 = msg.fValue1, -- fValue2 = msg.fValue2, -- fValue3 = msg.fValue3, -- fValue4 = msg.fValue4, -- fValue5 = msg.fValue5, -- } -- return whatever the zone control gave us msg.outActivityRating = newMsg.outActivityRating return msg end -------------------------------------------------------------- -- Start or stop the activity -- @TODO: old func, replaced with onRequestActivityExit, change out later -------------------------------------------------------------- function onRequestActivityStartStop(self, msg) -- forward this request on to the zone control object GAMEOBJ:GetZoneControlID():RequestActivityStartStop{bStart = msg.bStart, userID = msg.userID} end -------------------------------------------------------------- -- User Exits Activity -------------------------------------------------------------- function onRequestActivityExit(self, msg) if (msg.bUserCancel) == true then -- forward this request on to the zone control object GAMEOBJ:GetZoneControlID():RequestActivityExit{bUserCancel = msg.bUserCancel, userID = msg.userID} end end function enableSuperCharge(self, enable) if (enable) then local meItem1 = self:GetInventoryItemInSlot{slot = 0}.itemID local meItem2 = self:GetInventoryItemInSlot{slot = 1}.itemID self:EquipInventory{ itemtoequip = meItem1} self:EquipInventory{ itemtoequip = meItem2} self:SetShootingGalleryParams{playerPosOffset = CONSTANTS["CANNON_PLAYER_OFFSET"], projectileVelocity = CONSTANTS["CANNON_VELOCITY"], cooldown = 400.0, muzzlePosOffset = CONSTANTS["CANNON_BARREL_OFFSET"], minDistance = CONSTANTS["CANNON_MIN_DISTANCE"], cameraFOV = CONSTANTS["CANNON_FOV"], bUseLeaderboards = CONSTANTS["CANNON_USE_LEADERBOARDS"] , timeLimit = -1} self:NotifyClientObject{name = "cbskill", param1 = CONSTANTS["CANNON_SUPERCHARGE_SKILL"] } self:SetVar("CannonChargedState", true) else local meItem1 = self:GetInventoryItemInSlot{slot = 0}.itemID local meItem2 = self:GetInventoryItemInSlot{slot = 1}.itemID self:UnEquipInventory{ itemtounequip = meItem1} self:UnEquipInventory{ itemtounequip = meItem2} self:SetShootingGalleryParams{playerPosOffset = CONSTANTS["CANNON_PLAYER_OFFSET"], projectileVelocity = CONSTANTS["CANNON_VELOCITY"], cooldown = CONSTANTS["CANNON_REFIRE_RATE"], muzzlePosOffset = CONSTANTS["CANNON_BARREL_OFFSET"], minDistance = CONSTANTS["CANNON_MIN_DISTANCE"], cameraFOV = CONSTANTS["CANNON_FOV"], bUseLeaderboards = CONSTANTS["CANNON_USE_LEADERBOARDS"] , timeLimit = -1} self:NotifyClientObject{name = "cbskill", param1 = CONSTANTS["CANNON_SKILL"] } self:SetVar("CannonChargedState", nil ) GAMEOBJ:GetZoneControlID():NotifyObject{ name= "ResetStopCharge"} end end function onNotifyObject(self,msg) if msg.name == "GetLeaderData" then local targetID = self:GetActivityUser().userID self:RequestActivitySummaryLeaderboardData{user = targetID, target = self, queryType = 7, gameID = GAMEOBJ:GetZoneControlID():GetVar("CONSTANTS.ActivityID") } end if msg.name == "Cannon_Reset" then -- GAMEOBJ:GetZoneControlID():SetVar("StreakBonus",0) resetVars(self) self:SetVar("ImpactSkillID",CONSTANTS["IMPACT_SKILLID"]) -- self:SetVar("StreakBonus","0") --self:SetVar("Missed", false) end --- Start Timer on Client if msg.name == "Start" then self:SetVar("Started", true) local wave = GAMEOBJ:GetZoneControlID():GetVar("ThisWave") self:NotifyClientObject{name = "count", param1 = GAMEOBJ:GetZoneControlID():GetVar("timelimit") , paramStr = wave } end -- Stop Timer on Client if msg.name == "Stop" then self:NotifyClientObject{name = "Stop"} end if msg.name == "StartCharge" then ctimer = GAMEOBJ:GetZoneControlID():GetVar("CONSTANTS.ChargedTime") / 10 GAMEOBJ:GetTimer():AddTimerWithCancel( ctimer , "ChargedCompet", self ) self:SetVar("charge_keep", 9 ) end if msg.name =="ResetCharge" then GAMEOBJ:GetTimer():AddTimerWithCancel( 1 , "ChargedCompet", self ) end end function registerHit(self, target) local points = target:GetActivityPoints{}.points -- Only apply bonus to positive things and don't do streak etc for negative if (points >= 0) then points = points + (points * getCurrentBonus(self)) self:SetVar("m_targetsHit", self:GetVar("m_targetsHit") + 1) self:SetVar("m_killsSinceLastShot", self:GetVar("m_killsSinceLastShot") + 1) if (not self:GetVar("CannonChargedState")) then self:SetVar("m_curStreak", self:GetVar("m_curStreak") + 1) if (self:GetVar("m_curStreak") > self:GetVar("m_maxStreak")) then self:SetVar("m_maxStreak", self:GetVar("m_curStreak")) end end elseif (not self:GetVar("CannonChargedState")) then self:SetVar("m_curStreak", 0) -- This accounts for friendlies self:SetVar("m_misses", self:GetVar("m_misses") + 1) end self:NotifyClientShootingGalleryScore{rerouteID = getActivityUser(self), target = target, targetPos = target:GetPosition().pos, score=points} end function onActivityNotify(self,msg) local streakChanged = false -- Don't count any of this if we're firing our super charged cannon ball if (msg.notification["shot_done"] and msg.notification["shot_done"] ~= CONSTANTS["CANNON_SUPER_CHARGE"]) then streakChanged = true if (self:GetVar("m_killsSinceLastShot") <= 0) then self:SetVar("m_curStreak", 0) -- This account for real misses self:SetVar("m_misses", self:GetVar("m_misses") + 1) GAMEOBJ:GetZoneControlID():NotifyClientZoneObject{ name= "HideStreak"} GAMEOBJ:GetZoneControlID():NotifyClientZoneObject{ name = "UnMarkAll" } end if self:GetVar("m_killsSinceLastShot") > 1 then GAMEOBJ:GetZoneControlID():NotifyClientZoneObject{ name = "mHit" } end self:SetVar("m_killsSinceLastShot", 0) end if streakChanged == true then updateStreak(self) end end function intdiv(a,b) return math.floor(a/b) end function getCurrentBonus(self) local streak = self:GetVar("m_curStreak") -- Cap the streak if (streak > 12) then streak = 12 end local res = intdiv(streak, 3) return res end function updateStreak(self) local streakBonus = getCurrentBonus(self) local curStreak = self:GetVar("m_curStreak") local marks = math.mod(curStreak, 3) GAMEOBJ:GetZoneControlID():NotifyClientZoneObject{ name= "cStreak" , paramStr = curStreak } -- Update the marks if curStreak >= 0 and curStreak < 13 then -- Mark 1 if marks == 1 then GAMEOBJ:GetZoneControlID():NotifyClientZoneObject{ name = "Mark1" } elseif marks == 2 then GAMEOBJ:GetZoneControlID():NotifyClientZoneObject{ name = "Mark2" } elseif marks == 0 and curStreak > 0 then GAMEOBJ:GetZoneControlID():NotifyObject{ name= "SetPointBonus" ,param1 = streakBonus} GAMEOBJ:GetZoneControlID():NotifyClientZoneObject{ name= "ShowStreak" , paramStr = streakBonus + 1} GAMEOBJ:GetZoneControlID():NotifyClientZoneObject{ name = "Mark3" } else GAMEOBJ:GetZoneControlID():NotifyObject{ name= "SetPointBonus" ,param1 = streakBonus} GAMEOBJ:GetZoneControlID():NotifyClientZoneObject{ name = "UnMarkAll" } end end end function onTimerDone(self,msg) if msg.name == "ChargedCompet" then local chargeTime = self:GetVar("chargeUI") - 10 local chargeCount = self:GetVar("charge_count") - 1 if GAMEOBJ:GetZoneControlID():GetVar("WaveStatus") then if chargeCount == 0 then self:SetVar("charge_keep", 0 ) GAMEOBJ:GetZoneControlID():NotifyClientZoneObject{name = "charge_counting", param1 = 999 } self:SetVar("charge_count", 10) self:SetVar("chargeUI", 100 ) if self:GetVar("SC_ACTIVE") then enableSuperCharge(self, false) self:SetVar("SC_ACTIVE", false) end else if not self:GetVar("SC_ACTIVE") then enableSuperCharge(self, true) self:SetVar("SC_ACTIVE", true) end GAMEOBJ:GetZoneControlID():NotifyObject{name = "ResetCharge" } self:SetVar("charge_keep", self:GetVar("charge_keep") -1 ) GAMEOBJ:GetZoneControlID():NotifyClientZoneObject{name = "charge_counting", param1 = chargeTime } self:SetVar("charge_count", chargeCount ) self:SetVar("chargeUI", chargeTime ) local ctimer = GAMEOBJ:GetZoneControlID():GetVar("CONSTANTS.ChargedTime") / 10 GAMEOBJ:GetTimer():AddTimerWithCancel( ctimer , "ChargedCompet", self ) end if self:GetVar("chargeUI") == 0 then self:SetVar("chargeUI", 100) end end end end -------------------------------------------------------------- -- We get this message when the projectile kills something -------------------------------------------------------------- function onUpdateMissionTask(self, msg) --forward message to parent if (msg.taskType == "kill") then registerHit(self, msg.target) GAMEOBJ:GetZoneControlID():UpdateMissionTask{target = msg.target, value = msg.value, value2 = msg.value2, taskType = msg.taskType} getActivityUser(self):UpdateMissionTask{target = msg.target, value = msg.value, value2 = msg.value2, taskType = msg.taskType} end end