Scripts/resources/[ps]/ps-buffs/server/main.lua

194 lines
7.0 KiB
Lua
Raw Normal View History

2024-12-29 20:28:24 +00:00
local QBCore = exports['qb-core']:GetCoreObject()
local playerBuffs = {}
local next = next
--- Adds a buff to player
--- @param citizenID string - Player identifier
--- @param buffName string - Name of the buff
--- @param time number | nil - Optional time to add or how long you want buff to be
--- @return bool
local function AddBuff(sourceID, citizenID, buffName, time)
local buffData = Config.Buffs[buffName]
-- Check if we were given a correct buff name
if buffData == nil then
return false
end
-- If the player had no buffs at all then add them to the table
if not playerBuffs[citizenID] then
playerBuffs[citizenID] = {}
end
local maxTime = buffData.maxTime
-- If the player didnt already have the buff requested set it to time or maxTime
if not playerBuffs[citizenID][buffName] then
local buffTime = maxTime
if time then
buffTime = time
end
playerBuffs[citizenID][buffName] = buffTime
-- Since the player didnt already have this buff tell the front end to show it
if buffData.type == 'buff' then
-- Call client event to send nui to front end to start showing buff
TriggerClientEvent('hud:client:BuffEffect', sourceID, {
buffName = buffName,
display = true,
iconName = buffData.iconName,
iconColor = buffData.iconColor,
progressColor = buffData.progressColor,
progressValue = (buffTime * 100) / buffData.maxTime,
})
else
-- Call client event to send nui to front end to start showing enhancement
TriggerClientEvent('hud:client:EnhancementEffect', sourceID, {
display = true,
enhancementName = buffName,
iconColor = buffData.iconColor
})
end
else
-- Since the player already had a buff increase the buff time, but not higher than max buff time
local newTime = playerBuffs[citizenID][buffName] + time
if newTime > maxTime then
newTime = maxTime
end
playerBuffs[citizenID][buffName] = newTime
end
return true
end exports('AddBuff', AddBuff)
--- Removes a buff from provided player
--- @param citizenID string - Player identifier
--- @param buffName string - Name of the buff
--- @return bool - Success of removing the player buff
local function Removebuff(citizenID, buffName)
local buffData = Config.Buffs[buffName]
if playerBuffs[citizenID] and playerBuffs[citizenID][buffName] then
playerBuffs[citizenID][buffName] = nil
local player = QBCore.Functions.GetPlayerByCitizenId(citizenID)
local sourceID = nil
if player then
sourceID = player.PlayerData.source
end
-- Check if player is online
if sourceID then
-- Send a nui call to front end to stop showing icon
if buffData.type == 'buff' then
-- Call client event to send nui to front end to stop showing buff
TriggerClientEvent('hud:client:BuffEffect', sourceID, {
display = false,
buffName = buffName,
})
else
-- Call client event to send nui to front end to stop showing enhancement
TriggerClientEvent('hud:client:EnhancementEffect', sourceID, {
display = false,
enhancementName = buffName,
})
end
end
-- Check to see if that was the player's last buff
-- If so, then remove the player from the table to ensure we dont loop them
if next(playerBuffs[citizenID]) == nil then
playerBuffs[citizenID] = nil
end
return true
end
return false
end exports('RemoveBuff', RemoveBuff)
--- Method to fetch if player has buff with name and is not nil
--- @param citizenID string - Player identifier
--- @param buffName string - Name of the buff
--- @return bool
local function HasBuff(citizenID, buffName)
if playerBuffs[citizenID] then
return playerBuffs[citizenID][buffName] ~= nil
end
return false
end exports('HasBuff', HasBuff)
QBCore.Functions.CreateCallback('buffs:server:fetchBuffs', function(source, cb)
local player = QBCore.Functions.GetPlayer(source)
local citizenID = player.PlayerData.citizenid
cb(playerBuffs[citizenID])
end)
QBCore.Functions.CreateCallback('buffs:server:addBuff', function(source, cb, buffName, time)
local player = QBCore.Functions.GetPlayer(source)
local citizenID = player.PlayerData.citizenid
cb(AddBuff(source, citizenID, buffName, time))
end)
CreateThread(function()
local function DecrementBuff(sourceID, citizenID, buffName, currentTime)
local buffData = Config.Buffs[buffName]
local updatedTime = currentTime - Config.TickTime
-- Buff ran out of time we need to remove it from the player
if updatedTime <= 0 then
-- Only need to update buffs since they show progress on client
if buffData.type == 'buff' then
-- Check if player is online
if sourceID then
-- Call client event to send nui to front end, progress at 0
TriggerClientEvent('hud:client:BuffEffect', sourceID, {
buffName = buffName,
progressValue = 0,
})
end
end
Removebuff(citizenID, buffName)
else
playerBuffs[citizenID][buffName] = updatedTime
-- Only need to update buffs since they show progress on client
if buffData.type == 'buff' then
-- Check if player is online
if sourceID then
-- Call client event to send nui to front end
TriggerClientEvent('hud:client:BuffEffect', sourceID, {
buffName = buffName,
-- Progress value needs to be from 0 - 100
progressValue = (updatedTime * 100) / buffData.maxTime,
})
end
end
end
end
-- Not proud but need to loop through all timers but decrement it
-- Loop is good as long as we only loop players that have buffs
-- We ensure that when removing any buff, we check to see if it was the player's last buff
-- Then we remove that player from our table to ensure we dont loop them
while true do
for citizenID, buffTable in pairs(playerBuffs) do
local player = QBCore.Functions.GetPlayerByCitizenId(citizenID)
local sourceID = nil
if player then
sourceID = player.PlayerData.source
end
for buffName, currentTime in pairs(buffTable) do
DecrementBuff(sourceID, citizenID, buffName, currentTime)
end
end
Wait(Config.TickTime)
end
end)