Jump to content

A question or two regarding creature behaviours.


Recommended Posts

Hello again, modding has been going fairly smoothly.

Though I have ran into something that I am having trouble finding info on.

 

I am trying to make it so that spiders, hounds, and bats are neutral to my character. (without editing their lua files.)

I tried using Webber's code line: "inst:AddTag("spiderwhisperer")"

however spiders still appear to attack me, and even if it did work,

I doubt I could slap hounds and bats infront of the word "whisperer" to make them neutral as well.

 

I also would like to make pigmen use the runaway behaviour when they see my character,

however I am not quite sure how to do that without editing the pigmen's code.

 

 

Any help would be much appreciated.  :wilson_smile:

Link to comment
Share on other sites

This is a moderately complicated task, and although I could probably spend some time banging out a solution, I haven't worked a whole lot with brains yet so I think it would be best just to point you in the right direction. 
 
The "spiderwhisper" tag, unless I am mistaken, is mostly used to do hostility checks for things like trying to sleep in tents.  "monster" is the tag that spiders and pigs check to decide whether or not they should attack.  Do a search for HasTag("monster") to see how this is implemented in various creatures.  Simply adding the monster tag wont quite work for you, though, because you don't want EVERYTHING to treat you like a monster(pigmen, for example, will attack you on sight).
 
RunAway is a type of BehaviourNode used in a creature's brain.
 
runaway.lua:

RunAway = Class(BehaviourNode, function(self, inst, hunterparams, see_dist, safe_dist, fn, runhome)BehaviourNode._ctor(self, "RunAway")self.safe_dist = safe_distself.see_dist = see_distself.hunterparams = hunterparamsself.inst = instself.runshomewhenchased = runhomeself.shouldrunfn = fnend)

 
Pigs have both an "IsDay" PriorityNode and an "IsNight" PriorityNode (both are wrapped in a WhileNode that checks if it is day or night, respectively).  The RunAway nodes are child nodes of ChattyNodes in both the day and night nodes.
 
The BehaviourTree class actually has a built-in __tostring() function which allows you to peek into behavior trees in-game.  If you set an entity with a behaviortree as the debug entity( c_spawn, SetDebugEntity, etc), it will automatically display the tree on the right hand side of the screen when you press backspace.

 

 

I'm extremely tired at the moment so I apologize if this reads as a block of incoherent babble, but in any case, you'll have to figure out where in the BehaviourTree you want to prioritize your RunAway node, and use table.insert to inject it.  Note that this is not a particularly clean solution, and instead of inserting it into a static position every time, you should try to optimize this to have the least chance of breaking other mods that may mess with the tree.  You should programmatically locate a node that you want it to appear before/after, and insert it there.  I'm sure that's not the absolute best way to go about it, but at least you'll have something to go by for now.

 

Alternatively, if the current RunAway prioritization works for you, and you just want to extend the range at which they run away, you can modify the see_dist and safe_dist values of the RunAway node. In daytime you can test this in a console by doing something like:

m = c_spawn("pigman")m.brain.bt.root.children[6].children[2].children[6].children[1].see_dist = 15m.brain.bt.root.children[6].children[2].children[6].children[1].safe_dist = 15

Obviously this is just to see it working-- programmatically you would want to 'search' for that node by looking for a RunAway node with hunterparams == "player".

 

 

Link to comment
Share on other sites

I think the easiest way to do this would be to use the canbeattackedfn in your characters combat component. You might need to test for special cases (such as when you're attacking them yourself), but if you're looking for an easy way to prevent them from attacking you, this will do it pretty concisely without changing their internal workings.

-- where inst refers to the player instanceinst.components.combat.canbeattackedfn = function(inst, attacker)    if not (attacker.prefab == "spider"    -- or attacker.prefab == ...    ) then        -- Can also check if the player is targeting the creature here        -- if inst.components.combat:IsRecentTarget(attacker) then        return true    endend
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...