Jump to content

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?

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.

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

Edited by code4240
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
Edited by RazvanM

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

Edited by code4240

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)
Edited by squeek

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:

 

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
×
  • Create New...