Jump to content

Quick question about sanity auras, etc


Recommended Posts

Hey all, me again!

Still hard at work on my modded character. He loves bees, and I'm having trouble giving the bees a small positive sanity aura for him. I have been rooting around the evil flower files as well as the pigman files to understand how exactly sanity auras affect the player character. I also couldn't find any relevant information with google searches/previous mods. 

I figure the code will go somewhere in the "name".lua file under his master_postinit but I'm just getting my feet wet in the modding/coding world so I could be totally wrong. Any help is really appreciated :).

Link to comment
Share on other sites

1 hour ago, BeansInMyLean said:

Still hard at work on my modded character. He loves bees, and I'm having trouble giving the bees a small positive sanity aura for him. I have been rooting around the evil flower files as well as the pigman files to understand how exactly sanity auras affect the player character. I also couldn't find any relevant information with google searches/previous mods.

Every tick of the game, the sanity component of each entity in the game updates.

Here's what happens while calculating the sanity rate:

local aura_delta = 0
local x, y, z = self.inst.Transform:GetWorldPosition()
local ents = TheSim:FindEntities(x, y, z, TUNING.SANITY_EFFECT_RANGE, nil, { "FX", "NOCLICK", "DECOR","INLIMBO" })
for i, v in ipairs(ents) do 
	if v.components.sanityaura ~= nil and v ~= self.inst then
		local aura_val = v.components.sanityaura:GetAura(self.inst) / math.max(1, self.inst:GetDistanceSqToInst(v))
		aura_delta = aura_delta + (aura_val < 0 and aura_val * self.neg_aura_mult or aura_val)
	end
end

//...

self.rate = dapper_delta + moisture_delta + light_delta + aura_delta + ghost_delta

x, y, z get the player position.

ents gets all entities within a 10 units range of x, y, z (1 turf = 4 units) that aren't special effects, unclickable, or in your inventory (limbo).

For each of those entities, do the following:

- if entity has a sanity aura, and the entity isn't the guy doing the sanity calculation then

-- get the aura value, divide it by the max between 1 or, the distance squared between sanity guy and entity

-- if aura value is negative, and sanity guy has a neg_aura_mult attribute, apply it before doing the sum

sum the aura delta to the total rate.

 

Now, what is sanityaura? This short component:

local SanityAura = Class(function(self, inst)
    self.inst = inst
    self.aura = 0
    self.aurafn = nil
end)

function SanityAura:GetAura(observer)
    return self.aurafn == nil and self.aura or self.aurafn(self.inst, observer)
end

return SanityAura

SanityAura has the members, inst (guy who receives component), aura (a number), aurafn (a function).

SanityAura.GetAura is another member function, which does the following:

return aura number if aurafn is nil, return the result of the function called with sanityaura guy and observer as arguments.

 

So, back to sanity:

v.components.sanityaura:GetAura(self.inst)

v is one of the entities the sanity component picked up in FindEntities, and will be the self.inst of the aurafn, if called.

self.inst, the sanity guy (the player), will be the observer.

 

Evil flowers have a number for aura:

inst:AddComponent("sanityaura")
inst.components.sanityaura.aura = -TUNING.SANITYAURA_SMALL

So it pretty much affects all characters with sanity and a neg_aura_mult different of 0.

 

Pigmen have a function for aura:

local function CalcSanityAura(inst, observer)
    return (inst.components.werebeast ~= nil and inst.components.werebeast:IsInWereState() and -TUNING.SANITYAURA_LARGE)
        or (inst.components.follower ~= nil and inst.components.follower.leader == observer and TUNING.SANITYAURA_SMALL)
        or 0
end

inst:AddComponent("sanityaura")
inst.components.sanityaura.aurafn = CalcSanityAura

With inst being the pig, observer being the guy with sanity.

So the function returns a debuff is pig is werepig, a buff if observer is friend of pig, or 0 if nothing else.

 

All of this being said. There are two ways of doing what you want:

1) Give a sanityaura for bees (since they don't have any) that benefits your character.

In modmain.lua:

-- The PostInit only needs to run server side, on the master simulation
if GLOBAL.TheNet:GetIsMasterSimulation() then

	-- If observer is not nil, and observer prefab is "wilson", return a positive number for the aura
	-- Other cases, return 0
	local function AuraFn(inst, observer)
		if observer and observer.prefab == "wilson" then
			return GLOBAL.TUNING.SANITYAURA_SMALL
		end
		return 0
	end

	local function BeePostInit(inst)
		-- If there isn't a sanity aura, make our own, and give it our function
		-- Else, we need to override it! Other modder gave the bee a sanity aura too!
		-- We need to save the old function, then use it on the new function we will put
		if not inst.components.sanityaura then
			inst:AddComponent("sanityaura")
			inst.components.sanityaura.aurafn = AuraFn
		else
			-- We save the old function
			local old_aurafn = inst.components.sanityaura.aurafn
			inst.components.sanityaura.aurafn = function(inst, observer)
				-- If observer is ourselves, return positive sanity aura
				-- Very much like or function
				if observer and observer.prefab == "wilson" then
					return GLOBAL.TUNING.SANITYAURA_SMALL
				end
				-- If the modder gave the bee a new function for the aura
				if old_aurafn then
					-- Then let the old function handle it
					return old_aurafn(inst, observer)
				end
				-- Else, he gave the bee a number for the aura
				-- So we should return that
				return inst.components.sanityaura.aura
			end
		end
	end

	-- Make the function BeePostInit run on each prefab named "bee"
	-- The function BeePostInit is given the prefab entity to modify, which we will call inst, short of instance
	AddPrefabPostInit("bee", BeePostInit)

end

2) Very much like how the game calculates the aura, you do the same.

There's this part in the sanity rate calculations:

if self.custom_rate_fn ~= nil then
	self.rate = self.rate + self.custom_rate_fn(self.inst)
end

Which means that if your sanity component has a function custom_rate_fn, you can apply your own delta to the sanity rate.

As such, you put in your master_postinit function of your character:

-- We copy paste the aura code, mostly
-- We look for entities with the "bee" tag, and entities without any of those 4 tags
-- Entities with "bee" can be either bees or killer bees, or any other thing with "bee" tag
-- So we check that the prefab of each entity in ents table is, in fact, a bee
-- Instead of depending on a sanity aura component, we feed directly the aura value we want per bee
-- We return the sum
local function SanityFn(inst)
	local aura_delta = 0
	local x, y, z = inst.Transform:GetWorldPosition()
	local ents = TheSim:FindEntities(x, y, z, TUNING.SANITY_EFFECT_RANGE, {"bee"}, {"FX", "NOCLICK", "DECOR", "INLIMBO"})
	for i, v in ipairs(ents) do 
		if v.prefab == "bee" then
			local aura_val = TUNING.SANITYAURA_SMALL / math.max(1, inst:GetDistanceSqToInst(v))
			aura_delta = aura_delta + aura_val
		end
	end
	return aura_delta
end

inst.components.sanity.custom_rate_fn = SanityFn

 

Link to comment
Share on other sites

1 hour ago, DarkXero said:

All of this being said. There are two ways of doing what you want:

1) Give a sanityaura for bees (since they don't have any) that benefits your character.

2) Very much like how the game calculates the aura, you do the same.

Thank you so much for such an awesome, in-depth and detailed guide on this! You really went above and beyond explaining and breaking down the parts :). I could cry its so user friendly with the comments and all.

The second way of doing this seems like the best way to go about it, but I think I'll use the first method with creating an aura; I think it will help me understand a little more of whats going on "behind the scenes" in the code rather than just giving the bees a custom aura value for my character. Thanks again!!

Klei should really think about hiring you for your coding prowess. 

----

I updated a picture; look at that nice little sanity buff!

20160519213312_1.jpg

Edited by BeansInMyLean
Picture
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...