mirror of
https://github.com/qbcore-fivem/qb-core.git
synced 2026-09-04 17:23:31 +00:00
Remove inventory code from the core (#784)
* tweak(config): remove inventory code * tweak(client/functions): remove inventory code * cleanup(server/commands): remove inventory command * cleanup(server/events): remove hasitem callback * cleanup(server/functions): remove inventory code * cleanup(server/player): remove inventory code * feat(server/player): QBCore:Player:SetPlayerData server side Removed QBCore:Server:PlayerLoaded for PR that will be merged before me that adds it * feat(server/player): QBCore:Server:OnGangUpdate * fix(shared/items): remove duplicate snowball * fix(server/events): warn for exploitable event * fix(server/functions): startup error * feat(server/player): some backwards compatibility * fix(server/events): warn for exploitable event * feat(server/player): Player.Functions.AddField * feat(server/exports): SetField and AddField * fix(server/player): inventory state check
This commit is contained in:
+3
-1
@@ -171,8 +171,10 @@ RegisterNetEvent('QBCore:Notify', function(text, type, length)
|
|||||||
QBCore.Functions.Notify(text, type, length)
|
QBCore.Functions.Notify(text, type, length)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon.
|
||||||
RegisterNetEvent('QBCore:Client:UseItem', function(item)
|
RegisterNetEvent('QBCore:Client:UseItem', function(item)
|
||||||
TriggerServerEvent('QBCore:Server:UseItem', item)
|
QBCore.Debug(string.format("%s triggered QBCore:Client:UseItem by ID %s with the following data. This event is deprecated due to exploitation, and will be removed soon. Check qb-inventory for the right use on this event.", GetInvokingResource(), source))
|
||||||
|
QBCore.Debug(item)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Callback Events --
|
-- Callback Events --
|
||||||
|
|||||||
+5
-33
@@ -8,38 +8,12 @@ function QBCore.Functions.GetPlayerData(cb)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function QBCore.Functions.GetCoords(entity)
|
function QBCore.Functions.GetCoords(entity)
|
||||||
return vector4(GetEntityCoords(entity), GetEntityHeading(entity))
|
local coords = GetEntityCoords(entity)
|
||||||
|
return vector4(coords.x, coords.y, coords.z, GetEntityHeading(entity))
|
||||||
end
|
end
|
||||||
|
|
||||||
function QBCore.Functions.HasItem(items, amount)
|
function QBCore.Functions.HasItem(items, amount)
|
||||||
local isTable = type(items) == 'table'
|
return exports['qb-inventory']:HasItem(items, amount)
|
||||||
local isArray = isTable and table.type(items) == 'array' or false
|
|
||||||
local totalItems = #items
|
|
||||||
local count = 0
|
|
||||||
local kvIndex = 2
|
|
||||||
if isTable and not isArray then
|
|
||||||
totalItems = 0
|
|
||||||
for _ in pairs(items) do totalItems += 1 end
|
|
||||||
kvIndex = 1
|
|
||||||
end
|
|
||||||
for _, itemData in pairs(QBCore.PlayerData.items) do
|
|
||||||
if isTable then
|
|
||||||
for k, v in pairs(items) do
|
|
||||||
local itemKV = {k, v}
|
|
||||||
if itemData and itemData.name == itemKV[kvIndex] and ((amount and itemData.amount >= amount) or (not isArray and itemData.amount >= v) or (not amount and isArray)) then
|
|
||||||
count += 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if count == totalItems then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
else -- Single item as string
|
|
||||||
if itemData and itemData.name == items and (not amount or (itemData and amount and itemData.amount >= amount)) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Utility
|
-- Utility
|
||||||
@@ -84,8 +58,8 @@ function QBCore.Functions.RequestAnimDict(animDict)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function QBCore.Functions.PlayAnim(animDict, animName, upperbodyOnly, duration)
|
function QBCore.Functions.PlayAnim(animDict, animName, upperbodyOnly, duration)
|
||||||
local flags = upperbodyOnly == true and 16 or 0
|
local flags = upperbodyOnly and 16 or 0
|
||||||
local runTime = duration ~= nil and duration or -1
|
local runTime = duration or -1
|
||||||
QBCore.Functions.RequestAnimDict(animDict)
|
QBCore.Functions.RequestAnimDict(animDict)
|
||||||
TaskPlayAnim(PlayerPedId(), animDict, animName, 8.0, 1.0, runTime, flags, 0.0, false, false, true)
|
TaskPlayAnim(PlayerPedId(), animDict, animName, 8.0, 1.0, runTime, flags, 0.0, false, false, true)
|
||||||
RemoveAnimDict(animDict)
|
RemoveAnimDict(animDict)
|
||||||
@@ -158,8 +132,6 @@ function QBCore.Functions.TriggerCallback(name, cb, ...)
|
|||||||
TriggerServerEvent('QBCore:Server:TriggerCallback', name, ...)
|
TriggerServerEvent('QBCore:Server:TriggerCallback', name, ...)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function QBCore.Functions.Progressbar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
|
function QBCore.Functions.Progressbar(name, label, duration, useWhileDead, canCancel, disableControls, animation, prop, propTwo, onFinish, onCancel)
|
||||||
if GetResourceState('progressbar') ~= 'started' then error('progressbar needs to be started in order for QBCore.Functions.Progressbar to work') end
|
if GetResourceState('progressbar') ~= 'started' then error('progressbar needs to be started in order for QBCore.Functions.Progressbar to work') end
|
||||||
exports['progressbar']:Progress({
|
exports['progressbar']:Progress({
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ QBConfig.Money.PayCheckTimeOut = 10 -- The time in minutes that it will give the
|
|||||||
QBConfig.Money.PayCheckSociety = false -- If true paycheck will come from the society account that the player is employed at, requires qb-management
|
QBConfig.Money.PayCheckSociety = false -- If true paycheck will come from the society account that the player is employed at, requires qb-management
|
||||||
|
|
||||||
QBConfig.Player = {}
|
QBConfig.Player = {}
|
||||||
QBConfig.Player.MaxWeight = 120000 -- Max weight a player can carry (currently 120kg, written in grams)
|
|
||||||
QBConfig.Player.MaxInvSlots = 41 -- Max inventory slots for a player
|
|
||||||
QBConfig.Player.HungerRate = 4.2 -- Rate at which hunger goes down.
|
QBConfig.Player.HungerRate = 4.2 -- Rate at which hunger goes down.
|
||||||
QBConfig.Player.ThirstRate = 3.8 -- Rate at which thirst goes down.
|
QBConfig.Player.ThirstRate = 3.8 -- Rate at which thirst goes down.
|
||||||
QBConfig.Player.Bloodtypes = {
|
QBConfig.Player.Bloodtypes = {
|
||||||
|
|||||||
@@ -235,18 +235,6 @@ QBCore.Commands.Add('setgang', 'Set A Players Gang (Admin Only)', { { name = 'id
|
|||||||
end
|
end
|
||||||
end, 'admin')
|
end, 'admin')
|
||||||
|
|
||||||
-- Inventory (should be in qb-inventory?)
|
|
||||||
|
|
||||||
QBCore.Commands.Add('clearinv', 'Clear Players Inventory (Admin Only)', { { name = 'id', help = 'Player ID' } }, false, function(source, args)
|
|
||||||
local playerId = args[1] ~= '' and args[1] or source
|
|
||||||
local Player = QBCore.Functions.GetPlayer(tonumber(playerId))
|
|
||||||
if Player then
|
|
||||||
Player.Functions.ClearInventory()
|
|
||||||
else
|
|
||||||
TriggerClientEvent('QBCore:Notify', source, Lang:t('error.not_online'), 'error')
|
|
||||||
end
|
|
||||||
end, 'admin')
|
|
||||||
|
|
||||||
-- Out of Character Chat
|
-- Out of Character Chat
|
||||||
|
|
||||||
QBCore.Commands.Add('ooc', 'OOC Chat Message', {}, false, function(source, args)
|
QBCore.Commands.Add('ooc', 'OOC Chat Message', {}, false, function(source, args)
|
||||||
|
|||||||
+3
-39
@@ -167,10 +167,10 @@ end)
|
|||||||
|
|
||||||
-- Items
|
-- Items
|
||||||
|
|
||||||
|
-- This event is exploitable and should not be used. It has been deprecated, and will be removed soon.
|
||||||
RegisterNetEvent('QBCore:Server:UseItem', function(item)
|
RegisterNetEvent('QBCore:Server:UseItem', function(item)
|
||||||
local src = source
|
print(string.format("%s triggered QBCore:Server:UseItem by ID %s with the following data. This event is deprecated due to exploitation, and will be removed soon. Check qb-inventory for the right use on this event.", GetInvokingResource(), source))
|
||||||
if not item or item.amount <= 0 or not QBCore.Functions.CanUseItem(item.name) then return end
|
QBCore.Debug(item)
|
||||||
QBCore.Functions.UseItem(src, item)
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
RegisterNetEvent('QBCore:Server:RemoveItem', function(itemName, amount, slot)
|
RegisterNetEvent('QBCore:Server:RemoveItem', function(itemName, amount, slot)
|
||||||
@@ -206,42 +206,6 @@ RegisterNetEvent('QBCore:CallCommand', function(command, args)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Has Item Callback (can also use client function - QBCore.Functions.HasItem(item))
|
|
||||||
|
|
||||||
QBCore.Functions.CreateCallback('QBCore:HasItem', function(source, cb, items, amount)
|
|
||||||
local retval = false
|
|
||||||
local Player = QBCore.Functions.GetPlayer(source)
|
|
||||||
if not Player then return cb(false) end
|
|
||||||
local isTable = type(items) == 'table'
|
|
||||||
local isArray = isTable and table.type(items) == 'array' or false
|
|
||||||
local totalItems = #items
|
|
||||||
local count = 0
|
|
||||||
local kvIndex = 2
|
|
||||||
if isTable and not isArray then
|
|
||||||
totalItems = 0
|
|
||||||
for _ in pairs(items) do totalItems += 1 end
|
|
||||||
kvIndex = 1
|
|
||||||
end
|
|
||||||
if isTable then
|
|
||||||
for k, v in pairs(items) do
|
|
||||||
local itemKV = {k, v}
|
|
||||||
local item = Player.Functions.GetItemByName(itemKV[kvIndex])
|
|
||||||
if item and ((amount and item.amount >= amount) or (not amount and not isArray and item.amount >= v) or (not amount and isArray)) then
|
|
||||||
count += 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if count == totalItems then
|
|
||||||
retval = true
|
|
||||||
end
|
|
||||||
else -- Single item as string
|
|
||||||
local item = Player.Functions.GetItemByName(items)
|
|
||||||
if item and not amount or (item and amount and item.amount >= amount) then
|
|
||||||
retval = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
cb(retval)
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Use this for player vehicle spawning
|
-- Use this for player vehicle spawning
|
||||||
-- Vehicle server-side spawning callback (netId)
|
-- Vehicle server-side spawning callback (netId)
|
||||||
-- use the netid on the client with the NetworkGetEntityFromNetworkId native
|
-- use the netid on the client with the NetworkGetEntityFromNetworkId native
|
||||||
|
|||||||
@@ -1,3 +1,35 @@
|
|||||||
|
-- Add or change (a) method(s) in the QBCore.Functions table
|
||||||
|
local function SetMethod(methodName, handler)
|
||||||
|
if type(methodName) ~= "string" then
|
||||||
|
return false, "invalid_method_name"
|
||||||
|
end
|
||||||
|
|
||||||
|
QBCore.Functions[methodName] = handler
|
||||||
|
|
||||||
|
TriggerEvent('QBCore:Server:UpdateObject')
|
||||||
|
|
||||||
|
return true, "success"
|
||||||
|
end
|
||||||
|
|
||||||
|
QBCore.Functions.SetMethod = SetMethod
|
||||||
|
exports("SetMethod", SetMethod)
|
||||||
|
|
||||||
|
-- Add or change (a) field(s) in the QBCore table
|
||||||
|
local function SetField(fieldName, data)
|
||||||
|
if type(fieldName) ~= "string" then
|
||||||
|
return false, "invalid_field_name"
|
||||||
|
end
|
||||||
|
|
||||||
|
QBCore[fieldName] = data
|
||||||
|
|
||||||
|
TriggerEvent('QBCore:Server:UpdateObject')
|
||||||
|
|
||||||
|
return true, "success"
|
||||||
|
end
|
||||||
|
|
||||||
|
QBCore.Functions.SetField = SetField
|
||||||
|
exports("SetField", SetField)
|
||||||
|
|
||||||
-- Single add job function which should only be used if you planning on adding a single job
|
-- Single add job function which should only be used if you planning on adding a single job
|
||||||
local function AddJob(jobName, job)
|
local function AddJob(jobName, job)
|
||||||
if type(jobName) ~= "string" then
|
if type(jobName) ~= "string" then
|
||||||
|
|||||||
+18
-33
@@ -253,15 +253,28 @@ end
|
|||||||
-- Items
|
-- Items
|
||||||
|
|
||||||
function QBCore.Functions.CreateUseableItem(item, cb)
|
function QBCore.Functions.CreateUseableItem(item, cb)
|
||||||
QBCore.UseableItems[item] = cb
|
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||||
|
|
||||||
|
if GetResourceState('qb-inventory') ~= 'started' then
|
||||||
|
CreateThread(function()
|
||||||
|
repeat
|
||||||
|
Wait(1000)
|
||||||
|
until GetResourceState('qb-inventory') == 'started'
|
||||||
|
exports['qb-inventory']:CreateUsableItem(item, cb)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
exports['qb-inventory']:CreateUsableItem(item, cb)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function QBCore.Functions.CanUseItem(item)
|
function QBCore.Functions.CanUseItem(item)
|
||||||
return QBCore.UseableItems[item]
|
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||||
|
return exports['qb-inventory']:GetUsableItem(item)
|
||||||
end
|
end
|
||||||
|
|
||||||
function QBCore.Functions.UseItem(source, item)
|
function QBCore.Functions.UseItem(source, item)
|
||||||
QBCore.UseableItems[item.name](source, item)
|
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||||
|
exports['qb-inventory']:UseItem(source, item)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Kick Player
|
-- Kick Player
|
||||||
@@ -402,36 +415,8 @@ end
|
|||||||
-- Utility functions
|
-- Utility functions
|
||||||
|
|
||||||
function QBCore.Functions.HasItem(source, items, amount)
|
function QBCore.Functions.HasItem(source, items, amount)
|
||||||
local Player = QBCore.Functions.GetPlayer(source)
|
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||||
if not Player then return false end
|
return exports['qb-inventory']:HasItem(source, items, amount)
|
||||||
local isTable = type(items) == 'table'
|
|
||||||
local isArray = isTable and table.type(items) == 'array' or false
|
|
||||||
local totalItems = #items
|
|
||||||
local count = 0
|
|
||||||
local kvIndex = 2
|
|
||||||
if isTable and not isArray then
|
|
||||||
totalItems = 0
|
|
||||||
for _ in pairs(items) do totalItems += 1 end
|
|
||||||
kvIndex = 1
|
|
||||||
end
|
|
||||||
if isTable then
|
|
||||||
for k, v in pairs(items) do
|
|
||||||
local itemKV = {k, v}
|
|
||||||
local item = Player.Functions.GetItemByName(itemKV[kvIndex])
|
|
||||||
if item and ((amount and item.amount >= amount) or (not isArray and item.amount >= v) or (not amount and isArray)) then
|
|
||||||
count += 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if count == totalItems then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
else -- Single item as string
|
|
||||||
local item = Player.Functions.GetItemByName(items)
|
|
||||||
if item and (not amount or (item and amount and item.amount >= amount)) then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function QBCore.Functions.Notify(source, text, type, length)
|
function QBCore.Functions.Notify(source, text, type, length)
|
||||||
|
|||||||
+58
-261
@@ -60,7 +60,7 @@ end
|
|||||||
function QBCore.Player.CheckPlayerData(source, PlayerData)
|
function QBCore.Player.CheckPlayerData(source, PlayerData)
|
||||||
PlayerData = PlayerData or {}
|
PlayerData = PlayerData or {}
|
||||||
local Offline = true
|
local Offline = true
|
||||||
if source ~= nil then
|
if source then
|
||||||
PlayerData.source = source
|
PlayerData.source = source
|
||||||
PlayerData.license = PlayerData.license or QBCore.Functions.GetIdentifier(source, 'license')
|
PlayerData.license = PlayerData.license or QBCore.Functions.GetIdentifier(source, 'license')
|
||||||
PlayerData.name = GetPlayerName(source)
|
PlayerData.name = GetPlayerName(source)
|
||||||
@@ -74,6 +74,7 @@ function QBCore.Player.CheckPlayerData(source, PlayerData)
|
|||||||
for moneytype, startamount in pairs(QBCore.Config.Money.MoneyTypes) do
|
for moneytype, startamount in pairs(QBCore.Config.Money.MoneyTypes) do
|
||||||
PlayerData.money[moneytype] = PlayerData.money[moneytype] or startamount
|
PlayerData.money[moneytype] = PlayerData.money[moneytype] or startamount
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Charinfo
|
-- Charinfo
|
||||||
PlayerData.charinfo = PlayerData.charinfo or {}
|
PlayerData.charinfo = PlayerData.charinfo or {}
|
||||||
PlayerData.charinfo.firstname = PlayerData.charinfo.firstname or 'Firstname'
|
PlayerData.charinfo.firstname = PlayerData.charinfo.firstname or 'Firstname'
|
||||||
@@ -158,7 +159,7 @@ function QBCore.Player.CheckPlayerData(source, PlayerData)
|
|||||||
PlayerData.gang.grade.level = PlayerData.gang.grade.level or 0
|
PlayerData.gang.grade.level = PlayerData.gang.grade.level or 0
|
||||||
-- Other
|
-- Other
|
||||||
PlayerData.position = PlayerData.position or QBConfig.DefaultSpawn
|
PlayerData.position = PlayerData.position or QBConfig.DefaultSpawn
|
||||||
PlayerData = QBCore.Player.LoadInventory(PlayerData)
|
PlayerData.items = GetResourceState('qb-inventory') ~= 'missing' and exports['qb-inventory']:LoadInventory(PlayerData.source, PlayerData.citizenid) or {}
|
||||||
return QBCore.Player.CreatePlayer(PlayerData, Offline)
|
return QBCore.Player.CreatePlayer(PlayerData, Offline)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -183,6 +184,7 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
|
|||||||
|
|
||||||
function self.Functions.UpdatePlayerData(dontUpdateChat)
|
function self.Functions.UpdatePlayerData(dontUpdateChat)
|
||||||
if self.Offline then return end -- Unsupported for Offline Players
|
if self.Offline then return end -- Unsupported for Offline Players
|
||||||
|
TriggerEvent('QBCore:Player:SetPlayerData', self.PlayerData)
|
||||||
TriggerClientEvent('QBCore:Player:SetPlayerData', self.PlayerData.source, self.PlayerData)
|
TriggerClientEvent('QBCore:Player:SetPlayerData', self.PlayerData.source, self.PlayerData)
|
||||||
if not dontUpdateChat then
|
if not dontUpdateChat then
|
||||||
QBCore.Commands.Refresh(self.PlayerData.source)
|
QBCore.Commands.Refresh(self.PlayerData.source)
|
||||||
@@ -242,6 +244,7 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
|
|||||||
|
|
||||||
if not self.Offline then
|
if not self.Offline then
|
||||||
self.Functions.UpdatePlayerData()
|
self.Functions.UpdatePlayerData()
|
||||||
|
TriggerEvent('QBCore:Server:OnGangUpdate', self.PlayerData.source, self.PlayerData.gang)
|
||||||
TriggerClientEvent('QBCore:Client:OnGangUpdate', self.PlayerData.source, self.PlayerData.gang)
|
TriggerClientEvent('QBCore:Client:OnGangUpdate', self.PlayerData.source, self.PlayerData.gang)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -347,148 +350,6 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
|
|||||||
return self.PlayerData.money[moneytype]
|
return self.PlayerData.money[moneytype]
|
||||||
end
|
end
|
||||||
|
|
||||||
function self.Functions.AddItem(item, amount, slot, info)
|
|
||||||
local totalWeight = QBCore.Player.GetTotalWeight(self.PlayerData.items)
|
|
||||||
local itemInfo = QBCore.Shared.Items[item:lower()]
|
|
||||||
if not itemInfo and not self.Offline then
|
|
||||||
TriggerClientEvent('QBCore:Notify', self.PlayerData.source, Lang:t('error.item_not_exist'), 'error')
|
|
||||||
return
|
|
||||||
end
|
|
||||||
amount = tonumber(amount)
|
|
||||||
slot = tonumber(slot) or QBCore.Player.GetFirstSlotByItem(self.PlayerData.items, item)
|
|
||||||
if itemInfo['type'] == 'weapon' and not info then
|
|
||||||
info = {
|
|
||||||
serie = tostring(QBCore.Shared.RandomInt(2) .. QBCore.Shared.RandomStr(3) .. QBCore.Shared.RandomInt(1) .. QBCore.Shared.RandomStr(2) .. QBCore.Shared.RandomInt(3) .. QBCore.Shared.RandomStr(4)),
|
|
||||||
}
|
|
||||||
end
|
|
||||||
if (totalWeight + (itemInfo['weight'] * amount)) <= QBCore.Config.Player.MaxWeight then
|
|
||||||
if (slot and self.PlayerData.items[slot]) and (self.PlayerData.items[slot].name:lower() == item:lower()) and (itemInfo['type'] == 'item' and not itemInfo['unique']) then
|
|
||||||
self.PlayerData.items[slot].amount = self.PlayerData.items[slot].amount + amount
|
|
||||||
|
|
||||||
if not self.Offline then
|
|
||||||
self.Functions.UpdatePlayerData()
|
|
||||||
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'AddItem', 'green', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** got item: [slot:' .. slot .. '], itemname: ' .. self.PlayerData.items[slot].name .. ', added amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[slot].amount)
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
elseif not itemInfo['unique'] and slot or slot and self.PlayerData.items[slot] == nil then
|
|
||||||
self.PlayerData.items[slot] = { name = itemInfo['name'], amount = amount, info = info or '', label = itemInfo['label'], description = itemInfo['description'] or '', weight = itemInfo['weight'], type = itemInfo['type'], unique = itemInfo['unique'], useable = itemInfo['useable'], image = itemInfo['image'], shouldClose = itemInfo['shouldClose'], slot = slot, combinable = itemInfo['combinable'] }
|
|
||||||
|
|
||||||
if not self.Offline then
|
|
||||||
self.Functions.UpdatePlayerData()
|
|
||||||
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'AddItem', 'green', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** got item: [slot:' .. slot .. '], itemname: ' .. self.PlayerData.items[slot].name .. ', added amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[slot].amount)
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
elseif itemInfo['unique'] or (not slot or slot == nil) or itemInfo['type'] == 'weapon' then
|
|
||||||
for i = 1, QBConfig.Player.MaxInvSlots, 1 do
|
|
||||||
if self.PlayerData.items[i] == nil then
|
|
||||||
self.PlayerData.items[i] = { name = itemInfo['name'], amount = amount, info = info or '', label = itemInfo['label'], description = itemInfo['description'] or '', weight = itemInfo['weight'], type = itemInfo['type'], unique = itemInfo['unique'], useable = itemInfo['useable'], image = itemInfo['image'], shouldClose = itemInfo['shouldClose'], slot = i, combinable = itemInfo['combinable'] }
|
|
||||||
|
|
||||||
if not self.Offline then
|
|
||||||
self.Functions.UpdatePlayerData()
|
|
||||||
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'AddItem', 'green', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** got item: [slot:' .. i .. '], itemname: ' .. self.PlayerData.items[i].name .. ', added amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[i].amount)
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif not self.Offline then
|
|
||||||
TriggerClientEvent('QBCore:Notify', self.PlayerData.source, Lang:t('error.too_heavy'), 'error')
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function self.Functions.RemoveItem(item, amount, slot)
|
|
||||||
amount = tonumber(amount)
|
|
||||||
slot = tonumber(slot)
|
|
||||||
if slot then
|
|
||||||
if self.PlayerData.items[slot].amount > amount then
|
|
||||||
self.PlayerData.items[slot].amount = self.PlayerData.items[slot].amount - amount
|
|
||||||
|
|
||||||
if not self.Offline then
|
|
||||||
self.Functions.UpdatePlayerData()
|
|
||||||
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** lost item: [slot:' .. slot .. '], itemname: ' .. self.PlayerData.items[slot].name .. ', removed amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[slot].amount)
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
elseif self.PlayerData.items[slot].amount == amount then
|
|
||||||
self.PlayerData.items[slot] = nil
|
|
||||||
|
|
||||||
if not self.Offline then
|
|
||||||
self.Functions.UpdatePlayerData()
|
|
||||||
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** lost item: [slot:' .. slot .. '], itemname: ' .. item .. ', removed amount: ' .. amount .. ', item removed')
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local slots = QBCore.Player.GetSlotsByItem(self.PlayerData.items, item)
|
|
||||||
local amountToRemove = amount
|
|
||||||
if slots then
|
|
||||||
for _, _slot in pairs(slots) do
|
|
||||||
if self.PlayerData.items[_slot].amount > amountToRemove then
|
|
||||||
self.PlayerData.items[_slot].amount = self.PlayerData.items[_slot].amount - amountToRemove
|
|
||||||
|
|
||||||
if not self.Offline then
|
|
||||||
self.Functions.UpdatePlayerData()
|
|
||||||
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** lost item: [slot:' .. _slot .. '], itemname: ' .. self.PlayerData.items[_slot].name .. ', removed amount: ' .. amount .. ', new total amount: ' .. self.PlayerData.items[_slot].amount)
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
elseif self.PlayerData.items[_slot].amount == amountToRemove then
|
|
||||||
self.PlayerData.items[_slot] = nil
|
|
||||||
|
|
||||||
if not self.Offline then
|
|
||||||
self.Functions.UpdatePlayerData()
|
|
||||||
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'RemoveItem', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** lost item: [slot:' .. _slot .. '], itemname: ' .. item .. ', removed amount: ' .. amount .. ', item removed')
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
function self.Functions.SetInventory(items, dontUpdateChat)
|
|
||||||
self.PlayerData.items = items
|
|
||||||
|
|
||||||
if not self.Offline then
|
|
||||||
self.Functions.UpdatePlayerData(dontUpdateChat)
|
|
||||||
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'SetInventory', 'blue', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** items set: ' .. json.encode(items))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function self.Functions.ClearInventory()
|
|
||||||
self.PlayerData.items = {}
|
|
||||||
|
|
||||||
if not self.Offline then
|
|
||||||
self.Functions.UpdatePlayerData()
|
|
||||||
TriggerEvent('qb-log:server:CreateLog', 'playerinventory', 'ClearInventory', 'red', '**' .. GetPlayerName(self.PlayerData.source) .. ' (citizenid: ' .. self.PlayerData.citizenid .. ' | id: ' .. self.PlayerData.source .. ')** inventory cleared')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function self.Functions.GetItemByName(item)
|
|
||||||
item = tostring(item):lower()
|
|
||||||
local slot = QBCore.Player.GetFirstSlotByItem(self.PlayerData.items, item)
|
|
||||||
return self.PlayerData.items[slot]
|
|
||||||
end
|
|
||||||
|
|
||||||
function self.Functions.GetItemsByName(item)
|
|
||||||
item = tostring(item):lower()
|
|
||||||
local items = {}
|
|
||||||
local slots = QBCore.Player.GetSlotsByItem(self.PlayerData.items, item)
|
|
||||||
for _, slot in pairs(slots) do
|
|
||||||
if slot then
|
|
||||||
items[#items+1] = self.PlayerData.items[slot]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return items
|
|
||||||
end
|
|
||||||
|
|
||||||
function self.Functions.SetCreditCard(cardNumber)
|
function self.Functions.SetCreditCard(cardNumber)
|
||||||
self.PlayerData.charinfo.card = cardNumber
|
self.PlayerData.charinfo.card = cardNumber
|
||||||
self.Functions.UpdatePlayerData()
|
self.Functions.UpdatePlayerData()
|
||||||
@@ -496,7 +357,7 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
|
|||||||
|
|
||||||
function self.Functions.GetCardSlot(cardNumber, cardType)
|
function self.Functions.GetCardSlot(cardNumber, cardType)
|
||||||
local item = tostring(cardType):lower()
|
local item = tostring(cardType):lower()
|
||||||
local slots = QBCore.Player.GetSlotsByItem(self.PlayerData.items, item)
|
local slots = exports['qb-inventory']:GetSlotsByItem(self.PlayerData.items, item)
|
||||||
for _, slot in pairs(slots) do
|
for _, slot in pairs(slots) do
|
||||||
if slot then
|
if slot then
|
||||||
if self.PlayerData.items[slot].info.cardNumber == cardNumber then
|
if self.PlayerData.items[slot].info.cardNumber == cardNumber then
|
||||||
@@ -507,15 +368,6 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function self.Functions.GetItemBySlot(slot)
|
|
||||||
slot = tonumber(slot)
|
|
||||||
return self.PlayerData.items[slot]
|
|
||||||
end
|
|
||||||
|
|
||||||
function self.Functions.AddMethod(methodName, handler)
|
|
||||||
self.Functions[methodName] = handler
|
|
||||||
end
|
|
||||||
|
|
||||||
function self.Functions.Save()
|
function self.Functions.Save()
|
||||||
if self.Offline then
|
if self.Offline then
|
||||||
QBCore.Player.SaveOffline(self.PlayerData)
|
QBCore.Player.SaveOffline(self.PlayerData)
|
||||||
@@ -529,6 +381,14 @@ function QBCore.Player.CreatePlayer(PlayerData, Offline)
|
|||||||
QBCore.Player.Logout(self.PlayerData.source)
|
QBCore.Player.Logout(self.PlayerData.source)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function self.Functions.AddMethod(methodName, handler)
|
||||||
|
self.Functions[methodName] = handler
|
||||||
|
end
|
||||||
|
|
||||||
|
function self.Functions.AddField(fieldName, data)
|
||||||
|
self[fieldName] = data
|
||||||
|
end
|
||||||
|
|
||||||
if self.Offline then
|
if self.Offline then
|
||||||
return self
|
return self
|
||||||
else
|
else
|
||||||
@@ -544,8 +404,8 @@ end
|
|||||||
-- Add a new function to the Functions table of the player class
|
-- Add a new function to the Functions table of the player class
|
||||||
-- Use-case:
|
-- Use-case:
|
||||||
--[[
|
--[[
|
||||||
AddEventHandler('QBCore:Server:PlayerLoaded', function(player)
|
AddEventHandler('QBCore:Server:PlayerLoaded', function(Player)
|
||||||
QBCore.Functions.AddPlayerMethod(player.PlayerData.source, "functionName", function(oneArg, orMore)
|
QBCore.Functions.AddPlayerMethod(Player.PlayerData.source, "functionName", function(oneArg, orMore)
|
||||||
-- do something here
|
-- do something here
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
@@ -570,6 +430,33 @@ function QBCore.Functions.AddPlayerMethod(ids, methodName, handler)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Add a new field table of the player class
|
||||||
|
-- Use-case:
|
||||||
|
--[[
|
||||||
|
AddEventHandler('QBCore:Server:PlayerLoaded', function(Player)
|
||||||
|
QBCore.Functions.AddPlayerField(Player.PlayerData.source, "fieldName", "fieldData")
|
||||||
|
end)
|
||||||
|
]]
|
||||||
|
|
||||||
|
function QBCore.Functions.AddPlayerField(ids, fieldName, data)
|
||||||
|
local idType = type(ids)
|
||||||
|
if idType == "number" then
|
||||||
|
if ids == -1 then
|
||||||
|
for _, v in pairs(QBCore.Players) do
|
||||||
|
v.Functions.AddField(fieldName, data)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not QBCore.Players[ids] then return end
|
||||||
|
|
||||||
|
QBCore.Players[ids].Functions.AddField(fieldName, data)
|
||||||
|
end
|
||||||
|
elseif idType == "table" and table.type(ids) == "array" then
|
||||||
|
for i = 1, #ids do
|
||||||
|
QBCore.Functions.AddPlayerField(ids[i], fieldName, data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Save player info to database (make sure citizenid is the primary key in your database)
|
-- Save player info to database (make sure citizenid is the primary key in your database)
|
||||||
|
|
||||||
function QBCore.Player.Save(source)
|
function QBCore.Player.Save(source)
|
||||||
@@ -589,7 +476,7 @@ function QBCore.Player.Save(source)
|
|||||||
position = json.encode(pcoords),
|
position = json.encode(pcoords),
|
||||||
metadata = json.encode(PlayerData.metadata)
|
metadata = json.encode(PlayerData.metadata)
|
||||||
})
|
})
|
||||||
QBCore.Player.SaveInventory(source)
|
if GetResourceState('qb-inventory') ~= 'missing' then exports['qb-inventory']:SaveInventory(source) end
|
||||||
QBCore.ShowSuccess(GetCurrentResourceName(), PlayerData.name .. ' PLAYER SAVED!')
|
QBCore.ShowSuccess(GetCurrentResourceName(), PlayerData.name .. ' PLAYER SAVED!')
|
||||||
else
|
else
|
||||||
QBCore.ShowError(GetCurrentResourceName(), 'ERROR QBCORE.PLAYER.SAVE - PLAYERDATA IS EMPTY!')
|
QBCore.ShowError(GetCurrentResourceName(), 'ERROR QBCORE.PLAYER.SAVE - PLAYERDATA IS EMPTY!')
|
||||||
@@ -610,7 +497,7 @@ function QBCore.Player.SaveOffline(PlayerData)
|
|||||||
position = json.encode(PlayerData.position),
|
position = json.encode(PlayerData.position),
|
||||||
metadata = json.encode(PlayerData.metadata)
|
metadata = json.encode(PlayerData.metadata)
|
||||||
})
|
})
|
||||||
QBCore.Player.SaveOfflineInventory(PlayerData)
|
if GetResourceState('qb-inventory') ~= 'missing' then exports['qb-inventory']:SaveInventory(PlayerData, true) end
|
||||||
QBCore.ShowSuccess(GetCurrentResourceName(), PlayerData.name .. ' OFFLINE PLAYER SAVED!')
|
QBCore.ShowSuccess(GetCurrentResourceName(), PlayerData.name .. ' OFFLINE PLAYER SAVED!')
|
||||||
else
|
else
|
||||||
QBCore.ShowError(GetCurrentResourceName(), 'ERROR QBCORE.PLAYER.SAVEOFFLINE - PLAYERDATA IS EMPTY!')
|
QBCore.ShowError(GetCurrentResourceName(), 'ERROR QBCORE.PLAYER.SAVEOFFLINE - PLAYERDATA IS EMPTY!')
|
||||||
@@ -658,125 +545,35 @@ function QBCore.Player.DeleteCharacter(source, citizenid)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Inventory
|
-- Inventory Backwards Compatibility
|
||||||
|
|
||||||
function QBCore.Player.LoadInventory(PlayerData)
|
|
||||||
PlayerData.items = {}
|
|
||||||
local inventory = MySQL.prepare.await('SELECT inventory FROM players WHERE citizenid = ?', { PlayerData.citizenid })
|
|
||||||
local missingItems = {}
|
|
||||||
if inventory then
|
|
||||||
inventory = json.decode(inventory)
|
|
||||||
if next(inventory) then
|
|
||||||
for _, item in pairs(inventory) do
|
|
||||||
if item then
|
|
||||||
local itemInfo = QBCore.Shared.Items[item.name:lower()]
|
|
||||||
if itemInfo then
|
|
||||||
PlayerData.items[item.slot] = {
|
|
||||||
name = itemInfo['name'],
|
|
||||||
amount = item.amount,
|
|
||||||
info = item.info or '',
|
|
||||||
label = itemInfo['label'],
|
|
||||||
description = itemInfo['description'] or '',
|
|
||||||
weight = itemInfo['weight'],
|
|
||||||
type = itemInfo['type'],
|
|
||||||
unique = itemInfo['unique'],
|
|
||||||
useable = itemInfo['useable'],
|
|
||||||
image = itemInfo['image'],
|
|
||||||
shouldClose = itemInfo['shouldClose'],
|
|
||||||
slot = item.slot,
|
|
||||||
combinable = itemInfo['combinable']
|
|
||||||
}
|
|
||||||
else
|
|
||||||
missingItems[#missingItems+1] = item.name:lower()
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if #missingItems > 0 then
|
|
||||||
print(("%s the following items removed as they no longer exist: %s"):format(GetPlayerName(PlayerData.source), json.encode(missingItems)))
|
|
||||||
end
|
|
||||||
return PlayerData
|
|
||||||
end
|
|
||||||
|
|
||||||
function QBCore.Player.SaveInventory(source)
|
function QBCore.Player.SaveInventory(source)
|
||||||
if not QBCore.Players[source] then return end
|
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||||
local PlayerData = QBCore.Players[source].PlayerData
|
exports['qb-inventory']:SaveInventory(source, false)
|
||||||
local items = PlayerData.items
|
|
||||||
local ItemsJson = {}
|
|
||||||
if items and next(items) then
|
|
||||||
for slot, item in pairs(items) do
|
|
||||||
if items[slot] then
|
|
||||||
ItemsJson[#ItemsJson+1] = {
|
|
||||||
name = item.name,
|
|
||||||
amount = item.amount,
|
|
||||||
info = item.info,
|
|
||||||
type = item.type,
|
|
||||||
slot = slot,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
MySQL.prepare('UPDATE players SET inventory = ? WHERE citizenid = ?', { json.encode(ItemsJson), PlayerData.citizenid })
|
|
||||||
else
|
|
||||||
MySQL.prepare('UPDATE players SET inventory = ? WHERE citizenid = ?', { '[]', PlayerData.citizenid })
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function QBCore.Player.SaveOfflineInventory(PlayerData)
|
function QBCore.Player.SaveOfflineInventory(PlayerData)
|
||||||
local items = PlayerData.items
|
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||||
local ItemsJson = {}
|
exports['qb-inventory']:SaveInventory(PlayerData, true)
|
||||||
if items and next(items) then
|
|
||||||
for slot, item in pairs(items) do
|
|
||||||
if items[slot] then
|
|
||||||
ItemsJson[#ItemsJson+1] = {
|
|
||||||
name = item.name,
|
|
||||||
amount = item.amount,
|
|
||||||
info = item.info,
|
|
||||||
type = item.type,
|
|
||||||
slot = slot,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
MySQL.Async.prepare('UPDATE players SET inventory = ? WHERE citizenid = ?', { json.encode(ItemsJson), PlayerData.citizenid })
|
|
||||||
else
|
|
||||||
MySQL.Async.prepare('UPDATE players SET inventory = ? WHERE citizenid = ?', { '[]', PlayerData.citizenid })
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Util Functions
|
|
||||||
|
|
||||||
function QBCore.Player.GetTotalWeight(items)
|
function QBCore.Player.GetTotalWeight(items)
|
||||||
local weight = 0
|
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||||
if not items then return 0 end
|
return exports['qb-inventory']:GetTotalWeight(items)
|
||||||
for _, item in pairs(items) do
|
|
||||||
weight += item.weight * item.amount
|
|
||||||
end
|
|
||||||
return tonumber(weight)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function QBCore.Player.GetSlotsByItem(items, itemName)
|
function QBCore.Player.GetSlotsByItem(items, itemName)
|
||||||
local slotsFound = {}
|
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||||
if not items then return slotsFound end
|
return exports['qb-inventory']:GetSlotsByItem(items, itemName)
|
||||||
for slot, item in pairs(items) do
|
|
||||||
if item.name:lower() == itemName:lower() then
|
|
||||||
slotsFound[#slotsFound+1] = slot
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return slotsFound
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function QBCore.Player.GetFirstSlotByItem(items, itemName)
|
function QBCore.Player.GetFirstSlotByItem(items, itemName)
|
||||||
if not items then return nil end
|
if GetResourceState('qb-inventory') == 'missing' then return end
|
||||||
for slot, item in pairs(items) do
|
return exports['qb-inventory']:GetFirstSlotByItem(items, itemName)
|
||||||
if item.name:lower() == itemName:lower() then
|
|
||||||
return tonumber(slot)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Util Functions
|
||||||
|
|
||||||
function QBCore.Player.CreateCitizenId()
|
function QBCore.Player.CreateCitizenId()
|
||||||
local UniqueFound = false
|
local UniqueFound = false
|
||||||
local CitizenId = nil
|
local CitizenId = nil
|
||||||
|
|||||||
@@ -386,7 +386,6 @@ QBShared.Items = {
|
|||||||
['moneybag'] = {['name'] = 'moneybag', ['label'] = 'Money Bag', ['weight'] = 0, ['type'] = 'item', ['image'] = 'moneybag.png', ['unique'] = true, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'A bag with cash'},
|
['moneybag'] = {['name'] = 'moneybag', ['label'] = 'Money Bag', ['weight'] = 0, ['type'] = 'item', ['image'] = 'moneybag.png', ['unique'] = true, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'A bag with cash'},
|
||||||
['parachute'] = {['name'] = 'parachute', ['label'] = 'Parachute', ['weight'] = 30000, ['type'] = 'item', ['image'] = 'parachute.png', ['unique'] = true, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'The sky is the limit! Woohoo!'},
|
['parachute'] = {['name'] = 'parachute', ['label'] = 'Parachute', ['weight'] = 30000, ['type'] = 'item', ['image'] = 'parachute.png', ['unique'] = true, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'The sky is the limit! Woohoo!'},
|
||||||
['binoculars'] = {['name'] = 'binoculars', ['label'] = 'Binoculars', ['weight'] = 600, ['type'] = 'item', ['image'] = 'binoculars.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Sneaky Breaky...'},
|
['binoculars'] = {['name'] = 'binoculars', ['label'] = 'Binoculars', ['weight'] = 600, ['type'] = 'item', ['image'] = 'binoculars.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Sneaky Breaky...'},
|
||||||
['snowball'] = {['name'] = 'snowball', ['label'] = 'Snowball', ['weight'] = 0, ['type'] = 'item', ['image'] = 'snowball.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Should have catched it :D'},
|
|
||||||
['lighter'] = {['name'] = 'lighter', ['label'] = 'Lighter', ['weight'] = 0, ['type'] = 'item', ['image'] = 'lighter.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'On new years eve a nice fire to stand next to'},
|
['lighter'] = {['name'] = 'lighter', ['label'] = 'Lighter', ['weight'] = 0, ['type'] = 'item', ['image'] = 'lighter.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'On new years eve a nice fire to stand next to'},
|
||||||
['certificate'] = {['name'] = 'certificate', ['label'] = 'Certificate', ['weight'] = 0, ['type'] = 'item', ['image'] = 'certificate.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Certificate that proves you own certain stuff'},
|
['certificate'] = {['name'] = 'certificate', ['label'] = 'Certificate', ['weight'] = 0, ['type'] = 'item', ['image'] = 'certificate.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Certificate that proves you own certain stuff'},
|
||||||
['markedbills'] = {['name'] = 'markedbills', ['label'] = 'Marked Money', ['weight'] = 1000, ['type'] = 'item', ['image'] = 'markedbills.png', ['unique'] = true, ['useable'] = false, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Money?'},
|
['markedbills'] = {['name'] = 'markedbills', ['label'] = 'Marked Money', ['weight'] = 1000, ['type'] = 'item', ['image'] = 'markedbills.png', ['unique'] = true, ['useable'] = false, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Money?'},
|
||||||
|
|||||||
Reference in New Issue
Block a user