poison7797 Posted November 18, 2014 Share Posted November 18, 2014 Hello, im having trouble releasing dead enemy after some time. When i kill enemy i want body to disappear after 5 sec. I have change AI script , have no errors but it does not work. Can someone help ? Here is my code. Thanks import "Scripts/AnimationManager.lua" import "Scripts/Functions/GetEntityNeighbors.lua" --Public values Script.health=40--int "Health" Script.enabled=true--bool "Enabled" Script.target=nil--entity "Target" Script.sightradius=3--float "Sight Range" Script.senseradius=3--float "Hearing Range" Script.teamid=2--choice "Team" "Neutral,Good,Bad" --Private values Script.damage=5 Script.attackrange=1 Script.updatefrequency=500 Script.lastupdatetime=0 Script.prevtarget=nil Script.animation={} Script.animation.idle=0 Script.animation.run=1 Script.animation.attack={} Script.animation.attack[0]=2 Script.animation.attack[1]=2 Script.animation.death=3 Script.followingtarget=false Script.maxaccel=10 Script.speed=1.5 Script.lastupdatetargettime=0 Script.attackmode=0 Script.attackbegan=0 Script.sound={} Script.sound.death = Sound:Load("Sound/Characters/zombiecrawlerdie.wav") Script.sound.alert = Sound:Load("Sound/Characters/zombiecrawlerintro.wav") Script.sound.attack={} Script.sound.attack[1] = Sound:Load("Sound/Characters/zombiecrawlerswipe.wav") Script.sound.attack[2] = Sound:Load("Sound/Characters/zombiecrawlerswipe.wav") Script.removeBodyTimer = 0 Script.removeBodyTime = 5 function Script:Enable()--in if self.enabled==false then if self.health>0 then self.enabled=true if self.target~=nil then self:SetMode("roam") else self:SetMode("idle") end end end end function Script:ChooseTarget() local entities = GetEntityNeighbors(self.entity,self.sightradius,true) local k,entity for k,entity in pairs(entities) do if entity.script.teamid~=nil and entity.script.teamid~=0 and entity.script.teamid~=self.teamid then if entity.script.health>0 then local d = self.entity:GetDistance(entity) --if d<self.senseradius then -- return entity.script --else -- local p = Transform:Point(entity:GetPosition(),nil,self.entity) -- if (p.z>-math.abs(p.x) and p.z<-math.abs(p.y)) then local pickinfo=PickInfo() if self.entity.world:Pick(self.entity:GetPosition()+Vec3(0,1.6,0),entity:GetPosition()+Vec3(0,1.6,0),pickinfo,0,false,Collision.LineOfSight)==false then return entity.script end -- end --end end end end end function Script:DistanceToTarget() local pos = self.entity:GetPosition() local targetpos = self.target.entity:GetPosition() if math.abs(targetpos.y-pos.y)<1.5 then return pos:xz():DistanceToPoint(targetpos:xz()) else return 100000--if they are on different vertical levels, assume they can't be reached end end function Script:TargetInRange() local pos = self.entity:GetPosition() local targetpos = self.target.entity:GetPosition() if math.abs(targetpos.y-pos.y)<1.5 then if pos:xz():DistanceToPoint(targetpos:xz())<self.attackrange then return true end end return false end --[[ function WorldGetEntitiesInAABBDoCallback(entity,extra) if entity~=extra then if GetEntityNeighborsScriptedOnly==false or entity.script~=nil then table.insert(WorldGetEntitiesInAABBDoCallbackTable,entity) end end end function GetEntityNeighbors(entity,radius,scriptOnly) local result local aabb = AABB() local p = entity:GetPosition(true) local temp = GetEntityNeighborsScriptedOnly GetEntityNeighborsScriptedOnly=scriptOnly aabb.min = p - radius aabb.max = p + radius aabb:Update() local table = WorldGetEntitiesInAABBDoCallbackTable WorldGetEntitiesInAABBDoCallbackTable = {} entity.world:ForEachEntityInAABBDo(aabb,"WorldGetEntitiesInAABBDoCallback",entity) result = WorldGetEntitiesInAABBDoCallbackTable WorldGetEntitiesInAABBDoCallbackTable = table GetEntityNeighborsScriptedOnly = temp return result end ]]-- function Script:Start() self.animationmanager = AnimationManager:Create(self.entity) if self.enabled then if self.target~=nil then self:SetMode("roam") else self:SetMode("idle") end end end function Script:Hurt(damage,distributorOfPain) if self.health>0 then if self.target==nil then self.target=distributorOfPain self:SetMode("attack") end self.health = self.health - damage if self.health<=0 then self.entity:SetMass(0) self.entity:SetCollisionType(0) self.entity:SetPhysicsMode(Entity.RigidBodyPhysics) self:SetMode("dying") end end end function Script:EndDeath() self:SetMode("dead") self.removeBodyTimer = self.removeBodyTimer + (Time:GetSpeed()/100) end function Script:DirectMoveToTarget() self.entity:Stop() local targetpos = self.target.entity:GetPosition() local pos = self.entity:GetPosition() local dir = Vec2(targetpos.z-pos.z,targetpos.x-pos.x):Normalize() local angle = -Math:ATan2(dir.y,-dir.x) self.entity:SetInput(angle,self.speed) end function Script:SetMode(mode) if mode~=self.mode then local prevmode=self.mode self.mode=mode if mode=="idle" then self.target=nil self.animationmanager:SetAnimationSequence(0,0.02) self.entity:Stop()--stop following anything elseif mode=="roam" then if self.target~=nil then self.animationmanager:SetAnimationSequence(1,0.04) self.entity:GoToPoint(self.target:GetPosition(true),5,5) else self:SetMode("idle") end elseif mode=="attack" then self:EndAttack() elseif mode=="chase" then if self.entity:Follow(self.target.entity,self.speed,self.maxaccel) then if prevmode~="chase" then self.entity:EmitSound(self.sound.alert) end self.followingtarget=true self.animationmanager:SetAnimationSequence(self.animation.run,0.05,300) if self:DistanceToTarget()<self.attackrange*2 then self.followingtarget=false self.entity:Stop() self:DirectMoveToTarget() end else self.target=nil self:SetMode("idle") return end elseif mode=="dying" then self.entity:EmitSound(self.sound.death) self.entity:Stop() self.animationmanager:SetAnimationSequence(self.animation.death,0.04,300,1,self,self.EndDeath) elseif mode=="dead" then self.entity:SetCollisionType(0) self.entity:SetMass(0) self.entity:SetShape(nil) self.entity:SetPhysicsMode(Entity.RigidBodyPhysics) self.enabled=false if (self.removeBodyTimer > self.removeBodyTime) then self.entity:Release() end end end end function Script:EndAttack() if self.mode=="attack" then if self.target.health<=0 then self:SetMode("idle") return end local d = self:DistanceToTarget() if d>self.attackrange then --if d>self.attackrange*2 then self:SetMode("chase") return --else -- local pos = self.entity:GetPosition() -- local targetpos = self.target.entity:GetPosition() -- self.entity:SetInput(-Math:ATan2(targetpos.x-pos.x,targetpos.y-pos.y),self.speed) -- return --end end self.entity:Stop() self.attackmode = 1-self.attackmode--switch between right and left attack modes self.animationmanager:SetAnimationSequence(self.animation.attack[self.attackmode],0.04*math.random(1,1.25),300,1,self,self.EndAttack) self.attackbegan = Time:GetCurrent() if math.random()>0.75 then self.entity:EmitSound(self.sound.attack[self.attackmode+1]) end end end function Script:UpdatePhysics() if self.enabled==false then return end local t = Time:GetCurrent() self.entity:SetInput(self.entity:GetRotation().y,0) if self.mode=="idle" then if t-self.lastupdatetargettime>250 then self.lastupdatetargettime=t self.target = self:ChooseTarget() if self.target then self:SetMode("chase") end end elseif self.mode=="roam" then if self.entity:GetDistance(self.target)<1 then self:SetMode("idle") end elseif self.mode=="chase" then if self.target.health<=0 then self:SetMode("idle") return end if self:TargetInRange() then self:SetMode("attack") elseif self:DistanceToTarget()<self.attackrange*2 then self.followingtarget=false self.entity:Stop() self:DirectMoveToTarget() else if self.followingtarget==false then if self.entity:Follow(self.target.entity,self.speed,self.maxaccel) then self:SetMode("idle") end end end elseif self.mode=="attack" then if self.attackbegan~=nil then if t-self.attackbegan>300 then self.attackbegan=nil self.target:Hurt(self.damage) end end local pos = self.entity:GetPosition() local targetpos = self.target.entity:GetPosition() local dx=targetpos.x-pos.x local dz=targetpos.z-pos.z self.entity:AlignToVector(-dx,0,-dz) end end function Script:Draw() if self.enabled==false then return end self.animationmanager:Update() end Quote PoisonGames Link to comment Share on other sites More sharing options...
Ma-Shell Posted November 18, 2014 Share Posted November 18, 2014 Your EndDeath()-Function only gets called once, after the dying-animation is finnished. Assuming, you want the timer to start then, you should replace self.removeBodyTimer = self.removeBodyTimer + (Time:GetSpeed()/100) at that point by self.removeBodyTimer = 0 Then you have to increase the timer every frame and check, if its value exceeded the given threshold. So, you should move the line, you originally had into UpdatePhysics()-Function. You should have a chunk there that says: if mode == "dead" then self.removeBodyTimer = self.removeBodyTimer + (Time:GetSpeed()/100) if (self.removeBodyTimer > self.removeBodyTime) then self.entity:Release() end end Quote Link to comment Share on other sites More sharing options...
poison7797 Posted November 18, 2014 Author Share Posted November 18, 2014 Thanks for help. I done that but still wont work! Can you check ? import "Scripts/AnimationManager.lua" import "Scripts/Functions/GetEntityNeighbors.lua" --Public values Script.health=40--int "Health" Script.enabled=true--bool "Enabled" Script.target=nil--entity "Target" Script.sightradius=3--float "Sight Range" Script.senseradius=3--float "Hearing Range" Script.teamid=2--choice "Team" "Neutral,Good,Bad" --Private values Script.damage=5 Script.attackrange=1 Script.updatefrequency=500 Script.lastupdatetime=0 Script.prevtarget=nil Script.animation={} Script.animation.idle=0 Script.animation.run=1 Script.animation.attack={} Script.animation.attack[0]=2 Script.animation.attack[1]=2 Script.animation.death=3 Script.followingtarget=false Script.maxaccel=10 Script.speed=1.5 Script.lastupdatetargettime=0 Script.attackmode=0 Script.attackbegan=0 Script.sound={} Script.sound.death = Sound:Load("Sound/Characters/zombiecrawlerdie.wav") Script.sound.alert = Sound:Load("Sound/Characters/zombiecrawlerintro.wav") Script.sound.attack={} Script.sound.attack[1] = Sound:Load("Sound/Characters/zombiecrawlerswipe.wav") Script.sound.attack[2] = Sound:Load("Sound/Characters/zombiecrawlerswipe.wav") Script.removeBodyTimer = 0 Script.removeBodyTime = 5 function Script:Enable()--in if self.enabled==false then if self.health>0 then self.enabled=true if self.target~=nil then self:SetMode("roam") else self:SetMode("idle") end end end end function Script:ChooseTarget() local entities = GetEntityNeighbors(self.entity,self.sightradius,true) local k,entity for k,entity in pairs(entities) do if entity.script.teamid~=nil and entity.script.teamid~=0 and entity.script.teamid~=self.teamid then if entity.script.health>0 then local d = self.entity:GetDistance(entity) --if d<self.senseradius then -- return entity.script --else -- local p = Transform:Point(entity:GetPosition(),nil,self.entity) -- if (p.z>-math.abs(p.x) and p.z<-math.abs(p.y)) then local pickinfo=PickInfo() if self.entity.world:Pick(self.entity:GetPosition()+Vec3(0,1.6,0),entity:GetPosition()+Vec3(0,1.6,0),pickinfo,0,false,Collision.LineOfSight)==false then return entity.script end -- end --end end end end end function Script:DistanceToTarget() local pos = self.entity:GetPosition() local targetpos = self.target.entity:GetPosition() if math.abs(targetpos.y-pos.y)<1.5 then return pos:xz():DistanceToPoint(targetpos:xz()) else return 100000--if they are on different vertical levels, assume they can't be reached end end function Script:TargetInRange() local pos = self.entity:GetPosition() local targetpos = self.target.entity:GetPosition() if math.abs(targetpos.y-pos.y)<1.5 then if pos:xz():DistanceToPoint(targetpos:xz())<self.attackrange then return true end end return false end --[[ function WorldGetEntitiesInAABBDoCallback(entity,extra) if entity~=extra then if GetEntityNeighborsScriptedOnly==false or entity.script~=nil then table.insert(WorldGetEntitiesInAABBDoCallbackTable,entity) end end end function GetEntityNeighbors(entity,radius,scriptOnly) local result local aabb = AABB() local p = entity:GetPosition(true) local temp = GetEntityNeighborsScriptedOnly GetEntityNeighborsScriptedOnly=scriptOnly aabb.min = p - radius aabb.max = p + radius aabb:Update() local table = WorldGetEntitiesInAABBDoCallbackTable WorldGetEntitiesInAABBDoCallbackTable = {} entity.world:ForEachEntityInAABBDo(aabb,"WorldGetEntitiesInAABBDoCallback",entity) result = WorldGetEntitiesInAABBDoCallbackTable WorldGetEntitiesInAABBDoCallbackTable = table GetEntityNeighborsScriptedOnly = temp return result end ]]-- function Script:Start() self.animationmanager = AnimationManager:Create(self.entity) if self.enabled then if self.target~=nil then self:SetMode("roam") else self:SetMode("idle") end end end function Script:Hurt(damage,distributorOfPain) if self.health>0 then if self.target==nil then self.target=distributorOfPain self:SetMode("attack") end self.health = self.health - damage if self.health<=0 then self.entity:SetMass(0) self.entity:SetCollisionType(0) self.entity:SetPhysicsMode(Entity.RigidBodyPhysics) self:SetMode("dying") end end end function Script:EndDeath() self:SetMode("dead") self.removeBodyTimer = 0 end function Script:DirectMoveToTarget() self.entity:Stop() local targetpos = self.target.entity:GetPosition() local pos = self.entity:GetPosition() local dir = Vec2(targetpos.z-pos.z,targetpos.x-pos.x):Normalize() local angle = -Math:ATan2(dir.y,-dir.x) self.entity:SetInput(angle,self.speed) end function Script:SetMode(mode) if mode~=self.mode then local prevmode=self.mode self.mode=mode if mode=="idle" then self.target=nil self.animationmanager:SetAnimationSequence(0,0.02) self.entity:Stop()--stop following anything elseif mode=="roam" then if self.target~=nil then self.animationmanager:SetAnimationSequence(1,0.04) self.entity:GoToPoint(self.target:GetPosition(true),5,5) else self:SetMode("idle") end elseif mode=="attack" then self:EndAttack() elseif mode=="chase" then if self.entity:Follow(self.target.entity,self.speed,self.maxaccel) then if prevmode~="chase" then self.entity:EmitSound(self.sound.alert) end self.followingtarget=true self.animationmanager:SetAnimationSequence(self.animation.run,0.05,300) if self:DistanceToTarget()<self.attackrange*2 then self.followingtarget=false self.entity:Stop() self:DirectMoveToTarget() end else self.target=nil self:SetMode("idle") return end elseif mode=="dying" then self.entity:EmitSound(self.sound.death) self.entity:Stop() self.animationmanager:SetAnimationSequence(self.animation.death,0.04,300,1,self,self.EndDeath) elseif mode=="dead" then self.entity:SetCollisionType(0) self.entity:SetMass(0) self.entity:SetShape(nil) self.entity:SetPhysicsMode(Entity.RigidBodyPhysics) self.enabled=false end end end function Script:EndAttack() if self.mode=="attack" then if self.target.health<=0 then self:SetMode("idle") return end local d = self:DistanceToTarget() if d>self.attackrange then --if d>self.attackrange*2 then self:SetMode("chase") return --else -- local pos = self.entity:GetPosition() -- local targetpos = self.target.entity:GetPosition() -- self.entity:SetInput(-Math:ATan2(targetpos.x-pos.x,targetpos.y-pos.y),self.speed) -- return --end end self.entity:Stop() self.attackmode = 1-self.attackmode--switch between right and left attack modes self.animationmanager:SetAnimationSequence(self.animation.attack[self.attackmode],0.04*math.random(1,1.25),300,1,self,self.EndAttack) self.attackbegan = Time:GetCurrent() if math.random()>0.75 then self.entity:EmitSound(self.sound.attack[self.attackmode+1]) end end end function Script:UpdatePhysics() if self.enabled==false then return end local t = Time:GetCurrent() self.entity:SetInput(self.entity:GetRotation().y,0) if self.mode=="idle" then if t-self.lastupdatetargettime>250 then self.lastupdatetargettime=t self.target = self:ChooseTarget() if self.target then self:SetMode("chase") end end elseif self.mode=="roam" then if self.entity:GetDistance(self.target)<1 then self:SetMode("idle") end elseif self.mode=="chase" then if self.target.health<=0 then self:SetMode("idle") return end if self:TargetInRange() then self:SetMode("attack") elseif self:DistanceToTarget()<self.attackrange*2 then self.followingtarget=false self.entity:Stop() self:DirectMoveToTarget() else if self.followingtarget==false then if self.entity:Follow(self.target.entity,self.speed,self.maxaccel) then self:SetMode("idle") end end end elseif self.mode=="attack" then if self.attackbegan~=nil then if t-self.attackbegan>300 then self.attackbegan=nil self.target:Hurt(self.damage) end end if mode == "dead" then self.removeBodyTimer = self.removeBodyTimer + (Time:GetSpeed()/100) if (self.removeBodyTimer > self.removeBodyTime) then self.entity:Release() end end local pos = self.entity:GetPosition() local targetpos = self.target.entity:GetPosition() local dx=targetpos.x-pos.x local dz=targetpos.z-pos.z self.entity:AlignToVector(-dx,0,-dz) end end function Script:Draw() if self.enabled==false then return end self.animationmanager:Update() end Thanks Quote PoisonGames Link to comment Share on other sites More sharing options...
Ma-Shell Posted November 18, 2014 Share Posted November 18, 2014 It has to be "self.mode" inside the UpdatePhysics()-Function (My bad ) If it still doesn't work, try printing the value of "self.removeBodyTimer" after increasing it and see, if this creates any usable information. Quote Link to comment Share on other sites More sharing options...
poison7797 Posted November 18, 2014 Author Share Posted November 18, 2014 Thanks, still wont work. System Print wont print anything. I have create RemoveBody.lua and when i put that script on some entity, lets say barrel, its working. But when inside of MonsterAI.lua it just wont work. Strange... Quote PoisonGames Link to comment Share on other sites More sharing options...
Ma-Shell Posted November 18, 2014 Share Posted November 18, 2014 You put the chunk inside the if self.mode == "attack" Block. This is bound to fail. Move it outside. Quote Link to comment Share on other sites More sharing options...
poison7797 Posted November 18, 2014 Author Share Posted November 18, 2014 outside where ? I have put that code on many places inside UpdatePhisics. Can you give me example! Please! Quote PoisonGames Link to comment Share on other sites More sharing options...
poison7797 Posted November 18, 2014 Author Share Posted November 18, 2014 Ohh i did it Thanks a LOT MAN!!!!! Quote PoisonGames Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.