diff --git a/README.md b/README.md
index df92ae2..a54e80b 100644
--- a/README.md
+++ b/README.md
@@ -4,46 +4,109 @@
Ultra customizable hud featuring a unique and robust settings menu. Change eveything about your experience!

+### **Dependencies**
+- [ox_lib](https://github.com/overextended/ox_lib)
-### Optional:
-* [ps-buffs](https://github.com/Project-Sloth/ps-buffs)
+### **Optional**
+- [ps-buffs](https://github.com/Project-Sloth/ps-buffs)
-### ⚠️Important:
-- **Do not rename this resource from ps-hud or you will encounter issues.**
-- Locale is now supported. Make sure that your qb-core is update. You can update it [here](https://github.com/qbcore-framework/qb-core).
-- **This script is fully open source, it has no obfuscation.** Svelte compiled the js when it gets build and original source code is here [svelte-source](https://github.com/Project-Sloth/ps-hud/tree/main/svelte-source).
-- **If the minimap is pulsating or flickering**, make sure if you are using custom maps that you ensure ps-hud BEFORE map resource or if another script use the `SetRadarZoom()` native for disable it there.
-
-
-
-
-
+---
-### Start installing now
-We will now provide you with a step-by-step guide for the installation process. Shouldn't take too long and it shouldn't be too confusing either!
+## ⚠️ **Important Information**
+- **Do not rename the resource from `ps-hud`, or issues may occur.**
+- Locale is supported. Ensure your `qb-core` is up to date: [Update qb-core](https://github.com/qbcore-framework/qb-core).
+- **This script is fully open source** with no obfuscation. Svelte compiles the JS during the build. The original source code is available [here](https://github.com/Project-Sloth/ps-hud/tree/main/svelte-source).
+- **Minimap Flickering:** If the minimap pulsates or flickers, ensure that `ps-hud` is started **before** the map resource or adjust any scripts using `SetRadarZoom()`.
+---
-### Step 1:
-Go ahead and start by dragging and dropping ps-hud into your designated resources folder.
-
-If you are still lost, Slothy has created a few GIF's to help guide you through all the installation steps.
-
-
-
-
-
-
-### Admin Only Setting:
-If you don't want your community to be able to access the customizability options within the menu; make sure to change **Config.AdminOnly** to **true** instead of **false**. Keep in mind as well, while **true**, the changes you save will override for everyone on the server.
-
-This configuration setting is found in **ps-hud/config.lua** as shown in the GIF below.
-
-
+
-
+## **Installation Guide**
+Follow these steps for a seamless installation:
+
+### **Step 1: Add to Your Resources**
+Drag and drop the `ps-hud` folder into your designated resources folder.
+
+💡 Need extra help? Watch this GIF for guidance:
+
+
+---
+
+### **Admin-Only Setting**
+To restrict access to customization options, set **`Config.AdminOnly = true`**. While enabled, admin-saved settings override those of other players.
+
+Modify this in `ps-hud/config.lua` as shown:
+
+
+---
+
+## Framework-Specific Setup
+
+### **QB-Core**
+1. **Set Framework**:
+ `Config.Framework = 'qb'` in the configuration file.
+2. **Update fxmanifest**:
+ Comment out line 18:
+ ```lua
+ -- '@qbx_core/modules/playerdata.lua'
+ ```
+3. **Prevent Spawn In Health Regen**:
+ - if you use qb-ambulancejob head to client/job.lua
+ - look around line 107 for this event
+ ```lua
+ RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
+ exports.spawnmanager:setAutoSpawn(false)
+ local ped = PlayerPedId()
+ local player = PlayerId()
+ CreateThread(function()
+ Wait(5000)
+ SetEntityMaxHealth(ped, 200)
+ SetEntityHealth(ped, 200)
+ SetPlayerHealthRechargeMultiplier(player, 0.0)
+ SetPlayerHealthRechargeLimit(player, 0.0)
+ end)
+ CreateThread(function()
+ Wait(1000)
+ QBCore.Functions.GetPlayerData(function(PlayerData)
+ PlayerJob = PlayerData.job
+ onDuty = PlayerData.job.onduty
+ SetPedArmour(PlayerPedId(), PlayerData.metadata['armor'])
+ if (not PlayerData.metadata['inlaststand'] and PlayerData.metadata['isdead']) then
+ deathTime = Config.ReviveInterval
+ OnDeath()
+ DeathTimer()
+ elseif (PlayerData.metadata['inlaststand'] and not PlayerData.metadata['isdead']) then
+ SetLaststand(true)
+ else
+ TriggerServerEvent('hospital:server:SetDeathStatus', false)
+ TriggerServerEvent('hospital:server:SetLaststandStatus', false)
+ end
+ if PlayerJob.name == 'ambulance' and onDuty then
+ TriggerServerEvent('hospital:server:AddDoctor', PlayerJob.name)
+ end
+ end)
+ end)
+ end)
+ ```
+ and we are just going to comment out these
+ ```lua
+ SetEntityHealth(ped, 200)
+ ```
+
+### **QBox Install**
+1. **Set the Framework**:
+ Ensure `Config.Framework = 'qbx'` in the configuration file.
+2. **Update fxmanifest**:
+ Verify that line 18 is **not commented out**:
+ ```lua
+ '@qbx_core/modules/playerdata.lua'
+ ```
+#
+

@@ -53,11 +116,10 @@ This configuration setting is found in **ps-hud/config.lua** as shown in the GIF
* Customize settings for individual icons
* Endless options for icon position and orientation
-
+#

-
### Time to show you what it looks like!
Here's a few showcased examples while using ps-hud.
diff --git a/client.lua b/client/client.lua
similarity index 89%
rename from client.lua
rename to client/client.lua
index d2417b4..d767074 100644
--- a/client.lua
+++ b/client/client.lua
@@ -78,7 +78,7 @@ local function hasHarness()
if not IsPedInAnyVehicle(ped, false) then return end
local _harness = false
- local hasHarness = exports['qb-smallresources']:HasHarness()
+ local hasHarness = getHarness()
if hasHarness then
_harness = true
else
@@ -89,7 +89,7 @@ local function hasHarness()
end
local function loadSettings()
- QBCore.Functions.Notify(Lang:t("notify.hud_settings_loaded"), "success")
+ Notify(Lang:t("notify.hud_settings_loaded"), "success")
Wait(1000)
TriggerEvent("hud:client:LoadMap")
end
@@ -113,14 +113,13 @@ local function sendUIUpdateMessage(data)
end
local function HandleSetupResource()
- QBCore.Functions.TriggerCallback('hud:server:getRank', function(isAdminOrGreater)
- if isAdminOrGreater then
- admin = true
- else
- admin = false
- end
- SendAdminStatus()
- end)
+ local isAdminOrGreater = lib.callback.await('hud:server:getRank', false)
+ if isAdminOrGreater then
+ admin = true
+ else
+ admin = false
+ end
+ SendAdminStatus()
if Config.AdminOnly then
-- Send the client what the saved ui config is (enforced by the server)
if next(UIConfig) then
@@ -131,13 +130,28 @@ end
RegisterNetEvent("QBCore:Client:OnPlayerLoaded", function()
Wait(2000)
+
HandleSetupResource()
-- local hudSettings = GetResourceKvpString('hudSettings')
-- if hudSettings then loadSettings(json.decode(hudSettings)) end
loadSettings()
PlayerData = QBCore.Functions.GetPlayerData()
+ local player = PlayerId()
+ SetPlayerHealthRechargeMultiplier(player, 0.0)
+ SetPlayerHealthRechargeLimit(player, 0.0)
+ repeat Wait(1) until type(PlayerData) == 'table'
+ local health = PlayerData.metadata['health']
+ if not health then
+ local add = lib.callback.await('ps-hud:getHealth', false)
+ health = add
+ end
+ SetEntityHealth(PlayerPedId(), health)
+ if Config.PersistantArmor then
+ SetPedArmour(PlayerPedId(), QBCore.Functions.GetPlayerData().metadata['armor'])
+ end
end)
+
RegisterNetEvent("QBCore:Client:OnPlayerUnload", function()
PlayerData = {}
admin = false
@@ -186,7 +200,7 @@ RegisterKeyMapping('menu', Lang:t('info.open_menu'), 'keyboard', Config.OpenMenu
-- Reset hud
local function restartHud()
TriggerEvent("hud:client:playResetHudSounds")
- QBCore.Functions.Notify(Lang:t("notify.hud_restart"), "error")
+ Notify(Lang:t("notify.hud_restart"), "error")
Wait(1500)
if IsPedInAnyVehicle(PlayerPedId()) then
SendNUIMessage({
@@ -215,7 +229,7 @@ local function restartHud()
show = true,
})
Wait(500)
- QBCore.Functions.Notify(Lang:t("notify.hud_start"), "success")
+ Notify(Lang:t("notify.hud_start"), "success")
SendNUIMessage({
action = 'menu',
topic = 'restart',
@@ -244,7 +258,9 @@ RegisterNetEvent("hud:client:resetStorage", function()
if Menu.isResetSoundsChecked then
TriggerServerEvent("InteractSound_SV:PlayOnSource", "airwrench", 0.1)
end
- QBCore.Functions.TriggerCallback('hud:server:getMenu', function(menu) loadSettings(menu); SetResourceKvp('hudSettings', json.encode(menu)) end)
+ local menu = lib.callback.await('hud:server:getMenu', false)
+ loadSettings(menu);
+ SetResourceKvp('hudSettings', json.encode(menu))
end)
-- Notifications
@@ -414,7 +430,7 @@ RegisterNetEvent("hud:client:LoadMap", function()
Wait(150)
end
if Menu.isMapNotifChecked then
- QBCore.Functions.Notify(Lang:t("notify.load_square_map"))
+ Notify(Lang:t("notify.load_square_map"))
end
SetMinimapClipType(0)
AddReplaceTexture("platform:/textures/graphics", "radarmasksm", "squaremap", "radarmasksm")
@@ -443,7 +459,7 @@ RegisterNetEvent("hud:client:LoadMap", function()
end
Wait(1200)
if Menu.isMapNotifChecked then
- QBCore.Functions.Notify(Lang:t("notify.loaded_square_map"))
+ Notify(Lang:t("notify.loaded_square_map"))
end
elseif Menu.isToggleMapShapeChecked == "circle" then
RequestStreamedTextureDict("circlemap", false)
@@ -451,7 +467,7 @@ RegisterNetEvent("hud:client:LoadMap", function()
Wait(150)
end
if Menu.isMapNotifChecked then
- QBCore.Functions.Notify(Lang:t("notify.load_circle_map"))
+ Notify(Lang:t("notify.load_circle_map"))
end
SetMinimapClipType(1)
AddReplaceTexture("platform:/textures/graphics", "radarmasksm", "circlemap", "radarmasksm")
@@ -480,7 +496,7 @@ RegisterNetEvent("hud:client:LoadMap", function()
end
Wait(1200)
if Menu.isMapNotifChecked then
- QBCore.Functions.Notify(Lang:t("notify.loaded_circle_map"))
+ Notify(Lang:t("notify.loaded_circle_map"))
end
end
end)
@@ -580,12 +596,12 @@ RegisterNUICallback('cinematicMode', function(data, cb)
if data.checked then
CinematicShow(true)
if Menu.isCinematicNotifChecked then
- QBCore.Functions.Notify(Lang:t("notify.cinematic_on"))
+ Notify(Lang:t("notify.cinematic_on"))
end
else
CinematicShow(false)
if Menu.isCinematicNotifChecked then
- QBCore.Functions.Notify(Lang:t("notify.cinematic_off"), 'error')
+ Notify(Lang:t("notify.cinematic_off"), 'error')
end
local player = PlayerPedId()
local vehicle = GetVehiclePedIsIn(player)
@@ -740,9 +756,9 @@ RegisterCommand('+engine', function()
local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
if vehicle == 0 or GetPedInVehicleSeat(vehicle, -1) ~= PlayerPedId() then return end
if GetIsVehicleEngineRunning(vehicle) then
- QBCore.Functions.Notify(Lang:t("notify.engine_off"))
+ Notify(Lang:t("notify.engine_off"))
else
- QBCore.Functions.Notify(Lang:t("notify.engine_on"))
+ Notify(Lang:t("notify.engine_on"))
end
SetVehicleEngineOn(vehicle, not GetIsVehicleEngineRunning(vehicle), false, true)
end)
@@ -784,6 +800,7 @@ local function updatePlayerHud(data)
if shouldUpdate then
-- Since we found updated data, replace player cache with data
prevPlayerStats = data
+
SendNUIMessage({
action = 'hudtick',
topic = 'status',
@@ -867,17 +884,19 @@ end
local lastFuelUpdate = 0
local lastFuelCheck = {}
+
+
local function getFuelLevel(vehicle)
local updateTick = GetGameTimer()
if (updateTick - lastFuelUpdate) > 2000 then
lastFuelUpdate = updateTick
- lastFuelCheck = math.floor(exports[Config.FuelScript]:GetFuel(vehicle))
+ lastFuelCheck = fuelCheck(vehicle)
end
return lastFuelCheck
end
-- HUD Update loop
-
+local spawned = false
CreateThread(function()
local wasInVehicle = false
while true do
@@ -899,9 +918,9 @@ CreateThread(function()
end
end
- playerDead = IsEntityDead(player) or PlayerData.metadata["inlaststand"] or PlayerData.metadata["isdead"] or false
+ playerDead = isDead()
parachute = GetPedParachuteState(player)
-
+
-- Stamina
if not IsEntityInWater(player) then
oxygen = 100 - GetPlayerSprintStaminaRemaining(playerId)
@@ -926,18 +945,19 @@ CreateThread(function()
if IsPauseMenuActive() then
show = false
end
-
+
local vehicle = GetVehiclePedIsIn(player)
-
+ local health = GetEntityHealth(PlayerPedId()) - 100
+ if health < 0 then health = 0 end
if not (IsPedInAnyVehicle(player) and not IsThisModelABicycle(vehicle)) then
updatePlayerHud({
show,
- GetEntityHealth(player) - 100,
+ health,
playerDead,
- GetPedArmour(player),
- thirst,
- hunger,
- stress,
+ GetPedArmour(PlayerPedId()),
+ getData('thirst'),
+ getData('hunger'),
+ getData('stress'),
voice,
LocalPlayer.state['radioChannel'],
radioTalking,
@@ -970,15 +990,15 @@ CreateThread(function()
end
wasInVehicle = true
-
+
updatePlayerHud({
show,
- GetEntityHealth(player) - 100,
+ health,
playerDead,
GetPedArmour(player),
- thirst,
- hunger,
- stress,
+ getData('thirst'),
+ getData('hunger'),
+ getData('stress'),
voice,
LocalPlayer.state['radioChannel'],
radioTalking,
@@ -1052,7 +1072,7 @@ CreateThread(function()
if exports[Config.FuelScript]:GetFuel(GetVehiclePedIsIn(ped, false)) <= 20 then -- At 20% Fuel Left
if Menu.isLowFuelChecked then
TriggerServerEvent("InteractSound_SV:PlayOnSource", "pager", 0.10)
- QBCore.Functions.Notify(Lang:t("notify.low_fuel"), "error")
+ Notify(Lang:t("notify.low_fuel"), "error")
Wait(60000) -- repeats every 1 min until empty
end
end
@@ -1096,7 +1116,7 @@ end)
-- Harness Check / Seatbelt Check
-CreateThread(function()
+CreateThread(function() -- Seatbelt/Harness
while true do
Wait(1500)
if LocalPlayer.state.isLoggedIn then
@@ -1104,33 +1124,52 @@ CreateThread(function()
if IsPedInAnyVehicle(ped, false) then
hasHarness()
local veh = GetEntityModel(GetVehiclePedIsIn(ped, false))
- if seatbeltOn ~= true and IsThisModelACar(veh) then
- TriggerEvent("InteractSound_CL:PlayOnOne", "beltalarm", 0.6)
+ if seatbeltOn == false and IsThisModelACar(veh) then
+ local beltspeed = GetEntitySpeed(GetVehiclePedIsIn(ped, false))
+ if beltspeed > Config.SeatBeltSpeed then
+ TriggerServerEvent("InteractSound_SV:PlayOnSource", "beltalarm", 0.8)
+ end
end
end
end
end
end)
-
--- Stress Gain
-
-CreateThread(function() -- Speeding
+CreateThread(function() -- Speeding / Stress
+ local run = false
+ for k, v in pairs (Config.DisableStress) do
+ if v == 'all' then
+ run = true
+ break
+ end
+ end
+ if run then return end
while true do
if LocalPlayer.state.isLoggedIn then
local ped = PlayerPedId()
+ local veh = GetVehiclePedIsIn(ped, false)
+ local model = GetEntityModel(veh)
+ local speed = GetEntitySpeed(GetVehiclePedIsIn(ped, false)) * speedMultiplier
if IsPedInAnyVehicle(ped, false) then
- local speed = GetEntitySpeed(GetVehiclePedIsIn(ped, false)) * speedMultiplier
- local stressSpeed = seatbeltOn and config.MinimumSpeed or config.MinimumSpeedUnbuckled
- local vehClass = GetVehicleClass(GetVehiclePedIsIn(ped, false))
- if Config.VehClassStress[tostring(vehClass)] then
+ if IsThisModelABike(model) then
+ local stressSpeed = config.BikeSpeed
+ if speed >= stressSpeed then
+ TriggerServerEvent('hud:server:GainStress', math.random(1, 2))
+ end
+ elseif IsThisModelAHeli(model) or IsThisModelAPlane(model) then
+ local stressSpeed = config.FlyingSpeed
if speed >= stressSpeed then
- TriggerServerEvent('hud:server:GainStress', math.random(1, 3))
+ TriggerServerEvent('hud:server:GainStress', math.random(1, 2))
+ end
+ elseif IsThisModelACar(model) then
+ local stressSpeed = seatbeltOn and config.MinimumSpeed or config.MinimumSpeedUnbuckled
+ if speed >= stressSpeed then
+ TriggerServerEvent('hud:server:GainStress', math.random(1, 2))
end
end
end
end
- Wait(10000)
+ Wait(20000)
end
end)
@@ -1146,24 +1185,36 @@ local function IsWhitelistedWeaponStress(weapon)
end
CreateThread(function() -- Shooting
- while true do
- if LocalPlayer.state.isLoggedIn then
- local ped = PlayerPedId()
- local weapon = GetSelectedPedWeapon(ped)
- if weapon ~= `WEAPON_UNARMED` then
- if IsPedShooting(ped) and not IsWhitelistedWeaponStress(weapon) then
- if math.random() < config.StressChance then
- TriggerServerEvent('hud:server:GainStress', math.random(1, 3))
- end
- Wait(100)
- else
- Wait(500)
- end
- else
- Wait(1000)
- end
+ local run = false
+ local count = 0
+ for k, v in pairs (Config.DisableStress) do
+ if v == 'all' then
+ run = true
+ break
+ end
+ end
+ if run then return end
+ while not run do
+ local ped = PlayerPedId()
+ local weapon = GetSelectedPedWeapon(ped)
+ local chance = math.random()
+ if weapon == `WEAPON_UNARMED` then
+ Wait(2000) -- makes loop 2 seconds if not armed
else
+ local ammo = GetAmmoInPedWeapon(ped, weapon)
Wait(1000)
+ local newAmmo = GetAmmoInPedWeapon(ped, weapon)
+ local shots = ammo - newAmmo
+ if shots >= 1 and not IsWhitelistedWeaponStress(weapon) then
+ count = count + shots
+ if count >= Config.MaxShotBeforeStress or chance < config.StressChance then
+ local amountStress = math.floor(count / Config.MaxShotBeforeStress)
+ local amount = math.random(1,3)
+ if amountStress > 1 then amount = amount * amountStress end
+ count = 0
+ TriggerServerEvent('hud:server:GainStress',amount)
+ end
+ end
end
end
end)
@@ -1189,7 +1240,15 @@ local function GetEffectInterval(stresslevel)
end
CreateThread(function()
- while true do
+ local run = false
+ for k, v in pairs (Config.DisableStress) do
+ if v == 'all' then
+ run = true
+ break
+ end
+ end
+ if run then return end
+ while not run do
if LocalPlayer.state.isLoggedIn then
local ped = PlayerPedId()
local effectInterval = GetEffectInterval(stress)
diff --git a/client/functions.lua b/client/functions.lua
new file mode 100644
index 0000000..f864fd3
--- /dev/null
+++ b/client/functions.lua
@@ -0,0 +1,61 @@
+local QBCore = exports['qb-core']:GetCoreObject()
+
+function Notify(text, type)
+ if Config.Notify =='ox' then
+ lib.notify({title = text, type = type})
+ elseif Config.Notify == 'qb' then
+ QBCore.Functions.Notify(text, type)
+ elseif Config.Notify == 'ps' then
+ exports['ps-ui']:Notify(text, type, 3000)
+ else
+ print"^1 SCRIPT ERROR: ps-hud Invalid Option For Config.Notify"
+ end
+end
+
+RegisterNetEvent('ps-hud:client:notify', function(text, type)
+ Notify(text, type)
+end)
+
+function isDead()
+ if Config.Framework == 'qbx' then
+ local isDead = exports.qbx_medical:IsDead()
+ local inLaststand = exports.qbx_medical:IsLaststand()
+ if isDead or inLaststand then return true end
+ return false
+ elseif Config.Framework == 'qb' then
+ local isDead = QBCore.Functions.GetPlayerData().metadata.isdead
+ local inLaststand = QBCore.Functions.GetPlayerData().metadata.inlaststand
+ if isDead or inLaststand then return true end
+ return false
+ end
+ return false
+end
+
+function fuelCheck(veh)
+ if not veh then return false end
+ if GetResourceState('ox_fuel') == 'started' then
+ local fuel = Entity(veh).state.fuel
+ return math.floor(fuel)
+ else
+ local fuel = exports[Config.FuelScript]:GetFuel(veh)
+ return math.floor(fuel)
+ end
+end
+
+function getHarness()
+ if GetResourceState('qbx_seatbelt') == 'started' then
+ local harness = exports.qbx_seatbelt:HasHarness()
+ return harness
+ elseif Framework == 'qb' then
+ local harness = exports['qb-smallresources']:HasHarness()
+ return harness
+ end
+end
+
+function getData(type)
+ if Config.Framework == 'qbx' then
+ return QBX.PlayerData.metadata[type]
+ elseif Config.Framework == 'qb' then
+ return QBCore.Functions.GetPlayerData().metadata[type]
+ end
+end
diff --git a/config.lua b/config.lua
index f3bdf89..42cbcc4 100644
--- a/config.lua
+++ b/config.lua
@@ -1,13 +1,26 @@
Config = {}
+Config.Framework = 'qb' -- qbx or qb
Config.OpenMenu = 'I' -- https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/
+Config.Notify = 'ox' -- qb or ox or ps
Config.StressChance = 0.1 -- Default: 10% -- Percentage Stress Chance When Shooting (0-1)
+Config.MaxShotBeforeStress = 10 -- Default: 5 -- Maximum Amount
Config.UseMPH = true -- If true speed math will be done as MPH, if false KPH will be used (YOU HAVE TO CHANGE CONTENT IN STYLES.CSS TO DISPLAY THE CORRECT TEXT)
Config.MinimumStress = 50 -- Minimum Stress Level For Screen Shaking
Config.MinimumSpeedUnbuckled = 50 -- Going Over This Speed Will Cause Stress
Config.MinimumSpeed = 100 -- Going Over This Speed Will Cause Stress
-Config.DisablePoliceStress = false -- Default: false, If true will disable stress for people with the police job
-Config.FuelScript = 'LegacyFuel' -- change to lj-fuel if you use lj-fuel or something else if you use any other LegcyFuel compatible script
+Config.BikeSpeed = 90 -- Going Over This Speed Will Cause Stress for Bike users
+Config.FlyingSpeed = 150 -- Going Over This Speed Will Cause Stress for Aircraft users
+Config.SeatBeltSpeed = 10 -- Going over this speed will make the seatbelt sound
+Config.PersistantArmor = true -- If true, armor will be save when people log out
+
+Config.DisableStress = { -- job TYPES that you want to disable stress for
+ 'leo',
+ 'ambulance',
+ -- 'all' -- If you want to disable stress for all jobs, uncomment this line
+}
+
+Config.FuelScript = 'LegacyFuel' -- ps-fuel/lj-fuel/LegacyFuel/cdn-fuel or if you use ox_fuel then you can ignore as we hard check for it in the fuelCheck function
-- Admin only to change hud icons/shapes
Config.AdminOnly = false
diff --git a/fxmanifest.lua b/fxmanifest.lua
index 9f6e04c..e1ba36c 100644
--- a/fxmanifest.lua
+++ b/fxmanifest.lua
@@ -2,18 +2,24 @@ fx_version 'cerulean'
game 'gta5'
description 'ps-hud'
-version '2.1.2'
+version '2.1.3'
shared_scripts {
'@qb-core/shared/locale.lua',
'locales/en.lua',
'locales/*.lua',
'config.lua',
- 'uiconfig.lua'
+ 'uiconfig.lua',
+ '@ox_lib/init.lua'
}
-client_script 'client.lua'
-server_script 'server.lua'
+client_script {
+ 'client/**.lua',
+ --'@qbx_core/modules/playerdata.lua'
+}
+server_script {
+ 'server/**.lua'
+}
lua54 'yes'
use_fxv2_oal 'yes'
diff --git a/server/functions.lua b/server/functions.lua
new file mode 100644
index 0000000..656f8b9
--- /dev/null
+++ b/server/functions.lua
@@ -0,0 +1,25 @@
+local QBCore = exports['qb-core']:GetCoreObject()
+
+function Notify(source, text, type)
+ local src = source
+ if Config.Notify == 'qb' then
+ TriggerClientEvent("QBCore:Notify", src, text, type)
+ elseif Config.Notify == 'ox' then
+ lib.notify(src, { title = text, type = type})
+ elseif Config.Notify == 'ps' then
+ TriggerClientEvent('ps-hud:server:Notify', src, text, type)
+ else
+ print"^1 SCRIPT ERROR: ps-hud Invalid Option For Config.Notify"
+ end
+end
+
+function getPlayer(source)
+ if Config.Framework == 'qbx' then
+ local Player = exports.qbx_core:GetPlayer(source)
+ return Player
+ elseif Config.Framework == 'qb' then
+ local Player = QBCore.Functions.GetPlayer(source)
+ return Player
+ end
+end
+
diff --git a/server.lua b/server/server.lua
similarity index 77%
rename from server.lua
rename to server/server.lua
index 42e8698..da99704 100644
--- a/server.lua
+++ b/server/server.lua
@@ -1,27 +1,40 @@
local QBCore = exports['qb-core']:GetCoreObject()
local ResetStress = false
-QBCore.Commands.Add('cash', Lang:t('info.check_cash_balance'), {}, false, function(source, args)
- local Player = QBCore.Functions.GetPlayer(source)
+lib.addCommand('cash', {
+ help = Lang:t('info.check_cash_balance'),
+}, function(source, args, raw)
+ local Player = getPlayer(source)
local cashamount = Player.PlayerData.money.cash
TriggerClientEvent('hud:client:ShowAccounts', source, 'cash', cashamount)
end)
-QBCore.Commands.Add('bank', Lang:t('info.check_bank_balance'), {}, false, function(source, args)
- local Player = QBCore.Functions.GetPlayer(source)
+lib.addCommand('bank', {
+ help = Lang:t('info.check_bank_balance'),
+}, function(source, args, raw)
+ local Player = getPlayer(source)
local bankamount = Player.PlayerData.money.bank
TriggerClientEvent('hud:client:ShowAccounts', source, 'bank', bankamount)
end)
-QBCore.Commands.Add("dev", Lang:t('info.toggle_dev_mode'), {}, false, function(source, args)
+lib.addCommand('dev', {
+ help = Lang:t('info.toggle_dev_mode'),
+ restricted = 'group.admin'
+}, function(source, args, raw)
TriggerClientEvent("qb-admin:client:ToggleDevmode", source)
-end, 'admin')
+end)
RegisterNetEvent('hud:server:GainStress', function(amount)
local src = source
- local Player = QBCore.Functions.GetPlayer(src)
+ local Player = getPlayer(src)
local newStress
- if not Player or (Config.DisablePoliceStress and Player.PlayerData.job.name == 'police') then return end
+ local stop = false
+ for k, v in pairs (Config.DisableStress) do
+ if v == Player.PlayerData.job.type or v == 'all' then
+ stop = true
+ end
+ end
+ if stop then Player.Functions.SetMetaData('stress', 0) return end
if not ResetStress then
if not Player.PlayerData.metadata['stress'] then
Player.PlayerData.metadata['stress'] = 0
@@ -36,12 +49,12 @@ RegisterNetEvent('hud:server:GainStress', function(amount)
end
Player.Functions.SetMetaData('stress', newStress)
TriggerClientEvent('hud:client:UpdateStress', src, newStress)
- TriggerClientEvent('QBCore:Notify', src, Lang:t("notify.stress_gain"), 'error', 1500)
+ Notify(src, Lang:t("notify.stress_gain"), 'error')
end)
RegisterNetEvent('hud:server:RelieveStress', function(amount)
local src = source
- local Player = QBCore.Functions.GetPlayer(src)
+ local Player = getPlayer(src)
local newStress
if not Player then return end
if not ResetStress then
@@ -58,7 +71,7 @@ RegisterNetEvent('hud:server:RelieveStress', function(amount)
end
Player.Functions.SetMetaData('stress', newStress)
TriggerClientEvent('hud:client:UpdateStress', src, newStress)
- TriggerClientEvent('QBCore:Notify', src, Lang:t("notify.stress_removed"))
+ Notify(src, Lang:t("notify.stress_removed"), 'success')
end)
RegisterNetEvent('hud:server:saveUIData', function(data)
@@ -194,15 +207,38 @@ RegisterNetEvent('hud:server:saveUIData', function(data)
TriggerClientEvent('hud:client:UpdateUISettings', -1, uiConfigData)
end)
-QBCore.Functions.CreateCallback('hud:server:getMenu', function(source, cb)
- cb(Config.Menu)
+lib.callback.register('hud:server:getMenu', function(source)
+ return Config.Menu
end)
-QBCore.Functions.CreateCallback('hud:server:getRank', function(source, cb)
+lib.callback.register('hud:server:getRank', function(source)
local src = source
if QBCore.Functions.HasPermission(src, 'admin') or IsPlayerAceAllowed(src, 'command') then
- cb(true)
+ return true
+ else
+ return false
+ end
+end)
+
+lib.callback.register('ps-hud:getHealth', function(source)
+ local src = source
+ local Player = getPlayer(src)
+ local ped = GetPlayerPed(src)
+ local health = GetEntityHealth(ped)
+ Player.Functions.SetMetaData('health', health)
+ return health
+end)
+
+AddEventHandler('playerDropped', function(reason)
+ local src = source
+ local Player = getPlayer(src)
+ local ped = GetPlayerPed(src)
+ local health = GetEntityHealth(ped)
+ Player.Functions.SetMetaData('health', health)
+ if Config.PersistantArmor then
+ local armor = GetPedArmour(ped)
+ Player.Functions.SetMetaData('armor', armor)
else
- cb(false)
+ Player.Functions.SetMetaData('armor', 0)
end
end)
\ No newline at end of file