i really hope im right here, as on a discord server no one wants to help me for some reason.
We run a Project for a game called Garry's Mod and currently try to get a "Toxic Gas" Script Working.
But we face the following issue
[ERROR] gamemodes/zombierp/plugins/toxicgas/sh_plugin.lua:44: attempt to index local 'item' (a boolean value)
1. IsEquippingGasmask - gamemodes/zombierp/plugins/toxicgas/sh_plugin.lua:44
2. v - gamemodes/zombierp/plugins/toxicgas/sh_plugin.lua:121
3. unknown - gamemodes/helix/gamemode/core/libs/sh_plugin.lua:477
And me being fairly new to Lua, im just completly confused and dont know how to fix it.
Here is the Full Script
local config = {
smokeColor = Color(63, 127, 0),
smokeAlpha = 110,
maskItem = "gasmask",
smokeSpawnerDistance = 100 -- distance between the smoke emitters on the box line
}
local PLUGIN = PLUGIN
PLUGIN.name = "Toxic Gas"
PLUGIN.author = ""
PLUGIN.description = ""
PLUGIN.positions = PLUGIN.positions or {}
PLUGIN.smokeStacks = PLUGIN.smokeStacks or {}
function PLUGIN:LoadData()
PLUGIN.positions = self:GetData()
self:UpdateWorldData()
end
function PLUGIN:SaveData()
self:SetData(PLUGIN.positions)
self:UpdateWorldData()
end
function PLUGIN:UpdateWorldData()
SetNetVar("toxicGasPositions", PLUGIN.positions)
-- global netvar doesn't seem to sync without this
for _, ply in pairs(player.GetAll()) do
ply:SyncVars()
end
end
function PLUGIN:IsEquippingGasmask(ply)
local character = ply:GetCharacter()
if not character then return false end
local inventoryID = character:GetInventory():GetID()
local inventory = ix.item.inventories[inventoryID]
for x, items in pairs(inventory.slots) do
for y, item in pairs(items) do
if item.uniqueID == config.maskItem
and item:GetData("equip") == true then
return true
end
end
end
return false
end
local function GetBoxLine(min, max)
local deltaX = math.abs(min.x - max.x)
local deltaY = math.abs(min.y - max.y)
local lineStart, lineEnd
if deltaX < deltaY then
lineStart = Vector(min.x + (max.x - min.x) / 2, min.y, min.z)
lineEnd = Vector(min.x + (max.x - min.x) / 2, min.y + (max.y - min.y), min.z)
else
lineStart = Vector(min.x, min.y + (max.y - min.y) / 2, min.z)
lineEnd = Vector(min.x + (max.x - min.x), min.y + (max.y - min.y) / 2, min.z)
end
return lineStart, lineEnd
end
if SERVER then
function PLUGIN:Think()
for idx, gasBox in pairs(PLUGIN.positions) do
if PLUGIN.smokeStacks[idx] == nil then
local min, max = gasBox.min, gasBox.max
local startSmoke, endSmoke = GetBoxLine(min, max)
PLUGIN.smokeStacks[idx] = {
count = math.floor(startSmoke:Distance(endSmoke) / config.smokeSpawnerDistance),
stacks = {}
}
for i = 1, PLUGIN.smokeStacks[idx].count do
local smoke = ents.Create("env_smokestack")
smoke:SetPos(startSmoke + (endSmoke - startSmoke):GetNormalized() * (i) * config.smokeSpawnerDistance)
smoke:SetKeyValue("InitialState", "1")
smoke:SetKeyValue("WindAngle", "0 0 0")
smoke:SetKeyValue("WindSpeed", "0")
smoke:SetKeyValue("rendercolor", tostring(config.smokeColor))
smoke:SetKeyValue("renderamt", tostring(config.smokeAlpha))
smoke:SetKeyValue("SmokeMaterial", "particle/particle_smokegrenade.vmt")
smoke:SetKeyValue("BaseSpread", tostring(config.smokeSpawnerDistance))
smoke:SetKeyValue("SpreadSpeed", "10")
smoke:SetKeyValue("Speed", "32")
smoke:SetKeyValue("StartSize", "32")
smoke:SetKeyValue("EndSize", "32")
smoke:SetKeyValue("roll", "8")
smoke:SetKeyValue("Rate", "64")
smoke:SetKeyValue("JetLength", tostring(max.z - min.z))
smoke:SetKeyValue("twist", "6")
smoke:Spawn()
smoke:Activate()
smoke.Think = function()
if PLUGIN.positions[idx] == nil then
smoke:Remove()
end
end
PLUGIN.smokeStacks[idx].stacks[i] = smoke
end
end
end
for _, ply in pairs(player.GetAll()) do
local pos = ply:EyePos()
if not ply:Alive() then continue end
local canBreathe = false
if not canBreathe then
canBreathe = self:IsEquippingGasmask(ply)
end
if not canBreathe then
for _, gasBox in pairs(PLUGIN.positions) do
if pos:WithinAABox(gasBox.min, gasBox.max) then
ply.nextGasDamage = ply.nextGasDamage or CurTime()
if CurTime() >= ply.nextGasDamage then
ply.nextGasDamage = CurTime() + .75
ply:TakeDamage(6)
ix.util.Notify("You are choking. You need a gas mask.", ply)
end
break
end
end
end
end
end
end
if CLIENT then
-- toggles showing toxic gas boxes when in noclip/observer
CreateConVar("ix_toxicgas_observer", "0", FCVAR_ARCHIVE)
local function IsInRange(min, max, scale)
local localPos = LocalPlayer():GetPos()
local distance = min:Distance(max)
if localPos:Distance(min + ((max - min) / 2)) <= distance * scale then
return true
end
return false
end
function PLUGIN:PostDrawTranslucentRenderables()
local toxicGasPositions = GetNetVar("toxicGasPositions")
if toxicGasPositions == nil then return end
for _, gasBox in pairs(toxicGasPositions) do
local min, max = gasBox.min, gasBox.max
if not IsInRange(min, max, 3) then continue end
local observerCvar = GetConVar("ix_toxicgas_observer")
if LocalPlayer():IsAdmin()
and LocalPlayer():GetMoveType() == MOVETYPE_NOCLIP
and observerCvar and observerCvar:GetBool() then
render.DrawWireframeBox(min, Angle(), Vector(0, 0, 0), max - min, Color(142, 222, 131, 255), false)
local startSmoke, endSmoke = GetBoxLine(min, max)
render.DrawLine(startSmoke, endSmoke, Color(0, 255, 0), false)
end
end
end
function PLUGIN:HUDPaint()
-- this is an FPS killer tbh
--[[
local toxicGasPositions = game.GetWorld():GetNetVar("toxicGasPositions")
if toxicGasPositions == nil then return end
local inToxicGas = false
local center
local cornerDist
for _, gasBox in pairs(toxicGasPositions) do
local min, max = gasBox.min, gasBox.max
center = min + ((max - min) / 2)
cornerDist = min:Distance(max)
if LocalPlayer():EyePos():WithinAABox(min, max) then
inToxicGas = true
continue
end
end
if inToxicGas then
local isEquippingGasmask = self:IsEquippingGasmask(LocalPlayer())
local distance = LocalPlayer():EyePos():Distance(center)
ix.util.DrawBlurAt(0, 0, ScrW(), ScrH(), 1, 0.2, isEquippingGasmask and 50 or 255)
end
]]
end
end
ix.command.Add("AddToxicGas", {
description = "Adds a toxic gas box from where you're standing and where you're looking at.",
adminOnly = true,
OnRun = function(self, client)
local pos = client:GetPos()
local tr = client:GetEyeTrace()
if not tr then return end
local hitPos = tr.HitPos
table.insert(PLUGIN.positions, {
min = pos, max = hitPos
})
PLUGIN:SaveData()
return "Added toxic gas."
end
})
ix.command.Add("RemoveToxicGas", {
description = "Removes the closest toxic gas point relative to you.",
adminOnly = true,
OnRun = function(self, client)
local closestDistance = -1
local closestIndex = -1
for idx, gasBox in pairs(PLUGIN.positions) do
local min, max = gasBox.min, gasBox.max
local center = min + ((max - min) / 2)
local distance = client:GetPos():Distance(center)
if closestDistance == -1 or distance < closestDistance then
closestDistance = distance
closestIndex = idx
end
end
if closestIndex ~= -1 then
table.remove(PLUGIN.positions, closestIndex)
if PLUGIN.smokeStacks[closestIndex] then
for k, v in pairs(PLUGIN.smokeStacks[closestIndex].stacks) do
v:Remove()
end
table.remove(PLUGIN.smokeStacks, closestIndex)
end
PLUGIN:SaveData()
return "Removed 1 toxic gas box."
else
return "Could not find any toxic gas to remove!"
end
end
})
I Really hope someone can help me with that as im trying since 2 days now
Try replacing for y, item in pairs(items) do
with for item, _ in pairs(items) do
.
Reason: there is a chance that items
is a set, i.e., a Lua table, in which keys are set members and values are true
.