194 lines
7.0 KiB
Lua
194 lines
7.0 KiB
Lua
|
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)
|