-- All credits go to race authors and the MTA team nametag = {} local nametags = {} local g_screenX,g_screenY = guiGetScreenSize() local bHideNametags = false local NAMETAG_SCALE = 0.2 --Overall adjustment of the nametag, use this to resize but constrain proportions local NAMETAG_ALPHA_DISTANCE = 50 --Distance to start fading out local NAMETAG_DISTANCE = 120 --Distance until we're gone local NAMETAG_ALPHA = 120 --The overall alpha level of the nametag local NAMETAG_BORDER_THICKNESS = 1 local NAMETAG_FONT = "default-bold" --The following arent actual pixel measurements, they're just proportional constraints local NAMETAG_TEXT_BAR_SPACE = 0.5 local NAMETAG_WIDTH = 35 local NAMETAG_HEIGHT = 5 local NAMETAG_TEXTSIZE = 0.65 local NAMETAG_OUTLINE_THICKNESS = 0.8 -- local NAMETAG_ALPHA_DIFF = NAMETAG_DISTANCE - NAMETAG_ALPHA_DISTANCE NAMETAG_SCALE = 1/NAMETAG_SCALE * 800 / g_screenY -- Ensure the name tag doesn't get too big local maxScaleCurve = { {0, 0}, {3, 3}, {13, 5} } -- Ensure the text doesn't get too small/unreadable local textScaleCurve = { {0, 0.8}, {0.8, 1.2}, {99, 99} } -- Make the text a bit brighter and fade more gradually local textAlphaCurve = { {0, 0}, {25, 100}, {120, 190}, {255, 190} } function nametag.create ( player ) nametags[player] = true end function nametag.destroy ( player ) nametags[player] = nil end addEventHandler ( "onClientRender", getRootElement(), function() -- Hideous quick fix -- for i,player in ipairs(getElementsByType"player") do if player ~= getLocalPlayer() then setPlayerNametagShowing ( player, false ) if not nametags[player] then nametag.create ( player ) end end end if bHideNametags then return end local x,y,z = getCameraMatrix() for player in pairs(nametags) do while true do if getElementHealth( player ) <= 0 or not getElementData( player, "classID" ) then break end local px,py,pz = getElementPosition ( player ) local pdistance = getDistanceBetweenPoints3D ( x,y,z,px,py,pz ) dxDrawLine( px, py, pz, px+2, py+2, pz+2, tocolor(255,0,0) ) local checkBuildings, checkVehicles, checkPlayers, checkObjects = true, false, false, true local hit = processLineOfSight( x, y, z, px, py, pz, checkBuildings, checkVehicles, checkPlayers, checkObjects ) if pdistance <= NAMETAG_DISTANCE and not hit then --Get screenposition local sx,sy = getScreenFromWorldPosition ( px, py, pz+getElementDistanceFromCentreOfMassToBaseOfModel( player )/3, 0.06 ) if not sx or not sy then break end --Calculate our components local scale = 1/(NAMETAG_SCALE * (pdistance / NAMETAG_DISTANCE)) local alpha = ((pdistance - NAMETAG_ALPHA_DISTANCE) / NAMETAG_ALPHA_DIFF) alpha = (alpha < 0) and NAMETAG_ALPHA or NAMETAG_ALPHA-(alpha*NAMETAG_ALPHA) scale = math.evalCurve(maxScaleCurve,scale) local textscale = math.evalCurve(textScaleCurve,scale) local textalpha = math.evalCurve(textAlphaCurve,alpha) local outlineThickness = NAMETAG_OUTLINE_THICKNESS*(scale) --Draw our text local r,g,b = getPlayerNametagColor( player ) local offset = (scale) * NAMETAG_TEXT_BAR_SPACE/2 dxDrawText ( getPlayerName(player), sx - NAMETAG_BORDER_THICKNESS, sy - offset - NAMETAG_BORDER_THICKNESS, sx - NAMETAG_BORDER_THICKNESS, sy - offset - NAMETAG_BORDER_THICKNESS, tocolor(0,0,0,textalpha), textscale*NAMETAG_TEXTSIZE, NAMETAG_FONT, "center", "bottom", false, false, false ) dxDrawText ( getPlayerName(player), sx + NAMETAG_BORDER_THICKNESS, sy - offset + NAMETAG_BORDER_THICKNESS, sx + NAMETAG_BORDER_THICKNESS, sy - offset + NAMETAG_BORDER_THICKNESS, tocolor(0,0,0,textalpha), textscale*NAMETAG_TEXTSIZE, NAMETAG_FONT, "center", "bottom", false, false, false ) dxDrawText ( getPlayerName(player), sx + NAMETAG_BORDER_THICKNESS, sy - offset - NAMETAG_BORDER_THICKNESS, sx + NAMETAG_BORDER_THICKNESS, sy - offset - NAMETAG_BORDER_THICKNESS, tocolor(0,0,0,textalpha), textscale*NAMETAG_TEXTSIZE, NAMETAG_FONT, "center", "bottom", false, false, false ) dxDrawText ( getPlayerName(player), sx - NAMETAG_BORDER_THICKNESS, sy - offset + NAMETAG_BORDER_THICKNESS, sx - NAMETAG_BORDER_THICKNESS, sy - offset + NAMETAG_BORDER_THICKNESS, tocolor(0,0,0,textalpha), textscale*NAMETAG_TEXTSIZE, NAMETAG_FONT, "center", "bottom", false, false, false ) dxDrawText ( getPlayerName(player), sx, sy - offset, sx, sy - offset, tocolor(r,g,b,textalpha), textscale*NAMETAG_TEXTSIZE, NAMETAG_FONT, "center", "bottom", false, false, false ) --We draw three parts to make the healthbar. First the outline/background local drawX = sx - NAMETAG_WIDTH*scale/2 drawY = sy + offset local width,height = NAMETAG_WIDTH*scale, NAMETAG_HEIGHT*scale dxDrawRectangle ( drawX, drawY, width, height, tocolor(0,0,0,alpha) ) --Next the inner background local health = math.max( 0, getElementHealth( player ) ) local r,g = 255 - health/100*255,health/100*255 dxDrawRectangle ( drawX + outlineThickness, drawY + outlineThickness, width - outlineThickness*2, height - outlineThickness*2, tocolor(r,g,0,0.4*alpha) ) --Finally, the actual health dxDrawRectangle ( drawX + outlineThickness, drawY + outlineThickness, (health/100)*(width - outlineThickness*2), height - outlineThickness*2, tocolor(r,g,0,alpha) ) end break end end end ) ---------------THE FOLLOWING IS THE MANAGEMENT OF NAMETAGS----------------- addEventHandler('onClientResourceStart', getResourceRootElement(), function() for i,player in ipairs(getElementsByType"player") do if player ~= getLocalPlayer() then nametag.create ( player ) end end end ) addEventHandler ( "onClientPlayerJoin", getRootElement(), function() if source == getLocalPlayer() then return end setPlayerNametagShowing ( source, false ) nametag.create ( source ) end ) addEventHandler ( "onClientPlayerQuit", getRootElement(), function() nametag.destroy ( source ) end ) function math.evalCurve( curve, input ) -- First value if input