Cigg Posted March 5 Share Posted March 5 (edited) Hello! I'm trying to change frog behavior so that they will: a) Be passive towards prefabs with the "froggyfren" tag b) Follow the player if they have aforementioned tag as well as fed them popcorn (more trade than fed, since they don't have an eat anim) c) Defend the player when attacked, or when leader/player is attacking an entity So I've this bit of code in my modmain: local BrainCommon = require("brains/braincommon") local Follow = require("behaviours/follow") AddPrefabPostInit("frog", function(inst) local SEE_PLAYER_DIST = 5 -- set to default if not inst.components.follower then inst:AddComponent("follower") end if not inst.components.trader then inst:AddComponent("trader") inst.components.trader:SetAcceptTest(function(inst, item) return item.prefab == "corn_cooked" end) inst.components.trader.onaccept = function(inst, giver, item) if giver:HasTag("froggyfren") then inst.components.follower:SetLeader(giver) inst.components.follower:AddLoyaltyTime(TUNING.TOTAL_DAY_TIME) giver:PushEvent("makefriend") inst.components.follower:StartLeashing() end end inst.components.trader.onrefuse = function(inst, item) if inst.components.sleeper and inst.components.sleeper:IsAsleep() then inst.components.sleeper:WakeUp() end end end local function ModifyFrogBrain(inst) if inst.brain then function inst.brain:OnStart() local root = PriorityNode({ IfNode(function() return inst.components.follower and inst.components.follower.leader ~= nil end, "HasLeader", PriorityNode({ Follow(inst, function() return inst.components.follower.leader end, 2, 5, 10), -- Maybe adjust distance buffer, cause of unleashing? WhileNode(function() return inst.components.combat.target ~= nil or (inst.components.follower.leader and inst.components.follower.leader.components.combat and inst.components.follower.leader.components.combat.target) end, "DefendLeader", ChaseAndAttack(inst, SpringCombatMod(MAX_CHASE_TIME), SpringCombatMod(MAX_CHASE_DIST))), }, 0.5)), }, .25) self.bt = BT(inst, root) end inst.brain:OnStart() -- Reinitialize the brain with the new logic end end ModifyFrogBrain(inst) inst:ListenForEvent("entitywake", function(inst) if inst.components.follower.leader and not inst:IsNear(inst.components.follower.leader, 3) then inst.components.follower:SetLeader(nil) inst.components.follower:StopLeashing() end end) inst:ListenForEvent("loseloyalty", function(inst) if inst.components.follower then inst.components.follower:StopLeashing() end end) local RETARGET_MUST_TAGS = { "_combat", "_health" } local RETARGET_CANT_TAGS = { "merm", "froggyfren" } local LUNAR_RETARGET_CANT_TAGS = { "merm", "lunar_aligned", "froggyfren" } inst.components.combat:SetRetargetFunction(3, function(inst) if not inst.components.health:IsDead() and inst.components.follower and inst.components.follower.leader then local leader = inst.components.follower.leader local target_dist = SEE_PLAYER_DIST local leader_target = leader.components.combat and leader.components.combat.target or nil if leader_target then return leader_target else return FindEntity(inst, target_dist, function(guy) return guy.components.inventory ~= nil and not guy:HasTag("froggyfren") end, RETARGET_MUST_TAGS, RETARGET_CANT_TAGS) end end end) end) Which should make it so that frogs leash and follow the player when fed popcorn. Everything works except for overwriting the frog nodes. Am I doing something wrong in terms of priority, can they just not do this behavior, or do I just have to make another frogbrain.lua and rewrite that, OR do I just turn the frogs into something else when fed popcorn (a longer implementation, but at this point I can't figure out how to make default frogs just.. follow me.) Any expert help would be appreciated, thank you! Edited March 5 by sournvitriol2 Link to comment Share on other sites More sharing options...
_zwb Posted March 6 Share Posted March 6 use a AddBrainPostInit to modify mob brains, or import the brain using require and override its methods. Just use the require method actually, it's much faster. 1 Link to comment Share on other sites More sharing options...
Cigg Posted March 6 Author Share Posted March 6 (edited) Did the require method, but game isn't loading the brain properly. Code as follows: Modmain: local ModdedFrogBrain = require("brains/moddedfrogbrain") AddPrefabPostInit("frog", function(inst) local SEE_PLAYER_DIST = 10 inst:SetBrain(ModdedFrogBrain) if inst.brain then print("Brain has been set to the frog: ", inst.brain.name) else print("Failed to set brain to the frog") end -- Ensure the trader component is set up properly if not inst.components.trader then inst:AddComponent("trader") inst.components.trader:SetAcceptTest(function(inst, item) return item.prefab == "corn_cooked" -- Only accept cooked corn end) local playedfriendsfx = false inst.components.trader.onaccept = function(inst, giver, item) if not inst.components.follower then inst:AddComponent("follower") end if giver:HasTag("froggyfren") then print("Frog is now following the player.") giver.components.leader:AddFollower(inst) inst.components.follower:AddLoyaltyTime(480) if not playedfriendsfx then giver:PushEvent("makefriend") playedfriendsfx = true -- Trigger UI/sound effects for making a friend end end end inst.components.trader.onrefuse = function(inst, item) if inst.components.sleeper and inst.components.sleeper:IsAsleep() then inst.components.sleeper:WakeUp() end end end local function DefendLeader(inst) local leader = inst.components.follower and inst.components.follower.leader if leader and leader.components.combat and leader.components.combat.target then return leader.components.combat.target end return nil end inst:ListenForEvent("entitywake", function(inst) if inst.components.follower and inst.components.follower.leader and not inst:IsNear(inst.components.follower.leader, 3) then inst.components.follower:SetLeader(nil) inst.components.follower:StopLeashing() end end) inst:ListenForEvent("loseloyalty", function(inst) if inst.components.follower then inst.components.follower:StopLeashing() end end) local RETARGET_MUST_TAGS = { "_combat", "_health" } local RETARGET_CANT_TAGS = { "merm", "froggyfren" } local LUNAR_RETARGET_CANT_TAGS = { "merm", "lunar_aligned", "froggyfren" } inst.components.combat:SetRetargetFunction(3, function(inst) if not inst.components.health:IsDead() and inst.components.follower and inst.components.follower.leader then local leader = inst.components.follower.leader local target_dist = 30 local leader_target = leader.components.combat and leader.components.combat.target if leader_target then return leader_target else return FindEntity(inst, target_dist, function(guy) return guy.components.inventory ~= nil and not guy:HasTag("froggyfren") end, RETARGET_MUST_TAGS, RETARGET_CANT_TAGS) end end end) end) Print return is failstate for brain loading. Could also be an issue with brain logic, so here's moddedfrogbrain.lua: require "behaviours/wander" require "behaviours/doaction" require "behaviours/chaseandattack" require "behaviours/standstill" require "behaviours/follow" local BrainCommon = require("brains/braincommon") local STOP_RUN_DIST = 10 local SEE_PLAYER_DIST = 5 local MAX_WANDER_DIST = 20 local SEE_TARGET_DIST = 6 local MAX_CHASE_DIST = 7 local MAX_CHASE_TIME = 8 local MIN_FOLLOW_DIST = 1 local TARGET_FOLLOW_DIST = 2 local MAX_FOLLOW_DIST = 3 local function GoHomeAction(inst) if inst.components.homeseeker and inst.components.homeseeker.home and inst.components.homeseeker.home:IsValid() then return BufferedAction(inst, inst.components.homeseeker.home, ACTIONS.GOHOME) end end local function ShouldGoHome(inst) return (not inst.islunar) and (not inst.components.follower or not inst.components.follower.leader) and (not TheWorld.state.isday or TheWorld.state.iswinter) end local function ShouldFollowLeader(inst) return inst.components.follower and inst.components.follower.leader ~= nil end local function GetLeader(inst) return inst.components.follower and inst.components.follower.leader end local ModdedFrogBrain = Class(Brain, function(self, inst) Brain._ctor(self, inst) end) function ModdedFrogBrain:OnStart() local root = PriorityNode( { BrainCommon.PanicTrigger(self.inst), ChaseAndAttack(self.inst, MAX_CHASE_TIME), IfNode(function() return ShouldFollowLeader(self.inst) end, "HasLeader", PriorityNode({ Follow(self.inst, function() return GetLeader(self.inst) end, MIN_FOLLOW_DIST, TARGET_FOLLOW_DIST, MAX_FOLLOW_DIST), WhileNode(function() return self.inst.components.combat.target ~= nil or (GetLeader(self.inst) and GetLeader(self.inst).components.combat and GetLeader(self.inst).components.combat.target) end, "DefendLeader", ChaseAndAttack(self.inst, MAX_CHASE_TIME)), }, 0.5)), WhileNode(function() return ShouldGoHome(self.inst) end, "ShouldGoHome", DoAction(self.inst, function() return GoHomeAction(self.inst) end, "go home", true )), WhileNode(function() return not ShouldFollowLeader(self.inst) and not self.inst.islunar end, "DefaultWander", Wander(self.inst, function() return self.inst.components.knownlocations:GetLocation("home") end, MAX_WANDER_DIST)), StandStill(self.inst, function() return self.inst.sg:HasStateTag("idle") end), }, .25) self.bt = BT(self.inst, root) end return ModdedFrogBrain Not sure what's the hiccup here. I also tried to set the brain via console, I don't think it was working either. Any help is appreciated. EDIT: Nevermind. Just made a new frog prefab spawn, and added a function to set a leader via tag when it spawns. But yes, I still haven't made default frogs turn friendly. Could be because of the hostile tag found in frog.lua, the brain logic as it is currently or something along those lines. Edited March 6 by Cigg 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