Jump to content

How to make a frog act neutral to a character?


Recommended Posts

Hi guys! Is there any simple way that I can make a monster creature (frog for example) to not attack my mod character as long as I don't attack it?

For example, I'd like frogs to do nothing / ignore when my mod character is nearby, just like how normally a beefalo behaves, or like how spiders behave to Webber?

I'm very new to coding and if you can point out which file(s) I should go and how to edit that'd be very nice. Thank you!

Link to comment
Share on other sites

for frogs coding

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" },
        { "the tag of your character", "INLIMBO" }
    )
end

 

your character 

inst:AddTag("the tag of your character")

 

these are some coding i think might work it may not work though but just for refrence

Link to comment
Share on other sites

EDIT: I believe to have found a better way to do this (see my post further down). The code in THIS post makes it impossible for frogs to target you, even if you're attacking them. Further down, I've given a draft of some code which will let frogs attack you IF you attack them first...and they will remember that you did until they die, and I believe they can share their target with other frogs :) 

---------------------------------------------------------------------------------------------------

Original post:

Frogs don't really have that kind of code, thomas4845.

What you need to do, menghuancat, is replace the retarget function set on the frog's combat-component. Since the original function is local, and we need to alter the code and cannot just extend it because we can't intercept the return value before it's too late, we need to copy it and alter it. Luckily, it's a small change.

Put this at the bottom of your modmain.lua, give your character a unique tag, and replace the "CHARACTER_SPECIFIC_TAG" line with that tag.

local function frogretargetfn(inst)
    if not inst.components.health:IsDead() and not inst.components.sleeper:IsAsleep() then
        return GLOBAL.FindEntity(inst, GLOBAL.TUNING.FROG_TARGET_DIST, function(guy) 
            if not guy.components.health:IsDead() then
                return guy.components.inventory ~= nil
            end
        end,
        {"_combat","_health"}, -- see entityreplica.lua
        {"CHARACTER_SPECIFIC_TAG"} -- This is the list of tags the frog will avoid targeting.
        )
    end
end

AddPrefabPostInit("frog", function(inst)
	inst.components.combat:SetRetargetFunction(3, frogretargetfn)
end)

 

Edited by Ultroman
Link to comment
Share on other sites

@Ultroman

Ahh thank you! That helps a lot!! I have one more dumb question, how do I create a unique tag for my character?  In a lot of character mods they have something called "xxxbuilder" in their modmain, where xxx is the name of the character. Is the builder thing the tag? Or do I have to create it in modmain first?

Link to comment
Share on other sites

6 hours ago, thomas4845 said:

oh cool sorry i'm not use to this all yet i'm still coding like a newbie huh :) 

Well, the code was in the vicinity, which is what you said you were going for, so it's fine :) Don't be discouraged from helping another time.

5 hours ago, menghuancat said:

@Ultroman

Ahh thank you! That helps a lot!! I have one more dumb question, how do I create a unique tag for my character?  In a lot of character mods they have something called "xxxbuilder" in their modmain, where xxx is the name of the character. Is the builder thing the tag? Or do I have to create it in modmain first?

It's really easy, actually. In your character's LUA script, go to your post-init function (e.g. master_postinit() or something) and put in inst:AddTag("CHARACTER_SPECIFIC_TAG")

I'm not quite sure what builder-tags you're talking about, but the builder-component can limit/enable the building of things based on tags.

Link to comment
Share on other sites

4 hours ago, Ultroman said:

Well, the code was in the vicinity, which is what you said you were going for, so it's fine :) Don't be discouraged from helping another time.

i'm only starting to try and help people because i'm trying to be like people like you who just helps (cool kids) :)

Link to comment
Share on other sites

Just now, thomas4845 said:

i'm only starting to try and help people because i'm trying to be like people like you who just helps (cool kids) :)

That's awesome! Never stop aiming for awesome ;) And thanks for the compliment. I do my best. Even I am not an expert on this game, though. After all these years (3 or 4, I think) I still get surprised.

Edited by Ultroman
Link to comment
Share on other sites

3 minutes ago, thomas4845 said:

:) love you too

btw i mean this in a like sibling love (sorry if it sounds weird ) 

Hahaha, thanks :) That's OK, I never take the word "love" for its traditional meaning, when it's not uttered face-to-face. I'm always happy to see more people coming in to help the poor newcomers climb the steep learning curve that is Don't Starve modding and coding in general.

Link to comment
Share on other sites

I have to say, though, I just realized this code will make frogs not be able to attack you at all...not even if you attack them. Not sure if that was what you were after. Making it so they can still attack you if you attack them, is a bit more complex.

Link to comment
Share on other sites

You could add a list (attackedOnPurpose) to the frog's combat script, and then every time someone attacks the frog and they are playing your character (and they're not already in the list), you add them to the list. Then, you can add a check to your new retargetfn, to let the frog target that player despite the ignore-tag. This code should work. The frog NEVER forgets it if you attack him, and AFAIK if the frog chooses to share its target, it can still call on the other frogs in the area to attack you, since the ShareTarget function doesn't use retarget...I could be wrong about that, though. Anyway, this code should make it so frogs never attack your character, unless you attack them first...in which case you go on their kill-list :D

local function frogretargetfn(inst)
	if not inst.components.health:IsDead() and not inst.components.sleeper:IsAsleep() then
		return GLOBAL.FindEntity(inst, GLOBAL.TUNING.FROG_TARGET_DIST, function(guy) 
			if not guy.components.health:IsDead() then
				if guy.components.inventory == nil then
					return false
				end
			
				if guy.prefab == "CHARACTER_PREFAB_NAME" then
					return inst.components.combat.attackedOnPurpose[data.attacker.name]
				end
			end
		end,
		{"_combat","_health"}, -- see entityreplica.lua
		nil -- This is the list of tags the frog will avoid targeting.
		)
	end
end

AddPrefabPostInit("frog", function(inst)
	inst.components.combat.attackedOnPurpose = {}
	inst:ListenForEvent("attacked", function(data)
		if data and data.attacker and data.attacker.name and data.attacker:HasTag("player") and data.attacker.prefab == "CHARACTER_PREFAB_NAME" and not inst.components.combat.attackedOnPurpose[data.attacker.name] then
			table.insert[inst.components.combat.attackedOnPurpose, data.attacker.name]
		end
	end)
	inst.components.combat:SetRetargetFunction(3, frogretargetfn)
end)

 

Edited by Ultroman
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...