ry3bread Posted January 1, 2020 Share Posted January 1, 2020 Hi! I've just completed a character mod (Nicole & Nando) and I'd like to implement interactions between her and Beefalo. Basic friendliness will do the job as a starting point but after doing some research and finding a few threads (found info for similar functionality for bees and frogs) I'm realizing that beefalo are one of the more complex mobs due to their already-complex interactions with players. I've learned that the combat components (IsValidTarget) and modmain.lua (tags) are likely to see changes but this is my first custom behaviour tweak that will require new tags, functions, and component changes in general. I imagine this might involve or conflict with some of the domestication functions in beefalometrics.lua, but those aren't restricted/required on my end. I'll add that I'm a decent coder but new to lua, so bear with me. I haven't posted code but will work at it and update as pointers come in! Any tips or info on how to proceed with this would be so appreciated. For now I really just want her to be able to be around them and shear them without any issue. Thank you for reading! This is a great community. I'm working on a mod tool for character development/testing that I'm excited to share one day soon. Link to comment Share on other sites More sharing options...
Ultroman Posted January 9, 2020 Share Posted January 9, 2020 I don't know much about Beefalo, especially after all the riding was added, but their combat component is identical to all other entities, so yes, extend their current CanTarget and just check if the target is your prefab, and if so, return false, otherwise, return whatever the original CanTarget function would return. 1 Link to comment Share on other sites More sharing options...
Skoith Posted January 30, 2020 Share Posted January 30, 2020 There's a custom character mod called 'Wully' on the steam workshop that basically behaves like a beefalo and is not attacked by them, maybe you can find some help there? 1 Link to comment Share on other sites More sharing options...
ry3bread Posted March 8, 2020 Author Share Posted March 8, 2020 On 2020-01-09 at 10:52 AM, Ultroman said: I don't know much about Beefalo, especially after all the riding was added, but their combat component is identical to all other entities, so yes, extend their current CanTarget and just check if the target is your prefab, and if so, return false, otherwise, return whatever the original CanTarget function would return. Thanks! Will go that route. Would you mind giving a really basic example for extending existing functions? I know enough to know that supplying a modified beefalo prefab isn’t ideal but I’m just not sure on syntax for extending. Thanks again On 2020-01-30 at 3:59 PM, Skoith said: There's a custom character mod called 'Wully' on the steam workshop that basically behaves like a beefalo and is not attacked by them, maybe you can find some help there? I’ll definitely be taking a peek, appreciate the tip Link to comment Share on other sites More sharing options...
Ultroman Posted March 9, 2020 Share Posted March 9, 2020 (edited) For functions which do NOT return anything: local oldOnDestack = comp.inst.components.stackable.ondestack comp.inst.components.stackable.ondestack = function(inst) -- Do some code stuff -- Call the existing function, if there was any. if oldOnDestack ~= nil then oldOnDestack(inst) end -- Do some code stuff end For functions which DO return something:Pretend that ondestack returns something (which it doesn't!!!). Then what? local oldOnDestack = comp.inst.components.stackable.ondestack comp.inst.components.stackable.ondestack = function(inst) -- MAYBE do some code stuff, perhaps changing the given parameters or -- changing how the existing function is used. -- Call the existing function, if there was any, and store the result in a variable. var result = nil if oldOnDestack ~= nil then result = oldOnDestack(inst) end -- MAYBE do some code stuff, perhaps changing the result in certain instances. -- Or you might just want to trigger a custom event here. Who knows? return result end Another example, where the function returns two variables! Pretend that ondestack returns 2 variables (which it doesn't!!!). local oldOnDestack = comp.inst.components.stackable.ondestack comp.inst.components.stackable.ondestack = function(inst) -- MAYBE do some code stuff, perhaps changing the given parameters or -- changing how the existing function is used. -- Call the existing function, if there was any, and store the result in a variable. var result1 = nil var result2 = nil if oldOnDestack ~= nil then result, result2 = oldOnDestack(inst) end -- MAYBE do some code stuff, perhaps changing the results in certain instances. -- Or you might just want to trigger a custom event here. Who knows? return result, result2 end An actual example, where I wanted to change the properties of the children spawned by a childspawner. local oldOnspawned = inst.components.childspawner.onspawned inst.components.childspawner.onspawned = function(childspawner, child) child.components.pollinator.collectcount = 3 child.components.locomotor.walkspeed = 5.5 child.components.health:SetMaxHealth(70) child.components.combat:SetDefaultDamage(7) child.AnimState:SetBuild("honeybee_build") if oldOnspawned ~= nil then oldOnspawned(inst) end end Edited March 14, 2020 by Ultroman 1 1 Link to comment Share on other sites More sharing options...
ry3bread Posted March 9, 2020 Author Share Posted March 9, 2020 3 hours ago, Ultroman said: For functions which do NOT return anything: local oldOnDestack = comp.inst.components.stackable.ondestack comp.inst.components.stackable.ondestack = function(inst) -- Do some code stuff -- Call the existing function, if there was any. if oldOnDestack ~= nil then oldOnDestack(inst) end end For functions which DO return something:Pretend that ondestack returns something. Then what? local oldOnDestack = comp.inst.components.stackable.ondestack comp.inst.components.stackable.ondestack = function(inst) -- MAYBE do some code stuff, perhaps changing the given parameters or -- changing how the existing function is used. -- Call the existing function, if there was any, and store the result in a variable. var result = nil if oldOnDestack ~= nil then result = oldOnDestack(inst) end -- MAYBE do some code stuff, perhaps changing the result in certain instances. -- Or you might just want to trigger a custom event here. Who knows? return result end An actual example, where I wanted to change the properties of the children spawned by a childspawner. local oldOnspawned = inst.components.childspawner.onspawned inst.components.childspawner.onspawned = function(childspawner, child) child.components.pollinator.collectcount = 3 child.components.locomotor.walkspeed = 5.5 child.components.health:SetMaxHealth(70) child.components.combat:SetDefaultDamage(7) child.AnimState:SetBuild("honeybee_build") if oldOnspawned ~= nil then oldOnspawned(inst) end end Thanks for this. Really appreciate you taking the time. 1 Link to comment Share on other sites More sharing options...
Ultroman Posted March 9, 2020 Share Posted March 9, 2020 You're welcome! This post goes into my "Tutorial links.txt" file 1 Link to comment Share on other sites More sharing options...
ry3bread Posted March 9, 2020 Author Share Posted March 9, 2020 (edited) 44 minutes ago, Ultroman said: You're welcome! This post goes into my "Tutorial links.txt" file So at the moment I've solved the friendliness issue by giving Nicole the 'beefalo' tag. That takes care of a lot of things, but not the shaving while awake problem. I was able to get that working by changing prefabs/beefalo.lua, specifically the CanShaveTest function from: local function CanShaveTest(inst) if inst.components.sleeper:IsAsleep() then return true else return false, "AWAKEBEEFALO" end end ...to: local function CanShaveTest(inst) local player = GetClosestInstWithTag("player", inst, 2) if inst.components.sleeper:IsAsleep() or player ~= nil and player:HasTag("Nicole") then return true else return false, "AWAKEBEEFALO" end end But, I'd rather extend it instead of including a modified prefabs/beefalo.lua file like you've been helping me with. So it looks like you're extending component functions in your (awesome) examples, what about if the target function is in a prefab? Is that something we can do? Also which file should the extension be in? nicole.lua or modmain.lua? Edited March 9, 2020 by ry3bread Additional question Link to comment Share on other sites More sharing options...
Ultroman Posted March 9, 2020 Share Posted March 9, 2020 (edited) On 9.3.2020 at 11:25 PM, ry3bread said: But, I'd rather extend it instead of including a modified prefabs/beefalo.lua file like you've been helping me with. So it looks like you're extending component functions in your (awesome) examples, what about if the target function is in a prefab? Is that something we can do? Good boy...or girl...or whatever Bad news is you cannot extend a local function. They are not accessible from outside their scope. Good news is, if you see where CanShaveTest is used, it's like this: inst.components.beard.canshavetest = CanShaveTest This is the only place it's used. This means that the non-local "canshavetest" variable/reference on the beard component is set to refer to the local CanShaveTest function. What you can do, is extend inst.components.beard.canshavetest in an AddPrefabPostInit call on the beefalo prefabs (I believe there are more beefalo prefabs than just "beefalo", at least "babybeefalo"). This code goes in your modmain.lua. Make one for each prefab: AddPrefabPostInit("beefalo", function(inst) -- Code here end) Edited March 11, 2020 by Ultroman 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