From e2a6cde40b6c9c9501cdfdd15b588f801e8bf407 Mon Sep 17 00:00:00 2001 From: Mycroft Date: Mon, 1 Aug 2022 17:55:02 +0100 Subject: [PATCH 01/15] Feat: ESX_Ambulancejob: Allow Camera movement while dead --- [esx_addons]/esx_ambulancejob/client/main.lua | 625 ++++++++++-------- 1 file changed, 364 insertions(+), 261 deletions(-) diff --git a/[esx_addons]/esx_ambulancejob/client/main.lua b/[esx_addons]/esx_ambulancejob/client/main.lua index a68033ec..57224f8d 100644 --- a/[esx_addons]/esx_ambulancejob/client/main.lua +++ b/[esx_addons]/esx_ambulancejob/client/main.lua @@ -4,375 +4,478 @@ isDead, isSearched, medic = false, false, 0 RegisterNetEvent('esx:playerLoaded') AddEventHandler('esx:playerLoaded', function(xPlayer) - ESX.PlayerLoaded = true + ESX.PlayerLoaded = true end) RegisterNetEvent('esx:onPlayerLogout') AddEventHandler('esx:onPlayerLogout', function() - ESX.PlayerLoaded = false - firstSpawn = true + ESX.PlayerLoaded = false + firstSpawn = true end) AddEventHandler('esx:onPlayerSpawn', function() - isDead = false + isDead = false + ClearTimecycleModifier() + SetPedMotionBlur(PlayerPedId(), false) + ClearExtraTimecycleModifier() + EndDeathCam() + if firstSpawn then + firstSpawn = false - if firstSpawn then - firstSpawn = false + if Config.SaveDeathStatus then + while not ESX.PlayerLoaded do + Wait(1000) + end - if Config.SaveDeathStatus then - while not ESX.PlayerLoaded do - Wait(1000) - end - - ESX.TriggerServerCallback('esx_ambulancejob:getDeathStatus', function(shouldDie) - if shouldDie then - Wait(1000) - SetEntityHealth(PlayerPedId(), 0) - end - end) - end - end + ESX.TriggerServerCallback('esx_ambulancejob:getDeathStatus', function(shouldDie) + if shouldDie then + Wait(1000) + SetEntityHealth(PlayerPedId(), 0) + end + end) + end + end end) -- Create blips CreateThread(function() - for k,v in pairs(Config.Hospitals) do - local blip = AddBlipForCoord(v.Blip.coords) + for k, v in pairs(Config.Hospitals) do + local blip = AddBlipForCoord(v.Blip.coords) - SetBlipSprite(blip, v.Blip.sprite) - SetBlipScale(blip, v.Blip.scale) - SetBlipColour(blip, v.Blip.color) - SetBlipAsShortRange(blip, true) + SetBlipSprite(blip, v.Blip.sprite) + SetBlipScale(blip, v.Blip.scale) + SetBlipColour(blip, v.Blip.color) + SetBlipAsShortRange(blip, true) - BeginTextCommandSetBlipName('STRING') - AddTextComponentSubstringPlayerName(_U('blip_hospital')) - EndTextCommandSetBlipName(blip) - end + BeginTextCommandSetBlipName('STRING') + AddTextComponentSubstringPlayerName(_U('blip_hospital')) + EndTextCommandSetBlipName(blip) + end - while true do - local Sleep = 1500 - - if isDead then - Sleep = 0 - DisableAllControlActions(0) - EnableControlAction(0, 47, true) -- G - EnableControlAction(0, 245, true) -- T - EnableControlAction(0, 38, true) -- E + while true do + local Sleep = 1500 - if isSearched then - local playerPed = PlayerPedId() - local ped = GetPlayerPed(GetPlayerFromServerId(medic)) - isSearched = false - - AttachEntityToEntity(playerPed, ped, 11816, 0.54, 0.54, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true) - Wait(1000) - DetachEntity(playerPed, true, false) - ClearPedTasksImmediately(playerPed) - end - end + if isDead then + Sleep = 0 + DisableAllControlActions(0) + EnableControlAction(0, 47, true) -- G + EnableControlAction(0, 245, true) -- T + EnableControlAction(0, 38, true) -- E - Wait(Sleep) - end + ProcessCamControls() + if isSearched then + local playerPed = PlayerPedId() + local ped = GetPlayerPed(GetPlayerFromServerId(medic)) + isSearched = false + + AttachEntityToEntity(playerPed, ped, 11816, 0.54, 0.54, 0.0, 0.0, 0.0, 0.0, false, false, false, false, 2, true) + Wait(1000) + DetachEntity(playerPed, true, false) + ClearPedTasksImmediately(playerPed) + end + end + + Wait(Sleep) + end end) RegisterNetEvent('esx_ambulancejob:clsearch') AddEventHandler('esx_ambulancejob:clsearch', function(medicId) - local playerPed = PlayerPedId() + local playerPed = PlayerPedId() - if isDead then - local coords = GetEntityCoords(playerPed) - local playersInArea = ESX.Game.GetPlayersInArea(coords, 50.0) + if isDead then + local coords = GetEntityCoords(playerPed) + local playersInArea = ESX.Game.GetPlayersInArea(coords, 50.0) - for i=1, #playersInArea, 1 do - local player = playersInArea[i] - if player == GetPlayerFromServerId(medicId) then - medic = tonumber(medicId) - isSearched = true - break - end - end - end + for i = 1, #playersInArea, 1 do + local player = playersInArea[i] + if player == GetPlayerFromServerId(medicId) then + medic = tonumber(medicId) + isSearched = true + break + end + end + end end) function OnPlayerDeath() - isDead = true - ESX.UI.Menu.CloseAll() - ESX.HideUI() - TriggerServerEvent('esx_ambulancejob:setDeathStatus', true) - StartDeathTimer() - StartDistressSignal() + isDead = true + ESX.UI.Menu.CloseAll() + ClearTimecycleModifier() + SetTimecycleModifier("REDMIST_blend") + SetTimecycleModifierStrength(0.7) + SetExtraTimecycleModifier("fp_vig_red") + SetExtraTimecycleModifierStrength(1.0) + SetPedMotionBlur(PlayerPedId(), true) + TriggerServerEvent('esx_ambulancejob:setDeathStatus', true) + StartDeathTimer() + StartDeathCam() + StartDistressSignal() end RegisterNetEvent('esx_ambulancejob:useItem') AddEventHandler('esx_ambulancejob:useItem', function(itemName) - ESX.UI.Menu.CloseAll() + ESX.UI.Menu.CloseAll() - if itemName == 'medikit' then - local lib, anim = 'anim@heists@narcotics@funding@gang_idle', 'gang_chatting_idle01' -- TODO better animations - local playerPed = PlayerPedId() + if itemName == 'medikit' then + local lib, anim = 'anim@heists@narcotics@funding@gang_idle', 'gang_chatting_idle01' -- TODO better animations + local playerPed = PlayerPedId() - ESX.Streaming.RequestAnimDict(lib, function() - TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false) - RemoveAnimDict(lib) + ESX.Streaming.RequestAnimDict(lib, function() + TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false) + RemoveAnimDict(lib) - Wait(500) - while IsEntityPlayingAnim(playerPed, lib, anim, 3) do - Wait(0) - DisableAllControlActions(0) - end + Wait(500) + while IsEntityPlayingAnim(playerPed, lib, anim, 3) do + Wait(0) + DisableAllControlActions(0) + end - TriggerEvent('esx_ambulancejob:heal', 'big', true) - ESX.ShowNotification(_U('used_medikit')) - end) + TriggerEvent('esx_ambulancejob:heal', 'big', true) + ESX.ShowNotification(_U('used_medikit')) + end) - elseif itemName == 'bandage' then - local lib, anim = 'anim@heists@narcotics@funding@gang_idle', 'gang_chatting_idle01' -- TODO better animations - local playerPed = PlayerPedId() + elseif itemName == 'bandage' then + local lib, anim = 'anim@heists@narcotics@funding@gang_idle', 'gang_chatting_idle01' -- TODO better animations + local playerPed = PlayerPedId() - ESX.Streaming.RequestAnimDict(lib, function() - TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false) - RemoveAnimDict(lib) + ESX.Streaming.RequestAnimDict(lib, function() + TaskPlayAnim(playerPed, lib, anim, 8.0, -8.0, -1, 0, 0, false, false, false) + RemoveAnimDict(lib) - Wait(500) - while IsEntityPlayingAnim(playerPed, lib, anim, 3) do - Wait(0) - DisableAllControlActions(0) - end + Wait(500) + while IsEntityPlayingAnim(playerPed, lib, anim, 3) do + Wait(0) + DisableAllControlActions(0) + end - TriggerEvent('esx_ambulancejob:heal', 'small', true) - ESX.ShowNotification(_U('used_bandage')) - end) - end + TriggerEvent('esx_ambulancejob:heal', 'small', true) + ESX.ShowNotification(_U('used_bandage')) + end) + end end) function StartDistressSignal() - CreateThread(function() - local timer = Config.BleedoutTimer + CreateThread(function() + local timer = Config.BleedoutTimer - while timer > 0 and isDead do - Wait(0) - timer = timer - 30 + while timer > 0 and isDead do + Wait(0) + timer = timer - 30 - SetTextFont(4) - SetTextScale(0.5, 0.5) - SetTextColour(200, 50, 50, 255) - SetTextDropshadow(0.1, 3, 27, 27 , 255) - BeginTextCommandDisplayText('STRING') - AddTextComponentSubstringPlayerName(_U('distress_send')) - EndTextCommandDisplayText(0.43, 0.77) + SetTextFont(4) + SetTextScale(0.5, 0.5) + SetTextColour(200, 50, 50, 255) + SetTextDropshadow(0.1, 3, 27, 27, 255) + BeginTextCommandDisplayText('STRING') + AddTextComponentSubstringPlayerName(_U('distress_send')) + EndTextCommandDisplayText(0.43, 0.77) - if IsControlJustReleased(0, 47) then - SendDistressSignal() - break - end - end - end) + if IsControlJustReleased(0, 47) then + SendDistressSignal() + break + end + end + end) end function SendDistressSignal() - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) - ESX.ShowNotification(_U('distress_sent')) - TriggerServerEvent('esx_ambulancejob:onPlayerDistress') + ESX.ShowNotification(_U('distress_sent')) + TriggerServerEvent('esx_ambulancejob:onPlayerDistress') end function DrawGenericTextThisFrame() - SetTextFont(4) - SetTextScale(0.0, 0.5) - SetTextColour(255, 255, 255, 255) - SetTextDropshadow(0, 0, 0, 0, 255) - SetTextDropShadow() - SetTextOutline() - SetTextCentre(true) + SetTextFont(4) + SetTextScale(0.0, 0.5) + SetTextColour(255, 255, 255, 255) + SetTextDropshadow(0, 0, 0, 0, 255) + SetTextDropShadow() + SetTextOutline() + SetTextCentre(true) end function secondsToClock(seconds) - local seconds, hours, mins, secs = tonumber(seconds), 0, 0, 0 + local seconds, hours, mins, secs = tonumber(seconds), 0, 0, 0 - if seconds <= 0 then - return 0, 0 - else - local hours = string.format('%02.f', math.floor(seconds / 3600)) - local mins = string.format('%02.f', math.floor(seconds / 60 - (hours * 60))) - local secs = string.format('%02.f', math.floor(seconds - hours * 3600 - mins * 60)) + if seconds <= 0 then + return 0, 0 + else + local hours = string.format('%02.f', math.floor(seconds / 3600)) + local mins = string.format('%02.f', math.floor(seconds / 60 - (hours * 60))) + local secs = string.format('%02.f', math.floor(seconds - hours * 3600 - mins * 60)) - return mins, secs - end + return mins, secs + end end function StartDeathTimer() - local canPayFine = false + local canPayFine = false - if Config.EarlyRespawnFine then - ESX.TriggerServerCallback('esx_ambulancejob:checkBalance', function(canPay) - canPayFine = canPay - end) - end + if Config.EarlyRespawnFine then + ESX.TriggerServerCallback('esx_ambulancejob:checkBalance', function(canPay) + canPayFine = canPay + end) + end - local earlySpawnTimer = ESX.Math.Round(Config.EarlyRespawnTimer / 1000) - local bleedoutTimer = ESX.Math.Round(Config.BleedoutTimer / 1000) + local earlySpawnTimer = ESX.Math.Round(Config.EarlyRespawnTimer / 1000) + local bleedoutTimer = ESX.Math.Round(Config.BleedoutTimer / 1000) - CreateThread(function() - -- early respawn timer - while earlySpawnTimer > 0 and isDead do - Wait(1000) + CreateThread(function() + -- early respawn timer + while earlySpawnTimer > 0 and isDead do + Wait(1000) - if earlySpawnTimer > 0 then - earlySpawnTimer = earlySpawnTimer - 1 - end - end + if earlySpawnTimer > 0 then + earlySpawnTimer = earlySpawnTimer - 1 + end + end - -- bleedout timer - while bleedoutTimer > 0 and isDead do - Wait(1000) + -- bleedout timer + while bleedoutTimer > 0 and isDead do + Wait(1000) - if bleedoutTimer > 0 then - bleedoutTimer = bleedoutTimer - 1 - end - end - end) + if bleedoutTimer > 0 then + bleedoutTimer = bleedoutTimer - 1 + end + end + end) - CreateThread(function() - local text, timeHeld + CreateThread(function() + local text, timeHeld - -- early respawn timer - while earlySpawnTimer > 0 and isDead do - Wait(0) - text = _U('respawn_available_in', secondsToClock(earlySpawnTimer)) + -- early respawn timer + while earlySpawnTimer > 0 and isDead do + Wait(0) + text = _U('respawn_available_in', secondsToClock(earlySpawnTimer)) - DrawGenericTextThisFrame() - BeginTextCommandDisplayText('STRING') - AddTextComponentSubstringPlayerName(text) - EndTextCommandDisplayText(0.5, 0.8) - end + DrawGenericTextThisFrame() + BeginTextCommandDisplayText('STRING') + AddTextComponentSubstringPlayerName(text) + EndTextCommandDisplayText(0.5, 0.8) + end - -- bleedout timer - while bleedoutTimer > 0 and isDead do - Wait(0) - text = _U('respawn_bleedout_in', secondsToClock(bleedoutTimer)) + -- bleedout timer + while bleedoutTimer > 0 and isDead do + Wait(0) + text = _U('respawn_bleedout_in', secondsToClock(bleedoutTimer)) - if not Config.EarlyRespawnFine then - text = text .. _U('respawn_bleedout_prompt') + if not Config.EarlyRespawnFine then + text = text .. _U('respawn_bleedout_prompt') - if IsControlPressed(0, 38) and timeHeld > 120 then - RemoveItemsAfterRPDeath() - break - end - elseif Config.EarlyRespawnFine and canPayFine then - text = text .. _U('respawn_bleedout_fine', ESX.Math.GroupDigits(Config.EarlyRespawnFineAmount)) + if IsControlPressed(0, 38) and timeHeld > 120 then + RemoveItemsAfterRPDeath() + break + end + elseif Config.EarlyRespawnFine and canPayFine then + text = text .. _U('respawn_bleedout_fine', ESX.Math.GroupDigits(Config.EarlyRespawnFineAmount)) - if IsControlPressed(0, 38) and timeHeld > 120 then - TriggerServerEvent('esx_ambulancejob:payFine') - RemoveItemsAfterRPDeath() - break - end - end + if IsControlPressed(0, 38) and timeHeld > 120 then + TriggerServerEvent('esx_ambulancejob:payFine') + RemoveItemsAfterRPDeath() + break + end + end - if IsControlPressed(0, 38) then - timeHeld += 1 - else - timeHeld = 0 - end + if IsControlPressed(0, 38) then + timeHeld += 1 + else + timeHeld = 0 + end - DrawGenericTextThisFrame() + DrawGenericTextThisFrame() - BeginTextCommandDisplayText('STRING') - AddTextComponentSubstringPlayerName(text) - EndTextCommandDisplayText(0.5, 0.8) - end + BeginTextCommandDisplayText('STRING') + AddTextComponentSubstringPlayerName(text) + EndTextCommandDisplayText(0.5, 0.8) + end - if bleedoutTimer < 1 and isDead then - RemoveItemsAfterRPDeath() - end - end) + if bleedoutTimer < 1 and isDead then + RemoveItemsAfterRPDeath() + end + end) end function GetClosestRespawnPoint() - local PlyCoords = GetEntityCoords(PlayerPedId()) - local ClosestDist, ClosestHospital, ClosestCoord = 10000, {}, nil + local PlyCoords = GetEntityCoords(PlayerPedId()) + local ClosestDist, ClosestHospital, ClosestCoord = 10000, {}, nil - for k,v in pairs(Config.RespawnPoints) do - local Distance = #(PlyCoords - vector3(v.coords.x, v.coords.y, v.coords.z)) - if Distance <= ClosestDist then - ClosestDist = Distance - ClosestHospital = v - ClosestCoord = vector3(v.coords.x, v.coords.y, v.coords.z) - end - end + for k, v in pairs(Config.RespawnPoints) do + local Distance = #(PlyCoords - vector3(v.coords.x, v.coords.y, v.coords.z)) + if Distance <= ClosestDist then + ClosestDist = Distance + ClosestHospital = v + ClosestCoord = vector3(v.coords.x, v.coords.y, v.coords.z) + end + end - return ClosestCoord, ClosestHospital + return ClosestCoord, ClosestHospital end function RemoveItemsAfterRPDeath() - TriggerServerEvent('esx_ambulancejob:setDeathStatus', false) + TriggerServerEvent('esx_ambulancejob:setDeathStatus', false) - CreateThread(function() - ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() - local RespawnCoords, ClosestHospital = GetClosestRespawnPoint() - - ESX.SetPlayerData('loadout', {}) + CreateThread(function() + ESX.TriggerServerCallback('esx_ambulancejob:removeItemsAfterRPDeath', function() + local RespawnCoords, ClosestHospital = GetClosestRespawnPoint() - DoScreenFadeOut(800) - RespawnPed(PlayerPedId(), RespawnCoords, ClosestHospital.heading) - while not IsScreenFadedOut() do - Wait(0) - end - DoScreenFadeIn(800) - end) - end) + ESX.SetPlayerData('loadout', {}) + + DoScreenFadeOut(800) + RespawnPed(PlayerPedId(), RespawnCoords, ClosestHospital.heading) + while not IsScreenFadedOut() do + Wait(0) + end + DoScreenFadeIn(800) + end) + end) end function RespawnPed(ped, coords, heading) - SetEntityCoordsNoOffset(ped, coords.x, coords.y, coords.z, false, false, false) - NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, heading, true, false) - SetPlayerInvincible(ped, false) - ClearPedBloodDamage(ped) + SetEntityCoordsNoOffset(ped, coords.x, coords.y, coords.z, false, false, false) + NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z, heading, true, false) + SetPlayerInvincible(ped, false) + ClearPedBloodDamage(ped) - TriggerServerEvent('esx:onPlayerSpawn') - TriggerEvent('esx:onPlayerSpawn') - TriggerEvent('playerSpawned') -- compatibility with old scripts, will be removed soon + TriggerServerEvent('esx:onPlayerSpawn') + TriggerEvent('esx:onPlayerSpawn') + TriggerEvent('playerSpawned') -- compatibility with old scripts, will be removed soon end RegisterNetEvent('esx_phone:loaded') AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) - local specialContact = { - name = 'Ambulance', - number = 'ambulance', - base64Icon = 'data:image/png;base64,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' - } + local specialContact = {name = 'Ambulance', number = 'ambulance', + base64Icon = 'data:image/png;base64,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'} - TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) + TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) end) AddEventHandler('esx:onPlayerDeath', function(data) - OnPlayerDeath() + OnPlayerDeath() end) RegisterNetEvent('esx_ambulancejob:revive') AddEventHandler('esx_ambulancejob:revive', function() - local playerPed = PlayerPedId() - local coords = GetEntityCoords(playerPed) - TriggerServerEvent('esx_ambulancejob:setDeathStatus', false) - - DoScreenFadeOut(800) + local playerPed = PlayerPedId() + local coords = GetEntityCoords(playerPed) + TriggerServerEvent('esx_ambulancejob:setDeathStatus', false) - while not IsScreenFadedOut() do - Wait(50) - end + DoScreenFadeOut(800) - local formattedCoords = { - x = ESX.Math.Round(coords.x, 1), - y = ESX.Math.Round(coords.y, 1), - z = ESX.Math.Round(coords.z, 1) - } + while not IsScreenFadedOut() do + Wait(50) + end - RespawnPed(playerPed, formattedCoords, 0.0) - isDead = false - DoScreenFadeIn(800) + local formattedCoords = {x = ESX.Math.Round(coords.x, 1), y = ESX.Math.Round(coords.y, 1), z = ESX.Math.Round(coords.z, 1)} + + RespawnPed(playerPed, formattedCoords, 0.0) + isDead = false + ClearTimecycleModifier() + SetPedMotionBlur(playerPed, false) + ClearExtraTimecycleModifier() + EndDeathCam() + DoScreenFadeIn(800) end) -- Load unloaded IPLs if Config.LoadIpl then - RequestIpl('Coroner_Int_on') -- Morgue + RequestIpl('Coroner_Int_on') -- Morgue +end + +local cam = nil + +local isDead = false + +local angleY = 0.0 + +local angleZ = 0.0 + +------------------------------------------------------- + +-----------------DEATH CAMERA FUNCTIONS --------------- + +-------------------------------------------------------- + +-- initialize camera + +function StartDeathCam() + ClearFocus() + local playerPed = PlayerPedId() + cam = CreateCamWithParams("DEFAULT_SCRIPTED_CAMERA", GetEntityCoords(playerPed), 0, 0, 0, GetGameplayCamFov()) + SetCamActive(cam, true) + RenderScriptCams(true, true, 1000, true, false) +end + +-- destroy camera + +function EndDeathCam() + ClearFocus() + RenderScriptCams(false, false, 0, true, false) + DestroyCam(cam, false) + cam = nil +end +-- process camera controls +function ProcessCamControls() + local playerPed = PlayerPedId() + local playerCoords = GetEntityCoords(playerPed) + -- disable 1st person as the 1st person camera can cause some glitches + DisableFirstPersonCamThisFrame() + -- calculate new position + local newPos = ProcessNewPosition() + SetFocusArea(newPos.x, newPos.y, newPos.z, 0.0, 0.0, 0.0) + -- set coords of cam + SetCamCoord(cam, newPos.x, newPos.y, newPos.z) + -- set rotation + PointCamAtCoord(cam, playerCoords.x, playerCoords.y, playerCoords.z + 0.5) +end + +function ProcessNewPosition() + local mouseX = 0.0 + local mouseY = 0.0 + -- keyboard + if (IsInputDisabled(0)) then + -- rotation + mouseX = GetDisabledControlNormal(1, 1) * 8.0 + + mouseY = GetDisabledControlNormal(1, 2) * 8.0 + -- controller + else + mouseX = GetDisabledControlNormal(1, 1) * 1.5 + + mouseY = GetDisabledControlNormal(1, 2) * 1.5 + end + + angleZ = angleZ - mouseX -- around Z axis (left / right) + + angleY = angleY + mouseY -- up / down + -- limit up / down angle to 90° + + if (angleY > 89.0) then + angleY = 89.0 + elseif (angleY < -89.0) then + angleY = -89.0 + end + local pCoords = GetEntityCoords(PlayerPedId()) + local behindCam = {x = pCoords.x + ((Cos(angleZ) * Cos(angleY)) + (Cos(angleY) * Cos(angleZ))) / 2 * (5.5 + 0.5), + + y = pCoords.y + ((Sin(angleZ) * Cos(angleY)) + (Cos(angleY) * Sin(angleZ))) / 2 * (5.5 + 0.5), + + z = pCoords.z + ((Sin(angleY))) * (5.5 + 0.5)} + local rayHandle = StartShapeTestRay(pCoords.x, pCoords.y, pCoords.z + 0.5, behindCam.x, behindCam.y, behindCam.z, -1, PlayerPedId(), 0) + + local a, hitBool, hitCoords, surfaceNormal, entityHit = GetShapeTestResult(rayHandle) + + local maxRadius = 1.9 + if (hitBool and Vdist(pCoords.x, pCoords.y, pCoords.z + 0.5, hitCoords) < 5.5 + 0.5) then + maxRadius = Vdist(pCoords.x, pCoords.y, pCoords.z + 0.5, hitCoords) + end + + local offset = {x = ((Cos(angleZ) * Cos(angleY)) + (Cos(angleY) * Cos(angleZ))) / 2 * maxRadius, + y = ((Sin(angleZ) * Cos(angleY)) + (Cos(angleY) * Sin(angleZ))) / 2 * maxRadius, z = ((Sin(angleY))) * maxRadius} + + local pos = {x = pCoords.x + offset.x, y = pCoords.y + offset.y, z = pCoords.z + offset.z} + + return pos end From 785aac1a18c2a13cdf11da518519e4c80d9b68e8 Mon Sep 17 00:00:00 2001 From: Mycroft Date: Mon, 1 Aug 2022 19:32:49 +0100 Subject: [PATCH 02/15] fix: esx_lscustom: TextUI not appearing --- [esx_addons]/esx_lscustom/client/main.lua | 18 ++++-------------- [esx_addons]/esx_lscustom/locales/en.lua | 2 +- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/[esx_addons]/esx_lscustom/client/main.lua b/[esx_addons]/esx_lscustom/client/main.lua index c5c8b803..ba9cbe58 100644 --- a/[esx_addons]/esx_lscustom/client/main.lua +++ b/[esx_addons]/esx_lscustom/client/main.lua @@ -479,6 +479,7 @@ end) CreateThread(function() while true do local Sleep = 1500 + local Near = false local playerPed = PlayerPedId() if IsPedInAnyVehicle(playerPed, false) then @@ -488,14 +489,14 @@ CreateThread(function() if (ESX.PlayerData.job and ESX.PlayerData.job.name == 'mechanic') or not Config.IsMechanicJobOnly then for k, v in pairs(Config.Zones) do local zonePos = vector3(v.Pos.x, v.Pos.y, v.Pos.z) - if #(coords - zonePos) < v.Size.x then + if #(coords - zonePos) < 10.0 then + Near = true Sleep = 0 if not lsMenuIsShowed then if not HintDisplayed then HintDisplayed = true ESX.TextUI(v.Hint) end - if IsControlJustReleased(0, 38) then lsMenuIsShowed = true @@ -527,21 +528,10 @@ CreateThread(function() end end) end - else - if HintDisplayed then - HintDisplayed = false - ESX.HideUI() - end - end - else - if HintDisplayed then - HintDisplayed = false - ESX.HideUI() end end end - else - if HintDisplayed then + if not Near and HintDisplayed then HintDisplayed = false ESX.HideUI() end diff --git a/[esx_addons]/esx_lscustom/locales/en.lua b/[esx_addons]/esx_lscustom/locales/en.lua index 7f9b7fa9..3f7b5ec9 100644 --- a/[esx_addons]/esx_lscustom/locales/en.lua +++ b/[esx_addons]/esx_lscustom/locales/en.lua @@ -4,7 +4,7 @@ Locales['en'] = { ['already_own'] = 'you already own: %s', ['not_enough_money'] = 'you cannot afford this mod!', ['purchased'] = 'you have purchased the mod!', - ['press_custom'] = 'press ~INPUT_PICKUP~ to personalize your vehicle.', + ['press_custom'] = 'press ~b~[E]~s~ to Personalise Your Vehicle', ['level'] = 'level %s', ['neon'] = 'neon', ['blip_name'] = 'los Santos Customs', From 3000eb8aa6820bd5254321720d93e59275ce0dbc Mon Sep 17 00:00:00 2001 From: Benzo <102178921+Benzo00@users.noreply.github.com> Date: Tue, 2 Aug 2022 16:23:32 +0200 Subject: [PATCH 03/15] fix - ehm something, --- [esx]/esx_context/config.lua | 1 + [esx]/esx_context/fxmanifest.lua | 1 + [esx]/esx_context/index.html | 11 ++- [esx]/esx_context/main.lua | 113 +++++++++++++++++++------------ 4 files changed, 78 insertions(+), 48 deletions(-) create mode 100644 [esx]/esx_context/config.lua diff --git a/[esx]/esx_context/config.lua b/[esx]/esx_context/config.lua new file mode 100644 index 00000000..909b3805 --- /dev/null +++ b/[esx]/esx_context/config.lua @@ -0,0 +1 @@ +PREVIEW_KEYBIND = false -- "LMENU" \ No newline at end of file diff --git a/[esx]/esx_context/fxmanifest.lua b/[esx]/esx_context/fxmanifest.lua index 164a2b59..d46be98c 100644 --- a/[esx]/esx_context/fxmanifest.lua +++ b/[esx]/esx_context/fxmanifest.lua @@ -11,6 +11,7 @@ ui_page 'index.html' shared_script '@es_extended/imports.lua' client_scripts { + 'config.lua', 'main.lua', } diff --git a/[esx]/esx_context/index.html b/[esx]/esx_context/index.html index d504747c..27168ec1 100644 --- a/[esx]/esx_context/index.html +++ b/[esx]/esx_context/index.html @@ -3,6 +3,7 @@ + @@ -286,9 +287,13 @@ }) window.addEventListener("keydown",(e) => { - if (e.key == "Escape" || e.key == "Backspace") { - Close() - } + if (e.key == "Escape" || e.key == "Backspace") { + if (e.target.tagName.toLowerCase() == "input") { + return + } + + Close() + } }) // Open([ diff --git a/[esx]/esx_context/main.lua b/[esx]/esx_context/main.lua index 43fb66f3..6f3634d7 100644 --- a/[esx]/esx_context/main.lua +++ b/[esx]/esx_context/main.lua @@ -20,6 +20,8 @@ function Open(position,eles,onSelect,onClose) onClose = onClose } + LocalPlayer.state:set("context:active",true) + Post("Open",eles,position) end @@ -31,6 +33,8 @@ function Closed() activeMenu = nil + LocalPlayer.state:set("context:active",false) + if cb then cb(menu) end @@ -95,7 +99,7 @@ RegisterNUICallback("selected",function(data) return end - activeMenu.onSelect(activeMenu,ele) + activeMenu:onSelect(ele) end) RegisterNUICallback("changed",function(data) @@ -130,62 +134,81 @@ RegisterNUICallback("changed",function(data) end end) +-- Keybind + +local function focusPreview() + if not activeMenu + or not activeMenu.onSelect + then + return + end + + SetNuiFocus(true,true) +end + +if PREVIEW_KEYBIND then + RegisterCommand("previewContext",focusPreview) + + RegisterKeyMapping("previewContext","Preview Active Context","keyboard",PREVIEW_KEYBIND) +end + +exports("focusPreview",focusPreview) + -- Debug/Test -- Commands: -- [ ctx:preview | ctx:open | ctx:close | ctx:form ] -local position = "right" +if Debug then + local position = "right" -local eles = { - { - unselectable=true, - icon="fas fa-info-circle", - title="Unselectable Item (Header/Label?)", - }, - { - icon="fas fa-check", - title="Item A", - description="Some description here. Add some words to make the text overflow." - }, - { - disabled=true, - icon="fas fa-times", - title="Disabled Item", - description="Some description here. Add some words to make the text overflow." - }, - { - icon="fas fa-check", - title="Item B", - description="Some description here. Add some words to make the text overflow." - }, -} + local eles = { + { + unselectable=true, + icon="fas fa-info-circle", + title="Unselectable Item (Header/Label?)", + }, + { + icon="fas fa-check", + title="Item A", + description="Some description here. Add some words to make the text overflow." + }, + { + disabled=true, + icon="fas fa-times", + title="Disabled Item", + description="Some description here. Add some words to make the text overflow." + }, + { + icon="fas fa-check", + title="Item B", + description="Some description here. Add some words to make the text overflow." + }, + } -local function onSelect(menu,ele) - print("Ele selected",ele.title) + local function onSelect(menu,ele) + print("Ele selected",ele.title) + + if ele.name == "close" then + exports["esx_context"]:Close() + end + + if ele.name ~= "submit" then + return + end + + for _,ele in ipairs(menu.eles) do + if ele.input then + print(ele.name,ele.inputType,ele.inputValue) + end + end - if ele.name == "close" then exports["esx_context"]:Close() end - if ele.name ~= "submit" then - return + local function onClose(menu) + print("Menu closed.") end - for _,ele in ipairs(menu.eles) do - if ele.input then - print(ele.name,ele.inputType,ele.inputValue) - end - end - - exports["esx_context"]:Close() -end - -local function onClose(menu) - print("Menu closed.") -end - - -if Debug then RegisterCommand("ctx:preview",function() exports["esx_context"]:Preview(position,eles) end) From 777b568ba9f3051ad0f5dc54be301e258c2cca01 Mon Sep 17 00:00:00 2001 From: Mycroft Date: Wed, 3 Aug 2022 22:19:06 +0100 Subject: [PATCH 04/15] refactor: better readme --- readme.md | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/readme.md b/readme.md index 4607d927..1c6f9559 100644 --- a/readme.md +++ b/readme.md @@ -1,24 +1,17 @@ -

ESX Legacy

Discord - Website - Documentation +

ESX Legacy

+

+

Discord - Website - Documentation -**IMPORTANT**: ESX Legacy now supports ox Inventory. **HOWEVER, THIS SHOULD ONLY BE USED IF YOU ARE EXPERIENCED AND KNOW WHAT YOU ARE DOING**. - -##### ESX is the leading framework for creating roleplay servers on FiveM, with many official and community resources designed to utilise the tools provided here. For a taste of what's available - -> esx_identity: Enables character registration defining a players name, sex, height, and date of birth -> esx_society: Allows job resources to register a society, gaining employee management, society funds, and more -> esx_billing: Allows members of some societies to send fines or bills to other players -> esx_vehicleshop: Allow players to purchase vehicles from a dealership, or setup society support for a player-managed dealership -> esx_ambulancejob: Adds a death and respawn system while allowing players to work as EMS to heal and revive others - -Many more resources are included in this repository, or you can browse the [ESX Community Github](https://github.com/esx-community/) or [Cfx.re Releases board](https://forum.cfx.re/tag/esx) for more. +

Want More resources? You can browse the ESX Community Github or Cfx.re Releases board for more! +

ESX is the leading framework, trusted By thousands of commmunitys for the heighest quality roleplay servers on FiveM


### License -es_extended - ESX framework for FiveM +ESX-legacy - ESX framework for FiveM -Copyright (C) 2015-2022 Jérémie N'gadi +Copyright (C) 2015-2022 ESX-Framework This program Is free software: you can redistribute it And/Or modify it under the terms Of the GNU General Public License As published by the Free Software Foundation, either version 3 Of the License, Or (at your option) any later version. From f4adea60e0806b94f4e96db1041e0aa4fbb609e2 Mon Sep 17 00:00:00 2001 From: Mycroft Date: Fri, 5 Aug 2022 05:01:22 +0100 Subject: [PATCH 05/15] fix error --- [esx]/async/async.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/[esx]/async/async.lua b/[esx]/async/async.lua index 72cf0130..aacd1a44 100644 --- a/[esx]/async/async.lua +++ b/[esx]/async/async.lua @@ -35,7 +35,7 @@ function Async.parallelLimit(tasks, limit, cb) local queue, results = {}, {} for i=1, #tasks, 1 do - queue[queue + 1] = tasks[i] + queue[#queue + 1] = tasks[i] end local function processQueue() From 5dc65a031b78b44d6c1ff9b5db3df17725d52ab3 Mon Sep 17 00:00:00 2001 From: Mycroft Date: Sat, 6 Aug 2022 23:53:36 +0100 Subject: [PATCH 06/15] ! Refactor: Progressbar - Colour Support, onClose support, Scenario support --- [esx]/esx_progressbar/Progress.lua | 28 +++++++++++++++++--- [esx]/esx_progressbar/fxmanifest.lua | 1 + [esx]/esx_progressbar/nui/js/script.js | 36 +++++++++++++++++++++++++- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/[esx]/esx_progressbar/Progress.lua b/[esx]/esx_progressbar/Progress.lua index 8e33f207..5f19b0ec 100644 --- a/[esx]/esx_progressbar/Progress.lua +++ b/[esx]/esx_progressbar/Progress.lua @@ -5,6 +5,8 @@ local function Progressbar(message,length,Options) TaskPlayAnim(ESX.PlayerData.ped, Options.animation.dict, Options.animation.lib, 1.0, 1.0, length, 1, 1.0, false,false,false) RemoveAnimDict(Options.animation.dict) end) + elseif Options.animation.type == "Scenario" then + TaskStartScenarioInPlace(ESX.PlayerData.ped, Options.animation.Scenario, 0, true) end end if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(),Options.FreezePlayer) end @@ -13,10 +15,28 @@ local function Progressbar(message,length,Options) length = length or 3000, message = message or "ESX-Framework" })) - Wait(length) - if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(),not Options.FreezePlayer) end - if Options.onFinish then Options.onFinish() end + if Options.onCancel then + SendNuiMessage(json.encode({ + type = "Close" + })) + local le = length or 3000 + while le > 0 do + Wait(0) + le -= 1 + if IsControlJustPressed(0, 178) then + Options.onCancel() + break + end + end + else + SetTimeout(length, function() + if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end + if Options.onFinish then Options.onFinish() end + end) + end + + + end exports('Progressbar', Progressbar) - diff --git a/[esx]/esx_progressbar/fxmanifest.lua b/[esx]/esx_progressbar/fxmanifest.lua index 8df232aa..0ac65731 100644 --- a/[esx]/esx_progressbar/fxmanifest.lua +++ b/[esx]/esx_progressbar/fxmanifest.lua @@ -1,6 +1,7 @@ fx_version 'adamant' game 'gta5' author 'ESX-Framework' +lua54 'yes' description 'ESX Progressbar' client_scripts { 'Progress.lua' } diff --git a/[esx]/esx_progressbar/nui/js/script.js b/[esx]/esx_progressbar/nui/js/script.js index 9ffa5e71..ec59f436 100644 --- a/[esx]/esx_progressbar/nui/js/script.js +++ b/[esx]/esx_progressbar/nui/js/script.js @@ -1,9 +1,43 @@ const w = window const doc = document +const codes = { + "~r~": "red", + "~b~": "#378cbf", + "~g~": "green", + "~y~": "yellow", + "~p~": "purple", + "~c~": "grey", + "~m~": "#212121", + "~u~": "black", + "~o~": "orange" +} + + $(function () { w.addEventListener('message', function(e) { - $(".text").text(e.data.message) + var message = e.data.message + const replaceColors = (str, obj) => { + let strToReplace = str + + for (let id in obj) { + strToReplace = strToReplace.replace(new RegExp(id, 'g'), obj[id]) + } + + return strToReplace + } + for (color in codes) { + if (message.includes(color)) { + let objArr = {}; + objArr[color] = ``; + objArr["~s~"] = ""; + + let newStr = replaceColors(message, objArr); + + message = newStr; + } + } + $(".text").text(message) if (e.data.type === "Progressbar") { doc.getElementById("notifyInfo").style.display = "block"; const start = new Date(); From 536ef757899fea68fec3edf0f3514735cec2ec4c Mon Sep 17 00:00:00 2001 From: Mycroft Date: Sun, 7 Aug 2022 00:02:38 +0100 Subject: [PATCH 07/15] fix - progressbar - while loop --- [esx]/esx_progressbar/Progress.lua | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/[esx]/esx_progressbar/Progress.lua b/[esx]/esx_progressbar/Progress.lua index 5f19b0ec..1fdd42f0 100644 --- a/[esx]/esx_progressbar/Progress.lua +++ b/[esx]/esx_progressbar/Progress.lua @@ -16,9 +16,6 @@ local function Progressbar(message,length,Options) message = message or "ESX-Framework" })) if Options.onCancel then - SendNuiMessage(json.encode({ - type = "Close" - })) local le = length or 3000 while le > 0 do Wait(0) @@ -28,8 +25,15 @@ local function Progressbar(message,length,Options) break end end + SendNuiMessage(json.encode({ + type = "Close" + })) + ClearPedTasks(ESX.PlayerData.ped) + if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end + if Options.onFinish then Options.onFinish() end else SetTimeout(length, function() + ClearPedTasks(ESX.PlayerData.ped) if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end if Options.onFinish then Options.onFinish() end end) @@ -40,3 +44,4 @@ local function Progressbar(message,length,Options) end exports('Progressbar', Progressbar) + From e935a9a6b6506cf6d474bc18f44670542e5ba190 Mon Sep 17 00:00:00 2001 From: Mycroft Date: Sun, 7 Aug 2022 00:06:47 +0100 Subject: [PATCH 08/15] readme didnt update for some reason :( --- [esx]/esx_progressbar/Progress.lua | 70 +++++++++++++++--------------- [esx]/esx_progressbar/readme.md | 39 ++++++++++++++++- 2 files changed, 73 insertions(+), 36 deletions(-) diff --git a/[esx]/esx_progressbar/Progress.lua b/[esx]/esx_progressbar/Progress.lua index 1fdd42f0..b0217415 100644 --- a/[esx]/esx_progressbar/Progress.lua +++ b/[esx]/esx_progressbar/Progress.lua @@ -1,46 +1,48 @@ +local InProgress = false local function Progressbar(message,length,Options) - if Options.animation then - if Options.animation.type == "anim" then - ESX.Streaming.RequestAnimDict(Options.animation.dict, function() - TaskPlayAnim(ESX.PlayerData.ped, Options.animation.dict, Options.animation.lib, 1.0, 1.0, length, 1, 1.0, false,false,false) - RemoveAnimDict(Options.animation.dict) - end) - elseif Options.animation.type == "Scenario" then - TaskStartScenarioInPlace(ESX.PlayerData.ped, Options.animation.Scenario, 0, true) - end - end - if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(),Options.FreezePlayer) end - SendNuiMessage(json.encode({ - type = "Progressbar", - length = length or 3000, - message = message or "ESX-Framework" - })) - if Options.onCancel then - local le = length or 3000 - while le > 0 do - Wait(0) - le -= 1 - if IsControlJustPressed(0, 178) then - Options.onCancel() - break + if not InProgress then + if Options.animation then + if Options.animation.type == "anim" then + ESX.Streaming.RequestAnimDict(Options.animation.dict, function() + TaskPlayAnim(ESX.PlayerData.ped, Options.animation.dict, Options.animation.lib, 1.0, 1.0, length, 1, 1.0, false,false,false) + RemoveAnimDict(Options.animation.dict) + end) + elseif Options.animation.type == "Scenario" then + TaskStartScenarioInPlace(ESX.PlayerData.ped, Options.animation.Scenario, 0, true) end end + if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(),Options.FreezePlayer) end SendNuiMessage(json.encode({ - type = "Close" + type = "Progressbar", + length = length or 3000, + message = message or "ESX-Framework" })) - ClearPedTasks(ESX.PlayerData.ped) - if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end - if Options.onFinish then Options.onFinish() end - else - SetTimeout(length, function() + if Options.onCancel then + local le = length or 3000 + while le > 0 do + Wait(0) + le -= 1 + if IsControlJustPressed(0, 178) then + SendNuiMessage(json.encode({ + type = "Close" + })) + Options.onCancel() + break + end + end ClearPedTasks(ESX.PlayerData.ped) if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end if Options.onFinish then Options.onFinish() end - end) + InProgress = false + else + SetTimeout(length, function() + ClearPedTasks(ESX.PlayerData.ped) + if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end + if Options.onFinish then Options.onFinish() end + InProgress = false + end) + end end - - - end exports('Progressbar', Progressbar) diff --git a/[esx]/esx_progressbar/readme.md b/[esx]/esx_progressbar/readme.md index e01762be..c99b59f6 100644 --- a/[esx]/esx_progressbar/readme.md +++ b/[esx]/esx_progressbar/readme.md @@ -16,6 +16,7 @@ ``` * Export + ```lua exports["esx_progressbar"]:Progressbar("Unlocking Storage", 3000,{ FreezePlayer = true, @@ -27,5 +28,39 @@ onFinish = function() --Code here end}) - - ``` +``` + +* Cancel + +```lua + ESX.Progressbar("Unlocking Storage", 3000,{ + FreezePlayer = true, + animation ={ + type = "anim", + dict = "anim@mp_player_intmenu@key_fob@", + lib ="fob_click" + }, + onFinish = function() + --Code here + end, OnCancel = function() + --Code here + end + }) +``` + +* Scenario + +```lua + ESX.Progressbar("Unlocking Storage", 3000,{ + FreezePlayer = true, + animation ={ + type = "Scenario", + Scenario = "PROP_HUMAN_BUM_BIN", + }, + onFinish = function() + --Code here + end, OnCancel = function() + --Code here + end + }) +``` \ No newline at end of file From 136da6cca6bc7d9af4960eb1f0d8491b923376e3 Mon Sep 17 00:00:00 2001 From: Mycroft Date: Sun, 7 Aug 2022 00:12:54 +0100 Subject: [PATCH 09/15] fix: typo --- [esx]/esx_progressbar/Progress.lua | 2 +- [esx]/esx_progressbar/readme.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/[esx]/esx_progressbar/Progress.lua b/[esx]/esx_progressbar/Progress.lua index b0217415..6e1bc73e 100644 --- a/[esx]/esx_progressbar/Progress.lua +++ b/[esx]/esx_progressbar/Progress.lua @@ -26,6 +26,7 @@ local function Progressbar(message,length,Options) SendNuiMessage(json.encode({ type = "Close" })) + le = 0 Options.onCancel() break end @@ -46,4 +47,3 @@ local function Progressbar(message,length,Options) end exports('Progressbar', Progressbar) - diff --git a/[esx]/esx_progressbar/readme.md b/[esx]/esx_progressbar/readme.md index c99b59f6..3af81bf0 100644 --- a/[esx]/esx_progressbar/readme.md +++ b/[esx]/esx_progressbar/readme.md @@ -42,7 +42,7 @@ }, onFinish = function() --Code here - end, OnCancel = function() + end, onCancel = function() --Code here end }) @@ -59,7 +59,7 @@ }, onFinish = function() --Code here - end, OnCancel = function() + end, onCancel = function() --Code here end }) From c02c0a05457e61eca5f4182a0d35d807bc32edbb Mon Sep 17 00:00:00 2001 From: Mycroft Date: Sun, 7 Aug 2022 00:14:53 +0100 Subject: [PATCH 10/15] fix: progressbar - make sure we are wanting to show when doing colours --- [esx]/esx_progressbar/nui/js/script.js | 45 +++++++++++++------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/[esx]/esx_progressbar/nui/js/script.js b/[esx]/esx_progressbar/nui/js/script.js index ec59f436..de331b93 100644 --- a/[esx]/esx_progressbar/nui/js/script.js +++ b/[esx]/esx_progressbar/nui/js/script.js @@ -13,32 +13,31 @@ const codes = { "~o~": "orange" } - $(function () { w.addEventListener('message', function(e) { - var message = e.data.message - const replaceColors = (str, obj) => { - let strToReplace = str - - for (let id in obj) { - strToReplace = strToReplace.replace(new RegExp(id, 'g'), obj[id]) - } - - return strToReplace - } - for (color in codes) { - if (message.includes(color)) { - let objArr = {}; - objArr[color] = ``; - objArr["~s~"] = ""; - - let newStr = replaceColors(message, objArr); - - message = newStr; - } - } - $(".text").text(message) if (e.data.type === "Progressbar") { + var message = e.data.message + const replaceColors = (str, obj) => { + let strToReplace = str + + for (let id in obj) { + strToReplace = strToReplace.replace(new RegExp(id, 'g'), obj[id]) + } + + return strToReplace + } + for (color in codes) { + if (message.includes(color)) { + let objArr = {}; + objArr[color] = ``; + objArr["~s~"] = ""; + + let newStr = replaceColors(message, objArr); + + message = newStr; + } + } + $(".text").text(message) doc.getElementById("notifyInfo").style.display = "block"; const start = new Date(); const maxTime = e.data.length From 12a5be072566fe1f9e4f04645314ad90f8903565 Mon Sep 17 00:00:00 2001 From: Mycroft Date: Sun, 7 Aug 2022 00:19:26 +0100 Subject: [PATCH 11/15] probably a better way but oh well --- [esx]/esx_progressbar/Progress.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/[esx]/esx_progressbar/Progress.lua b/[esx]/esx_progressbar/Progress.lua index 6e1bc73e..c529dd76 100644 --- a/[esx]/esx_progressbar/Progress.lua +++ b/[esx]/esx_progressbar/Progress.lua @@ -27,6 +27,10 @@ local function Progressbar(message,length,Options) type = "Close" })) le = 0 + ClearPedTasks(ESX.PlayerData.ped) + if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end + if Options.onFinish then Options.onFinish() end + InProgress = false Options.onCancel() break end @@ -47,3 +51,4 @@ local function Progressbar(message,length,Options) end exports('Progressbar', Progressbar) + From 81b174b5027d0dc360ab8de40d2c363ac7813e95 Mon Sep 17 00:00:00 2001 From: Mycroft Date: Sun, 7 Aug 2022 00:20:16 +0100 Subject: [PATCH 12/15] make sure its 100% canceled --- [esx]/esx_progressbar/Progress.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/[esx]/esx_progressbar/Progress.lua b/[esx]/esx_progressbar/Progress.lua index c529dd76..7b6b90aa 100644 --- a/[esx]/esx_progressbar/Progress.lua +++ b/[esx]/esx_progressbar/Progress.lua @@ -26,12 +26,12 @@ local function Progressbar(message,length,Options) SendNuiMessage(json.encode({ type = "Close" })) - le = 0 ClearPedTasks(ESX.PlayerData.ped) if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end if Options.onFinish then Options.onFinish() end InProgress = false Options.onCancel() + le = 0 break end end From a69496174744c6f7163450324c6c5a189abf8199 Mon Sep 17 00:00:00 2001 From: Mycroft Date: Sun, 7 Aug 2022 00:33:32 +0100 Subject: [PATCH 13/15] found the better method :) --- [esx]/esx_progressbar/Progress.lua | 45 +++++++++++++----------------- 1 file changed, 19 insertions(+), 26 deletions(-) diff --git a/[esx]/esx_progressbar/Progress.lua b/[esx]/esx_progressbar/Progress.lua index 7b6b90aa..797d357d 100644 --- a/[esx]/esx_progressbar/Progress.lua +++ b/[esx]/esx_progressbar/Progress.lua @@ -1,5 +1,6 @@ local InProgress = false local function Progressbar(message,length,Options) + local Canceled = false if not InProgress then if Options.animation then if Options.animation.type == "anim" then @@ -17,35 +18,27 @@ local function Progressbar(message,length,Options) length = length or 3000, message = message or "ESX-Framework" })) - if Options.onCancel then - local le = length or 3000 - while le > 0 do - Wait(0) - le -= 1 - if IsControlJustPressed(0, 178) then - SendNuiMessage(json.encode({ - type = "Close" - })) - ClearPedTasks(ESX.PlayerData.ped) - if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end - if Options.onFinish then Options.onFinish() end - InProgress = false - Options.onCancel() - le = 0 - break - end + local le = length or 3000 + while le > 0 do + Wait(0) + le -= 1 + if IsControlJustPressed(0, 194) and Options.onCancel then + SendNuiMessage(json.encode({ + type = "Close" + })) + Canceled = true + ClearPedTasksImmediately(ESX.PlayerData.ped) + if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end + InProgress = false + le = 0 + Options.onCancel() end - ClearPedTasks(ESX.PlayerData.ped) - if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end + end + if not Canceled then + ClearPedTasks(ESX.PlayerData.ped) + if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end if Options.onFinish then Options.onFinish() end InProgress = false - else - SetTimeout(length, function() - ClearPedTasks(ESX.PlayerData.ped) - if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end - if Options.onFinish then Options.onFinish() end - InProgress = false - end) end end end From ade89c1ba183cce0db847d64b71182b9cc8d2e3e Mon Sep 17 00:00:00 2001 From: Mycroft Date: Sun, 7 Aug 2022 01:29:38 +0100 Subject: [PATCH 14/15] fix:progressbar - fully working :) --- [esx]/esx_progressbar/Progress.lua | 49 ++++++++++++++------------ [esx]/esx_progressbar/nui/js/script.js | 7 ++-- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/[esx]/esx_progressbar/Progress.lua b/[esx]/esx_progressbar/Progress.lua index 797d357d..b89e56fa 100644 --- a/[esx]/esx_progressbar/Progress.lua +++ b/[esx]/esx_progressbar/Progress.lua @@ -1,7 +1,8 @@ -local InProgress = false +local CurrentProgress = nil local function Progressbar(message,length,Options) local Canceled = false - if not InProgress then + if not CurrentProgress then + CurrentProgress = Options if Options.animation then if Options.animation.type == "anim" then ESX.Streaming.RequestAnimDict(Options.animation.dict, function() @@ -18,30 +19,32 @@ local function Progressbar(message,length,Options) length = length or 3000, message = message or "ESX-Framework" })) - local le = length or 3000 - while le > 0 do - Wait(0) - le -= 1 - if IsControlJustPressed(0, 194) and Options.onCancel then - SendNuiMessage(json.encode({ - type = "Close" - })) - Canceled = true - ClearPedTasksImmediately(ESX.PlayerData.ped) + CurrentProgress.length = length or 3000 + while CurrentProgress ~= nil do + if CurrentProgress.length > 0 then + CurrentProgress.length -= 1000 + else + ClearPedTasks(ESX.PlayerData.ped) if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end - InProgress = false - le = 0 - Options.onCancel() + if Options.onFinish then Options.onFinish() end + CurrentProgress = nil end - end - if not Canceled then - ClearPedTasks(ESX.PlayerData.ped) - if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end - if Options.onFinish then Options.onFinish() end - InProgress = false + Wait(1000) end end end -exports('Progressbar', Progressbar) - +ESX.RegisterInput("cancelprog", "[ProgressBar] Cancel Progressbar", "keyboard", "BACK", function() + if not CurrentProgress then return end + if not CurrentProgress.onCancel then return end + SendNuiMessage(json.encode({ + type = "Close" + })) + ClearPedTasks(ESX.PlayerData.ped) + if CurrentProgress.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end + CurrentProgress.canceled = true + CurrentProgress.length = 0 + CurrentProgress.onCancel() + CurrentProgress = nil +end) +exports('Progressbar', Progressbar) \ No newline at end of file diff --git a/[esx]/esx_progressbar/nui/js/script.js b/[esx]/esx_progressbar/nui/js/script.js index de331b93..b362b306 100644 --- a/[esx]/esx_progressbar/nui/js/script.js +++ b/[esx]/esx_progressbar/nui/js/script.js @@ -40,7 +40,7 @@ $(function () { $(".text").text(message) doc.getElementById("notifyInfo").style.display = "block"; const start = new Date(); - const maxTime = e.data.length + const maxTime = e.data.length; const timeoutValue = Math.floor(maxTime/100); animUpdate(); @@ -54,13 +54,16 @@ $(function () { const prc = Math.round((timeoutDiff/maxTime)*100); if (prc <= 100) { updateProg(prc); - setTimeout(animUpdate, timeoutValue); + this.timeoutID = setTimeout(animUpdate, timeoutValue); } else { doc.getElementById('notifyInfo').style.display = "none"; } } } else { doc.getElementById("notifyInfo").style.display = "none" + clearTimeout(this.timeoutID); + timeoutValue = 0; + } }) }) From c5d6f14e4668c3aaf6fac0e1421b4c9e7c359328 Mon Sep 17 00:00:00 2001 From: Mycroft Date: Sun, 7 Aug 2022 01:40:33 +0100 Subject: [PATCH 15/15] allow no options to progressbar --- [esx]/esx_progressbar/Progress.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/[esx]/esx_progressbar/Progress.lua b/[esx]/esx_progressbar/Progress.lua index b89e56fa..52652729 100644 --- a/[esx]/esx_progressbar/Progress.lua +++ b/[esx]/esx_progressbar/Progress.lua @@ -2,18 +2,18 @@ local CurrentProgress = nil local function Progressbar(message,length,Options) local Canceled = false if not CurrentProgress then - CurrentProgress = Options - if Options.animation then - if Options.animation.type == "anim" then - ESX.Streaming.RequestAnimDict(Options.animation.dict, function() - TaskPlayAnim(ESX.PlayerData.ped, Options.animation.dict, Options.animation.lib, 1.0, 1.0, length, 1, 1.0, false,false,false) - RemoveAnimDict(Options.animation.dict) + CurrentProgress = Options or {} + if CurrentProgress.animation then + if CurrentProgress.animation.type == "anim" then + ESX.Streaming.RequestAnimDict(CurrentProgress.animation.dict, function() + TaskPlayAnim(ESX.PlayerData.ped, CurrentProgress.animation.dict, CurrentProgress.animation.lib, 1.0, 1.0, length, 1, 1.0, false,false,false) + RemoveAnimDict(CurrentProgress.animation.dict) end) - elseif Options.animation.type == "Scenario" then - TaskStartScenarioInPlace(ESX.PlayerData.ped, Options.animation.Scenario, 0, true) + elseif CurrentProgress.animation.type == "Scenario" then + TaskStartScenarioInPlace(ESX.PlayerData.ped, CurrentProgress.animation.Scenario, 0, true) end end - if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(),Options.FreezePlayer) end + if CurrentProgress.FreezePlayer then FreezeEntityPosition(PlayerPedId(),CurrentProgress.FreezePlayer) end SendNuiMessage(json.encode({ type = "Progressbar", length = length or 3000, @@ -25,8 +25,8 @@ local function Progressbar(message,length,Options) CurrentProgress.length -= 1000 else ClearPedTasks(ESX.PlayerData.ped) - if Options.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end - if Options.onFinish then Options.onFinish() end + if CurrentProgress.FreezePlayer then FreezeEntityPosition(PlayerPedId(), false) end + if CurrentProgress.onFinish then CurrentProgress.onFinish() end CurrentProgress = nil end Wait(1000)