diff options
Diffstat (limited to 'gamemode/shared/inventory.lua')
| -rw-r--r-- | gamemode/shared/inventory.lua | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/gamemode/shared/inventory.lua b/gamemode/shared/inventory.lua new file mode 100644 index 0000000..42f4516 --- /dev/null +++ b/gamemode/shared/inventory.lua @@ -0,0 +1,213 @@ + +print("Hello from inventory.lua!") +local pmeta = FindMetaTable("Player") +local emeta = FindMetaTable("Entity") +local invfuncs = include("inventory_common.lua") + +--A 2d array of the inventory. +pmeta.Inventory = {} + +--each backpack has 1:a tbl containing items or false, 2: a tbl {width,height} and 3:name +pmeta.Inventory.Backpacks = {} +--Eqiped stuff at base, player has 1=Head, 2=Body, 3=Legs, 4=Boots, 5=Gloves, 6=Left Hand, 7=Right Hand +pmeta.Inventory.Equiped = {} +local equipedslots = { + "Head","Body","Legs","Boots","Gloves","Left","Right" +} +for _,v in pairs(equipedslots) do + pmeta.Inventory.Equiped[v] = false +end + +function pmeta:PutInvItem(backpack,x,y,item) + invfuncs.PutItemInBackpack(self.Inventory.Backpacks[backpack],x,y,item) +end + +function pmeta:FindSpotForItem(item) + for n,v in pairs(self.Inventory.Backpacks) do + for row = 1,v[2][2] do + for col = 1,v[2][1] do + if self:CanFitInBackpack(v,row,col,item) then + return row,col,n + end + end + end + end +end + +function pmeta:GiveItem(item) + local x,y,b = self:FindSpotForItem(item) + self:PutInvItem(b,x,y,item) + self:SynchronizeInventory() +end + +function pmeta:CanFitInBackpack(backpack,x,y,item) + return invfuncs.CanFitInBackpack(backpack,x,y,item) +end + +if SERVER then + util.AddNetworkString("synchinventory") + util.AddNetworkString("moveitem") + util.AddNetworkString("equipitem") + util.AddNetworkString("unequipitem") +end + +net.Receive("unequipitem",function(len,ply) + local itemslot = net.ReadString() + local tobackpack = net.ReadUInt(16) + local topos = {} + topos[1] = net.ReadUInt(16) + topos[2] = net.ReadUInt(16) + local item = ply.Inventory.Equiped[itemslot] + if ply:CanFitInBackpack( + ply.Inventory.Backpacks[tobackpack], + topos[1], + topos[2], + item + ) then + ply.Inventory.Equiped[itemslot] = false + ply:PutInvItem(tobackpack,topos[1],topos[2],item) + ply:SynchronizeInventory() + end +end) + +net.Receive("equipitem",function(len,ply) + local backpacknum = net.ReadUInt(16) + local frompos = {} + frompos[1] = net.ReadUInt(16) + frompos[2] = net.ReadUInt(16) + local equippos = net.ReadString() + local item = ply.Inventory.Backpacks[backpacknum][1][frompos[1]][frompos[2]] + if item.Equipable ~= nil and item.Equipable == equippos then + --Remove from the backpack + for k = 1,#item.Shape do + for i = 1,#(item.Shape[k]) do + if k == 1 and i == 1 then continue end + ply.Inventory.Backpacks[backpacknum][1][frompos[1] + k - 1][frompos[2] + i - 1] = false + end + end + ply.Inventory.Backpacks[backpacknum][1][frompos[1]][frompos[2]] = false + ply.Inventory.Equiped[equippos] = item + if item.onEquip ~= nil then + item:onEquip(ply) + end + ply:SynchronizeInventory() + end +end) + +net.Receive("moveitem",function(len,ply) + local froment = net.ReadEntity() + local toent = net.ReadEntity() + + local frombackpack = net.ReadUInt(16) + local tobackpack = net.ReadUInt(16) + + local frompos = {net.ReadUInt(16),net.ReadUInt(16)} + local topos = {net.ReadUInt(16),net.ReadUInt(16)} + + print("Moveing from ",frompos[1],frompos[2],"to",topos[1],topos[2]) + + if froment:IsPlayer() and toent:IsPlayer() and (froment ~= toent) then--Just don't allow stealing between players, anything else is fine + ply:PrintMessage( HUD_PRINTCENTER, "You can't steal from this person!" ) + return + end + print("Passed the stealing check") + local item = froment.Inventory.Backpacks[frombackpack][1][frompos[1]][frompos[2]] + + --Set the shape it was at to false + for k = 1,#item.Shape do + for i = 1,#(item.Shape[k]) do + if k == 1 and i == 1 then continue end + froment.Inventory.Backpacks[frombackpack][1][frompos[1] + k - 1][frompos[2] + i - 1] = false + end + end + froment.Inventory.Backpacks[frombackpack][1][frompos[1]][frompos[2]] = false + print("Set shape to false") + --now check if it can fit in the backpack + if invfuncs.CanFitInBackpack(toent.Inventory.Backpacks[tobackpack],topos[1],topos[2],item) then + print("It can fit there") + invfuncs.PutItemInBackpack(toent.Inventory.Backpacks[tobackpack],topos[1],topos[2],item) + else + invfuncs.PutItemInBackpack(froment.Inventory.Backpacks[frombackpack],frompos[1],frompos[2],item) + end + froment:SynchronizeInventory() + toent:SynchronizeInventory() +end) + +function pmeta:LoadInventory(json) + local reinv = util.JSONToTable(json) + for k,v in pairs(reinv) do + self.Inventory[k] = v + end + self:SynchronizeInventory() +end + +function pmeta:SynchronizeInventory() + print("Player synchronize called") + net.Start("synchinventory") + net.WriteEntity(self) + net.WriteFloat(#self.Inventory.Backpacks) + for k,v in pairs(self.Inventory.Backpacks) do + invfuncs.SerializeBackpack(v) + end + for k,v in pairs(equipedslots) do + if self.Inventory.Equiped and self.Inventory.Equiped[v] ~= false then + net.WriteString(v) + local data = self.Inventory.Equiped[v]:Serialize() + net.WriteString(self.Inventory.Equiped[v].Name) + net.WriteUInt(#data,32) + net.WriteData(data,#data) + end + end + net.WriteString("END_EQUIPED") + net.Send(self) +end +if CLIENT then + net.Receive("synchinventory",function(len,ply) + if LocalPlayer().invdisplays == nil then + LocalPlayer().invdisplays = {} + end + local what = net.ReadEntity() + what.Inventory.Backpacks = {} + local numbackpacks = net.ReadFloat() + for k = 1,numbackpacks do + local tbackpack = invfuncs.DeSerializeBackpack() + table.insert(what.Inventory.Backpacks,tbackpack) + end + local neq = net.ReadString() + local updated_slots = {} + while neq ~= "END_EQUIPED" do + local itemslot = neq + local itemname = net.ReadString() + local itemdata = net.ReadData(net.ReadUInt(32)) + local item = ART.GetItemByName(itemname):DeSerialize(itemdata) + what.Inventory.Equiped[itemslot] = item + updated_slots[itemslot] = true + neq = net.ReadString() + end + if what.Inventory.Equiped ~= nil then + for k,v in pairs(equipedslots) do + if updated_slots[v] then continue end + what.Inventory.Equiped[v] = false + end + end + local discopy = LocalPlayer().invdisplays + LocalPlayer().invdisplays = {} + PrintTable(discopy) + for k,ptbl in pairs(discopy) do + if not ptbl.panel:IsValid() then continue end + if ptbl.panel.Close ~= nil then + ptbl.panel:Close() + else + print(ptbl.panel) + error("panel has no close method") + ptbl.panel:Remove() + end + ptbl.redraw() + end + end) +end + +concommand.Add("artery_showinventory",function(ply,cmd,args) + PrintTable(ply.Inventory) + PrintTable(ply.ClientInventory) +end) |
