Fixing GM12 addon: How to get a list of weapons?

Alright, Hi.
I had a problem with trying to fix this addon a while ago but it was a user error on my behalf.
This time it’s an actual LUA problem.

First of all, The addon required a list of weapons, it used to do this using:


local fullweps = list.Get("NPCWeapons")

but this was causing a strange error where the weapons list would only display various weapons prefixed with
"Mad Cows : "

I don’t have any madcows weapons installed and trying to spawn an NPC with any of these makes the game complain that it doesn’t recognise the weapon in the console. Failing to realise that it needed a list and not a table I tried using weapons.GetList(), Which returns a table and thus doesn’t work. (can’t find any ways to convert tables to lists either.)
Also there is nothing in the code I could find that could have been causing the “mad cows :” problem, I disabled all my addons and the weapon list just ended up being completely empty, not doing anything when clicked.

Additionally, The addon used to work completely fine with every SWep, even mad cows SWeps.

Anyone able to help?
Here’s the complete code:


TOOL.Category = "Krak's Tools"
TOOL.Name = "Squad NPCs"
TOOL.Command = nil
TOOL.ConfigName = ""

TOOL.ClientConVar ["npc"] = "npc_combine_s"
TOOL.ClientConVar ["weapon"] = "weapon_smg1"
TOOL.ClientConVar ["squad"] = "alpha"
TOOL.ClientConVar ["assign"] = "1"
TOOL.ClientConVar ["spawnangle"] = "0"
TOOL.ClientConVar ["offset_x"] = "0"
TOOL.ClientConVar ["offset_y"] = "0"
TOOL.ClientConVar ["offset_z"] = "0"
TOOL.ClientConVar ["worldalign"] = "0"

--TOOL.ClientConVar ["spawnflags"] = "0"
--keyvalues={}

npcs = {
	{"Combine Soldier","npc_combine_s"},
	{"Combine Elite","npc_combine_elite"},
	{"Combine Prison Guard","npc_combine_prisong"},
	{"Metro Police","npc_metropolice"},
	{"Citizen Refugee","npc_citizen"},
	{"Citizen Downtrodden","npc_citizen_dt"},
	{"Citizen Rebel","npc_rebel"},
	{"Citizen Rebel Medic","npc_rebel_medic"},
	{"Zombie","npc_zombie"},
	{"Zombie Torso","npc_zombie_torso"},
	{"Zombie (Poison)","npc_poisonzombie"},
	{"Zombie (Fast)","npc_fastzombie"},
	{"Zombie Torso (Fast)","npc_fastzombie_torso"},
	{"Zombine","npc_zombine"},
	{"Headcrab","npc_headcrab"},
	{"Headcrab (Fast)","npc_headcrab_fast"},
	{"Headcrab (Poison)","npc_headcrab_black"},
	{"Antlion","npc_antlion"},
	{"Antlion Guard","npc_antlionguard"},
	{"Antlion Worker","npc_antlion_worker"},
	--Add Story NPCs
	{"Barney","npc_barney"},
	{"Alyx","npc_alyx"},
	{"Eli Vance","npc_eli"},
	{"Isaac Kleiner","npc_kleiner"},
	{"Judith Mossman","npc_mossman"},
	{"Dr. Magnusson","npc_magnusson"},
	{"Wallace Breen","npc_breen"},
	{"G-Man","npc_gman"},
	{"D0g","npc_dog"},
	{"Father Grigori","npc_monk"},
	{"Vortigaunt","npc_vortigaunt"},
	--Combine Stuff
	{"Manhack","npc_manhack"},
	{"Rollermine","npc_rollermine"},
	{"Combine Camera","npc_combine_camera"},
	{"Combine Sniper *","npc_sniper"},
	{"Combine Mine (Hopper)","combine_mine"},
	{"Combine Turret (Ceiling)","npc_turret_ceiling"},
	{"Combine Turret (Mobile)","npc_turret_floor"},
	{"Combine Scanner","npc_cscanner"},
}

if CLIENT then
	language.Add ("Tool_squadnpcs_name", "Squad NPC Tool")
	language.Add ("Tool_squadnpcs_desc", "Create NPCs that work and communicate in a squad.")
	language.Add ("Tool_squadnpcs_0", "Primary: Spawn NPC.	Secondary: Assign Existing NPC to Squad.")
	language.Add ("Undone_Squad NPC", "Undone Squad NPC")
	math.randomseed(os.time())
end
 
function TOOL:LeftClick( trace )
	local ply = self:GetOwner()
	local tospawn = self:GetClientInfo("npc")
	local skin=tospawn	

	if(tospawn=="npc_combine_elite" or tospawn=="npc_combine_prisong") then
		tospawn="npc_combine_s"
	end
	if(tospawn=="npc_rebel" or tospawn=="npc_citizen_dt" or tospawn=="npc_rebel_medic") then
		tospawn="npc_citizen"
	end
	
	local newEnt=ents.Create(tospawn)
	
	--Give Weapons
	if (self:GetClientInfo("weapon") != "" and self:GetClientInfo("weapon") != "weapon_none") then
		newEnt:SetKeyValue("additionalequipment", self:GetClientInfo("weapon"))
	end
	
	/*--Spawnflags and Key Values
	newEnt:SetKeyValue("spawnflags",self:GetClientInfo("spawnflags"))
	for k,v in SortedPairs(keyvalues) do 
		newEnt:SetKeyValue(k,v)
	end*/	
	
	if(self:GetClientInfo("assign")=="1") then
		newEnt:SetKeyValue("squadname", self:GetClientInfo("squad"))
	end
	
	--Citizen Skins
	if(skin=="npc_rebel") then
		newEnt:SetKeyValue("citizentype",CT_REBEL)
		newEnt:SetKeyValue("spawnflags",SF_CITIZEN_RANDOM_HEAD)
	end
	if(skin=="npc_rebel_medic") then
		newEnt:SetKeyValue("citizentype",CT_REBEL)
		newEnt:SetKeyValue("spawnflags",SF_CITIZEN_MEDIC)
	end
	if(skin=="npc_citizen_dt") then
		newEnt:SetKeyValue("citizentype",CT_DOWNTRODDEN)
	end
	if(skin=="npc_citizen") then
		newEnt:SetKeyValue("citizentype",CT_REFUGEE)
	end
		
	--Combine Skins
	if(skin=="npc_combine_s") then
		newEnt:SetKeyValue("model","models/combine_soldier.mdl")
	end
	if(skin=="npc_combine_elite") then
		newEnt:SetKeyValue("model","models/combine_super_soldier.mdl")
	end
	if(skin=="npc_combine_prisong") then
		newEnt:SetKeyValue("model","models/combine_soldier_prisonguard.mdl")
	end
	if(skin=="npc_combine_icky") then
		newEnt:SetKeyValue("model","models/soldier_stripped.mdl")
	end
	if(skin=="npc_vortigaunt") then
		newEnt:SetKeyValue("model","models/vortigaunt.mdl")
	end
	
	if(skin=="npc_turret_ceiling") then
		newEnt:SetKeyValue("spawnflags","32")
	end
	
	newEnt:Spawn()
	newEnt:SetPos(trace.HitPos+Vector(self:GetClientInfo("offset_x"),self:GetClientInfo("offset_y"),self:GetClientInfo("offset_z")+1))
	
	if(self:GetClientInfo("worldalign")=="1") then
		newEnt:SetAngles(Angle(0,self:GetClientInfo("spawnangle"),0))
	else
		newEnt:SetAngles(Angle(0,ply:GetForward():GetNormal():Angle().y+self:GetClientInfo("spawnangle"),0))
		--newEnt:SetAngles(Angle(0,self:GetClientInfo("spawnangle"),0))
	end
	--
	
	undo.Create("Squad NPC")
		undo.AddEntity(newEnt)
		undo.SetPlayer(ply)
	undo.Finish()
	return true
end

function TOOL:RightClick(trace)
	local ply = self:GetOwner()
	--This is bad because it does not really know if the hit entity is an NPC.
	if(trace.Entity:GetClass()!="prop_physics" and trace.HitNonWorld)then
		trace.Entity:SetKeyValue("squadname", self:GetClientInfo("squad"), 1)
		
		--Debug Stuff
		Msg("Squad NPC attempt to Reassign squadname to ")
		Msg(self:GetClientInfo("squad"))
		Msg("
Actually is ")
		Msg(trace.Entity:GetKeyValues().squadname)
		Msg("
")
		return true
	else
		return false
	end
end

--Reload function spams debug info
function TOOL:Reload(trace)
	local ply = self:GetOwner()
	if(trace.HitNonWorld)then
		Msg("
Squad is ")
		Msg(trace.Entity:GetKeyValues().squadname)
		Msg("
Model is ")
		Msg(trace.Entity:GetModel())
		Msg("
Type is ")
		Msg(trace.Entity:GetClass())
		Msg("
")
		return true
	else
		return false
	end
end

function TOOL:Think()
	if(squadnpcs_npc=="") then
		squadnpcs_npc="npc_combine_s"
	end
	if(squadnpcs_spawnangle=="") then
		squadnpcs_spawnangle="0"
	end
	if(squadnpcs_offset_x=="") then
		squadnpcs_offset_x="0"
	end
	if(squadnpcs_offset_y=="") then
		squadnpcs_offset_y="0"
	end
	if(squadnpcs_offset_z=="") then
		squadnpcs_offset_z="0"
	end
end
 
function TOOL.BuildCPanel( panel )
	panel:AddControl("Header", { Text = "Squad NPCs", Description = "Create NPCs that work and communicate in a squad." })
	local fullweps = list.Get("NPCWeapons")
	local fullnpcs = list.Get("NPC")
 
	-- Set NPC
	params = {}
	params.Label = "NPC"
	params.Height = 400
	params.Options = {}
	for k,v in pairs (npcs) do 
		params.Options[v[1]] = {squadnpcs_npc = v[2]}    
	end
	for k,v in pairs(fullnpcs) do 
		params.Options[v.Name or k] = {squadnpcs_npc = v.Class}
		keyvalues=v.KeyValues
		squadnpcs_spawnflags=v.SpawnFlags
	end
	panel:AddControl ("ListBox", params)

	-- Set Weapon
	params = {}
	params.Label = "Weapon"
	params.MenuButton = 0
	params.Folder = "settings/menu/main/construct/test/"
	params.Options = {}
	list.Add("params.Options","weapon_none","None")
	for k,v in SortedPairs (fullweps) do 
	params.Options[v] = {squadnpcs_weapon = k}    
end
	panel:AddControl ("ComboBox", params)

	params = {}
	params.Label = "Squad"
	params.MaxLength = 25
	params.Text = squadnpcs_squad
	params.Command = "squadnpcs_squad"
	panel:AddControl("TextBox",params)
	
	params = {}
	params.Label = "Angle Offset"
	params.Type="Float"
	params.Min=0
	params.Max=360
	params.Command = "squadnpcs_spawnangle"
	panel:AddControl("Slider",params)
	panel:CheckBox("Align to World","squadnpcs_worldalign")
	
	params.Label = "X Offset"
	params.Min=-1000
	params.Max=1000
	params.Command = "squadnpcs_offset_x"
	panel:AddControl("Slider",params)
	
	params.Label = "Y Offset"
	params.Command = "squadnpcs_offset_y"
	panel:AddControl("Slider",params)
	
	params.Label = "Z Offset"
	params.Command = "squadnpcs_offset_z"
	panel:AddControl("Slider",params)	
	
	panel:CheckBox("Disable AI","ai_disabled")
	panel:CheckBox("Assign Squads (Uncheck to spawn regular NPCs)","squadnpcs_assign")
end

Some additional help would be nice if you see anything else wrong.

Hold C > NPCs > Weapon Override. If you see the same in that menu, then something on your client adds a bunch of MadCows weapons as NPC weapons. Search for list.Add( “NPCWeapons” or list.Set( “NPCWeapons” in your addons, etc.

My weapons override list is fine.

It has a few custom weapons but it has no mad cows weapons.

I mean, it is an addon doing this but it should still be showing the rest of the weapons too when I scroll up and down the list, as well as when all my addons are disabled.

Mad cows weapons are m9k I believe, try uninstalling it if you have it.

M9K was one of the first thing I uninstalled to try and fix the issue.
Didn’t work.

Oh, it’s “NPCUsableWeapons”, not “NPCWeapons” now.

Didn’t work, NPCUsableWeapons seems to be a table.

Well, yes it is, it has two fields, title for ‘nice’ name of the swep, and class for the weapon class. I am 99% sure you could’ve just PrintTable’d it out and find it out yourself.

But it doesn’t help me at all because, as I stated in my first post, I can’t use a table and I can’t find a way to covert the table to the type it needs.

Just add .class where needed, omg.

That doesn’t help. What the hell is .class and where do I put it.

I’m only at like, Intermediate LUA skill level here.

.class is a field in the table. If you had intermediate Lua skill, you’d know the solution without creating this thread.



for k,v in SortedPairs (fullweps) do 
    params.Options[v.title] = {squadnpcs_weapon = v.class}
end

Here’s the code.

For me, I class intermediate as being just above beginner, Beginner is barely able to do stuff, Intermediate is able to do basic stuff with alot of googling.

Sorry if i’ve been bothering you and thanks for the code, it worked well.

For the purposes of learning, Could you direct me to a web page or make a post explaining how the code you gave me works and why it was needed? To stop me from annoying more people.

You are not “above beginner” if you don’t know how to work with tables.

Here’s a useful link:
http://www.facepunch.com/showthread.php?t=1337945

Learn the language you are trying to use.

Please stop killing me.

I’m still learning.

Is that so damn hard to understand?

I’ve fixed GM12 SWeps before, this was my first attempt fixing a STool.

Have you tried just list.Get( “Weapon” );?

As seen in sandbox cl search module:
[lua] for k, v in pairs( list.Get( “Weapon” ) ) do

	v.ClassName = k
	v.PrintName = v.PrintName
	v.ScriptedEntityType = 'weapon'
	table.insert( ents, v )
		
end[/lua]

I am not killing you, I am just saying that you are using incorrect terms.

Because that also includes all the weapons that are unusable by NPCs.

I think what has happened here is that our definitions of skill are vastly different.

No, I would not call you intermediate, I wouldn’t call myself intermediate and I knew what to do here.

Again, a case of people seeing things such as beginner, intermediate, etc. differently to each other.