. . . Posted May 15, 2016 Share Posted May 15, 2016 Hello, it's me SuperDavid and I would like some help if possible please !!! So i'm trying to make a tamable hound and here's the code I have so far... require "behaviours/follow" require "behaviours/wander" require "behaviours/chaseandattack" require "behaviours/panic" require "behaviours/attackwall" require "behaviours/minperiod" require "behaviours/leash" require "behaviours/faceentity" require "behaviours/doaction" require "behaviours/standstill" local HoundBrain = Class(Brain, function(self, inst) Brain._ctor(self, inst) end) local SEE_DIST = 30 local MIN_FOLLOW_LEADER = 2 local MAX_FOLLOW_LEADER = 6 local TARGET_FOLLOW_LEADER = (MAX_FOLLOW_LEADER+MIN_FOLLOW_LEADER)/2 local LEASH_RETURN_DIST = 10 local LEASH_MAX_DIST = 40 local HOUSE_MAX_DIST = 40 local HOUSE_RETURN_DIST = 50 local SIT_BOY_DIST = 10 local TRADE_DIST = 20 local function GetTraderFn(inst) return FindEntity(inst, TRADE_DIST, function(target) return inst.components.trader:IsTryingToTradeWithMe(target) end, {"player"}) end local function KeepTraderFn(inst, target) return inst.components.trader:IsTryingToTradeWithMe(target) end local function EatFoodAction(inst) local target = FindEntity(inst, SEE_DIST, function(item) return inst.components.eater:CanEat(item) and item:IsOnValidGround() end) if target then return BufferedAction(inst, target, ACTIONS.EAT) end end local function GetLeader(inst) return inst.components.follower ~= nil and inst.components.follower.leader or nil end local function GetHome(inst) return inst.components.homeseeker ~= nil and inst.components.homeseeker.home or nil end local function GetHomePos(inst) local home = GetHome(inst) return home ~= nil and home:GetPosition() or nil end local function GetNoLeaderLeashPos(inst) return GetLeader(inst) == nil and GetHomePos(inst) or nil end local function GetWanderPoint(inst) local target = GetLeader(inst) or inst:GetNearestPlayer(true) return target ~= nil and target:GetPosition() or nil end local function ShouldStandStill(inst) return inst:HasTag("pet_hound") and not TheWorld.state.isday and not GetLeader(inst) and not inst.components.combat.target and inst:IsNear(GetHome(inst), SIT_BOY_DIST) end function HoundBrain:OnStart() local root = PriorityNode( { WhileNode(function() return self.inst.components.hauntable and self.inst.components.hauntable.panic end, "PanicHaunted", Panic(self.inst)), WhileNode(function() return self.inst.components.health.takingfiredamage end, "OnFire", Panic(self.inst) ), WhileNode(function() return not GetLeader(self.inst) end, "NoLeader", AttackWall(self.inst) ), WhileNode(function() return self.inst:HasTag("pet_hound") end, "Is Pet", ChaseAndAttack(self.inst, 10)), WhileNode(function() return not self.inst:HasTag("pet_hound") and GetHome(self.inst) end, "No Pet Has Home", ChaseAndAttack(self.inst, 10, 20)), WhileNode(function() return not self.inst:HasTag("pet_hound") and not GetHome(self.inst) end, "Not Pet", ChaseAndAttack(self.inst, 100)), Leash(self.inst, GetNoLeaderLeashPos, HOUSE_MAX_DIST, HOUSE_RETURN_DIST), DoAction(self.inst, EatFoodAction, "eat food", true ), Follow(self.inst, GetLeader, MIN_FOLLOW_LEADER, TARGET_FOLLOW_LEADER, MAX_FOLLOW_LEADER), FaceEntity(self.inst, GetLeader, GetLeader), StandStill(self.inst, ShouldStandStill), WhileNode(function() return GetHome(self.inst) end, "HasHome", Wander(self.inst, GetHomePos, 8) ), Wander(self.inst, GetWanderPoint, 20), }, .25) self.bt = BT(self.inst, root) end return HoundBrain That's the brain file. local assets = { Asset("ANIM", "anim/hound_basic.zip"), Asset("ANIM", "anim/hound.zip"), Asset("ANIM", "anim/hound_red.zip"), Asset("ANIM", "anim/hound_ice.zip"), Asset("SOUND", "sound/hound.fsb"), } local prefabs = { "houndstooth", "monstermeat", "redgem", "bluegem", } local brain = require "brains/houndbrainAdam" local function ShouldAcceptItem(inst, item, giver) return giver:HasTag("houndwhisperer") and inst.components.eater:CanEat(item) end function GetOtherHounds(inst) local x, y, z = inst.Transform:GetWorldPosition() return TheSim:FindEntities(x, y, z, 15, { "hound" }, { "FX", "NOCLICK", "DECOR", "INLIMBO" }) end local function OnGetItemFromPlayer(inst, giver, item) if inst.components.eater:CanEat(item) then local playedfriendsfx = false if inst.components.combat.target == giver then inst.components.combat:SetTarget(nil) elseif giver.components.leader ~= nil and inst.components.follower ~= nil then giver:PushEvent("makefriend") playedfriendsfx = true giver.components.leader:AddFollower(inst) inst.components.follower:AddLoyaltyTime(item.components.edible:GetHunger() * TUNING.SPIDER_LOYALTY_PER_HUNGER) local brain = require "brains/houndbrainAdamTamed" inst:RemoveTag("hostile") inst.components.locomotor.runspeed = 1.5 * TUNING.HOUND_SPEED inst.components.health.absorb = -1.25 inst.SoundEmitter:PlaySound("dontstarve/common/makeFriend") inst:AddTag("notraptrigger") inst.components.combat:SetDefaultDamage(1.25, TUNING.HOUND_DAMAGE) inst.components.health:DoDelta(TUNING.HEALING_LARGE) end if giver.components.leader ~= nil then local hounds = GetOtherHounds(inst) local maxHounds = 3 for i, v in ipairs(hounds) do if maxHounds <= 0 then break end if v.components.combat.target == giver then v.components.combat:SetTarget(nil) elseif giver.components.leader ~= nil and v.components.follower ~= nil and v.components.follower.leader == nil then if not playedfriendsfx then giver:PushEvent("makefriend") playedfriendsfx = true end giver.components.leader:AddFollower(v) v.components.follower:AddLoyaltyTime(item.components.edible:GetHunger() * TUNING.SPIDER_LOYALTY_PER_HUNGER) end maxHounds = maxHounds - 1 if v.components.sleeper:IsAsleep() then v.components.sleeper:WakeUp() end end end end end local function OnRefuseItem(inst, item) inst.sg:GoToState("taunt") if inst.components.sleeper:IsAsleep() then inst.components.sleeper:WakeUp() end end local function FindTarget(inst, radius) return FindEntity( inst, SpringCombatMod(radius), function(guy) return inst.components.combat:CanTarget(guy) and not (inst.components.follower ~= nil and inst.components.follower.leader == guy) end, { "_combat", "character" }, { "monster", "INLIMBO" } ) end local function CalcSanityAura(inst, observer) return observer:HasTag("houndwhisperer") and 0 or inst.components.sanityaura.aura end SetSharedLootTable( 'hound', { {'monstermeat', 1.000}, {'houndstooth', 0.125}, }) SetSharedLootTable( 'hound_fire', { {'monstermeat', 1.0}, {'houndstooth', 1.0}, {'houndfire', 1.0}, {'houndfire', 1.0}, {'houndfire', 1.0}, {'redgem', 0.2}, }) SetSharedLootTable( 'hound_cold', { {'monstermeat', 1.0}, {'houndstooth', 1.0}, {'houndstooth', 1.0}, {'bluegem', 0.2}, }) local WAKE_TO_FOLLOW_DISTANCE = 8 local SLEEP_NEAR_HOME_DISTANCE = 10 local SHARE_TARGET_DIST = 30 local HOME_TELEPORT_DIST = 30 local NO_TAGS = {"FX", "NOCLICK","DECOR","INLIMBO"} local function ShouldWakeUp(inst) return DefaultWakeTest(inst) or (inst.components.follower and inst.components.follower.leader and not inst.components.follower:IsNearLeader(WAKE_TO_FOLLOW_DISTANCE)) end local function ShouldSleep(inst) return inst:HasTag("pet_hound") and not TheWorld.state.isday and not (inst.components.combat and inst.components.combat.target) and not (inst.components.burnable and inst.components.burnable:IsBurning()) and (not inst.components.homeseeker or inst:IsNear(inst.components.homeseeker.home, SLEEP_NEAR_HOME_DISTANCE)) end local function OnNewTarget(inst, data) if inst.components.sleeper:IsAsleep() then inst.components.sleeper:WakeUp() end end local function retargetfn(inst) local dist = TUNING.HOUND_TARGET_DIST if inst:HasTag("pet_hound") then dist = TUNING.HOUND_FOLLOWER_TARGET_DIST end return FindEntity(inst, dist, function(guy) return inst.components.combat:CanTarget(guy) end, nil, {"wall","houndmound","hound","houndfriend","houndwhisperer"} ) end local function KeepTarget(inst, target) return inst.components.combat:CanTarget(target) and (not inst:HasTag("pet_hound") or inst:IsNear(target, TUNING.HOUND_FOLLOWER_TARGET_KEEP)) end local function OnAttacked(inst, data) inst.components.combat:SetTarget(data.attacker) inst.components.combat:ShareTarget(data.attacker, SHARE_TARGET_DIST, function(dude) return dude:HasTag("hound") or dude:HasTag("houndfriend") and not dude.components.health:IsDead() end, 5) end local function OnAttackOther(inst, data) inst.components.combat:ShareTarget(data.target, SHARE_TARGET_DIST, function(dude) return dude:HasTag("hound") or dude:HasTag("houndfriend") and not dude.components.health:IsDead() end, 5) end local function GetReturnPos(inst) local x, y, z = inst.Transform:GetWorldPosition() local rad = 2 local angle = math.random() * 2 * PI return x + rad * math.cos(angle), y, z - rad * math.sin(angle) end local function DoReturn(inst) --print("DoReturn", inst) if inst.components.homeseeker ~= nil and inst.components.homeseeker:HasHome() then if inst:HasTag("pet_hound") then if inst.components.homeseeker.home:IsAsleep() and not inst:IsNear(inst.components.homeseeker.home, HOME_TELEPORT_DIST) then inst.Physics:Teleport(GetReturnPos(inst.components.homeseeker.home)) end elseif inst.components.homeseeker.home.components.childspawner ~= nil then inst.components.homeseeker.home.components.childspawner:GoHome(inst) end end end local function OnEntitySleep(inst) --print("OnEntitySleep", inst) if not TheWorld.state.isday then DoReturn(inst) end end local function OnStopDay(inst) --print("OnStopDay", inst) if inst:IsAsleep() then DoReturn(inst) end end local function OnSpawnedFromHaunt(inst) if inst.components.hauntable ~= nil then inst.components.hauntable:Panic() end end local function OnSave(inst, data) data.ispet = inst:HasTag("pet_hound") or nil --print("OnSave", inst, data.ispet) end local function OnLoad(inst, data) --print("OnLoad", inst, data.ispet) if data ~= nil and data.ispet then inst:AddTag("pet_hound") if inst.sg ~= nil then inst.sg:GoToState("idle") end end end local function fncommon(build) local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddAnimState() inst.entity:AddPhysics() inst.entity:AddSoundEmitter() inst.entity:AddDynamicShadow() inst.entity:AddNetwork() MakeCharacterPhysics(inst, 10, .5) inst.DynamicShadow:SetSize(2.5, 1.5) inst.Transform:SetFourFaced() inst:AddTag("scarytoprey") inst:AddTag("monster") inst:AddTag("hostile") inst:AddTag("hound") inst.AnimState:SetBank("hound") inst.AnimState:SetBuild(build or "hound") inst.AnimState:PlayAnimation("idle") inst.entity:SetPristine() if not TheWorld.ismastersim then return inst end inst:AddComponent("locomotor") -- locomotor must be constructed before the stategraph inst.components.locomotor.runspeed = TUNING.HOUND_SPEED inst:SetStateGraph("SGhound") inst:SetBrain(brain) inst:AddComponent("follower") inst.components.follower.maxfollowtime = 10 * TUNING.TOTAL_DAY_TIME inst:AddComponent("eater") inst.components.eater:SetDiet({ FOODTYPE.MEAT }, { FOODTYPE.MEAT }) inst.components.eater:SetCanEatHorrible() inst.components.eater.strongstomach = true -- can eat monster meat! inst:AddComponent("health") inst.components.health:SetMaxHealth(TUNING.HOUND_HEALTH) inst:AddComponent("sanityaura") inst.components.sanityaura.aura = -TUNING.SANITYAURA_MED inst:AddComponent("combat") inst.components.combat:SetDefaultDamage(TUNING.HOUND_DAMAGE) inst.components.combat:SetAttackPeriod(TUNING.HOUND_ATTACK_PERIOD) inst.components.combat:SetRetargetFunction(3, retargetfn) inst.components.combat:SetKeepTargetFunction(KeepTarget) inst.components.combat:SetHurtSound("dontstarve/creatures/hound/hurt") inst:AddComponent("lootdropper") inst.components.lootdropper:SetChanceLootTable('hound') inst:AddComponent("inspectable") inst:AddComponent("trader") inst.components.trader:SetAcceptTest(ShouldAcceptItem) inst.components.trader.onaccept = OnGetItemFromPlayer inst.components.trader.onrefuse = OnRefuseItem inst:AddComponent("sleeper") inst.components.sleeper:SetResistance(3) inst.components.sleeper.testperiod = GetRandomWithVariance(6, 2) inst.components.sleeper:SetSleepTest(ShouldSleep) inst.components.sleeper:SetWakeTest(ShouldWakeUp) inst:ListenForEvent("newcombattarget", OnNewTarget) MakeHauntableChangePrefab(inst, { "firehound", "icehound" }) inst:ListenForEvent("spawnedfromhaunt", OnSpawnedFromHaunt) inst:WatchWorldState("stopday", OnStopDay) inst.OnEntitySleep = OnEntitySleep inst.OnSave = OnSave inst.OnLoad = OnLoad inst:ListenForEvent("attacked", OnAttacked) inst:ListenForEvent("onattackother", OnAttackOther) return inst end local function fndefault() local inst = fncommon() if not TheWorld.ismastersim then return inst end MakeMediumFreezableCharacter(inst, "hound_body") MakeMediumBurnableCharacter(inst, "hound_body") return inst end local function PlayFireExplosionSound(inst) inst.SoundEmitter:PlaySound("dontstarve/creatures/hound/firehound_explo", "explosion") end local function fnfire() local inst = fncommon("hound_red") if not TheWorld.ismastersim then return inst end MakeMediumFreezableCharacter(inst, "hound_body") inst.components.freezable:SetResistance(4) --because fire inst.components.combat:SetDefaultDamage(TUNING.FIREHOUND_DAMAGE) inst.components.combat:SetAttackPeriod(TUNING.FIREHOUND_ATTACK_PERIOD) inst.components.locomotor.runspeed = TUNING.FIREHOUND_SPEED inst.components.health:SetMaxHealth(TUNING.FIREHOUND_HEALTH) inst.components.lootdropper:SetChanceLootTable('hound_fire') inst:ListenForEvent("death", PlayFireExplosionSound) return inst end local function DoIceExplosion(inst) if not inst.components.freezable then MakeMediumFreezableCharacter(inst, "hound_body") end inst.components.freezable:SpawnShatterFX() inst:RemoveComponent("freezable") local x,y,z = inst.Transform:GetWorldPosition() local ents = TheSim:FindEntities(x, y, z, 4, {"freezable"}, NO_TAGS) for i,v in pairs(ents) do if v.components.freezable then v.components.freezable:AddColdness(2) end end inst.SoundEmitter:PlaySound("dontstarve/creatures/hound/icehound_explo", "explosion") end local function fncold() local inst = fncommon("hound_ice") if not TheWorld.ismastersim then return inst end MakeMediumBurnableCharacter(inst, "hound_body") inst.components.combat:SetDefaultDamage(TUNING.ICEHOUND_DAMAGE) inst.components.combat:SetAttackPeriod(TUNING.ICEHOUND_ATTACK_PERIOD) inst.components.locomotor.runspeed = TUNING.ICEHOUND_SPEED inst.components.health:SetMaxHealth(TUNING.ICEHOUND_HEALTH) inst.components.lootdropper:SetChanceLootTable('hound_cold') inst:ListenForEvent("death", DoIceExplosion) return inst end local function fnfiredrop() local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddNetwork() MakeInventoryPhysics(inst) inst.entity:SetPristine() if not TheWorld.ismastersim then return inst end MakeLargeBurnable(inst, 6 + math.random() * 6) MakeLargePropagator(inst) --Remove the default handlers that toggle persists flag inst.components.burnable:SetOnIgniteFn(nil) inst.components.burnable:SetOnExtinguishFn(inst.Remove) inst.components.burnable:Ignite() return inst end return Prefab("hound", fndefault, assets, prefabs), Prefab("firehound", fnfire, assets, prefabs), Prefab("icehound", fncold, assets, prefabs), Prefab("houndfire", fnfiredrop, assets, prefabs) And here's the prefab file. My problem's that no matter what I do I can't get the hound to stop attack everything that isn't an hound on sight like how Spiders are when you tame them... Does anyone know what parts of the Hound have to get removed or changed then it stops attacking everything automatically?! Any help would be so very appreciated because I tried everything like removing "hostility" component and messed with the brain file but I can't figure how to get them to not be super hostile ... Again I would be super happy if anyone can help !!! And thanks so very much for reading through this very long post !!!!!!! Link to comment Share on other sites More sharing options...
CarlZalph Posted May 15, 2016 Share Posted May 15, 2016 In your "inst.components.follower:AddLoyaltyTime" you are declaring a local brain but not assigning it with "SetBrain(brain)". So the hound's AI logic doesn't change when tamed. Also I'd move the tamed brain variable next to the other brain and call each something different. Don't forget to revert the brain back when the pet loses a master. Link to comment Share on other sites More sharing options...
. . . Posted May 15, 2016 Author Share Posted May 15, 2016 9 hours ago, CarlZalph said: 9 hours ago, CarlZalph said: How do I assign the local brain then the AI logic changes when tamed?! Can you please help me because I don't know what to do... I did this but the game just crashes local brain = require "SetBrain(houndbrainAdamTamed)" I don't know how to code at all... If nobody can help then i'll just change the hound's brain to a spider, that will probably make it stop attacking everything on sight . Link to comment Share on other sites More sharing options...
DrSmugleaf Posted May 15, 2016 Share Posted May 15, 2016 2 minutes ago, SuperDavid said: How do I assign the local brain then the AI logic changes when tamed?! Can you please help me because I don't know what to do... I did this but the game just crashes local brain = require "SetBrain(houndbrainAdamTamed)" I don't know how to code at all... If nobody can help then i'll just change the hound's brain to a spider, that will probably make it stop attacking everything on sight . local brain = require "brains/spiderbrain" inst:SetBrain(brain) Link to comment Share on other sites More sharing options...
. . . Posted May 15, 2016 Author Share Posted May 15, 2016 local brain = require "brains/spiderbrain" inst:SetBrain(brain) I put that code into the hound prefab and made a copy of spiderbrain and put it into the brains folder in my mod but it just crashed ... I think I'll just keep the hounds the way they are and let them attack everything on sight, thanks for the help everyone I really appreciate it ! Link to comment Share on other sites More sharing options...
Aquaterion Posted May 15, 2016 Share Posted May 15, 2016 1 hour ago, SuperDavid said: local brain = require "brains/spiderbrain" inst:SetBrain(brain) I put that code into the hound prefab and made a copy of spiderbrain and put it into the brains folder in my mod but it just crashed ... I think I'll just keep the hounds the way they are and let them attack everything on sight, thanks for the help everyone I really appreciate it ! Did you try using the brain u made instead of the spiderbrain, using this new way of inserting the brain? Link to comment Share on other sites More sharing options...
. . . Posted May 15, 2016 Author Share Posted May 15, 2016 Yes I did and it crashed with both of them, I copy pasted the spider brain code into my hound and it crashed, I used the spiderbrain file and it also crashed. I think there's some code in my brain file which makes hounds attack everything on sight (like normal hounds) but I don't know which part it is to remove ... My brain file's up there if you wanna take a look but you don't have to because this isn't very bad for my mod, as long as the hounds follow you around after they killed everything or died then it's okay I guess ... 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