-- Wandering and Following Creature AI for skill summoned creatures -- Three proximity volumes created on an object: -- 1 - StopFollow - On enter stops pet from following player -- 2 - Wander - On enter starts pet's wandering AI, on exit starts pet following player -- 3 - Teleport - On exit teleports pet to player -- Erik Beyer 5-3-11 -- Extent of proximity volumes local StopFollowRadius = 5 local WanderRadius = 10 local TeleportRadius = 50 -- Min Max Time Delay while wandering local WanderDelayMin = 4 local WanderDelayMax = 9 -- What's the walk speed of the creature while wandering? 0.5 and below plays the walk animation instead of the run local WanderSpeed = 0.5 function onStartup(self) -- Set the faction to receive emotes self:SetFaction{faction = -1} -- Tell pet to not allow follow cancelling until it actually is following self:SetVar("follow",false) -- Create proximities self:SetProximityRadius{radius = StopFollowRadius, name = "StopFollow"} self:SetProximityRadius{radius = WanderRadius + 5, name = "Wander"} -- Adding +5 to make sure his wander doesn't get him into his follow state self:SetProximityRadius{radius = TeleportRadius, name = "Teleport"} end function onProximityUpdate(self, msg) local player = self:GetParentObj().objIDParent -- Random value generated for wander timer local randwandtime = math.random (WanderDelayMin, WanderDelayMax) -- Is the player interacting with the proximities? if (player) then if (msg.name == "StopFollow") then if (msg.status == "ENTER") then --Only cancel follow if the pet's following if self:GetVar("follow") then --print "Cancel follow" -- Stop following player self:FollowTarget { targetID = msg.objId, radius = StopFollowRadius, speed = 2, keepFollowing = false, bRequireValidPath = true } -- Can't cancel follow until follow is reactivated self:SetVar("follow",false) end end elseif (msg.name == "Wander") then if (msg.status == "ENTER") then -- Start wander timer --print "Start Wander Timer" GAMEOBJ:GetTimer():AddTimerWithCancel(randwandtime, "StartWander", self) elseif (msg.status == "LEAVE") then -- Start following --print "Start following" self:FollowTarget { targetID = msg.objId, radius = StopFollowRadius, speed = 2, keepFollowing = true, bRequireValidPath = true } -- Make sure the wander timer's cancelled when the pet's wandering GAMEOBJ:GetTimer():CancelAllTimers(self) -- Allow follow to be cancelled self:SetVar("follow",true) end elseif (msg.name == "Teleport") then if (msg.status == "LEAVE") then -- Get player and player's position--we know the player's the parent of the skill created object local ParentID = self:GetParentObj().objIDParent local ParentPos = ParentID:GetPosition().pos -- Get position 5 units behind the player and teleport pet there local xSplit= {x= ParentPos.x, y= ParentPos.y, z= ParentPos.z + 5} self:Teleport{ pos = xSplit} -- Also match pet's rotation to player's rotation local rot = ParentID:GetRotation() self:SetRotation{y=rot.y, x=rot.x, w=rot.w, z=rot.z} end end end end -- Wander Function - Gets a random location around the Minifig (the parent) and goes there -- function Wander(self,msg) -- Get player pos local wanderround = self:GetParentObj().objIDParent local mypos = wanderround:GetPosition().pos -- Get a random point around the Minifig through the getRandomPos function local PoS = getRandomPos(self,mypos) -- Go to random point self:GoTo {speed = WanderSpeed, target = { x = PoS.x, z = PoS.z, y = PoS.y, }, } end function getRandomPos(self,myPos) -- Not sure how this works since Wander radius is just restored to WanderRadius on PosMin, but it does work PoSSet = WanderRadius + WanderRadius PoSMin = WanderRadius - PoSSet PoSMax = WanderRadius PoS = {} PoS.x = myPos.x + math.random (PoSMin, WanderRadius) PoS.z = myPos.z + math.random (PoSMin, WanderRadius) PoS.y = myPos.y return PoS end function onTimerDone(self, msg) -- Random value generated for wander timer local randwandtime = math.random (WanderDelayMin, WanderDelayMax) if (msg.name == "StartWander") then -- Call wander function Wander(self,msg) -- Make sure we don't have any overlapping wander timers GAMEOBJ:GetTimer():CancelAllTimers(self) -- Start another wander timer GAMEOBJ:GetTimer():AddTimerWithCancel( randwandtime, "StartWander", self ) --print (PoS.x .. PoS.y .. PoS.z) end end