Skip to content

Commit

Permalink
fix(server/inventory): newdrop corrections
Browse files Browse the repository at this point in the history
Should match the behaviour of moving an item to an empty slot.
- Add "action" to the hook payload.
- Validate weight before creating a new drop.
- Clone metadata if splitting a stack.

Additional refactoring to reduce duplicate code and improve structure.
  • Loading branch information
thelindat committed Jun 3, 2023
1 parent aff8ef9 commit a275872
Showing 1 changed file with 38 additions and 21 deletions.
59 changes: 38 additions & 21 deletions modules/inventory/server.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1531,14 +1531,28 @@ end)

local TriggerEventHooks = require 'modules.hooks.server'

local function dropItem(source, data)
local playerInventory = Inventory(source)
---@class SwapSlotData
---@field count number
---@field fromSlot number
---@field toSlot number
---@field instance any
---@field fromType string
---@field toType string
---@field coords? vector3

if not playerInventory then return end
---@param source number
---@param playerInventory OxInventory
---@param fromData SlotWithItem?
---@param data SwapSlotData
local function dropItem(source, playerInventory, fromData, data)
if not fromData then return end

local fromData = playerInventory.items[data.fromSlot]
local toData = table.clone(fromData)
toData.slot = data.toSlot
toData.count = data.count
toData.weight = Inventory.SlotWeight(Items(toData.name), toData)

if not fromData then return end
if toData.weight > shared.playerweight then return end

if not TriggerEventHooks('swapItems', {
source = source,
Expand All @@ -1549,21 +1563,20 @@ local function dropItem(source, data)
toSlot = data.toSlot,
toType = 'drop',
count = data.count,
action = 'move',
}) then return end

if data.count > fromData.count then data.count = fromData.count end

local toData = table.clone(fromData)
toData.slot = data.toSlot
toData.count = data.count
fromData.count -= data.count
fromData.weight = Inventory.SlotWeight(Items(fromData.name), fromData)
toData.weight = Inventory.SlotWeight(Items(toData.name), toData)
fromData.count -= data.count
fromData.weight = Inventory.SlotWeight(Items(fromData.name), fromData)

if fromData.count < 1 then fromData = nil end
if fromData.count < 0 then
fromData = nil
else
toData.metadata = table.clone(toData.metadata)
end

playerInventory.weight -= toData.weight
local slot = data.fromSlot
playerInventory.weight -= toData.weight
playerInventory.items[slot] = fromData

if slot == playerInventory.weapon then
Expand Down Expand Up @@ -1600,13 +1613,11 @@ end

local activeSlots = {}

---@param source number
---@param data SwapSlotData
lib.callback.register('ox_inventory:swapItems', function(source, data)
if data.count < 1 then return end

if data.toType == 'newdrop' then
return dropItem(source, data)
end

local playerInventory = Inventory(source)

if not playerInventory then return end
Expand Down Expand Up @@ -1673,9 +1684,15 @@ lib.callback.register('ox_inventory:swapItems', function(source, data)
}
end

if fromData and (not fromData.metadata.container or fromData.metadata.container and toInventory.type ~= 'container') then
if data.count > fromData.count then data.count = fromData.count end
if data.count > fromData.count then
data.count = fromData.count
end

if data.toType == 'newdrop' then
return dropItem(source, playerInventory, fromData, data)
end

if fromData and (not fromData.metadata.container or fromData.metadata.container and toInventory.type ~= 'container') then
local container, containerItem = (not sameInventory and playerInventory.containerSlot) and (fromInventory.type == 'container' and fromInventory or toInventory)

if container then
Expand Down

0 comments on commit a275872

Please sign in to comment.