Jump to content

How Do I Change Deciduous Trees from Leafless to Leafy and Vice Versa? (Solved)


Recommended Posts

Solution:

Worked around the issue by sending in the console GetSeasonManager():StartSummer() and then LongUpdate(14*16*30) to skip to the last day of Summer (No Flingomatics were needed since wildfires only start occurring a few days into Summer and never occur on the first or last day). To prevent the issue from occurring, send GetSeasonManager():StartAutumn() in the console every few days (so the last 10% of Autumn is never reached), or go through the seasons naturally.

 

TD;LR:

My trees are stuck in "barren" state. What console command can I use to change all deciduous trees in my single-player RoG Don't Starve world to be "colorful", "normal", or "barren"?

Things I've Tried (Trees did not grow leaves. In the case of the console commands, OnSeasonChange is a local function so it didn't work):

*Using LongUpdate() to cycle through a whole in-game year.

*Triggering StartSpring with a console command and then triggering StartAutumn again.

*for k,v in pairs(Ents) do if v.prefab == "deciduoustree" then v:OnSeasonChange(v, "autumn") end end

*for k,v in pairs(Ents) do if v.prefab == "deciduoustree" then v.target_leaf_state = "colorful" end end

Another question is, is my game considered bugged if using LongUpdate() didn't solve the problem?

(Vanilla Don't Starve Reign of Giants, no mods enabled)

 

Original Post:

My deciduous trees remain leafless after triggering Autumn with the console command (during Winter):

GetSeasonManager():StartAutumn()

Triggering Spring does not fix my deciduous trees.

My question is how do I remotely manage or change the "leafiness" of deciduous trees in my world?

I'm assuming that I can do that with a console command.

(This issue occurred to me in in Single player Don't Starve RoG, I haven't checked if it also occurs in DST.)

Also, which .lua file contains the deciduoustree prefab? Since there exists no deciduoustree.lua or acorn.lua inside \data\scripts\prefabs.

Edited by Gnosis
Link to comment
Share on other sites

What has

dont_starve\data\DLC0001\scripts\prefabs\deciduoustrees.lua

ever done to you to deserve to be ignored like this? :)

It has all the information and functions you'll need to solve this problem. Do ask any questions, though.

I may have misunderstood you about whether you're looking for help with DS or DST, but the same file exists in the DST prefab folder.

Link to comment
Share on other sites

1 hour ago, Ultroman said:

What has


dont_starve\data\DLC0001\scripts\prefabs\deciduoustrees.lua

ever done to you to deserve to be ignored like this? :)

It has all the information and functions you'll need to solve this problem. Do ask any questions, though.

I may have misunderstood you about whether you're looking for help with DS or DST, but the same file exists in the DST prefab folder.

Thanks for the answer. It must have murder 3 puppies of mine in its previous incarnation because I don't know how I missed that.

Unfortunately I'm not a programmer, so I don't know how to utilize this information in a console command.

local function OnSeasonChange(inst, season)
    if season == SEASONS.AUTUMN then
        inst.target_leaf_state = "colorful"
    elseif season == SEASONS.WINTER then
        inst.target_leaf_state = "barren"
    else --SPRING AND SUMMER
        inst.target_leaf_state = "normal"
    end

    if inst.target_leaf_state ~= inst.leaf_state then
        local time = math.random(TUNING.MIN_LEAF_CHANGE_TIME, TUNING.MAX_LEAF_CHANGE_TIME)
        inst.targetleaveschangetime = GetTime() + time
        inst.leaveschangetask = inst:DoTaskInTime(time, OnChangeLeaves)
    end
end

 

Link to comment
Share on other sites

6 minutes ago, Ultroman said:

You should probably check whether the problem even occurs in DST first. The season system is very different.

It actually wouldn't be an issue for me if the command only works in DS. I'm used to using a lot of mods when I play DST so I have it set up very differently and a lot more conveniently when I want to build creatively (so I would never encounter this problem in the first place). The mod selection screen takes forever to load in DS and is really inconvenient, so I've decided to just use the unmodded game and console commands this time for DS.

I've tried this sending through the console and a few other possibilities my non-programmer brain could conjure up.

for k,v in pairs(Ents) do if v.prefab == "deciduoustree" then v.target_leaf_state = "colorful"

But but as far as I can see, I've failed.

Link to comment
Share on other sites

From the code, it seems like in DST they react to season changes by watching the world state continuously. In DS - RoG, however, their concept of which season it is, is set directly on them the second they start growing, and is changed at every change of day. The problem is, they detect whether the season is within its last 10%, and if so, the season is changed for the tree. Since you change it to be autumn instantly, autumn has started immediately, and is NOT in its last 10%, so the trees don't react to the change. I think it'll work just fine, if you just skip, like 5 days at a time, or skip to summer first and then skip 2-3 days at a time until it becomes autumn.

There is probably an elaborate console command to run through all the deciduoustree prefabs and call OnSeasonChange on them, where you'd be able to pass in the inst and the proper season. I can try to find out.

Link to comment
Share on other sites

1 minute ago, Ultroman said:

From the code, it seems like in DST they react to season changes by watching the world state continuously. In DS - RoG, however, their concept of which season it is, is set directly on them the second they start growing, and is changed at every change of day. The problem is, they detect whether the season is within its last 10%, and if so, the season is changed for the tree. Since you change it to be autumn instantly, autumn has started immediately, and is NOT in its last 10%, so the trees don't react to the change. I think it'll work just fine, if you just skip, like 5 days at a time, or skip to summer first and then skip 2-3 days at a time until it becomes autumn.

There is probably an elaborate console command to run through all the deciduoustree prefabs and call OnSeasonChange on them, where you'd be able to pass in the inst and the proper season. I can try to find out.

Would that elaborate console command start with something like this?

for k,v in pairs(Ents) do if v.prefab == "deciduoustree" then

 

Link to comment
Share on other sites

for k,v in pairs(Ents) do if v.prefab == "deciduoustree" then v:OnSeasonChange(v, "autumn") end end

 

Oops, almost forgot the "end", there. Pretty important

I think that should work for DS - RoG

Actually forgot the second "end" as well ^^ That should do it.

Edited by Ultroman
Link to comment
Share on other sites

11 minutes ago, Ultroman said:

for k,v in pairs(Ents) do if v.prefab == "deciduoustree" then v:OnSeasonChange(v, "autumn") end end

 

Oops, almost forgot the "end", there. Pretty important

I think that should work for DS - RoG

Actually forgot the second "end" as well ^^ That should do it.

Hey thanks for the help, I was wondering why it gave me "attempt to call a nil value".

I then sent the command with the two "end"s, and the log gave me "attempt to call method 'OnSeasonChange' (a nil value)".

Any ideas?

I also tried 

for k,v in pairs(Ents) do if v.prefab == "deciduoustree" then v.target_leaf_state = "colorful" end end

That didn't give me "attempt to call a nil value", but nothing happened in-game, the trees didn't grow leaves.

Edited by Gnosis
Link to comment
Share on other sites

Ah, crap. I'm sorry, m8. OnSeasonChange is a local function. You can't access it...hmm...

for k,inst in pairs(Ents) do if inst.prefab == "deciduoustree" then
	inst.target_leaf_state = "colorful"
    if inst.target_leaf_state ~= inst.leaf_state then
        local time = math.random(TUNING.MIN_LEAF_CHANGE_TIME, TUNING.MAX_LEAF_CHANGE_TIME)
        inst.targetleaveschangetime = GetTime() + time
        inst.leaveschangetask = inst:DoTaskInTime(time, OnChangeLeaves)
    end
 end end

 

Try this, then xD

Link to comment
Share on other sites

6 minutes ago, Ultroman said:

Ah, crap. I'm sorry, m8. OnSeasonChange is a local function. You can't access it...hmm...


for k,inst in pairs(Ents) do if inst.prefab == "deciduoustree" then
	inst.target_leaf_state = "colorful"
    if inst.target_leaf_state ~= inst.leaf_state then
        local time = math.random(TUNING.MIN_LEAF_CHANGE_TIME, TUNING.MAX_LEAF_CHANGE_TIME)
        inst.targetleaveschangetime = GetTime() + time
        inst.leaveschangetask = inst:DoTaskInTime(time, OnChangeLeaves)
    end
 end end

 

Try this, then xD

Thanks, that seems like quite a handful just to change some trees lol

Unfortunately OnChangeLeaves is also a local function so the game gave me "variable 'OnChangeLeaves' is not declared'.

This is getting a bit troublesome, so I really appreciate your time.

Link to comment
Share on other sites

The unfortunate thing is that for whatever reason, I left Wild Fires On in my world configuration when I made my world since I wanted the base RoG game as it is. I usually have it off in DST when building is my primary thing. And unlike DST, the saveindex and save files for DS are long strings of numbers and letters, so I can't change a true/false value in the saveindex file to get rid of it like I can if I was playing DST.

Link to comment
Share on other sites

Try this stupid concoction xD

for k,inst in pairs(Ents)
do
	if inst.prefab == "deciduoustree" then
		local function MyGetBuild(inst)
			local build = builds[inst.build]
			if build == nil then
				return builds["normal"]
			end
			return build
		end

		local function MyGrowLeavesFn(inst, monster, monsterout)
			if inst:HasTag("stump") or inst:HasTag("burnt") or inst:HasTag("fire") then 
				inst:RemoveEventCallback("animover", MyGrowLeavesFn)
				return
			end

			if inst.leaf_state == "barren" or inst.target_leaf_state == "barren" then 
				inst:RemoveEventCallback("animover", MyGrowLeavesFn)
				if inst.target_leaf_state == "barren" then inst.build = "barren" end
			end

			if MyGetBuild(inst).leavesbuild then
				inst.AnimState:OverrideSymbol("swap_leaves", MyGetBuild(inst).leavesbuild, "swap_leaves")
			else
				inst.AnimState:ClearOverrideSymbol("swap_leaves")
			end

			if inst.components.growable then
				if inst.components.growable.stage == 1 then
					inst.components.lootdropper:SetLoot(MyGetBuild(inst).short_loot)
				elseif inst.components.growable.stage == 2 then
					inst.components.lootdropper:SetLoot(MyGetBuild(inst).normal_loot)
				else
					inst.components.lootdropper:SetLoot(MyGetBuild(inst).tall_loot)
				end
			end

			inst.leaf_state = inst.target_leaf_state
			if inst.leaf_state == "barren" then
				inst.AnimState:Hide("mouseover")
			else
				if inst.build == "barren" then
					inst.build = (inst.leaf_state == "normal") and "normal" or "red"
				end
				inst.AnimState:Show("mouseover")
			end

			if not monster and not monsterout then Sway(inst) end
		end

		local function MyOnChangeLeaves(inst, monster, monsterout)
			if inst:HasTag("stump") or inst:HasTag("burnt") or inst:HasTag("fire") then 
				inst.targetleaveschangetime = nil
				inst.leaveschangetask = nil
				return
			end
			if not monster and inst.components.workable and inst.components.workable.lastworktime and inst.components.workable.lastworktime < GetTime() - 10 then
				inst.targetleaveschangetime = GetTime() + 11
				inst.leaveschangetask = inst:DoTaskInTime(11, OnChangeLeaves)
				return
			else
				inst.targetleaveschangetime = nil
				inst.leaveschangetask = nil
			end

			if inst.target_leaf_state ~= "barren" then
				if inst.target_leaf_state == "colorful" then
					local rand = math.random()
					if rand < .33 then
						inst.build = "red"
					elseif rand < .67 then
						inst.build = "orange"
					else
						inst.build = "yellow"
					end
					inst.AnimState:SetMultColour(1, 1, 1, 1)
				elseif inst.target_leaf_state == "poison" then
					inst.AnimState:SetMultColour(1, 1, 1, 1)
					inst.build = "poison"
				else
					inst.AnimState:SetMultColour(inst.color, inst.color, inst.color, 1)
					inst.build = "normal"
				end

				if inst.leaf_state == "barren" then
					if MyGetBuild(inst).leavesbuild then
						inst.AnimState:OverrideSymbol("swap_leaves", MyGetBuild(inst).leavesbuild, "swap_leaves")
					else
						inst.AnimState:ClearOverrideSymbol("swap_leaves")
					end
					inst.AnimState:PlayAnimation(inst.anims.growleaves)
					inst.SoundEmitter:PlaySound("dontstarve/forest/treeGrow")
					inst:ListenForEvent("animover", MyGrowLeavesFn)
				else
					MyGrowLeavesFn(inst, monster, monsterout)
				end
			else
				inst.AnimState:PlayAnimation(inst.anims.dropleaves)
				SpawnLeafFX(inst, 11*FRAMES)
				inst.SoundEmitter:PlaySound("dontstarve/forest/treeWilt")
				inst:ListenForEvent("animover", MyGrowLeavesFn)
			end
			if MyGetBuild(inst).shelter then
				if not inst:HasTag("shelter") then inst:AddTag("shelter") end
			else
				while inst:HasTag("shelter") do inst:RemoveTag("shelter") end
			end
		end

		inst.target_leaf_state = "colorful"
		if inst.target_leaf_state ~= inst.leaf_state then
			local time = math.random(TUNING.MIN_LEAF_CHANGE_TIME, TUNING.MAX_LEAF_CHANGE_TIME)
			inst.targetleaveschangetime = GetTime() + time
			inst.leaveschangetask = inst:DoTaskInTime(time, MyOnChangeLeaves)
		end
	end
end

 

Changed something...

Edited by Ultroman
Link to comment
Share on other sites

Holy crap.

Um, well, I'd be interesting if that actually worked, but it gave me "attempt to call a nil value".

The thing is, have no clue if the entire code was even sent in the console or if there's some kind of limit? I'm certain I copy and pasted it correctly though, since I copied the entire thing into a text editor and then recopied it from there.

Surely there has to be a simpler way of going about this.

EDIT:

So it still gives me "attempt to call a nil value". Just to make sure, you took the code from deciduoustree.lua from the DS files and not the DST files right?

Edited by Gnosis
Link to comment
Share on other sites

So I backed up my world files and used LongUpdate(17*16*30) multiple times until I cycled through a whole in-game year.

But my barren trees have not updated to become leafy.

Do you have any clue what could be wrong?

Oh god, and the eye-plants everywhere. Well, I'm going to switch this world back to the backup anyways, but yeah.

Edited by Gnosis
Link to comment
Share on other sites

17 is a lot of days. Remember, you have to hit a day in the last 10% of summer AND then wait for the day to end.

It only triggers the check for whether you are at the last 10% of summer when a day ends.

Oops...meant the last 10% of summer. I corrected it.

Edited by Ultroman
Link to comment
Share on other sites

45 minutes ago, Ultroman said:

17 is a lot of days. Remember, you have to hit a day in the last 10% of summer AND then wait for the day to end.

It only triggers the check for whether you are at the last 10% of summer when a day ends.

Oops...meant the last 10% of summer. I corrected it.

Would my deciduous trees still update if I went far away from my base or into the caves, send StartSummer, and then wait for Summer to end (Autumn to start "naturally"), then moved back to my base?

I can't stay in my base as it'll burn from wild fires, I'd need a large number of flingomatics which would be troublesome to manage, since my base is relatively large. Would the trees in my base area still update if I was far away? I'm assuming they won't update, since I think I found deciduous trees in the other deciduous biome to still have leaves, which is extremely unfortunate.

I mean, I suppose I could first place all the flingomatics, send StartSummer, then send LongUpdate(14*16*30), since the Flingomatics won't need to be refilled.

Does that sound like a good and feasible solution?

I could then remove all the flingomatics afterwards and make sure to always send StartAutumn before Winter starts so the trees never lose their leaves.

Edited by Gnosis
Link to comment
Share on other sites

They should still update. Not sure, though.

It's quite a problem, really. It won't even be easy to fix by making a mod for it. Not unless you're OK with the mod being incompatible with other mods which make changes to deciduous trees. The code is written in a very unmoddable way (if I'm reading it correctly). But you could technically make a mod just for yourself, which changes the deciduous trees to either update more frequently, of always be leafy.

If that's something you want to do, I can help you with that.

Link to comment
Share on other sites

I see, that's honestly pretty odd.

Thank you spending so much time trying to help me.

I'll wait until tomorrow to see about what I should do since it's getting quite late where I am.

I didn't notice all the natural trees were bugged until I actually had to use trees for part of the build. I'm definitely gonna go back to DST once I'm done reminiscing with the base game and messing around with Hamlet. I've encountered so many odd problems with single-player Don't Starve; if I'm perfectly honest it seems like a neglected game.

I sent you a couple of screenshots of completed parts of the build I'm doing if you like that sort of thing.

Link to comment
Share on other sites

Hey @Ultroman, thanks for all the help. Managed to solve problem by sending in the console GetSeasonManager():StartSummer() and then LongUpdate(14*16*30) to skip to the last day of Summer (No Flingomatics were needed since wildfires only start occurring a few days into Summer and never occur on the first or last day). Had no clue the behavior of trees were like this, it would make a lot more sense if they actually updated upon season change.

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