Jump to content

Sanity drain from being wet from rain


Recommended Posts

Hello there!
So i was trying to create a character wich would lose sanity when it would be raining,tried to code it myself and looked here and there but nothing seems to work.
I looked up how WX-78 loses his health during rain and tried to modify the code but it seems to not work at all
 

Quote

 

local function dorainsparks(inst, dt)
    if inst.components.moisture ~= nil and inst.components.moisture:GetMoisture() > 0 then
        local t = GetTime()

        -- Raining, no moisture-giving equipment on head, and moisture is increasing. Pro-rate damage based on waterproofness.
        if inst.components.inventory:GetEquippedMoistureRate(EQUIPSLOTS.HEAD) <= 0 and inst.components.moisture:GetRate() > 0 then
            local waterproofmult =
                (   inst.components.sheltered ~= nil and
                    inst.components.sheltered.sheltered and
                    inst.components.sheltered.waterproofness or 0
                ) +
                (   inst.components.inventory ~= nil and
                    inst.components.inventory:GetWaterproofness() or 0
                )
            if waterproofmult < 1 and t > inst.spark_time + inst.spark_time_offset + waterproofmult * 7 then
                inst.components.sanity:DoDelta( -1, false, "rain")
                inst.spark_time_offset = 3 + math.random() * 2
                inst.spark_time = t
                
            end
        elseif t > inst.spark_time + inst.spark_time_offset then -- We have moisture-giving equipment on our head or it is not raining and we are just passively wet (but drying off). Do full damage.
            inst.components.sanity:DoDelta(
                inst.components.moisture:GetRate() >= 0 and
                -1 or
                -1,
                false, "water")
            inst.spark_time_offset = 3 + math.random() * 2
            inst.spark_time = t
            
        end
    end
end

local function onisraining(inst, israining)
    if israining then
        if inst.spark_task == nil then
            inst.spark_task = inst:DoPeriodicTask(.1, dorainsparks, nil, .1)
        end
    elseif inst.spark_task ~= nil then
        inst.spark_task:Cancel()
        inst.spark_task = nil
    end
end

 

So if anybody could help me i would appreciate it a lot!

Link to comment
Share on other sites

I would say something like : check if it's raining, and if it's raining, having a negative sanity gain ? Or a dotaskintime to remove sanity time to time ?

WX code is complex because it's here to do damage time to time, but not doing damage if the character is sheltered for the rain. You just want a "if it's raining, lose sanity, if not, no", no ? So you don't need something that complex ?

Link to comment
Share on other sites

Use the sanity component's custom_rate_fn variable to store a custom function, for example this

inst.components.sanity.custom_rate_fn = function(inst) return -inst.components.moisture:GetMoistureRate() end

decreases your sanity at the same rate as rain increases your wetness. Take a look at the moisture component (data/scripts/components/moisture.lua) to see how it's calculated.

Link to comment
Share on other sites

8 hours ago, alainmcd said:

Use the sanity component's custom_rate_fn variable to store a custom function, for example this


inst.components.sanity.custom_rate_fn = function(inst) return -inst.components.moisture:GetMoistureRate() end

decreases your sanity at the same rate as rain increases your wetness. Take a look at the moisture component (data/scripts/components/moisture.lua) to see how it's calculated.

Thank you so much! It works all fine even tho i would prefer to have the shelter no sanity drop but still im happy with this thank you again!!

Link to comment
Share on other sites

Not sure what you mean. If you want not to have a sanity penalty when sheltered, well, the game calculates the moisture rate with being sheltered offering only partial water proofing. But you can always tune it. See example below.

Also, the proper way to do use a custom sanity function is indeed through custom_rate_fn, but you should probably account for the possibility that other mods might also be adding a custom sanity function of their own. So you'd usually store that custom sanity function in a local "Old" variable and then call it from your own function.

Example with no sanity penalty if sheltered and accounting for possible custom functions from other mods:

local OldCustomSanityFn = inst.components.sanity.custom_rate_fn		--temp store previous custom_rate_fn
inst.components.sanity.custom_rate_fn = function(inst)
	local old = OldCustomSanityFn and OldCustomSanityFn(inst) or 0	--previous custom sanity or 0
	return (not inst.components.sheltered.sheltered and		--only apply if not sheltered
		-inst.components.moisture:GetMoistureRate() or 0)
		+ old
end

Untested, but it probably still works.

Link to comment
Share on other sites

16 hours ago, alainmcd said:

Untested, but it probably still works

put it in the code and got this error,tried to put 'function' after local but it still doesnt work and tried to put the code in the 'master_postinit' but still getting this crash

87c6a5b29a.png

Link to comment
Share on other sites

On 7/14/2017 at 2:45 PM, alainmcd said:

I don't know what your line 52 looks like or its context. Please copy your whole endy.lua.

So i tried again and got this crash 

92c0c8d47e.png

here's the code

Quote

 

local MakePlayerCharacter = require "prefabs/player_common"


local assets = {
    Asset("SCRIPT", "scripts/prefabs/player_common.lua"),
}
local prefabs = {}

-- Custom starting items
local start_inv = { 
"blowdart_pipe" , "blowdart_pipe" , "blowdart_pipe" , "blowdart_pipe" , "blowdart_pipe" , "grass_umbrella" , "flowerhat"
}

-- When the character is revived from human
local function onbecamehuman(inst)
    -- Set speed when reviving from ghost (optional)
    inst.components.locomotor:SetExternalSpeedMultiplier(inst, "endy_speed_mod", 1)
end

local function onbecameghost(inst)
    -- Remove speed modifier when becoming a ghost
   inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "endy_speed_mod")
end

-- When loading or spawning the character
local function onload(inst)
    inst:ListenForEvent("ms_respawnedfromghost", onbecamehuman)
    inst:ListenForEvent("ms_becameghost", onbecameghost)

    if inst:HasTag("playerghost") then
        onbecameghost(inst)
    else
        onbecamehuman(inst)
    end
end

local function playersanfn(inst) --For gaining sanity near players
    local x, y, z = inst.Transform:GetWorldPosition()
    local delta = 0
    local ents = TheSim:FindEntities(x, y, z, 30, {"player"})
    for k, v in pairs(ents) do
        if v ~= inst then
            local bonus_sanity = TUNING.SANITYAURA_LARGE
            local distsq = math.max(inst:GetDistanceSqToInst(v), 1)
            delta = delta + bonus_sanity / distsq
        end
    end
    return delta
end

local OldCustomSanityFn = inst.components.sanity.custom_rate_fn        --temp store previous custom_rate_fn
inst.components.sanity.custom_rate_fn = function(inst)
    local old = OldCustomSanityFn and OldCustomSanityFn(inst) or 0    --previous custom sanity or 0
    return (not inst.components.sheltered.sheltered and        --only apply if not sheltered
        -inst.components.moisture:GetMoistureRate() or 0)
        + old
end

-- This initializes for both the server and client. Tags can be added here.
local common_postinit = function(inst) 
    -- Minimap icon
    inst.MiniMapEntity:SetIcon( "endy.tex" )
end

-- This initializes for the server only. Components are added here.
local master_postinit = function(inst)
    -- choose which sounds this character will play
    inst.soundsname = "wilson"
    
    -- Uncomment if "wathgrithr"(Wigfrid) or "webber" voice is used
    --inst.talker_path_override = "dontstarve_DLC001/characters/"
    
    -- Stats    
    inst.components.health:SetMaxHealth(150)
    inst.components.hunger:SetMax(200)
    inst.components.sanity:SetMax(100)
    
    -- Damage multiplier (optional)
    inst.components.combat.damagemultiplier = 1
    
    -- Hunger rate (optional)
    inst.components.hunger.hungerrate = 0.2 * TUNING.WILSON_HUNGER_RATE
    
    inst.components.sanity.night_drain_mult = 1.1
    
    
    inst.OnLoad = onload
    inst.OnNewSpawn = onload
    
end

return MakePlayerCharacter("endy", prefabs, assets, common_postinit, master_postinit, start_inv ,)

 

 

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...