MrDoge124

  • Content Count

    56
  • Joined

  • Last visited

 Content Type 

Profiles

Forums

Downloads

Klei Bug Tracker

Game Updates

Hot Lava Bug Reporter

Posts posted by MrDoge124


  1. I got it to work. I asked a friend and we fixed it.

    So while poking around at another character, we discovered differences in the code that allowed us to reverse engineer a solution. With the error message telling us that “Inst” was a null value. Initially we thought that Inst was always in reference to the player whenever it’s called. THIS IS NOT THE CASE.
    We then found that whenever we declared a function, "Inst" was not declared.

    AddModRPCHandler(“Green”,"GREEN_STUN", function(---INST IS MISSING HERE---)

    We changed “Inst” to “player” just to make the code more readable in the future and then changed any reference to Inst into player. In addition to this, several functions were missing declarations which we fixed by adding player.
     

    AddModRPCHandler(“Green”,"GREEN_STUN", function(player)
    Spoiler
    
    
    TheInput = GLOBAL.TheInput
    local KEY_Z = GLOBAL.KEY_Z
    
    -- This function is rather complicated. You don't need to change anything in here.
    local function ApplyBuff(buffData, instToBuff, ents)
        --print(ents)
        local buffUniqueName = buffData.uniqueName
        
        -- Cancel any existing duplicate timed buff.
        if instToBuff[buffUniqueName.."Task"] ~= nil then
            buffData.removeFunction(instToBuff, ents)
            instToBuff[buffUniqueName.."Task"]:Cancel()
            instToBuff[buffUniqueName.."Task"] = nil
        end
        
        -- Make sure that our buff is removed BEFORE the entity is saved (the server is closed or player quits).
        -- This is only necessary if you change variables which are saved, like current health, health-penalty, etc.
        -- Without it, you could apply a max-health buff, quit before it ran out, rejoin, and you would have kept
        -- the extra max health!
        local buffOnSave = function(self, player, data)
            if player[buffUniqueName.."Task"] ~= nil then
                buffData.removeFunction(player, ents)
                player[buffUniqueName.."Task"]:Cancel()
                player[buffUniqueName.."Task"] = nil
            end
        end
        
        if instToBuff.OnSave ~= nil then
            local oldOnSave = instToBuff.OnSave
            instToBuff.OnSave = function(self, player, data)
                buffOnSave(self, player, data)
                oldOnSave(self, player, data)
            end
        else
            instToBuff.OnSave = buffOnSave
        end
        
        -- Apply the buff.
        buffData.applyFunction(instToBuff, ents)
        
        -- Set up removal after a certain amount of time.
        instToBuff[buffUniqueName.."Task"] = instToBuff:DoTaskInTime(buffData.duration, function(player)
            buffData.removeFunction(player, ents)
            player[buffUniqueName.."Task"] = nil
        end)
    end
    
    
    -- Now to make some buffs and put them in a Buffs-dictionary.
    local Buffs = {"stunbuff",}
    
    -- This function creates a new buff-data object and adds it to the Buffs-dictionary
    -- with the uniqueName as key.
    local function CreateBuff(uniqueName, duration, applyFunction, removeFunction)
        local newBuff = {}
        newBuff.uniqueName = uniqueName
        newBuff.duration = duration
        newBuff.applyFunction = applyFunction
        newBuff.removeFunction = removeFunction
        Buffs[uniqueName] = newBuff
    end
    
    -- This is an example of how to use the CreateBuff() function to create a new buff.
    CreateBuff("stunbuff", 5.0,
        function(player, ents)
            -- Apply all your buff code here
            -- Remember to always check whether the components you want to change are actually present on the
            -- entity before you try to mess with them.-- Store the current maxhealth in a variable.
            -- Add 0% speed boost in all situations
        for i, ent in ipairs(ents) do
    		--local ds = ent.entity:GetDebugString()
    		--local tagsstr = string.match(ds, "Tags: ([^\n]+)\n")
    		--print(tagsstr)
            ent.components.locomotor:SetExternalSpeedMultiplier(player, "stunkey", 0)
            if ent.brain then
                ent.brain:Stop()
            end
    	end
        end,
        function(player, ents)
            -- Revert your buff code here
            -- Remember to always check whether the components you want to change are actually present on the
            -- entity before you try to mess with them.
        -- Remove speed bonus.
        for i, ent in ipairs(ents) do
            ent.components.locomotor:RemoveExternalSpeedMultiplier(player, "stunkey")
            if ent.brain then
                ent.brain:Start()
            end
        end
    end
    )
    
    AddModRPCHandler("Green", "GREEN_STUN", function(player)
        local x, y, z = player.Transform:GetWorldPosition()
        local range = 5
        local ents = TheSim:FindEntities(x, y, z, range, { "_combat"}, { "player", "playermerm", "playermonster", "structure", "INLIMBO", "playermonster", "NOCLICK"}, {"hostile", "pig", "merm", "monster", "prey", "animal", "bee",})
        --Find Entity nearby
        if not chargeincooldown and player.components.sanity.current > 10 and table.getn(ents) > 0 then
        --If chargeincooldown is false and current sanity is larger than 10 and there is more that 0 entities nearby
            chargeincooldown = true --Disable the move by starting the cooldown
            ApplyBuff(Buffs["stunbuff"], player, ents) --Run the apply buff function, inputting the entity table. God only knows how the rest of the function works.
            print("buff applied")
            player.components.sanity.current = player.components.sanity.current - 10 --Remove 10 sanity
        	player.SoundEmitter:PlaySound("dontstarve/characters/green/stun")
            player.Light:SetIntensity(0.75)
            player.Light:SetFalloff(.1)
            player.Light:SetRadius(1.5)--Deal with lighting
            player:DoTaskInTime(0.2, function()
                player.Light:Enable (false)--Hide light after 1 second
            end)
            --Reset everything after 15 seconds
            player:DoTaskInTime(480, function()
    		    print("recharged")
                player.Light:SetIntensity(.75)
                player.Light:SetFalloff(.5)
                player.Light:SetRadius(0.8)
                player.Light:Enable (true)
                chargeincooldown = false
            end)
        end
    end)
    
    local greenhandlers = {}
    AddPlayerPostInit(function(player)
        -- We hack
        player:DoTaskInTime(0, function()
            -- We check if the character is ourselves
            -- So if another green player joins, we don't get the handlers
            if player == GLOBAL.ThePlayer then
                -- If we are green
                if player.prefab == "green" then
                    -- We create and store the key handlers
                    greenhandlers[1] = TheInput:AddKeyDownHandler(KEY_Z, function()
                        SendModRPCToServer(MOD_RPC["Green"]["GREEN_STUN"])
                    end)
                    -- If not, we go to the handlerslist and empty it
                    -- This is to avoid having the handlers if we switch characters in wilderness
                    -- If it's already empty, nothing changes
                    for k, v in pairs(greenhandlers) do
                        greenhandlers[k] = nil
                    end
                end
            end
        end)
    end)

     

    Thanks for the help!

    • Thanks 1

  2. I've tried to add RPC handlers to the code but it doesn't work, I'm not sure what I'm doing.

    Spoiler
    
    
    AddModRPCHandler(modname, "GREEN_STUN", function()
        local x, y, z = inst.Transform:GetWorldPosition()
        local range = 5
        local ents = TheSim:FindEntities(x, y, z, range, { "_combat"}, { "player", "playermerm", "playermonster", "structure", "INLIMBO", "playermonster", "NOCLICK"}, {"hostile", "pig", "merm", "monster", "prey", "animal", "bee",})
        --Find Entity nearby
        if not chargeincooldown and inst.components.sanity.current > 10 and table.getn(ents) > 0 then
        --If chargeincooldown is false and current sanity is larger than 10 and there is more that 0 entities nearby
            chargeincooldown = true --Disable the move by starting the cooldown
            ApplyBuff(Buffs["stunbuff"], inst, ents) --Run the apply buff function, inputting the entity table. God only knows how the rest of the function works.
            print("buff applied")
            inst.components.sanity.current = inst.components.sanity.current - 10 --Remove 10 sanity
        	inst.SoundEmitter:PlaySound("dontstarve/characters/green/stun")
            inst.Light:SetIntensity(0.75)
            inst.Light:SetFalloff(.1)
            inst.Light:SetRadius(1.5)--Deal with lighting
            inst:DoTaskInTime(0.2, function()
                inst.Light:Enable (false)--Hide light after 1 second
            end)
            --Reset everything after 15 seconds
            inst:DoTaskInTime(480, function()
    		    print("recharged")
                inst.Light:SetIntensity(.75)
                inst.Light:SetFalloff(.5)
                inst.Light:SetRadius(0.8)
                inst.Light:Enable (true)
                chargeincooldown = false
            end)
        end
        end)
    
        local greenhandlers = {}
    
        AddPlayerPostInit(function(inst)
            -- We hack
            inst:DoTaskInTime(0, function()
                -- We check if the character is ourselves
                -- So if another green player joins, we don't get the handlers
                if inst == GLOBAL.ThePlayer then
                    -- If we are green
                    if inst.prefab == "green" then
                        -- We create and store the key handlers
                        greenhandlers[1] = TheInput:AddKeyDownHandler(KEY_R, function()
                            SendModRPCToServer(MOD_RPC[modname]["GREENCHARGE"])
                        end)
                        -- If not, we go to the handlerslist and empty it
                        -- This is to avoid having the handlers if we switch characters in wilderness
                        -- If it's already empty, nothing changes
                        for k, v in pairs(greenhandlers) do
                            greenhandlers[k] = nil
                        end
                    end
                end
            end)
        end)

     

    I've found this error in the code.

    Spoiler
    
    [00:00:52]: [string "../mods/Green/scripts/prefabs/green.lua"]:244: variable 'Green' is not declared
    LUA ERROR stack traceback:
    =[C]:-1 in (global) error (C) <-1--1>
    scripts/strict.lua:23 in () ? (Lua) <21-26>
       t = table: 08D51E68
       n = Green
    ../mods/Green/scripts/prefabs/green.lua:244 in (upvalue) master_postinit (Lua) <78-300>
       inst = 118130 -  (valid:true)
       speedadjustment = function - ../mods/Green/scripts/prefabs/green.lua:113
       ApplyBuff = function - ../mods/Green/scripts/prefabs/green.lua:156
       Buffs = table: 2049C948
       CreateBuff = function - ../mods/Green/scripts/prefabs/green.lua:205
    scripts/prefabs/player_common.lua:1768 in (field) fn (Lua) <1395-1797>
       inst = 118130 -  (valid:true)
       gamemode = endless
    scripts/mainfunctions.lua:258 in () ? (Lua) <247-289>
       name = green
       prefab = Prefab green - 
    
    [00:00:52]: [string "../mods/Green/scripts/prefabs/green.lua"]:244: variable 'Green' is not declared
    LUA ERROR stack traceback:
        =[C]:-1 in (global) error (C) <-1--1>
        scripts/strict.lua:23 in () ? (Lua) <21-26>
        ../mods/Green/scripts/prefabs/green.lua:244 in (upvalue) master_postinit (Lua) <78-300>
        scripts/prefabs/player_common.lua:1768 in (field) fn (Lua) <1395-1797>
        scripts/mainfunctions.lua:258 in () ? (Lua) <247-289>
    	
    [00:00:52]: Error decoding lua RPC sender
    [00:00:52]: 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:00:52]: stack traceback:
    	scripts/widgets/widget.lua:605 in (method) SetFocusFromChild (Lua) <602-627>
    	scripts/widgets/widget.lua:624 in (method) SetFocusFromChild (Lua) <602-627>
    	scripts/widgets/widget.lua:624 in (method) SetFocusFromChild (Lua) <602-627>
    	scripts/widgets/widget.lua:656 in (method) SetFocus (Lua) <629-665>
    	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>	

     

     


  3. In this previous post I managed to get a AOE stun attack working. However when I enable caves it doesn't work.


    Turns out I think I'm missing something. It might be an action handler or some sort of net code which could be why it doesn't work when caves are enabled. It also doesn't crash or print anything to the logs, So I'm not sure why it isn't working.

    This is the code. It's all contained inside a character lua file.

    Spoiler
    
    -- This function is rather complicated. You don't need to change anything in here.
    local function ApplyBuff(buffData, instToBuff, ents)
        --print(ents)
        local buffUniqueName = buffData.uniqueName
        
        -- Cancel any existing duplicate timed buff.
        if instToBuff[buffUniqueName.."Task"] ~= nil then
            buffData.removeFunction(instToBuff, ents)
            instToBuff[buffUniqueName.."Task"]:Cancel()
            instToBuff[buffUniqueName.."Task"] = nil
        end
        
        -- Make sure that our buff is removed BEFORE the entity is saved (the server is closed or player quits).
        -- This is only necessary if you change variables which are saved, like current health, health-penalty, etc.
        -- Without it, you could apply a max-health buff, quit before it ran out, rejoin, and you would have kept
        -- the extra max health!
        local buffOnSave = function(self, inst, data)
            if inst[buffUniqueName.."Task"] ~= nil then
                buffData.removeFunction(inst, ents)
                inst[buffUniqueName.."Task"]:Cancel()
                inst[buffUniqueName.."Task"] = nil
            end
        end
        
        if instToBuff.OnSave ~= nil then
            local oldOnSave = instToBuff.OnSave
            instToBuff.OnSave = function(self, inst, data)
                buffOnSave(self, inst, data)
                oldOnSave(self, inst, data)
            end
        else
            instToBuff.OnSave = buffOnSave
        end
        
        -- Apply the buff.
        buffData.applyFunction(instToBuff, ents)
        
        -- Set up removal after a certain amount of time.
        instToBuff[buffUniqueName.."Task"] = instToBuff:DoTaskInTime(buffData.duration, function(inst)
            buffData.removeFunction(inst, ents)
            inst[buffUniqueName.."Task"] = nil
        end)
    end
    
    
    -- Now to make some buffs and put them in a Buffs-dictionary.
    local Buffs = {"stunbuff",}
    
    -- This function creates a new buff-data object and adds it to the Buffs-dictionary
    -- with the uniqueName as key.
    local function CreateBuff(uniqueName, duration, applyFunction, removeFunction)
        local newBuff = {}
        newBuff.uniqueName = uniqueName
        newBuff.duration = duration
        newBuff.applyFunction = applyFunction
        newBuff.removeFunction = removeFunction
        Buffs[uniqueName] = newBuff
    end
    
    -- This is an example of how to use the CreateBuff() function to create a new buff.
    CreateBuff("stunbuff", 5.0,
        function(inst, ents)
            -- Apply all your buff code here
            -- Remember to always check whether the components you want to change are actually present on the
            -- entity before you try to mess with them.-- Store the current maxhealth in a variable.
            -- Add 0% speed boost in all situations
        for i, ent in ipairs(ents) do
    		--local ds = ent.entity:GetDebugString()
    		--local tagsstr = string.match(ds, "Tags: ([^\n]+)\n")
    		--print(tagsstr)
            ent.components.locomotor:SetExternalSpeedMultiplier(inst, "stunkey", 0)
            if ent.brain then
                ent.brain:Stop()
            end
    	end
        end,
        function(inst, ents)
            -- Revert your buff code here
            -- Remember to always check whether the components you want to change are actually present on the
            -- entity before you try to mess with them.
        -- Remove speed bonus.
        for i, ent in ipairs(ents) do
            ent.components.locomotor:RemoveExternalSpeedMultiplier(inst, "stunkey")
            if ent.brain then
                ent.brain:Start()
            end
        end
    end
    )
    
    TheInput:AddKeyDownHandler(KEY_Z, function()
        local x, y, z = inst.Transform:GetWorldPosition()
        local range = 5
        local ents = TheSim:FindEntities(x, y, z, range, { "_combat"}, { "player", "playermerm", "playermonster", "structure", "INLIMBO", "playermonster", "NOCLICK"}, {"hostile", "pig", "merm", "monster", "prey", "animal", "bee",})
        --Find Entity nearby
        if not chargeincooldown and inst.components.sanity.current > 10 and table.getn(ents) > 0 then
        --If chargeincooldown is false and current sanity is larger than 10 and there is more that 0 entities nearby
            chargeincooldown = true --Disable the move by starting the cooldown
            ApplyBuff(Buffs["stunbuff"], inst, ents) --Run the apply buff function, inputting the entity table. God only knows how the rest of the function works.
            print("buff applied")
            inst.components.sanity.current = inst.components.sanity.current - 10 --Remove 10 sanity
        	inst.SoundEmitter:PlaySound("dontstarve/characters/green/stun")
            inst.Light:SetIntensity(0.75)
            inst.Light:SetFalloff(.1)
            inst.Light:SetRadius(1.5)--Deal with lighting
            inst:DoTaskInTime(0.2, function()
                inst.Light:Enable (false)--Hide light after 1 second
            end)
            --Reset everything after 15 seconds
            inst:DoTaskInTime(480, function()
    		    print("recharged")
                inst.Light:SetIntensity(.75)
                inst.Light:SetFalloff(.5)
                inst.Light:SetRadius(0.8)
                inst.Light:Enable (true)
                chargeincooldown = false
            end)
        end
        end)

     

    Any help would be appreciated.


  4. When I enable caves it does nothing, no errors. Nothing is printed even if I tell it to print something.

    I think something isn't being triggered properly. My best guess is the "TheInput:AddKeyDownHandler(KEY_Z, function()" part isn't working right as nothing happens when I press Z.

    I might have to add an action for the attack, but I'm not sure how that works. I've found an example where actions are used and it seems to work fine.


  5. Ok I got it to work with some help from a friend.

    Here is the code

    Spoiler
    
    -- This function is rather complicated. You don't need to change anything in here.
    local function ApplyBuff(buffData, instToBuff, ents)
        --print(ents)
        local buffUniqueName = buffData.uniqueName
        
        -- Cancel any existing duplicate timed buff.
        if instToBuff[buffUniqueName.."Task"] ~= nil then
            buffData.removeFunction(instToBuff, ents)
            instToBuff[buffUniqueName.."Task"]:Cancel()
            instToBuff[buffUniqueName.."Task"] = nil
        end
        
        -- Make sure that our buff is removed BEFORE the entity is saved (the server is closed or player quits).
        -- This is only necessary if you change variables which are saved, like current health, health-penalty, etc.
        -- Without it, you could apply a max-health buff, quit before it ran out, rejoin, and you would have kept
        -- the extra max health!
        local buffOnSave = function(self, inst, data)
            if inst[buffUniqueName.."Task"] ~= nil then
                buffData.removeFunction(inst, ents)
                inst[buffUniqueName.."Task"]:Cancel()
                inst[buffUniqueName.."Task"] = nil
            end
        end
        
        if instToBuff.OnSave ~= nil then
            local oldOnSave = instToBuff.OnSave
            instToBuff.OnSave = function(self, inst, data)
                buffOnSave(self, inst, data)
                oldOnSave(self, inst, data)
            end
        else
            instToBuff.OnSave = buffOnSave
        end
        
        -- Apply the buff.
        buffData.applyFunction(instToBuff, ents)
        
        -- Set up removal after a certain amount of time.
        instToBuff[buffUniqueName.."Task"] = instToBuff:DoTaskInTime(buffData.duration, function(inst)
            buffData.removeFunction(inst, ents)
            inst[buffUniqueName.."Task"] = nil
        end)
    end
    
    
    -- Now to make some buffs and put them in a Buffs-dictionary.
    local Buffs = {"stunbuff",}
    
    -- This function creates a new buff-data object and adds it to the Buffs-dictionary
    -- with the uniqueName as key.
    local function CreateBuff(uniqueName, duration, applyFunction, removeFunction)
        local newBuff = {}
        newBuff.uniqueName = uniqueName
        newBuff.duration = duration
        newBuff.applyFunction = applyFunction
        newBuff.removeFunction = removeFunction
        Buffs[uniqueName] = newBuff
    end
    
    -- This is an example of how to use the CreateBuff() function to create a new buff.
    CreateBuff("stunbuff", 5.0,
        function(inst, ents)
            -- Apply all your buff code here
            -- Remember to always check whether the components you want to change are actually present on the
            -- entity before you try to mess with them.-- Store the current maxhealth in a variable.
            -- Add 0% speed boost in all situations
        for i, ent in ipairs(ents) do
    		--local ds = ent.entity:GetDebugString()
    		--local tagsstr = string.match(ds, "Tags: ([^\n]+)\n")
    		--print(tagsstr)
            ent.components.locomotor:SetExternalSpeedMultiplier(inst, "stunkey", 0)
            if ent.brain then
                ent.brain:Stop()
            end
    	end
        end,
        function(inst, ents)
            -- Revert your buff code here
            -- Remember to always check whether the components you want to change are actually present on the
            -- entity before you try to mess with them.
        -- Remove speed bonus.
        for i, ent in ipairs(ents) do
            ent.components.locomotor:RemoveExternalSpeedMultiplier(inst, "stunkey")
            if ent.brain then
                ent.brain:Start()
            end
        end
    end
    )
    
    TheInput:AddKeyDownHandler(KEY_Z, function()
        local x, y, z = inst.Transform:GetWorldPosition()
        local range = 5
        local ents = TheSim:FindEntities(x, y, z, range, { "_combat"}, { "player", "structure", "INLIMBO", "NOCLICK" }, {"hostile", "pig"})
        --Find Entity nearby
        if not chargeincooldown and inst.components.sanity.current > 10 and table.getn(ents) > 0 then
        --If chargeincooldown is false and current sanity is larger than 10 and there is more that 0 entities nearby
            chargeincooldown = true --Disable the move by starting the cooldown
            ApplyBuff(Buffs["stunbuff"], inst, ents) --Run the apply buff function, inputting the entity table. God only knows how the rest of the function works.
            inst.components.sanity.current = inst.components.sanity.current - 10 --Remove 10 sanity
        	inst.SoundEmitter:PlaySound("dontstarve/characters/green/stun")
            inst.Light:SetIntensity(0.75)
            inst.Light:SetFalloff(.1)
            inst.Light:SetRadius(1.5)--Deal with lighting
            inst:DoTaskInTime(0.2, function()
                inst.Light:Enable (false)--Hide light after 1 second
            end)
            --Reset everything after 15 seconds
            inst:DoTaskInTime(480, function()
                inst.Light:SetIntensity(.75)
                inst.Light:SetFalloff(.5)
                inst.Light:SetRadius(0.8)
                inst.Light:Enable (true)
                chargeincooldown = false
            end)
        end
        end)
    end

     

    Also the keyhandler.lua which goes in a components folder in scripts.

    Spoiler
    
    local KeyHandler = Class(function(self, inst)
    	self.inst = inst
    	self.handler = TheInput:AddKeyHandler(function(key, down) self:OnRawKey(key, down) end )
    end)
    
    function KeyHandler:OnRawKey(key, down)
    	local player = ThePlayer
      	if (key and not down) and not IsPaused() then
          	player:PushEvent("keypressed", {inst = self.inst, player = player, key = key})
        elseif key and down and not IsPaused() then
          	player:PushEvent("keydown", {inst = self.inst, player = player, key = key})
      	end
    end
    
    function KeyHandler:AddActionListener(Namespace, Key, Action)
    	self.inst:ListenForEvent("keypressed", function(inst, data)
    		if data.inst == ThePlayer then
    			if data.key == Key then
    				if TheWorld.ismastersim then
    					ThePlayer:PushEvent("keyaction"..Namespace..Action, { Namespace = Namespace, Action = Action, Fn = MOD_RPC_HANDLERS[Namespace][MOD_RPC[Namespace][Action].id] })
    				else
    					SendModRPCToServer( MOD_RPC[Namespace][Action] )
    				end
    			end
    		end
    	end)
    
    	if TheWorld.ismastersim then
          self.inst:ListenForEvent("keyaction"..Namespace..Action, function(inst, data)
              if not data.Action == Action and not data.Namespace == Namespace then
                  return
              end
              
              data.Fn(inst)
          end, self.inst) 
        end
    end
    
    return KeyHandler

     

    Thank you for the help! I'm sorry if i was being a pain.

    • Like 1

  6. So I got it to find other things and the basics work

    Here is what I did to get it to work. (It probably isn't very efficient.)

    Spoiler
    
    -- This is an example of how to use the CreateBuff() function to create a new buff.
    CreateBuff("stunbuff", 5.0,
        function(inst)
            -- Apply all your buff code here
            -- Remember to always check whether the components you want to change are actually present on the
            -- entity before you try to mess with them.-- Store the current maxhealth in a variable.
            -- Add 0% speed boost in all situations
    	local x, y, z = inst.Transform:GetWorldPosition()
    	local range = 5
        local ents = TheSim:FindEntities(x, y, z, range, { "_combat"}, { "player", "structure", "INLIMBO", "NOCLICK" }, {"hostile", "pig"})
        for i, ent in ipairs(ents) do
    		--local ds = ent.entity:GetDebugString()
    		--local tagsstr = string.match(ds, "Tags: ([^\n]+)\n")
    		--print(tagsstr)
    		ent.components.locomotor:SetExternalSpeedMultiplier(inst, "stunkey", 0)
    	end
        end,
        function(inst)
            -- Revert your buff code here
            -- Remember to always check whether the components you want to change are actually present on the
            -- entity before you try to mess with them.
        -- Remove speed bonus.
    	local x, y, z = inst.Transform:GetWorldPosition()
    	local range = 45
        local ents = TheSim:FindEntities(x, y, z, range, { "_combat"}, { "player", "structure", "INLIMBO", "NOCLICK" }, { "hostile", "pig"})
        for i, ent in ipairs(ents) do
    		--local ds = ent.entity:GetDebugString()
    		--local tagsstr = string.match(ds, "Tags: ([^\n]+)\n")
    		--print(tagsstr)
        ent.components.locomotor:RemoveExternalSpeedMultiplier(inst, "stunkey")
        end
    	end
    )

     

    I'm not sure how to get cool downs to work and the effects to the character. (Turning off the light and the sanity penalty.)


  7. I think I'm missing something, because I get this error when I press the key

    [00:01:43]: [string "../mods/Green/modmain.lua"]:198: attempt to index local 'instToBuff' (a nil value)
    LUA ERROR stack traceback:
    ../mods/Green/modmain.lua:198 in (upvalue) ApplyBuff (Lua) <194-234>
       buffData = table: 4B41C1D0
       instToBuff = nil
       buffUniqueName = stunbuff
    ../mods/Green/modmain.lua:273 in (field) fn (Lua) <272-274>
    scripts/events.lua:46 in (method) HandleEvent (Lua) <42-49>
       self =
          events = table: 29B1A1C0
       event = 122
       arg = nil
       handlers = table: 4B41C2C0
       k = table: 4B41C270
       v = true
    scripts/input.lua:187 in (method) OnRawKey (Lua) <184-191>
       self =
          onkeyup = table: 29B1A3F0
          entitiesundermouse = table: 8E1BCF40
          onmousebutton = table: 29B19F40
          controllerid_cached = 0
          onkey = table: 29B1A3C8
          enabledebugtoggle = true
          ongesture = table: 29B1A418
          mouse_enabled = true
          ontextinput = table: 29B1A648
          position = table: 29B1A760
          onkeydown = table: 29B1A198
          oncontrol = table: 29B1A8C8
       key = 122
       down = true
    scripts/input.lua:396 in () ? (Lua) <395-397>
       key = 122
       is_up = true
    
    [00:01:43]: [string "../mods/Green/modmain.lua"]:198: attempt to index local 'instToBuff' (a nil value)
    LUA ERROR stack traceback:
        ../mods/Green/modmain.lua:198 in (upvalue) ApplyBuff (Lua) <194-234>
        ../mods/Green/modmain.lua:273 in (field) fn (Lua) <272-274>
        scripts/events.lua:46 in (method) HandleEvent (Lua) <42-49>
        scripts/input.lua:187 in (method) OnRawKey (Lua) <184-191>
        scripts/input.lua:396 in () ? (Lua) <395-397>
    	

    I think I'm just being stupid here, but I'm not sure what is wrong.

    Spoiler
    
    -- This function is rather complicated. You don't need to change anything in here.
    local function ApplyBuff(buffData, instToBuff)
        local buffUniqueName = buffData.uniqueName
        
        -- Cancel any existing duplicate timed buff.
        if instToBuff[buffUniqueName.."Task"] ~= nil then
            buffData.removeFunction(instToBuff)
            instToBuff[buffUniqueName.."Task"]:Cancel()
            instToBuff[buffUniqueName.."Task"] = nil
        end
        
        -- Make sure that our buff is removed BEFORE the entity is saved (the server is closed or player quits).
        -- This is only necessary if you change variables which are saved, like current health, health-penalty, etc.
        -- Without it, you could apply a max-health buff, quit before it ran out, rejoin, and you would have kept
        -- the extra max health!
        local buffOnSave = function(self, inst, data)
            if inst[buffUniqueName.."Task"] ~= nil then
                buffData.removeFunction(inst)
                inst[buffUniqueName.."Task"]:Cancel()
                inst[buffUniqueName.."Task"] = nil
            end
        end
        
        if instToBuff.OnSave ~= nil then
            local oldOnSave = instToBuff.OnSave
            instToBuff.OnSave = function(self, inst, data)
                buffOnSave(self, inst, data)
                oldOnSave(self, inst, data)
            end
        else
            instToBuff.OnSave = buffOnSave
        end
        
        -- Apply the buff.
        buffData.applyFunction(instToBuff)
        
        -- Set up removal after a certain amount of time.
        instToBuff[buffUniqueName.."Task"] = instToBuff:DoTaskInTime(buffData.duration, function(inst)
            buffData.removeFunction(inst)
            inst[buffUniqueName.."Task"] = nil
        end)
    end
    
    
    -- Now to make some buffs and put them in a Buffs-dictionary.
    local Buffs = {"stunbuff",}
    
    -- This function creates a new buff-data object and adds it to the Buffs-dictionary
    -- with the uniqueName as key.
    local function CreateBuff(uniqueName, duration, applyFunction, removeFunction)
        local newBuff = {}
        newBuff.uniqueName = uniqueName
        newBuff.duration = duration
        newBuff.applyFunction = applyFunction
        newBuff.removeFunction = removeFunction
        Buffs[uniqueName] = newBuff
    end
    
    -- This is an example of how to use the CreateBuff() function to create a new buff.
    CreateBuff("stunbuff", 5.0,
        function(inst)
            -- Apply all your buff code here
            -- Remember to always check whether the components you want to change are actually present on the
            -- entity before you try to mess with them.-- Store the current maxhealth in a variable.
            -- Add 0% speed boost in all situations
            inst.components.locomotor:SetExternalSpeedMultiplier(inst, "stunkey", 0)
        end,
        function(inst)
            -- Revert your buff code here
            -- Remember to always check whether the components you want to change are actually present on the
            -- entity before you try to mess with them.
        -- Remove speed bonus.
        inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "stunkey")
        end
    )
    
    TheInput = GLOBAL.TheInput
    local KEY_Z = GLOBAL.KEY_Z
    
    TheInput:AddKeyDownHandler(KEY_Z, function()
        ApplyBuff(Buffs["stunbuff"], inst)
    end)

     

     


  8. I've been using this code to activate the buff

    TheInput:AddKeyDownHandler(KEY_Z, function()
    	ApplyBuff(Buffs["stunbuff"], inst)
    end)

    However this seems to target me and nothing else. I'm not sure how to target things around me and not myself. I also need a way of adding a cool down so that I can't just use it constantly. 

    Here is what the rest of the code looks like.

    Spoiler
    
    -- This function is rather complicated. You don't need to change anything in here.
    local function ApplyBuff(buffData, instToBuff)
        local buffUniqueName = buffData.uniqueName
        
        -- Cancel any existing duplicate timed buff.
        if instToBuff[buffUniqueName.."Task"] ~= nil then
            buffData.removeFunction(instToBuff)
            instToBuff[buffUniqueName.."Task"]:Cancel()
            instToBuff[buffUniqueName.."Task"] = nil
        end
        
        -- Make sure that our buff is removed BEFORE the entity is saved (the server is closed or player quits).
        -- This is only necessary if you change variables which are saved, like current health, health-penalty, etc.
        -- Without it, you could apply a max-health buff, quit before it ran out, rejoin, and you would have kept
        -- the extra max health!
        local buffOnSave = function(self, inst, data)
            if inst[buffUniqueName.."Task"] ~= nil then
                buffData.removeFunction(inst)
                inst[buffUniqueName.."Task"]:Cancel()
                inst[buffUniqueName.."Task"] = nil
            end
        end
        
        if instToBuff.OnSave ~= nil then
            local oldOnSave = instToBuff.OnSave
            instToBuff.OnSave = function(self, inst, data)
                buffOnSave(self, inst, data)
                oldOnSave(self, inst, data)
            end
        else
            instToBuff.OnSave = buffOnSave
        end
        
        -- Apply the buff.
        buffData.applyFunction(instToBuff)
        
        -- Set up removal after a certain amount of time.
        instToBuff[buffUniqueName.."Task"] = instToBuff:DoTaskInTime(buffData.duration, function(inst)
            buffData.removeFunction(inst)
            inst[buffUniqueName.."Task"] = nil
        end)
    end
    
    
    -- Now to make some buffs and put them in a Buffs-dictionary.
    local Buffs = {}
    
    -- This function creates a new buff-data object and adds it to the Buffs-dictionary
    -- with the uniqueName as key.
    local function CreateBuff(uniqueName, duration, applyFunction, removeFunction)
        local newBuff = {}
        newBuff.uniqueName = uniqueName
        newBuff.duration = duration
        newBuff.applyFunction = applyFunction
        newBuff.removeFunction = removeFunction
        Buffs[uniqueName] = newBuff
    end
    
    -- This is an example of how to use the CreateBuff() function to create a new buff.
    CreateBuff("stunbuff", 5.0,
        function(inst)
            -- Apply all your buff code here
            -- Remember to always check whether the components you want to change are actually present on the
            -- entity before you try to mess with them.-- Store the current maxhealth in a variable.
            -- Add 0% speed boost in all situations
            inst.components.locomotor:SetExternalSpeedMultiplier(inst, "stunkey", 0)
        end,
        function(inst)
            -- Revert your buff code here
            -- Remember to always check whether the components you want to change are actually present on the
            -- entity before you try to mess with them.
        -- Remove speed bonus.
        inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "stunkey")
        end
    )
    
    TheInput:AddKeyDownHandler(KEY_Z, function()
        ApplyBuff(Buffs["stunbuff"], inst)
    end)

     

     


  9. So far I have this,

    inst.lightstunisapplied = false
    
    local applybuff = function(inst)
    	-- Apply all your buff stuff here
    	inst.components.locomotor:SetExternalSpeedMultiplier(inst, "lightstunkey", 0)
    end
    
    local removebuff = function(inst)
    	-- Remove all your buff stuff here
    	inst.components.locomotor:RemoveExternalSpeedMultiplier(inst, "lightstunkey")
    end
    
    inst:DoPeriodicTask(0.5, function(inst)
    	if inst == nil or not inst:IsValid() or inst.components.health:IsDead() then
    		-- If the player instance is invalid or they're dead, then we don't want to do anything.
    		return
    	end
    	
    	-- If our buff is applied and our measurements say it should not be applied anymore, we remove it.
    	-- Else, if our buff is not applied and our measurements say it should be, we apply it.
    	if inst.lightstunisapplied and inst.components.sanity:GetPercentWithPenalty() > 0.07 then
    		removebuff(inst)
    	elseif not inst.lightstunisapplied and inst.components.sanity:GetPercentWithPenalty() <= 0.07 then
    		applybuff(inst)
    	end
    end)

    This seems to slow him down when on 7% sanity. I'm not sure how to find an entity and slow them down with the inst thing and I am not sure how I would activate this with a key press.

    I do know however that I'll need a keyhandler.lua as other mods use this when dealing with key inputs.


  10. I had a character that can glow in the dark, I though of an idea where they could use this light to stun enemies. I've looked at examples but I couldn't quite get it right.
    I wanted to make it so when he activates it his light will be gone for 8 minutes (a day) and he'll get a sanity penalty. (About -10 to -15 maybe?)
    I was going to make it activated by a key press by I couldn't quite figure it out.
    Any help would be appreciated.


  11. image.thumb.png.1bfa5875729cfd5de5c9520558a354e6.png

    I added the shell animation zip to the local assets but it didn't work. I think I have to get it to actually use the animations when the backpack is used.

    It uses a custom backpack i retextured but I don't think the backpack has right sprite, so it becomes invisible. I will try later to add the shell sprite onto the sprite sheet and see if it works


  12. I have a backpack that I would like to modify to have the ability of a snurtle shell, where you can hide inside it.

    I got it to work but the bag doesn't have the sprites for it so the bag turns invisible. (See picture)

    Is there a way to give the backpack the animations or sprites needed? Can I swap the animations when you use it and change them back when you stop using it?

    I've attached the backpack's code below.

    image.png.f7cd222af4a2a4af2359ffd31a2e6177.png

    green_backpack.lua


  13. So I looked into the client log and it says this

    [00:04:13]: [string "scripts/widgets/containerwidget.lua"]:29: attempt to index local 'widget' (a nil value)
    LUA ERROR stack traceback:
    scripts/widgets/containerwidget.lua:29 in (method) Open (Lua) <24-132>
       self =
          callbacks = table: 3327C010
          slotsperrow = 3
          inst = 101672 -  (valid:true)
          focus = false
          children = table: 3327BED0
          focus_flow_args = table: 3327C0D8
          focus_target = false
          isopen = false
          owner = 100658 - webber (valid:true)
          open = false
          can_fade_alpha = true
          inv = table: 3327BE80
          parent = 
          name = Container
          bgimage = Image - :
          focus_flow = table: 3327BFC0
          enabled = true
          bganim = UIAnim
          shown = true
       container = 101661 - green_backpack (valid:true)
       doer = 100658 - webber (valid:true)
       widget = nil
    scripts/screens/playerhud.lua:242 in (upvalue) OpenContainerWidget (Lua) <239-244>
       self =
          fireover = FireOver
          sandover = SandOver
          fumeover = FumeOver
          shown = true
          overlayroot = overlays
          last_focus = HUD
          handlers = table: 0CE56A60
          mindcontrolover = UIAnim
          enabled = true
          under_root = under_root
          eventannouncer = EventAnnouncer
          name = HUD
          focus_flow = table: 0CE56330
          bloodover = BloodOver
          storm_root = storm_root
          over_root = over_root
          callbacks = table: 0CE55E30
          popupstats_root = popupstats_root
          sanddustover = UIAnim
          inst = 100659 -  (valid:true)
          focus = true
          targetindicators = table: 32742188
          gogglesover = GogglesOver
          heatover = HeatOver
          focus_flow_args = table: 0CE56920
          focus_target = false
          vig = UIAnim
          owner = 100658 - webber (valid:true)
          can_fade_alpha = true
          iceover = IceOver
          controls = Controls
          clouds = UIAnim
          beefbloodover = BeefBloodOver
          parent = screenroot
          storm_overlays = storm_overlays
          children = table: 0CE56100
          root = root
       container = 101661 - green_backpack (valid:true)
       side = false
       containerwidget = Container
    scripts/screens/playerhud.lua:252 in (method) OpenContainer (Lua) <246-254>
       self =
          fireover = FireOver
          sandover = SandOver
          fumeover = FumeOver
          shown = true
          overlayroot = overlays
          last_focus = HUD
          handlers = table: 0CE56A60
          mindcontrolover = UIAnim
          enabled = true
          under_root = under_root
          eventannouncer = EventAnnouncer
          name = HUD
          focus_flow = table: 0CE56330
          bloodover = BloodOver
          storm_root = storm_root
          over_root = over_root
          callbacks = table: 0CE55E30
          popupstats_root = popupstats_root
          sanddustover = UIAnim
          inst = 100659 -  (valid:true)
          focus = true
          targetindicators = table: 32742188
          gogglesover = GogglesOver
          heatover = HeatOver
          focus_flow_args = table: 0CE56920
          focus_target = false
          vig = UIAnim
          owner = 100658 - webber (valid:true)
          can_fade_alpha = true
          iceover = IceOver
          controls = Controls
          clouds = UIAnim
          beefbloodover = BeefBloodOver
          parent = screenroot
          storm_overlays = storm_overlays
          children = table: 0CE56100
          root = root
       container = 101661 - green_backpack (valid:true)
       side = false
    scripts/components/container_replica.lua:288 in (method) Open (Lua) <274-295>
       self =
          ondetachclassified = function - scripts/components/container_replica.lua:106
          acceptsstacks = true
          _numslots = 0
          _isopen = false
          issidewidget = false
          _cannotbeopened = net_bool (2B0D2528)
          classified = 101668 - container_classified (valid:true)
          inst = 101661 - green_backpack (valid:true)
       doer = 100658 - webber (valid:true)
    scripts/components/container_replica.lua:95 in (field) fn (Lua) <87-101>
       inst = 101661 - green_backpack (valid:true)
       self =
          ondetachclassified = function - scripts/components/container_replica.lua:106
          acceptsstacks = true
          _numslots = 0
          _isopen = false
          issidewidg
    [00:04:13]: [string "scripts/widgets/containerwidget.lua"]:29: attempt to index local 'widget' (a nil value)
    LUA ERROR stack traceback:
        scripts/widgets/containerwidget.lua:29 in (method) Open (Lua) <24-132>
        scripts/screens/playerhud.lua:242 in (upvalue) OpenContainerWidget (Lua) <239-244>
        scripts/screens/playerhud.lua:252 in (method) OpenContainer (Lua) <246-254>
        scripts/components/container_replica.lua:288 in (method) Open (Lua) <274-295>
        scripts/components/container_replica.lua:95 in (field) fn (Lua) <87-101>
        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>