Skip to content

Commit

Permalink
v2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
yiruzu authored Nov 13, 2024
1 parent cb2d784 commit cb19714
Show file tree
Hide file tree
Showing 17 changed files with 431 additions and 0 deletions.
8 changes: 8 additions & 0 deletions bridge/client/custom.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
local Config = require("shared.sh_config")

if Config.Framework ~= "custom" then return end

--- Revives the player character
function RevivePed()
-- Add event or logic to revive the player character
end
14 changes: 14 additions & 0 deletions bridge/client/esx.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
local Config = require("shared.sh_config")

if Config.Framework ~= "esx" then return end

function RevivePed()
TriggerEvent("esx_ambulancejob:RespawnAtHospital") --! Don't forget to check the documentation to ensure this works properly.
end

AddEventHandler("esx:onPlayerDeath", function()
TriggerEvent("cloud-deathscreen:client:OnPlayerDeath")
end)
AddEventHandler("esx:onPlayerSpawn", function()
TriggerEvent("cloud-deathscreen:client:OnPlayerSpawn")
end)
15 changes: 15 additions & 0 deletions bridge/client/qbcore.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
local Config = require("shared.sh_config")

if Config.Framework ~= "qbcore" then return end

function RevivePed()
TriggerServerEvent("hospital:server:RespawnAtHospital")
end

RegisterNetEvent("QBCore:Player:SetPlayerData", function(data)
if data.metadata.isdead or data.metadata.inlaststand then
TriggerEvent("cloud-deathscreen:client:OnPlayerDeath")
else
TriggerEvent("cloud-deathscreen:client:OnPlayerSpawn")
end
end)
43 changes: 43 additions & 0 deletions bridge/server/custom.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
local Config = require("shared.sh_config")
local Locales = require("shared.sh_locales")

if Config.Framework ~= "custom" then return end

--- Retrieves the Player ID for the given source
---@param source number -- The player's source ID
---@return number -- The Player ID
function GetPlayerId(source)
return GetPlayer(source)
end

--- Processes payment of the fine for death and notifies the player.
---@param source number -- The players source ID
---@return boolean -- Returns true if the fine was successfully paid, false otherwise
local function PayFine(source)
-- Retrieve the player object using their source ID
local Player = GetPlayerId(source)

if Player then
local amount = Config.PriceForDeath -- Fine amount to be paid
local moneyAvailable = Player.GetMoney("cash") -- Player’s available cash balance
local bankAvailable = Player.GetMoney("bank") -- Player’s available bank balance

-- Attempt to pay with cash first, then bank, and notify accordingly
if moneyAvailable >= amount then
Player.RemoveMoney("cash", amount) -- Remove Player’s cash
ServerNotify(source, Locales.Notify.PaidFine:format(amount), "info")
return true
elseif bankAvailable >= amount then
Player.RemoveMoney("bank", amount) -- Remove Player’s bank money
ServerNotify(source, Locales.Notify.PaidFine:format(amount), "info")
return true
else
ServerNotify(source, Locales.Notify.NoMoney, "error")
return false
end
end
return false
end

-- Registers the PayFine function as a server callback
lib.callback.register("cloud-deathscreen:server:PayFine", PayFine)
34 changes: 34 additions & 0 deletions bridge/server/esx.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
local Config = require("shared.sh_config")
local Locales = require("shared.sh_locales")

if Config.Framework ~= "esx" then return end

local ESX = exports["es_extended"]:getSharedObject()

function GetPlayerId(source)
return ESX.GetPlayerFromId(source)
end

local function PayFine(source)
local xPlayer = GetPlayerId(source)
if not xPlayer then return false end

local amount = Config.PriceForDeath
local moneyAvailable = xPlayer.getAccount("money").money
local bankAvailable = xPlayer.getAccount("bank").money

if moneyAvailable >= amount then
xPlayer.removeAccountMoney("money", amount)
ServerNotify(source, Locales.Notify.PaidFine:format(amount), "info")
return true
elseif bankAvailable >= amount then
xPlayer.removeAccountMoney("bank", amount)
ServerNotify(source, Locales.Notify.PaidFine:format(amount), "info")
return true
else
ServerNotify(source, Locales.Notify.NoMoney, "error")
return false
end
end

lib.callback.register("cloud-deathscreen:server:PayFine", PayFine)
36 changes: 36 additions & 0 deletions bridge/server/qbcore.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
local Config = require("shared.sh_config")
local Locales = require("shared.sh_locales")

if Config.Framework ~= "qbcore" then return end

local QBCore = exports["qb-core"]:GetCoreObject()

function GetPlayerId(source)
return QBCore.Functions.GetPlayer(source)
end

local function PayFine(source)
local Player = QBCore.Functions.GetPlayer(source)

if Player then
local amount = Config.PriceForDeath
local moneyAvailable = Player.Functions.GetMoney("cash")
local bankAvailable = Player.Functions.GetMoney("bank")

if moneyAvailable >= amount then
Player.Functions.RemoveMoney("cash", amount)
ServerNotify(source, Locales.Notify.PaidFine:format(amount), "info")
return true
elseif bankAvailable >= amount then
Player.Functions.RemoveMoney("bank", amount)
ServerNotify(source, Locales.Notify.PaidFine:format(amount), "info")
return true
else
ServerNotify(source, Locales.Notify.NoMoney, "error")
return false
end
end
return false
end

lib.callback.register("cloud-deathscreen:server:PayFine", PayFine)
126 changes: 126 additions & 0 deletions client.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
local Config = require("shared.sh_config")
local Locales = require("shared.sh_locales")

local isDead = false

local function DisableControls()
CreateThread(function()
while isDead do
DisableAllControlActions(0) -- This will disable in-game controls (e.g., movement, actions) but will not prevent menus or UIs that open via key mappings from appearing.
for _, keyCode in ipairs(Config.EnabledControls) do
EnableControlAction(0, keyCode, true)
end
Wait(0)
end
end)
end

local function ToggleUI(bool)
SendNUIMessage({ action = "toggleDeathscreen", isVisible = bool })
SetNuiFocus(bool, bool)
SetNuiFocusKeepInput(bool)
DisableControls()
if Config.BlurUIBackground then
if bool then
TriggerScreenblurFadeIn(0)
else
TriggerScreenblurFadeOut(0)
end
end
end

local function LoadAnimDict(animDict)
while not HasAnimDictLoaded(animDict) do
RequestAnimDict(animDict)
Wait(10)
end
end

-- credits to qb-ambulancejob for parts of this function
local function DoDeathAnim()
local playerPed = cache.ped

while GetEntitySpeed(playerPed) > 0.5 or IsPedRagdoll(playerPed) do
Wait(10)
end

if isDead then
local coords = GetEntityCoords(playerPed)
local heading = GetEntityHeading(playerPed)

if IsPedInAnyVehicle(playerPed, false) then
local playerVeh = GetVehiclePedIsIn(playerPed, false)
local vehSeats = GetVehicleModelNumberOfSeats(GetHashKey(GetEntityModel(playerVeh)))
for i = -1, vehSeats do
local vehSeatPed = GetPedInVehicleSeat(playerVeh, i)
if vehSeatPed == playerPed then
NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z + 0.5, heading, 0, false)
SetPedIntoVehicle(playerPed, playerVeh, i)
end
end
else
NetworkResurrectLocalPlayer(coords.x, coords.y, coords.z + 0.5, heading, 0, false)
end

local maxHealth = GetPedMaxHealth(playerPed)
SetEntityInvincible(playerPed, true)
SetEntityHealth(playerPed, maxHealth)

local animDict = IsPedInAnyVehicle(playerPed, false) and "veh@low@front_ps@idle_duck" or Config.DeathAnim.animDict
local animName = IsPedInAnyVehicle(playerPed, false) and "sit" or Config.DeathAnim.animName
LoadAnimDict(animDict)

while isDead do
if not IsEntityPlayingAnim(playerPed, animDict, animName, 8) then TaskPlayAnim(playerPed, animDict, animName, 1.0, 1.0, -1, 8, 0, false, false, false) end
Wait(1000)
end
end
end

local function OnPlayerDeath()
isDead = true
if IsPauseMenuActive() then SetFrontendActive(false) end
ToggleUI(true)
HandleVoiceState(false)
if Config.DeathAnim.enabled then DoDeathAnim() end
end
RegisterNetEvent("cloud-deathscreen:client:OnPlayerDeath", OnPlayerDeath)

local function OnPlayerSpawn()
isDead = false
ToggleUI(false)
HandleVoiceState(true)
end
RegisterNetEvent("cloud-deathscreen:client:OnPlayerSpawn", OnPlayerSpawn)

local function ReviveActions()
isDead = false
ToggleUI(false)
RevivePed()
HandleVoiceState(true)
end

RegisterNUICallback("deathscreen:fetchData", function(data, cb)
local label = data.label
if label == "setData" then
cb({ locales = Locales.UI, soundVolume = Config.SoundVolume, mainTimer = Config.MainTimer, faceDeathTimer = Config.FaceDeathTimer })
elseif label == "callEmergency" then
PlaySoundFrontend(-1, "Click", "DLC_HEIST_HACKING_SNAKE_SOUNDS", true)
CallEmergency()
cb("ok")
elseif label == "faceDeath" then
local paymentSuccess = lib.callback.await("cloud-deathscreen:server:PayFine", false)

if paymentSuccess then
PlaySoundFrontend(-1, "Click", "DLC_HEIST_HACKING_SNAKE_SOUNDS", true)
ReviveActions()
cb("ok")
else
PlaySoundFrontend(-1, "CHECKPOINT_MISSED", "HUD_MINI_GAME_SOUNDSET", true)
cb("error")
end
elseif label == "timeExpired" then
ReviveActions()
cb("ok")
end
end)
21 changes: 21 additions & 0 deletions fxmanifest.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
fx_version "cerulean"
game "gta5"

lua54 "yes"
use_experimental_fxv2_oal "yes"

author "yiruzu"
description "Cloud Service - Deathscreen"
version "2.0.0"

discord "https://discord.gg/jAnEnyGBef"
repository "https://github.com/yiruzu/cloud-deathscreen"
license "CC BY-NC"

file { "shared/sh_config.lua", "shared/sh_locales.lua" }
shared_scripts { "@ox_lib/init.lua", "shared/sh_functions.lua" }
server_scripts { "bridge/server/**.lua", "server.lua" }
client_scripts { "bridge/client/**.lua", "client.lua" }

ui_page { "web/index.html" }
files { "web/**/*" }
12 changes: 12 additions & 0 deletions server.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
local Config = require("shared.sh_config")

lib.versionCheck("yiruzu/cloud-deathscreen")

if Config.Voice == "saltychat" then
local player = GetPlayerId(source)

RegisterNetEvent("cloud-deathscreen:server:IsDeadSaltyChat")
AddEventHandler("cloud-deathscreen:server:IsDeadSaltyChat", function(isDead)
exports["saltychat"]:SetPlayerAlive(player, isDead)
end)
end
29 changes: 29 additions & 0 deletions shared/sh_config.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--! DONT FORGET TO CHECK THE DOCUMENTATION TO ENSURE EVERYTHING WORKS CORRECTLY: https://cloud-service-1.gitbook.io/docs/free-resources/cloud-deathscreen

return {
--[[ FRAMEWORK SETTINGS ]]
Framework = "esx", -- Options: "esx", "qbcore" or "custom"
Voice = "pma-voice", -- Options: "pma-voice" or "saltychat". Set to `false` to disable the voice chat deafen feature when dead.

--[[ TIMERS ]]
MainTimer = 600, -- Time (in seconds) until the player is fully dead
FaceDeathTimer = 5, -- Time (in seconds) until the player can click the "FACE DEATH" button
PriceForDeath = 1000, -- Cost for clicking the "FACE DEATH" button

--[[ UI SETTINGS ]]
SoundVolume = 0.35,
BlurUIBackground = true, -- Enable or disable background blur for the death screen UI

--[[ DEATH ANIMATION SETTINGS ]]
DeathAnim = {
enabled = true, -- Toggle death animation on/off
animDict = "combat@damage@writhe",
animName = "writhe_loop",
},

--[[ ENABLED CONTROLS ]]
EnabledControls = {
245, -- Control key code for chat ([T] by default)
-- Add other control key codes here if needed
},
}
46 changes: 46 additions & 0 deletions shared/sh_functions.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
local Config = require("shared.sh_config")

function CallEmergency()
if Config.Framework == "esx" then
TriggerServerEvent("esx_ambulancejob:onPlayerDistress")
elseif Config.Framework == "qbcore" then
TriggerServerEvent("hospital:server:ambulanceAlert", "Unconscious Person")
elseif Config.Framework == "custom" then
-- Your custom logic here
end
end

--- Handles the voice state (mute/unmute) based on the configured voice system.
---@param isActive boolean -- true to activate voice, false to deactivate
function HandleVoiceState(isActive)
if Config.Voice == "pma-voice" then
MumbleSetActive(isActive)
elseif Config.Voice == "saltychat" then
TriggerServerEvent("cloud-deathscreen:server:IsDeadSaltyChat", isActive)
end
end

---@param msg string -- The message content for the notification
---@param type string -- The type of notification (e.g., "info", "error", "success")
function ClientNotify(msg, type)
lib.notify({
title = "Information",
description = msg,
type = type,
position = "top-left",
duration = 5000,
})
end

---@param source number -- The player source ID to whom the notification is sent
---@param msg string -- The message content for the notification
---@param type string -- The type of notification (e.g., "info", "error", "success")
function ServerNotify(source, msg, type)
TriggerClientEvent("ox_lib:notify", source, {
title = "Information",
description = msg,
type = type,
position = "top-left",
duration = 5000,
})
end
Loading

0 comments on commit cb19714

Please sign in to comment.