Jump to content

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?
 

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)

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

 

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

Edited by SenL

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