Jump to content

Mod for Birdcage Feeder - overriding onoccupied issue


Recommended Posts

I've been doing a bit of modding on Don't Starve, first encounter with LUA. 

 

Anyways, adding a "bird feeder" to the birdcage, and one of the things I wanted to do was to add a PrefabPostInit which replaces the inst.component.occupiable.onoccupied with my own. Then what I did was store the old onoccupied (as inst.component.occupiable.old_onoccupied) and called it as the first line of my new one.

 

However, this seemed to break the animations of the birdcage. It would still register as occupied (or unoccupied) but the old_onoccupied wouldn't seem to execute correctly (despite definitely being triggered and executing). No bird would show up, I could feed the birdcage but nothing would happen if I did.

 

I was trying to override the onoccupied in order to avoid simply copying all the birdcage code into a new file and completely overwriting the prefab. However it seems like that may not be possible...?

 

Anyone know what could be gumming it up? Is it failing because there are local art assets in the birdcage.lua file that were not in modmain.lua file?

Link to comment
Share on other sites

--[[ LongLiveTheBird -- by RivenwyrmRemove RoG's finite bird lifetime--]] local function GotItem(inst, giver, item)  print("GotItem")  local stocked = false    if item.components.perishable and item.components.edible then    print("gi1" .. tostring(inst.components.occupiable.occupant.components.perishable:GetPercent()))    -- If food is fresh and bird is not very hungry, stock item    if inst.components.occupiable.occupant.components.perishable:GetPercent() > .9 then      print("gi2")      if item.components.perishable:IsFresh() then        print("gi3")        local seed_name = string.lower(item.prefab .. "_seeds")        local is_seed = Prefabs[seed_name] or item.prefab == "seeds"        if is_seed and inst.stockedseeds < 20 then          print("gi4")          inst.stockedseeds = inst.stockedseeds + 1          print("stocked seed " .. inst.stockedseeds)          stocked = true        end      end    end        if not stocked then      print("Old_onaccept, stocked seeds" .. inst.stockedseeds)      -- Call the old code instead      inst:old_onaccept(inst, giver, item)    end  end  print("Fin_GotItem")endlocal function EmptiedOfBird(inst, bird)    print("Emptied")		inst.updatetask:Cancel()    inst.updatetask = nil    inst:old_onemptied(inst, bird)endlocal function OccupiedWithBird(inst, bird)    print("Occupied")        inst:old_onoccupied(inst, bird)    local idling = tostring(inst.idletask ~= nil)    print("idling " .. idling)        if bird.components.perishable:GetPercent() < .90 and inst.stockedseeds > 0 then      print("Bring bird to full")      inst.components.occupiable.occupant.components.perishable:SetPercent(1)      inst.stockedseeds = inst.stockedseeds - 1    end    --local delay = bird.components.perishable.perishtime * .90    local delay = 5    inst.updatetask = inst:DoPeriodicTask(.1, PeriodicFeedBird, .1, inst)    local update = tostring(inst.updatetask ~= nil)    print("update " .. update)endlocal function PeriodicFeedBird(inst)    print("PeriodicFeedBird")    if inst.stockedseeds > 0 then      -- Should be unnecessary, can't hurt      if inst.components.occupiable.occupant then        -- Secondary guard against over feeding, timing of update task is first guard        if inst.components.occupiable.occupant.components.perishable:IsStale() then          print("Bird was fed")          inst.components.occupiable.occupant.components.perishable:SetPercent(1)          inst.stockedseeds = inst.stockedseeds - 1        end      end      endendlocal function PrefabAddBirdFeeder(inst)  -- Rejigger the mainsail  inst.old_onaccept = inst.components.trader.onaccept  inst.components.trader.onaccept = GotItem  inst.old_onoccupied = inst.components.occupiable.onoccupied  inst.components.occupiable.onoccupied = OccupiedWithBird  inst.old_onemptied = inst.components.occupiable.onemptied  inst.components.occupiable.onemptied = EmptiedOfBird  inst.stockedseeds = 0  print("prefab birds")endAddPrefabPostInit("birdcage", PrefabAddBirdFeeder)

Codes!

Link to comment
Share on other sites

You're using the foo:bar() syntax incorrectly when calling the saved functions. These two lines of code are functionally identical; the top one is simply a shortcut for the bottom one:

x:fn()x.fn(x)
In the top one, the first parameter is implied, and gets set to the object that the function is being called from. So, when you do:

inst:old_onoccupied(inst, bird)
What's actually happening is this:

inst.old_onoccupied(inst, inst, bird)
so the saved component function is being called with the prefab object (inst) as the 'self' parameter (the name of the implied first parameter) when it is expecting the component object.

To fix it, you'd want to call the saved component functions like so:

inst.old_onoccupied(self, inst, bird)
Link to comment
Share on other sites

To fix it, you'd want to call the saved component functions like so:

inst.old_onoccupied(self, inst, bird)

 

Hmmm, you were definitely on the right track, although this appears to have been the right syntax:

inst.old_onoccupied(inst, bird)

Thanks much

Link to comment
Share on other sites

Hmmm, you were definitely on the right track, although this appears to have been the right syntax:

inst.old_onoccupied(inst, bird)
Thanks much
Ah, you're right. For some reason, I thought you were overriding a component member function, not a callback function. If you were overriding inst.components.occupiable.Occupy, for example, then the syntax I posted would have been correct (see the 'require' section of Code Tips and Tricks for more information about overriding component member functions).
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

Please be aware that the content of this thread may be outdated and no longer applicable.

×
  • Create New...