From 1d2088fc2c6b8633af2c1ad9afe2a7a77dd75022 Mon Sep 17 00:00:00 2001 From: DateFTP <301770276+DateFTP@users.noreply.github.com> Date: Tue, 4 Aug 2026 13:07:41 +0300 Subject: [PATCH] Add speed text and headlight status icon to speedometer - Show the current vehicle speed as km/h text on the gauge - Add headlight on/off icons (lights_0/lights_1) reflecting the current headlight state, falling back to the time of day when lights are in automatic mode --- [gameplay]/speedometer/client.lua | 57 +++++++++++++++++++++ [gameplay]/speedometer/images/lights_0.png | Bin 0 -> 733 bytes [gameplay]/speedometer/images/lights_1.png | Bin 0 -> 576 bytes [gameplay]/speedometer/meta.xml | 4 ++ 4 files changed, 61 insertions(+) create mode 100644 [gameplay]/speedometer/images/lights_0.png create mode 100644 [gameplay]/speedometer/images/lights_1.png diff --git a/[gameplay]/speedometer/client.lua b/[gameplay]/speedometer/client.lua index ea48b9ef3..ddd2642e1 100644 --- a/[gameplay]/speedometer/client.lua +++ b/[gameplay]/speedometer/client.lua @@ -10,6 +10,37 @@ local function dxDrawRelativeImage(startX, startY, width, height, image, rot, ro dxDrawImage(screenW * startX, screenH * startY, scaledW, scaledH, image, rot or 0, rotX or 0, rotY or 0, color or base_color, postGUI or false) end +function dxDrawRelText(text, relX, relY, relWidth, relHeight, color, scaleXY, font, alignX, alignY, clip, wordBreak, postGUI, colorCoded, subPixelPositioning, fRotation, fRotationCenterX, fRotationCenterY, fLineSpacing) + local scale = math.min(screenW / baseW, screenH / baseH) + local absX = screenW * relX + local absY = screenH * relY + local absRight = screenW * (relX + relWidth) + local absBottom = screenH * (relY + relHeight) + + + local scaledScale = scaleXY * scale + + dxDrawText( + text, + absX, absY, + absRight, absBottom, + color or tocolor(255, 255, 255, 255), + scaledScale, scaledScale, -- scaleX, scaleY + font or "default", + alignX or "left", + alignY or "top", + clip or false, + wordBreak or false, + postGUI or false, + colorCoded or false, + subPixelPositioning or false, + fRotation or 0, + fRotationCenterX or 0, + fRotationCenterY or 0, + fLineSpacing or 0 + ) +end + function drawSpeedo() local veh = getPedOccupiedVehicle(localPlayer) if not veh then return end @@ -18,9 +49,35 @@ function drawSpeedo() local speed = (velx ^ 2 + vely ^ 2 + velz ^ 2) ^ (0.5) dxDrawRelativeImage(0.82, 0.65, 300, 300, "images/disc.png") + local kmh = math.floor( getElementSpeed(veh, 'km/h') ) --mph + dxDrawRelText(kmh, 0.65, 0.71, 0.5, 0.1, tocolor(255, 255, 255), 1.5, "default-bold", "center", "center") + + if getVehicleOverrideLights( veh ) == 2 then + dxDrawRelativeImage(0.88, 0.85, 40, 40, "images/lights_1.png", 0, 0, 0, tocolor(255, 255, 255, 255)) + elseif getVehicleOverrideLights( veh ) == 1 then + dxDrawRelativeImage(0.88, 0.85, 40, 40, "images/lights_0.png", 0, 0, 0, tocolor(255, 255, 255, 255)) + else + local h,m = getTime() + if h >= 6 and h <= 21 then + dxDrawRelativeImage(0.88, 0.85, 40, 40, "images/lights_0.png", 0, 0, 0, tocolor(255, 255, 255, 255)) + else + dxDrawRelativeImage(0.88, 0.85, 40, 40, "images/lights_1.png", 0, 0, 0, tocolor(255, 255, 255, 255)) + end + end + dxDrawRelativeImage(0.82, 0.65, 300, 300, "images/needle.png", -145-(1.5-(speed/1.5) * 305)) end +function getElementSpeed(theElement, unit) + assert(isElement(theElement), "Bad argument 1 @ getElementSpeed (element expected, got " .. type(theElement) .. ")") + local elementType = getElementType(theElement) + assert(elementType == "player" or elementType == "ped" or elementType == "object" or elementType == "vehicle" or elementType == "projectile", "Invalid element type @ getElementSpeed (player/ped/object/vehicle/projectile expected, got " .. elementType .. ")") + assert((unit == nil or type(unit) == "string" or type(unit) == "number") and (unit == nil or (tonumber(unit) and (tonumber(unit) == 0 or tonumber(unit) == 1 or tonumber(unit) == 2)) or unit == "m/s" or unit == "km/h" or unit == "mph"), "Bad argument 2 @ getElementSpeed (invalid speed unit)") + unit = unit == nil and 0 or ((not tonumber(unit)) and unit or tonumber(unit)) + local mult = (unit == 0 or unit == "m/s") and 50 or ((unit == 1 or unit == "km/h") and 180 or 111.84681456) + return (Vector3(getElementVelocity(theElement)) * mult).length +end + local isSpeedoShown = false function toggleRender(bool) if bool then diff --git a/[gameplay]/speedometer/images/lights_0.png b/[gameplay]/speedometer/images/lights_0.png new file mode 100644 index 0000000000000000000000000000000000000000..490b7bdd0369601dfad1eca82c300cf6f6c61b4c GIT binary patch literal 733 zcmeAS@N?(olHy`uVBq!ia0vp^DImv`Ti-aegi~{<_ zz9h&mm_g?0y}$Y8>OrYo>XP{;R}%Qc}& z_r15wW3Oa$DMe4+A>epwL)x<6Gg?|07#Mp!T^vIsB;Ovm8Fo29gzbU6m%8t)jT>{L ztooZ2mIgTdz5jo$&)x#vSliz+K6-m@$WICK(p)+v=+*zJ@iQJyPcWO;zkG4Q#@u}m z;wy^(pIS42@rUO9sr-eH%??=0YGg6&co4rx-<ZzM?c<%PRnO_+y zWanL-DH||T&v#v$oYtq_wDR>UjwHKya_oNc_EOGvwgT^)JYn8mMhwbPJc*NogqSTZ zE#saYb~ooC;}4hB=QT8!$M#Hm_wqqQ(Y2BfJO{n^CSE&qvWZVm@kXGLL!v*s9gB$V zVu4GJYzHr|ODj7Q$njFa*|OT|M8LTQKBXy_7d3M{-SRSl^Wv)9Yc31j*_l0py!J7F zP}_3K#>2?#T|mX+P}xO${Wq`ZJ~YS7G~$WxW(M`^TOt>3sg9~~t-RN=$ZC~9@FoXU zHj`?P2T9g{GE8b*6&G~cH%)F?B+BJIZ>n!~!RDnadJhSoztO@tXX$Kyx7i}<^Um8} wee_yw)wHsjNp8d^R9ZqF0H0t(@0mdmdKI;Vst01M+QkN^Mx literal 0 HcmV?d00001 diff --git a/[gameplay]/speedometer/images/lights_1.png b/[gameplay]/speedometer/images/lights_1.png new file mode 100644 index 0000000000000000000000000000000000000000..989a33ed57a6c15a2580327122b87a2dcb610fa8 GIT binary patch literal 576 zcmeAS@N?(olHy`uVBq!ia0vp^DIme@~uP)Q|^sC4(X2aF7E^{Vdt7%ONJ%8ZM4z3lF|NIyj7;`*b977}| z-yVpZG}}Og^+Gon7dB5J(Po4OA;<}JX|5pdXU&(4Lof71wx%8j?QilDZ(+g#m zo4#*fbZCFZF{{tJrx#fLOMI>;uk|OuF_3S;lkGanneyJ<^MC9L4%p71R##vy`p9(U z0+tIAbt%h*+IL=5kCv8MvN+!8fk6DUCLQ;P>V3b?YBn@(;%<_g62YL&9M+;UrGz1l zXQ!fyXL5(RZzfK-P`p20EK>q$jg<*9HN3&yR5McifsB&$v9Lg?CcxBwmNlDHC!PHcmNH zaE`}FVCJm4Z*1u)9!(9KKCJ$bCJ~gdeHx?fx9oW$k}?YyFFCGg_Uo)}5|8*nhUJU= z_bPdLdtN(K`9axwYKL(^Nz>)e&6`&W + + + +