From 86d5c711c8a38fb8b061036a4cc844c524d4c9d4 Mon Sep 17 00:00:00 2001 From: Matthew <22198949+MafewTM@users.noreply.github.com> Date: Mon, 15 Jan 2024 13:51:52 -0500 Subject: [PATCH] refactor(client/heli): style fixes and renamings * refactor(client/heli): style fixes and renamings * fix: indentation * fix: linting error * fix: linting error --- client/heli.lua | 460 ++++++++++++++++++++++++------------------------ 1 file changed, 226 insertions(+), 234 deletions(-) diff --git a/client/heli.lua b/client/heli.lua index 9163f14..859f8d5 100644 --- a/client/heli.lua +++ b/client/heli.lua @@ -1,25 +1,23 @@ local config = require 'config.client' -local fovMax = 80.0 -local fovMin = 10.0 -- max zoom level (smaller fov is more zoom) -local zoomSpeed = 2.0 -- camera zoom speed -local speedLr = 3.0 -- speed by which the camera pans left-right -local speedUd = 3.0 -- speed by which the camera pans up-down +local FOV_MAX = 80.0 +local FOV_MIN = 10.0 -- max zoom level (smaller fov is more zoom) +local ZOOM_SPEED = 2.0 -- camera zoom speed +local LR_SPEED = 3.0 -- speed by which the camera pans left-right +local UD_SPEED = 3.0 -- speed by which the camera pans up-down local toggleHeliCam = 51 -- control id of the button by which to toggle the heliCam mode. Default: INPUT_CONTEXT (E) local toggleVision = 25 -- control id to toggle vision mode. Default: INPUT_AIM (Right mouse btn) local toggleRappel = 154 -- control id to rappel out of the heli. Default: INPUT_DUCK (X) local toggleSpotlight = 74 -- control id to toggle the front spotlight Default: INPUT_VEH_HEADLIGHT (H) local toggleLockOn = 22 -- control id to lock onto a vehicle with the camera. Default is INPUT_SPRINT (spacebar) local spotlightState = false - --- Script starts here local heliCam = false -local fov = (fovMax + fovMin) * 0.5 +local fov = (FOV_MAX + FOV_MIN) * 0.5 ---@enum local VISION_STATE = { - normal = 0, - nightmode = 1, - thermal = 2, + normal = 0, + nightmode = 1, + thermal = 2, } local visionState = VISION_STATE.normal @@ -27,278 +25,272 @@ local scanValue = 0 ---@enum local VEHICLE_LOCK_STATE = { - dormant = 0, - scanning = 1, - locked = 2, + dormant = 0, + scanning = 1, + locked = 2, } local vehicleLockState = VEHICLE_LOCK_STATE.dormant local vehicleDetected = nil local lockedOnVehicle = nil --- Functions -local function isPlayerInPolmav() - return GetEntityModel(cache.vehicle) == joaat(config.policeHelicopter) +local function isPlayerInPoliceHeli() + return GetEntityModel(cache.vehicle) == joaat(config.policeHelicopter) end local function isHeliHighEnough(heli) - return GetEntityHeightAboveGround(heli) > 1.5 + return GetEntityHeightAboveGround(heli) > 1.5 end local function changeVision() - PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) - if visionState == VISION_STATE.normal then - SetNightvision(true) - elseif visionState == VISION_STATE.nightmode then - SetNightvision(false) - SetSeethrough(true) - elseif visionState == VISION_STATE.thermal then - SetSeethrough(false) - else - error('Unexpected visionState ' .. json.encode(visionState)) - end - visionState = (visionState + 1) % 3 + PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) + if visionState == VISION_STATE.normal then + SetNightvision(true) + elseif visionState == VISION_STATE.nightmode then + SetNightvision(false) + SetSeethrough(true) + elseif visionState == VISION_STATE.thermal then + SetSeethrough(false) + else + error('Unexpected visionState ' .. json.encode(visionState)) + end + visionState = (visionState + 1) % 3 end local function hideHudThisFrame() - HideHelpTextThisFrame() - HideHudAndRadarThisFrame() - HideHudComponentThisFrame(19) -- weapon wheel - HideHudComponentThisFrame(1) -- Wanted Stars - HideHudComponentThisFrame(2) -- Weapon icon - HideHudComponentThisFrame(3) -- Cash - HideHudComponentThisFrame(4) -- MP CASH - HideHudComponentThisFrame(13) -- Cash Change - HideHudComponentThisFrame(11) -- Floating Help Text - HideHudComponentThisFrame(12) -- more floating help text - HideHudComponentThisFrame(15) -- Subtitle Text - HideHudComponentThisFrame(18) -- Game Stream + HideHelpTextThisFrame() + HideHudAndRadarThisFrame() + + local hudComponents = {1, 2, 3, 4, 13, 11, 12, 15, 18, 19} + for _, component in ipairs(hudComponents) do + HideHudComponentThisFrame(component) + end end -local function checkInputRotation(cam, zoomvalue) - local rightAxisX = GetDisabledControlNormal(0, 220) - local rightAxisY = GetDisabledControlNormal(0, 221) - local rotation = GetCamRot(cam, 2) - if rightAxisX == 0.0 and rightAxisY == 0.0 then return end +local function checkInputRotation(cam, zoomValue) + local rightAxisX = GetDisabledControlNormal(0, 220) + local rightAxisY = GetDisabledControlNormal(0, 221) + local rotation = GetCamRot(cam, 2) + if rightAxisX == 0.0 and rightAxisY == 0.0 then return end - local newZ = rotation.z + rightAxisX * -1.0 * speedUd * (zoomvalue + 0.1) - local newX = math.max(math.min(20.0, rotation.x + rightAxisY * -1.0 * speedLr * (zoomvalue + 0.1)), -89.5) -- Clamping at top (cant see top of heli) and at bottom (doesn't glitch out in -90deg) - SetCamRot(cam, newX, 0.0, newZ, 2) + local zoomFactor = zoomValue + 0.1 + local newZ = rotation.z - rightAxisX * UD_SPEED * zoomFactor + local newY = rightAxisY * -1.0 * LR_SPEED * zoomFactor + local newX = math.max(math.min(20.0, rotation.x + newY), -89.5) + SetCamRot(cam, newX, 0.0, newZ, 2) end local function handleZoom(cam) - if IsControlJustPressed(0,241) then -- Scrollup - fov = math.max(fov - zoomSpeed, fovMin) - end - if IsControlJustPressed(0,242) then - fov = math.min(fov + zoomSpeed, fovMax) -- ScrollDown - end - local currentFov = GetCamFov(cam) - if math.abs(fov - currentFov) < 0.1 then -- the difference is too small, just set the value directly to avoid unneeded updates to FOV of order 10^-5 - fov = currentFov - end - SetCamFov(cam, currentFov + (fov - currentFov) * 0.05) -- Smoothing of camera zoom + if IsControlJustPressed(0,241) then -- Scrollup + fov = math.max(fov - ZOOM_SPEED, FOV_MIN) + end + if IsControlJustPressed(0,242) then + fov = math.min(fov + ZOOM_SPEED, FOV_MAX) -- ScrollDown + end + local currentFov = GetCamFov(cam) + if math.abs(fov - currentFov) < 0.1 then -- the difference is too small, just set the value directly to avoid unneeded updates to FOV of order 10^-5 + fov = currentFov + end + SetCamFov(cam, currentFov + (fov - currentFov) * 0.05) -- Smoothing of camera zoom end local function rotAnglesToVec(rot) -- input vector3 - local z = math.rad(rot.z) - local x = math.rad(rot.x) - local num = math.abs(math.cos(x)) - return vector3(-math.sin(z) * num, math.cos(z) * num, math.sin(x)) + local z = math.rad(rot.z) + local x = math.rad(rot.x) + local num = math.abs(math.cos(x)) + return vector3(-math.sin(z) * num, math.cos(z) * num, math.sin(x)) end local function getVehicleInView(cam) - local coords = GetCamCoord(cam) - local forwardVector = rotAnglesToVec(GetCamRot(cam, 2)) - --DrawLine(coords, coords + (forward_vector * 100.0), 255, 0, 0, 255) -- debug line to show LOS of cam - local rayHandle = CastRayPointToPoint(coords, coords + (forwardVector * 400.0), 10, cache.vehicle, 0) - local _, _, _, _, entityHit = GetRaycastResult(rayHandle) - return IsEntityAVehicle(entityHit) and entityHit or 0 + local coords = GetCamCoord(cam) + local forwardVector = rotAnglesToVec(GetCamRot(cam, 2)) + --DrawLine(coords, coords + (forward_vector * 100.0), 255, 0, 0, 255) -- debug line to show LOS of cam + local rayHandle = CastRayPointToPoint(coords, coords + (forwardVector * 400.0), 10, cache.vehicle, 0) + local _, _, _, _, entityHit = GetRaycastResult(rayHandle) + return IsEntityAVehicle(entityHit) and entityHit or 0 end local function renderVehicleInfo(vehicle) - local pos = GetEntityCoords(vehicle) - local model = GetEntityModel(vehicle) - local vehName = GetLabelText(GetDisplayNameFromVehicleModel(model)) - local licensePlate = GetPlate(vehicle) - local speed = math.ceil(GetEntitySpeed(vehicle) * 3.6) - local street1, street2 = GetStreetNameAtCoord(pos.x, pos.y, pos.z) - local streetLabel = GetStreetNameFromHashKey(street1) - if street2 ~= 0 then - streetLabel = streetLabel .. ' | ' .. GetStreetNameFromHashKey(street2) - end - SendNUIMessage({ - type = 'heliupdateinfo', - model = vehName, - plate = licensePlate, - speed = speed, - street = streetLabel, - }) + local pos = GetEntityCoords(vehicle) + local model = GetEntityModel(vehicle) + local vehName = GetLabelText(GetDisplayNameFromVehicleModel(model)) + local licensePlate = GetPlate(vehicle) + local speed = math.ceil(GetEntitySpeed(vehicle) * 3.6) + local street1, street2 = GetStreetNameAtCoord(pos.x, pos.y, pos.z) + local streetLabel = GetStreetNameFromHashKey(street1) + if street2 ~= 0 then + streetLabel = streetLabel .. ' | ' .. GetStreetNameFromHashKey(street2) + end + SendNUIMessage({ + type = 'heliupdateinfo', + model = vehName, + plate = licensePlate, + speed = speed, + street = streetLabel, + }) end --- Events -RegisterNetEvent('heli:spotlight', function(serverID, state) - SetVehicleSearchlight(GetVehiclePedIsIn(GetPlayerPed(GetPlayerFromServerId(serverID)), false), state, false) +RegisterNetEvent('heli:spotlight', function(serverId, state) + SetVehicleSearchlight(GetVehiclePedIsIn(GetPlayerPed(GetPlayerFromServerId(serverId)), false), state, false) end) local function heliCamThread() - CreateThread(function() - local sleep - while heliCam do - sleep = 0 - if vehicleLockState == VEHICLE_LOCK_STATE.scanning then - if scanValue < 100 then - scanValue += 1 - SendNUIMessage({ - type = 'heliscan', - scanvalue = scanValue, - }) - if scanValue == 100 then - PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) - lockedOnVehicle = vehicleDetected - vehicleLockState = VEHICLE_LOCK_STATE.locked - end - sleep = 10 - end - elseif vehicleLockState == VEHICLE_LOCK_STATE.locked then - scanValue = 100 - renderVehicleInfo(lockedOnVehicle) - sleep = 100 - else - scanValue = 0 - sleep = 500 - end - Wait(sleep) - end - end) + CreateThread(function() + local sleep + while heliCam do + sleep = 0 + if vehicleLockState == VEHICLE_LOCK_STATE.scanning then + if scanValue < 100 then + scanValue += 1 + SendNUIMessage({ + type = 'heliscan', + scanvalue = scanValue, + }) + if scanValue == 100 then + PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) + lockedOnVehicle = vehicleDetected + vehicleLockState = VEHICLE_LOCK_STATE.locked + end + sleep = 10 + end + elseif vehicleLockState == VEHICLE_LOCK_STATE.locked then + scanValue = 100 + renderVehicleInfo(lockedOnVehicle) + sleep = 100 + else + scanValue = 0 + sleep = 500 + end + Wait(sleep) + end + end) end local function unlockCam(cam) - PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) - lockedOnVehicle = nil - local rot = GetCamRot(cam, 2) -- All this because I can't seem to get the camera unlocked from the entity - fov = GetCamFov(cam) - local oldCam = cam - DestroyCam(oldCam, false) - local newCam = CreateCam('DEFAULT_SCRIPTED_FLY_CAMERA', true) - AttachCamToEntity(newCam, cache.vehicle, 0.0,0.0,-1.5, true) - SetCamRot(newCam, rot.x, rot.y, rot.z, 2) - SetCamFov(newCam, fov) - RenderScriptCams(true, false, 0, true, false) - vehicleLockState = VEHICLE_LOCK_STATE.dormant - scanValue = 0 - SendNUIMessage({ - type = 'disablescan', - }) - return newCam + PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) + lockedOnVehicle = nil + local rot = GetCamRot(cam, 2) -- All this because I can't seem to get the camera unlocked from the entity + fov = GetCamFov(cam) + local oldCam = cam + DestroyCam(oldCam, false) + local newCam = CreateCam('DEFAULT_SCRIPTED_FLY_CAMERA', true) + AttachCamToEntity(newCam, cache.vehicle, 0.0,0.0,-1.5, true) + SetCamRot(newCam, rot.x, rot.y, rot.z, 2) + SetCamFov(newCam, fov) + RenderScriptCams(true, false, 0, true, false) + vehicleLockState = VEHICLE_LOCK_STATE.dormant + scanValue = 0 + SendNUIMessage({ + type = 'disablescan', + }) + return newCam end local function turnOffCam() - PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) - heliCam = false - vehicleLockState = VEHICLE_LOCK_STATE.dormant - scanValue = 0 - SendNUIMessage({ - type = 'disablescan', - }) - SendNUIMessage({ - type = 'heliclose', - }) + PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) + heliCam = false + vehicleLockState = VEHICLE_LOCK_STATE.dormant + scanValue = 0 + SendNUIMessage({ + type = 'disablescan', + }) + SendNUIMessage({ + type = 'heliclose', + }) end local function handleInVehicle() - if not IsLoggedIn then return end - if QBX.PlayerData.job.type ~= 'leo' or not QBX.PlayerData.job.onduty then return end - if isHeliHighEnough(cache.vehicle) then - if IsControlJustPressed(0, toggleHeliCam) then -- Toggle Helicam - PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) - heliCam = true - heliCamThread() - SendNUIMessage({ - type = 'heliopen', - }) - end + if not IsLoggedIn then return end + if QBX.PlayerData.job.type ~= 'leo' and not QBX.PlayerData.job.onduty then return end + if isHeliHighEnough(cache.vehicle) then + if IsControlJustPressed(0, toggleHeliCam) then -- Toggle Helicam + PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) + heliCam = true + heliCamThread() + SendNUIMessage({ + type = 'heliopen', + }) + end - if IsControlJustPressed(0, toggleRappel) and (cache.seat == 1 or cache.seat == 2) then -- Initiate rappel - PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) - TaskRappelFromHeli(cache.ped, 1) - end - end + if IsControlJustPressed(0, toggleRappel) and (cache.seat == 1 or cache.seat == 2) then -- Initiate rappel + PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) + TaskRappelFromHeli(cache.ped, 1) + end + end - if IsControlJustPressed(0, toggleSpotlight) and (cache.seat == -1 or cache.seat == 0) then - spotlightState = not spotlightState - TriggerServerEvent('heli:spotlight', spotlightState) - PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) - end + if IsControlJustPressed(0, toggleSpotlight) and (cache.seat == -1 or cache.seat == 0) then + spotlightState = not spotlightState + TriggerServerEvent('heli:spotlight', spotlightState) + PlaySoundFrontend(-1, 'SELECT', 'HUD_FRONTEND_DEFAULT_SOUNDSET', false) + end - if heliCam then - SetTimecycleModifier('heliGunCam') - SetTimecycleModifierStrength(0.3) - local scaleform = lib.requestScaleformMovie('HELI_CAM') - local cam = CreateCam('DEFAULT_SCRIPTED_FLY_CAMERA', true) - AttachCamToEntity(cam, cache.vehicle, 0.0,0.0,-1.5, true) - SetCamRot(cam, 0.0, 0.0, GetEntityHeading(cache.vehicle), 2) - SetCamFov(cam, fov) - RenderScriptCams(true, false, 0, true, false) - PushScaleformMovieFunction(scaleform, 'SET_CAM_LOGO') - PushScaleformMovieFunctionParameterInt(0) -- 0 for nothing, 1 for LSPD logo - PopScaleformMovieFunctionVoid() - lockedOnVehicle = nil - while heliCam and not IsEntityDead(cache.ped) and cache.vehicle and isHeliHighEnough(cache.vehicle) do - if IsControlJustPressed(0, toggleHeliCam) then -- Toggle Helicam - turnOffCam() - end - if IsControlJustPressed(0, toggleVision) then - changeVision() - end - local zoomvalue = 0 - if lockedOnVehicle then - if DoesEntityExist(lockedOnVehicle) then + if heliCam then + SetTimecycleModifier('heliGunCam') + SetTimecycleModifierStrength(0.3) + local scaleform = lib.requestScaleformMovie('HELI_CAM') + local cam = CreateCam('DEFAULT_SCRIPTED_FLY_CAMERA', true) + AttachCamToEntity(cam, cache.vehicle, 0.0,0.0,-1.5, true) + SetCamRot(cam, 0.0, 0.0, GetEntityHeading(cache.vehicle), 2) + SetCamFov(cam, fov) + RenderScriptCams(true, false, 0, true, false) + PushScaleformMovieFunction(scaleform, 'SET_CAM_LOGO') + PushScaleformMovieFunctionParameterInt(0) -- 0 for nothing, 1 for LSPD logo + PopScaleformMovieFunctionVoid() + lockedOnVehicle = nil + while heliCam and not IsEntityDead(cache.ped) and cache.vehicle and isHeliHighEnough(cache.vehicle) do + if IsControlJustPressed(0, toggleHeliCam) then -- Toggle Helicam + turnOffCam() + end + if IsControlJustPressed(0, toggleVision) then + changeVision() + end + local zoomValue = 0 + if lockedOnVehicle then + if DoesEntityExist(lockedOnVehicle) then - PointCamAtEntity(cam, lockedOnVehicle, 0.0, 0.0, 0.0, true) - if IsControlJustPressed(0, toggleLockOn) then - cam = unlockCam(cam) - end - else - vehicleLockState = VEHICLE_LOCK_STATE.dormant - SendNUIMessage({ - type = 'disablescan', - }) - lockedOnVehicle = nil -- Cam will auto unlock when entity doesn't exist anyway - end - else - zoomvalue = (1.0 / (fovMax - fovMin)) * (fov - fovMin) - checkInputRotation(cam, zoomvalue) - vehicleLockState = DoesEntityExist(getVehicleInView(cam)) and VEHICLE_LOCK_STATE.scanning or VEHICLE_LOCK_STATE.dormant - end - handleZoom(cam) - hideHudThisFrame() - PushScaleformMovieFunction(scaleform, 'SET_ALT_FOV_HEADING') - PushScaleformMovieFunctionParameterFloat(GetEntityCoords(cache.vehicle).z) - PushScaleformMovieFunctionParameterFloat(zoomvalue) - PushScaleformMovieFunctionParameterFloat(GetCamRot(cam, 2).z) - PopScaleformMovieFunctionVoid() - DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 255, 0) - Wait(0) - end - heliCam = false - ClearTimecycleModifier() - fov = (fovMax + fovMin) * 0.5 -- reset to starting zoom level - RenderScriptCams(false, false, 0, true, false) -- Return to gameplay camera - SetScaleformMovieAsNoLongerNeeded(scaleform) -- Cleanly release the scaleform - DestroyCam(cam, false) - SetNightvision(false) - SetSeethrough(false) - end + PointCamAtEntity(cam, lockedOnVehicle, 0.0, 0.0, 0.0, true) + if IsControlJustPressed(0, toggleLockOn) then + cam = unlockCam(cam) + end + else + vehicleLockState = VEHICLE_LOCK_STATE.dormant + SendNUIMessage({ + type = 'disablescan', + }) + lockedOnVehicle = nil -- Cam will auto unlock when entity doesn't exist anyway + end + else + zoomValue = (1.0 / (FOV_MAX - FOV_MIN)) * (fov - FOV_MIN) + checkInputRotation(cam, zoomValue) + vehicleLockState = DoesEntityExist(getVehicleInView(cam)) and VEHICLE_LOCK_STATE.scanning or VEHICLE_LOCK_STATE.dormant + end + handleZoom(cam) + hideHudThisFrame() + PushScaleformMovieFunction(scaleform, 'SET_ALT_FOV_HEADING') + PushScaleformMovieFunctionParameterFloat(GetEntityCoords(cache.vehicle).z) + PushScaleformMovieFunctionParameterFloat(zoomValue) + PushScaleformMovieFunctionParameterFloat(GetCamRot(cam, 2).z) + PopScaleformMovieFunctionVoid() + DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 255, 0) + Wait(0) + end + heliCam = false + ClearTimecycleModifier() + fov = (FOV_MAX + FOV_MIN) * 0.5 -- reset to starting zoom level + RenderScriptCams(false, false, 0, true, false) -- Return to gameplay camera + SetScaleformMovieAsNoLongerNeeded(scaleform) -- Cleanly release the scaleform + DestroyCam(cam, false) + SetNightvision(false) + SetSeethrough(false) + end end --- Threads AddEventHandler('ox_lib:cache:vehicle', function() - CreateThread(function() - if not isPlayerInPolmav() then return end - while cache.vehicle do - handleInVehicle() - Wait(0) - end - end) + CreateThread(function() + if not isPlayerInPoliceHeli() then return end + while cache.vehicle do + handleInVehicle() + Wait(0) + end + end) end) \ No newline at end of file