Author Topic: Health Bar HUD questions  (Read 3684 times)

0 Members and 2 Guests are viewing this topic.

Offline KnowledgeJunkie

  • Newbie
  • *
  • Posts: 5
  • Karma: 0
Health Bar HUD questions
« on: July 10, 2010, 09:43:04 AM »
I recently got permission from Facepunch user ryan1271 to edit his Metal Gear Style Health bar, mainly because I wanted to add resolution scaling, support for armor, and the "damage taken turns red then disappears" effect from Metal Gear Solid. I've coded the armor bar, and added resolution scaling, but it seems my "MaxArmor" and "MaxHealth" values are not being retrieved properly, or aren't taking into account the fact that ulx can set  a user's health and armor. The rectangles for the health bar and armor bar seem to show a max of about 1000, but "ulx armor", for example, can set the number much higher. Also, my health amount doesn't display in any way. So I was wondering if anyone has some suggestions:

How can I reliably get a player's "MaxHealth" and "MaxArmor" (the only method I say mentioned on GModWiki: LocalPlayer():GetNetworkedInt( "MaxHealth" ) Is the method you suggest ulx mod specific? I guess I don't care too much if it doesn't work outside ulx, but making it mod-independent would be swell.

Here's my code: (I should rewrite this, as it's just a bunch of assignments then poop):
Code: [Select]
function MetalGearHUD ()

local Player = LocalPlayer()
local PlayerName = LocalPlayer():GetName()
local Health = LocalPlayer():Health()
local MaxHealth = LocalPlayer():GetNetworkedInt( "MaxHealth" )
local Armor = LocalPlayer():Armor()
local MaxArmor = LocalPlayer():GetNetworkedInt( "MaxArmor" )
local Width = ScrW()
local Height = ScrH()
local NameWidth, NameHeight = surface.GetTextSize( PlayerName )
-- Adjust the numbers in these "math.ceil()" equations to scale bar heights and starting positions.
local BarStartX = math.ceil( Width/40 )
local BarStartY = math.ceil( Height/30 )
local BarMaxWidth = ( Width/2 - BarStartX )
local BarHeight = math.ceil( Height/50 )
local ArmorBarHeight = math.ceil( Height/150 ) -- notice the armor bar's height is 1/3 the height of the health bar.
local NameOffsetWidth = math.ceil( Width/150 )
local DrawPlayerName = true -- Draw the player name? Default value == true. Must be "false" (no quotes) to hide PlayerName.
local DrawNamePlaceMarker = false -- Draw the translucent box behind the PlayerName. Default value == false.

if !Player:Alive() then
return
end

if(Player:GetActiveWeapon() == NULL or Player:GetActiveWeapon() == "Camera") then
return
end
-- Draw the Health Rectangle (translucent innards)
surface.SetDrawColor( 0, 0, 0, 50 )
surface.DrawRect( BarStartX, BarStartY, BarMaxWidth, BarHeight )

-- Draw the Heatlh bar
surface.SetDrawColor( 20, 120, 255, 250 )
surface.DrawRect( BarStartX, BarStartY, ( BarMaxWidth * math.ceil( Health/MaxHealth ) ), BarHeight )

-- Draw the Health Rectangle border
surface.SetDrawColor( 0, 0, 0, 255 )
surface.DrawOutlinedRect( BarStartX, BarStartY, BarMaxWidth, BarHeight )

-- Draw the Armor Rectangle (translucent innards)
surface.SetDrawColor( 0, 0, 0, 50 )
surface.DrawRect( BarStartX, ( BarStartY + BarHeight ), BarMaxWidth, ArmorBarHeight )

-- Draw the Armor bar
surface.SetDrawColor( 0, 20, 255, 250 )
surface.DrawRect( BarStartX, ( BarStartY + BarHeight ), Armor, ArmorBarHeight )

-- Draw the Armor Rectangle border
surface.SetDrawColor( 0, 0, 0, 255 )
surface.DrawOutlinedRect( BarStartX, ( BarStartY + BarHeight ), BarMaxWidth, ArmorBarHeight )

-- Draw the Player Name, only if DrawPlayerName == true
if DrawPlayerName == true then
if DrawNamePlaceMarker == true then --Draw the NamePlaceMarker (translucent box), only if DrawPlayerName == true AND DrawNamePlaceMarker == true.
surface.SetDrawColor( 0, 0, 0, 150 )
surface.DrawRect( ( BarStartX + NameOffsetWidth-2 ), ( BarStartY + ArmorBarHeight ), NameWidth+4, NameHeight+4 )
end
surface.SetFont( "MenuLarge" )
surface.SetTextColor( 255, 255, 255, 255 )
surface.SetTextPos( ( BarStartX + NameOffsetWidth ), ( BarStartY+ArmorBarHeight+2 ) )
surface.DrawText( PlayerName )
end
end
hook.Add( "HUDPaint", "MetalGearHUD", MetalGearHUD )

-- Hide the original Health/Armor Hud
function HideThings( name ) 
    if ( name == "CHudHealth" ) then 
        return false 
    end
if ( name == "CHudBattery" ) then
return false
end
end 
hook.Add( "HUDShouldDraw", "HideThings", HideThings ) 

Offline JamminR

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 8096
  • Karma: 390
  • Sertafide Ulysses Jenius
    • Team Ulysses [ULib/ULX, other fine releases]
Re: Health Bar HUD questions
« Reply #1 on: July 10, 2010, 12:02:34 PM »
I'm not 100% sure, but, I think it's because you're calling LocalPlayer variables before the player has fully initialized on the server.
That, and using Networked vars is slow even after initialization at times.
All those variables get set at player connect. That is, the server hasn't even spawned the player yet for some of them, so they come back empty.
The way you have them would also never update when called later in the script.
Try turning your Armor and Health static variables into a function
Something like (Been a while since I've done this, bear with me, learn from my mistake if it doesn't work, or another team member will come behind me and straighten us out);
local Armor = function( return LocalPlayer():Armor() ) end
Same for any other 'live' dynamic numbers.
"Though a program be but three lines long, someday it will have to be maintained." -- The Tao of Programming

Offline KnowledgeJunkie

  • Newbie
  • *
  • Posts: 5
  • Karma: 0
Re: Health Bar HUD questions
« Reply #2 on: July 10, 2010, 02:11:57 PM »
well, using

Code: [Select]
local Armor = function( return LocalPlayer():Armor() ) end
caused an error... function expected "name" or "...". I think I have it figured out-

Code: [Select]
local MaxArmor = 100 -- default value to set bar length
local function GetArmor()
       LocalPlayer():Armor()
       return CurrentArmor
         if MaxArmor < CurrentArmor
            MaxArmor = CurrentArmor
         end
       end
hook.Add( Player.SetArmor, "GettheCurrentArmorDefault", "GetArmor" )
hook.Add( ulx.cc_armor, "GettheCurrentArmorULX", "GetArmor" )
hook.Add( otheradminmod.commandhere, "GetTheCurrentArmorSomeMOD", "GetArmor" )