mirror of
https://github.com/jimathy/jim-consumables.git
synced 2026-08-16 22:16:02 +01:00
34
README.md
34
README.md
@@ -6,15 +6,29 @@ This script is designed as a replacement/override for food and drink consumables
|
||||
|
||||
It's main purpose was to make it possible to not stand up while sitting due to lazy events such as ClearPedTasks in most scripts, this one is designed to cancel the animation you have chosen, not all animations. This includes progressbar.
|
||||
|
||||
## v1.4 Beta Information
|
||||
I've added a export system that allows scripts to easily add new foods and drinks to be usable and then sync them between players
|
||||
This should work but may have issues.
|
||||
|
||||
But because of the export system being used, Jim-Consumables **NEEDS** to start before any scripts that use it.
|
||||
|
||||
And small example snippet for this imports the item and the emote, then syncs it to players
|
||||
|
||||
```lua
|
||||
local foodTable = {
|
||||
["shotfries"] = { emote = "bsfries", canRun = false, time = math.random(5000, 6000), stress = math.random(2, 4), heal = 0, armor = 0, type = "food", stats = { hunger = math.random(55,65), }},
|
||||
}
|
||||
local emoteTable = {
|
||||
["bsfries"] = {"mp_player_inteat@burger", "mp_player_int_eat_burger_fp", "Fries", AnimationOptions = { Prop = "prop_food_bs_chips", PropBone = 18905, PropPlacement = {0.09, -0.06, 0.05, 300.0, 150.0}, EmoteMoving = true, EmoteLoop = true, }},
|
||||
}
|
||||
|
||||
for k, v in pairs(emoteTable) do exports["jim-consumables"]:importEmote(k, v) end
|
||||
for k, v in pairs(foodTable) do exports["jim-consumables"]:importConsumable(k, v) end
|
||||
```
|
||||
This will grab the `shotfries` item info and add it to the `Config.Consumables` while the servers running and the same with the built-in emote system
|
||||
|
||||
# Installation
|
||||
|
||||
```
|
||||
Please stop asking to how add a progressbar...PLEASE
|
||||
|
||||
This script was designed to not need one, because of how it cancels all the player animations instantly
|
||||
|
||||
You can manage without a progressbar.
|
||||
```
|
||||
This script is recommended to be ran last/at the bottom of your server.cfg because this is intended to take control of items, if ran too early the original script may override this one.
|
||||
|
||||
It already takes control of default qbcore food and drink, but you would probably want to add more.
|
||||
@@ -28,6 +42,10 @@ To add an item, you only need to add a new item table in the Config.Consumables
|
||||
heal = 0, -- Set amount to heal by after consuming
|
||||
armor = 5, -- Amount of armor to add
|
||||
type = "food", -- Type: "alcohol" / "drink" / "food"
|
||||
returnItem = { -- Item that will be given when the item is used
|
||||
item = "plastic", -- eg. Plastic bottles can give "plastic"
|
||||
amount = 1,
|
||||
},
|
||||
stats = {
|
||||
screen = "rampage", -- The screen effect to be played when after consuming the item
|
||||
effect = "heal", -- The status effect given by the item, "heal" / "stamina"
|
||||
@@ -70,4 +88,4 @@ If this script is enabled it will automatically try to use their system to apply
|
||||
"strength" -- Strength effect
|
||||
```
|
||||
|
||||
This script supports dpemotes style emotes, so if you have some that you want to be triggered when eating or drinking drop it in the Config.Emotes section.
|
||||
This script supports dpemotes style emotes, so if you have some that you want to be triggered when eating or drinking drop it in the Config.Emotes section.
|
||||
|
||||
@@ -16,22 +16,31 @@ end
|
||||
local consuming = false
|
||||
local cancelled = false
|
||||
|
||||
AddEventHandler('onResourceStart', function(r) if GetCurrentResourceName() ~= r then return end TriggerServerEvent("jim-consumables:getSync") end)
|
||||
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() TriggerServerEvent("jim-consumables:getSync") end)
|
||||
RegisterNetEvent("jim-consumables:syncItems", function(consumables, emotes)
|
||||
if consumables then for k, v in pairs(consumables) do if not Config.Consumables[k] then Config.Consumables[k] = v print("^5Debug^7 ^2Adding Item^7: '^6"..k.."^7'") end end end
|
||||
if emotes then for k, v in pairs(emotes) do if not Config.Emotes[k] then Config.Emotes[k] = v print("^5Debug^7 ^2Adding Emote^7: '^6"..k.."^7'") end end end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('jim-consumables:Consume', function(itemName)
|
||||
if not HasItem(itemName, 1) then print("^5Debug^7: ^1Error^7: ^2Item not found in inventory^7, ^2stopping^7..") end
|
||||
if Config.Debug then print("^5Debug^7: ^3Consume^7: ^2Starting event, locking inventory and grabbing data^7..") end
|
||||
LocalPlayer.state:set("inv_busy", true, true) TriggerEvent('inventory:client:busy:status', true) TriggerEvent('canUseInventoryAndHotbar:toggle', false)
|
||||
local Player = PlayerPedId()
|
||||
local emote = Config.Emotes[Config.Consumables[itemName].emote]
|
||||
local emote = Config.Emotes[Config.Consumables[itemName].emote] or "eat"
|
||||
local returnItem = Config.Consumables[itemName].returnItem or nil
|
||||
local animDict = tostring(emote[1])
|
||||
local anim = 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
|
||||
if emote.AnimationOptions.Prop then
|
||||
model = emote.AnimationOptions.Prop
|
||||
bone = GetPedBoneIndex(PlayerPedId(), emote.AnimationOptions.PropBone)
|
||||
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(PlayerPedId(), emote.AnimationOptions.SecondPropBone)
|
||||
bone2 = GetPedBoneIndex(Player, emote.AnimationOptions.SecondPropBone)
|
||||
P7, P8, P9, P10, P11, P12 = table.unpack(emote.AnimationOptions.SecondPropPlacement)
|
||||
end
|
||||
end
|
||||
@@ -67,12 +76,12 @@ RegisterNetEvent('jim-consumables:Consume', function(itemName)
|
||||
end
|
||||
else MovementType = 0 end
|
||||
if Config.Debug then print("^5Debug^7: ^3Consume^7: ^2Checking if player is in a vehicle^7...") end
|
||||
local InVehicle = IsPedInAnyVehicle(PlayerPedId(), true)
|
||||
local InVehicle = IsPedInAnyVehicle(Player, true)
|
||||
if InVehicle == 1 then MovementType = 51 end
|
||||
--Load and Start animation
|
||||
if Config.Debug then print("^5Debug^7: ^3Consume^7: ^2Playing Animation^7...") end
|
||||
loadAnimDict(animDict)
|
||||
TaskPlayAnim(PlayerPedId(), animDict, anim, 1.0, 1.0, -1, MovementType, 0, 0, 0, 0)
|
||||
TaskPlayAnim(Player, animDict, anim, 1.0, 1.0, -1, MovementType, 0, 0, 0, 0)
|
||||
|
||||
if Config.UseProgbar then
|
||||
QBCore.Functions.Progressbar('jimmy_consume_', string..QBCore.Shared.Items[itemName].label.."..", time, false, false, {disableMovement = false, disableCarMovement = false, disableMouse = false, disableCombat = true,}, {}, {}, {}, function() consuming = false end, function() end, itemName)
|
||||
@@ -87,11 +96,11 @@ RegisterNetEvent('jim-consumables:Consume', function(itemName)
|
||||
if IsModelValid(model) == 1 then
|
||||
if Config.Debug then print("^5Debug^7: ^3PropSpawn^7: ^2Spawning consumable prop^7.") end
|
||||
attachProp = makeProp({ prop = model, coords = vector4(0.0,0.0,0.0,0.0)}, 1, 1)
|
||||
AttachEntityToEntity(attachProp, PlayerPedId(), bone, P1, P2, P3, P4, P5, P6, true, true, false, true, 1, true)
|
||||
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 = vector4(0.0,0.0,0.0,0.0)}, 1, 1)
|
||||
AttachEntityToEntity(attachProp2, PlayerPedId(), bone2, P7, P8, P9, P10, P11, P12, true, true, false, true, 1, true)
|
||||
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
|
||||
@@ -117,10 +126,11 @@ RegisterNetEvent('jim-consumables:Consume', function(itemName)
|
||||
Wait(10)
|
||||
time -= 10
|
||||
end
|
||||
StopEntityAnim(PlayerPedId(), anim, animDict, 1.0)
|
||||
StopEntityAnim(Player, anim, animDict, 1.0)
|
||||
unloadAnimDict(animDict)
|
||||
if not cancelled then
|
||||
toggleItem(false, itemName, 1)
|
||||
if returnItem ~= nil then toggleItem(true, returnItem.item, returnItem.amount) end
|
||||
if QBCore.Shared.Items[itemName].thirst then TriggerServerEvent("jim-consumables:server:addThirst", QBCore.Functions.GetPlayerData().metadata["thirst"] + QBCore.Shared.Items[itemName].thirst) end
|
||||
if QBCore.Shared.Items[itemName].hunger then TriggerServerEvent("jim-consumables:server:addHunger", QBCore.Functions.GetPlayerData().metadata["hunger"] + QBCore.Shared.Items[itemName].hunger) end
|
||||
if not QBCore.Shared.Items[itemName].thirst and not QBCore.Shared.Items[itemName].hunger then
|
||||
@@ -139,11 +149,11 @@ RegisterNetEvent('jim-consumables:Consume', function(itemName)
|
||||
end
|
||||
if heal and heal ~= 0 then
|
||||
if Config.Debug then print("^5Debug^7: ^3Consume^7: ^2Healing player by^7: ^6"..heal) end
|
||||
SetEntityHealth(PlayerPedId(), GetEntityHealth(PlayerPedId()) + heal)
|
||||
SetEntityHealth(Player, GetEntityHealth(Player) + heal)
|
||||
end
|
||||
if armor and armor ~= 0 then
|
||||
if Config.Debug then print("^5Debug^7: ^3Consume^7: ^2Adding ^6"..armor.." ^2armour^7.") end
|
||||
TriggerServerEvent('hospital:server:SetArmor', (GetPedArmour(PlayerPedId()) + armor)) SetPedArmour(PlayerPedId(), (GetPedArmour(PlayerPedId()) + armor))
|
||||
TriggerServerEvent('hospital:server:SetArmor', (GetPedArmour(Player) + armor)) SetPedArmour(Player, (GetPedArmour(Player) + armor))
|
||||
end
|
||||
if type == "alcohol" then
|
||||
if Config.Debug then print("^5Debug^7: ^3Consume^7: ^2Current ^4alcoholCount^7: ^6"..(alcoholCount + 1)) end
|
||||
@@ -171,29 +181,33 @@ RegisterNetEvent('jim-consumables:Consume', function(itemName)
|
||||
drugCount += 1
|
||||
if drugCount >= 4 then
|
||||
if Config.Debug then print("^5Debug^7: ^3Consume^7: ^2Current ^4drugCount^7: ^6"..drugCount.."^7 - ^2 removing health") end
|
||||
SetEntityHealth(PlayerPedId(), GetEntityHealth(PlayerPedId()) - math.random(10,15))
|
||||
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 == "heal" then
|
||||
if GetResourceState("ps-buffs") == "started" then exports["ps-buffs"]:AddHealthBuff((stats.time or 10000), (stats.amount or 6))
|
||||
else CreateThread(function() HealEffect({(stats.time or 10000), (stats.amount or 6)}) end) end
|
||||
if GetResourceState("ps-buffs") == "started" then
|
||||
if Config.Debug then print("^5Debug^7: ^3Consume^7: ^4PS^7-^4Buffs ^2found^7, ^2hooking in to get buffs and applying ^6Health Buff ^2for ^6"..stats.time.."^7ms") end
|
||||
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
|
||||
if stats.effect == "stamina" then
|
||||
if GetResourceState("ps-buffs") == "started" then exports["ps-buffs"]:StaminaBuffEffect((stats.time or 10000), (stats.amount or 6))
|
||||
else CreateThread(function() StaminaEffect({(stats.time or 10000), (stats.amount or 6)}) end) end
|
||||
if GetResourceState("ps-buffs") == "started" then
|
||||
if Config.Debug then print("^5Debug^7: ^3Consume^7: ^4PS^7-^4Buffs ^2found^7, ^2hooking in to get buffs and applying ^6Stamina Buff ^2for ^6"..stats.time.."^7ms") end
|
||||
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
|
||||
if GetResourceState("ps-buffs") == "started" then --PS-BUFFS ONLY
|
||||
if Config.Debug then print("^5Debug^7: ^3Consume^7: ^4PS^7-^4Buffs ^2found^7, ^2hooking in to get buffs") end
|
||||
if stats.effect == "armor" then exports["ps-buffs"]:AddArmorBuff((stats.time or 10000), (stats.amount or 6)) end
|
||||
if stats.effect == "stress" then exports["ps-buffs"]:AddStressBuff((stats.time or 10000), (stats.amount or 6)) end
|
||||
if stats.effect == "swimming" then exports["ps-buffs"]:SwimmingBuffEffect((stats.time or 10000), (stats.amount or 6)) end
|
||||
if stats.effect == "hacking" then exports["ps-buffs"]:AddBuff("hacking", (stats.time or 10000)) end
|
||||
if stats.effect == "intelligence" then exports["ps-buffs"]:AddBuff("intelligence", (stats.time or 10000)) end
|
||||
if stats.effect == "luck" then exports["ps-buffs"]:AddBuff("luck", (stats.time or 10000)) end
|
||||
if stats.effect == "strength" then exports["ps-buffs"]:AddBuff("strength", (stats.time or 10000)) end
|
||||
if Config.Debug then print("^5Debug^7: ^3Consume^7: ^4PS^7-^4Buffs ^2found^7, ^2hooking in to get buffs and applying ^6"..stats.effect.." Buff ^2for ^6"..(stats.time or "nil").."^7ms") end
|
||||
if stats.effect == "armor" then exports["ps-buffs"]:AddArmorBuff((tonumber(stats.time) or 10000), (stats.amount or 6)) end
|
||||
if stats.effect == "stress" then exports["ps-buffs"]:AddStressBuff((tonumber(stats.time) or 10000), (stats.amount or 6)) end
|
||||
if stats.effect == "swimming" then exports["ps-buffs"]:SwimmingBuffEffect((tonumber(stats.time) or 10000), (stats.amount or 6)) end
|
||||
if stats.effect == "hacking" then exports["ps-buffs"]:AddBuff("hacking", (tonumber(stats.time) or 10000)) end
|
||||
if stats.effect == "intelligence" then exports["ps-buffs"]:AddBuff("intelligence", (tonumber(stats.time) or 10000)) end
|
||||
if stats.effect == "luck" then exports["ps-buffs"]:AddBuff("luck", (tonumber(stats.time) or 10000)) end
|
||||
if stats.effect == "strength" then exports["ps-buffs"]:AddBuff("strength", (tonumber(stats.time) or 10000)) end
|
||||
end
|
||||
if stats.widepupils then TriggerEvent("evidence:client:SetStatus", "widepupils", 200) end
|
||||
end
|
||||
|
||||
169
config.lua
169
config.lua
@@ -6,7 +6,9 @@ print("^2Jim^7-^2Consumables ^7v^41^7.^43^7.^42 ^7- ^2Consumables Script by ^1Ji
|
||||
|
||||
Config = {
|
||||
Debug = false,
|
||||
|
||||
Notify = "qb",
|
||||
|
||||
UseProgbar = false,
|
||||
|
||||
Consumables = {
|
||||
@@ -52,6 +54,10 @@ Config = {
|
||||
heal = 0, -- Set amount to heal by after consuming
|
||||
armor = 5, -- Amount of armor to add
|
||||
type = "food", -- Type: "alcohol" / "drink" / "food"
|
||||
returnItem = { -- Item that will be given when the item is used
|
||||
item = "plastic", -- eg. Plastic bottles can give "plastic"
|
||||
amount = 1,
|
||||
},
|
||||
stats = {
|
||||
screen = "rampage", -- The screen effect to be played when after consuming the item
|
||||
effect = "heal", -- The status effect given by the item, "heal" / "stamina"
|
||||
@@ -109,168 +115,5 @@ Config = {
|
||||
["sprunk"] = {"mp_player_intdrink", "loop_bottle", "Sprunk", AnimationOptions =
|
||||
{ Prop = "v_res_tt_can03", PropBone = 18905, PropPlacement = {0.12, 0.008, 0.03, 240.0, -60.0},
|
||||
EmoteMoving = true, EmoteLoop = true, }},
|
||||
--Jim-BeanMachine
|
||||
["bmcoffee1"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Coffee2", AnimationOptions =
|
||||
{ Prop = 'prop_fib_coffee', PropBone = 28422, PropPlacement = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
|
||||
["bmcoffee2"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Coffee3", AnimationOptions =
|
||||
{ Prop = 'ng_proc_coffee_01a', PropBone = 28422, PropPlacement = {0.0, 0.0, -0.06, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
|
||||
["bmcoffee3"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Coffee3", AnimationOptions =
|
||||
{ Prop = 'v_club_vu_coffeecup', PropBone = 28422, PropPlacement = {0.0, 0.0, -0.06, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
--Jim-PizzaThis
|
||||
["redwine"] = {"mp_player_intdrink", "loop_bottle", "Red Wine Bottle", AnimationOptions =
|
||||
{ Prop = "prop_wine_rose", PropBone = 18905, PropPlacement = {0.00, -0.26, 0.10, 240.0, -60.0},
|
||||
EmoteMoving = true, EmoteLoop = true, }},
|
||||
["whitewine"] = {"mp_player_intdrink", "loop_bottle", "White Wine Bottle", AnimationOptions =
|
||||
{ Prop = "prop_wine_white", PropBone = 18905, PropPlacement = {0.00, -0.26, 0.10, 240.0, -60.0},
|
||||
EmoteMoving = true, EmoteLoop = true, }},
|
||||
["pizza"] = {"mp_player_inteat@burger", "mp_player_int_eat_burger_fp", "Pizza", AnimationOptions =
|
||||
{ Prop = "v_res_tt_pizzaplate", PropBone = 18905, PropPlacement = {0.20, 0.038, 0.051, 15.0, 155.0},
|
||||
EmoteMoving = true, EmoteLoop = true, }},
|
||||
["bowl"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "bowl", AnimationOptions =
|
||||
{ Prop = "h4_prop_h4_coke_plasticbowl_01", PropBone = 28422, PropPlacement = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
EmoteMoving = true, EmoteLoop = true, }},
|
||||
["pineapple"] = {"mp_player_inteat@burger", "mp_player_int_eat_burger_fp", "Pizza", AnimationOptions =
|
||||
{ Prop = "prop_pineapple", PropBone = 18905, PropPlacement = {0.10, 0.038, 0.03, 15.0, 50.0},
|
||||
EmoteMoving = true, EmoteLoop = true, }},
|
||||
["foodbowl"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "bowl", AnimationOptions =
|
||||
{ Prop = "prop_cs_bowl_01", PropBone = 28422, PropPlacement = {0.0, 0.0, 0.050, 0.0, 0.0, 0.0},
|
||||
EmoteMoving = true, EmoteLoop = true, }},
|
||||
--Jim-BurgerShot
|
||||
["milk"] = {"mp_player_intdrink", "loop_bottle", "Milk", AnimationOptions =
|
||||
{ Prop = "v_res_tt_milk", PropBone = 18905, PropPlacement = {0.10, 0.008, 0.07, 240.0, -60.0},
|
||||
EmoteMoving = true, EmoteLoop = true, }},
|
||||
["bscoke"] = {"mp_player_intdrink", "loop_bottle", "BS Coke", AnimationOptions =
|
||||
{ Prop = "prop_food_bs_juice01", PropBone = 18905, PropPlacement = {0.04, -0.10, 0.10, 240.0, -60.0},
|
||||
EmoteMoving = true, EmoteLoop = true, }},
|
||||
["bscoffee"] = {"mp_player_intdrink", "loop_bottle", "BS Coffee", AnimationOptions =
|
||||
{ Prop = "prop_food_bs_coffee", PropBone = 18905, PropPlacement = {0.08, -0.10, 0.10, 240.0, -60.0},
|
||||
EmoteMoving = true, EmoteLoop = true, }},
|
||||
["glass"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Tall Glass", AnimationOptions =
|
||||
{ Prop = 'prop_wheat_grass_glass', PropBone = 28422, PropPlacement = {0.0, 0.0, -0.1, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
|
||||
["torpedo"] = {"mp_player_inteat@burger", "mp_player_int_eat_burger_fp", "Torpedo", AnimationOptions =
|
||||
{ Prop = "prop_food_bs_burger2", PropBone = 18905, PropPlacement = {0.10, -0.07, 0.091, 15.0, 135.0},
|
||||
EmoteMoving = true, EmoteLoop = true, }},
|
||||
["bsfries"] = {"mp_player_inteat@burger", "mp_player_int_eat_burger_fp", "Fries", AnimationOptions =
|
||||
{ Prop = "prop_food_bs_chips", PropBone = 18905, PropPlacement = {0.09, -0.06, 0.05, 300.0, 150.0},
|
||||
EmoteMoving = true, EmoteLoop = true, }},
|
||||
["donut2"] = {"mp_player_inteat@burger", "mp_player_int_eat_burger", "Donut2", AnimationOptions =
|
||||
{ Prop = 'prop_donut_02', PropBone = 18905, PropPlacement = {0.13, 0.05, 0.02, -50.0, 100.0, 270.0},
|
||||
EmoteMoving = true, EmoteLoop = true, }},
|
||||
|
||||
--Jim-CatCafe
|
||||
["boba1"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Boba 1", AnimationOptions =
|
||||
{ Prop = 'denis3d_catcafe_boobaA', PropBone = 28422, PropPlacement = {0.0, 0.0, -0.1, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["boba2"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Boba 2", AnimationOptions =
|
||||
{ Prop = 'denis3d_catcafe_boobaB', PropBone = 28422, PropPlacement = {0.0, 0.0, -0.1, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["boba3"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Boba 3", AnimationOptions =
|
||||
{ Prop = 'denis3d_catcafe_boobaC', PropBone = 28422, PropPlacement = {0.0, 0.0, -0.1, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["boba4"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Boba 4", AnimationOptions =
|
||||
{ Prop = 'denis3d_catcafe_boobaD', PropBone = 28422, PropPlacement = {0.0, 0.0, -0.1, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["mochi"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Mochi", AnimationOptions =
|
||||
{ Prop = 'denis3d_catcafe_plateD', PropBone = 28422, PropPlacement = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
|
||||
--Jim-Tequilala
|
||||
["whiskeyb"] = {"anim@amb@nightclub@mini@drinking@drinking_shots@ped_b@normal@", "glass_hold", "Whiskey Bottle", AnimationOptions =
|
||||
{ Prop = "prop_cs_whiskey_bottle", PropBone = 60309, PropPlacement = {0.08, 0.0, 0.05, 240.0, -60.0},
|
||||
EmoteMoving = true, EmoteLoop = true }},
|
||||
["rumb"] = {"anim@amb@nightclub@mini@drinking@drinking_shots@ped_b@normal@", "glass_hold", "Rum Bottle", AnimationOptions =
|
||||
{ Prop = "prop_rum_bottle", PropBone = 60309, PropPlacement = {-0.04, -0.18, 0.12, 240.0, -60.0},
|
||||
EmoteMoving = true, EmoteLoop = true }},
|
||||
["icream"] = {"anim@amb@nightclub@mini@drinking@drinking_shots@ped_b@normal@", "glass_hold", "Irish Cream Bottle", AnimationOptions =
|
||||
{ Prop = "prop_bottle_brandy", PropBone = 60309, PropPlacement = {-0.04, -0.18, 0.12, 240.0, -60.0},
|
||||
EmoteMoving = true, EmoteLoop = true }},
|
||||
["ginb"] = {"anim@amb@nightclub@mini@drinking@drinking_shots@ped_b@normal@", "glass_hold", "Gin Bottle", AnimationOptions =
|
||||
{ Prop = "prop_tequila_bottle", PropBone = 60309, PropPlacement = {-0.04, -0.18, 0.12, 240.0, -60.0},
|
||||
EmoteMoving = true, EmoteLoop = true }},
|
||||
["vodkab"] = {"anim@amb@nightclub@mini@drinking@drinking_shots@ped_b@normal@", "glass_hold", "Vodka Bottle", AnimationOptions =
|
||||
{ Prop = 'prop_vodka_bottle', PropBone = 60309, PropPlacement = {-0.04, -0.18, 0.12, 240.0, -60.0},
|
||||
EmoteMoving = true, EmoteLoop = true }},
|
||||
["browncup"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Brown Cup", AnimationOptions =
|
||||
{ Prop = 'v_serv_bs_mug', PropBone = 28422, PropPlacement = {0.03, -0.02, 0.0, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["crisps"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Crisps", AnimationOptions =
|
||||
{ Prop = 'v_ret_ml_chips2', PropBone = 28422, PropPlacement = {0.01, -0.05, -0.1, 0.0, 0.0, 90.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["smoke2"] = {"amb@world_human_aa_smoke@male@idle_a", "idle_c", "Smoke 2", AnimationOptions =
|
||||
{ Prop = 'prop_cs_ciggy_01', PropBone = 28422, PropPlacement = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["smoke3"] = {"amb@world_human_aa_smoke@male@idle_a", "idle_b", "Smoke 3", AnimationOptions =
|
||||
{ Prop = 'prop_cs_ciggy_01', PropBone = 28422, PropPlacement = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["smoke4"] = {"amb@world_human_smoking@female@idle_a", "idle_b", "Smoke 4", AnimationOptions =
|
||||
{ Prop = 'prop_cs_ciggy_01', PropBone = 28422, PropPlacement = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["bong"] = {"anim@safehouse@bong", "bong_stage3", "Bong", AnimationOptions =
|
||||
{ Prop = 'hei_heist_sh_bong_01', PropBone = 18905, PropPlacement = {0.10,-0.25,0.0,95.0,190.0,180.0}, }},
|
||||
["coffee"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Coffee", AnimationOptions =
|
||||
{ Prop = 'p_amb_coffeecup_01', PropBone = 28422, PropPlacement = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["whiskey"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Whiskey", AnimationOptions =
|
||||
{ Prop = 'prop_drink_whisky', PropBone = 28422, PropPlacement = {0.01, -0.01, -0.06, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["beer"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Beer", AnimationOptions =
|
||||
{ Prop = 'prop_amb_beer_bottle', PropBone = 28422, PropPlacement = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["cup"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Cup", AnimationOptions =
|
||||
{ Prop = 'prop_plastic_cup_02', PropBone = 28422, PropPlacement = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["donut"] = {"mp_player_inteat@burger", "mp_player_int_eat_burger", "Donut", AnimationOptions =
|
||||
{ Prop = 'prop_amb_donut', PropBone = 18905, PropPlacement = {0.13, 0.05, 0.02, -50.0, 16.0, 60.0},
|
||||
EmoteMoving = true, }},
|
||||
["burger"] = {"mp_player_inteat@burger", "mp_player_int_eat_burger", "Burger", AnimationOptions =
|
||||
{ Prop = 'prop_cs_burger_01', PropBone = 18905, PropPlacement = {0.13, 0.05, 0.02, -50.0, 16.0, 60.0},
|
||||
EmoteMoving = true, }},
|
||||
["sandwich"] = {"mp_player_inteat@burger", "mp_player_int_eat_burger", "Sandwich", AnimationOptions =
|
||||
{ Prop = 'prop_sandwich_01', PropBone = 18905, PropPlacement = {0.13, 0.05, 0.02, -50.0, 16.0, 60.0},
|
||||
EmoteMoving = true, }},
|
||||
["soda"] = {"amb@world_human_drinking@coffee@male@idle_a", "idle_c", "Soda", AnimationOptions =
|
||||
{ Prop = 'prop_ecola_can', PropBone = 28422, PropPlacement = {0.0, 0.0, 0.0, 0.0, 0.0, 130.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["egobar"] = {"mp_player_inteat@burger", "mp_player_int_eat_burger", "Ego Bar", AnimationOptions =
|
||||
{ Prop = 'prop_choc_ego', PropBone = 60309, PropPlacement = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
|
||||
EmoteMoving = true, }},
|
||||
["wine"] = {"anim@heists@humane_labs@finale@keycards", "ped_a_enter_loop", "Wine", AnimationOptions =
|
||||
{ Prop = 'prop_drink_redwine', PropBone = 18905, PropPlacement = {0.10, -0.03, 0.03, -100.0, 0.0, -10.0},
|
||||
EmoteMoving = true, EmoteLoop = true }},
|
||||
["flute"] = {"anim@heists@humane_labs@finale@keycards", "ped_a_enter_loop", "Flute", AnimationOptions =
|
||||
{ Prop = 'prop_champ_flute', PropBone = 18905, PropPlacement = {0.10, -0.03, 0.03, -100.0, 0.0, -10.0},
|
||||
EmoteMoving = true, EmoteLoop = true }},
|
||||
["champagne"] = {"anim@heists@humane_labs@finale@keycards", "ped_a_enter_loop", "Champagne", AnimationOptions =
|
||||
{ Prop = 'prop_drink_champ', PropBone = 18905, PropPlacement = {0.10, -0.03, 0.03, -100.0, 0.0, -10.0},
|
||||
EmoteMoving = true, EmoteLoop = true }},
|
||||
["cigar"] = {"amb@world_human_smoking@male@male_a@enter", "enter", "Cigar", AnimationOptions =
|
||||
{ Prop = 'prop_cigar_02', PropBone = 47419, PropPlacement = {0.010, 0.0, 0.0, 50.0, 0.0, -80.0},
|
||||
EmoteMoving = true, EmoteDuration = 2600 }},
|
||||
["cigar2"] = {"amb@world_human_smoking@male@male_a@enter", "enter", "Cigar 2", AnimationOptions =
|
||||
{ Prop = 'prop_cigar_01', PropBone = 47419, PropPlacement = {0.010, 0.0, 0.0, 50.0, 0.0, -80.0},
|
||||
EmoteMoving = true, EmoteDuration = 2600 }},
|
||||
["joint"] = {"amb@world_human_smoking@male@male_a@enter", "enter", "Joint", AnimationOptions =
|
||||
{ Prop = 'p_cs_joint_02', PropBone = 47419, PropPlacement = {0.015, -0.009, 0.003, 55.0, 0.0, 110.0},
|
||||
EmoteMoving = true, EmoteDuration = 2600 }},
|
||||
["cig"] = {"amb@world_human_smoking@male@male_a@enter", "enter", "Cig", AnimationOptions =
|
||||
{ Prop = 'prop_amb_ciggy_01', PropBone = 47419, PropPlacement = {0.015, -0.009, 0.003, 55.0, 0.0, 110.0},
|
||||
EmoteMoving = true, EmoteDuration = 2600 }},
|
||||
["clean"] = {"timetable@floyd@clean_kitchen@base", "base", "Clean", AnimationOptions =
|
||||
{ Prop = "prop_sponge_01", PropBone = 28422, PropPlacement = {0.0, 0.0, -0.01, 90.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["clean2"] = {"amb@world_human_maid_clean@", "base", "Clean 2", AnimationOptions =
|
||||
{ Prop = "prop_sponge_01", PropBone = 28422, PropPlacement = {0.0, 0.0, -0.01, 90.0, 0.0, 0.0},
|
||||
EmoteLoop = true, EmoteMoving = true, }},
|
||||
["coke"] = { "switch@trevor@trev_smoking_meth", "trev_smoking_meth_loop", "Coke", AnimationOptions =
|
||||
{ EmoteLoop = true, EmoteMoving = true, }},
|
||||
["oxy"] = { "mp_suicide", "pill", "Oxy", AnimationOptions =
|
||||
{ EmoteLoop = true, EmoteMoving = true, }},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name "Jim-Consumables"
|
||||
author "Jimathy"
|
||||
version "v1.3.2"
|
||||
version "v1.4"
|
||||
description "Consumable Script By Jimathy"
|
||||
fx_version "cerulean"
|
||||
game "gta5"
|
||||
|
||||
@@ -2,8 +2,8 @@ local QBCore = exports['qb-core']:GetCoreObject()
|
||||
|
||||
for k, v in pairs(Config.Consumables) do
|
||||
QBCore.Functions.CreateUseableItem(k, function(source, item) TriggerClientEvent('jim-consumables:Consume', source, item.name) end)
|
||||
if not QBCore.Shared.Items[k] then print("Item check - '"..k.."' not found in the shared lua") end
|
||||
if not Config.Emotes[v.emote] then print("Emote check - '"..k.."' requested emote '"..v.emote.."' - not found in config.lua") end
|
||||
if not QBCore.Shared.Items[k] then print("^1Debug^7: ^2Item check ^7- '^1"..k.."^7' ^2not found in the shared lua^7") end
|
||||
if not Config.Emotes[v.emote] then print("^1Debug^7: ^2Emote check ^7- '^1"..k.."^7' ^2requested emote ^7'^6"..v.emote.."^7' - ^2not found in config^7.^2lua^7") end
|
||||
end
|
||||
|
||||
RegisterNetEvent('jim-consumables:server:toggleItem', function(give, item, amount)
|
||||
@@ -13,14 +13,47 @@ RegisterNetEvent('jim-consumables:server:toggleItem', function(give, item, amoun
|
||||
TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[item], "remove", amount or 1)
|
||||
end
|
||||
else
|
||||
if not Config.Consumables[give] then print(('%s may have potentially attempted an item exploit to gain %s %s'):format(src, amount, item)) return end -- cancel if item does not exist in config
|
||||
|
||||
if QBCore.Functions.GetPlayer(src).Functions.AddItem(item, amount or 1) then
|
||||
TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[item], "add", amount or 1)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent("jim-consumables:server:DupeWarn", function(item, newsrc)
|
||||
local src = newsrc or source
|
||||
local P = QBCore.Functions.GetPlayer(src)
|
||||
print("^5DupeWarn: ^1"..P.PlayerData.charinfo.firstname.." "..P.PlayerData.charinfo.lastname.."^7(^1"..tostring(src).."^7) ^2Tried to remove item ^7('^3"..item.."^7')^2 but it wasn't there^7")
|
||||
if not Config.Debug then DropPlayer(src, "Kicked for attempting to duplicate items") end
|
||||
print("^5DupeWarn: ^1"..P.PlayerData.charinfo.firstname.." "..P.PlayerData.charinfo.lastname.."^7(^1"..tostring(src).."^7) ^2Dropped from server for item duplicating^7")
|
||||
end)
|
||||
|
||||
RegisterNetEvent('jim-consumables:server:toggleItem', function(give, item, amount, newsrc)
|
||||
local src = newsrc or source
|
||||
local amount = amount or 1
|
||||
local remamount = amount
|
||||
if not give then
|
||||
if HasItem(src, item, amount) then -- check if you still have the item
|
||||
if QBCore.Functions.GetPlayer(src).Functions.GetItemByName(item).unique then -- If unique item, keep removing until gone
|
||||
while remamount > 0 do
|
||||
QBCore.Functions.GetPlayer(src).Functions.RemoveItem(item, 1)
|
||||
remamount -= 1
|
||||
end
|
||||
TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[item], "remove", amount) -- Show removal item box when all are removed
|
||||
return
|
||||
end
|
||||
if QBCore.Functions.GetPlayer(src).Functions.RemoveItem(item, amount) then
|
||||
if Config.Debug then print("^5Debug^7: ^1Removing ^2from Player^7(^2"..src.."^7) '^6"..QBCore.Shared.Items[item].label.."^7(^2x^6"..(amount or "1").."^7)'") end
|
||||
TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[item], "remove", amount)
|
||||
end
|
||||
else TriggerEvent("jim-consumables:server:DupeWarn", item, src) end -- if not boot the player
|
||||
elseif give then
|
||||
if QBCore.Functions.GetPlayer(src).Functions.AddItem(item, amount) then
|
||||
if Config.Debug then print("^5Debug^7: ^4Giving ^2Player^7(^2"..src.."^7) '^6"..QBCore.Shared.Items[item].label.."^7(^2x^6"..(amount or "1").."^7)'") end
|
||||
TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[item], "add", amount)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
RegisterNetEvent('jim-consumables:server:addThirst', function(amount)
|
||||
local Player = QBCore.Functions.GetPlayer(source)
|
||||
if not Player then return end
|
||||
@@ -34,3 +67,44 @@ RegisterNetEvent('jim-consumables:server:addHunger', function(amount)
|
||||
Player.Functions.SetMetaData('hunger', amount)
|
||||
TriggerClientEvent('hud:client:UpdateNeeds', source, amount, Player.PlayerData.metadata.thirst)
|
||||
end)
|
||||
|
||||
function HasItem(source, items, amount)
|
||||
local amount = amount or 1
|
||||
local Player = QBCore.Functions.GetPlayer(source)
|
||||
if not Player then return false end
|
||||
local count = 0
|
||||
|
||||
if Config.Debug then print("^5Debug^7: ^3HasItem^7: ^2Checking if player has required item^7 '^3"..tostring(items).."^7'") end
|
||||
|
||||
for _, itemData in pairs(Player.PlayerData.items) do
|
||||
if itemData and (itemData.name == items) then
|
||||
if Config.Debug then print("^5Debug^7: ^3HasItem^7: ^2Item^7: '^3"..tostring(items).."^7' ^2Slot^7: ^3"..itemData.slot.." ^7x(^3"..tostring(itemData.amount).."^7)") end
|
||||
count += itemData.amount
|
||||
end
|
||||
end
|
||||
if count >= amount then
|
||||
if Config.Debug then print("^5Debug^7: ^3HasItem^7: ^2Items ^5FOUND^7 x^3"..count.."^7") end
|
||||
return true
|
||||
end
|
||||
if Config.Debug then print("^5Debug^7: ^3HasItem^7: ^2Items ^1NOT FOUND^7") end
|
||||
return false
|
||||
end
|
||||
|
||||
--Export Import System--
|
||||
RegisterNetEvent("jim-consumables:getSync", function() local src = source TriggerClientEvent("jim-consumables:syncItems", source, Config.Consumables, Config.Emotes) end)
|
||||
local function importEmote(emoteName, eInfo)
|
||||
if Config.Debug then print("^5Debug^7: ^2Importing Item ^7'^6"..emoteName.."^7'") end
|
||||
Config.Emotes[emoteName] = eInfo
|
||||
TriggerClientEvent("jim-consumables:syncItems", -1, nil, Config.Emotes)
|
||||
end
|
||||
|
||||
local function importConsumable(itemName, conInfo)
|
||||
if Config.Debug then print("^5Debug^7: ^2Importing Item ^7'^6"..itemName.."^7'") end
|
||||
if not QBCore.Shared.Items[itemName] then print("^1Debug^7: ^2Item check ^7- '^1"..k.."^7' ^2not found in the shared lua^7") end
|
||||
Config.Consumables[itemName] = conInfo
|
||||
QBCore.Functions.CreateUseableItem(itemName, function(source, item) TriggerClientEvent('jim-consumables:Consume', source, itemName) end)
|
||||
TriggerClientEvent("jim-consumables:syncItems", -1, Config.Consumables, nil)
|
||||
end
|
||||
|
||||
exports("importEmote", importEmote)
|
||||
exports("importConsumable", importConsumable)
|
||||
|
||||
@@ -12,9 +12,9 @@ function loadModel(model) if not HasModelLoaded(model) then
|
||||
end
|
||||
end end
|
||||
function unloadModel(model) if Config.Debug then print("^5Debug^7: ^2Removing Model^7: '^6"..model.."^7'") end SetModelAsNoLongerNeeded(model) end
|
||||
function loadAnimDict(dict) if not HasAnimDictLoaded(dict) then if Config.Debug then print("^5Debug^7: ^2Loading Anim Dictionary^7: '^6"..dict.."^7'") end while not HasAnimDictLoaded(dict) do RequestAnimDict(dict) Wait(5) end end end
|
||||
function loadAnimDict(dict) if not HasAnimDictLoaded(dict) then if Config.Debug then print("^5Debug^7: ^2Loading Anim Dictionary^7: '^6"..dict.."^7'") end while not HasAnimDictLoaded(dict) do RequestAnimDict(dict) Wait(5) end end end
|
||||
function unloadAnimDict(dict) if Config.Debug then print("^5Debug^7: ^2Removing Anim Dictionary^7: '^6"..dict.."^7'") end RemoveAnimDict(dict) end
|
||||
function loadPtfxDict(dict) if not HasNamedPtfxAssetLoaded(dict) then if Config.Debug then print("^5Debug^7: ^2Loading Ptfx Dictionary^7: '^6"..dict.."^7'") end while not HasNamedPtfxAssetLoaded(dict) do RequestNamedPtfxAsset(dict) Wait(5) end end end
|
||||
function loadPtfxDict(dict) if not HasNamedPtfxAssetLoaded(dict) then if Config.Debug then print("^5Debug^7: ^2Loading Ptfx Dictionary^7: '^6"..dict.."^7'") end while not HasNamedPtfxAssetLoaded(dict) do RequestNamedPtfxAsset(dict) Wait(5) end end end
|
||||
function unloadPtfxDict(dict) if Config.Debug then print("^5Debug^7: ^2Removing Ptfx Dictionary^7: '^6"..dict.."^7'") end RemoveNamedPtfxAsset(dict) end
|
||||
|
||||
function destroyProp(entity)
|
||||
@@ -58,6 +58,24 @@ function countTable(table) local i = 0 for keys in pairs(table) do i += 1 end re
|
||||
|
||||
function toggleItem(give, item, amount) TriggerServerEvent("jim-consumables:server:toggleItem", give, item, amount) end
|
||||
|
||||
function HasItem(items, amount)
|
||||
local amount = amount or 1
|
||||
local count = 0
|
||||
for _, itemData in pairs(QBCore.Functions.GetPlayerData().items) do
|
||||
if itemData and (itemData.name == items) then
|
||||
if Config.Debug then print("^5Debug^7: ^3HasItem^7: ^2Item^7: '^3"..tostring(items).."^7' ^2Slot^7: ^3"..itemData.slot.." ^7x(^3"..tostring(itemData.amount).."^7)") end
|
||||
count += itemData.amount
|
||||
end
|
||||
end
|
||||
if count >= amount then
|
||||
if Config.Debug then print("^5Debug^7: ^3HasItem^7: ^2Items ^5FOUND^7 x^3"..count.."^7") end
|
||||
return true
|
||||
else
|
||||
if Config.Debug then print("^5Debug^7: ^3HasItem^7: ^2Items ^1NOT FOUND^7") end
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
--Screen Effects
|
||||
local alienEffect = false
|
||||
function AlienEffect()
|
||||
|
||||
Reference in New Issue
Block a user