• Colors throws a nil value error
    8 replies, posted
[lua]function hud:PaintPanel( x, y, w, h, colors) surface.SetDrawColor( clr( colors.border ) ) surface.DrawOutlinedRect( x, y, w, h) x = x + 1 y = y + 1 w = w - 2 h = h - 2 surface.SetDrawColor( clr( colors.background ) ) surface.DrawRect( x, y, w, h ) end[/lua] I'm throwing this error: Hook 'PaintOurHud' Failed: [gamemodes\classstrike\gamemode\cl_hud.lua:42] attempt to index local 'colors' (a nil value) on the line for "surface:SetDrawColor()". I'm not really sure why. It seems to think that colors is a null value, but should it even be throwing that error on a function. Colors is defined in the parameters of the function? Sorry if its a stupid question. Just learning here.
well just because it's being defined in the function definition doesn't mean it's really there. I just checked and that function doesn't have a page on the wiki, change it to what I have below and see what you get. [lua] function hud:PaintPanel( ... ) PrintTable(arg) end [/lua] This will print all the arguments that function is being passed and a field n which is the arg count, any nil value will drop from the result table, they are listed in order otherwise. [editline]15th May 2011[/editline] Also if you haven't done so, you should read [url=http://www.lua.org/pil/index.html]Programming in Lua[/url] and the page from that which explains the ... is [url=http://www.lua.org/pil/5.2.html]Section 5.2 - Variable Number of Arguments[/url] Hope this helps.
Alright, I'm not wholly sure if I understand what you mean, but I've done that and this is what pops up in the console. [code]1 = 35 2 = 871 3 = 320 4 = 118 5: border: a = 255 b = 128 g = 255 r = 190 background: a = 75 b = 0 g = 240 r = 120 n = 5 Hook 'PaintOurHud' Failed: [gamemodes\classstrike\gamemode\cl_hud.lua:8] attempt to index global 'colors' (a nil value) [/code] 'colors' being the fifth value in the table and it is defined, so I'm not sure what the problem is. I've read the majority of Programming in Lua and I just reread 5.2, and although I see how it applies to what you've posted, I'm not sure how I can apply it to solving my error. Thanks for your help though so far. Just still not sure what I'm doing wrong exactly, as according to the table of arguments, it is defined.
Hmm, odd, and that is line 8 from cl_hud.lua? It is referencing the PaintOurHud hook, i'm not quite sure you're looking in the right spot, because, yes, colors is defined. Also the error says global and I believe colors is local to that function. I'd say double check that is line 8 and if so post your cl_hud.lua [editline]15th May 2011[/editline] Wait a sec, you removed the other code from the function when you did the test, right? If you did then it can't be that function causing the error.
I did, but the error log I posted was from after I decommented the code and ran it with the PrintTable(arg). When I run it with just the PrintTable, it doesn't throw an error, but it fails to properly draw the panels, obviously. Here is the full code. The error, exactly is: Hook 'PaintOurHud' Failed: [gamemodes\classstrike\gamemode\cl_hud.lua:8] attempt to index global 'colors' (a nil value) [lua]-- Create the hud object hud = {} local function clr( color ) return color.r, color,g, color.b, color.a end function hud:PaintPanel(...) PrintTable(arg) surface.SetDrawColor( clr( colors.border ) ) surface.DrawOutlinedRect( x, y, w, h) x = x + 1 y = y + 1 w = w - 2 h = h - 2 surface.SetDrawColor( clr( colors.background ) ) surface.DrawRect( x, y, w, h ) end function hud:PaintBar( x, y, w, h, colors, value) self.PaintPanel( x, y, w, h, colors ) x = x + 1 y = y + 1 w = w - 2 h = h - 2 surface.SetDrawColor( clr( colors.background )) surface.DrawOutlinedRect( x, y, w, h ) local width = w * math.Clamp( value, 0, 1) local shade = 4 surface.SetDrawColor( clr( colors.shade) ) surface.DrawRect( x, y, width, shade ) surface.SetDrawColor( clr( colors.fill )) surface.DrawRect( x, y + shade, width, width, h - shade ) end function hud:PaintText(x, y, text, font, colors) surface.SetFont( font ) surface.SetTextPos(x+1, y+1) surface.SetTextColor( clr( colors.shadow ) ) surface.DrawText( text ) surface.SetTextPos( x, y ) surface.SetTextColor( clr( colors.text ) ) surface.DrawText( text ) end function hud:TextSize( text, font ) surface.SetFont( font ) return surface. GetTextSize( text ) end local vars = { font = "TargetID", padding = 10, margin = 35, text_spacing = 2, bar_spacing = 5, bar_height = 5, width = .25, } local colors = { background = { border = Color( 190, 255, 128, 255), background = Color(120, 240, 0, 75 ) }, text = { shadow = Color( 0, 0, 0, 200 ), text = Color( 255, 255, 255, 255 ) }, health_bar = { border = Color(255, 0, 0, 255), background = Color( 255, 0, 0, 75), shade = Color(255, 104, 104, 255), fill = Color(232, 0, 0, 255) }, suit_bar = { border = Color(0, 0, 255, 255), background = Color(0, 0, 255, 75), shade = Color(136, 136, 255, 255), fill = Color( 0, 0, 219, 255 ) } } local function HUDPaint() client = client or LocalPlayer() if (!client:Alive() ) then return end local _, th = hud:TextSize( "TEXT", vars.font ) local i = 2 local width = vars.width * ScrW() local bar_width = width - ( vars.padding * i ) local height = (vars.padding * i) + (th * i) + (vars.text_spacing * i) + (vars.bar_height * i) * vars.bar_spacing local x = vars.margin local y = ScrH() - vars.margin - height local cx = x + vars.padding local cy = y + vars.padding hud:PaintPanel( x, y, width, height, colors.background) local by = th + vars.text_spacing local text = string.format( "Health: %iHP", client:Health( ) ); -- get health text hud:PaintText( cx, cy, text, vars.font, colors.text ); -- paint health text and health bar hud:PaintBar( cx, cy + by, bar_width, vars.bar_height, colors.health_bar, client:Health( ) / 100 ); by = by + vars.bar_height + vars.bar_spacing; -- increment text position local text = string.format( "Suit: %iSP", client:Armor( ) ); -- get suit text hud:PaintText( cx, cy + by, text, vars.font, colors.text ); -- paint suit text and suit bar hud:PaintBar( cx, cy + by + th + vars.text_spacing, bar_width, vars.bar_height, colors.suit_bar, client:Armor( ) / 100 ); end hook.Add( "HUDPaint", "PaintOurHud", HUDPaint )[/lua] FYI, this is code out of one of the HUD tutorials on the Lua wiki, so after painfully retyping most of it (I find that I learn better that way), it really frustrates me to not see it work. But alas, such is learning another programming language. Anyway, yeah, there you go, I'm terribly confused. Edit: Hold on, I replaced the '...' with the original 'x, y, w, h, colors' and now its throwing this error: Hook 'PaintOurHud' Failed: [@lua\includes\util.lua:35] bad argument #1 to 'pairs' (table expected, got nil)
Did you remove PrintTable(args)? Anyway, I'm too tired to think more tonight, i'll look the code over tomorrow.
Just to be safe rename the main colors table since you use colors for a lot of variables, change it to something like hudColors or just something else, besides it get's confusing having too many things with the same name, and that might be part of your problem. Also a line or so above where colors if defined, line 69 you have an extra comma, not a big problem, but thought i'd let you know. and instead of the clr function you made you could try unpack(color.border) it explodes a table in to arguments. Well i'll post later if I think of something else. [editline]16th May 2011[/editline] Found it! That was bugging me... anyway comment out line 21 [lua] self.PaintPanel( x, y, w, h, colors ) [/lua] it's passing only 4 values for some reason, I edited you code in luapad till it worked, and that's what I found, but I'll post my version just in case I changed something else that I don't remember. I renamed a bunch of stuff, and changed the way the table is being created, I think my way is a little slower but I think it's easier to read, but it's only called once on startup and it's a small table so it should be fine. [lua] -- Create the hud object hud = {} local function splitColor( clr ) return clr.r, clr,g, clr.b, clr.a end function hud:PaintPanel(x,y,w,h, clrs) ` surface.SetDrawColor( splitColor(clrs.border) ) surface.DrawOutlinedRect( x, y, w, h) x = x + 1 y = y + 1 w = w - 2 h = h - 2 surface.SetDrawColor( splitColor(clrs.background) ) surface.DrawRect( x, y, w, h ) end function hud:PaintBar( x, y, w, h, clrs, value) --only passing 4 values.. odd and not sure you need it anyway --self.PaintPanel( x, y, w, h, clrs ) x = x + 1 y = y + 1 w = w - 2 h = h - 2 surface.SetDrawColor( splitColor(clrs.background)) surface.DrawOutlinedRect( x, y, w, h ) local width = w * math.Clamp( value, 0, 1) local shade = 4 surface.SetDrawColor( splitColor(clrs.shade) ) surface.DrawRect( x, y, width, shade ) surface.SetDrawColor( splitColor(clrs.fill)) surface.DrawRect( x, y + shade, width, width, h - shade ) end function hud:PaintText(x, y, text, font, clrs) surface.SetFont( font ) surface.SetTextPos(x+1, y+1) surface.SetTextColor( splitColor(clrs.shadow) ) surface.DrawText( text ) surface.SetTextPos( x, y ) surface.SetTextColor( splitColor(clrs.text ) ) surface.DrawText( text ) end function hud:TextSize( text, font ) surface.SetFont( font ) return surface. GetTextSize( text ) end local vars = { font = "TargetID", padding = 10, margin = 35, text_spacing = 2, bar_spacing = 5, bar_height = 5, width = 0.25 } hud.HudColors = {} hud.HudColors["background"] = {} hud.HudColors["background"]["border"] = Color( 190, 255, 128, 255) hud.HudColors["background"]["background"] = Color(120, 240, 0, 75 ) hud.HudColors["text"] = {} hud.HudColors["text"]["shadow"] = Color( 0, 0, 0, 200 ) hud.HudColors["text"]["text"] = Color( 255, 255, 255, 255 ) hud.HudColors["health_bar"] = {} hud.HudColors["health_bar"]["border"] = Color(255, 0, 0, 255) hud.HudColors["health_bar"]["background"] = Color( 255, 0, 0, 75) hud.HudColors["health_bar"]["shade"] = Color(255, 104, 104, 255) hud.HudColors["health_bar"]["fill"] = Color(232, 0, 0, 255) hud.HudColors["suit_bar"] = {} hud.HudColors["suit_bar"]["border"] = Color(0, 0, 255, 255) hud.HudColors["suit_bar"]["background"] = Color(0, 0, 255, 75) hud.HudColors["suit_bar"]["shade"] = Color(136, 136, 255, 255) hud.HudColors["suit_bar"]["fill"] = Color( 0, 0, 219, 255 ) local function HUDPaint() client = client or LocalPlayer() if (!client:Alive() ) then return end local _, th = hud:TextSize( "TEXT", vars.font ) local i = 2 local width = vars.width * ScrW() local bar_width = width - ( vars.padding * i ) local height = (vars.padding * i) + (th * i) + (vars.text_spacing * i) + (vars.bar_height * i) * vars.bar_spacing local x = vars.margin local y = ScrH() - vars.margin - height local cx = x + vars.padding local cy = y + vars.padding hud:PaintPanel( x, y, width, height, hud.HudColors.background) local by = th + vars.text_spacing local text = string.format( "Health: %iHP", client:Health( ) ); -- get health text hud:PaintText( cx, cy, text, vars.font, hud.HudColors.text ); -- paint health text and health bar hud:PaintBar( cx, cy + by, bar_width, vars.bar_height, hud.HudColors.health_bar, client:Health( ) / 100 ); by = by + vars.bar_height + vars.bar_spacing; -- increment text position local text = string.format( "Suit: %iSP", client:Armor( ) ); -- get suit text hud:PaintText( cx, cy + by, text, vars.font, hud.HudColors.text ); -- paint suit text and suit bar hud:PaintBar( cx, cy + by + th + vars.text_spacing, bar_width, vars.bar_height, hud.HudColors.suit_bar, client:Armor( ) / 100 ); end hook.Add( "HUDPaint", "PaintOurHud", HUDPaint ) [/lua] Well I hope you get it working it looks like a ok hud design.
Awesome! Got it to work. I had some trouble with the background, but I eventually got it to work. I'm still not sure what the problem was. Thanks Fantym, you were an amazing help. Anyway, I didn't want to make a new thread, but I worked out a new HUD design, this one based on my own new knowledge instead of a tutorial and I managed to work something out. It's really simple - health and shield bar in the corner with Health: Health% and Shield: Shield%. It's all supposed to be bottom left. The problem that I have is that the shield and health text indicators don't seem to go where I tell them to go - which should be smack dab in the bottom left. Instead they are top right. What am I doing wrong! Code below. [lua]HUD = {} -- Basic table to store our stuff within. HUD.ColorSchema = { health_bar = Color( 255, 0, 0, 255 ), shield_bar = Color( 0, 0, 255, 255) , health_text = Color( 255, 255, 255, 255), shield_text = Color( 255, 255, 255, 255), health_text_outline = Color( 0, 0, 0, 150 ), shield_text_outline = Color( 0, 0, 0, 150 ) } HUD.Variables = { padding = 30, x_margin = 20, y_margin = 60, roundness = 2, width_percentage = .2, height_percentage = .02, font = 'default', font_padding = 2, font_size = 10, font_outline = 2 } local function DrawHUD() local client = client or LocalPlayer() local x = HUD.Variables.x_margin local y = ScrH() - HUD.Variables.y_margin local width_health = client:Health() * (ScrW() * HUD.Variables.width_percentage / 100) local width_shield = client:Armor() * (ScrW() * HUD.Variables.width_percentage / 100) local height = ScrH() * HUD.Variables.height_percentage draw.RoundedBox( HUD.Variables.roundness, x, y, width_health, height, HUD.ColorSchema.health_bar ) local font_y = y - (height / 2) local font_x = x + HUD.Variables.font_padding local font_x = x + HUD.Variables.font_padding local text = string.format('Health: %i', client:Health()) draw.SimpleTextOutlined( text, HUD.Variables.font, font_y, font_x, HUD.ColorSchema.health_text, TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT, HUD.Variables.font_outline, HUD.ColorSchema.health_text_outline) local y = y - HUD.Variables.padding local font_y = y - HUD.Variables.padding if (client:Armor()) <=0 then else draw.RoundedBox( HUD.Variables.roundness, x, y, width_shield, height, HUD.ColorSchema.shield_bar ) end local text = string.format('Shield: %i', client:Armor()) draw.SimpleTextOutlined( text, HUD.Variables.font, font_y, font_x, HUD.ColorSchema.shield_text, TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT, HUD.Variables.font_outline, HUD.ColorSchema.shield_text_outline) end hook.Add( "HUDPaint", "ClientHUD", DrawHUD ) local function HideThings(name) -- Designed to hide the health and shield indicators if(name == "CHudHealth") or (name == "CHudBattery") then return false end -- We don't return anything here otherwise it will overwrite all other -- HUDShouldDraw hooks. end hook.Add( "HUDShouldDraw", "HideThings", HideThings ) -- Hook that actually hides the stuff[/lua]
Not sure looking at it, if I get some time i'll try and mess with it. Have you ever tried Lua Pad? it is an in-game lua editor. It can't save as lua, you have to save it as text files in the /data/ directory, but you can just copy & paste things in and out to Notepad++ (or whatever you use) after you are finished testing the code. [url=http://www.garrysmod.org/downloads/?tag=Luapad] Lua Pad's on Garrysmod.org [/url] I'm using version 1.11 and it works pretty good, there a few different version on there. Anyway if you download it you can copy the code in to Lua Pad and edit the position values and run it, see what changed, change something else and run it again to see the change, etc, etc, etc. Kind of a brute force approach but it works if you're not sure what's wrong. Only change one thing at a time or it get's confusing.
Sorry, you need to Log In to post a reply to this thread.