• Need Help with this error. Please help!
    5 replies, posted
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.