Fancy_Fox_Pers Posted April 24, 2016 Share Posted April 24, 2016 Hi, there! I want my follower to die when the leader attacks him or to despawn when the leader logs out. I wanted to use abigail's code when she gets attacked, but I realised that my follower stops following when getting attacked and that it wouldn't make it despawn when logging out anyway. Any ideas? (Sorry for posting so much) Link to comment Share on other sites More sharing options...
Aquaterion Posted April 24, 2016 Share Posted April 24, 2016 (edited) --wurm.lua local function onattacked(inst, data) if data.attacker == inst.components.follower:GetLeader() then inst.components.health:Kill() else inst.components.combat:SetTarget(data.attacker) inst.components.combat:ShareTarget(data.attacker, 30, function(friend) return not friend.components.health:IsDead() and friend.components.follower ~= nil and friend.components.follower.leader == inst.components.follower.leader end, 10) end end -- main function inst:ListenForEvent("attacked", onattacked) and in the previous listening for "stopfollowing" do --under local wurmleader = data.leader inst:DoTaskInTime(0.5, --wait a bit to make sure the leader is nil (not positive on how much this actually works) function() if wurmleader == nil then inst:Remove()-- or inst.components.health:Kill() end end) --note, this would probably only work on dedicated servers or clients, since as a host, the server would just close -- you could add this to the main function to make it disappear when the server closes inst.persists = false Edited April 24, 2016 by Aquaterion Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted April 24, 2016 Author Share Posted April 24, 2016 @Aquaterion Thank you for replying again Sorry, it doesn't work. To be clear, I put the local function onattacked in the lua, thought of listening for the event in the main function and for the stopfollowing I did this : inst:ListenForEvent("stopfollowing", function(inst, data) local wurmleader = data.leader if wurmleader ~= nil and not wurmleader:HasTag("wurm_thibaud_builder") then -- print("Game knows wurmleader can't craft wurms") local wurms = wurmleader.components.leader:CountFollowers("wurm") -- print("Game counts followers again") if wurmleader.components.leader:CountFollowers("wurm") < 4 then -- print("Game knows there are less than 4 followers") wurmleader:AddTag("wurm_thibaud_builder") -- print("Character is now able to craft wurms again") end end inst:DoTaskInTime(0.5, --wait a bit to make sure the leader is nil (not positive on how much this actually works) function() if wurmleader == nil then inst:Remove()-- or inst.components.health:Kill() end end) end) And this is exactly how the code is set up, the forum didn't make any spacing mistakes Link to comment Share on other sites More sharing options...
Aquaterion Posted April 24, 2016 Share Posted April 24, 2016 Just now, Thibooms said: @Aquaterion Thank you for replying again Sorry, it doesn't work. To be clear, I put the local function onattacked in the lua, thought of listening for the event in the main function and for the stopfollowing I did this : inst:ListenForEvent("stopfollowing", function(inst, data) local wurmleader = data.leader if wurmleader ~= nil and not wurmleader:HasTag("wurm_thibaud_builder") then -- print("Game knows wurmleader can't craft wurms") local wurms = wurmleader.components.leader:CountFollowers("wurm") -- print("Game counts followers again") if wurmleader.components.leader:CountFollowers("wurm") < 4 then -- print("Game knows there are less than 4 followers") wurmleader:AddTag("wurm_thibaud_builder") -- print("Character is now able to craft wurms again") end end inst:DoTaskInTime(0.5, --wait a bit to make sure the leader is nil (not positive on how much this actually works) function() if wurmleader == nil then inst:Remove()-- or inst.components.health:Kill() end end) end) And this is exactly how the code is set up, the forum didn't make any spacing mistakes so what didn't work? both? or the despawn on leave? did you see the inst.persists things? Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted April 24, 2016 Author Share Posted April 24, 2016 (edited) 1 minute ago, Aquaterion said: so what didn't work? both? or the despawn on leave? did you see the inst.persists things? Both, sadly. Forgot about the inst.persists, doing it now Edit: Ok, the despawning upon logging out now works. But will this then not work when hosting a normal server? Edited April 24, 2016 by Thibooms Link to comment Share on other sites More sharing options...
Aquaterion Posted April 24, 2016 Share Posted April 24, 2016 (edited) You sure the onattacked thing didn't work? because I have it for mine and it works just fine, you could try inst:Remove() instead of the inst......Kill() Edited April 24, 2016 by Aquaterion Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted April 24, 2016 Author Share Posted April 24, 2016 Just now, Aquaterion said: You sure the onattacked thing didn't work? because I have it for mine and it works just fine, you could try inst:Remove() instead of the inst......Kill() Yeah I'm sure it didn't work. Don't know why though. Again, to be clear, this is what I got. In the lua local function onattacked(inst, data) if data.attacker == inst.components.follower:GetLeader() then inst.components.health:Kill() else inst.components.combat:SetTarget(data.attacker) inst.components.combat:ShareTarget(data.attacker, 30, function(friend) return not friend.components.health:IsDead() and friend.components.follower ~= nil and friend.components.follower.leader == inst.components.follower.leader end, 10) end end In the main function inst:ListenForEvent("attacked", onattacked) Link to comment Share on other sites More sharing options...
Aquaterion Posted April 24, 2016 Share Posted April 24, 2016 Just now, Thibooms said: Yeah I'm sure it didn't work. Don't know why though. Again, to be clear, this is what I got. In the lua local function onattacked(inst, data) if data.attacker == inst.components.follower:GetLeader() then inst.components.health:Kill() else inst.components.combat:SetTarget(data.attacker) inst.components.combat:ShareTarget(data.attacker, 30, function(friend) return not friend.components.health:IsDead() and friend.components.follower ~= nil and friend.components.follower.leader == inst.components.follower.leader end, 10) end end In the main function inst:ListenForEvent("attacked", onattacked) that's all in the wurm.lua right? well add some prints to see if it's even getting there print("Onattacked") print(data.attacker) Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted April 24, 2016 Author Share Posted April 24, 2016 (edited) 3 minutes ago, Aquaterion said: that's all in the wurm.lua right? Yes 3 minutes ago, Aquaterion said: well add some prints to see if it's even getting there I guess it's not getting there but I'll try the prints now FYI: I tried by replacing the kill by inst:Remove() and then I tried inst.components.health:SetVal(0) Edit: Ok so I see this in the log (I attacked the thing to death) [00:00:48]: onattacked function gets called [00:00:49]: onattacked function gets called [00:00:49]: onattacked function gets called [00:00:52]: onattacked function gets called [00:00:52]: onattacked function gets called I printed by adding print("onattacked function gets called") directly under the function, before the if Edited April 24, 2016 by Thibooms Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted April 24, 2016 Author Share Posted April 24, 2016 (edited) 6 minutes ago, Aquaterion said: print("data.attacker") Where do I put this? client_log.txt Edited April 24, 2016 by Thibooms Link to comment Share on other sites More sharing options...
Aquaterion Posted April 24, 2016 Share Posted April 24, 2016 Just now, Thibooms said: Where do I put this? client_log.txt [00:00:47]: onattacked function gets called [00:00:48]: onattacked function gets called [00:00:49]: onattacked function gets called [00:00:49]: onattacked function gets called [00:00:52]: onattacked function gets called [00:00:52]: onattacked function gets called seems like it is getting called and its print(data.attacker), without the " ", put it right below the other 1, its to print the attacker, to check if for some reason hes nil Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted April 24, 2016 Author Share Posted April 24, 2016 (edited) [00:00:44]: onattacked function gets called [00:00:44]: 110793 - thibaud [00:00:45]: onattacked function gets called [00:00:45]: 110793 - thibaud [00:00:46]: onattacked function gets called [00:00:46]: 110793 - thibaud [00:00:46]: onattacked function gets called [00:00:46]: 110793 - thibaud [00:00:47]: onattacked function gets called [00:00:47]: 110793 - thibaud [00:00:47]: onattacked function gets called [00:00:47]: 110793 - thibaud client_log.txt Don't know what this means ^^ I made sure to not put the " " Edited April 24, 2016 by Thibooms Link to comment Share on other sites More sharing options...
Aquaterion Posted April 24, 2016 Share Posted April 24, 2016 Just now, Thibooms said: [00:00:44]: onattacked function gets called [00:00:44]: 110793 - thibaud [00:00:45]: onattacked function gets called [00:00:45]: 110793 - thibaud [00:00:46]: onattacked function gets called [00:00:46]: 110793 - thibaud [00:00:46]: onattacked function gets called [00:00:46]: 110793 - thibaud [00:00:47]: onattacked function gets called [00:00:47]: 110793 - thibaud [00:00:47]: onattacked function gets called [00:00:47]: 110793 - thibaud client_log.txt Don't know what this means ^^ I made sure to not put the " " wait, do you have a character called thibaud? because if you do, then that's normal, can you put another print in the "if" as well? Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted April 24, 2016 Author Share Posted April 24, 2016 Just now, Aquaterion said: wait, do you have a character called thibaud? because if you do, then that's normal, can you put another print in the "if" as well? Yes I do. I added the print in the if I don't see anything about the if print though. It put it like this : local function onattacked(inst, data) print("onattacked function gets called") print(data.attacker) if data.attacker == inst.components.follower:GetLeader() then print("the if got fired") client_log.txt Link to comment Share on other sites More sharing options...
Aquaterion Posted April 24, 2016 Share Posted April 24, 2016 if inst.components.follower:GetLeader() == nil then inst:Remove() -- or kill end Oh wait, I just realised what it is, change the "if" to the one above ^ It wasnt working because the follower component makes it that if a follower is attacked by its owner, it stops "following" it, so the leader was always being nil, and to combat that, we'll check if it has a leader instead. Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted April 24, 2016 Author Share Posted April 24, 2016 1 minute ago, Aquaterion said: if inst.components.follower:GetLeader() == nil then inst:Remove() -- or kill end Oh wait, I just realised what it is, change the "if" to the one above ^ It wasnt working because the follower component makes it that if a follower is attacked by its owner, it stops "following" it, so the leader was always being nil, and to combat that, we'll check if it has a leader instead. Oh that's a cool way of doing it. Thanks! Works now Link to comment Share on other sites More sharing options...
Aquaterion Posted April 24, 2016 Share Posted April 24, 2016 (edited) 4 minutes ago, Thibooms said: Oh that's a cool way of doing it. Thanks! Works now what the weird thing is, technically, when you attack it, "stopfollowing" should have been triggered, making it despawn at 0.5 seconds.. hmmm Can you comment the onattack thing for now and try this?(you only need to comment the listener part) --change the "if" in the "inst:DoTaskInTime()" to this: if inst.components.follower:GetLeader() == nil then inst:Remove()-- or inst.components.health:Kill() end Edited April 24, 2016 by Aquaterion Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted April 24, 2016 Author Share Posted April 24, 2016 9 minutes ago, Aquaterion said: what the weird thing is, technically, when you attack it, "stopfollowing" should have been triggered, making it despawn at 0.5 seconds.. hmmm Can you comment the onattack thing for now and try this?(you only need to comment the listener part) --change the "if" in the "inst:DoTaskInTime()" to this: if inst.components.follower:GetLeader() == nil then inst:Remove()-- or inst.components.health:Kill() end Yeah That works, it dies after half a second (like you'd think it does). So best to keep this then? Which one do you think is most practical when coding (if I want to add anything, which I don't at the moment) Link to comment Share on other sites More sharing options...
Aquaterion Posted April 24, 2016 Share Posted April 24, 2016 (edited) Just now, Thibooms said: Yeah That works, it dies after half a second (like you'd think it does). So best to keep this then? Which one do you think is most practical when coding (if I want to add anything, which I don't at the moment) you could probably lower the time to like 0.1 or 0.2 The new DoTaskInTime would be required in multiplayer I believe so that 1 will have to stay, and the other, well its kinda pointless if its gonna get removed before anyways, although I also put some code in there for targetting, sharing targets with friendly followers and not attacking friendlies, so just remove the inst:remove() line from the onattacked BTW, You should probably try making your forum titles less specific, that way you don't have to do 4-5 topics for 1 creature Edited April 24, 2016 by Aquaterion Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted April 24, 2016 Author Share Posted April 24, 2016 Just now, Aquaterion said: you could probably lower the time to like 0.1 or 0.2 Actually that's only annoying when using Remove. With kill it dies just fine (which sounds awkard to say) Just now, Aquaterion said: The new DoTaskInTime would be required in multiplayer I believe so that 1 will have to stay, and the other, well its kinda pointless if its gonna get removed before anyways, although I also put some code in there for targetting, sharing targets with friendly followers and not attacking friendlies, so just remove the inst:remove() line from the onattacked Ok, thanks Just now, Aquaterion said: BTW, You should probably try making your forum titles less specific, that way you don't have to do 4-5 topics for 1 creature Yeah sorry but every single time I'm done with one topic I think of another thing I forgot x). I'll try being less specific next time ^^ Thank you so much Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted April 25, 2016 Author Share Posted April 25, 2016 (edited) @Aquaterion Hi man sorry to bother you by pushing this notification but I thought it was best to do this rather than to make another post on this same damn creature. I promise this is the last thing! ^^' So I wanted him to explode when getting attacked, which I managed to code by myself (yay me)! But I'm having a little trouble making him attack back. Right now, he will GO to a creature that attacks him or that the leader attacks but he WIL NOT actually attack (opponent doesn't go to "hit" state). Here's the code I used (that I got from an old mod I made, but someone coded for me) along with some questions (because I've forgotten how it works : This gets fired by the "attacked" event local function attackback(inst, data) inst.components.combat:SetTarget(data.attacker) -- The Wurm sets the target (guy who attacked him)? inst.components.combat:ShareTarget(data.attacker, 30,function(dude) -- Here the wurm is supposed to go after the same guy the leader attacks? return dude:HasTag("paperdrawing") and not dude:HasTag("player") and not dude.components.health:IsDead() -- The Wurm makes sure it's not attacking a Wurm or player or something that's dead? end, 5) -- What's this 5? (Also, what's the 30 above?) end This is how I made sure he should be able to do damage (main function) inst:AddComponent("combat") inst.components.combat:SetDefaultDamage(TUNING.KOALEFANT_DAMAGE) This is in the stategraph and originally comes from the koealefant : State{ name = "attack", tags = {"attack"}, onenter = function(inst) -- inst.SoundEmitter:PlaySound("dontstarve/creatures/koalefant/angry") inst.components.combat:StartAttack() inst.components.locomotor:StopMoving() inst.AnimState:PlayAnimation("attack_down") --this said "atk_pre" inst.AnimState:PushAnimation("attack_down", false) -- this said "atk" end, timeline= { TimeEvent(15*FRAMES, function(inst) inst.components.combat:DoAttack() end), -- What's this? }, events= { EventHandler("animqueueover", function(inst) inst.sg:GoToState("idle") end), -- What's this? }, }, And this is the brain : require "behaviours/follow" require "behaviours/wander" local MIN_FOLLOW = 0 local MAX_FOLLOW = 8 local MED_FOLLOW = 6 local MAX_WANDER_DIST = 10 local MAX_CHASE_TIME = 6 --Here we create a new brain local wurm_thibaudbrain = Class(Brain, function(self, inst) Brain._ctor(self, inst) self.mytarget = nil end) function wurm_thibaudbrain:SetTarget(target) self.listenerfunc = function() self.mytarget = nil end if target ~= self.target then if self.mytarget then self.inst:RemoveEventCallback("onremove", self.listenerfunc, self.mytarget) end if target then self.inst:ListenForEvent("onremove", self.listenerfunc, target) end end self.mytarget = target end --This function sets up our brain's 'behavior tree'. A behavior tree is just a prioritized list of behaviors. --In this case, our creature's first priority is always to runaway and it's second priority is to stand around --looking pretty. You can find more behaviours in the game's data/scripts/behaviours folder. function wurm_thibaudbrain:OnStart() --Some behavior trees have multiple priority nodes. Ours has a single node with two behaviours. local root = PriorityNode( { ChaseAndAttack(self.inst, MAX_CHASE_TIME), Follow(self.inst, function() return self.inst.components.follower.leader end, MIN_FOLLOW, MED_FOLLOW, MAX_FOLLOW, true), Wander(self.inst, function() if self.mytarget then return Point(self.mytarget.Transform:GetWorldPosition()) end end, MAX_WANDER_DIST) --This tells the creature to check every 1 second if it should be changing which behaviour it's doing. }, 1) --Now we attach the behaviour tree to our brain. self.bt = BT(self.inst, root) end --Register our new brain so that it can later be attached to any creature we create. return wurm_thibaudbrain I hope you can help when you have the time of course Edited April 25, 2016 by Thibooms Link to comment Share on other sites More sharing options...
Aquaterion Posted April 25, 2016 Share Posted April 25, 2016 I had this problem too, this is what DarkXero told me to do to fix it: --wurm.lua local function doattack(inst, data) --inst.sg:GoToState("attack", data.target) if inst.components.health and not inst.components.health:IsDead() and (not inst.sg:HasStateTag("busy") or inst.sg:HasStateTag("hit")) then local buffered_attack = BufferedAction(inst, data.target, ACTIONS.ATTACK) inst:PushBufferedAction(buffered_attack) end end --main function inst:ListenForEvent("doattack", doattack) Link to comment Share on other sites More sharing options...
DarkXero Posted April 25, 2016 Share Posted April 25, 2016 1 minute ago, Aquaterion said: this is what DarkXero told me to do to fix it: I told you that because you required a buffered action to properly use the attack state of the wilson stategraph. If you guys are using the attack state of a koalefant, and the ChaseAndAttack behaviour, use the doattack handler like: EventHandler("doattack", function(inst) if not inst.components.health:IsDead() then inst.sg:GoToState("attack") end end), Link to comment Share on other sites More sharing options...
Aquaterion Posted April 25, 2016 Share Posted April 25, 2016 Just now, DarkXero said: I told you that because you required a buffered action to properly use the attack state of the wilson stategraph. If you guys are using the attack state of a koalefant, and the ChaseAndAttack behaviour, use the doattack handler like: EventHandler("doattack", function(inst) if not inst.components.health:IsDead() then inst.sg:GoToState("attack") end end), yea when I was copying it I was like im sure he said something about mine being specific, but I forgot, mostly why I mentioned you Link to comment Share on other sites More sharing options...
Fancy_Fox_Pers Posted April 25, 2016 Author Share Posted April 25, 2016 (edited) Give me a second 11 minutes ago, DarkXero said: I told you that because you required a buffered action to properly use the attack state of the wilson stategraph. If you guys are using the attack state of a koalefant, and the ChaseAndAttack behaviour, use the doattack handler like: EventHandler("doattack", function(inst) if not inst.components.health:IsDead() then inst.sg:GoToState("attack") end end), Ok, great, thanks that works. Although the creature becomes invisible now, but that's probably a problem on animation which I'll fix tomorrow for sure. Thank you very much for helping Edit: @DarkXero It's actually really confusing me why that happens. The attack state seems fine regarding animation. Is it because of the pre attack thing? (My attack animation in spriter is called "attack_down") 18 minutes ago, Aquaterion said: I had this problem too, this is what DarkXero told me to do to fix it: --wurm.lua local function doattack(inst, data) --inst.sg:GoToState("attack", data.target) if inst.components.health and not inst.components.health:IsDead() and (not inst.sg:HasStateTag("busy") or inst.sg:HasStateTag("hit")) then local buffered_attack = BufferedAction(inst, data.target, ACTIONS.ATTACK) inst:PushBufferedAction(buffered_attack) end end --main function inst:ListenForEvent("doattack", doattack) Thanks for trying to help, as always Edited April 25, 2016 by Thibooms Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now