So on my TTT Server which has custom weaponry, and multiple Traitor weapons and Detective weapons, the console gets spammed with this lua error[QUOTE][ERROR] gamemodes/terrortown/gamemode/weaponry.lua:221: attempt to concatenate global 'id' (a nil value)
1. DropNotifiedWeapon - gamemodes/terrortown/gamemode/weaponry.lua:221
2. unknown - gamemodes/terrortown/gamemode/weaponry.lua:258
3. unknown - lua/includes/modules/concommand.lua:69[/QUOTE]
I have no idea how to fix this and it would be nice to fix so my players don't get spammed. This is the code. [CODE]
include("weaponry_shd.lua") -- inits WEPS tbl
-- Pool all SWEP classnames, as we will be sending some over the wire regularly
for k, w in pairs(weapons.GetList()) do
if w then
umsg.PoolString(WEPS.GetClass(w))
end
end
---- Weapon system, pickup limits, etc
local IsEquipment = WEPS.IsEquipment
-- Prevent players from picking up multiple weapons of the same type etc
function GM:PlayerCanPickupWeapon(ply, wep)
if not IsValid(wep) and not IsValid(ply) then return end
-- Disallow picking up for ammo
if ply:HasWeapon(wep:GetClass()) then
return false
elseif not ply:CanCarryWeapon(wep) then
return false
elseif IsEquipment(wep) and wep.IsDropped and (not ply:KeyDown(IN_USE)) then
return false
end
local tr = util.TraceEntity({start=wep:GetPos(), endpos=ply:GetShootPos(), mask=MASK_SOLID}, wep)
if tr.Fraction == 1.0 or tr.Entity == ply then
wep:SetPos(ply:GetShootPos())
end
return true
end
-- Cache role -> default-weapons table
local loadout_weapons = nil
local function GetLoadoutWeapons(r)
if not loadout_weapons then
local tbl = {
[ROLE_INNOCENT] = {},
[ROLE_TRAITOR] = {},
[ROLE_DETECTIVE]= {}
};
for k, w in pairs(weapons.GetList()) do
if w and type(w.InLoadoutFor) == "table" then
for _, wrole in pairs(w.InLoadoutFor) do
table.insert(tbl[wrole], WEPS.GetClass(w))
end
end
end
loadout_weapons = tbl
end
return loadout_weapons[r]
end
-- Give player loadout weapons he should have for his role that he does not have
-- yet
local function GiveLoadoutWeapons(ply)
local r = GetRoundState() == ROUND_PREP and ROLE_INNOCENT or ply:GetRole()
local weps = GetLoadoutWeapons(r)
if not weps then return end
for _, cls in pairs(weps) do
if not ply:HasWeapon(cls) then
ply:Give(cls)
end
end
end
local function HasLoadoutWeapons(ply)
if ply:IsSpec() then return true end
local r = GetRoundState() == ROUND_PREP and ROLE_INNOCENT or ply:GetRole()
local weps = GetLoadoutWeapons(r)
if not weps then return true end
for _, cls in pairs(weps) do
if not ply:HasWeapon(cls) then
return false
end
end
return true
end
-- Give loadout items.
local function GiveLoadoutItems(ply)
local items = EquipmentItems[ply:GetRole()]
if items then
for _, item in pairs(items) do
if item.loadout and item.id then
ply:GiveEquipmentItem(item.id)
end
end
end
end
-- Quick hack to limit hats to models that fit them well
local Hattables = { "phoenix.mdl", "arctic.mdl", "Group01", "monk.mdl" }
local function CanWearHat(ply)
local path = string.Explode("/", ply:GetModel())
if #path == 1 then path = string.Explode("\\", path) end
return table.HasValue(Hattables, path[3])
end
CreateConVar("ttt_detective_hats", "0")
-- Just hats right now
local function GiveLoadoutSpecial(ply)
if ply:IsDetective() and GetConVar("ttt_detective_hats"):GetBool() and CanWearHat(ply) then
if not IsValid(ply.hat) then
local hat = ents.Create("ttt_hat_deerstalker")
if not IsValid(hat) then return end
hat:SetPos(ply:GetPos() + Vector(0,0,70))
hat:SetAngles(ply:GetAngles())
hat:SetParent(ply)
ply.hat = hat
hat:Spawn()
end
else
SafeRemoveEntity(ply.hat)
ply.hat = nil
end
end
-- Sometimes, in cramped map locations, giving players weapons fails. A timer
-- calling this function is used to get them the weapons anyway as soon as
-- possible.
local function LateLoadout(id)
local ply = player.GetByID(id)
if not IsValid(ply) then
timer.Destroy("lateloadout" .. id)
return
end
if not HasLoadoutWeapons(ply) then
GiveLoadoutWeapons(ply)
if HasLoadoutWeapons(ply) then
timer.Destroy("lateloadout" .. id)
end
end
end
-- Note that this is called both when a player spawns and when a round starts
function GM:PlayerLoadout( ply )
if IsValid(ply) and (not ply:IsSpec()) then
-- clear out equipment flags
ply:ResetEquipment()
-- give default items
GiveLoadoutItems(ply)
-- hand out weaponry
GiveLoadoutWeapons(ply)
GiveLoadoutSpecial(ply)
if not HasLoadoutWeapons(ply) then
timer.Create("lateloadout" .. ply:EntIndex(), 1, 0,
function() LateLoadout(ply:EntIndex()) end)
end
end
end
function GM:UpdatePlayerLoadouts()
for k, v in pairs(player.GetAll()) do
GAMEMODE:PlayerLoadout(v)
end
end
---- Weapon switching
local function ForceWeaponSwitch(ply, cmd, args)
-- Turns out even SelectWeapon refuses to switch to empty guns, gah.
-- Worked around it by giving every weapon a single Clip2 round.
-- Works because no weapon uses those.
local wepname = args[1]
local wep = ply:GetWeapon(wepname)
if IsValid(wep) then
-- Weapons apparently not guaranteed to have this
if wep.SetClip2 then
wep:SetClip2(1)
end
ply:SelectWeapon(wepname)
end
end
concommand.Add("wepswitch", ForceWeaponSwitch)
---- Weapon dropping
function WEPS.DropNotifiedWeapon(ply, wep, death_drop)
if IsValid(ply) and IsValid(wep) then
-- Hack to tell the weapon it's about to be dropped and should do what it
-- must right now
if wep.PreDrop then
wep:PreDrop(death_drop)
end
-- PreDrop might destroy weapon
if not IsValid(wep) then return end
-- Tag this weapon as dropped, so that if it's a special weapon we do not
-- auto-pickup when nearby.
wep.IsDropped = true
ply:DropWeapon(wep)
wep:PhysWake()
if HasLoadoutWeapons(ply) then timer.Destroy("lateloadout" .. id) end
-- After dropping a weapon, always switch to holstered, so that traitors
-- will never accidentally pull out a traitor weapon
ply:SelectWeapon("weapon_ttt_unarmed")
end
end
local function DropActiveWeapon(ply)
if not IsValid(ply) then return end
local wep = ply:GetActiveWeapon()
local max = 0
if not IsValid(wep) then return end
if wep.AllowDrop == false then
return
end
if wep.DropOnce == true then
if ( player.NextInvite and player.NextInvite > CurTime() ) then
ply:PrintMessage( HUD_PRINTTALK, "Can't Drop This Right Now." )
return
else
player.NextInvite = CurTime() + 120;
end
end
local tr = util.QuickTrace(ply:GetShootPos(), ply:GetAimVector() * 32, ply)
if tr.HitWorld then
LANG.Msg(ply, "drop_no_room")
return
end
ply:AnimPerformGesture(ACT_ITEM_PLACE)
WEPS.DropNotifiedWeapon(ply,wep)
end
concommand.Add("ttt_dropweapon", DropActiveWeapon)
local function DropActiveAmmo(ply)
if not IsValid(ply) then return end
local wep = ply:GetActiveWeapon()
if not IsValid(wep) then return end
if not wep.AmmoEnt then return end
local amt = wep:Clip1()
if amt < 1 or amt <= (wep.Primary.ClipSize * 0.25) then
LANG.Msg(ply, "drop_no_ammo")
return
end
local pos, ang = ply:GetShootPos(), ply:EyeAngles()
local dir = (ang:Forward() * 32) + (ang:Right() * 6) + (ang:Up() * -5)
local tr = util.QuickTrace(pos, dir, ply)
if tr.HitWorld then return end
wep:SetClip1(0)
ply:AnimPerformGesture(ACT_ITEM_GIVE)
local box = ents.Create(wep.AmmoEnt)
if not
Here is that line for anyone too lazy to look it up.
[code]
local pos, ang = ply:GetShootPos(), ply:EyeAngles()
[/code]
I'm not sure what the problem is but you could try:
[code]
local (pos, ang) = ply:GetShootPos(), ply:EyeAngles()
[/code]
Looking at the code it seems the actual error is occuring on line 333 when it calls GiveEquipmentWeapon(ply:UniqueID(), id)
Try replacing id in that to tonumber(id)
That's not line 221..
If the above post is the case then are you just running the command without arguments? id is being set to args[1] on line 286 and used in 333. It'd throw an error if there were no args.
You haven't pasted the whole thing so line 221 in what you have pasted doesn't match with your error message. However the message mentions 'DropNotifiedWeapon'
This function [lua]function WEPS.DropNotifiedWeapon(ply, wep, death_drop)
if IsValid(ply) and IsValid(wep) then
-- Hack to tell the weapon it's about to be dropped and should do what it
-- must right now
if wep.PreDrop then
wep:PreDrop(death_drop)
end
-- PreDrop might destroy weapon
if not IsValid(wep) then return end
-- Tag this weapon as dropped, so that if it's a special weapon we do not
-- auto-pickup when nearby.
wep.IsDropped = true
ply:DropWeapon(wep)
wep:PhysWake()
if HasLoadoutWeapons(ply) then timer.Destroy("lateloadout" .. id) end
-- After dropping a weapon, always switch to holstered, so that traitors
-- will never accidentally pull out a traitor weapon
ply:SelectWeapon("weapon_ttt_unarmed")
end
end[/lua]
This line [lua]if HasLoadoutWeapons(ply) then timer.Destroy("lateloadout" .. id) end[/lua]
It is using the variable 'id', but id is not set anywhere in that function code.
I suspect you could add [lua]local id = ply:EntIndex()[/lua] before that line to fix it.
[QUOTE=wh1t3rabbit;41121914]You haven't pasted the whole thing so line 221 in what you have pasted doesn't match with your error message. However the message mentions 'DropNotifiedWeapon'
This function [lua]function WEPS.DropNotifiedWeapon(ply, wep, death_drop)
if IsValid(ply) and IsValid(wep) then
-- Hack to tell the weapon it's about to be dropped and should do what it
-- must right now
if wep.PreDrop then
wep:PreDrop(death_drop)
end
-- PreDrop might destroy weapon
if not IsValid(wep) then return end
-- Tag this weapon as dropped, so that if it's a special weapon we do not
-- auto-pickup when nearby.
wep.IsDropped = true
ply:DropWeapon(wep)
wep:PhysWake()
if HasLoadoutWeapons(ply) then timer.Destroy("lateloadout" .. id) end
-- After dropping a weapon, always switch to holstered, so that traitors
-- will never accidentally pull out a traitor weapon
ply:SelectWeapon("weapon_ttt_unarmed")
end
end[/lua]
This line [lua]if HasLoadoutWeapons(ply) then timer.Destroy("lateloadout" .. id) end[/lua]
It is using the variable 'id', but id is not set anywhere in that function code.
I suspect you could add [lua]local id = ply:EntIndex()[/lua] before that line to fix it.[/QUOTE]
This worked! Thank you kind sir!
Sorry, you need to Log In to post a reply to this thread.