Adding Primay, Secondary, and Total Ammo to Custom HUD

I have looked all around, and I found this:
This is my custom HUD code, it is just for dev. purposes.



-snip-


The italics parts are the ones I am having trouble with.
When I run this on my dedicated server, I get this error:



[ERROR] gamemodes/gmodz_ecg/gamemode/cl_init.lua:17: attempt to call method 'Clip1' (a nil value)
  1. unknown - gamemodes/gmodz_ecg/gamemode/cl_init.lua:17


There’s another thread with this same issue, read it please:

http://www.facepunch.com/showthread.php?t=1409599

Yes, but it doesn’t cover his other issue…

This covers proper hud creation ( look at mandatory checks, the second one shows mandatory checks for weapon huds )
https://dl.dropboxusercontent.com/u/26074909/tutoring/vgui/proper_hud_creation.lua.html

Next, don’t create fonts, call Material, etc within the actual hook because you’ll eventually run out of memory. Define them once, change when needed. You can do this inside of the hook, but it is better to just define it outside of the hook and not have to run additional logic to create or not create every frame.

Alright, I followed that thread, and this is my new code:



-snip-


When I run the game, I get this error:
(The HP and ARM of my HUD show now though.)



[ERROR] gamemodes/gmodz_ecg/gamemode/cl_init.lua:50: attempt to concatenate global 'AM' (a nil value)
  1. unknown - gamemodes/gmodz_ecg/gamemode/cl_init.lua:50


Define AM outside of the if statement where you check if the weapon is valid, and set it equal to like 0. Then, if the weapon is valid, do like AM = wep:Clip1(). It isn’t working now because AM is nil, and hasn’t been properly defined.

Repeat with SAM and TAM

Also read my response; you still have a memory leak.

All he has to do is move surface.CreateFont out of the hook.

An IsValid ply would help too; also he calls a lot of LocalPlayer( ) despite creating a reference to the player object.

Here… I cleaned it up a little in the sense that the font doesn’t need to be set before each element unless it changes between elements, or a different draw function could be drawn between elements. I also moved font outside of the hook, and removed duplicate code ( LocalPlayer( ), GetActiveWeapon( ), etc being repeated unnecessarily ) and finally I changed the order so the health and armor can always be drawn regardless of whether or not a weapon is present:


// Create the font ONCE, not every frame
surface.CreateFont( "HUDInfo", {
	font = "DermaDefaultBold",
	size = 13,
	weight = 500,
	antialias = true,
	italic = false,
} )


//
// Since this is for a new game-mode, overwrite HUDPaint
//
function GM:HUDPaint()
	self.BaseClass:HUDPaint()
	local ply = LocalPlayer()

	// Make sure player isn't valid, otherwise check to see if the player is dead. Both cases return..
	if ( !IsValid( ply ) || !ply:Alive() ) then return; end

	// The area to draw health and armor; draw this regardless of weapon status
	local HP  = ply:Health()
	local ARM = ply:Armor()

	// The font will be the same throughout this entire hud, we only need to set it once.
	// We'd change / set between draw items IF we take a break from the draw function whereby a
	// different function could change it, OR if we use different fonts between elements
	surface.SetFont( "HUDInfo" )

	// Health
	surface.SetTextColor( 20, 180, 50, 255 )
	surface.SetTextPos( 20, 20 )
	surface.DrawText( HP )

	// Armor
	surface.SetTextColor( 0, 0, 255, 255 )
	surface.SetTextPos( 20, 40 )
	surface.DrawText( ARM )


	// Create a reference to the active weapon ( it is possible to be invalid )
	local WEP = ply:GetActiveWeapon()

	// If the weapon isn't valid, no point in continuing... Also, because HL2 weapons do not have SWEP functions, 
	// check to make sure the swep functions we use exist ( technically we only need to check 1, but added in repetition to help teach )
	if ( !IsValid( WEP ) || !WEP.Clip1 || !WEP.Clip2 || !WEP.GetAmmoCount ) then return; end

	// Continue with weapon stuff...
	local AM  = WEP:Clip1()
	local SAM = WEP:Clip2()
	local TAM = ply:GetAmmoCount(WEP:GetPrimaryAmmoType())

	--local AM  = WEP:Clip1()
	--local SAM = WEP:Clip2()
	--local TAM = WEP:GetPrimaryAmmoType():GetAmmoCount()

	// Primary Ammo
	surface.SetTextColor( Color( 50, 50, 10, 255 ) )
	surface.SetTextPos( 20, 60 )
	surface.DrawText( "AMMO: " ..AM )

	// Secondary Ammo
	surface.SetTextColor( Color( 50, 50, 20, 255 ) )
	surface.SetTextPos( 20, 80 )
	surface.DrawText( "SAMMO: " ..SAM )

	// Ammo Reserves
	surface.SetTextColor( Color( 50, 50, 50, 255 ) )
	surface.SetTextPos( 20, 100 )
	surface.DrawText( "TAMMO: " ..TAM )
end

Alright, I tried your guys’ ideas above and this is my code:



-snip-


I get no console/script errors when joining, but my Ammo, Secondary Ammo, and Total Ammo does not show in the top left like it should…

Add a few print statements to see where it is occurring. Likely it may be the text… Try using something like surface.DrawText( "Health: " … HP );

If there is an error, it’ll show up with concatenations.

Also, with your HUDShouldDraw, do this: https://dl.dropboxusercontent.com/u/26074909/tutoring/vgui/proper_hud_creation.lua.html

It is the difference between running at 15 seconds over 100 million iterations vs 0.08 seconds.

Alrighty, I fixed my HUD to the improved version, and did the test with HP.
The ("Health: " …HP) works fine as I now see Health: 100 in the top left.
My ammo counters however, still do not show up

Notice the checks I added? They check to make sure functions exist on the weapon.

Which weapon are you holding when they don’t show up? Have you tried any SWEPs?

I tried it on at least 3 guns from each M9K weapon pack, and none of it shows up.

Alright, so I still have a problem. The ammo, secondary ammo, and total ammo still will not show, and I get no errors.
I have tried all of the M9K Weapon packs and HL2Weapons.


 -snip- 

Never Mind, I tried another method and it worked. Thanks for your help guys!