Jump to content

Modifying food values without breaking compatibility


Recommended Posts

I'm trying to make my first mod for Don't Starve. This is also literally the first time I've ever worked with lua (most of my programming experience is with Java).

 

I'm trying to make a character that can eat Monster meat, but is damaged by regular meat. I can't just do whatever is done in the webber files because webber is still able to eat normal meat. Also, I want a total reversal, including the slight health regen that comes with regular cooked meat.

 

Now, the easiest way to do this is to simply override meats.lua with my own food values, and this works, but it causes ALL of the characters to have reversed food values. It also makes the mod incompatible with any other mod that modifies meat.lua.

 

What would be a better way to do this?

Link to comment
Share on other sites

I'm trying to make my first mod for Don't Starve. This is also literally the first time I've ever worked with lua (most of my programming experience is with Java).

 

I'm trying to make a character that can eat Monster meat, but is damaged by regular meat. I can't just do whatever is done in the webber files because webber is still able to eat normal meat. Also, I want a total reversal, including the slight health regen that comes with regular cooked meat.

 

Now, the easiest way to do this is to simply override meats.lua with my own food values, and this works, but it causes ALL of the characters to have reversed food values. It also makes the mod incompatible with any other mod that modifies meat.lua.

 

What would be a better way to do this?

 

See the eater component. You can use the SetOnEatFn to do this.

inst.components.eater:SetOnEatFn(yourfunction)

Of course, you need a "yourfunction" function to call.

local function yourfunction(inst, food)    local bannedfood = "meat"    local damage = inst.components.health.maxhealth    if food.prefab == bannedfood then        inst.components.health:DoDelta(damage)    endend

For example, that would kill the player character.

Link to comment
Share on other sites

i think I figured it out

I did this:

 

local function rawMeat(inst)	if GLOBAL.GetPlayer().prefab == "wod" then		inst.components.edible.healthvalue = -TUNING.HEALING_MED		inst.components.edible.hungervalue = TUNING.CALORIES_MEDSMALL		inst.components.edible.sanityvalue = -TUNING.SANITY_MED	endendAddPrefabPostInit("meat", rawMeat)

This achieves what I wanted. I didn't know how to use AddPrefabPostInit when I posted this, but I spent the whole time trying to figure it out.

 

EDIT: removed retarded meaningless statement

Link to comment
Share on other sites

void setStats(int healthValue, int calorieValue, int sanityValue){        inst.components.edible.healthvalue = healthValue;        inst.components.edible.hungervalue = calorieValue;        inst.components.edible.sanityvalue = sanityValue;}if GLOBAL.GetPlayer().prefab == "wod" thenAddPrefabPostInit("meat_dried", setStats())end

whoa, um, I pressed space twice and it automatically submitted that post... i wasn't done with it.

I don't think you can do that in java. AddPrefabPostInit is getting a handler for an event. You can't pass your own arguments to the handler method. It gets what it gets, in the case of prefabpostinit, it gets the prefab instance.

 

Anyway.

 

You can try something like this (It's not tested). All you have to do, is add a new prefab / values to the table.

local overrides = {	meat = { health = -1, calories = -3, sanity = -10 }	-- New prefab	--  {prefab} = {health = .., calories = ..., sanity = ... }}local function handleOverride(inst)    if GLOBAL.GetPlayer().prefab == "wod" then		-- Get the override values		local values = overrides[inst.prefab]		-- normally we should not do the check, since we are		--	handling only declared keys 		--	however with quantum fluctuations you never know		if values then 			inst.components.edible.healthvalue = values.health			inst.components.edible.hungervalue = values.calories			inst.components.edible.sanityvalue = values.sanity		end    endendfor k,v in pairs(overrides) do	AddPrefabPostInit(k, handleOverride)end

Or If you want to use your function, you need to create a wrapper function that receives the instance and pass that along

if GLOBAL.GetPlayer().prefab == "wod" then	AddPrefabPostInit("meat_dried", function(inst)		setStats(inst, -10, -5, -10)	end))end
Link to comment
Share on other sites

I tried putting this in modmain.lua, after the AddModCharacter("wod") line:

--function for changing food valueslocal function setStats(inst, healthVal, calorieVal, sanityVal)    inst.components.edible.healthvalue = healthVal    inst.components.edible.hungervalue = calorieVal    inst.components.edible.sanityvalue = sanityValendif GLOBAL.GetPlayer().prefab == "wod" then    AddPrefabPostInit("meat_dried", function(inst)        setStats(inst, -10, -5, -10)    end)end

When I run this, I get "attempted to index a nil value" at the player check line. If I remove that check and go with this...

local function setStats(inst, healthVal, calorieVal, sanityVal)    inst.components.edible.healthvalue = healthVal    inst.components.edible.hungervalue = calorieVal    inst.components.edible.sanityvalue = sanityValendAddPrefabPostInit("meat_dried", function(inst)    setStats(inst, -10, -5, -10)end)

...it works, albeit with the undesired result of applying this change to all the characters.

I know the player check works because I used it in my previous method. What this is telling me is that either this file is a bad place to check for that prefab or I'm being stupid and screwing something up. Probably a bit of both.

 

(P.S. disregard what I said about java, I've never done anything like this in java so I'm not sure why I said that.)

Link to comment
Share on other sites

The player doesn't exist yet when modmain.lua is run. You could put the player check inside the prefab post init callback like so:

 

local function setStats(inst, healthVal, calorieVal, sanityVal)    if GLOBAL.GetPlayer().prefab == "wod" then        inst.components.edible.healthvalue = healthVal        inst.components.edible.hungervalue = calorieVal        inst.components.edible.sanityvalue = sanityVal    endend AddPrefabPostInit("meat_dried", function(inst)    setStats(inst, -10, -5, -10)end)
Link to comment
Share on other sites

The player doesn't exist yet when modmain.lua is run. You could put the player check inside the prefab post init callback like so:

 

local function setStats(inst, healthVal, calorieVal, sanityVal)    if GLOBAL.GetPlayer().prefab == "wod" then        inst.components.edible.healthvalue = healthVal        inst.components.edible.hungervalue = calorieVal        inst.components.edible.sanityvalue = sanityVal    endend AddPrefabPostInit("meat_dried", function(inst)    setStats(inst, -10, -5, -10)end)

That was something I considered. I figured finding a better place to put the calls would be preferable because I'd only have to check the player a single time, as opposed to checking for every prefab. That's just me being slightly OCD about the performance though. This works fine.

 

Thank you all for your input, your caring is appreciated! :love_heart:

 

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