Jump to content

Healing the Werebeaver with wood (and also Wickerbottom)


Recommended Posts

I've been banging my head against this problem for days. I'm trying to code in a health delta when there is a positive delta to beaverness but I just can't get it to work. I initially tried to code in a health value to the wood prefabs but I found the eater code specifically disables any stat changes if beaverness is changed. So I tried to write a local function to handle it, using some code from Wilbur and code posted here. This is what I came up with:

in the master_postinit

Quote

    inst:ListenForEvent("beavernessdelta", woodheal)

and then in the prefab

Quote

local function woodheal(inst, data)
        if data.food ~= nil and data.food.edible.woodiness ~= nil and inst:HasTag("beaver")then
            local delta = food.components.edible:GetWoodiness(self.inst)
        else
            local delta = 0
            if delta >= 0 then
                inst.components.health:DoDelta(delta)
        end
    end
end

Can anyone see why this code isn't working? Have I just written it wrong? I'm very new to lua so I'm kind of just experimenting here.

 

I also want to tweak the sanity costs of Wickerbottom's books, but the value is nested pretty deep in a function rather than just a prefab value so I'm not sure how to go about changing it without overwriting the whole books.lua prefab. I want to make it toggleable if possible you see.

 

Any help would be wonderful, thanks!

 

Link to comment
Share on other sites

local function woodheal(inst, data)
    if data.food ~= nil and data.food.edible.woodiness ~= nil and inst:HasTag("beaver")then
        local delta = food.components.edible:GetWoodiness(inst)
        inst.components.health:DoDelta(delta)
    end
end 

You don't need the else if you're just gonna heal 0, I removed self from self.inst, since self isn't declared here.

You were also only doing the healing in the else, which is when delta is always 0

Link to comment
Share on other sites

On 12/12/2016 at 3:55 PM, Aquaterion said:

local function woodheal(inst, data)
    if data.food ~= nil and data.food.edible.woodiness ~= nil and inst:HasTag("beaver")then
        local delta = food.components.edible:GetWoodiness(inst)
        inst.components.health:DoDelta(delta)
    end
end 

You don't need the else if you're just gonna heal 0, I removed self from self.inst, since self isn't declared here.

You were also only doing the healing in the else, which is when delta is always 0

Thanks for the reply. I tried amending the code like you suggested but it still doesn't work. Oh well, back to the drawing board.

Link to comment
Share on other sites

This isn't working because you're listening for beavernessdelta and trying to access data.food, but beavernessdelta doesn't push that data:

self.inst:PushEvent("beavernessdelta", { oldpercent = old / self.max, newpercent = self.current / self.max, overtime = overtime })

but if you simply listen to "oneat", which has data.food and data.feeder being given,

self.inst:PushEvent("oneat", { food = food, feeder = feeder })

your code will only run when you eat something, and if that item has woodiness, then it gives health too.

 

Link to comment
Share on other sites

I've tried amending the code to run the function "oneat" but it always causes crashes as the game says that 'food' is undefined. I might rethink my plans, make the function just copy onbeavernessdelta and see if that works. Will report back with results.

 

On looking at the statusdisplays code, the green pulse around the meters comes "if not data.overtime" and "if data.newpercent > data.oldpercent". No maybe if I use that it'll work? We'll see.

Edited by deadlyreg
Had another idea!
Link to comment
Share on other sites

Okay, so this is kind weird but I think I solved the problem but I don't understand how that well.

I now have the code runnin on two event handlers, a beaver on that is inst:ListenForEvent("beavernessdelta", woodheal) and on Woodie form is  inst:RemoveEventCallback("beavernessdelta", woodheal) and the function is:

local function woodheal(inst, data)
    if not data.overtime then --status changes not overtime give pulse
    inst.components.health:DoDelta((data.newpercent - data.oldpercent) * 100)  --needs the 100 multiplier
    end
end 

 

and it works perfectly! I think I kind of lucked out on this one, I pulled apart some other mod code for ideas and through the prefabs for clues. Thanks for your help.

Link to comment
Share on other sites

local function woodheal(inst, data)
    if data.food ~= nil and data.food.edible.woodiness ~= nil and inst:HasTag("beaver")then
        local delta = food.components.edible:GetWoodiness(inst)
        inst.components.health:DoDelta(delta)
    end
end 

your normal code

inst:ListenForEvent("oneat", woodheal)

changing the event you listen for.

 

I'm not sure what your issue was

Link to comment
Share on other sites

I honestly don't know why it wouldn't work, I tried it the way you corrected me and every time the werebeaver ate something the game crashed. There was something about trying to get the Woodiness data from the food oneat that the game didn't like. I'm disappointed that my code didn't work but I'm glad my hacky second attempt got somewhere.

Also solved the Wickerbottom book problem in an overkill way. I made an amended copy of the "books.lua" file and used GetModconfigdata to trigger insert.table(prefabs, "books") to overwrite it. It's not quite what I wanted but it works so that's something. 

Link to comment
Share on other sites

Wait.. are you editing base files? Ideally you wouldn't do that, instead you use a function in modmain.lua (AddPrefabPostInit)

like so:

AddPrefabPostInit("woodie", function(inst)
	if not GLOBAL.TheWorld.ismastersim then
		return inst
	end

	inst:ListenForEvent("oneat", function(inst, data)
		if inst:HasTag("beaver") and data.food and data.food.components.edible.woodiness then
			inst.components.health:DoDelta(data.food.components.edible:GetWoodiness())
		end
	end)
end)

 

Link to comment
Share on other sites

Yes I am using modded base files, I use the Prefab table to import the files and I assume overwrite the base game files. It's not ideal I know, and it mean there's a good chance of compatibility issues but I want to edit functions and components in functions and I don't know how to do that. For example I want to turn off the sanity gain from planting trees, but the function is this:

local function ondeployitem(inst, data)
    if data.prefab == "pinecone" or data.prefab == "acorn" or data.prefab == "twiggy_nut" then
        --inst.components.beaverness:DoDelta(TUNING.WOODIE_PLANT_TREE_GAIN)
        inst.components.sanity:DoDelta(TUNING.SANITY_TINY)
    end
end

Without overwriting my own prefab I don't know how to change this function to make the DoDelta 0, or to disable the function entirely. Another is 

local function onbecamebeaver(inst)

which contains

    inst.components.temperature.inherentinsulation = TUNING.INSULATION_LARGE
    inst.components.temperature.inherentsummerinsulation = TUNING.INSULATION_LARGE
    inst.components.moisture:SetInherentWaterproofness(TUNING.WATERPROOFNESS_LARGE)

I want to amend these values, but again they're inside a function. How do I get access to them to amend them? I'm still too much of an amateur to work around the problem so I've kind of brute forced it. Any insight would be welcome.

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