|
|
|
-- __ _ _______ _ __
|
|
|
|
-- / / /\ | | |__ __| | | \ \
|
|
|
|
-- / / / \ | |_ __ ___ | | ___ ___| |__ \ \
|
|
|
|
-- < < / /\ \ | | '_ ` _ \| |/ _ \/ __| '_ \ > >
|
|
|
|
-- \ \ / ____ \| | | | | | | | __/ (__| | | | / /
|
|
|
|
-- \_\ /_/ \_\_|_| |_| |_|_|\___|\___|_| |_| /_/
|
|
|
|
|
|
|
|
Quantum.Server.Inventory = {}
|
|
|
|
|
|
|
|
Quantum.Inventory.Size = Quantum.Inventory.Width * Quantum.Inventory.Height
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.Create( char )
|
|
|
|
char.inventory = {}
|
|
|
|
char.equipped = {}
|
|
|
|
char.effects = {}
|
|
|
|
|
|
|
|
return char.inventory
|
|
|
|
end
|
|
|
|
|
|
|
|
local function isEquippable( item )
|
|
|
|
return item.equipslot != nil
|
|
|
|
end
|
|
|
|
|
|
|
|
local function isStackable( item )
|
|
|
|
return item.stack || false
|
|
|
|
end
|
|
|
|
|
|
|
|
local function setupWeaponItem( pl, itemTbl, dontSelect )
|
|
|
|
if( itemTbl.equipgive != nil ) then
|
|
|
|
pl:StripAmmo()
|
|
|
|
pl:Give( itemTbl.equipgive, false )
|
|
|
|
if( !dontSelect ) then pl:SelectWeapon( itemTbl.equipgive ) end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function setupEquipedItem( pl, itemTbl )
|
|
|
|
if( itemTbl.equipeffect != nil ) then
|
|
|
|
Quantum.Effect.Give( pl, itemTbl.equipeffect ) -- give the player the effect
|
|
|
|
end
|
|
|
|
setupWeaponItem( pl, itemTbl )
|
|
|
|
end
|
|
|
|
|
|
|
|
local function setupWeaponOnRespawn( pl, char )
|
|
|
|
char = char || Quantum.Server.Char.GetCurrentCharacter( pl )
|
|
|
|
local slotItem = Quantum.Server.Inventory.GetSlotItem( char, char.equipped[Quantum.EquipSlots.Weapon] )
|
|
|
|
if( slotItem != nil ) then
|
|
|
|
local itemTbl = Quantum.Item.Get( slotItem[1] )
|
|
|
|
if( itemTbl != nil ) then
|
|
|
|
setupEquipedItem( pl, itemTbl, true )
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
hook.Add( "PlayerSpawn", "Quantum_Inventory_Equip_GiveWeapon", function( ply )
|
|
|
|
if( ply.isloaded ) then
|
|
|
|
setupWeaponOnRespawn( ply )
|
|
|
|
ply:SelectWeapon( "quantum_hands" )
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.UnEquipItem( pl, equipslot, char )
|
|
|
|
char = char || Quantum.Server.Char.GetCurrentCharacter( pl )
|
|
|
|
|
|
|
|
if( char.equipped[equipslot] != nil ) then
|
|
|
|
local slotItem = Quantum.Server.Inventory.GetSlotItem( char, char.equipped[equipslot] )
|
|
|
|
local itemTbl = Quantum.Item.Get( slotItem[1] )
|
|
|
|
|
|
|
|
if( itemTbl.equipeffect != nil ) then -- remove the items effect
|
|
|
|
Quantum.Effect.Remove( pl, itemTbl.equipeffect )
|
|
|
|
end
|
|
|
|
|
|
|
|
if( itemTbl.equipgive != nil ) then
|
|
|
|
pl:StripWeapon( itemTbl.equipgive )
|
|
|
|
pl:SelectWeapon( "quantum_hands" )
|
|
|
|
end
|
|
|
|
Quantum.Debug( tostring(pl) .. " unequipped item (" .. tostring( itemTbl.id ) .. ") - (" .. tostring( char.equipped[equipslot] ) .. ")" )
|
|
|
|
char.equipped[equipslot] = nil
|
|
|
|
|
|
|
|
Quantum.Net.Inventory.SetEquipItem( pl, -1, equipslot )
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.EquipItem( pl, itemindex )
|
|
|
|
local char = Quantum.Server.Char.GetCurrentCharacter( pl )
|
|
|
|
local slotitem = Quantum.Server.Inventory.GetSlotItem( char, itemindex )
|
|
|
|
local itemTbl = Quantum.Item.Get( slotitem[1] )
|
|
|
|
|
|
|
|
if( itemTbl != nil ) then
|
|
|
|
local equipslot = itemTbl.equipslot
|
|
|
|
|
|
|
|
if( equipslot == nil ) then
|
|
|
|
Quantum.Error( tostring(pl) .. " tried to equip an non-equippable item: (" .. tostring(itemTbl[1]) .. ")" )
|
|
|
|
return
|
|
|
|
else
|
|
|
|
local equipslotKey = table.KeyFromValue( Quantum.EquipSlots, equipslot )
|
|
|
|
if( equipslotKey != nil ) then
|
|
|
|
|
|
|
|
Quantum.Server.Inventory.UnEquipItem( pl, equipslot, char ) -- unequip the slot first
|
|
|
|
char.equipped[equipslot] = itemindex -- set it in the table
|
|
|
|
setupEquipedItem( pl, itemTbl ) -- setup the player
|
|
|
|
|
|
|
|
Quantum.Debug( tostring(pl) .. " equipped item (" .. tostring(slotitem[1]) .. ") - (" .. tostring(itemindex) .. ")" )
|
|
|
|
-- NETWORKING --
|
|
|
|
Quantum.Net.Inventory.SetEquipItem( pl, itemindex, equipslot )
|
|
|
|
|
|
|
|
else
|
|
|
|
Quantum.Error( tostring(pl) .. " tried to equip an item in a non-existent equip slot: (" .. tostring(equipslot) .. ")" )
|
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.GetEquippedItems( pl, char )
|
|
|
|
char = char || Quantum.Server.Char.GetCurrentCharacter( pl )
|
|
|
|
local returnTbl = {}
|
|
|
|
|
|
|
|
for equipType, equipSlot in pairs( char.equipped ) do
|
|
|
|
returnTbl[ #returnTbl + 1 ] = { type = equipType, slot = equipSlot }
|
|
|
|
end
|
|
|
|
|
|
|
|
return returnTbl
|
|
|
|
end
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.SetSlotItem( pl, char, pos, itemid, amount )
|
|
|
|
local setItemTbl = {}
|
|
|
|
if( amount < 1 ) then
|
|
|
|
local equippedItems = Quantum.Server.Inventory.GetEquippedItems( pl, char )
|
|
|
|
for ei, slotTbl in pairs( equippedItems ) do
|
|
|
|
if( slotTbl.slot == pos ) then
|
|
|
|
Quantum.Server.Inventory.UnEquipItem( pl, slotTbl.type ) -- unequipp the item if it was removed
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
setItemTbl = nil
|
|
|
|
else
|
|
|
|
local item = Quantum.Item.Get( itemid )
|
|
|
|
if( isEquippable( item ) || !isStackable( item ) ) then
|
|
|
|
amount = 1
|
|
|
|
setItemTbl = { itemid, amount }
|
|
|
|
else
|
|
|
|
amount = amount || 1
|
|
|
|
setItemTbl = { itemid, amount }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
char.inventory[pos] = setItemTbl -- remove the item
|
|
|
|
-- Sent the new data to the client
|
|
|
|
amount = amount || 1
|
|
|
|
Quantum.Net.Inventory.SetItem( pl, pos, itemid, amount )
|
|
|
|
end
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.RemoveSlotItem( pl, char, pos, amount )
|
|
|
|
local slotItem = Quantum.Server.Inventory.GetSlotItem( char, pos )
|
|
|
|
local itemid = slotItem[1]
|
|
|
|
|
|
|
|
if( slotItem == nil ) then return end
|
|
|
|
|
|
|
|
if( amount <= 0 ) then
|
|
|
|
Quantum.Server.Inventory.SetSlotItem( pl, char, pos, itemid, 0 )
|
|
|
|
return 0
|
|
|
|
else
|
|
|
|
local am_diff = slotItem[2] - amount
|
|
|
|
if( am_diff <= 0 ) then
|
|
|
|
Quantum.Server.Inventory.SetSlotItem( pl, char, pos, itemid, 0 )
|
|
|
|
return 0
|
|
|
|
else
|
|
|
|
Quantum.Server.Inventory.SetSlotItem( pl, char, pos, itemid, am_diff )
|
|
|
|
return am_diff
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.GetSlotItem( char, pos ) return char.inventory[pos] end
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.FindStackable( char, item )
|
|
|
|
if( item.stack ) then
|
|
|
|
local inv = Quantum.Server.Char.GetInventory( char )
|
|
|
|
local itemInSlotAmount
|
|
|
|
for i, item2 in pairs( inv ) do
|
|
|
|
itemInSlotAmount = item2[2] || 1
|
|
|
|
if( item2[1] == item.id && itemInSlotAmount < item.stack ) then -- if the item is stackable and it is the same item
|
|
|
|
return i -- return its index
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.GetItemAmount( char, itemid, inv )
|
|
|
|
inv = inv || Quantum.Server.Char.GetInventory( char )
|
|
|
|
local amount = 0
|
|
|
|
|
|
|
|
for pos, item in pairs( inv ) do
|
|
|
|
if( item[1] == itemid && item[2] != nil ) then
|
|
|
|
if( item[2] > 0 ) then
|
|
|
|
amount = amount + item[2]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return amount
|
|
|
|
end
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.FindItemSpot( char )
|
|
|
|
local inv = Quantum.Server.Char.GetInventory( char )
|
|
|
|
local pos = 0
|
|
|
|
|
|
|
|
local item
|
|
|
|
for ii = 1, Quantum.Inventory.Width * Quantum.Inventory.Height, 1 do
|
|
|
|
item = inv[ii]
|
|
|
|
if( item == nil ) then
|
|
|
|
pos = ii
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return pos
|
|
|
|
end
|
|
|
|
|
|
|
|
local function getStackSize( char, item )
|
|
|
|
return item.stack || 1
|
|
|
|
end
|
|
|
|
|
|
|
|
local function sortItem( pl, char, itemid, amount )
|
|
|
|
|
|
|
|
-- Quantum.Debug( "--Stacking Debug--" )
|
|
|
|
|
|
|
|
local item = Quantum.Item.Get( itemid )
|
|
|
|
local slotitem = Quantum.Server.Inventory.GetSlotItem( char, index )
|
|
|
|
local inv = Quantum.Server.Char.GetInventory( char )
|
|
|
|
|
|
|
|
local stacksize = getStackSize( char, item )
|
|
|
|
|
|
|
|
local index = Quantum.Server.Inventory.FindStackable( char, item ) || #inv + 1
|
|
|
|
|
|
|
|
local rest = amount
|
|
|
|
if( slotitem != nil ) then rest = rest + slotitem[2] end
|
|
|
|
|
|
|
|
local count = 0
|
|
|
|
|
|
|
|
local itemInSlot = Quantum.Server.Inventory.GetSlotItem( char, index )
|
|
|
|
|
|
|
|
if( itemInSlot != nil ) then
|
|
|
|
if( itemInSlot[1] == itemid && itemInSlot[2] < stacksize ) then
|
|
|
|
|
|
|
|
local add = itemInSlot[2] + amount
|
|
|
|
if( add > stacksize ) then
|
|
|
|
rest = rest - ( stacksize - itemInSlot[2] )
|
|
|
|
else
|
|
|
|
rest = rest - amount
|
|
|
|
end
|
|
|
|
local setAmt = math.Clamp( add, 1, stacksize )
|
|
|
|
Quantum.Server.Inventory.SetSlotItem( pl, char, index, itemid, setAmt )
|
|
|
|
|
|
|
|
--print( "1", itemid, setAmt, rest, index )
|
|
|
|
|
|
|
|
end
|
|
|
|
else
|
|
|
|
local setAmt = math.Clamp( amount, 1, stacksize )
|
|
|
|
local pos = Quantum.Server.Inventory.FindItemSpot( char )
|
|
|
|
rest = rest - setAmt
|
|
|
|
Quantum.Server.Inventory.SetSlotItem( pl, char, pos, itemid, setAmt )
|
|
|
|
|
|
|
|
--print( "2", itemid, setAmt, rest, pos )
|
|
|
|
end
|
|
|
|
|
|
|
|
while( rest >= stacksize ) do
|
|
|
|
count = count + 1
|
|
|
|
|
|
|
|
if( count == 1 ) then
|
|
|
|
local setAmt = math.Clamp( amount, 1, stacksize )
|
|
|
|
|
|
|
|
if( itemInSlot != nil ) then
|
|
|
|
setAmt = math.Clamp( itemInSlot[2] + amount, 1, stacksize )
|
|
|
|
end
|
|
|
|
|
|
|
|
rest = rest - setAmt
|
|
|
|
|
|
|
|
local pos = Quantum.Server.Inventory.FindItemSpot( char )
|
|
|
|
Quantum.Server.Inventory.SetSlotItem( pl, char, pos, itemid, setAmt )
|
|
|
|
--print( "3", itemid, setAmt, rest, pos )
|
|
|
|
else
|
|
|
|
index = index + 1
|
|
|
|
itemInSlot = Quantum.Server.Inventory.GetSlotItem( char, index )
|
|
|
|
|
|
|
|
if( itemInSlot != nil ) then
|
|
|
|
if( itemInSlot[1] == itemid && itemInSlot[2] < stacksize ) then
|
|
|
|
rest = rest - ( stacksize - itemInSlot[2] )
|
|
|
|
Quantum.Server.Inventory.SetSlotItem( pl, char, index, itemid, stacksize )
|
|
|
|
|
|
|
|
--print( "4", itemid, stacksize, rest, index )
|
|
|
|
|
|
|
|
if( rest <= 0 ) then
|
|
|
|
rest = 0
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
else
|
|
|
|
rest = rest - stacksize
|
|
|
|
Quantum.Server.Inventory.SetSlotItem( pl, char, index, itemid, stacksize )
|
|
|
|
--print( "5", itemid, stacksize, rest, index )
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local stackIndex = Quantum.Server.Inventory.FindStackable( char, item )
|
|
|
|
--print( "stackIndex=", stackIndex )
|
|
|
|
local pos
|
|
|
|
if( stackIndex == nil ) then
|
|
|
|
pos = Quantum.Server.Inventory.FindItemSpot( char )
|
|
|
|
Quantum.Server.Inventory.SetSlotItem( pl, char, pos, itemid, rest )
|
|
|
|
--print( "6", itemid, rest, rest, pos )
|
|
|
|
else
|
|
|
|
if( rest > 0 ) then
|
|
|
|
pos = stackIndex
|
|
|
|
itemInSlot = Quantum.Server.Inventory.GetSlotItem( char, pos )
|
|
|
|
|
|
|
|
local setAmt = math.Clamp( itemInSlot[2] + rest, 1, stacksize )
|
|
|
|
local diff = ( itemInSlot[2] + rest ) - setAmt
|
|
|
|
rest = rest - diff
|
|
|
|
|
|
|
|
if( rest <= 0 ) then
|
|
|
|
Quantum.Server.Inventory.SetSlotItem( pl, char, pos, itemid, setAmt )
|
|
|
|
--print( "7", itemid, setAmt, rest, pos )
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
-- Quantum.Debug( "--End of Stacking Debug--" )
|
|
|
|
end
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.GiveItem( pl, itemid, amount ) -- Quantum.Server.Inventory.GiveItem( Entity(1), "test2", 21 )
|
|
|
|
local char = Quantum.Server.Char.GetCurrentCharacter( pl ) -- Quantum.Server.Inventory.GiveItem( Entity(1), "test", 1 )
|
|
|
|
local inv = Quantum.Server.Char.GetInventory( char )
|
|
|
|
local item = Quantum.Item.Get( itemid )
|
|
|
|
|
|
|
|
if( item == nil ) then Quantum.Error( "Tried to give " .. tostring(pl) .. " a non-existent item! Item '" .. tostring(itemid) .. "' does not exist." ) return end
|
|
|
|
|
|
|
|
if( #inv + 1 <= Quantum.Inventory.Size || Quantum.Server.Inventory.FindStackable( char, item ) != nil ) then
|
|
|
|
sortItem( pl, char, itemid, amount )
|
|
|
|
else
|
|
|
|
Quantum.Debug( "Tried to give " .. tostring(pl) .. " a item but their inventory is full!" )
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.DropItem( pl, index, amount ) -- Quantum.Server.Inventory.DropItem( Entity(1), 1, 9 )
|
|
|
|
local char = Quantum.Server.Char.GetCurrentCharacter( pl ) -- Quantum.Server.Inventory.DropItem( Entity(1), 4, 1 )
|
|
|
|
local inv = Quantum.Server.Char.GetInventory( char )
|
|
|
|
|
|
|
|
if( inv[index] != nil ) then
|
|
|
|
local itemid = inv[index][1]
|
|
|
|
|
|
|
|
local item = Quantum.Item.Get( itemid )
|
|
|
|
|
|
|
|
if( item.soulbound == true ) then
|
|
|
|
Quantum.Notify.Deny( pl, "You can not drop that item!" )
|
|
|
|
return
|
|
|
|
end -- players cant drop soulbound items
|
|
|
|
|
|
|
|
local am_diff = inv[index][2] - amount
|
|
|
|
|
|
|
|
if( am_diff >= 0 ) then -- drop the item from the players inv
|
|
|
|
-- remove the items am_diff from its stack
|
|
|
|
--Quantum.Server.Inventory.SetSlotItem( pl, char, index, itemid, am_diff )
|
|
|
|
Quantum.Server.Inventory.RemoveSlotItem( pl, char, index, amount )
|
|
|
|
|
|
|
|
-- spawn the item infront of the player
|
|
|
|
Quantum.Server.Item.SpawnItemAtPlayer( pl, itemid, amount )
|
|
|
|
end
|
|
|
|
else
|
|
|
|
Quantum.Error( "Player " .. Quantum.PrintPlayer( pl ) .. " tried to drop a something from index=" .. tostring(index) .. " where there exists no item." )
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.UseItem( pl, index )
|
|
|
|
local char = Quantum.Server.Char.GetCurrentCharacter( pl )
|
|
|
|
local inv = Quantum.Server.Char.GetInventory( char )
|
|
|
|
|
|
|
|
local item = inv[index]
|
|
|
|
|
|
|
|
if( item != nil || #item > 0 ) then
|
|
|
|
local itemTbl = Quantum.Item.Get( item[1] )
|
|
|
|
if( itemTbl.useeffect != nil ) then
|
|
|
|
Quantum.Server.Inventory.RemoveSlotItem( pl, char, index, 1 )
|
|
|
|
Quantum.Effect.Give( pl, itemTbl.useeffect ) -- call the function
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.EatItem( pl, index )
|
|
|
|
local char = Quantum.Server.Char.GetCurrentCharacter( pl )
|
|
|
|
local inv = Quantum.Server.Char.GetInventory( char )
|
|
|
|
|
|
|
|
local item = inv[index]
|
|
|
|
|
|
|
|
if( item != nil || #item > 0 ) then
|
|
|
|
local itemTbl = Quantum.Item.Get( item[1] )
|
|
|
|
if( itemTbl.consumeeffect != nil ) then
|
|
|
|
Quantum.Server.Inventory.RemoveSlotItem( pl, char, index, 1 )
|
|
|
|
Quantum.Effect.Give( pl, itemTbl.consumeeffect )
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function Quantum.Server.Inventory.FindItemSlots( pl, itemid, inv )
|
|
|
|
local char = Quantum.Server.Char.GetCurrentCharacter( pl )
|
|
|
|
inv = inv || Quantum.Server.Char.GetInventory( char )
|
|
|
|
|
|
|
|
local indexes = {}
|
|
|
|
|
|
|
|
for i, item in pairs( inv ) do
|
|
|
|
if( item != nil ) then
|
|
|
|
if( item[1] == itemid ) then
|
|
|
|
indexes[ #indexes + 1 ] = i
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return indexes
|
|
|
|
end
|