forked from Simnation/Main
184 lines
5.5 KiB
Lua
184 lines
5.5 KiB
Lua
![]() |
local QBCore = exports['qb-core']:GetCoreObject()
|
||
|
local bowls = {}
|
||
|
|
||
|
-- Initialize
|
||
|
Citizen.CreateThread(function()
|
||
|
-- Load all bowls from database
|
||
|
LoadBowls()
|
||
|
end)
|
||
|
|
||
|
-- Load bowls from database
|
||
|
function LoadBowls()
|
||
|
MySQL.query('SELECT * FROM pet_bowls', {}, function(results)
|
||
|
if results and #results > 0 then
|
||
|
for _, bowl in pairs(results) do
|
||
|
bowls[bowl.bowl_id] = {
|
||
|
id = bowl.bowl_id,
|
||
|
model = bowl.model,
|
||
|
type = bowl.type,
|
||
|
fillLevel = bowl.fill_level,
|
||
|
coords = bowl.coords
|
||
|
}
|
||
|
end
|
||
|
print('^2[Pet-Bowls]^7 Loaded ' .. #results .. ' bowls from database')
|
||
|
else
|
||
|
print('^2[Pet-Bowls]^7 No bowls found in database')
|
||
|
end
|
||
|
end)
|
||
|
end
|
||
|
|
||
|
-- Client requests all bowls
|
||
|
RegisterNetEvent('pet-bowls:server:requestBowls', function()
|
||
|
local src = source
|
||
|
TriggerClientEvent('pet-bowls:client:loadBowls', src, bowls)
|
||
|
end)
|
||
|
|
||
|
-- Place a new bowl
|
||
|
RegisterNetEvent('pet-bowls:server:placeBowl', function(bowlId, model, bowlType, coords)
|
||
|
local src = source
|
||
|
local Player = QBCore.Functions.GetPlayer(src)
|
||
|
|
||
|
if not Player then return end
|
||
|
|
||
|
-- Save to database
|
||
|
local coordsJson = json.encode(coords)
|
||
|
MySQL.insert('INSERT INTO pet_bowls (bowl_id, model, type, fill_level, coords) VALUES (?, ?, ?, ?, ?)',
|
||
|
{bowlId, model, bowlType, 0, coordsJson},
|
||
|
function(id)
|
||
|
if id then
|
||
|
-- Save to memory
|
||
|
bowls[bowlId] = {
|
||
|
id = bowlId,
|
||
|
model = model,
|
||
|
type = bowlType,
|
||
|
fillLevel = 0,
|
||
|
coords = coordsJson
|
||
|
}
|
||
|
|
||
|
-- Notify all clients about the new bowl
|
||
|
TriggerClientEvent('pet-bowls:client:updateBowlLevel', -1, bowlId, 0)
|
||
|
end
|
||
|
end
|
||
|
)
|
||
|
end)
|
||
|
|
||
|
-- Fill a bowl
|
||
|
RegisterNetEvent('pet-bowls:server:fillBowl', function(bowlId, itemName, fillAmount)
|
||
|
local src = source
|
||
|
local Player = QBCore.Functions.GetPlayer(src)
|
||
|
|
||
|
if not Player then return end
|
||
|
|
||
|
-- Check if player has the item
|
||
|
local hasItem = exports["tgiann-inventory"]:GetItemByName(src, itemName)
|
||
|
|
||
|
if not hasItem or hasItem.amount < 1 then
|
||
|
TriggerClientEvent('ox_lib:notify', src, Config.Notifications.noItem)
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- Remove the item
|
||
|
exports["tgiann-inventory"]:RemoveItem(src, itemName, 1)
|
||
|
|
||
|
-- Update bowl fill level
|
||
|
local bowl = bowls[bowlId]
|
||
|
if bowl then
|
||
|
local newLevel = math.min(100, bowl.fillLevel + fillAmount)
|
||
|
|
||
|
-- Update in memory
|
||
|
bowl.fillLevel = newLevel
|
||
|
|
||
|
-- Update in database
|
||
|
MySQL.update('UPDATE pet_bowls SET fill_level = ?, last_refill = CURRENT_TIMESTAMP WHERE bowl_id = ?',
|
||
|
{newLevel, bowlId}
|
||
|
)
|
||
|
|
||
|
-- Update all clients
|
||
|
TriggerClientEvent('pet-bowls:client:updateBowlLevel', -1, bowlId, newLevel)
|
||
|
TriggerClientEvent('ox_lib:notify', src, Config.Notifications.bowlFilled)
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
-- Consume from a bowl
|
||
|
RegisterNetEvent('pet-bowls:server:consumeBowl', function(bowlId)
|
||
|
local src = source
|
||
|
local Player = QBCore.Functions.GetPlayer(src)
|
||
|
|
||
|
if not Player then return end
|
||
|
|
||
|
-- Get bowl data
|
||
|
local bowl = bowls[bowlId]
|
||
|
if not bowl then return end
|
||
|
|
||
|
-- Find the bowl config
|
||
|
local bowlConfig = nil
|
||
|
for _, config in pairs(Config.BowlProps) do
|
||
|
if config.model == bowl.model then
|
||
|
bowlConfig = config
|
||
|
break
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if not bowlConfig then return end
|
||
|
|
||
|
-- Check if bowl has content
|
||
|
if bowl.fillLevel <= 0 then
|
||
|
TriggerClientEvent('ox_lib:notify', src, Config.Notifications.bowlEmpty)
|
||
|
return
|
||
|
end
|
||
|
|
||
|
-- Consume from bowl
|
||
|
local consumeAmount = bowlConfig.consumeAmount
|
||
|
local newLevel = math.max(0, bowl.fillLevel - consumeAmount)
|
||
|
|
||
|
-- Update in memory
|
||
|
bowl.fillLevel = newLevel
|
||
|
|
||
|
-- Update in database
|
||
|
MySQL.update('UPDATE pet_bowls SET fill_level = ? WHERE bowl_id = ?',
|
||
|
{newLevel, bowlId}
|
||
|
)
|
||
|
|
||
|
-- Apply effects to player
|
||
|
local effects = Config.Effects[bowl.type]
|
||
|
if effects then
|
||
|
if effects.hunger then
|
||
|
-- Apply hunger effect
|
||
|
TriggerClientEvent('hud:client:UpdateHunger', src, effects.hunger, true)
|
||
|
end
|
||
|
|
||
|
if effects.thirst then
|
||
|
-- Apply thirst effect
|
||
|
TriggerClientEvent('hud:client:UpdateThirst', src, effects.thirst, true)
|
||
|
end
|
||
|
|
||
|
if effects.stress then
|
||
|
-- Apply stress effect
|
||
|
TriggerClientEvent('hud:client:UpdateStress', src, effects.stress)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Update all clients
|
||
|
TriggerClientEvent('pet-bowls:client:updateBowlLevel', -1, bowlId, newLevel)
|
||
|
TriggerClientEvent('ox_lib:notify', src, Config.Notifications.consumed)
|
||
|
end)
|
||
|
|
||
|
-- Remove a bowl
|
||
|
RegisterNetEvent('pet-bowls:server:removeBowl', function(bowlId)
|
||
|
local src = source
|
||
|
local Player = QBCore.Functions.GetPlayer(src)
|
||
|
|
||
|
if not Player then return end
|
||
|
|
||
|
-- Remove from database
|
||
|
MySQL.query('DELETE FROM pet_bowls WHERE bowl_id = ?', {bowlId})
|
||
|
|
||
|
-- Remove from memory
|
||
|
bowls[bowlId] = nil
|
||
|
end)
|
||
|
|
||
|
-- Register command to place bowls
|
||
|
QBCore.Commands.Add('placebowl', 'Place a pet bowl', {}, false, function(source, args)
|
||
|
TriggerClientEvent('pet-bowls:client:openPlaceBowlMenu', source)
|
||
|
end)
|