PCMod2 Help

Need help fixing the glitch with panels im pcmod2.


[addons\pcmod2\lua\pcmod\cl_gui.lua:275] attempt to get length of field 'Panels' (a nil value) 

pcmod2 cl_gui



// ---------------------------------------------------------------------------------------------------------
// cl_gui.lua - Revision 1
// Client-Side
// Controls drawing operations on the client
// ---------------------------------------------------------------------------------------------------------

// ---------------------------------------------------------------------------------------------------------
// Define our library
// ---------------------------------------------------------------------------------------------------------

PCMod.Gui = {}
PCMod.Gui.Version = "1.0"
PCMod.SelEntity = 0

PCMod.Gui.MouseDown = false

PCMod.Gui.DebugBoxes = {}
PCMod.Gui.Themes = {}

PCMod.Gui.CamLocked = false
PCMod.Gui.CamLockID = 0

PCMod.Msg( "Gui Library Loaded (V" .. PCMod.Gui.Version .. ")", true )


// ---------------------------------------------------------------------------------------------------------
// Load all themes
// ---------------------------------------------------------------------------------------------------------

function PCMod.LoadTheme( id )
	THEME = {}
	local fn = "pcmod/themes/" .. id
	THEME.FileName = fn
	THEME.Name = "base"
	THEME.Description = "Base theme"
	THEME.Author = "[GU]thomasfn"
	include( fn )
	PCMod.Gui.Themes[ THEME.Name ] = table.Copy( THEME )
	PCMod.Msg( "Theme '" .. THEME.Name .. "' loaded!", true )
end

local ths = file.FindInLua( "pcmod/themes/cl_*" )
if ((!ths) || (#ths == 0)) then
	PCMod.Warning( "No themes to load!" )
else
	for _, v in pairs( ths ) do
		THEME = {}
		PCMod.LoadTheme( v )
	end
end

concommand.Add( "pc_theme_reload", function( pl, com, args ) PCMod.LoadTheme( args[1] ) ; end )


// ---------------------------------------------------------------------------------------------------------
// GetThemeColour - Gets the colour value that a theme specifies
// ---------------------------------------------------------------------------------------------------------
function PCMod.Gui.GetThemeColour( themename, key, default )
	if (!PCMod.Gui.Themes[ themename ]) then return default end
	return PCMod.Gui.Themes[ themename ][ key ] or default
end

// ---------------------------------------------------------------------------------------------------------
// ThemeDraw - Calls a theme draw hook
// ---------------------------------------------------------------------------------------------------------
function PCMod.Gui.ThemeDraw( themename, ... )
	if (!PCMod.Cfg.HighQuality) then return end
	if (!PCMod.Gui.Themes[ themename ]) then return end
	if (!PCMod.Gui.Themes[ themename ].Draw) then return end
	return PCMod.Gui.Themes[ themename ]:Draw( ... )
end

// ---------------------------------------------------------------------------------------------------------
// SURFACE: DrawOutline - Draws an unfilled box
// ---------------------------------------------------------------------------------------------------------
function surface.DrawOutline( x, y, w, h, col )
	if (col) then surface.SetDrawColor( col.r, col.g, col.b, col.a ) end
	surface.DrawLine( x, y, x+w, y ) -- Top Line
	surface.DrawLine( x, y+h, x+w, y+h ) -- Bottom Line
	surface.DrawLine( x, y, x, y+h ) -- Left Line
	surface.DrawLine( x+w, y, x+w, y+h ) -- Right Line
end

// ---------------------------------------------------------------------------------------------------------
// InitFonts - Creates all the fonts we need
// ---------------------------------------------------------------------------------------------------------
function PCMod.Gui.InitFonts()
	PCMod.Msg( "Creating fonts...", true )
	surface.CreateFont( "Tahoma", 20, 400, true, false, "pcmod_3d2d" )
end
hook.Add( "Initialize", "PCMod.Gui.InitFonts", PCMod.Gui.InitFonts )

// ---------------------------------------------------------------------------------------------------------
// DrawSelEnt - Draws information for the selected entity to the screen
// ---------------------------------------------------------------------------------------------------------
function PCMod.Gui.DrawSelEnt()
	if (PCMod.SelEntity == 0) then return end -- No entity = no draw
	local ent = ents.GetByIndex( PCMod.SelEntity ) -- Get the entity
	if ((!ent) || (!ent:IsValid())) then return end -- Check it's validness
	
	// Get the draw coords
	local origin = ent:GetPos():ToScreen()
	
	// Tell the ent to draw
	if (ent.DrawInfo) then ent:DrawInfo( origin ) end
	
	// Clear the stored entity
	PCMod.SelEntity = 0
end
hook.Add( "HUDPaint", "PCMod.Gui.DrawSelEnt", PCMod.Gui.DrawSelEnt )

// ---------------------------------------------------------------------------------------------------------
// DrawWirelessLinks - Draws lines between wireless entities
// ---------------------------------------------------------------------------------------------------------
function PCMod.Gui.DrawWirelessLinks( ent )
	if (!PCMod.Cfg.WirelessInfo) then return end

	// Get all entities in range
	local range = PCMod.Cfg.WirelessRange
	local elist = {}
	if (range > 0) then
		elist = ents.FindInSphere( ent:GetPos(), range )
	else
		elist = ents.FindByClass( ent:GetClass() )
	end
	
	// Calculate starting position
	local startpos = ent:GetPos():ToScreen()
	
	// Cycle through and draw when needed
	local col = PCMod.Cfg.WirelessInfoDrawCol
	surface.SetDrawColor( col.r, col.g, col.b, col.a )
	local offs = 0
	for _, v in pairs( elist ) do
		if ((v) && (v:IsValid()) && (v.IsPCMod) && (v != ent)) then
			if (v:GetGVar( "wireless" )) then
				local endpos = v:GetPos():ToScreen()
				if (math.IsOnScreen( endpos )) then
					surface.DrawLine( startpos.x, startpos.y, endpos.x, endpos.y )
				else
					offs = offs + 1
				end
			end
		end
	end
	if (offs > 0) then
		// There are 'offs' many wireless links not drawn, what to do with this info??? -thomasfn
	end
end

// ---------------------------------------------------------------------------------------------------------
// EnableScreenClicker - Override, we don't want to turn off the mouse whilst we are locked!
// ---------------------------------------------------------------------------------------------------------
if (!gui.ESC) then
	gui.ESC = gui.EnableScreenClicker
	function gui.EnableScreenClicker( enabled )
		if ((PCMod) && (PCMod.Gui)) then
			if (PCMod.Gui.CamLocked) then enabled = true end
		end
		gui.ESC( enabled )
	end
end

// ---------------------------------------------------------------------------------------------------------
// ShowDocument - Shows a printed document on the screen
// ---------------------------------------------------------------------------------------------------------
function PCMod.Gui.ShowDocument( str )
	PCMod.Msg( "Showing printed document! (" .. str .. ")", true )
	if (PCMod.Gui.PDoc) then
		PCMod.Gui.PDoc:Remove()
		PCMod.Gui.PDoc = nil
	end
	local pn = vgui.Create( "PrintedDoc" )
	if (!pn) then return end
	pn:SetText( str, "ScoreboardText" )
	pn:SetVisible( true )
	PCMod.Gui.PDoc = pn
	gui.EnableScreenClicker( true )
end
PCMod.Beam.Hook( "docu_info", PCMod.Gui.ShowDocument )

// ---------------------------------------------------------------------------------------------------------
// HideDocument - Hides a printed document on the screen
// ---------------------------------------------------------------------------------------------------------
function PCMod.Gui.HideDocument()
	if (PCMod.Gui.PDoc) then
		PCMod.Gui.PDoc:Remove()
		PCMod.Gui.PDoc = nil
	end
	gui.EnableScreenClicker( false )
end

// ---------------------------------------------------------------------------------------------------------
// PopupNotice - Pops up a notice window
// ---------------------------------------------------------------------------------------------------------
function PCMod.Gui.PopupNotice( title, text )
	if (PCMod.Gui.Popup) then
		PCMod.Gui.Popup:Remove()
		PCMod.Gui.Popup = nil
	end
	local pn = vgui.Create( "PopupWindow" )
	pn:SetTitle( title )
	pn:Setup( text )
	pn:MakePopup()
	PCMod.Gui.Popup = pn
end
usermessage.Hook( "pcmod_ppnot", function( um )
	PCMod.Gui.PopupNotice( um:ReadString(), um:ReadString() )
end )

// ---------------------------------------------------------------------------------------------------------
// DrawLabel - Draws a label containing a single or multiple strings
// ---------------------------------------------------------------------------------------------------------
function PCMod.Gui.DrawLabel( x, y, font, text, padding, bgcol, txtcol )
	if (PCMod.Gui.CamLocked) then return end
	local tmp_w = {}
	local tmp_h = {}
	local cnt
	surface.SetFont( "ScoreboardText" )
	for cnt=1, #text do
		local tw, th = surface.GetTextSize( text[ cnt ] )
		tmp_w[ cnt ] = tw
		tmp_h[ cnt ] = th
	end
	local w = table.MaxVal( tmp_w ) + padding
	local h = table.TotalVal( tmp_h ) + padding
	draw.RoundedBox( 6, x-(w*0.5), y, w, h, bgcol )
	local cy = 0
	for cnt=1, #text do
		local th = tmp_h[ cnt ]
		draw.SimpleText( text[ cnt ], font, x, y+(padding*0.5)+cy+(th*0.5), txtcol, 1, 1 )
		cy = cy + th
	end
end

// ---------------------------------------------------------------------------------------------------------
// AskForPort - Shows a menu asking for a port
// ---------------------------------------------------------------------------------------------------------
function PCMod.Gui.AskForPort( entid, filter, cstatus )
	
	// Get the port data, validate it
	local pdata = PCMod.PortData[ entid ]	
	if (!pdata) then
		PCMod.Warning( "No port data!" )
		return
	end
	
	// Ensure cstatus is valid
	if (!cstatus) then cstatus = false end
	
	// Create the derma menu
	local dm = DermaMenu()
	local cnt = 0
	
	// Go through all ports, add them to menu
	for k, v in pairs( pdata ) do
		if (((filter) && (v.Type==filter)) || (!filter)) then -- Does the port match our filter?
			if (v.Connected == cstatus) then -- Does the port link status match our fiter?
			
				// Increase the counter, build the display string
				cnt = cnt + 1
				local vt = v.Type
				for _, pt in pairs( PCMod.Cfg.WireTypes ) do
					if (pt.Name == v.Type) then vt = pt.ExtName end
				end
				local str = tostring( k ) .. " - " .. vt
			
				// Add the item
				dm:AddOption( str, function( self )
					RunConsoleCommand( "pc_selport", entid, self.ID )
				end )
				
				// Tell the item what ID we are
				local pn = dm.Panels[ #dm.Panels ]
				if (pn) then pn.ID = k end
				
			end
		end
	end
	
	// Open the menu
	dm:Open()
	
	// Set the menu's position to where the entity is
	local ent = ents.GetByIndex( entid )
	if (ent) then
		local pos = LocalPlayer():GetShootPos()
		local ang = LocalPlayer():GetAimVector()
		local tracedata = {}
		tracedata.start = pos
		tracedata.endpos = pos+(ang*80)
		tracedata.filter = LocalPlayer()
		local trace = util.TraceLine(tracedata)
		local ps = trace.HitPos:ToScreen()
		dm:SetPos( ps.x, ps.y )
	
	end
	
	// If we have no ports, cancel us
	if (cnt == 0) then
		
		// We have no ports shown!
		dm:Remove()
		gui.EnableScreenClicker( false )
		PCMod.Notice( "No ports!" )
	
	end
end

// ---------------------------------------------------------------------------------------------------------
// RegisterClick - Parses a click and checks if it needs to be processed
// ---------------------------------------------------------------------------------------------------------
function PCMod.Gui.RegisterClick( mx, my, ent )
	PCMod.Msg( "Mouse Clicked!", true )
	// Gonna comment this function, because it's long and complicated
	// Ignore mx and my, CalcCursor already knows these bits
	
	// Get the cursor position
	if ((!PCMod.Gui.CamLocked) && (!PCMod.Cfg.AdvancedMode)) then
		PCMod.Msg( "Cam is not locked!", true )
		return
	end
	if (!ent) then ent = ents.GetByIndex( PCMod.Gui.CamLockID ) end
	if ((!ent) || (!ent:IsValid())) then
		PCMod.Msg( "Entity is invalid! (" .. PCMod.Gui.CamLockID .. ")", true )
		return
	end
	local x, y = PCMod.SDraw.CalcCursor( ent )
	
	PCMod.Msg( "Position calculated!", true )
	
	// Get the screenspace for the entity
	local ss = PCMod.SDraw.SSpaces[ ent:EntIndex() ]
	if (ss == "nospace") then return end
	if (!ss) then
		PCMod.Msg( "Entity (" .. tostring( ent:EntIndex() ) .. ") has no screenspace!", true )
		PCMod.SDraw.SSpaces[ ent:EntIndex() ] = "nospace"
		return
	end
	ss = table.Copy( ss )
	
	// Cycle through every device, and 'tag' it if the mouse is potentially ontop of it
	for k, v in pairs( ss ) do
		if (type( v ) == "table") then
			ss[ k ].Tagged = false
			if ((x > v.X) && (x < (v.X+v.W)) && (y > v.Y) && (y < (v.Y+v.H))) then ss[ k ].Tagged = true end
		end
	end
	
	// Now grab the device with the highest priority that is tagged
	local p = -1
	local devn = ""
	for k, v in pairs( ss ) do
		if (type( v ) == "table") then
			if (v.Tagged) then
				if (v.Priority > p) then
					p = v.Priority
					devn = k
				end
			end
		end
	end
	
	// Obtain the device from storage
	local dev_name = tostring( ent:EntIndex() ) .. ":" .. devn
	if (!PCMod.SDraw.DevMap[ dev_name ]) then
		PCMod.Msg( "Clicked on unexistant device!", true )
		return
	end
	local device = ss[ devn ]
	
	// Calculate where abouts the click is on the device
	local dx = (x - device.X) / device.W
	local dy = (y - device.Y) / device.H
	
	// Register the click and set the focus
	PCMod.SDraw.DevFocus = devn
	PCMod.SDraw.DevMap[ dev_name ]:Int_DoClick( dx, dy )
	//PCMod.SDraw.DevMap[ dev_name ]:DoClick( dx, dy )
end

// ---------------------------------------------------------------------------------------------------------
// CalcTextWrap - Calculates how a paragraph should wrap (returns a table of wrapped text)
// ---------------------------------------------------------------------------------------------------------
function PCMod.Gui.CalcTextWrap( text, font, w )
	local cx = 0
	surface.SetFont( font )
	local txt = string.Explode( "", text )
	local tmp = {}
	local cnt = 0
	local line = 1
	for cnt=1,#txt do
		if (!tmp[ line ]) then tmp[ line ] = "" end
		local char = txt[ cnt ]
		local cw, ch = surface.GetTextSize( char )
		cx = cx + cw
		if ((cx > w) || (char == "
")) then
			line = line + 1
			if (!tmp[ line ]) then tmp[ line ] = "" end
			cx = 0
		end
		tmp[ line ] = tmp[ line ] .. char
	end
	return tmp
end

// ---------------------------------------------------------------------------------------------------------
// BindPress - Stops a bind being run in certain circumstances, and performs actions
// ---------------------------------------------------------------------------------------------------------
function PCMod.Gui.BindPress( ply, bind )
	if (PCMod.Cfg.AdvancedMode) then
		if (bind == "+attack") then
			PCMod.Msg( "[BINDPRESS] Attack bind detected!", true )
			local ent = ply:GetEyeTrace().Entity
			if ((ent) && (ent:IsValid()) && (ent.IsScreen) && ((ent:GetPos()-ply:GetPos()):Length() < 64)) then
				local ss = PCMod.SDraw.SSpaces[ ent:EntIndex() ]
				if ((ss) && (ss.SC)) then
					PCMod.Gui.RegisterClick( gui.MouseX(), gui.MouseY(), ent )
					return true
				else
					PCMod.Msg( "[BINDPRESS] No ScreenSpace/Cursor!", true )
				end
			else
				PCMod.Msg( "[BINDPRESS] No entity!", true )
			end
		end
	end
end
hook.Add( "PlayerBindPress", "PCMod.BindPress2", PCMod.Gui.BindPress )


// ---------------------------------------------------------------------------------------------------------
// Include the vgui file
// ---------------------------------------------------------------------------------------------------------
include( "pcmod/cl_vgui.lua" )

This issue has been fixed several times on the forums, you should have searched,
change line 274 to local pn = dm:GetItems()[#dm:GetItems()]

Okay i will try this, and i also searched for this issue i knew it was very common, but i couldnt find anything on it.