loopuleasa Posted October 10, 2019 Share Posted October 10, 2019 Hi, I am doing a change in birdcage.lua Is it possible to import the functions from the original birdcage.lua, or even call the original ones in my AddPrefabPostInit I do not wish to copy over literally 7 functions for my change. local function DigestFood(inst, food) if food == nil then return false end if food.components.edible.foodtype == GLOBAL.FOODTYPE.MEAT then --If the food is meat: --Spawn an egg. inst.components.lootdropper:SpawnLootPrefab("bird_egg") else local seed_name = string.lower(food.prefab .. "_seeds") if Prefabs[seed_name] ~= nil then --If the food has a relavent seed type: --Spawn 1 or 2 of those seeds. local num_seeds = math.random(2) for k = 1, num_seeds do inst.components.lootdropper:SpawnLootPrefab(seed_name) end --Spawn regular seeds on a 50% chance. if math.random() < 0.5 then inst.components.lootdropper:SpawnLootPrefab("seeds") end else --Otherwise... --Spawn a poop 1/3 times. if math.random() < 0.33 then local loot = inst.components.lootdropper:SpawnLootPrefab("guano") loot.Transform:SetScale(.33, .33, .33) end end end --Refill bird stomach. local bird = GetBird(inst) if bird and bird:IsValid() and bird.components.perishable then bird.components.perishable:SetPercent(1) --TODO:Bird dies if too much mmeat is given if food.components.edible.foodtype == GLOBAL.FOODTYPE.MEAT and food.components.edible:GetHealth(inst) < 0 then --monster meat is currently the only negative health meat item if bird.monsterbelly ~= nil and bird.monsterbelly ~= 0 then bird.monsterbelly = bird.monsterbelly+1 else bird.monsterbelly = 1 end print(bird.monsterbelly ) if bird.monsterbelly >= 4 then --OnBirdStarve(inst, bird) inst.AnimState:PlayAnimation("death") --PushStateAnim(inst, "idle", false) --Put loot on "shelf" local loot = SpawnPrefab("smallmeat") inst.components.inventory:GiveItem(loot) inst.components.shelf:PutItemOnShelf(loot) end end end end Link to comment Share on other sites More sharing options...
Serpens Posted October 10, 2019 Share Posted October 10, 2019 (edited) what functions exactly you want to change? All non-local functions can be accessed in AddPrefabPostInit. And most local functions can be accessed with the upvaluehacker IF you really need to access the local (in 90% of the cases there are better ways to achieve the same result) https://github.com/rezecib/Rezecib-s-Rebalance/blob/master/scripts/tools/upvaluehacker.lua so you should NOT replace birdcage.lua, but do all changes within modmain. Edited October 10, 2019 by Serpens Link to comment Share on other sites More sharing options...
loopuleasa Posted October 10, 2019 Author Share Posted October 10, 2019 8 minutes ago, Serpens said: what functions exactly you want to change? All non-local functions can be accessed in AddPrefabPostInit. And most local functions can be accessed with the upvaluehacker IF you really need to access the local (in 90% of the cases there are better ways to achieve the same result) https://github.com/rezecib/Rezecib-s-Rebalance/blob/master/scripts/tools/upvaluehacker.lua so you should NOT replace birdcage.lua, but do all changes within modmain. the functions seem to be local I just want to do a small change down a stack of 3-4 local functions can check the upvalue, no other way? 19 minutes ago, Serpens said: what functions exactly you want to change? All non-local functions can be accessed in AddPrefabPostInit. And most local functions can be accessed with the upvaluehacker IF you really need to access the local (in 90% of the cases there are better ways to achieve the same result) https://github.com/rezecib/Rezecib-s-Rebalance/blob/master/scripts/tools/upvaluehacker.lua so you should NOT replace birdcage.lua, but do all changes within modmain. For example, here is my full change (makes bird die after being fed 4 monster meat) It ended up being huge, and I copied over most things ----------------------------------------------------------------- -- Bird dies if fed too much monster meat ----------------------------------------------------------------- --TODO: Shorten functions here, and overwrite only (maybe use upvalue hacker) local function OnBirdStarve(inst, bird) if inst.AnimationTask then inst.AnimationTask:Cancel() inst.AnimationTask = nil end inst.CAGE_STATE = "_death" inst.AnimState:PlayAnimation("death") inst.AnimState:PushAnimation("idle"..inst.CAGE_STATE, false) --PushStateAnim(inst, "idle", false) --Put loot on "shelf" local loot = GLOBAL.SpawnPrefab("smallmeat") inst.components.inventory:GiveItem(loot) inst.components.shelf:PutItemOnShelf(loot) end local function DigestFood(inst, food) if food == nil then return false end if food.components.edible.foodtype == GLOBAL.FOODTYPE.MEAT then --If the food is meat: --Spawn an egg. inst.components.lootdropper:SpawnLootPrefab("bird_egg") else local seed_name = string.lower(food.prefab .. "_seeds") if Prefabs[seed_name] ~= nil then --If the food has a relavent seed type: --Spawn 1 or 2 of those seeds. local num_seeds = math.random(2) for k = 1, num_seeds do inst.components.lootdropper:SpawnLootPrefab(seed_name) end --Spawn regular seeds on a 50% chance. if math.random() < 0.5 then inst.components.lootdropper:SpawnLootPrefab("seeds") end else --Otherwise... --Spawn a poop 1/3 times. if math.random() < 0.33 then local loot = inst.components.lootdropper:SpawnLootPrefab("guano") loot.Transform:SetScale(.33, .33, .33) end end end --Refill bird stomach. local bird = (inst.components.occupiable and inst.components.occupiable:GetOccupant()) or nil if bird and bird:IsValid() and bird.components.perishable then bird.components.perishable:SetPercent(1) --TODO:Bird dies if too much mmeat is given if food.components.edible.foodtype == GLOBAL.FOODTYPE.MEAT and food.components.edible:GetHealth(inst) < 0 then --monster meat is currently the only negative health meat item if bird.monsterbelly ~= nil and bird.monsterbelly ~= 0 then bird.monsterbelly = bird.monsterbelly+1 else bird.monsterbelly = 1 end print(bird.monsterbelly ) if bird.monsterbelly >= 4 then OnBirdStarve(inst, bird) end end end end local function OnGetItem(inst, giver, item) --If you're sleeping, wake up. if inst.components.sleeper and inst.components.sleeper:IsAsleep() then inst.components.sleeper:WakeUp() end if item~=nil and item.components.edible ~= nil and item.components.edible.foodtype ~= nil and ( item.components.edible.foodtype == GLOBAL.FOODTYPE.MEAT or item.prefab == "seeds" or Prefabs[string.lower(item.prefab .. "_seeds")] ~= nil ) then --If the item is edible... --Play some animations (peck, peck, peck, hop, idle) inst.AnimState:PlayAnimation("peck") inst.AnimState:PushAnimation("peck") inst.AnimState:PushAnimation("peck") inst.AnimState:PushAnimation("hop") inst.AnimState:PushAnimation("idle"..inst.CAGE_STATE, true) --Digest Food in 60 frames. inst:DoTaskInTime(60 * GLOBAL.FRAMES, DigestFood, item) end end AddPrefabPostInit("birdcage", DigestFood, OnGetItem, OnBirdStarve) AddPrefabPostInit("birdcage", function (inst) if inst ~= nil and inst.components.trader ~= nil then inst.components.trader.onaccept = OnGetItem end end) Link to comment Share on other sites More sharing options...
Serpens Posted October 11, 2019 Share Posted October 11, 2019 (edited) never saw such code: AddPrefabPostInit("birdcage", DigestFood, OnGetItem, OnBirdStarve) what does it? Is it already overwriting the original functions? Or just adding them only accessable by you? Or is this code wrong and not working (because it adds random functins that are not accessable by anyone) Anyway, if I wanted to make the birds die after eating too much monstermeat I would simply go into OnGetItem (like you more or less did), but not overwrite the function, only add code. AddPrefabPostInit("birdcage", function (inst) if inst ~= nil and inst.components.trader ~= nil then local old_onaccept = inst.components.trader.onaccept inst.components.trader.onaccept = function(inst, giver, item,...) old_onaccept(inst,giver,item,...) -- and now check if it was monster meat and do your stuff, maybe with a small DoTaskInTime delay to make sure the bird finished eating. end end end) only small problem is that you can not call the local OnBirdStarve this way. So you have 2 possibilites: 1) Write your own one that is only called when birds dies by monstermeat (this way if your mod breaks, only this death will crash) 2) Use upvaluehacker to get this function and call it. It mostly depends if you want to change OnBirdStarve. your code above changes it, but I dont see why this is neccessary? You want to play a different death animation? Do you want it only for the monstermeat death? Then use 1). Edited October 11, 2019 by Serpens Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now