Mikeloeven Posted January 23, 2016 Share Posted January 23, 2016 Does anyone know of a simple mod that adds basic controls for ALL followers I need toggles to make them wait at a specific location (assume some wandering within a radius) as well as a toggle between Agressive(attack monster on sight) Defensive(Only attack monsters in self defense or that are targeting player) and Passive (RUN AWAY RUN AWAY !!) Link to comment https://forums.kleientertainment.com/forums/topic/63151-simple-ai-toggle-for-all-followers-waitfollow-agressivepassive/ Share on other sites More sharing options...
Rincevvind Posted January 24, 2016 Share Posted January 24, 2016 (edited) don't think it's possible without changing follower's brains. Edited January 24, 2016 by Rincevvind Link to comment https://forums.kleientertainment.com/forums/topic/63151-simple-ai-toggle-for-all-followers-waitfollow-agressivepassive/#findComment-713262 Share on other sites More sharing options...
Mikeloeven Posted January 25, 2016 Author Share Posted January 25, 2016 (edited) If brain is an interface type you could try a procedure that encapsulates the existing brain of any follower and extends it with the required functions and overrides it with the new object My programming skills are mostly Data Access and Business Logic i am not very familiar with game programming so this might not even be something you can do in LUA Edited January 25, 2016 by Mikeloeven Link to comment https://forums.kleientertainment.com/forums/topic/63151-simple-ai-toggle-for-all-followers-waitfollow-agressivepassive/#findComment-713527 Share on other sites More sharing options...
Rincevvind Posted January 25, 2016 Share Posted January 25, 2016 (edited) local root = PriorityNode({ IfNode(function() return IsCode(0) end, "IgnoreMode", PriorityNode{ Follow(self.inst, GetLeader, MIN_FOLLOW_IGNORE, MED_FOLLOW_IGNORE, MAX_FOLLOW_IGNORE, true), RunAway(self.inst, ShouldRunAway, RUN_START_DIST, RUN_STOP_DIST_IGNORE), -- Wander(self.inst, GetPlayerPos, MAX_WANDER_DIST) },0.5), IfNode(function() return IsCode(2) end, "AttackMode", PriorityNode{ RunAway(self.inst, SmartRunAway, SMART_RUN_START_DIST, SMART_RUN_STOP_DIST), ChaseAndAttack(self.inst, MAX_CHASE_TIME*2), Follow(self.inst, GetLeader, MIN_FOLLOW, MED_FOLLOW, MAX_FOLLOW, true), Wander(self.inst, GetPlayerPos, MAX_WANDER_DIST) },0.5), IfNode(function() return IsCode(1) end, "DefMode", PriorityNode{ Follow(self.inst, GetLeader, MIN_FOLLOW, MED_FOLLOW, MAX_FOLLOW, true), RunAway(self.inst, SmartRunAway, SMART_RUN_START_DIST, SMART_RUN_STOP_DIST), ChaseAndAttack(self.inst, MAX_CHASE_TIME), Wander(self.inst, GetPlayerPos, MAX_WANDER_DIST) },0.5) }, .5) self.bt = BT(self.inst, root) thats part of brain code to control abigail behavior brain isn't simple procedure, it's a "class", like IfNode and all this standart behaviors. It's too complex to "just inheright it" so you have to inject your control for each potential follower and overriding their brains one by one. Some of them is simple, some is complex like pigman have. Edited January 25, 2016 by Rincevvind Link to comment https://forums.kleientertainment.com/forums/topic/63151-simple-ai-toggle-for-all-followers-waitfollow-agressivepassive/#findComment-713805 Share on other sites More sharing options...
Mikeloeven Posted January 27, 2016 Author Share Posted January 27, 2016 what about using factory pattern to derive a modified brain from the existing brain ? Link to comment https://forums.kleientertainment.com/forums/topic/63151-simple-ai-toggle-for-all-followers-waitfollow-agressivepassive/#findComment-714348 Share on other sites More sharing options...
Blueberrys Posted January 27, 2016 Share Posted January 27, 2016 (edited) To modify brains (found here): Spoiler ----------------------------------- -- Brain mod example -- -- AddBrainPostInit("brainname", initfn) -- Lets you modify a brain after it's been initialized. The most useful -- part is probably adding or removing nodes from brain.bt, which is the -- brain's behaviour tree. -- -- Note that "brainname" is the name of the lua file in scripts/brains/. ----------------------------------- -- Since the final brain a creature gets doesn't quite look like the brain -- specified in code, use this utility to print a brain to the console and -- to log.txt. local function DumpBT(bnode, indent) local s = "" for i=1,indent do s = s.."| " end s = s..bnode.name print(s) if bnode.children then for i,childnode in ipairs(bnode.children) do DumpBT(childnode, indent+1) end end end -- This example shows both removing and adding nodes to the Behaviour Tree, through -- finding an existing node, removing it, and re-inserting it at a different location. local function MakePigsHateTrees(brain) -- Uncomment this section to see the brain printed to the console/log.txt, so -- that you can see what the behaviours are called and how they are structured. -- We'll use a little bit of searching and a little bit of direct indexing to -- find the nodes we want so referencing the "final" output is very useful. --print("\n\n\t\t\t\tDumping a pigbrain") --DumpBT(brain.bt.root, 0) --print("\n\n") -- We want pigs to chop trees more than anything, except when they are on fire. -- First we find their chopping action and remove it from the tree. Then we'll -- modify it, and re-insert it at the top of the tree, right after their -- "OnFire" behaviour. So they will prefer chopping to attacking enemies and -- everything else, except they'll still stop while on fire. -- First find the priority node guarded by the IsDay condition. This is inside -- a Parallel node inside the root Parallel node. local daygroup = nil --print("looking for isday") for i,node in ipairs(brain.bt.root.children) do --print("\t"..node.name.." > "..(node.children and node.children[1].name or "")) if node.name == "Parallel" and node.children[1].name == "IsDay" then daygroup = node.children[2] break end end if not daygroup then print("Couldn't find the 'IsDay' behaviour in this brain!") return end -- Then search in the daygroup for the Sequence which contains all the chopping -- behaviours. local chopsequence = nil local chopsequenceindex = nil --print("looking for chop") for i,node in ipairs(daygroup.children) do --print("\t"..node.name.." > "..(node.children and node.children[1].name or "")) if node.name == "Sequence" and node.children[1].name == "chop" then chopsequence = node chopsequenceindex = i break end end if not chopsequence then print("Couldn't find the chopping behaviour in this brain!") return end -- We have the chop sequence, so remove it from the old location table.remove(daygroup.children, chopsequenceindex) -- Right now pigs only chop if their leader is chopping, lets change that local function StartChopppingCond(inst) return true -- always! ME HATES TREE end local function KeepChoppingCond(inst) return true -- always! TREE DIE NOW end chopsequence.children[1].fn = function() return StartChopppingCond(brain.inst) end -- this is the chop node chopsequence.children[2].children[1].fn = function() return KeepChoppingCond(brain.inst) end -- this is the keep chopping node -- Find the OnFire Parallel in the root local fireindex = nil for i,node in ipairs(brain.bt.root.children) do if node.name == "Parallel" and node.children[1].name == "OnFire" then fireindex = i break end end -- Finally, re-insert our chop behaviour after the OnFire. table.insert(brain.bt.root.children, fireindex+1, chopsequence) -- Print make sure our change took! --print("\n\n\t\t\t\tCHANGED BRAIN") --DumpBT(brain.bt.root, 0) end AddBrainPostInit("pigbrain", MakePigsHateTrees) You could probably recursively go through the brains you want to change and save references when you find the correct node type, then loop through your list to modify them all at once. Note: The postinit functions only run once, they'll be useful in retrieving references or executing code when the entity is created, but you'll need something else (clickable button, key press, etc) for toggling. Edited January 27, 2016 by Blueberrys Link to comment https://forums.kleientertainment.com/forums/topic/63151-simple-ai-toggle-for-all-followers-waitfollow-agressivepassive/#findComment-714357 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