mirror of
https://github.com/jimathy/jim-consumables.git
synced 2026-08-16 22:16:02 +01:00
249 lines
12 KiB
Lua
249 lines
12 KiB
Lua
|
|
RegisterNetEvent("jim-consumables:client:consumableCreator", function()
|
||
|
|
local itemTable, emoteTable = {}, {}
|
||
|
|
for k, v in pairsByKeys(Items) do itemTable[#itemTable+1] = { value = tostring(k), label = tostring((v.label or k)) } end
|
||
|
|
table.sort(itemTable, function(a, b) return a.label < b.label end)
|
||
|
|
for k in pairsByKeys(Emotes) do emoteTable[#emoteTable+1] = { value = k, label = k } end
|
||
|
|
local input = lib.inputDialog("Consumable Creator", {
|
||
|
|
{ type = "select",
|
||
|
|
label = "Item List",
|
||
|
|
options = itemTable,
|
||
|
|
required = true,
|
||
|
|
icon = "fas fa-burger",
|
||
|
|
clearable = true,
|
||
|
|
searchable = true -- Doesnt work as i think only ox_lib lua was updated, the web stuff doesn't support this
|
||
|
|
},
|
||
|
|
{ type = "select",
|
||
|
|
label = "Emote",
|
||
|
|
options = emoteTable,
|
||
|
|
required = true,
|
||
|
|
icon = "fas fa-user",
|
||
|
|
clearable = true,
|
||
|
|
searchable = true, -- Doesnt work as i think only ox_lib lua was updated, the web stuff doesn't support this
|
||
|
|
default = "burger",
|
||
|
|
},
|
||
|
|
{ type = "select",
|
||
|
|
label = "Item Required for consuming",
|
||
|
|
options = itemTable,
|
||
|
|
required = false,
|
||
|
|
icon = "fas fa-utensils",
|
||
|
|
clearable = true,
|
||
|
|
searchable = true -- Doesnt work as i think only ox_lib lua was updated, the web stuff doesn't support this
|
||
|
|
},
|
||
|
|
{ type = 'number', label = 'Time', description = "How long it takes in ms to consume item", default = 5000, icon = "fas fa-clock", },
|
||
|
|
{ type = 'number', label = 'Stress Relief', description = "How much stress to relieve", default = 0, icon = "fas fa-mug-hot", },
|
||
|
|
{ type = 'number', label = 'Healing Amount', description = "How much to heal after consuming", default = 0, icon = "fas fa-notes-medical", },
|
||
|
|
{ type = 'number', label = 'Armour', description = "How much armour to give after consuming", default = 0, icon = "fas fa-shield-halved", },
|
||
|
|
{ type = "select", label = "Type", default = "food", icon = "fas fa-box", options = {
|
||
|
|
{ value = "food", label = "Food" },
|
||
|
|
{ value = "drink", label = "Drink" },
|
||
|
|
{ value = "alcohol", label = "Alcohol" },
|
||
|
|
{ value = "drug", label = "Drugs" },
|
||
|
|
{ value = "smoke", label = "Cigar/Cigarette" },
|
||
|
|
{ value = "pack", label = "Pack (Container Item)" },
|
||
|
|
}},
|
||
|
|
})
|
||
|
|
if not input or not input[1] then return end
|
||
|
|
local resultTable = {
|
||
|
|
item = input[1],
|
||
|
|
emote = input[2],
|
||
|
|
requireItem = input[3] or nil,
|
||
|
|
time = { input[4], input[4] + 1000 },
|
||
|
|
stress = input[5],
|
||
|
|
heal = input[6],
|
||
|
|
armor = input[7],
|
||
|
|
type = input[8],
|
||
|
|
}
|
||
|
|
if resultTable.type == "food" or resultTable.type == "drink" then foodInput(resultTable)
|
||
|
|
elseif resultTable.type == "pack" then packInput(resultTable, itemTable)
|
||
|
|
else
|
||
|
|
ExtraStatsInput(resultTable)
|
||
|
|
end
|
||
|
|
end, false)
|
||
|
|
|
||
|
|
function foodInput(prevInput)
|
||
|
|
local resultTable = prevInput
|
||
|
|
local input = lib.inputDialog((Items[prevInput.item].label or prevInput.item).." - Food or Drink",{
|
||
|
|
{ type = 'number', label = 'Hunger %', default = 0, icon = "fas fa-burger", },
|
||
|
|
{ type = 'number', label = 'Thirst %', default = 0, icon = "fas fa-mug-hot", },
|
||
|
|
})
|
||
|
|
if not input or not input[1] then return end
|
||
|
|
resultTable["stats"] = {
|
||
|
|
hunger = input[1] ~= 0 and { input[1], input[1] + 10 } or 0,
|
||
|
|
thirst = input[2] ~= 0 and { input[2], input[2] + 10 } or 0,
|
||
|
|
}
|
||
|
|
ExtraStatsInput(resultTable)
|
||
|
|
end
|
||
|
|
|
||
|
|
function packInput(prevInput, itemTable)
|
||
|
|
local resultTable = prevInput
|
||
|
|
local input = lib.inputDialog((Items[prevInput.item].label or prevInput.item).." - Pack", {
|
||
|
|
{ type = "select",
|
||
|
|
label = "Item List",
|
||
|
|
options = itemTable,
|
||
|
|
required = true,
|
||
|
|
icon = "fas fa-burger",
|
||
|
|
},
|
||
|
|
{ type = 'number', label = 'Amount to give of item', default = 1, icon = "fas fa-box", },
|
||
|
|
})
|
||
|
|
resultTable["pack"] = { item = input[1], amount = input[2], }
|
||
|
|
getConsumableResult(resultTable)
|
||
|
|
end
|
||
|
|
|
||
|
|
function ExtraStatsInput(prevInput)
|
||
|
|
local resultTable = prevInput
|
||
|
|
local input = lib.inputDialog((Items[prevInput.item].label or prevInput.item).." - Extra Stats", {
|
||
|
|
{ type = "select", label = "Buff Type", description = "These are 'gradual' buff effects", default = "none", options = {
|
||
|
|
{ value = "none", label = "None" },
|
||
|
|
{ value = "heal", label = "Healing" },
|
||
|
|
{ value = "stamina", label = "Stamina" },
|
||
|
|
{ value = "armor", label = "Armour" },
|
||
|
|
{ value = "stress", label = "Stress" },
|
||
|
|
{ value = "swimming", label = "Swimming" },
|
||
|
|
{ value = "hacking", label = "Hacking" },
|
||
|
|
{ value = "intelligence", label = "Intelligence" },
|
||
|
|
{ value = "luck", label = "Luck" },
|
||
|
|
{ value = "strength", label = "Strength" },
|
||
|
|
}},
|
||
|
|
{ type = "select", label = "Screen Effect", default = "none", options = {
|
||
|
|
{ value = "none", label = "None" },
|
||
|
|
{ value = "rampage", label = "Rampage" },
|
||
|
|
{ value = "turbo", label = "Turbo" },
|
||
|
|
{ value = "focus", label = "Focus" },
|
||
|
|
{ value = "weed", label = "Weed" },
|
||
|
|
{ value = "trevor", label = "Trevor" },
|
||
|
|
{ value = "nightvision", label = "Night Vision" },
|
||
|
|
{ value = "thermal", label = "Thermal Vision" },
|
||
|
|
}},
|
||
|
|
{ type = "number", label = "Total Time of 'Buff'", default = 10000, },
|
||
|
|
{ type = "number", label = "Amount to give per second", default = 6, },
|
||
|
|
((prevInput.type ~= "food" and prevInput.type ~= "drink") and { type = "select", label = "Wide Pupils", default = "false", options = {
|
||
|
|
{ value = "true", label = "True" },
|
||
|
|
{ value = "false", label = "False" },
|
||
|
|
}} or nil),
|
||
|
|
((prevInput.type ~= "food" and prevInput.type ~= "drink") and { type = "select", label = "Can Over Dose", default = "false", options = {
|
||
|
|
{ value = "true", label = "True" },
|
||
|
|
{ value = "false", label = "False" },
|
||
|
|
}} or nil),
|
||
|
|
})
|
||
|
|
if not input or not input[1] then return end
|
||
|
|
resultTable["stats"] = {
|
||
|
|
hunger = resultTable["stats"] and resultTable["stats"].hunger or 0,
|
||
|
|
thirst = resultTable["stats"] and resultTable["stats"].thirst or 0,
|
||
|
|
screen = input[2] or nil,
|
||
|
|
effect = input[1] or nil,
|
||
|
|
time = input[1] ~= "none" and input[3] or nil,
|
||
|
|
amount = input[1] ~= "none" and input[4] or nil,
|
||
|
|
widepupils = input[5],
|
||
|
|
canOD = input[6],
|
||
|
|
}
|
||
|
|
getConsumableResult(resultTable)
|
||
|
|
end
|
||
|
|
|
||
|
|
function getConsumableResult(data)
|
||
|
|
local resultString = '["'..data.item..'"] = { '
|
||
|
|
resultString = resultString..'emote = "'..data.emote..'", '
|
||
|
|
resultString = resultString.."canRun = true, "
|
||
|
|
resultString = resultString.."time = {"..data.time[1]..", "..data.time[2].."}, "
|
||
|
|
resultString = (data.stress > 0 and resultString.."stress = "..data.stress..", ") or resultString..""
|
||
|
|
resultString = (data.heal > 0 and resultString.."heal = "..data.heal..", ") or resultString..""
|
||
|
|
resultString = (data.armor > 0 and resultString.."armor = "..data.armor..", ") or resultString..""
|
||
|
|
resultString = resultString..'type = "'..data.type..'", '
|
||
|
|
if data.type == "pack" then
|
||
|
|
resultString = resultString..'pack = { item = "'..data.pack.item..'", amount = "'..data.pack.amount..'", }, '
|
||
|
|
end
|
||
|
|
if data.stats then
|
||
|
|
resultString = resultString.."stats = { "
|
||
|
|
if data.stats.hunger and type(data.stats.hunger) == "table" then
|
||
|
|
resultString = resultString..'hunger = { '..data.stats.hunger[1]..', '..data.stats.hunger[2]..' }, '
|
||
|
|
end
|
||
|
|
if data.stats.thirst and type(data.stats.thirst) == "table" then
|
||
|
|
resultString = resultString..'thirst = { '..data.stats.thirst[1]..', '..data.stats.thirst[2]..' }, '
|
||
|
|
end
|
||
|
|
if data.stats.screen and data.stats.screen ~= "none" then
|
||
|
|
resultString = resultString..'screen = "'..data.stats.screen..'", '
|
||
|
|
end
|
||
|
|
if data.stats.effect and data.stats.effect ~= "none" then
|
||
|
|
resultString = resultString..'effect = "'..data.stats.effect..'", '
|
||
|
|
resultString = resultString..'time = "'..data.stats.time..'", '
|
||
|
|
resultString = resultString..'amount = "'..data.stats.amount..'", '
|
||
|
|
end
|
||
|
|
if data.stats.widepupils == "true" then
|
||
|
|
resultString = resultString..'widepupils = "'..data.stats.widepupils..'", '
|
||
|
|
end
|
||
|
|
if data.stats.canOD == "true" then
|
||
|
|
resultString = resultString..'canOD = "'..data.stats.canOD..'", '
|
||
|
|
end
|
||
|
|
end
|
||
|
|
triggerNotify(nil, "Copied new consumable info to clipboard", "success")
|
||
|
|
lib.setClipboard(resultString .. " },")
|
||
|
|
end
|
||
|
|
|
||
|
|
RegisterNetEvent("jim-consumables:client:testEmotes", function()
|
||
|
|
local Menu = {}
|
||
|
|
for k, v in pairsByKeys(Emotes) do
|
||
|
|
Menu[#Menu+1] = {
|
||
|
|
header = k,
|
||
|
|
onSelect = function()
|
||
|
|
testEmote(v, k)
|
||
|
|
end
|
||
|
|
}
|
||
|
|
end
|
||
|
|
openMenu(Menu, { header = "Test Consumable Emotes" })
|
||
|
|
end)
|
||
|
|
|
||
|
|
function testEmote(emote, name)
|
||
|
|
triggerNotify(nil, "Testing "..name, "warning")
|
||
|
|
triggerNotify(nil, "Anim will loop twice then return to menu", "warning")
|
||
|
|
local MovementType = nil
|
||
|
|
local Player = PlayerPedId()
|
||
|
|
local InVehicle = IsPedInAnyVehicle(Player, true)
|
||
|
|
|
||
|
|
local animDict, anim = tostring(emote[1]), tostring(emote[2])
|
||
|
|
local model, model2, bone, bone2
|
||
|
|
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(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 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
|
||
|
|
|
||
|
|
playAnim(animDict, anim, (GetAnimDuration(animDict, anim) * 1000 )*2, MovementType)
|
||
|
|
local consuming = true
|
||
|
|
--Prop Spawning
|
||
|
|
CreateThread(function()
|
||
|
|
if model then
|
||
|
|
if IsModelValid(model) == 1 then
|
||
|
|
triggerNotify(nil, "Debug: Spawning consumable prop")
|
||
|
|
attachProp = makeProp({ prop = model, coords = vector4(0.0,0.0,0.0,0.0)}, 1, 1)
|
||
|
|
AttachEntityToEntity(attachProp, Player, bone, P1, P2, P3, P4, P5, P6, true, true, false, true, 1, true)
|
||
|
|
if model2 then
|
||
|
|
triggerNotify(nil, "Debug: Spawning consumable prop 2")
|
||
|
|
if IsModelValid(model2) == 1 then
|
||
|
|
attachProp2 = makeProp({ prop = model2, coords = vector4(0.0,0.0,0.0,0.0)}, 1, 1)
|
||
|
|
AttachEntityToEntity(attachProp2, Player, bone2, P7, P8, P9, P10, P11, P12, true, true, false, true, 1, true)
|
||
|
|
else triggerNotify(nil, "Debug: Second prop model isn't valid", "error") 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 triggerNotify(nil, "Debug: Prop model isn't valid", "error") end
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
Wait((GetAnimDuration(animDict, anim) * 1000)*2)
|
||
|
|
consuming = false
|
||
|
|
stopAnim(animDict, anim)
|
||
|
|
TriggerEvent("jim-consumables:client:testEmotes")
|
||
|
|
end
|