I’m coding an attack and debuff handler that will story players stats and debuffs in order to apply them per tick. However, it is erroring and stopping after 1 loop when it arrives at line 45.
Here’s the code:
fx = game.Lighting.Effects
rs = game:GetService("RunService")
playerlist = {
scout = {
chr = game.Workspace.Scout,
maxhp = 100,
speed = 16,
defense = 0,
immunity = 0,
synth = 0,
},
owwy = {
chr = game.Workspace.Owwy,
maxhp = 100,
speed = 16,
defense = 0,
immunity = 0,
synth = 0,
}
}
debuffs = {
poison = {
subjects = {
scout = {[1] = "scout",dmg = 0.2,ticksleft = 0,length = 20, per = 5},
owwy = {[1] = "owwy",dmg = 5,ticksleft = 0,length = 100, per = 20}
},
starttick = function(plr)
end,
endtick = function(plr)
end,
runtick = function()
for i,b in pairs(debuffs["poison"]["subjects"]) do
b["ticksleft"] -= 1
b["length"] -= 1
if b["ticksleft"] <= 0 then
b["ticksleft"] = b["per"]
if playerlist[b[1]]["defense"]~=nil then
local defs = tonumber(playerlist[b[1]]["defense"])
attack(b[1],b["dmg"],defs, playerlist[b[1]]["immunity"],"ticks")
end
end
if b["length"] and b["length"] <= 0 then
table.remove(b)
end
end
end,
}
}
function attack(plr,dmg,def,imm,typ)
local hm = playerlist[plr]["chr"].Humanoid
if typ == "hit" then
hm.Health -= dmg-(dmg*(def/100))
elseif typ == "ticks" then
local att = dmg
if imm > 0 then
local roll = math.random(1,100)
if roll < imm then
att = 0
end
elseif imm<0 then
local roll = math.random(1,100)
if roll < -imm then
att = dmg*2
end
end
hm.Health -= att
end
end
function heal()
end
function generate()
end
function clear()
end
script.Input.Event:connect(function()
end)
while rs.Heartbeat:Wait() do
debuffs["poison"].runtick()
end
Two problems. One, you need to define attack before calling it. Two, not really a problem, but just use i instead of b[1]
fx = game.Lighting.Effects
rs = game:GetService("RunService")
function attack(plr,dmg,def,imm,typ)
local hm = playerlist[plr]["chr"].Humanoid
if typ == "hit" then
hm.Health -= dmg-(dmg*(def/100))
elseif typ == "ticks" then
local att = dmg
if imm > 0 then
local roll = math.random(1,100)
if roll < imm then
att = 0
end
elseif imm<0 then
local roll = math.random(1,100)
if roll < -imm then
att = dmg*2
end
end
hm.Health -= att
end
end
playerlist = {
scout = {
chr = game.Workspace.Scout,
maxhp = 100,
speed = 16,
defense = 0,
immunity = 0,
synth = 0,
},
owwy = {
chr = game.Workspace.Owwy,
maxhp = 100,
speed = 16,
defense = 0,
immunity = 0,
synth = 0,
}
}
debuffs = {
poison = {
subjects = {
scout = {[1] = "scout",dmg = 0.2,ticksleft = 0,length = 20, per = 5},
owwy = {[1] = "owwy",dmg = 5,ticksleft = 0,length = 100, per = 20}
},
starttick = function(plr)
end,
endtick = function(plr)
end,
runtick = function()
for i,b in pairs(debuffs["poison"]["subjects"]) do
b["ticksleft"] -= 1
b["length"] -= 1
if b["ticksleft"] <= 0 then
b["ticksleft"] = b["per"]
if playerlist[i]["defense"]~=nil then
local defs = tonumber(playerlist[b[1]]["defense"])
attack(i,b["dmg"],defs, playerlist[b[1]]["immunity"],"ticks")
end
end
if b["length"] and b["length"] <= 0 then
table.remove(b)
end
end
end,
}
}
function heal()
end
function generate()
end
function clear()
end
script.Input.Event:connect(function()
end)
while rs.Heartbeat:Wait() do
debuffs["poison"].runtick()
end
Hopefully I’m understanding your intentions with the code correctly, but I think the issue stems from here.
Instead of removing the subject from the subjects table, you are removing the first index, in this case the name, from the subject description. Then later since the subject still exists within the subjects table, it loops through again and it tries to index the name which you removed, causing an error: "attempt to index nil with ‘defense’ "
So instead, I would replace the above with this:
if b["length"] and b["length"] <= 0 then
debuffs["poison"]["subjects"][i] = nil
end
This should remove the subject from the subjects table.