almightyjanitor Posted December 4, 2015 Share Posted December 4, 2015 I'm making a dart that causes insanity in mobs. I've got it to work for passive creatures, who run around in a panic and then die after some time, but for neutral and hostile mobs I want them to freak out and start attacking their own kind. I'm kind of stumped on this part. I'm not looking for step-to-step instructions but some pointers would be appreciated. Problems: - The non-passive mobs shouldn't die at the end, instead the insanity effect should wear off after a while. I think I should use DoPeriodicTask() for this? -Need to stop the insane mob from targeting the player (unless the player hits them) and tell them what to target instead. I can already see that the existing code's not working because it only executes once. -The insane mob should run around panicked until they find a target to attack. Do I need a new behaviour, or can I just add the panic behaviour to their brain? - Is there a better way to determine if the target is a passive mob? I've found that even rabbits and birds have the combat component. Right now I'm checking their tags but not all of them are tagged clearly. I'm basing most of it off the blowdart code. Relevant bits below:--determines whether the mob hit by the dart can fightlocal function canCombat(target) if target:HasTag("hostile") then return true end if target:HasTag("character") then return true end return false endlocal function findTarget(attacker) --borrowed this from the merm code --local victim = FindEntity(???) --how can i find the attacker's same species? return victimendlocal function attack(inst, attacker, target) if target.components.locomotor then target.SoundEmitter:PlaySound("dontstarve/wilson/blowdart_impact_sleep") if target.components.sleeper and target.components.sleeper:IsAsleep() then target.components.sleeper:WakeUp() end if canCombat(target) then --this is where I attempt to make the mob attack nearby other mobs local newtarget = findTarget(target) target.components.combat:SuggestTarget(newtarget) elseif target:HasTag("bird") then target.sg:GoToState("distress_pre") target:DoTaskInTime(10+math.random()*5, function() target.components.health:Kill() end) else local behaviours = target.brain.bt.root.children table.insert(behaviours, 1, Panic(target)) target:DoTaskInTime(10+math.random()*5, function() target.components.health:Kill() end) end --part of the blowdart code, I don't know if anything changed when I comment it out. --if target.sg and target.sg.sg.states.hit then -- target.sg:GoToState("hit") --end endend Link to comment Share on other sites More sharing options...
pickleplayer Posted December 5, 2015 Share Posted December 5, 2015 Whew, making mobs attack the nearest target sounds tough.Maybe you could try something like "inst.components.combat:SetTarget(TheSim:FindNearestEntityWithTag("whatevertag")) (That's not 'exactly' what the actual code would look like, I'm just making it up from what I can remember. But it could look something like that) also I'm not even sure if that would work.You shouldn't need to make a new behavior, the existing panic should work. I can show you how to add behaviors to creatures brains priority nodes. Been there, done that.I'll have to look it up later though, becaus I remember it being pretty complicated Link to comment Share on other sites More sharing options...
Arkathorn Posted December 5, 2015 Share Posted December 5, 2015 Don't use 'DoPeriodicTask' or 'DoTaskInTime', they aren't persistent. You'll need to have a component with a variable that counts down and stops the effect when it runs out, and saves the value across sessions. You could just have a list of what mobs are considered passive, and check that each time (Or use 'AddPrefabPostInitAny' to add a tag when they are first created, so you only have to check the list once per prefab). I'm pretty sure the 'combat' component is also about taking damage, not just dealing it. Link to comment Share on other sites More sharing options...
almightyjanitor Posted December 5, 2015 Author Share Posted December 5, 2015 Thanks for the replies. Can I add a component to the entity when it's hit, or do I have to add it to all the mobs I want to have it from the start? Link to comment Share on other sites More sharing options...
pickleplayer Posted December 5, 2015 Share Posted December 5, 2015 Yea, you can add components on hit. inst(orwhatever):AddComponent("componentname") Link to comment Share on other sites More sharing options...
Arkathorn Posted December 5, 2015 Share Posted December 5, 2015 I suggest you take a look at Mobbstar's Soulful Alchemy. It's potion effects are similar to what you are describing. Link to comment Share on other sites More sharing options...
almightyjanitor Posted December 6, 2015 Author Share Posted December 6, 2015 How do event listeners work? I don't quite understand this bit of code in the spider prefab: local function OnAttacked(inst, data) inst.components.combat:SetTarget(data.attacker) inst.components.combat:ShareTarget(data.attacker, 30, function(dude) return dude:HasTag("spider") and not dude.components.health:IsDead() and dude.components.follower and dude.components.follower.leader == inst.components.follower.leader end, 10)end inst:ListenForEvent("attacked", OnAttacked)What is the "data" parameter? What's being passed into the function? Link to comment Share on other sites More sharing options...
pickleplayer Posted December 6, 2015 Share Posted December 6, 2015 Well I've just started learning all this recentlyand it's pretty complicated. But a simple way to use event listeners is to add that line of code, in this case "inst:ListenForEvent("attacked", OnAttacked)" and then somewhere else (probably in combat.lua) you can activate the event with "inst:PushEvent("attacked")" which will cause the spider's "OnAttacked" function to run. Link to comment Share on other sites More sharing options...
almightyjanitor Posted December 7, 2015 Author Share Posted December 7, 2015 Yeah, I figured it out, the PushEvent was in combat.lua:function Combat:GetAttacked(attacker, damage, weapon) --blah blah self.inst:PushEvent("attacked", {attacker = attacker, damage = damage, weapon = weapon}) --blah blahendThis is great since I can call a function whenever I want instead of just relying on the component's function handles. Anyways, I made a new "panic" component. It doesn't do much right now, just stops the target's brain, but it properly wears off after a set time, so hooray. Although I don't know how to make it persist across sessions yet. I'm thinking that if I'm going to inject some new complicated behaviour into the brain, I need to "reset" their brain when the effect runs out, right? Is the unmodified brain saved somewhere? Link to comment Share on other sites More sharing options...
pickleplayer Posted December 7, 2015 Share Posted December 7, 2015 Yeah, I figured it out, the PushEvent was in combat.lua:function Combat:GetAttacked(attacker, damage, weapon) --blah blah self.inst:PushEvent("attacked", {attacker = attacker, damage = damage, weapon = weapon}) --blah blahendThis is great since I can call a function whenever I want instead of just relying on the component's function handles.Anyways, I made a new "panic" component. It doesn't do much right now, just stops the target's brain, but it properly wears off after a set time, so hooray. Although I don't know how to make it persist across sessions yet.I'm thinking that if I'm going to inject some new complicated behaviour into the brain, I need to "reset" their brain when the effect runs out, right? Is the unmodified brain saved somewhere?Yep. And nah, the brain just resets itself to how it normally is. You can check out some of my code in the mod "Kaji" I do some brain things with behaviors, but with "runaway" instead of "panic" (in both his character prefab and the fearcore prefab) Link to comment Share on other sites More sharing options...
almightyjanitor Posted December 8, 2015 Author Share Posted December 8, 2015 I've gotten the "attack anything in sight" part to work by calling combat:SetRetargetFunction() and replacing it with a new function. Their old retarget function is saved in a variable, which gets put back when the effect ends (although they tend to die hilariously before that happens because they attacked their neighbour). The only thing left to do is to add the panic behaviour. The problem is that they'll stop running around to eat food off the ground... I know that behaviours are prioritized in the brain, but I can't figure how you specify the priority of new behaviours. Obviously panic should come before eating food, but after combat. Link to comment Share on other sites More sharing options...
pickleplayer Posted December 8, 2015 Share Posted December 8, 2015 here try this:table.insert(v.brain.bt.root.children, math.min(1, #behaviours), Panic(v)) I'm actually pretty sure that will work.I THINK behavior prioritization is defined by than number after math.min (I had a problem with spiders falling asleep when running away. I never actually fixed that bug and instead disabled spiders ability to fall asleep while running)But maybe try changing that 1 to a 0. That might make it actual top priority Link to comment Share on other sites More sharing options...
almightyjanitor Posted December 8, 2015 Author Share Posted December 8, 2015 I've tried changing that number. 1 works fine for most mobs, but spiders prefer eating and sleeping, at 0 it's broken and they don't panic at all. I think I might be inserting the panic behaviour into their brains multiple times when I shoot them with more than one dart... I'll have to fix that. It looks like the brains use a tree to prioritize behaviours, so it's more complex than just a list of priorities from top to bottom, unfortunately I'm not good with trees... But whatever, moving onto the next thing for now. I want to check if a creature has noticed the player. I can check combat.target for hostile creatures, but for ones that run away from the player like rabbits and pigs, I can't find any relevant variables that tell me who they're running away from. So how can I check if something's running away from me? Link to comment Share on other sites More sharing options...
pickleplayer Posted December 8, 2015 Share Posted December 8, 2015 I find it usefull to stop the creatures brain immediately after inserting the behavior. (they can't make any decisions while their brain is stopped) The Panic behavior doesn't have a "target" to run away from. They just run in completely random directions.The RunAway behavior does though. in RunAway.lua its "hunterparams". Not sure if that will really help you, but yea. Link to comment Share on other sites More sharing options...
Recommended Posts
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.