Sign in to follow this  
WaffleKat

Sanity drain from being wet from rain

Recommended Posts

WaffleKat    1

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!

Share this post


Link to post
Share on other sites
Lumina    2153

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 ?

Share this post


Link to post
Share on other sites
alainmcd    901

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.

Share this post


Link to post
Share on other sites
WaffleKat    1
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!!

Share this post


Link to post
Share on other sites
alainmcd    901

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.

Share this post


Link to post
Share on other sites
WaffleKat    1
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

Share this post


Link to post
Share on other sites
alainmcd    901

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

Edited by alainmcd

Share this post


Link to post
Share on other sites
WaffleKat    1
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 ,)

 

 

Share this post


Link to post
Share on other sites
WaffleKat    1
5 minutes ago, alainmcd said:

The code I suggested here belongs in your master_postinit. The other crash you mention is because of the last comma in your last line of code.

Thank you! It works perfectly fine now!

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
Sign in to follow this