mirror of
https://github.com/jimathy/jim-consumables.git
synced 2026-08-16 22:16:02 +01:00
Not sure what is going on, they are server synced but Its possible its not loading the correctly because of the spawn location I've changed it to make the props at the players location in hopes this fixes the issue
510 lines
22 KiB
Lua
510 lines
22 KiB
Lua
local alcoholCount, drugCount, consuming, cancelled = 0, 0, false, false
|
|
Consumables, Emotes = {}, {}
|
|
|
|
onPlayerLoaded(function()
|
|
-- Wait until statebag exists, then trigger local handler
|
|
CreateThread(function()
|
|
while not GlobalState.jimConsumableItems do Wait(100) end
|
|
local newConsumables = GlobalState.jimConsumableItems
|
|
for k in pairsByKeys(newConsumables) do
|
|
if not Consumables[k] then
|
|
debugPrint("^5Statebag^7: ^2New ^3Consumable ^2Info synced^7: ^6"..k.."^7")
|
|
end
|
|
end
|
|
while not GlobalState.jimConsumableEmotes do Wait(100) end
|
|
local newEmotes = GlobalState.jimConsumableEmotes
|
|
for k in pairsByKeys(newEmotes) do
|
|
if not Emotes[k] then
|
|
debugPrint("^5Statebag^7: ^2New ^3Emote ^2Info synced^7: ^6"..k.."^7")
|
|
end
|
|
end
|
|
Consumables = newConsumables
|
|
Emotes = newEmotes
|
|
debugPrint("^5Statebag^7: ^2Synced ^6"..countTable(Consumables).." ^2Items and ^6"..countTable(Emotes).." ^2Emotes^7")
|
|
end)
|
|
end, true)
|
|
|
|
-- Handlers to recieve global statebag data from the server
|
|
AddStateBagChangeHandler("jimConsumableItems", nil, function(bagName, key, value, _unused)
|
|
if type(value) == "table" then
|
|
local newItemCount = 0
|
|
for k in pairsByKeys(value) do
|
|
if not Consumables[k] then
|
|
newItemCount += 1
|
|
debugPrint("^5Statebag^7: ^2New ^3Consumable ^2Info synced^7: ^6"..k.."^7")
|
|
end
|
|
end
|
|
Consumables = value
|
|
debugPrint("^5Statebag^7: ^2Synced ^6"..newItemCount.." ^2new Consumables^7")
|
|
end
|
|
end)
|
|
AddStateBagChangeHandler("jimConsumableEmotes", nil, function(bagName, key, value, _unused)
|
|
if type(value) == "table" then
|
|
local newEmoteCount = 0
|
|
for k in pairsByKeys(value) do
|
|
if not Emotes[k] then
|
|
newEmoteCount += 1
|
|
debugPrint("^5Statebag^7: ^2New ^3Emote ^2Info synced^7: ^6"..k.."^7")
|
|
end
|
|
end
|
|
Emotes = value
|
|
debugPrint("^5Statebag^7: ^2Synced ^6"..newEmoteCount.." ^2new Emotes^7")
|
|
end
|
|
end)
|
|
|
|
RegisterNetEvent(getScript()..':Consume', function(itemName)
|
|
if not Consumables[itemName] then return end
|
|
local consumable = Consumables[itemName]
|
|
if not hasItem(itemName, 1) then
|
|
print("^5Debug^7: ^1Error^7: ^2Item not found in inventory^7, ^2stopping^7..")
|
|
end
|
|
local requiredItem = consumable and consumable.requiredItem or nil
|
|
|
|
if requiredItem then
|
|
if not hasItem(requiredItem, 1) then
|
|
triggerNotify(nil, "You need a "..Items[requiredItem].label, "error")
|
|
return
|
|
else
|
|
-- if requiredItem == "lighter" then breakTool({ item = "lighter", damage = math.random(0, 1) }) end
|
|
end
|
|
end
|
|
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^2Starting event, locking inventory and grabbing data^7..")
|
|
tempLockInv(true)
|
|
local Player = PlayerPedId()
|
|
local pedCoords = GetEntityCoords(Player)
|
|
local emote = Emotes[consumable.emote] or Emotes["crisps"]
|
|
if isAnimal then --- Animal ped adjustments
|
|
local presets = {
|
|
["default"] = {
|
|
propPlacement = { 0.0, 0.25, -0.04, 0.0, 0.0, 0.0, },
|
|
propPlacement2 = { 0.0, 0.25, -0.02, 0.0, 0.0, 0.0, }
|
|
},
|
|
[`a_c_rabbit_01`] = {
|
|
propPlacement = { 0.0, 0.37, -0.15, 0.0, 0.0, 0.0, },
|
|
propPlacement2 = { 0.0, 0.37, -0.13, 0.0, 0.0, 0.0, }
|
|
},
|
|
[`a_c_rat`] = {
|
|
propPlacement = { 0.0, 0.25, -0.04, 0.0, 0.0, 0.0, },
|
|
propPlacement2 = { 0.0, 0.25, -0.02, 0.0, 0.0, 0.0, }
|
|
},
|
|
[`a_c_crow`] = {
|
|
propPlacement = { 0.0, 0.25, 0.02, 0.0, 0.0, 0.0, },
|
|
propPlacement2 = { 0.0, 0.25, 0.04, 0.0, 0.0, 0.0, }
|
|
},
|
|
}
|
|
|
|
local model = GetEntityModel(Player)
|
|
local isCat = (isCat() or model == `ft-raccoon`) and (model ~= `ft-sphynx`)
|
|
local isDog, bigDog = isDog()
|
|
if isDog and model == `a_c_coyote` then isDog = false end
|
|
local isCoyote = (model == `ft-sphynx` or model == `a_c_coyote`)
|
|
if model == `ft-capmonkey2` then isDog = true end
|
|
|
|
local propPlacement, propPlacement2 = { 0.0, 0.37, -0.19, 0.0, 0.0, 0.0, }, { 0.0, 0.37, -0.17, 0.0, 0.0, 0.0, }
|
|
if isDog then
|
|
if bigDog or isCoyote then
|
|
propPlacement = { 0.0, 0.53, -0.39, 0.0, 0.0, 0.0, } propPlacement2 = { 0.0, 0.53, -0.37, 0.0, 0.0, 0.0, }
|
|
else
|
|
propPlacement = { 0.0, 0.33, -0.28, 0.0, 0.0, 0.0, } propPlacement2 = { 0.0, 0.33, -0.26, 0.0, 0.0, 0.0, }
|
|
end
|
|
end
|
|
if not isCat and not isDog then
|
|
propPlacement = presets[model] and presets[model].propPlacement or presets["default"].propPlacement
|
|
propPlacement2 = presets[model] and presets[model].propPlacement2 or presets["default"].propPlacement
|
|
end
|
|
|
|
emote = {
|
|
"creatures@pug@move", "nill", "",
|
|
AnimationOptions = {
|
|
EmoteLoop = true,
|
|
Prop = "v_res_tt_bowl",
|
|
PropBone = 64081,
|
|
PropPlacement = propPlacement,
|
|
SecondProp = Emotes[consumable.emote].AnimationOptions.Prop or nil,
|
|
SecondPropBone = Emotes[consumable.emote].AnimationOptions.Prop and 64081 or nil,
|
|
SecondPropPlacement = Emotes[consumable.emote].AnimationOptions.Prop and propPlacement2 or nil,
|
|
},
|
|
}
|
|
end
|
|
|
|
local returnItem = consumable.returnItem or nil
|
|
local animDict, anim = tostring(emote[1]), tostring(emote[2])
|
|
local model, model2, bone, bone2, drugeffect, stress
|
|
local P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12 = table.unpack({0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}) -- Default placement coord cariable
|
|
local RewardItem = consumable.rewards or nil
|
|
local type = consumable.type or ""
|
|
local pack = consumable.pack or nil
|
|
local string = "Using "
|
|
local canRun = consumable.canRun
|
|
local stats = consumable.stats
|
|
|
|
local time, stress, heal, armor, needStats = GenerateRandomValues({
|
|
time = consumable.time or { 5000, 6000 },
|
|
stress = consumable.stress or 0,
|
|
heal = consumable.heal or 0,
|
|
armor = consumable.armor or 0,
|
|
hunger = consumable.stats and consumable.stats.hunger or 0,
|
|
thirst = consumable.stats and consumable.stats.thirst or 0,
|
|
})
|
|
if emote.AnimationOptions.Prop then
|
|
model = emote.AnimationOptions.Prop
|
|
bone = GetPedBoneIndex(Player, emote.AnimationOptions.PropBone)
|
|
P1, P2, P3, P4, P5, P6 = table.unpack(emote.AnimationOptions.PropPlacement)
|
|
if emote.AnimationOptions.SecondProp then
|
|
model2 = emote.AnimationOptions.SecondProp
|
|
bone2 = GetPedBoneIndex(Player, emote.AnimationOptions.SecondPropBone)
|
|
P7, P8, P9, P10, P11, P12 = table.unpack(emote.AnimationOptions.SecondPropPlacement)
|
|
end
|
|
end
|
|
|
|
if type == "drink" or type == "alcohol" then
|
|
string = "Drinking "
|
|
elseif type == "food" then
|
|
string = "Eating "
|
|
elseif type == "smoke" then
|
|
string = "Smoking "
|
|
elseif type == "pack" then
|
|
string = "Opening "
|
|
end
|
|
|
|
if consuming then
|
|
cancelled = true
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^2Event already started^7, ^1Cancelling^7.")
|
|
tempLockInv(false)
|
|
if Config.UseProgbar then
|
|
stopProgressBar()
|
|
else
|
|
triggerNotify(nil, "Stopped "..string, "error")
|
|
end
|
|
consuming = not consuming
|
|
return
|
|
end
|
|
--Emote Stuff
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^2Grabbing Emote Animation Options^7...")
|
|
local InVehicle = IsPedInAnyVehicle(Player, true)
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^2Checking if player is in a vehicle^7 - ^6"..tostring(InVehicle).."^7")
|
|
|
|
MovementType = 0 -- Default movement type
|
|
|
|
if InVehicle == 1 then
|
|
MovementType = 51
|
|
elseif emote.AnimationOptions then
|
|
if emote.AnimationOptions.EmoteMoving then
|
|
MovementType = 51
|
|
elseif emote.AnimationOptions.EmoteLoop then
|
|
MovementType = 1
|
|
elseif emote.AnimationOptions.EmoteStuck then
|
|
MovementType = emote.AnimationOptions.EmoteMoving and 50 or 2
|
|
elseif emote.AnimationOptions.EmoteMoving == false then
|
|
MovementType = 0
|
|
end
|
|
|
|
end
|
|
--Load and Start animation
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^2Playing Animation^7...")
|
|
if not (GetPedType(Player) == 28)then
|
|
playAnim(animDict, anim, -1, MovementType)
|
|
end
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^2Player Movement Flag^7 - ^6"..json.encode(MovementType).." ^7")
|
|
if Config.Main.UseProgbar then
|
|
CreateThread(function()
|
|
if progressBar({
|
|
time = time,
|
|
label = string..Items[itemName].label.."..",
|
|
dead = false,
|
|
disableMovement = false,
|
|
disableCombat = true,
|
|
cancel = false
|
|
}) then
|
|
consuming = false
|
|
else
|
|
consuming = false
|
|
end
|
|
end)
|
|
else
|
|
triggerNotify(nil, string..Items[itemName].label.."..", "success")
|
|
end
|
|
|
|
consuming = true
|
|
|
|
CreateThread(function()
|
|
--Prop Spawning
|
|
if model then
|
|
if IsModelValid(model) == 1 then
|
|
debugPrint("^5Debug^7: ^3PropSpawn^7: ^2Spawning consumable prop^7...")
|
|
attachProp = makeProp({ prop = model, coords = vec4(pedCoords.x, pedCoords.y, pedCoords.z, 0.0)}, 1, 1)
|
|
AttachEntityToEntity(attachProp, Player, bone, P1, P2, P3, P4, P5, P6, true, true, false, true, 1, true)
|
|
if model2 then
|
|
if IsModelValid(model2) == 1 then
|
|
attachProp2 = makeProp({ prop = model2, coords = vec4(pedCoords.x, pedCoords.y, pedCoords.z, 0.0)}, 1, 1)
|
|
AttachEntityToEntity(attachProp2, Player, bone2, P7, P8, P9, P10, P11, P12, true, true, false, true, 1, true)
|
|
else
|
|
print("^5Debug^7: ^3PropSpawn^7: ^2Second prop model isn't valid/found^7.")
|
|
end
|
|
end
|
|
while consuming do Wait(50) end
|
|
if DoesEntityExist(attachProp) then
|
|
destroyProp(attachProp)
|
|
attachProp = nil
|
|
end
|
|
if DoesEntityExist(attachProp2) then
|
|
destroyProp(attachProp2)
|
|
attachProp2 = nil
|
|
end
|
|
else
|
|
print("^5Debug^7: ^3PropSpawn^7: ^2Prop model isn't valid/found^7.")
|
|
end
|
|
end
|
|
end)
|
|
|
|
while consuming do
|
|
if debugMode then
|
|
drawText(nil, {
|
|
"Time: "..tostring(time),
|
|
"Type: "..(type or ""),
|
|
"Hunger: "..(needStats.hunger or 0).."%",
|
|
"Thirst: "..(needStats.thirst or 0).."%",
|
|
"Stress: "..(stress or 0).."%",
|
|
"Heal: "..(heal or 0).."%",
|
|
"Armour: "..(armor or 0).."%",
|
|
}, nil, nil)
|
|
end
|
|
makeInstructionalButtons({
|
|
{ keys = { 194 }, text = "Stop Consuming" },
|
|
})
|
|
if time <= 0 then
|
|
consuming = false
|
|
end
|
|
if (IsControlJustPressed(0, 21) and not canRun) or IsPedRagdoll(Player) or IsControlJustPressed(0, 177) then
|
|
consuming = false
|
|
cancelled = true
|
|
tempLockInv(false)
|
|
hideText()
|
|
if Config.Main.UseProgbar then
|
|
stopProgressBar()
|
|
else
|
|
triggerNotify(nil, "Cancelled "..string, "error")
|
|
end
|
|
end
|
|
Wait(0)
|
|
time -= 12
|
|
end
|
|
StopEntityAnim(Player, anim, animDict, 1.0)
|
|
unloadAnimDict(animDict)
|
|
if not cancelled then
|
|
hideText()
|
|
removeItem(itemName, 1)
|
|
if returnItem ~= nil then
|
|
debugPrint("returnItem detected")
|
|
currentToken = triggerCallback(AuthEvent)
|
|
addItem(returnItem.item, returnItem.amount)
|
|
end
|
|
|
|
-- Reward Item calculations
|
|
CreateThread(function()
|
|
if RewardItem then
|
|
debugPrint("Reward Item detected")
|
|
for i = 1, consumable.amounttogive do
|
|
local rarity = math.random(1, 4) -- rarity calculation
|
|
while true do
|
|
local item = math.random(1, countTable(RewardItem)) -- random item in the list to pick
|
|
if RewardItem[item].rarity >= rarity then
|
|
currentToken = triggerCallback(AuthEvent)
|
|
addItem(RewardItem[item].item, math.random(1, RewardItem[item].max or 1))
|
|
debugPrint("^5Debug^7: ^2Given reward prize^7: '^6"..RewardItem[item].item.."^7'")
|
|
break
|
|
end
|
|
Wait(100)
|
|
end
|
|
Wait(1500)
|
|
end
|
|
end
|
|
end)
|
|
if needStats then
|
|
jsonPrint(needStats)
|
|
if needStats.hunger > 0 then
|
|
local hunger = 0
|
|
if Core and Core.Functions then
|
|
hunger = (Core.Functions.GetPlayerData().metadata["hunger"] or 0) + needStats.hunger
|
|
hunger = hunger > 100 and 100 or hunger
|
|
|
|
elseif ESX and ESX.GetPlayerData then
|
|
hunger = (needStats.hunger / 100) * 1000000
|
|
hunger = hunger > 1000000 and 1000000 or hunger
|
|
end
|
|
|
|
TriggerServerEvent(getScript()..":server:setNeed", "hunger", hunger)
|
|
end
|
|
|
|
if needStats.thirst > 0 then
|
|
local thirst = 0
|
|
if Core and Core.Functions then
|
|
thirst = (Core.Functions.GetPlayerData().metadata["thirst"] or 0) + needStats.thirst
|
|
thirst = thirst > 100 and 100 or thirst
|
|
|
|
elseif ESX and ESX.GetPlayerData then
|
|
thirst = (needStats.thirst / 100) * 1000000
|
|
thirst = thirst > 1000000 and 1000000 or thirst
|
|
end
|
|
|
|
TriggerServerEvent(getScript()..":server:setNeed", "thirst", thirst)
|
|
end
|
|
end
|
|
debugPrint("^5Debug^7: ^2Hunger^7: [^6"..(needStats.hunger or 0).."^7] ^2Thrist^7: [^6"..(needStats.thirst or 0).."^7]" )
|
|
if stress and stress ~= 0 then
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^2Relieving ^6"..stress.." ^2stress^7.")
|
|
TriggerServerEvent('hud:server:RelieveStress', stress)
|
|
end
|
|
if heal and heal ~= 0 then
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^2Healing player by^7: ^6"..heal)
|
|
SetEntityHealth(Player, GetEntityHealth(Player) + heal)
|
|
end
|
|
if armor and armor ~= 0 then
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^2Adding ^6"..armor.." ^2armour^7.")
|
|
TriggerServerEvent('hospital:server:SetArmor', (GetPedArmour(Player) + armor)) SetPedArmour(Player, (GetPedArmour(Player) + armor))
|
|
end
|
|
if type == "alcohol" then
|
|
alcoholCount += 1
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^2Current ^4alcoholCount^7: ^6"..alcoholCount)
|
|
if alcoholCount > 1 and alcoholCount < 4 then
|
|
TriggerEvent("evidence:client:SetStatus", "alcohol", 200)
|
|
elseif alcoholCount >= 4 then
|
|
TriggerEvent("evidence:client:SetStatus", "heavyalcohol", 200)
|
|
CreateThread(function()
|
|
AlienEffect()
|
|
end) -- Used as overdosing/too drunk effect
|
|
end
|
|
end
|
|
if pack then
|
|
currentToken = triggerCallback(AuthEvent)
|
|
addItem(pack.item, pack.amount)
|
|
end
|
|
if stats then
|
|
if stats.screen then -- Screen effect activation
|
|
debugPrint(stats.screen)
|
|
local statFunctions = {
|
|
["turbo"] = TurboEffect,
|
|
["focus"] = FocusEffect,
|
|
["rampage"] = RampageEffect,
|
|
["weed"] = WeedEffect,
|
|
["trevor"] = TrevorEffect,
|
|
["nightvision"] = NightVisionEffect,
|
|
["thermal"] = ThermalEffect,
|
|
}
|
|
if statFunctions[stats.screen] then
|
|
CreateThread(function()
|
|
statFunctions[stats.screen]()
|
|
end)
|
|
end
|
|
end
|
|
if stats.canOD then
|
|
drugCount += 1
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^2Current ^4drugCount^7: ^6"..drugCount)
|
|
if drugCount >= 4 then
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^2Current ^4drugCount^7: ^6"..drugCount.."^7 - ^2 removing health")
|
|
SetEntityHealth(PlayerPedId(), GetEntityHealth(Player) - math.random(10, 15))
|
|
if drugCount >= 7 then
|
|
CreateThread(function() AlienEffect() end) -- If too many drugs, if not dead will make you stumble
|
|
end
|
|
end
|
|
end
|
|
if stats.effect then
|
|
local effectTable = {
|
|
["heal"] = function(stats)
|
|
if isStarted("ps-buffs") then
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^4PS^7-^4Buffs ^2found^7, ^2hooking in to get buffs and applying ^6Health Buff ^2for ^6"..stats.time.."^7ms")
|
|
exports["ps-buffs"]:AddHealthBuff((tonumber(stats.time) or 10000), (stats.amount or 6))
|
|
else
|
|
CreateThread(function()
|
|
HealEffect({(tonumber(stats.time) or 10000), (stats.amount or 6)})
|
|
end)
|
|
end
|
|
end,
|
|
["stamina"] = function(stats)
|
|
if isStarted("ps-buffs") then
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^4PS^7-^4Buffs ^2found^7, ^2hooking in to get buffs and applying ^6Stamina Buff ^2for ^6"..stats.time.."^7ms")
|
|
exports["ps-buffs"]:StaminaBuffEffect((tonumber(stats.time) or 10000), (stats.amount or 6))
|
|
else
|
|
CreateThread(function()
|
|
StaminaEffect({(tonumber(stats.time) or 10000), (stats.amount or 6)})
|
|
end)
|
|
end
|
|
end,
|
|
["armor"] = function(stats)
|
|
if isStarted("ps-buffs") then --PS-BUFFS ONLY
|
|
exports["ps-buffs"]:AddArmorBuff((tonumber(stats.time) or 10000), (stats.amount or 6))
|
|
end
|
|
end,
|
|
["stress"] = function(stats)
|
|
if isStarted("ps-buffs") then --PS-BUFFS ONLY
|
|
exports["ps-buffs"]:AddStressBuff((tonumber(stats.time) or 10000), (stats.amount or 6))
|
|
end
|
|
end,
|
|
["swimming"] = function(stats)
|
|
if isStarted("ps-buffs") then --PS-BUFFS ONLY
|
|
exports["ps-buffs"]:SwimmingBuffEffect((tonumber(stats.time) or 10000), (stats.amount or 6))
|
|
end
|
|
end,
|
|
["hacking"] = function(stats)
|
|
if isStarted("ps-buffs") then --PS-BUFFS ONLY
|
|
exports["ps-buffs"]:AddBuff("hacking", (tonumber(stats.time) or 10000))
|
|
end
|
|
end,
|
|
["intelligence"] = function(stats)
|
|
if isStarted("ps-buffs") then --PS-BUFFS ONLY
|
|
exports["ps-buffs"]:AddBuff("intelligence", (tonumber(stats.time) or 10000))
|
|
end
|
|
end,
|
|
["luck"] = function(stats)
|
|
if isStarted("ps-buffs") then --PS-BUFFS ONLY
|
|
exports["ps-buffs"]:AddBuff("luck", (tonumber(stats.time) or 10000))
|
|
end
|
|
end,
|
|
["strength"] = function(stats)
|
|
if isStarted("ps-buffs") then --PS-BUFFS ONLY
|
|
exports["ps-buffs"]:AddBuff("strength", (tonumber(stats.time) or 10000))
|
|
end
|
|
end,
|
|
}
|
|
|
|
if effectTable[stats.effect] then
|
|
effectTable[stats.effect](stats)
|
|
end
|
|
end
|
|
if stats.widepupils then
|
|
TriggerEvent("evidence:client:SetStatus", "widepupils", 200)
|
|
end
|
|
end
|
|
end
|
|
cancelled = false
|
|
consuming = false
|
|
debugPrint("^5Debug^7: ^3Consume^7: ^2Finished, unlocking inventory^7...")
|
|
tempLockInv(false)
|
|
end)
|
|
|
|
CreateThread(function()
|
|
while true do
|
|
Wait(10)
|
|
if alcoholCount > 0 then
|
|
Wait(1000 * 60 * 15)
|
|
alcoholCount -= 1
|
|
else
|
|
Wait(1000)
|
|
end
|
|
if drugCount > 0 then
|
|
Wait(1000 * 60 * 15)
|
|
drugCount -= 1
|
|
else
|
|
Wait(1000)
|
|
end
|
|
end
|
|
end)
|
|
|
|
onResourceStop(function()
|
|
|
|
lockInv(false)
|
|
|
|
StopEffects()
|
|
|
|
end, true) |