forked from Simnation/Main
301 lines
10 KiB
Lua
301 lines
10 KiB
Lua
EquippedItem = nil
|
|
ItemData = nil
|
|
local AttachedProp
|
|
local PerformingAction
|
|
local ProcessingEffect
|
|
|
|
function DisableControls(denied)
|
|
for i=1, #denied do
|
|
DisableControlAction(0, denied[i], true)
|
|
end
|
|
end
|
|
|
|
function RemoveAttachedProp()
|
|
if AttachedProp and DoesEntityExist(AttachedProp) then
|
|
DeleteEntity(AttachedProp)
|
|
end
|
|
AttachedProp = nil
|
|
end
|
|
|
|
function AttachProp(name)
|
|
RemoveAttachedProp()
|
|
local ped = PlayerPedId()
|
|
local coords = GetEntityCoords(ped)
|
|
local cfg = Config.Items[name]
|
|
local prop = cfg.prop
|
|
AttachedProp = CreateProp(prop.model, coords.x, coords.y, coords.z, true, true, false)
|
|
SetEntityCollision(AttachedProp, false, true)
|
|
AttachEntityToEntity(AttachedProp, ped, GetPedBoneIndex(ped, prop.boneId),
|
|
prop.offset.x, prop.offset.y, prop.offset.z,
|
|
prop.rotation.x, prop.rotation.y, prop.rotation.z, false, false, false, true, 2, true)
|
|
end
|
|
|
|
function ConsumeItem(name)
|
|
if PerformingAction then return end
|
|
PerformingAction = "consume"
|
|
local cfg = Config.Items[name]
|
|
|
|
-- Check if config exists
|
|
if not cfg then
|
|
print("^1ERROR: Configuration missing for item: " .. name .. "^0")
|
|
PerformingAction = nil
|
|
return
|
|
end
|
|
|
|
local anim = cfg.animation
|
|
|
|
-- Check if animation exists
|
|
if not anim then
|
|
print("^1ERROR: Animation configuration missing for item: " .. name .. "^0")
|
|
PerformingAction = nil
|
|
return
|
|
end
|
|
|
|
-- Ensure animation time exists
|
|
if not anim.time then
|
|
print("^1ERROR: Animation time not defined for item: " .. name .. "^0")
|
|
anim.time = 2000 -- Default to 2 seconds if missing
|
|
end
|
|
|
|
local ped = PlayerPedId()
|
|
CreateThread(function()
|
|
local timeLeft = anim.time -- Now we know this won't be nil
|
|
SendNUIMessage({
|
|
type = "holdInteract",
|
|
bool = true
|
|
})
|
|
|
|
while PerformingAction == "consume" and timeLeft > 0 do
|
|
if anim.time - timeLeft > 100 and not IsEntityPlayingAnim(ped, anim.dict, anim.anim, 13) then
|
|
timeLeft = timeLeft - 100
|
|
PlayAnim(ped, anim.dict, anim.anim, anim.params[1] or 1.0, anim.params[2] or -1.0, anim.params[3] or -1, anim.params[4] or 1, anim.params[5] or 1, anim.params[6], anim.params[7], anim.params[8])
|
|
Wait(100)
|
|
else
|
|
timeLeft = timeLeft - 10
|
|
Wait(10)
|
|
end
|
|
end
|
|
|
|
SendNUIMessage({
|
|
type = "holdInteract",
|
|
bool = false
|
|
})
|
|
|
|
ClearPedTasks(ped)
|
|
|
|
-- Store animation time in a local variable to avoid nil reference
|
|
local animTime = anim.time
|
|
|
|
-- Check if timeLeft is nil and provide a default
|
|
if timeLeft == nil then
|
|
timeLeft = 0
|
|
end
|
|
|
|
-- Now use the local variable for comparison
|
|
if timeLeft > 0 and animTime and (animTime - timeLeft <= 100) then
|
|
OptionsMenu()
|
|
PerformingAction = nil
|
|
elseif timeLeft <= 0 then
|
|
lib.callback("pickle_consumables:useItem", "", function(result, uses)
|
|
-- Check if cfg still exists (could have changed during callback)
|
|
if not cfg then
|
|
PerformingAction = nil
|
|
return
|
|
end
|
|
|
|
-- Safe access to cfg.effect
|
|
local effectName = ""
|
|
if cfg.effect and cfg.effect.name then
|
|
effectName = cfg.effect.name
|
|
end
|
|
|
|
if result and Config.Effects[effectName] and Config.Effects[effectName].process then
|
|
CreateThread(function()
|
|
if ProcessingEffect and not Config.Effects[effectName].canOverlap then return end
|
|
ProcessingEffect = true
|
|
Config.Effects[effectName].process(cfg.effect)
|
|
-- Event auslösen
|
|
TriggerEvent("pickle_consumables:effectStarted", effectName, cfg.effect, name)
|
|
ProcessingEffect = false
|
|
end)
|
|
end
|
|
|
|
-- Check if ItemData exists
|
|
if not ItemData then
|
|
PerformingAction = nil
|
|
return
|
|
end
|
|
|
|
-- Check if uses is nil and provide a default
|
|
if uses == nil then
|
|
print("^1WARNING: Server returned nil for uses. Defaulting to 0.^0")
|
|
uses = 0
|
|
end
|
|
|
|
ItemData.uses = uses
|
|
if uses < 1 then
|
|
return RemoveItem()
|
|
end
|
|
|
|
-- Re-fetch config to ensure it's current
|
|
local cfg = Config.Items[name]
|
|
if cfg and cfg.animation and cfg.animation.time then
|
|
SendNUIMessage({
|
|
type = "displayApp",
|
|
data = { quantity = uses, time = cfg.animation.time }
|
|
})
|
|
else
|
|
-- Fallback if config is missing
|
|
SendNUIMessage({
|
|
type = "displayApp",
|
|
data = { quantity = uses, time = 2000 }
|
|
})
|
|
end
|
|
PerformingAction = nil
|
|
end)
|
|
else
|
|
PerformingAction = nil
|
|
end
|
|
end)
|
|
end
|
|
|
|
|
|
|
|
function RemoveItem()
|
|
local ped = PlayerPedId()
|
|
SendNUIMessage({
|
|
type = "hideApp",
|
|
})
|
|
RemoveAttachedProp()
|
|
ClearPedTasks(ped)
|
|
EquippedItem = nil
|
|
ItemData = nil
|
|
PerformingAction = nil
|
|
end
|
|
|
|
function ItemThread(name, metadata)
|
|
if EquippedItem then return end
|
|
EquippedItem = name
|
|
ItemData = metadata
|
|
AttachProp(name)
|
|
local cfg = Config.Items[name]
|
|
|
|
-- Check if config exists
|
|
if not cfg then
|
|
print("^1ERROR: Configuration missing for item: " .. name .. "^0")
|
|
return RemoveItem()
|
|
end
|
|
|
|
-- Safe access to animation time
|
|
local animTime = (cfg.animation and cfg.animation.time) or 2000
|
|
|
|
SendNUIMessage({
|
|
type = "displayApp",
|
|
data = { quantity = ItemData.uses, time = animTime }
|
|
})
|
|
|
|
CreateThread(function()
|
|
local pressTime = 0
|
|
local holding = false
|
|
while EquippedItem == name do
|
|
local ped = PlayerPedId()
|
|
if IsControlJustPressed(1, 45) then
|
|
TriggerServerEvent("pickle_consumables:returnItem")
|
|
RemoveItem()
|
|
elseif IsControlPressed(1, 191) or IsControlPressed(1, 51) then
|
|
if not PerformingAction then
|
|
ConsumeItem(name)
|
|
end
|
|
elseif PerformingAction then
|
|
PerformingAction = nil
|
|
end
|
|
if cfg.idle and not PerformingAction then
|
|
local anim = cfg.idle
|
|
if not IsEntityPlayingAnim(ped, anim.dict, anim.anim, 13) then
|
|
PlayAnim(ped, anim.dict, anim.anim, anim.params[1] or 1.0, anim.params[2] or -1.0, anim.params[3] or -1, anim.params[4] or 1, anim.params[5] or 1, anim.params[6], anim.params[7], anim.params[8])
|
|
Wait(100)
|
|
end
|
|
end
|
|
if GetEntityHealth(ped) < 1 then
|
|
local coords = GetEntityCoords(AttachedProp)
|
|
local _, zCoords = GetGroundZFor_3dCoord(coords.x, coords.y, coords.z)
|
|
RemoveItem()
|
|
TriggerServerEvent("pickle_consumables:drop:createDrop", vector3(coords.x, coords.y, zCoords + 1.0))
|
|
end
|
|
if insideMenu then
|
|
DisableControls({1, 2, 24, 69, 70, 92, 114, 140, 141, 142, 257, 263, 264})
|
|
else
|
|
DisableControls({24, 69, 70, 92, 114, 140, 141, 142, 257, 263, 264})
|
|
end
|
|
Wait(0)
|
|
end
|
|
local ped = PlayerPedId()
|
|
ClearPedTasks(ped)
|
|
end)
|
|
end
|
|
|
|
|
|
RegisterNetEvent("pickle_consumables:equipItem", function(name, metadata)
|
|
if not Config.Items[name] then return print("^1ERROR: This item is not configured.^0") end
|
|
if EquippedItem then return ShowNotification(_L("item_active")) end
|
|
ItemThread(name, metadata)
|
|
end)
|
|
|
|
RegisterNetEvent("pickle_consumables:removeItem", function()
|
|
RemoveItem()
|
|
end)
|
|
|
|
AddEventHandler("onResourceStop", function(name)
|
|
if name ~= GetCurrentResourceName() then return end
|
|
TransitionFromBlurred(0)
|
|
RemoveAttachedProp()
|
|
end)
|
|
|
|
function ValidateItemConfigs()
|
|
print("^2Validating item configurations...^0")
|
|
local issues = 0
|
|
|
|
for itemName, itemConfig in pairs(Config.Items) do
|
|
-- Check for required properties
|
|
if not itemConfig.animation then
|
|
print("^1WARNING: Item '" .. itemName .. "' is missing animation configuration^0")
|
|
issues = issues + 1
|
|
elseif not itemConfig.animation.time then
|
|
print("^1WARNING: Item '" .. itemName .. "' is missing animation time configuration^0")
|
|
issues = issues + 1
|
|
end
|
|
|
|
if not itemConfig.prop then
|
|
print("^1WARNING: Item '" .. itemName .. "' is missing prop configuration^0")
|
|
issues = issues + 1
|
|
end
|
|
|
|
-- Check for effect configuration if referenced
|
|
if itemConfig.effect and itemConfig.effect.name then
|
|
if not Config.Effects[itemConfig.effect.name] then
|
|
print("^1WARNING: Item '" .. itemName .. "' references non-existent effect: " .. itemConfig.effect.name .. "^0")
|
|
issues = issues + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
if issues > 0 then
|
|
print("^1Found " .. issues .. " configuration issues. Please fix them to ensure proper functionality.^0")
|
|
else
|
|
print("^2All item configurations validated successfully!^0")
|
|
end
|
|
end
|
|
|
|
-- Call this when the resource starts
|
|
AddEventHandler('onResourceStart', function(resourceName)
|
|
if (GetCurrentResourceName() ~= resourceName) then return end
|
|
ValidateItemConfigs()
|
|
end)
|
|
|
|
-- Event-Listener für Alkoholkonsum
|
|
AddEventHandler("pickle_consumables:effectStarted", function(effectName, effectData, itemName)
|
|
if effectName == "drunk" then
|
|
local intensity = effectData.intensity or 1.0
|
|
TriggerServerEvent('qb-alcoholtest:server:alcoholConsumed', itemName, intensity)
|
|
end
|
|
end)
|