RaymondFoxford

Making character afraid of webber

Recommended Posts

so, I have a character who is arachnophobic, he loses a lot of sanity near spiders, I'm using this function for this to work:

 

local function sanityfn(inst)
	local x,y,z = inst.Transform:GetWorldPosition()	
	local delta = 0
	local max_rad = 20
	local ent = FindEntity(inst, 100, function(ent) 
		return ent:HasTag("spider")
			and not(ent.components.health and ent.components.health:IsDead())
	end)
	
	local ent = FindEntity(inst, 100, function(ent) 
		return ent:HasTag("spider_warrior")
			and not(ent.components.health and ent.components.health:IsDead())
	end)
	
	local ent = FindEntity(inst, 100, function(ent) 
		return ent:HasTag("spiderden")
			and not(ent.components.health and ent.components.health:IsDead())
	end)
	
	
	if ent then
		local sz = -TUNING.SANITYAURA_LARGE*3
		local rad = 20
		sz = sz * ( math.min(max_rad, rad) / max_rad )
		local distsq = inst:GetDistanceSqToInst(ent)
		delta = delta + sz/math.max(1, distsq)
	end

    return delta
end

and the sanity funcion:

local master_postinit = function(inst)

	-- Custom sanity function
	inst.components.sanity.custom_rate_fn = sanityfn

end

 

so, I thought: "Webber is a huge spider monster, it would make sense to lose sanity next to him if another player is using him next to my character", so I tried the same code:

 

local ent = FindEntity(inst, 100, function(ent) 
		return ent:HasTag("webber")
			and not(ent.components.health and ent.components.health:IsDead())
	end)

but no luck at all, it's possible to do that? make my character lose sanity to another player who is using Webber?

 

Share this post


Link to post
Share on other sites
CarlZalph    1,650

Instead of calling FindEntity multiple times, you can just use the function:

TheSim:FindEntities(origin_x, origin_y, origin_z, radius, musthavetags, canthavetags, musthaveoneoftags)

And populate the musthaveoneoftags with a table of each.

 

Example:

TheSim:FindEntities(x, 0, z, TUNING.SANITY_EFFECT_RANGE, nil, {"INLIMBO"}, {"spider","spider_warrior","spider_den","spiderwhisperer"})

 

Webber's special tag is "spiderwhisperer" from his prefab file, and the maximum radius negative sanity aura affects should be applied to is 10.0 units in-game, the value of TUNING.SANITY_EFFECT_RANGE.

 

Then iterate over the list of entities returned by it if it returned not nil, and add onto a delta sanity counter to then do a delta sanity tick for your character.

Or if you're just wanting the closest entity only to matter, then get the first entity index returned by the function- it's automatically sorted by proximity.

Share this post


Link to post
Share on other sites
On 11/14/2017 at 5:31 PM, CarlZalph said:

Instead of calling FindEntity multiple times, you can just use the function:

TheSim:FindEntities(origin_x, origin_y, origin_z, radius, musthavetags, canthavetags, musthaveoneoftags)

And populate the musthaveoneoftags with a table of each.

 

Example:

TheSim:FindEntities(x, 0, z, TUNING.SANITY_EFFECT_RANGE, nil, {"INLIMBO"}, {"spider","spider_warrior","spider_den","spiderwhisperer"})

 

Webber's special tag is "spiderwhisperer" from his prefab file, and the maximum radius negative sanity aura affects should be applied to is 10.0 units in-game, the value of TUNING.SANITY_EFFECT_RANGE.

 

Then iterate over the list of entities returned by it if it returned not nil, and add onto a delta sanity counter to then do a delta sanity tick for your character.

Or if you're just wanting the closest entity only to matter, then get the first entity index returned by the function- it's automatically sorted by proximity.

Thank you so much! it worked perfectly! :D

btw, I have another question, before I changed this code, I noticed that my mod was causing a huge lag on servers up to 4 or more players, do you think it's because I called the "FindEntity" these multiple times?

still didn't had the chance to test with the new code.

Share this post


Link to post
Share on other sites
CarlZalph    1,650
49 minutes ago, RaymondFoxford said:

Thank you so much! it worked perfectly! :D

btw, I have another question, before I changed this code, I noticed that my mod was causing a huge lag on servers up to 4 or more players, do you think it's because I called the "FindEntity" these multiple times?

still didn't had the chance to test with the new code.

Each call on the function FindEntity uses TheSim:FindEntities, which always iterates over all entities.

It's best to have it in as few calls as possible, and optimally just one.

The sanity component's custom rate function is called quite frequently, too, so this is going to be compounded by a lot.

 

A bit of an obscure method on doing this is to create or hook into sanity auras with custom rates.

Sanity.lua calls TheSim:FindEntities already and does the calculations based on proximity as-is for all entities that have these rates.

May as well add a little bit of load here than to iterate more.

Lines 288-296 of sanity.lua:

Spoiler

    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 (self.neg_aura_absorb > 0 and self.neg_aura_absorb * -aura_val or aura_val) * self.neg_aura_mult or aura_val)
        end
    end

 

 

And example of this here, for "winona" prefab which would be replaced with your character's prefab name:

Spoiler

local function CreateOrHookSanityAura(inst, rate)
    if inst.components.sanityaura == nil
    then
        inst:AddComponent("sanityaura")
    end
    local GetAura_old = inst.components.sanityaura.GetAura
    inst.components.sanityaura.GetAura = function(self, observer, ...)
        if observer.prefab == "winona"
        then
            return rate
        end
        return GetAura_old(self, observer, ...)
    end
end
local function MakeThisSpiderScary(prefab, rate)
    AddPrefabPostInit(
        prefab,
        function(inst)
            if not GLOBAL.TheWorld.ismastersim
            then
                return
            end
            inst:DoTaskInTime(
                0,
                function(inst)
                    CreateOrHookSanityAura(inst, rate)
                end
            )
        end
    )
end
MakeThisSpiderScary("webber", -5)

MakeThisSpiderScary("spider", -10)
MakeThisSpiderScary("spider_warrior", -20)

MakeThisSpiderScary("spider_hider", -10)
MakeThisSpiderScary("spider_spitter", -20)
MakeThisSpiderScary("spider_dropper", -20)

MakeThisSpiderScary("spiderden", -10)
MakeThisSpiderScary("spiderden_2", -20)
MakeThisSpiderScary("spiderden_3", -30)
MakeThisSpiderScary("spiderqueen", -50)

 

 

Edited by CarlZalph
Line numbers and code from sanity.lua
  • Thanks 1

Share this post


Link to post
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