Jump to content

Recommended Posts

@Deicon
Basically I have a tent that 'melts' when it's not winter.  It uses finite uses to count down until it should break.  Eventually I noticed that even when burnt, the structure was still counting down and breaking, so I made I made it stop counting down and it worked.  Trouble is, I realized it was still counting, so it was just counting down, forever.  I want to stop it doing that.

I added "inst.task:Cancel()" inside the 'notwinter' task, but it doesn't seem to have worked, although the mod didn't crash.  Do I need to specify what periodic task I want to stop?

Edited by FurryEskimo

I name my tasks when I want to interrupt them. For example: "inst.'taskname' = inst:DoPeriodicTask (time, function () ... end)" and when I want to cancel: "inst.'taskname':Cancel()"
This way has worked for me. I started modding a little while ago, so I won't be able to help you much.

  • Thanks 1
  • Health 1

@Deicon
How strange.  I did "inst.task = inst:DoPeriodicTask(1, notwinter)" which would imply I use "inst.task:Cancel()" to stop it, but that hasn't seem to have worked.

I appreciate the help.  Hopefully someone will know how to stop a periodic task.  I can't find any forum posts about how to do it.

  • Like 1

yes, they are right.
So you have to make sure that you save the task into a persistent variable, to be able to cancel it later.
With "inst.task" you are saving it into inst, while inst is usueally the instance of the object, so your tent.
When you try to cancel it, make sure "inst" is still the very same object and the task is still saved in inst.task. Then you can cancel it it.

But when you restart the server, this task is deleted and eventually restarted on startup (depending on where you put the code), so make sure you don't restart this task if eg. the object is burnt or sth like this.

Edited by Serpens
  • Like 1

@penguin0616 @Serpens
I'm not sure what I might be going wrong.  From what I can tell, this function should run (I'm in autumn) and then stop itself, but it doesn't.

local function notwinter(inst)  --If the den isn't burnt and it's not winter, continue using the ice den's finite uses.
	if not inst:HasTag("burnt") then
		if inst.components.burnable ~= nil and inst.components.burnable:IsBurning() then
			inst.components.finiteuses:Use(8)  --Tent melts when on fire. (x / 2,500 * 100 = ~0.32%)
		else

			if not TheWorld.state.iswinter then
				inst.components.finiteuses:Use(1)  --Rate of ice den melting when not winter.
				if TheWorld.state.issummer then
					inst.components.finiteuses:Use(1)  --Added rate of ice den melting in summer.

					inst.task:Cancel()  --Note: HERE is where I expect to make the task to stop being called.
				end
			end

			if TheWorld.state.israining then  --Sometimes rains in the caves too, but I'm not sure how to check for that condition.
				inst.components.finiteuses:Use(0.5)  --Ice den melts when it rains, even in the winter. (This only happens if the map's settings have been changed.)
				if TheWorld:HasTag("cave") and not TheWorld.state.isspring then
					inst.components.finiteuses:Use(-0.5)  --Ice den is protected from rain if in a cave, expect in spring, when it frequently rains in the caves.
				end
			end

			if TheWorld.state.issnowing and not TheWorld:HasTag("cave") and inst.components.finiteuses:GetUses() < 2400 then
				local maxuses = 2400 + math.random(1,360)
				inst.components.finiteuses:SetMaxUses(maxuses)  --Test code.
				inst.components.finiteuses:SetUses(maxuses)
			end
		end
	else
		--Note: If the ice den is burnt, stop doing this periodic task.
	--	Stopnotwinter(inst)  --Note: Currently crashes the game.
	inst.task:Cancel()
	end
end

------------------------------------------------------------
[ In local function ice_den() ]

inst.task = inst:DoPeriodicTask(1, notwinter)

Edited by FurryEskimo
6 minutes ago, FurryEskimo said:

@penguin0616 @Serpens
I'm not sure what I might be going wrong.  From what I can tell, this function should run (I'm in autumn) and then stop itself, but it doesn't.


local function notwinter(inst)  --If the den isn't burnt and it's not winter, continue using the ice den's finite uses.
    if not inst:HasTag("burnt") then
        if inst.components.burnable ~= nil and inst.components.burnable:IsBurning() then
            inst.components.finiteuses:Use(8)  --Tent melts when on fire. (x / 2,500 * 100 = ~0.32%)
        else

            if not TheWorld.state.iswinter then
                inst.components.finiteuses:Use(1)  --Rate of ice den melting when not winter.
                if TheWorld.state.issummer then
                    inst.components.finiteuses:Use(1)  --Added rate of ice den melting in summer.

                    inst.task:Cancel()  --Note: Test code, remove
                end
            end

            if TheWorld.state.israining then  --Sometimes rains in the caves too, but I'm not sure how to check for that condition.
                inst.components.finiteuses:Use(0.5)  --Ice den melts when it rains, even in the winter. (This only happens if the map's settings have been changed.)
                if TheWorld:HasTag("cave") and not TheWorld.state.isspring then
                    inst.components.finiteuses:Use(-0.5)  --Ice den is protected from rain if in a cave, expect in spring, when it frequently rains in the caves.
                end
            end

            if TheWorld.state.issnowing and not TheWorld:HasTag("cave") and inst.components.finiteuses:GetUses() < 2400 then
                local maxuses = 2400 + math.random(1,360)
                inst.components.finiteuses:SetMaxUses(maxuses)  --Test code.
                inst.components.finiteuses:SetUses(maxuses)
            end
        end
    else
        --Note: If the ice den is burnt, stop doing this periodic task.
    --    Stopnotwinter(inst)  --Note: Currently crashes the game.
    inst.task:Cancel()
    end
end

------------------------------------------------------------
[ In local function ice_den() ]

inst.task = inst:DoPeriodicTask(1, notwinter)

 

there are code tags, use them (I added it to the quote so I'm able to read the code)
(I will try to find the problem and write again here, may take an hour, because I'm currently doing sth else)

Edited by Serpens

hm... not sure, but it also depends heavily on the code where you are doing "inst.task = ..."
And also not sure if you can cancel a task while executing the function from the task...
Maybe this is executed several times, so after you cancel the task, it gets started again.

You should add several print("...") stuff in your code and see the logfile what is printed and what not and how often to find out if the code is executed like you expect.

You can also use "inst:WatchWorldState(...)" to be notified when eg. the season changes. But not sure if this helps.

Edited by Serpens
  • Like 1

Got it!  "inst.task:Cancel()" is correct, but in my test I accidentally put it in the condition for summer.  The nested conditions can be a little confusing, but it was the most effective way I knew to do it.  Anyways, thanks so much!  It seems to be working now!

  • Like 1
13 minutes ago, FurryEskimo said:

Got it!  "inst.task:Cancel()" is correct, but in my test I accidentally put it in the condition for summer.  The nested conditions can be a little confusing, but it was the most effective way I knew to do it.  Anyways, thanks so much!  It seems to be working now!

great :) adding some debug prints always helps to find such things out.

Maybe think about increasing the period from PeriodicTask, eg. to 10 and then increase all other values by factor 10. Just to reduce the load on the server. One single of such dent wont be noticable, but who know what other mods are installed and if someone will spawn hundreds of them. So increasing it to 10 will be better, if possible.
 

Originally I did consider this, and it's true, spawning hundreds of this structure could be a real issue, but frankly, I don't expect that to happen, and if someone cheat that many tents in, well, they're basically trying to break their game.  The ice dent automatically breaks itself most of the time after a few days, unless it's built in the winter, and so the real question is, how many of these structures can/will be built on a server, over the course of a single winter?  Long story short, you're not wrong, but I don't think it'll be a problem unless someone makes it a problem, and if I'm mistaken, I'll change it.

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