Jump to content

NEED POSTINIT HELP, Need to add a timer timer in already existing prefab functions.


Recommended Posts

I'm trying to edit the Toadstool_cap.lua prefab, and I need to add these lines in these functions:

local function ongrown(inst)
    inst:RemoveEventCallback("animover", ongrown)
    inst.MiniMapEntity:SetIcon(inst._dark:value() and "toadstool_cap_dark.png" or "toadstool_cap.png")
    inst.AnimState:PlayAnimation("mushroom_toad_idle_loop", true)
    inst:AddComponent("workable")
    inst.components.workable:SetWorkLeft(3)
    inst.components.workable:SetOnWorkCallback(onworked)
    inst.components.workable:SetOnFinishCallback(onworkfinished)

inst.components.timer:StartTimer("growsprouts", 1440)
end

AND

local function onspawntoad(inst)
    inst:RemoveEventCallback("animover", onspawntoad)
    inst.SoundEmitter:PlaySound("dontstarve/common/mushroom_up")

    local toadstool = SpawnPrefab(inst._dark:value() and "toadstool_dark" or "toadstool")
    inst.components.entitytracker:TrackEntity("toadstool", toadstool)
    tracktoad(inst, toadstool)
    setstate(inst, 0)

    toadstool.Transform:SetPosition(inst.Transform:GetWorldPosition())
    toadstool.sg:GoToState("surface")
inst.components.timer:StopTimer("growsprouts", 1440)
end

 

When putting this all in the toadstool_cap prefab it starts and stops properly, however, I need to get this same code into a postinit, to which I tried

 

local function onspawntoad(inst)
    inst.components.timer:StopTimer("growsprouts")

print("stop timer")
end


local function ongrown(inst)
    inst.components.timer:StartTimer("growsprouts", 1440)

print("start timer")
end


local function ongrowsproutsdone(inst, data)
    if data.name == "growsprouts" and GLOBAL.TheWorld.state.isautumn and GLOBAL.TheWorld.state.cycles > 70 then
        inst.components.sinkholespawner:StartSinkholes()
        inst.components.timer:StartTimer("growsprouts", 1440)
        print("MUSHROOMS START")
    else
        inst.components.timer:StartTimer("growsprouts", 1440)
        print("MUSHROOMS GO HOME")
    end
end

AddPrefabPostInit("toadstool_cap", onspawntoad, ongrown, ongrowsproutsdone)
AddPrefabPostInit("toadstool_cap", function (inst)
        inst:AddComponent("sinkholespawner")
    inst:ListenForEvent("timerdone", ongrowsproutsdone)
end)

 

 

However, the onspawntoad(inst) and ongrown(inst) seem to be absolutely ignored, and it starts reaching into the "ongrowsprouts" function despite not being called to.

Upon starting the world, the first print("stop timer") appears in the client_log, but never appears again, regardless of what I do in game.

I hope this makes ANY kind of sense, because I have no clue how to work postinit's properly, and after 4 days I can't get any **** to work no matter what I do.

Edited by Ogrecakes
Link to comment
Share on other sites

AddPrefabPostInit("toadstool_cap", onspawntoad, ongrown, ongrowsproutsdone)
you are the second one within few days that is using this strange code. Where did you see this and why do you think this will do anyhting useful?

Looking in modutil.lua, you see that AddPrefabPostInit only accepts the prefab and ONE function, not three.
And your assumption, using a name here of a function that already exists, will overwrite it, is also wrong. So forget this code.

Only your second code for AddprefabPostinit is the correct one.
And the code written within will be executed like the common/master postitnit of a prefab.
To overwrite existing functions, you have to directly tell the code to do so.
So in case this ongrown is safed within inst, so in case you see within toadstool script "inst.ongrown = ongrown" or sth like this. Then this means you can access and change ongrown via inst. So you put into your function that is called by AddPrefabostInit "inst.ongrown = yourfunction".
But of course you dont want to overwrite it completely, since every game update could change the code and makes your mod incompatible. So instead you willl save the old function and call it at the end or beginning of your new function. so sth like this:

local old_ongrown = inst.ongrown
inst.ongrown = function(a,b,c,...)
    local oldreturn = old_ongrown~=nil and old_ongrown(a,b,c,...) or nil -- call the original function first (or last if you want)
    -- your code to start/stop timer
    return oldreturn
end


BUT, as you see in Toadstool_cap.lua , the ongrown function is unfortunately not saved within inst. So we can not access or change it this way. And since it is a local function, it looks like you need the upvaluehacker.
https://github.com/rezecib/Rezecib-s-Rebalance/blob/master/scripts/tools/upvaluehacker.lua

But we should first see if there is really no other way to achieve the same result.
When exactly do you want your timer to start. Looking at the code we see that there is an event pushed "inst:PushEvent("toadstoolstatechanged", state)". Maybe it is enough to listen for this event, and depending on the state start/stop your timer?
With this event you at least have kind of access to ongrowing. And from there you also could listen for animover to get called directly after ongrown is called. And after ongrown you have the workable component that might fire an event onworkfinished (within workable component).
So it is not that easy, maybe the upvalue hacker is the better choice.

But I dont know why you need to start/stop this new timer. Maybe there is another way to achieve the same. Only you know that.

Edited by Serpens
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...