Fancy_Fox_Pers Posted May 27, 2015 Share Posted May 27, 2015 (edited) Hello, I have this code that allows me to turn koalefants into followers, spawning a new "copy" of the koalefant so I can do specific stuff with it. I tried to make them chop trees like pigs do, when the leader chops trees as well. I've had a look at the piggy files, including brain and this is what I got. In the follower's prefab lua I put at the very top : local function SuggestTreeTarget(inst, data) if data and data.tree and inst:GetBufferedAction() ~= ACTIONS.CHOP then inst.tree_target = data.tree endend Then I have the function making the actual koalefant (listing its anime, health, locomoter, etc) and in it I have : inst:ListenForEvent("suggest_tree_target", SuggestTreeTarget) And I've got this in the brain (which I did specify in the script, saying "require brain...") for the chopping :local function KeepChoppingAction(inst) local keep_chop = inst.components.follower.leader and inst.components.follower.leader:GetDistanceSqToInst(inst) <= KEEP_CHOPPING_DIST*KEEP_CHOPPING_DIST local target = FindEntity(inst, SEE_TREE_DIST/3, function(item) return item.prefab == "deciduoustree" and item.monster and item.components.workable and item.components.workable.action == ACTIONS.CHOP end) if inst.tree_target ~= nil then target = inst.tree_target end return (keep_chop or target ~= nil)endlocal function StartChoppingCondition(inst) local start_chop = inst.components.follower.leader and inst.components.follower.leader.sg and inst.components.follower.leader.sg:HasStateTag("chopping") local target = FindEntity(inst, SEE_TREE_DIST/3, function(item) return item.prefab == "deciduoustree" and item.monster and item.components.workable and item.components.workable.action == ACTIONS.CHOP end) if inst.tree_target ~= nil then target = inst.tree_target end return (start_chop or target ~= nil)endlocal function FindTreeToChopAction(inst) local target = FindEntity(inst, SEE_TREE_DIST, function(item) return item.components.workable and item.components.workable.action == ACTIONS.CHOP end) if target then local decid_monst_target = FindEntity(inst, SEE_TREE_DIST/3, function(item) return item.prefab == "deciduoustree" and item.monster and item.components.workable and item.components.workable.action == ACTIONS.CHOP end) if decid_monst_target ~= nil then target = decid_monst_target end if inst.tree_target then target = inst.tree_target inst.tree_target = nil end return BufferedAction(inst, target, ACTIONS.CHOP) endend And it's also listed in here like pigs do (I know there's a pig talker in there, I put it in just so I could test the thing out) :function FollowerBrain:OnStart()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),IfNode(function() return StartChoppingCondition(self.inst) end, "chop", WhileNode(function() return KeepChoppingAction(self.inst) end, "keep chopping", LoopNode{ ChattyNode(self.inst, STRINGS.PIG_TALK_HELP_CHOP_WOOD, DoAction(self.inst, FindTreeToChopAction ))})),}, 1) self.bt = BT(self.inst, root)end So, to sum up, the follower itself is working and everything BUT the chopping isn't. I guess that it's lacking some information like the anim. If that's the case by the way, I just want them to use their attack animation. Does anyone know what to do to make this work? What's missing? Thank you for your time! Edit: I only have this in the require behaviours of the follower's brain, maybe something's missing here?require "behaviours/follow"require "behaviours/wander" Edited May 27, 2015 by Thibooms Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/ Share on other sites More sharing options...
Kzisor Posted May 27, 2015 Share Posted May 27, 2015 @Thibooms, the brain isn't the only thing you have to edit, you also have to edit the stategraph. Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-641196 Share on other sites More sharing options...
Fancy_Fox_Pers Posted May 27, 2015 Author Share Posted May 27, 2015 (edited) @Kzisor, I now added a new stategraph for the koalefantfollower. I did this by copying everything frm the original SGkoalefant and assigned the koalefantfollower prefab to it. I added this to it, which I found in the pig's stategraph : State{ name = "chop", tags = {"chopping"}, onenter = function(inst) inst.Physics:Stop() inst.AnimState:PlayAnimation("atk") end, timeline= { TimeEvent(13*FRAMES, function(inst) inst:PerformBufferedAction() end ), }, events= { EventHandler("animover", function(inst) inst.sg:GoToState("idle") end), }, }, It didn't work so I figured changing it to this, comparing the attack state : State{ name = "chop", tags = {"chopping"}, onenter = function(inst) inst.Physics:Stop() inst.AnimState:PlayAnimation("atk") end, timeline= { TimeEvent(15*FRAMES, function(inst) inst.components.combat:DoAttack() end), }, events= { EventHandler("animover", function(inst) inst.sg:GoToState("idle") end), }, }, FYI, this is the attack state of a koalefant : 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("atk_pre") inst.AnimState:PushAnimation("atk", false) end, timeline= { TimeEvent(15*FRAMES, function(inst) inst.components.combat:DoAttack() end), }, events= { EventHandler("animqueueover", function(inst) inst.sg:GoToState("idle") end), }, }, Later I realized I also needed this : local actionhandlers = { ActionHandler(ACTIONS.CHOP, "chop"),}local events={ CommonHandlers.OnStep(), CommonHandlers.OnLocomote(true,true), CommonHandlers.OnSleep(), CommonHandlers.OnFreeze(), EventHandler("doattack", function(inst) if not inst.components.health:IsDead() then inst.sg:GoToState("attack") end end), EventHandler("death", function(inst) inst.sg:GoToState("death") end), EventHandler("attacked", function(inst) if inst.components.health:GetPercent() > 0 and not inst.sg:HasStateTag("attack") then inst.sg:GoToState("hit") end end),EventHandler("doaction", function(inst, data) if not inst.components.health:IsDead() and not inst.sg:HasStateTag("busy") then if data.action == ACTIONS.CHOP then inst.sg:GoToState("chop", data.target) end end enDidn't work eitherd),} I really don't know what to do anymore Edited May 27, 2015 by Thibooms Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-641217 Share on other sites More sharing options...
Seiai Posted May 27, 2015 Share Posted May 27, 2015 (edited) @Thibooms, put in print("describe the position in the code for yourself here") at different points to find out, what point of the code it reaches. It obviously starts in the brain, should buffer the action, then, once u reach the target, it should trigger the actionhandler, which should initiate the state. if u find the point which it doesnt cross, u can ofc also print the variable, to find out why, if u cant figure it out by just reading the code. Edited May 27, 2015 by Seiai Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-641284 Share on other sites More sharing options...
Fancy_Fox_Pers Posted May 30, 2015 Author Share Posted May 30, 2015 Hi, @Seiai, Sorry for not replying, didn't get a lot of time on my hands. Do you just add print("functionname") or something? I don't really get how this works, never used it. And do you add it next to or below the code? Thanks for the suggestion Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-642204 Share on other sites More sharing options...
Isosurface Posted May 30, 2015 Share Posted May 30, 2015 Do you have AddStategraphActionHandler, something like: AddStategraphActionHandler("koalefant", ActionHandler(ACTIONS.CHOP, "chop")) Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-642220 Share on other sites More sharing options...
Seiai Posted May 30, 2015 Share Posted May 30, 2015 @Thibooms,yeah, u just add something like print("here the action get buffered") and then u can see that string in the Debugoverlay(Ctrl+L in game) and in the logfile.its just a regular functioncall, so u can place it pretty freely.to give u an example from an Eventhandler above:EventHandler("doaction", function(inst, data) if not inst.components.health:IsDead() and not inst.sg:HasStateTag("busy") then if data.action == ACTIONS.CHOP then inst.sg:GoToState("chop", data.target) end end ento check how far u get:EventHandler("doaction", function(inst, data) print("ok, it triggers the handler") if not inst.components.health:IsDead() and not inst.sg:HasStateTag("busy") then print("i got into the first if") print(data.action) if data.action == ACTIONS.CHOP then print("and it goes to the state chop!") inst.sg:GoToState("chop", data.target) end end en Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-642232 Share on other sites More sharing options...
Fancy_Fox_Pers Posted May 30, 2015 Author Share Posted May 30, 2015 (edited) @Isosurface, Yes, I do. At the very top, after require("stategraphs/commonstates").local actionhandlers = { ActionHandler(ACTIONS.CHOP, "chop"),}@Seiai, Tried it and tried comparing pigs and mods to see what I'm missing but it won't show up. I didn't see any string I set up. I don't know what's wrong, honestly. Would you like me to upload any files? Edited May 30, 2015 by Thibooms Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-642258 Share on other sites More sharing options...
Seiai Posted May 30, 2015 Share Posted May 30, 2015 @Thibooms, well, if u cant find your printed string in the logfile, then the game never reached that point. if u post the code, and tell me what u did to try to reach it, we can have a look. Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-642279 Share on other sites More sharing options...
Fancy_Fox_Pers Posted May 30, 2015 Author Share Posted May 30, 2015 (edited) @Seiai, Ok. Here's the code, starting with the stategraph (I'm going to try to skip as much unrelevant code as I can) : require("stategraphs/commonstates")local actionhandlers = { ActionHandler(ACTIONS.CHOP, "chop"),}local events={ CommonHandlers.OnStep(), CommonHandlers.OnLocomote(true,true), CommonHandlers.OnSleep(), CommonHandlers.OnFreeze(), EventHandler("doattack", function(inst) if not inst.components.health:IsDead() then inst.sg:GoToState("attack") end end), EventHandler("death", function(inst) inst.sg:GoToState("death") end), EventHandler("attacked", function(inst) if inst.components.health:GetPercent() > 0 and not inst.sg:HasStateTag("attack") then inst.sg:GoToState("hit") end end),EventHandler("doaction", function(inst, data)print("it triggers the handler") if not inst.components.health:IsDead() and not inst.sg:HasStateTag("busy") then print("i got into the first if") if data.action == ACTIONS.CHOP then print("and it goes to the state chop") inst.sg:GoToState("chop", data.target) end end end),} 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("atk_pre") inst.AnimState:PushAnimation("atk", false) end, timeline= { TimeEvent(15*FRAMES, function(inst) inst.components.combat:DoAttack() end), }, events= { EventHandler("animqueueover", function(inst) inst.sg:GoToState("idle") end), }, }, State{ name = "chop", tags = {"chopping"}, onenter = function(inst) inst.Physics:Stop() inst.AnimState:PlayAnimation("atk") end, timeline= { TimeEvent(15*FRAMES, function(inst) inst:PerformBufferedAction() end ), }, events= { EventHandler("animover", function(inst) inst.sg:GoToState("idle") end), }, },return StateGraph("koalefantfollower", states, events, "idle", actionhandlers)So I added some prints as you can see. To test it, I had a koalefant follower with me and tried chopping a tree. No effect. I have this in the koalefantfollower's lua to make it use the brain and the stategraph : local brain = require "brains/koalefantfollowerbrain"inst:SetBrain(brain)inst:SetStateGraph("SGkoalefantfollower")And also this so it enables the tree targeting :inst:ListenForEvent("suggest_tree_target", SuggestTreeTarget) And I use the following in the brain for chopping : require "behaviours/doaction"local function KeepChoppingAction(inst) local keep_chop = inst.components.follower.leader and inst.components.follower.leader:GetDistanceSqToInst(inst) <= KEEP_CHOPPING_DIST*KEEP_CHOPPING_DIST local target = FindEntity(inst, SEE_TREE_DIST/3, function(item) return item.prefab == "deciduoustree" and item.monster and item.components.workable and item.components.workable.action == ACTIONS.CHOP end) if inst.tree_target ~= nil then target = inst.tree_target end return (keep_chop or target ~= nil)endlocal function StartChoppingCondition(inst) local start_chop = inst.components.follower.leader and inst.components.follower.leader.sg and inst.components.follower.leader.sg:HasStateTag("chopping") local target = FindEntity(inst, SEE_TREE_DIST/3, function(item) return item.prefab == "deciduoustree" and item.monster and item.components.workable and item.components.workable.action == ACTIONS.CHOP end) if inst.tree_target ~= nil then target = inst.tree_target end return (start_chop or target ~= nil)endlocal function FindTreeToChopAction(inst) local target = FindEntity(inst, SEE_TREE_DIST, function(item) return item.components.workable and item.components.workable.action == ACTIONS.CHOP end) if target then local decid_monst_target = FindEntity(inst, SEE_TREE_DIST/3, function(item) return item.prefab == "deciduoustree" and item.monster and item.components.workable and item.components.workable.action == ACTIONS.CHOP end) if decid_monst_target ~= nil then target = decid_monst_target end if inst.tree_target then target = inst.tree_target inst.tree_target = nil end return BufferedAction(inst, target, ACTIONS.CHOP) endendI have this in the FollowerBrain:OnStart() function : IfNode(function() return StartChoppingCondition(self.inst) end, "chop", WhileNode(function() return KeepChoppingAction(self.inst) end, "keep chopping", LoopNode{ DoAction(self.inst, FindTreeToChopAction )})), Edited May 30, 2015 by Thibooms Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-642288 Share on other sites More sharing options...
Seiai Posted May 30, 2015 Share Posted May 30, 2015 (edited) So I added some prints as you can see. To test it, I had a koalefant follower with me and tried chopping a tree. No effect.no effect as in no prints, or no prints AND no chopping? if he doesnt even chop, then his brain doesnt tell him too, u should add print in relevant functions in the brain to check whats goin on. btw, where did u take the relevant code for the brain and the stategraph from? Edited May 30, 2015 by Seiai Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-642328 Share on other sites More sharing options...
DarkXero Posted May 30, 2015 Share Posted May 30, 2015 The wander behaviour has to be the last behaviour in any brain.Or else, contained in an IfNode.Because every time you get to a wander behaviour, you run it, so everything down that is inaccessible. Put the chopping behaviour between Follow and Wander. Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-642330 Share on other sites More sharing options...
Seiai Posted May 30, 2015 Share Posted May 30, 2015 (edited) The wander behaviour has to be the last behaviour in any brain.ah yeah, thats the main problem. if u put prints in your brain like that, u would still get nothing cause he never even tries to chop, cause hes busy wandering^^ also, @DarkXero, yourcodeglommer is cut off on the top Edited May 30, 2015 by Seiai Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-642331 Share on other sites More sharing options...
DarkXero Posted May 30, 2015 Share Posted May 30, 2015 yourcodeglommer is cut off on the top It was either resizing and changing the font to something unreadable or cutting 40 pixels. Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-642338 Share on other sites More sharing options...
Fancy_Fox_Pers Posted May 30, 2015 Author Share Posted May 30, 2015 no effect as in no prints, or no prints AND no chopping? No prints AND no chopping btw, where did u take the relevant code for the brain and the stategraph from? From the pig files. I later also compared with the DS mod "Helpful Spiders" (to see if something was missing because it obviously wasn't working) that basically does what I want to do to koalefants to spiders. @DarkXero, Thanks, Dark! Can't believe it was something so stupid! Link to comment https://forums.kleientertainment.com/forums/topic/54473-help-trying-to-let-a-koalefant-chop-trees/#findComment-642394 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