Jump to content

Recommended Posts

The base character is actually supposed to get minor sanity regen and minor speed increases while in the rain.

 

I have tried various ways of coding it, but it simply doesn't work. I have incredibly high values so it's obvious, but nothing seems to help.

 

I have tried:

local function raingood(inst, israining)	if israining then		inst.components.locomotor.walkspeed = 6 * 5		inst.components.locomotor.runspeed = 7 * 5		inst.components.sanity.dapperness = TUNING.DAPPERNESS_HUGE * 50		else		inst.components.locomotor.walkspeed = 6		inst.components.locomotor.runspeed = 7		inst.components.sanity.dapperness = (0)	endend

I have also tried:

I tried to copy someone's health in the rain mod, and set it to 20, but that doesn't appear to have worked either.

local function onisraining(inst, israining)    if israining then        inst.rain_task = inst.rain_task or inst:DoPeriodicTask(1, function(inst) inst.components.health:DoDelta(20) end)    else        if inst.rain_task ~= nil then inst.rain_task:Cancel() end    endendlocal function onbecamealive(inst)	inst:WatchWorldState("israining", onisraining)end local function onbecameghost(inst)	inst:StopWatchingWorldState("israining", onisraining)end

The above codes also included:

local function master_postinit(inst)   inst:DoPeriodicTask(1/10, function() raingood(inst) end)   inst:ListenForEvent("ms_respawnedfromghost", onbecamealive)   inst:ListenForEvent("ms_becameghost", onbecameghost)    

Nothing seems to work.

 

I am absolutely at a loss.

Edited by Nyogtha

@Nyogtha, Something there should DEFINITELY be working. Are you sure you're not editing the wrong copy of the files (that is, the one that you're not actually running)? I know I've done that a bunch of times.

 

Edit: Your DoPeriodicTask implementation will always result in israining==nil, so instead of raingood(inst), you should have raingood(inst, TheWorld.state.israining). That being said, the WatchWorldState approach is much more efficient.

Edited by rezecib
1) WatchWorldState What are valid states?
 components/worldstate

 

2) ListenForEvent What are valid events?
This is a lot more complicated. Many things can push events. Some events are only pushed on specific entities (e.g. "death" will on be heard when listening with a specific entity). You just sort of have to... hunt around.

 

3) DoPeriodicTask How do you use this function?
Look at its implementation in scripts/entityscript. The basics are that you give it an interval, and a function. It runs the function once after each interval.

I'm looking at Wark's "moult" ability and the code is

 

inst:WatchWorldState("startsummer", Moult)

 

However, "startsummer" does not exist in worldstate.lua.

 

How does this work?

 

Edit:

Ok maybe it does at

 


local function SetVariable(var, val, togglename)

...

watchers = _watchers[(val and "start" or "stop")..togglename]

end

 

But does "startsummer" means only one time per summer or every day while in summer season?

Edited by SenL

We are in worldstate.lua, that SetVariable (that triggers the WatchWorldState) gets executed inside OnSeasonTick, OnSeasonTick gets executed when a seasontick event gets pushed into the world, the seasontick push occurs within OnSeasonDirty in seasons.lua, OnSeasonDirty gets executed when _season gets dirty (there is a set() function with it).

 

This happens in OnAdvanceSeason, OnRetreatSeason, OnSetSeason and the initialization of _season.

OnAdvanceSeason happens on a ms_cyclecomplete or ms_advanceseason event pushed.

OnRetreatSeason happens on a ms_retreatseason event pushed.

OnSetSeason happens on a ms_setseason event pushed.

 

This leads us to the clock.lua.

ms_cyclecomplete happens when the day changes (a cycle of 3 phases gets completed).

ms_advanceseason happens with debug keys and the winter chest trap.

ms_retreatseason happens with debug keys.

ms_setseason happens with debug keys, winter chest trap, and initially if you edit your world configuration, tuning_override makes events get pushed to change the world to look like the settings (like if I pick starting in winter).

 

So, every day, once per day.

Wow...

 

Edit:

Ok I copied Wark's but it doesn't work on mine.

All below is in mychar.lua:

 

local function DropItem(inst)

  local itemtoshed = SpawnPrefab("bonestew") --testing, will change to cutgrass

  local pos = inst:GetPosition()

  itemtoshed.Transform:SetPosition(pos.x + math.random()*2 - 1, 1, pos.z + math.random()*2 - 1)

end

 

local function mychar_shed(inst)

  local delay = 0

  for i=1,3 do

    delay = delay + math.random()*3

    inst:DoTaskInTime(delay, DropItem)

  end

end

 

local master_postinit = function(inst)

  --snip

  

  inst:WatchWorldState("startsummer", mychar_shed)

  --snip

 

At morning time day 2, mychar did not drop any bonestew/cutgrass.

What is missing?

 

Thanks.

Edited by SenL

@SenL, You still have that attached to startsummer, so it'll only drop a meaty stew on a winter -> summer transition. You can force this to occur by executing these commands:

TheWorld:PushEvent('ms_setseason', 'winter')TheWorld:PushEvent('ms_setseason', 'summer')

"startsummer" doesn't exist in worldstate, but "summer" does. When summer gets set to true, it pushes a "startsummer" event (you can look in worldstate, the code for that should be there). Similarly, it will push a "stopsummer" event when summer gets set to false.

Ah, right, my mistake. In the SetVariable, there is the first line that I overlooked:

if self.data[var] ~= val and val ~= nil then

so that the start and stops get pushed only when the seasons change (the issummer is set to true but data.season is set to winter).

 

However, each seasontick event is performed each day, and the value always changes inbetween days, that is why the remainingdaysinseason change all days.

 

What you want SenL, is instead:

inst:WatchWorldState("startday", function(inst)   if TheWorld.state.issummer then      mychar_shed(inst)   endend)

Or even:

TheWorld:ListenForEvent("seasontick", function(world)   if world.state.issummer then      mychar_shed(inst)   endend)

I changed it to

 

inst:ListenForEvent("seasontick", function(world)
  if world.state.issummer then
    --inst.components.talker:Say("debug: summer, time to shed")
    mychar_shed(inst)
  end

end)

(inside mychar.lua and inside master_postinit)

 

But so far hasn't shed.

Oops thanks for pointing out the typo. Changed to "TheWorld:ListenForEvent" and it works (starts on 2nd day though but it's ok).

Thanks all!

 

Now I want to randomize what he's shedding: log, boards, cutgrass or twigs

I have this code

 

local function DropItem(inst)

  local itemtoshed = SpawnPrefab("log")

  ...

end

 

local function mychar_shed(inst)

  local delay = math.random()

  inst:DoTaskInTime(delay, DropItem)

end

 

I think I could add math.random() stuff inside "DropItem", but what if I want to do the random-ing in mychar_shed?

 

Kind of like this (pseudo code)

 

math.random() stuff here

if this then

  inst:DoTaskInTime(delay, DropItem("log"))

elseif that1 then

  inst:DoTaskInTime(delay, DropItem("boards"))

elseif that2 then

  inst:DoTaskInTime(delay, DropItem("cutgrass"))

end

 

How... I'll try stuff meanwhile.

Thanks.

Edited by SenL

I have a bug. My char gets tiny health and sanity gain when it's raining... however, he keeps gaining this bonus when the rain stops.

How do you cancel "DoPeriodicTask"?

 

Code in mychar.lua:

local function rainheal(inst)
  inst.components.health:DoDelta(.5)
  inst.components.sanity:DoDelta(.5)
end
 
local function onisraining(inst, israining)
  if israining then
    inst:DoPeriodicTask(5, rainheal)
  end
  --else cancel period task... how?
end
 
local function onbecomingalive(inst)
  inst:WatchWorldState("israining", onisraining)
  onisraining(inst, TheWorld.state.israining)
  applyupgrades(inst)
end
 
local function onbecomingghost(inst)
  inst:StopWatchingWorldState("israining", onisraining)
end

 

Thanks.

 

Edit:
Looking at wx78.lua... I'll set it to inst.rainheal_task and use inst.rainheal_task:Cancel() when it's not raining...

 

Edit:

Seems to work.

Edited by SenL

@SenL, Looks like you figured it out, but yes, DoPeriodicTask returns the task, so you can store it in a variable like that and cancel it. You can look at how the scheduling works in scripts/scheduler.lua (although the DoPeriodicTask function is specified in entityscript.lua, but it's a pretty thin wrapper around scheduler functions).

@Nyogtha, Something there should DEFINITELY be working. Are you sure you're not editing the wrong copy of the files (that is, the one that you're not actually running)? I know I've done that a bunch of times.

 

Edit: Your DoPeriodicTask implementation will always result in israining==nil, so instead of raingood(inst), you should have raingood(inst, TheWorld.state.israining). That being said, the WatchWorldState approach is much more efficient.

 

I have a similar issue. I'm making a Pyromancer who's sanity raises while near fire and he has a rain weakness like WX-78. This character mod is for Dont starve together and I dont know what will work. What should I throw in into my prefabs folder?

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
×
  • Create New...