190 lines
6.0 KiB
Lua
190 lines
6.0 KiB
Lua
local sharedConfig = require 'config.shared'
|
|
local logger = require '@qbx_core.modules.logger'
|
|
|
|
---@class Injury
|
|
---@field severity integer
|
|
---@field weaponHash number
|
|
|
|
---@class PlayerStatus
|
|
---@field injuries table<BodyPartKey, Injury>
|
|
---@field isBleeding number
|
|
|
|
---@alias Source number
|
|
|
|
local triggerEventHooks = require '@qbx_core.modules.hooks'
|
|
|
|
local function getDeathState(src)
|
|
local player = exports.qbx_core:GetPlayer(src)
|
|
return player.PlayerData.metadata.isdead and sharedConfig.deathState.DEAD
|
|
or player.PlayerData.metadata.inlaststand and sharedConfig.deathState.LAST_STAND
|
|
or sharedConfig.deathState.ALIVE
|
|
end
|
|
|
|
RegisterNetEvent('QBCore:Server:OnPlayerLoaded', function()
|
|
local playerState = Player(source).state
|
|
playerState:set(DEATH_STATE_STATE_BAG, getDeathState(source), true)
|
|
playerState:set(BLEED_LEVEL_STATE_BAG, 0, true)
|
|
for bodyPartKey in pairs(sharedConfig.bodyParts) do
|
|
playerState:set(BODY_PART_STATE_BAG_PREFIX .. bodyPartKey, nil, true)
|
|
end
|
|
end)
|
|
|
|
AddStateBagChangeHandler(DEATH_STATE_STATE_BAG, nil, function(bagName, _, value)
|
|
local playerId = GetPlayerFromStateBagName(bagName)
|
|
local player = exports.qbx_core:GetPlayer(playerId)
|
|
player.Functions.SetMetaData('isdead', value == sharedConfig.deathState.DEAD)
|
|
player.Functions.SetMetaData('inlaststand', value == sharedConfig.deathState.LAST_STAND)
|
|
Player(playerId).state:set("isDead", value == sharedConfig.deathState.DEAD or value == sharedConfig.deathState.LAST_STAND, true)
|
|
end)
|
|
|
|
---@param player table|number
|
|
local function revivePlayer(player)
|
|
TriggerClientEvent('qbx_medical:client:playerRevived', player --[[@as number]])
|
|
end
|
|
|
|
exports('Revive', revivePlayer)
|
|
|
|
---removes all ailments, sets to full health, and fills up hunger and thirst.
|
|
---@param src Source
|
|
local function heal(src)
|
|
TriggerClientEvent('qbx_medical:client:heal', src, 'full')
|
|
end
|
|
|
|
exports('Heal', heal)
|
|
|
|
---Removes any injuries with severity 2 or lower. Stops bleeding if bleed level is less than 3.
|
|
---@param src Source
|
|
local function healPartially(src)
|
|
TriggerClientEvent('qbx_medical:client:heal', src, 'partial')
|
|
end
|
|
|
|
exports('HealPartially', healPartially)
|
|
|
|
---Compatibility with txAdmin Menu's heal options.
|
|
---This is an admin only server side event that will pass the target player id or -1.
|
|
---@class EventData
|
|
---@field id number
|
|
---@param eventData EventData
|
|
AddEventHandler('txAdmin:events:healedPlayer', function(eventData)
|
|
if GetInvokingResource() ~= 'monitor' or type(eventData) ~= 'table' or type(eventData.id) ~= 'number' then
|
|
return
|
|
end
|
|
|
|
revivePlayer(eventData.id)
|
|
heal(eventData.id)
|
|
end)
|
|
|
|
local function getPlayerInjuries(state)
|
|
local injuries = {}
|
|
for bodyPartKey in pairs(sharedConfig.bodyParts) do
|
|
injuries[bodyPartKey] = state[BODY_PART_STATE_BAG_PREFIX .. bodyPartKey]
|
|
end
|
|
return injuries
|
|
end
|
|
|
|
---Get human readable info on a player's health
|
|
---@param src Source
|
|
---@return {injuries: string[], bleedLevel: integer, bleedState: string, damageCauses: table<number, true>}
|
|
local function getPlayerStatus(src)
|
|
local state = Player(src).state
|
|
local bleedLevel = state[BLEED_LEVEL_STATE_BAG]
|
|
local injuries = getPlayerInjuries(state)
|
|
|
|
local injuryStatuses = {}
|
|
local weaponsThatDamagedPlayer = {}
|
|
local i = 0
|
|
for bodyPartKey, injury in pairs(injuries) do
|
|
local bodyPart = sharedConfig.bodyParts[bodyPartKey]
|
|
i += 1
|
|
injuryStatuses[i] = bodyPart.label .. ' (' .. sharedConfig.woundLevels[injury.severity].label .. ')'
|
|
weaponsThatDamagedPlayer[injury.weaponHash] = true
|
|
end
|
|
|
|
local status = {
|
|
injuries = injuryStatuses,
|
|
bleedLevel = bleedLevel,
|
|
bleedState = sharedConfig.bleedingStates[bleedLevel],
|
|
damageCauses = weaponsThatDamagedPlayer
|
|
}
|
|
|
|
return status
|
|
end
|
|
|
|
exports('GetPlayerStatus', getPlayerStatus)
|
|
|
|
---@param amount number
|
|
lib.callback.register('qbx_medical:server:setArmor', function(source, amount)
|
|
local player = exports.qbx_core:GetPlayer(source)
|
|
player.Functions.SetMetaData('armor', amount)
|
|
end)
|
|
|
|
local function resetHungerAndThirst(player)
|
|
if type(player) == 'number' then
|
|
player = exports.qbx_core:GetPlayer(player)
|
|
end
|
|
|
|
player.Functions.SetMetaData('hunger', 100)
|
|
player.Functions.SetMetaData('thirst', 100)
|
|
TriggerClientEvent('hud:client:UpdateNeeds', player.PlayerData.source, 100, 100)
|
|
end
|
|
|
|
lib.callback.register('qbx_medical:server:resetHungerAndThirst', resetHungerAndThirst)
|
|
|
|
lib.addCommand('revive', {
|
|
help = locale('info.revive_player_a'),
|
|
restricted = 'group.admin',
|
|
params = {
|
|
{ name = 'id', help = locale('info.player_id'), type = 'playerId', optional = true },
|
|
}
|
|
}, function(source, args)
|
|
if not args.id then args.id = source end
|
|
local player = exports.qbx_core:GetPlayer(tonumber(args.id))
|
|
if not player then
|
|
exports.qbx_core:Notify(source, locale('error.not_online'), 'error')
|
|
return
|
|
end
|
|
revivePlayer(args.id)
|
|
end)
|
|
|
|
lib.addCommand('kill', {
|
|
help = locale('info.kill'),
|
|
restricted = 'group.admin',
|
|
params = {
|
|
{ name = 'id', help = locale('info.player_id'), type = 'playerId', optional = true },
|
|
}
|
|
}, function(source, args)
|
|
if not args.id then args.id = source end
|
|
local player = exports.qbx_core:GetPlayer(tonumber(args.id))
|
|
if not player then
|
|
exports.qbx_core:Notify(source, locale('error.not_online'), 'error')
|
|
return
|
|
end
|
|
lib.callback.await('qbx_medical:client:killPlayer', args.id)
|
|
end)
|
|
|
|
lib.addCommand('aheal', {
|
|
help = locale('info.heal_player_a'),
|
|
restricted = 'group.admin',
|
|
params = {
|
|
{ name = 'id', help = locale('info.player_id'), type = 'playerId', optional = true },
|
|
}
|
|
}, function(source, args)
|
|
if not args.id then args.id = source end
|
|
local player = exports.qbx_core:GetPlayer(tonumber(args.id))
|
|
if not player then
|
|
exports.qbx_core:Notify(source, locale('error.not_online'), 'error')
|
|
return
|
|
end
|
|
heal(args.id)
|
|
end)
|
|
|
|
lib.callback.register('qbx_medical:server:respawn', function(source)
|
|
if not triggerEventHooks('respawn', {source = source}) then return false end
|
|
TriggerEvent('qbx_medical:server:playerRespawned', source)
|
|
return true
|
|
end)
|
|
|
|
lib.callback.register('qbx_medical:server:log', function(_, event, message)
|
|
logger.log({source = 'qbx_medical', event = event, message = message})
|
|
end)
|