Jump to content

gain sanity when planting pinecones


wowcobo

Recommended Posts

So im fairly new to modding dont starve, and im trying to make a character. The idea is that just like how you get a little sanity when you pick a flower, this character also gets a little sanity when she pants a pinecone. 

i have tried messing with some code that looks a little like this:

 

local function sanity_onplant:pinecone(cause)
    inst.components.sanity:DoDelta(TUNING.SANITY_TINY)
end
inst:ListenForEvent("onplant",DoDelta)
 
but it just crashes
does anyone have any tips on how i could fix the formatting on this code or how i could find/write the correct code for what im trying to do?
 
Link to comment
Share on other sites

Hey, I'm fairly new to modding as well, so there /may/ be a "best practice" way of doing this I'm not aware of, but for all intents and purposes, the answer below should work fine.

 

Instead of using event listeners(which I believe are a bit more low level than your typical lua script), you might want to try simply overriding the "ondeploy" function. Note, however that since the ondeploy function is declared as "local function", you wont have access to it.  What you do have access to is the deployable component-- overriding the function is as simple as giving deployable.ondeploy a new version of the ondeploy function.  Here's how you might achieve that, with comments describing what's going on.

GLOBAL.require "tuning"--We need to import some things from the GLOBAL namespaceGetRandomWithVariance = GLOBAL.GetRandomWithVarianceRemovePhysicsColliders = GLOBAL.RemovePhysicsCollidersGetTime = GLOBAL.GetTime-- Note that the ondeploy function calls this function in pinecone.lue.  Since it is declared as a local function-- there, we need to include it here.local function plant(inst, growtime)    inst:RemoveComponent("inventoryitem")    RemovePhysicsColliders(inst)    inst.AnimState:PlayAnimation("idle_planted")    inst.SoundEmitter:PlaySound("dontstarve/wilson/plant_tree")    inst.growtime = GetTime() + growtime    print ("PLANT", growtime)    inst.growtask = inst:DoTaskInTime(growtime, growtree)end-- This is effectively a clone of the original function... with one exception.  The original function didn't pass -- the "deployer" variable, which is needed to figure out who to apply the sanity gain to. Note that unlike many-- languages, LUA doesn't require that you call a function using the same number of arguments that it is defined-- with.  Looking in component's definition file, deployable.lua, the ondeploy function is actually declared as:----     function Deployable:Deploy(pt, deployer)---- That means that it IS in fact passing a reference to the deployer, so we can add it to our list of arguments.local function ondeployOverride (inst, pt, deployer)     -- This is the only thing that needed to be added.    deployer.components.sanity:DoDelta(TUNING.SANITY_TINY)    inst = inst.components.stackable:Get()    inst.Transform:SetPosition(pt:Get() )    local timeToGrow = GetRandomWithVariance(TUNING.PINECONE_GROWTIME.base, TUNING.PINECONE_GROWTIME.random)    plant(inst, timeToGrow)		--tell any nearby leifs to chill out	local ents = TheSim:FindEntities(pt.x,pt.y,pt.z, TUNING.LEIF_PINECONE_CHILL_RADIUS, {"leif"})		local played_sound = false	for k,v in pairs(ents) do				local chill_chance = TUNING.LEIF_PINECONE_CHILL_CHANCE_FAR		if distsq(pt, Vector3(v.Transform:GetWorldPosition())) < TUNING.LEIF_PINECONE_CHILL_CLOSE_RADIUS*TUNING.LEIF_PINECONE_CHILL_CLOSE_RADIUS then			chill_chance = TUNING.LEIF_PINECONE_CHILL_CHANCE_CLOSE		end			if math.random() < chill_chance then			if v.components.sleeper then				v.components.sleeper:GoToSleep(1000)			end		else			if not played_sound then				v.SoundEmitter:PlaySound("dontstarve/creatures/leif/taunt_VO")				played_sound = true			end		end			end	end-- Create a function to pass to addPrefabPostInitlocal function pineconeMod(inst)    inst.components.deployable.ondeploy = ondeployOverrideend-- And finally, register it to the list of functions to be run on the pinecone prefabAddPrefabPostInit("pinecone", pineconeMod)

Link to comment
Share on other sites

@wowcobo,  @Corrosive

 

For the sake of DRY, here's another way to implement it without rewriting the function as it was.

local function pineconeMod(inst)    inst.old_ondeploy = inst.components.deployable.ondeploy    inst.components.deployable.ondeploy = function(inst, pt, deployer)        inst:old_ondeploy(pt)        deployer.components.sanity:DoDelta(TUNING.SANITY_TINY)    endendAddPrefabPostInit("pinecone", pineconeMod)

(Theoretical code, not tested)

 

This should also improve compatibility with other mods.

 

Link to comment
Share on other sites

Hi Blueberrys

 

The code works as host buit as client, even when that char is not being used at all (mod is enabled but not used), client crashes.

Log:

 

...

[string "../mods/mychar/modmain.lua"]:61: attempt to index field 'deployable' (a nil value)

...

 

Help? :-)

 

Edit: whoops, probably should post @ DST instead...

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