Jump to content

Stopping a inst:ListenForEvent


Recommended Posts

I've been working on a character that gets diarrhea when she eats her special prefab, losing sanity and hunger rapidly. I'd like to make her lose health over time as well, I know how to do an immediate health penalty, but I was wondering what the health equivalent to inst.components.hunger.hungerrate and  inst.components.sanity.dapperness was.

More importantly, I'm using a Listen for "on eat" function to trigger the diarrhea by using it to call the ListenFor hunger component. This works perfectly in enabling the diarrhea, but it continues to call the ListenFor hungerdelta thingy. Ideally, I'd be able to put something after the elseif inst.components.hunger.current < 10  [then SOMETHING THAT STOPS inst:ListenForEvent("hungerdelta", onhungerchange)], anyone have any idea how to do this?

Relevant part of code:

local function onhungerchange(inst, data)

    if inst.components.hunger.current > 50  then 
	inst.components.hunger.hungerrate = 50 * TUNING.WILSON_HUNGER_RATE
	inst.components.sanity.dapperness = TUNING.DAPPERNESS_LARGE*-50
    inst.components.periodicspawner:Start()
	elseif inst.components.hunger.current < 10  then 
	inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
	inst.components.sanity.dapperness = TUNING.DAPPERNESS_LARGE*0
    inst.components.periodicspawner:Stop()
	
    end
	
	
	end
	
	
	
	
	inst:ListenForEvent("oneat", function(inst, data) 
	if data.food and data.food.components.edible and data.food.components.edible.foodtype and data.food.prefab == "poopypill"
	then 
	inst:ListenForEvent("hungerdelta", onhungerchange)
	end
	end)

Entire character prefab:


local MakePlayerCharacter = require "prefabs/player_common"


local assets = {
    Asset("SCRIPT", "scripts/prefabs/player_common.lua"),
}
local prefabs = {}

-- Custom starting items
local start_inv = {
"boomerang",
"spear",
	
}
	
	
local function onbecamehuman(inst)
	-- Set speed when reviving from ghost (optional)
	inst.components.locomotor:SetExternalSpeedMultiplier(inst, "winnie_speed_mod", .6)
	
	
end



local function onbecameghost(inst)
	-- Remove speed modifier when becoming a ghost
   inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "winnie_speed_mod")
end

-- When loading or spawning the character
local function onload(inst)
    inst:ListenForEvent("ms_respawnedfromghost", onbecamehuman)
    inst:ListenForEvent("ms_becameghost", onbecameghost)

    if inst:HasTag("playerghost") then
        onbecameghost(inst)
    else
        onbecamehuman(inst)
    end
end

-- This initializes for both the server and client. Tags can be added here.
local common_postinit = function(inst) 
	-- Minimap icon
	inst.MiniMapEntity:SetIcon( "winnie.tex" )
	inst:AddTag( "winnie" )
	
end

	
-- This initializes for the server only. Components are added here.
local master_postinit = function(inst)
	-- choose which sounds this character will play
	inst.soundsname = "winnie"
	
	-- Uncomment if "wathgrithr"(Wigfrid) or "webber" voice is used
    --inst.talker_path_override = "dontstarve_DLC001/characters/"
	inst.components.combat:SetAttackPeriod(0.5)
	-- Stats	
	inst.components.health:SetMaxHealth(150)
	inst.components.hunger:SetMax(200)
	inst.components.sanity:SetMax(200)
	
	inst:AddComponent("periodicspawner")
    inst.components.periodicspawner:SetPrefab("poopy")
    inst.components.periodicspawner:SetRandomTimes(60, 90)
    inst.components.periodicspawner:Start()
	
	
	-- Damage multiplier (optional)
    inst.components.combat.damagemultiplier = 1
	
	inst.components.locomotor.walkspeed = (TUNING.WILSON_WALK_SPEED* 1)
    inst.components.locomotor.runspeed = (TUNING.WILSON_RUN_SPEED* 1)
	inst.Transform:SetScale( 1,  1, 1)

	-- Hunger rate (optional)
	inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
	
	inst:AddComponent("periodicspawner")
    inst.components.periodicspawner:SetPrefab("poop")
    inst.components.periodicspawner:SetRandomTimes(1,1)
	
	inst.OnLoad = onload
    inst.OnNewSpawn = onload
	
	local Combat = Class(function(self, inst)
	--attack range is how far away the enemy is where the player will try to take a jab at it
	inst.components.combat.attackrange = 1
	--hitrange how far the player can actually hit
	inst.components.combat.hitrange = 1
	--attack_period is how long it takes to attack
	inst.components.combat.min_attack_period = 1
    end)
	 
	local function onhungerchange(inst, data)

    if inst.components.hunger.current > 50  then 
	inst.components.hunger.hungerrate = 50 * TUNING.WILSON_HUNGER_RATE
	inst.components.sanity.dapperness = TUNING.DAPPERNESS_LARGE*-50
    inst.components.periodicspawner:Start()
	elseif inst.components.hunger.current < 10  then 
	inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
	inst.components.sanity.dapperness = TUNING.DAPPERNESS_LARGE*0
    inst.components.periodicspawner:Stop()
	
    end
	
	
	end
	
	
	
	
	inst:ListenForEvent("oneat", function(inst, data) 
	if data.food and data.food.components.edible and data.food.components.edible.foodtype and data.food.prefab == "poopypill"
	then 
	inst:ListenForEvent("hungerdelta", onhungerchange)
	end
	end)
	
	end
		
-- When the character is revived from human

return MakePlayerCharacter("winnie", prefabs, assets, common_postinit, master_postinit, start_inv)

 

Link to comment
Share on other sites

From abigail_flower.lua:

local function activate(inst)
    inst.SoundEmitter:PlaySound("dontstarve/common/haunted_flower_LP", "loop")
    inst:ListenForEvent("entity_death", inst._onentitydeath, TheWorld)
end

local function deactivate(inst)
    inst.SoundEmitter:KillAllSounds()
    inst:RemoveEventCallback("entity_death", inst._onentitydeath, TheWorld)
end

So for your oneat you would make that function callback a local function somewhere, then listen/remove it.

local function event_oneat(inst, data)
	if data.food and data.food.components.edible and data.food.components.edible.foodtype and data.food.prefab == "poopypill"
	then 
		inst:ListenForEvent("hungerdelta", onhungerchange)
	end
end


inst:ListenForEvent("oneat", event_oneat)


inst:RemoveEventCallback("oneat", event_oneat)

This is an example, so adapt it to your use case of the other event.

Edited by CarlZalph
Link to comment
Share on other sites

Cool so I added inst:RemoveEventCallback("hungerdelta", onhungerchange) to the <10 hunger threshold to end the function. This works in stopping diarrhea from triggering just based on the hunger threshold constantly after eating poopypill for the first time. However after a while I end up getting this error:


[00:02:32]: [string "scripts/components/periodicspawner.lua"]:106: attempt to index local 'inst' (a nil value)
LUA ERROR stack traceback:
    scripts/components/periodicspawner.lua:106 in (method) TrySpawn (Lua) <61-111>
    scripts/components/periodicspawner.lua:7 in (field) fn (Lua) <1-9>
    scripts/scheduler.lua:177 in (method) OnTick (Lua) <155-207>
    scripts/scheduler.lua:371 in (global) RunScheduler (Lua) <369-377>
    scripts/update.lua:170 in () ? (Lua) <149-228>
	
[00:02:32]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:02:32]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:03:09]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:03:09]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/menu.lua:83 in (method) SetFocus (Lua) <74-85>
	scripts/widgets/scripterrorwidget.lua:109 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:03:09]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:03:09]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:03:32]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:03:32]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:03:32]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:03:32]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:05:03]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:05:03]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:05:03]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:05:03]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:05:58]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:05:58]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:621 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/menu.lua:83 in (method) SetFocus (Lua) <74-85>
	scripts/widgets/scripterrorwidget.lua:109 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	
[00:05:58]: Warning: Widget:SetFocusFromChild is happening on a widget outside of the screen/widget hierachy. This will cause focus moves to fail. Is 	ScriptErrorWidget	not a screen?	
[00:05:58]: stack traceback:
	scripts/widgets/widget.lua:602 in (method) SetFocusFromChild (Lua) <599-624>
	scripts/widgets/widget.lua:649 in (method) SetFocus (Lua) <626-658>
	scripts/widgets/scripterrorwidget.lua:107 in (method) OnUpdate (Lua) <102-119>
	scripts/update.lua:90 in () ? (Lua) <33-129>	

Is error on line 106 because I'm using part of the function as a way to cancel the rest of the function creating some logical loop? Line 106 is the inst:RemoveEventCallback("hungerdelta", onhungerchange) part, so thats what my hunch is but I'm not sure. I'm not sure what the Widget:SetFocusFromChild thing is. 

local function onhungerchange(inst, data)

    if inst.components.hunger.current > 50  then 
    inst.components.hunger.hungerrate = 50 * TUNING.WILSON_HUNGER_RATE
    inst.components.sanity.dapperness = TUNING.DAPPERNESS_LARGE*-50
    inst.components.periodicspawner:Start()
    elseif inst.components.hunger.current < 10  then 
    inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
    inst.components.sanity.dapperness = TUNING.DAPPERNESS_LARGE*0
    inst.components.periodicspawner:Stop()
    
    inst:RemoveEventCallback("hungerdelta", onhungerchange)
    end
    
    
    end
    inst.OnLoad = onload
    inst.OnNewSpawn = onload
    
    
    
    inst:ListenForEvent("oneat", function(inst, data) 
    if data.food and data.food.components.edible and data.food.components.edible.foodtype and data.food.prefab == "poopypill"
    then 
    inst:ListenForEvent("hungerdelta", onhungerchange)
    end
    end)
    
    end

Rest of the character prefab:


local MakePlayerCharacter = require "prefabs/player_common"


local assets = {
    Asset("SCRIPT", "scripts/prefabs/player_common.lua"),
}
local prefabs = {}

-- Custom starting items
local start_inv = {
"poopypill",

	
}
	
	
local function onbecamehuman(inst)
	-- Set speed when reviving from ghost (optional)
	inst.components.locomotor:SetExternalSpeedMultiplier(inst, "winnie_speed_mod", .6)
	
	
end



local function onbecameghost(inst)
	-- Remove speed modifier when becoming a ghost
   inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "winnie_speed_mod")
end

-- When loading or spawning the character
local function onload(inst)
    inst:ListenForEvent("ms_respawnedfromghost", onbecamehuman)
    inst:ListenForEvent("ms_becameghost", onbecameghost)

    if inst:HasTag("playerghost") then
        onbecameghost(inst)
    else
        onbecamehuman(inst)
    end
end

-- This initializes for both the server and client. Tags can be added here.
local common_postinit = function(inst) 
	-- Minimap icon
	inst.MiniMapEntity:SetIcon( "winnie.tex" )
	inst:AddTag( "winnie" )
	
end

	
-- This initializes for the server only. Components are added here.
local master_postinit = function(inst)
	-- choose which sounds this character will play
	inst.soundsname = "winnie"
	
	-- Uncomment if "wathgrithr"(Wigfrid) or "webber" voice is used
    --inst.talker_path_override = "dontstarve_DLC001/characters/"
	inst.components.combat:SetAttackPeriod(0.5)
	-- Stats	
	inst.components.health:SetMaxHealth(150)
	inst.components.hunger:SetMax(200)
	inst.components.sanity:SetMax(200)
	
	inst:AddComponent("periodicspawner")
    inst.components.periodicspawner:SetPrefab("poopy")
    inst.components.periodicspawner:SetRandomTimes(60, 90)
    inst.components.periodicspawner:Start()
	
	
	-- Damage multiplier (optional)
    inst.components.combat.damagemultiplier = 1
	
	inst.components.locomotor.walkspeed = (TUNING.WILSON_WALK_SPEED* 1)
    inst.components.locomotor.runspeed = (TUNING.WILSON_RUN_SPEED* 1)
	inst.Transform:SetScale( 1,  1, 1)

	-- Hunger rate (optional)
	inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
	
	inst:AddComponent("periodicspawner")
    inst.components.periodicspawner:SetPrefab("poop")
    inst.components.periodicspawner:SetRandomTimes(1,1)
	
	local Combat = Class(function(self, inst)
	--attack range is how far away the enemy is where the player will try to take a jab at it
	inst.components.combat.attackrange = 1
	--hitrange how far the player can actually hit
	inst.components.combat.hitrange = 1
	--attack_period is how long it takes to attack
	inst.components.combat.min_attack_period = 1
    end)
	 
	local function onhungerchange(inst, data)

    if inst.components.hunger.current > 50  then 
	inst.components.hunger.hungerrate = 50 * TUNING.WILSON_HUNGER_RATE
	inst.components.sanity.dapperness = TUNING.DAPPERNESS_LARGE*-50
    inst.components.periodicspawner:Start()
	elseif inst.components.hunger.current < 10  then 
	inst.components.hunger.hungerrate = 1 * TUNING.WILSON_HUNGER_RATE
	inst.components.sanity.dapperness = TUNING.DAPPERNESS_LARGE*0
    inst.components.periodicspawner:Stop()
	
	inst:RemoveEventCallback("hungerdelta", onhungerchange)
    end
	
	
	end
	inst.OnLoad = onload
    inst.OnNewSpawn = onload
	
	
	
	inst:ListenForEvent("oneat", function(inst, data) 
	if data.food and data.food.components.edible and data.food.components.edible.foodtype and data.food.prefab == "poopypill"
	then 
	inst:ListenForEvent("hungerdelta", onhungerchange)
	end
	end)
	
	end
		
-- When the character is revived from human

return MakePlayerCharacter("winnie", prefabs, assets, common_postinit, master_postinit, start_inv)

 

Link to comment
Share on other sites

  • Developer

It fails in line 106 in periodicspawner.lua, not your code. If you look at that code you'll see

    local inst = SpawnPrefab(prefab)
    inst.Transform:SetPosition(x, y, z)

It fails at the second line there, inst doesn't exist, so it failed to spawn the prefab requested - most likely because it's trying to spawn a prefab that doesn't exist. I don't know which one it is trying to spawn at that point, seems there's only two options in your code, and seems one isn't known to the code.

If you want to know which one it is you could temporarily add a print(prefab) when it tries to spawn it, but I'm guessing it's "poopy".

Is your "poopy" prefab registered?

(I don't know how a mod is supposed to register a prefab, just figured I'd give my input)

Link to comment
Share on other sites

28 minutes ago, bizziboi said:

It fails in line 106 in periodicspawner.lua, not your code. If you look at that code you'll see


    local inst = SpawnPrefab(prefab)
    inst.Transform:SetPosition(x, y, z)

It fails at the second line there, inst doesn't exist, so it failed to spawn the prefab requested - most likely because it's trying to spawn a prefab that doesn't exist. I don't know which one it is trying to spawn at that point, seems there's only two options in your code, and seems one isn't known to the code.

If you want to know which one it is you could temporarily add a print(prefab) when it tries to spawn it, but I'm guessing it's "poopy".

Is your "poopy" prefab registered?

(I don't know how a mod is supposed to register a prefab, just figured I'd give my input)

That was the issue! Changed poopy to poop like it was supposed to be and it stopped crashing. Thanks for the help and for making this game!

Edited by Monty_Droppings
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...