Monty_Droppings Posted December 1, 2018 Share Posted December 1, 2018 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 More sharing options...
CarlZalph Posted December 2, 2018 Share Posted December 2, 2018 (edited) 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 December 2, 2018 by CarlZalph Link to comment Share on other sites More sharing options...
Monty_Droppings Posted December 2, 2018 Author Share Posted December 2, 2018 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 More sharing options...
Developer bizziboi Posted December 2, 2018 Developer Share Posted December 2, 2018 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 More sharing options...
Monty_Droppings Posted December 2, 2018 Author Share Posted December 2, 2018 (edited) 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 December 2, 2018 by Monty_Droppings Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now