1
0
Fork 0
forked from Simnation/Main
Main/resources/[inventory]/nordi_petbowl/client.lua

244 lines
6.9 KiB
Lua
Raw Normal View History

2025-08-02 13:24:19 +02:00
local QBCore = exports['qb-core']:GetCoreObject()
local placedBowls = {}
local currentBowl = nil
-- Load placed bowls from server
RegisterNetEvent('pet-bowls:client:loadBowls', function(bowls)
for _, bowl in pairs(bowls) do
local coords = json.decode(bowl.coords)
local bowlCoords = vector3(coords.x, coords.y, coords.z)
-- Create the bowl object
local hash = GetHashKey(bowl.model)
RequestModel(hash)
while not HasModelLoaded(hash) do
Wait(10)
end
local bowlObject = CreateObject(hash, bowlCoords.x, bowlCoords.y, bowlCoords.z, false, false, false)
SetEntityHeading(bowlObject, coords.w)
FreezeEntityPosition(bowlObject, true)
SetEntityAsMissionEntity(bowlObject, true, true)
-- Store in local table
placedBowls[bowl.bowl_id] = {
object = bowlObject,
id = bowl.bowl_id,
model = bowl.model,
type = bowl.type,
fillLevel = bowl.fill_level
}
-- Add target
AddTargetToBowl(bowlObject, bowl.bowl_id, bowl.type)
end
end)
-- Function to add qb-target to a bowl
function AddTargetToBowl(bowlObject, bowlId, bowlType)
exports['qb-target']:AddTargetEntity(bowlObject, {
options = {
{
type = "client",
icon = "fas fa-hand",
label = "Use Bowl",
action = function()
UseBowl(bowlId, bowlType)
end,
canInteract = function()
return true
end,
},
{
type = "client",
icon = "fas fa-fill",
label = "Fill Bowl",
action = function()
OpenFillMenu(bowlId, bowlType)
end,
canInteract = function()
return true
end,
},
{
type = "client",
icon = "fas fa-trash",
label = "Pick Up Bowl",
action = function()
PickUpBowl(bowlId)
end,
canInteract = function()
return true
end,
}
},
distance = 2.0
})
end
-- Function to use a bowl
function UseBowl(bowlId, bowlType)
local bowl = placedBowls[bowlId]
if not bowl then return end
-- Check if bowl has content
if bowl.fillLevel <= 0 then
lib.notify(Config.Notifications.bowlEmpty)
return
end
-- Set animation and progress bar based on bowl type
local progressConfig = bowlType == 'food' and Config.ProgressBar.eating or Config.ProgressBar.drinking
-- Start progress bar
if lib.progressBar(progressConfig) then
-- Consume from bowl
TriggerServerEvent('pet-bowls:server:consumeBowl', bowlId)
end
end
-- Function to open fill menu
function OpenFillMenu(bowlId, bowlType)
local bowl = placedBowls[bowlId]
if not bowl then return end
-- Get fill items for this bowl type
local fillItems = Config.FillItems[bowlType]
local options = {}
for _, item in pairs(fillItems) do
table.insert(options, {
title = item.label,
description = 'Fill Amount: ' .. item.fillAmount .. '%',
onSelect = function()
FillBowl(bowlId, item.item, item.fillAmount)
end
})
end
lib.registerContext({
id = 'bowl_fill_menu',
title = 'Fill ' .. (bowlType == 'food' and 'Food' or 'Water') .. ' Bowl (' .. bowl.fillLevel .. '%)',
options = options
})
lib.showContext('bowl_fill_menu')
end
-- Function to fill a bowl
function FillBowl(bowlId, itemName, fillAmount)
-- Start progress bar
if lib.progressBar(Config.ProgressBar.filling) then
-- Fill the bowl
TriggerServerEvent('pet-bowls:server:fillBowl', bowlId, itemName, fillAmount)
end
end
-- Function to pick up a bowl
function PickUpBowl(bowlId)
local bowl = placedBowls[bowlId]
if not bowl then return end
-- Delete the object and remove from server
if DoesEntityExist(bowl.object) then
DeleteEntity(bowl.object)
end
TriggerServerEvent('pet-bowls:server:removeBowl', bowlId)
placedBowls[bowlId] = nil
end
-- Command to place a bowl
RegisterCommand('placebowl', function()
OpenPlaceBowlMenu()
end)
-- Function to open place bowl menu
function OpenPlaceBowlMenu()
local options = {}
for _, bowl in pairs(Config.BowlProps) do
table.insert(options, {
title = bowl.label,
description = 'Type: ' .. (bowl.type == 'food' and 'Food Bowl' or 'Water Bowl'),
onSelect = function()
PlaceBowl(bowl)
end
})
end
lib.registerContext({
id = 'place_bowl_menu',
title = 'Place Bowl',
options = options
})
lib.showContext('place_bowl_menu')
end
-- Function to place a bowl
function PlaceBowl(bowlConfig)
local playerPed = PlayerPedId()
local coords = GetEntityCoords(playerPed)
local heading = GetEntityHeading(playerPed)
-- Create the bowl object
local hash = GetHashKey(bowlConfig.model)
RequestModel(hash)
while not HasModelLoaded(hash) do
Wait(10)
end
local forward = GetEntityForwardVector(playerPed)
local placementCoords = vector3(
coords.x + forward.x * 0.5,
coords.y + forward.y * 0.5,
coords.z - 0.5
)
local bowlObject = CreateObject(hash, placementCoords.x, placementCoords.y, placementCoords.z, true, false, false)
SetEntityHeading(bowlObject, heading)
PlaceObjectOnGroundProperly(bowlObject)
FreezeEntityPosition(bowlObject, true)
SetEntityAsMissionEntity(bowlObject, true, true)
-- Generate a unique ID for this bowl
local bowlId = 'bowl_' .. math.random(100000, 999999) .. '_' .. GetGameTimer()
-- Save to server
local finalCoords = GetEntityCoords(bowlObject)
TriggerServerEvent('pet-bowls:server:placeBowl', bowlId, bowlConfig.model, bowlConfig.type, {
x = finalCoords.x,
y = finalCoords.y,
z = finalCoords.z,
w = heading
})
-- Store locally
placedBowls[bowlId] = {
object = bowlObject,
id = bowlId,
model = bowlConfig.model,
type = bowlConfig.type,
fillLevel = 0
}
-- Add target
AddTargetToBowl(bowlObject, bowlId, bowlConfig.type)
lib.notify(Config.Notifications.bowlPlaced)
end
-- Update bowl fill level
RegisterNetEvent('pet-bowls:client:updateBowlLevel', function(bowlId, newLevel)
if placedBowls[bowlId] then
placedBowls[bowlId].fillLevel = newLevel
end
end)
-- Initialize
Citizen.CreateThread(function()
-- Request all placed bowls from server
TriggerServerEvent('pet-bowls:server:requestBowls')
end)