--------------------------------------------- -- Server script on the skullkin drill -- -- created by brandi... 10/13/10 -- updated by mrb... 7/21/11 - only one drill bit will spawn when the player uses spinjitu -- updated abeechler ... 10/24/11 - don't allow bit smashes until the drill is fully raised. --------------------------------------------- -- *** putting cinematic --> 0:cinematicName in the config data of the drill mover -- will play a cinematic for the player when the drill is used. *** -- nj animations on use for the staff interaction local startAnim = "spinjitzu-staff-windup" local runAnim = "spinjitzu-staff-loop" local endAnim = "spinjitzu-staff-end" local resetTime = 10 -- how long to wait before resetting the drill local missionsToUpdate = {972, 1305, 1308} -- these are the missionID's to update when the drill is smashed function onStartup(self,msg) -- stop the drill from pathing self:StopPathing() -- set variables to false self:SetNetworkVar("bIsInUse", false) self:SetVar("bActive", true) -- play the spinning fx self:PlayFXEffect{name = "active", effectType = "spin"} -- get the stand object local standObj = getStandObj(self) if standObj then -- notify the stand object to activate the knockback standObj:NotifyObject{ObjIDSender = self, name = "activate"} end -- set up the prox radius for where the player needs to be to use the skill self:SetProximityRadius{radius = self:GetInteractionDistance().fDistance, name = "spin_distance"} end ---------------------------------------------- -- sent when the local player interacts with the -- object before ClientUse ---------------------------------------------- function onCheckUseRequirements(self, msg) if self:GetNetworkVar('bIsInUse') then msg.bCanUse = false return msg end local preConVar = self:GetVar("CheckPrecondition") if preConVar and preConVar ~= "" then local check = msg.objIDUser:CheckListOfPreconditionsFromLua{PreconditionsToCheck = preConVar, requestingID = self} if not check.bPass then msg.bCanUse = false return msg end end local preconditionID = 143 -- staff of imagination local check = {} if preconditionID then check = msg.objIDUser:CheckPrecondition{PreconditionID = preconditionID} end if not check.bPass then msg.bCanUse = false end return msg end -- function to get this drills stand object function getStandObj(self) local myGroup = self:GetVar("groupID") if not myGroup then return false end -- get the objects the correct group set in HF local standObjs = self:GetObjectsInGroup{group = "Drill_Stand_" .. string.sub(string.gsub(myGroup,"%;",""), -1), ignoreSpawners = true }.objects for k,obj in ipairs(standObjs) do if obj:Exists() then -- if the object exists return it return obj end end -- didn't find any objects so return false return false end function onSkillEventFired(self,msg) -- catch the spinjitzu charge up skill if msg.wsHandle ~= "NinjagoSpinEvent" or not isInProximity(self, msg.casterID) or self:GetNetworkVar("bIsInUse") then return end -- set flag to true so this wont happen twice self:SetNetworkVar("bIsInUse", true) toggleDrill(self) end -- custom function to check and see if the player is within the skill cast proximity function isInProximity(self, player) -- see if the player is within the proximity for k,v in ipairs(self:GetProximityObjects{name = "spin_distance"}.objects) do if v:GetID() == player:GetID() then return true end end return false end function toggleDrill(self) -- raise the drill up to expose the drill bit self:GoToWaypoint{iPathIndex = 1; bStopAtWaypoint = true} self:PlayAnimation{animationID = "slowdown", fPriority = 2.0} end ---------------------------------------------- -- Receive waypoint messages to determine when we -- have reached the raised stop position ---------------------------------------------- function onArrivedAtDesiredWaypoint(self, msg) if msg.iPathIndex == 1 then -- Get the position of the drill local oPos = { pos = "", rot = ""} oPos.pos = self:GetPosition().pos -- Set the position where the smashable is supposed to spawn in, had to put the pivot of the drill at the top so it could see the skill oPos.pos.y = oPos.pos.y - 21 oPos.rot = self:GetRotation() -- Spawn the smashable the drill bit, so it look like the player smashed the drill bit RESMGR:LoadObject { objectTemplate = 12346, x= oPos.pos.x, y= oPos.pos.y, z= oPos.pos.z, rw = oPos.rot.w, rx = oPos.rot.x, ry = oPos.rot.y, rz = oPos.rot.z, owner = self, configData = config} end end function onUse(self, msg) -- make sure the skill hasnt been caught before if not self:GetNetworkVar("bIsInUse") then -- set flag to true so this wont happen twice self:SetNetworkVar("bIsInUse", true) -- start playing the effects for the staff interaction msg.user:PlayFXEffect{name = "tornado", effectType = "on-anim", effectID = 5499} msg.user:PlayFXEffect{name = "staff", effectType = "on-anim", effectID = 5502} -- set the userID for later local userID = msg.user:GetID() self:SetVar("userID", userID) self:SetVar("activaterID", userID) -- play the startAnim on the player playAnim(self, msg.user, startAnim) playCinematic(self) freezePlayer(self, msg.user, true) end end function freezePlayer(self, player, bFreeze) local eChangeType = "POP" if bFreeze then if player:IsDead().bDead then return end eChangeType = "PUSH" else if player:IsDead().bDead then GAMEOBJ:GetTimer():AddTimerWithCancel( 0.1 , "TryUnFreezeAgain_" .. player:GetID(), self ) return end end player:SetStunned{ StateChangeType = eChangeType, bCantMove = true, bCantAttack = true, bCantInteract = true, bCantUseItem = true} end function onArrived(self, msg) -- get the stand object local standObj = getStandObj(self) -- mover is in the up position so turn it off if msg.wayPoint == 1 then -- do the stop anims and fx self:PlayAnimation{ animationID = "no-spin", fPriority = 2.0} self:StopFXEffect{name = "active"} self:PlayFXEffect{name = "indicator", effectType = "indicator"} -- set to inactive self:SetVar("bActive", false) local player = GAMEOBJ:GetObjectByID(self:GetVar("userID")) if player:Exists() then -- play cinematics and stop player animations playAnim(self, player, endAnim) end if standObj then -- notify the stand object to deactivate the knockback standObj:NotifyObject{ObjIDSender = self, name = "deactivate"} end else -- set the animations and fx to the active state self:PlayAnimation{ animationID = "idle", fPriority = 2.0} self:PlayFXEffect{name = "active", effectType = "spin"} -- stop the indicator fx self:StopFXEffect{name = "indicator"} if standObj then -- notify the stand object to activate the knockback standObj:NotifyObject{ObjIDSender = self, name = "activate"} end end end -- custom function to playCinematic function playCinematic(self) local player = GAMEOBJ:GetObjectByID(self:GetVar("userID")) if not player:Exists() then return end local cine = self:GetVar("cinematic") if not cine then return end -- we found a cinematic so play it player:PlayCinematic{pathName = cine} end function playAnim(self, player, animName) -- see if this object has an animation on it by getting the time local animTime = player:GetAnimationTime{animationID = animName}.time if not animTime then return end -- if the time isn't more than 0 we dont want to do anything if animTime > 0 then -- play the interact animation player:PlayAnimation{ animationID = animName, fPriority = 2.0} -- start up the anim done timer GAMEOBJ:GetTimer():AddTimerWithCancel( animTime , "AnimDone_" .. animName, self ) end end function onChildLoaded(self,msg) -- start timer to reset drill if player doesnt kill the drill bit GAMEOBJ:GetTimer():AddTimerWithCancel( resetTime, "killDrill", self ) -- set child to setvar self:SetVar("ChildSmash", msg.childID:GetID() ) -- we need to know when the child dies self:SendLuaNotificationRequest{requestTarget = msg.childID, messageName = "HitOrHealResult"} end function notifyHitOrHealResult(self, other, msg) -- check if the drill is active if not self:GetVar("bActive") and msg.diedAsResult then -- check if the killer was a player if msg.dealer:IsCharacter().isChar then -- update the missions for the killer for k,missionID in ipairs(missionsToUpdate) do msg.dealer:UpdateMissionTask{taskType = "complete", value = missionID, value2 = 1, target = self} end local activatorID = self:GetVar("activaterID") or 0 -- check if we have an activator if activatorID ~= 0 then -- check if the activator is the killer if activatorID ~= msg.dealer:GetID() then local activator = GAMEOBJ:GetObjectByID(activatorID) -- update the activators mission if they still exist if activator:Exists() then for k,missionID in ipairs(missionsToUpdate) do activator:UpdateMissionTask{taskType = "complete", value = missionID, value2 = 1, target = self} end end end end end -- when the invisible smashable is kill, kill the drill bit self:RequestDie{ killerID = self, killType = "SILENT" } GAMEOBJ:GetTimer():CancelTimer( "killDrill", self ) local standObj = getStandObj(self) if standObj then -- play the explode fx standObj:PlayFXEffect{name = "explode", effectType = "explode", effectID = 4946} end end end function onTimerDone(self, msg) if msg.name == "killDrill" then -- get the drilll bit local bit = GAMEOBJ:GetObjectByID(self:GetVar("ChildSmash")) if bit:Exists() then -- *** add check that shaft still exists -- set the flag back to false self:SetNetworkVar("bIsInUse", false) self:SetVar("bActive", true) self:SetVar("activaterID", 0) --kill the drill bit bit:RequestDie{ killerID = self, killType = "SILENT" } -- set the drill shaft back to starting position self:GoToWaypoint{ iPathIndex = 0; bStopAtWaypoint = true } end elseif string.starts(msg.name, "AnimDone") then local msgData = split(msg.name, "_") local animName = msgData[2] or false local player = GAMEOBJ:GetObjectByID(self:GetVar("userID")) if player:Exists() and animName then if animName == startAnim then toggleDrill(self) -- set inuse to false and update pick type player:PlayAnimation{ animationID = runAnim, fPriority = 2.0} elseif animName == endAnim then freezePlayer(self, player, false) -- clear the user and reequip any items that need it self:SetVar("userID", 0) -- stop the staff interaction fx player:StopFXEffect{name = "tornado"} player:StopFXEffect{name = "staff"} end end elseif string.starts(msg.name, "TryUnFreezeAgain") then local playerID = split(msg.name, "_")[2] or 0 local player = GAMEOBJ:GetObjectByID(playerID) if player:Exists() then freezePlayer(self, player, false) end 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