diff options
22 files changed, 672 insertions, 176 deletions
@@ -3,7 +3,7 @@ Apickx - Most of artery Built using work from: Code: - FPTje - MySQLite + FTPje - MySQLite TheMaw - Various ideas & item system structure JetBoom - AnimBoneLib (Lua Animation API) CapsAdmin - Pac3 @@ -11,7 +11,7 @@ Built using work from: Art & graphics: opengameart.org user "Emerald" - Art/icons - Massive amounts of icons by: + Massive amounts of icons by game-icons.net users: - Lorc, http://lorcblog.blogspot.com - Delapouite, http://delapouite.com - John Colburn, http://ninmunanmu.com diff --git a/gamemode/client/cl_inventory.lua b/gamemode/client/cl_inventory.lua index 390b923..0e14d50 100644 --- a/gamemode/client/cl_inventory.lua +++ b/gamemode/client/cl_inventory.lua @@ -5,9 +5,11 @@ Reserved inventory id's 1 - Equipment 2 - Prayers + 3 - Skills + 4 - Quests ]] local qinv = nrequire("cl_qinventory.lua") -local qpray = nrequire("cl_qprayers.lua") +--local qpray = nrequire("cl_qprayers.lua") print("Hello from cl_inventory.lua") --debug.Trace() @@ -17,32 +19,15 @@ local prayerequiped = { } net.Receive("equiphelpprayer",function() - print("equiphelp received client side!") - prayerequiped[4] = "Noob Help" + print("equiphelp received client side!") + prayerequiped[4] = "Noob Help" end) local lastpanel = lastpanel or 1 ---A master list of inventory sheets -local inventorysheets = {} - --Wether the player is in the inventory or not local plyisininventory = false ---Displays a dropdown of options under the players mouse, if the option is clicked, does the function ---Requires a table of strings to functions, or strings to tables of strings to functions. ---Be careful not to make this a recursive table. -local function createMenuFor(menu, tbl) - for k,v in pairs(tbl) do - if isfunction(v) then --This is a dead-end, add the menu - local thisoption = menu:AddOption(k,v) - else --Otherwise it should be a table, recursively call to create - local submenu = menu:AddSubMenu(k) - createMenuFor(submenu,v) - end - end -end - local qframe = nil --The master frame local qtabs = {} --The tabs @@ -63,7 +48,7 @@ local function BuildInventory() if not player_data then print("no player data!") return end qframe = vgui.Create("DFrame") qframe:SetPos(0,0) - qframe:SetSize(width/4, height) + qframe:SetSize(width / 4, height) qframe:SetTitle("Inventory") qframe:SetDraggable(true) qframe:MakePopup() @@ -76,16 +61,19 @@ local function BuildInventory() tabsheet:Dock(FILL) local invsheet = qinv.CreateInventorySheet(tabsheet) - local invid = #qtabs + 1 - invsheet.id = invid - qtabs[invid] = invsheet + --qpray.CreatePrayerSheet(tabsheet) + invsheet.id = #qtabs + 1 + qtabs[#qtabs + 1] = invsheet + --prasheet.id = #qtabs + 1 + --qtabs[#qtabs + 1] = prasheet tabsheet:AddSheet("Inventory",invsheet,"icon16/user.png") + --tabsheet:AddSheet("Prayers",prasheet,"icon16/user.png") end local function ShowInventory() print("qframe is ", qframe) - if not qframe then BuildInventory() + if not qframe then BuildInventory() else qframe:Show() end plyisininventory = true end @@ -97,13 +85,13 @@ hook.Add("OnSpawnMenuClose","ArteryCloseInventory",function() plyisininventory = false qframe:Hide() if (not sheet) or (not sheet:GetActiveTab()) or (not sheet:GetActiveTab():GetPanel()) then return end - lastpanel = sheet:GetActiveTab():GetPanel().sheetnum - for k,v in pairs(LocalPlayer().invdisplays) do - if not v.panel:IsValid() then continue end - --PrintTable(v) - v.panel:Close() - LocalPlayer().invdisplays[k] = nil - end + lastpanel = sheet:GetActiveTab():GetPanel().sheetnum + for k,v in pairs(LocalPlayer().invdisplays) do + if not v.panel:IsValid() then continue end + --PrintTable(v) + v.panel:Close() + LocalPlayer().invdisplays[k] = nil + end end) concommand.Add("showinventory",ShowInventory) @@ -112,28 +100,28 @@ local rotatespeed = 65 local bone = nil local previousheadscale = Vector(1,1,1) hook.Add("CalcView","ArteryInventoryView",function(ply,pos,ang,fov,nearz,farz) - if bone == nil then - bone = LocalPlayer():LookupBone("ValveBiped.Bip01_Head1") - end - local view = {} - --view.origin = LocalPlayer():GetBonePosition(bone) + LocalPlayer():GetUp() * 2 - view.origin = pos - if plyisininventory then - local trot = math.rad(CurTime() * rotatespeed) - local xoff = viewdistance * math.sin(trot) - local yoff = viewdistance * math.cos(trot) - view.origin = view.origin + Vector(xoff,yoff,10) - ang.pitch = 20 - ang.yaw = (-CurTime() * rotatespeed) - 90 - end - view.angles = ang - view.fov = fov - if not plyisininventory then - LocalPlayer():ManipulateBoneScale(bone,Vector(0,0,0)) - else - LocalPlayer():ManipulateBoneScale(bone,previousheadscale) - end - view.drawviewer = plyisininventory - - return view + if bone == nil then + bone = LocalPlayer():LookupBone("ValveBiped.Bip01_Head1") + end + local view = {} + --view.origin = LocalPlayer():GetBonePosition(bone) + LocalPlayer():GetUp() * 2 + view.origin = pos + if plyisininventory then + local trot = math.rad(CurTime() * rotatespeed) + local xoff = viewdistance * math.sin(trot) + local yoff = viewdistance * math.cos(trot) + view.origin = view.origin + Vector(xoff,yoff,10) + ang.pitch = 20 + ang.yaw = (-CurTime() * rotatespeed) - 90 + end + view.angles = ang + view.fov = fov + if not plyisininventory then + LocalPlayer():ManipulateBoneScale(bone,Vector(0,0,0)) + else + LocalPlayer():ManipulateBoneScale(bone,previousheadscale) + end + view.drawviewer = plyisininventory + + return view end) diff --git a/gamemode/client/qtabs/cl_qinventory.lua b/gamemode/client/qtabs/cl_qinventory.lua index a3f8a16..e60424f 100644 --- a/gamemode/client/qtabs/cl_qinventory.lua +++ b/gamemode/client/qtabs/cl_qinventory.lua @@ -1,7 +1,6 @@ --[[ One of the tabs in the inventory ]] - local inv = nrequire("inventory/inventory.lua") local itm = nrequire("item.lua") @@ -9,13 +8,41 @@ local q = {} local known_inventories = {} local inventory_frames = {} +local invsheet +local drawsheeton = function(id,inventory) + if invsheet == nil then return end + local tpanel = vgui.Create( "DPanel", invsheet ) + --tpanel.Paint = function( self, w, h ) + -- draw.RoundedBox( 4, 0, 0, w, h, Color( 0, 128, 255 ) ) + --end + if inventory.DrawOnDPanel then + print("Has drawondpanel") + local prox = inventory:DrawOnDPanel(tpanel) + print("Prox returned was",prox) + PrintTable(prox) + known_inventories[id]:AddObserver(prox) + print("Oservers is now") + PrintTable(known_inventories[id].observers) + end + invsheet:AddSheet( inventory.Name, tpanel, "icon16/tab.png" ) +end net.Receive("art_ObserveInventory",function() local id = net.ReadUInt(32) local inv_type = net.ReadString() print("Got inv type", inv_type,"id",id) - local inital_data = net.ReadData(net.ReadUInt(32)) - known_inventories[id] = inv.CreateInventoryFromData(inv_type,initaldata) + local datalen = net.ReadUInt(32) + local inital_data = net.ReadData(datalen) + local ownent = net.ReadEntity() + local tinv = inv.CreateInventoryFromData(inv_type,inital_data) + tinv.owner = ownent + tinv.id = id + print("Created new inventory:") + PrintTable(tinv) + known_inventories[id] = tinv + drawsheeton(id,tinv) + print("known inventories is now:") + PrintTable(known_inventories) end) net.Receive("art_UpdateInventory",function() @@ -24,9 +51,15 @@ net.Receive("art_UpdateInventory",function() local position = net.ReadTable() if isput then local item_name = net.ReadString() + print("Putting ", item_name, "into inventory ",id, " at position") + PrintTable(position) local item_data = net.ReadData(net.ReadUInt(32)) local item = itm.GetItemFromData(item_name,item_data) known_inventories[id]:Put(position,item) + print("Inventorie's observers:") + PrintTable(known_inventories[id].observers) + print("Inventory is now") + PrintTable(known_inventories[id]) else known_inventories[id]:Remove(position) end @@ -41,17 +74,15 @@ net.Receive("art_CloseInventory",function() end end) -local width,height = (ScrW() / 4) - 10, ScrH() -local iconsize = width / 5 - - q.CreateInventorySheet = function(dpanel_parent) --assert(known_inventories[watch_id] ~= nil,"Attempted to watch an inventory that dosn't exist!") --Display the equipment inventories - local invsheet = vgui.Create( "DPropertySheet", dpanel_parent ) + invsheet = vgui.Create( "DPropertySheet", dpanel_parent ) invsheet:Dock( FILL ) for k,v in pairs(known_inventories) do + drawsheeton(k,v) + --[[ local tpanel = vgui.Create( "DPanel", invsheet ) tpanel.Paint = function( self, w, h ) draw.RoundedBox( 4, 0, 0, w, h, Color( 0, 128, 255 ) ) @@ -61,9 +92,14 @@ q.CreateInventorySheet = function(dpanel_parent) known_inventories[k]:AddObserver(prox) end invsheet:AddSheet( v.Name, tpanel, "icon16/tab.png" ) + ]] end return invsheet end +concommand.Add("PrintKnownInventories",function(ply,cmd,args) + PrintTable(known_inventories) +end) + return q diff --git a/gamemode/core/inventory/inventory.lua b/gamemode/core/inventory/inventory.lua index f6e8f9c..47a7eb3 100644 --- a/gamemode/core/inventory/inventory.lua +++ b/gamemode/core/inventory/inventory.lua @@ -19,6 +19,10 @@ The below are automatically made if they do not exist. inv:AddObserver(tbl_other) ::number_id inv:RemoveObserver(number_id) ::nil + ------------------------------------------------------ + These fields should be defined when an inventory is created, before it can be used + inv.Owner ::entity + inv.id ::number The table used for "position" is not defined, and may vary from inventory to inventory, but a single inventory type should only use a single type of position. @@ -49,6 +53,11 @@ end local inventories = {} --Master list local function DefaultAddObserver(self,tbl) + assert(tbl ~= nil,"Cannot add a nil observer!") + for k,v in pairs({"Put","Remove"}) do + assert(tbl[v] ~= nil,"Cannot add an observer without a " .. v .. "! observer was:\n\t" .. table.concat(table.GetKeys(tbl),"\n\t")) + end + if self.observers == nil then self.observers = {} end self.observers[#self.observers + 1] = tbl return #self.observers @@ -65,6 +74,8 @@ local function SetDefaultObservers(tbl) local oldput,oldremove = tbl.Put,tbl.Remove tbl.Put = function(self,position,item) for k,v in pairs(self.observers) do + print("Calling put on observer:") + PrintTable(v) v:Put(position,item) end oldput(self,position,item) @@ -113,12 +124,20 @@ end function inv.CreateInventory(name) print("Createing inventory", name) assert(inventories[name] ~= nil, string.format("Tried to create a copy of inventory that does not exist:%s\nValid inventories are:\n\t%s",name,table.concat(table.GetKeys(inventories),"\n\t"))) - return TableCopy(inventories[name]) + local ret = TableCopy(inventories[name]) + ret.observers = {} + return ret end --Recreates an inventory from data function inv.CreateInventoryFromData(name,data) - return inv.CreateInventory(name):DeSerialize(data) + local tinv = inv.CreateInventory(name) + print("tinv was", tinv) + PrintTable(tinv) + tinv:DeSerialize(data) + print("is now",tinv) + PrintTable(tinv) + return tinv end --Must be called in a coroutine. diff --git a/gamemode/core/inventory/item.lua b/gamemode/core/inventory/item.lua index 86bd105..354472a 100644 --- a/gamemode/core/inventory/item.lua +++ b/gamemode/core/inventory/item.lua @@ -32,11 +32,12 @@ function itm.RegisterItem(tbl) assert(tbl[v] ~= nil, string.format("Attempted to register item without field %q",v)) end assert(items[tbl.Name] == nil, string.format("Attempted to register 2 items with the same name %q",tbl.Name)) + items[tbl.Name] = tbl log.debug("Registered item: " .. tbl.Name .. "\n") end function itm.GetItemByName(name) - assert(items[name] ~= nil,string.format("Attempted to get item with invalid name %q",name)) + assert(items[name] ~= nil,string.format("Attempted to get item with invalid name %q Valid item names are:\n\t%s",name,table.concat(table.GetKeys(items),"\n\t"))) return items[name] end @@ -53,7 +54,7 @@ function itm.DeriveItem(tbl,name) --Create a flywieght copy local ret = tbl local mt = { - __index = function(tbl,key) + __index = function(ntbl,key) return items[name][key] end } diff --git a/gamemode/core/inventory/sv_invtracker.lua b/gamemode/core/inventory/sv_invtracker.lua index 3bb2b37..98e0268 100644 --- a/gamemode/core/inventory/sv_invtracker.lua +++ b/gamemode/core/inventory/sv_invtracker.lua @@ -32,11 +32,16 @@ end) ]] net.Receive("art_RequestInvMove",function(len,ply) print("ply",ply,"requested inv move") + --Read the data from the net message local froment,toent = net.ReadEntity(),net.ReadEntity() local frominvid,toinvid = net.ReadUInt(32),net.ReadUInt(32) local frompos,topos = net.ReadTable(),net.ReadTable() --Make sure the player is not stealing! - assert(not (froment:IsPlayer() and toent:IsPlayer()), "Tried to move item between players!") + assert(not (froment:IsPlayer() and toent:IsPlayer() and froment ~= toent), "Tried to move item between players!") + print("froment",froment) + print("froment.data:",froment.data) + print("froment.data.inventories",froment.data.inventories) + print("invid:",froment.data.inventories[frominvid]) assert(froment.data ~= nil and froment.data.inventories ~= nil and froment.data.inventories[frominvid] ~= nil, "From entity did not have that inventory!") assert(toent.data ~= nil and toent.data.inventories ~= nil and toent.data.inventories[toinvid] ~= nil, "To entity did not have that inventory!") local frominv = froment.data.inventories[frominvid] @@ -46,35 +51,91 @@ net.Receive("art_RequestInvMove",function(len,ply) assert(toinv:CanFitIn(topos,item), "Could not fit the item in that position!") --If we've gotten here without error, we're all good! Move the item! frominv:Remove(frompos) - toinv:Put(topos) + toinv:Put(topos,item) end) -local slots = { - "inv_Head", - "inv_Shoulders", - "inv_Chest", - "inv_Arms", - "inv_Hands", - "inv_Legs", - "inv_Belt", - "inv_Feet", - "inv_Back", -} +local function ClearInventories(ply) + ply.data = {} + ply.data.inventories = {} +end + +--Updates the client side inventory whenever the inventory is updated server side +local function MakeInventoryObserver(ply,invid) + local observer = {} + observer.Put = function(self,pos,item) + print("In observer, item was", item) + PrintTable(item) + local name = item.Name + local data = item:Serialize() + net.Start("art_UpdateInventory") + net.WriteUInt(invid,32) + net.WriteBool(true) + net.WriteTable(pos) + net.WriteString(name) + net.WriteUInt(#data,32) + net.WriteData(data,#data) + net.Send(ply) + end + observer.Remove = function(self,pos) + net.Start("art_UpdateInventory") + net.WriteUInt(invid,32) + net.WriteBool(false) + net.WriteTable(pos) + net.Send(ply) + end + return observer +end + +local function GiveInventoryTo(ply,name) + local i = inv.CreateInventory(name) + i.owner = ply + local nid = #ply.data.inventories + 1 + i.id = nid + local dat = i:Serialize() + local observer = MakeInventoryObserver(ply,nid) + i:AddObserver(observer) + ply.data.inventories[nid] = i -concommand.Add("SendMeData",function(ply,cmd,args) - local i = inv.CreateInventory("Equipment") - if not ply.data then ply.data = {} end - if not ply.data.inventories then ply.data.inventories = {} end - ply.data.inventories[1] = i net.Start("art_ObserveInventory") - net.WriteUInt(1,32) - net.WriteString("Equipment") - local data = i:Serialize() - net.WriteUInt(#data,32) - net.WriteData(data,#data) + net.WriteUInt(nid,32) + net.WriteString(name) + net.WriteUInt(#dat,32) + net.WriteData(dat,#dat) + net.WriteEntity(ply) net.Send(ply) +end +concommand.Add("SendMeData",function(ply,cmd,args) + ClearInventories(ply) + GiveInventoryTo(ply,"Equipment") net.Start("art_load_player_data") net.WriteTable({}) net.Send(ply) end) + +concommand.Add("ShowMyInventories",function(ply,cmd,args) + PrintTable(ply.data.inventories) +end) + +concommand.Add("AddInventory",function(ply,cmd,args) + GiveInventoryTo(ply,args[1]) +end) + +concommand.Add("GiveItem",function(ply,cmd,args) + local itmname = args[1] + local item = itm.GetItemByName(itmname) + local foundplacefor = false + for k,v in pairs(ply.data.inventories) do + print("Trying to find a place in ", v.Name) + local pf = v:FindPlaceFor(item) + print("It returned ", pf) + if pf ~= nil then + v:Put(pf,item) + foundplacefor = true + break + end + end + if not foundplacefor then + print("I couldn't find a place to put it!") + end +end) diff --git a/gamemode/core/npc/cl_npcmap.lua b/gamemode/core/npc/cl_npcmap.lua index 5a9de7e..ea7293e 100644 --- a/gamemode/core/npc/cl_npcmap.lua +++ b/gamemode/core/npc/cl_npcmap.lua @@ -61,6 +61,7 @@ hook.Add("Initialize","loadmapicons",function() end local mapiconstxt = file.Read("artery/client/"..mapname.."/known.txt") + if not mapiconstxt then return end --File does not exist! for k,v in pairs(string.Explode("\r?\n",mapiconstxt,true)) do local isleaf = tobool(v[1]) local ttbl = string.Explode(",",v) diff --git a/gamemode/inventorysystem/cl_common.lua b/gamemode/inventorysystem/cl_common.lua new file mode 100644 index 0000000..07fc786 --- /dev/null +++ b/gamemode/inventorysystem/cl_common.lua @@ -0,0 +1,59 @@ + +local com = {} + +--Displays a dropdown of options under the players mouse, if the option is clicked, does the function +--Requires a table of strings to functions, or strings to tables of strings to functions. +--Be careful not to make this a recursive table. +function com.CreateMenuFor(menu, tbl) + for k,v in pairs(tbl) do + if isfunction(v) then --This is a dead-end, add the menu + menu:AddOption(k,v) + else --Otherwise it should be a table, recursively call to create + local submenu = menu:AddSubMenu(k) + CreateMenuFor(submenu,v) + end + end +end + +function com.generatereceiver() + return function(self,panels,dropped,index,cx,cy) + if dropped then + local froment,toent = panels[1].info.owner,self.info.owner + local fromid,toid = panels[1].info.id,self.info.id + local frompos,topos = panels[1].info.pos,self.info.pos + local frominv,toinv = panels[1].info.inv,self.info.inv + print("Something was dropped on:",x,y) + PrintTable(panels) + print("froment:",froment) + print("toent:",toent) + print("fromid",fromid) + print("toid",toid) + print("frompos:",frompos) + PrintTable(panels[1].info.pos) + print("topos:",topos) + PrintTable(self.info.pos) + print("frominv",frominv) + print("toinv",toinv) + local item = frominv:Get(frompos) + print("item was", item) + --Fake remove the item, in case the position we want to move it to overlaps with where it is now. + frominv:Remove(frompos) + local cf = toinv:CanFitIn(topos,item) + frominv:Put(frompos,item) + print("canfit was:",cf) + if cf == true then + --Send the request + net.Start("art_RequestInvMove") + net.WriteEntity(froment) + net.WriteEntity(toent) + net.WriteUInt(fromid,32) + net.WriteUInt(toid,32) + net.WriteTable(frompos) + net.WriteTable(topos) + net.SendToServer() + end + end + end +end + +return com diff --git a/gamemode/inventorysystem/equipment/cl_equipment.lua b/gamemode/inventorysystem/equipment/cl_equipment.lua index 5ffcccc..7abd27a 100644 --- a/gamemode/inventorysystem/equipment/cl_equipment.lua +++ b/gamemode/inventorysystem/equipment/cl_equipment.lua @@ -1,6 +1,7 @@ local col = nrequire("colortheme.lua") local svg = nrequire("cl_svg.lua") +local com = nrequire("cl_common.lua") local inv = {} local width, height = (ScrW() / 4) - 25, ScrH() @@ -98,20 +99,37 @@ local eqp = { } inv.DrawOnDPanel = function(self,panel) + print("Drawing equipment on panel") local prox = {} for k,v in pairs(eqp) do - local pn = vgui.Create("DImage",panel) + local pn = vgui.Create("DButton",panel) pn:SetSize(iconsize,iconsize) pn:SetPos(v.x,v.y) - if self.equiped[k] then - if self.equiped[k].OnPaint then - pn.Paint = self.equiped[k].OnPaint + pn.info = {} + pn.info.owner = LocalPlayer() + pn.info.id = self.id + pn.info.pos = {k} + pn.info.inv = self + pn:Droppable("item") + pn:Receiver("item",com.generatereceiver(),{"one","two","three"}) + if self.equiped[k] then --We have something equiped! + if self.equiped[k].GetOptions then + pn.DoClick = function() + local dm = DermaMenu() + com.CreateMenuFor(dm,self.equiped[k].GetOptions()) + dm:Open() + end + end + print("Found something equiped in ", k) + if self.equiped[k].OnEqpPaint then + pn.Paint = self.equiped[k].OnEqpPaint else pn.Paint = function(tp,w,h) draw.RoundedBox( 8, 0, 0, w, h, Color( 255, 0, 0 ) ) end end - else + else --We don't have something equiped! + print("Nothing was equiped in ", k) if v.img and v.img.material then local c = col.ui.border pn.Paint = function(tp,w,h) @@ -129,12 +147,42 @@ inv.DrawOnDPanel = function(self,panel) end prox[k] = pn end - prox.Put = function(position,item) - print("Put was called!") + prox.Put = function(self,position,item) + print("Put was called!",position,item) + PrintTable(position) + PrintTable(item) + assert(self[position[1]] ~= nil, "Tried to put an item into an unknown slot!") + if item.GetOptions then + self[position[1]].DoClick = function() + local dm = DermaMenu() + com.CreateMenuFor(dm,item.GetOptions()) + dm:Open() + end + end + if item.OnEqpPaint then + self[position[1]].Paint = item.OnEqpPaint + else + self[position[1]].Paint = function(tp,w,h) + draw.RoundedBox( 8, 0, 0, w, h, Color( 255, 0, 0 ) ) + end + end + self[position[1]]:Droppable("item") end - prox.Remove = function(position) - print("Remove was called!") + prox.Remove = function(self,position) + local pn = self[position[1]] + pn.DoClick = function() end + local c = col.ui.border + pn.Paint = function(self,w,h) + surface.SetDrawColor(c.r,c.g,c.b) + surface.DrawOutlinedRect(0, 0, w, h) + surface.SetDrawColor(255,255,255) + surface.SetMaterial( eqp[position[1]].img.material ) + surface.DrawTexturedRect( 0, 0, w, h ) + end + print("Remove was called!",position) + pn:Droppable("none") end + return prox end return inv diff --git a/gamemode/inventorysystem/equipment/sh_equipment.lua b/gamemode/inventorysystem/equipment/sh_equipment.lua index ca7c22d..3c30df15 100644 --- a/gamemode/inventorysystem/equipment/sh_equipment.lua +++ b/gamemode/inventorysystem/equipment/sh_equipment.lua @@ -64,7 +64,7 @@ inv.FindPlaceFor = function(self, item) end --Otherwise, just check if the slot is empty - if self.equiped[item.Equipable] == nil then + if self.equiped[item.Equipable] == nil and slots[self.equiped] ~= nil then return {item.Equipable} else return nil @@ -77,6 +77,7 @@ end inv.Put = function(self,position,item) self.equiped[position[1]] = item + if item.onEquip then item:onEquip(self.owner) end end inv.Has = function(self,string_or_compare_func) @@ -95,6 +96,8 @@ inv.Has = function(self,string_or_compare_func) end inv.Remove = function(self,position) + local item = self.equiped[position[1]] + if item.onUnEquip then item:onUnEquip(self.owner) end self.equiped[position[1]] = nil end @@ -124,57 +127,3 @@ inv.DeSerialize = function(self,data) end inventory.RegisterInventory(inv) - ---[[ -for k,v in pairs(slots) do - local inv = {} - inv.Name = "inv_" .. v - inv.FindPlaceFor = function(self, item) - if self.item == nil then return {} else return nil end - end - inv.CanFitIn = function(self,position,item) - if self.item == nil then return true else return "Inventory slot occupied by a(n)" .. self.item.Name end - end - inv.Put = function(self,pos,item) - self.item = item - end - inv.Has = function(self,prt) - if type(prt) == "string" then - if self.item ~= nil and self.item.Name == prt then return {} else return nil end - elseif type(prt) == "function" then - if prt(self.item) then return {} else return nil end - end - error(string.format("Passed a %s to %s:Has(), expected string or function",type(prt),self.Name)) - end - inv.Remove = function(self,pos) - self.item = nil - end - inv.Get = function(self,pos) - return self.item - end - inv.Serialize = function(self) - if self.item then - local data = ste.CreateStream() - local itemname = self.item.Name - local itemdata = self.item:Serialize() - data:WriteString(itemname) - data:WriteString(itemdata) - return data:ToString() - end - return "" - end - inv.DeSerialize = function(self,str) - print("data was",str) - if str == "" or str == nil then - return table.Copy(self) - else - local data = ste.CreateStream(str) - local itemname = data:ReadString() - local itemdata = data:ReadString() - self.item = itm.GetItemFromData(itemname,itemdata) - end - end - print("Attempting to register inventory with the name " .. inv.Name) - inventory.RegisterInventory(inv) -end -]] diff --git a/gamemode/inventorysystem/prayers/sh_prayers.lua b/gamemode/inventorysystem/prayers/sh_prayers.lua index 208540d..83414b7 100644 --- a/gamemode/inventorysystem/prayers/sh_prayers.lua +++ b/gamemode/inventorysystem/prayers/sh_prayers.lua @@ -1,5 +1,5 @@ -local reg = nrequire("inventory.lua") +local reg = nrequire("inventory/inventory.lua") local itm = nrequire("item.lua") local inv = {} inv.Name = "Prayers" @@ -27,7 +27,7 @@ function inv:Has(a) end function inv:Remove(pos) for i = 1,pos[1] do - self.track[i] = self.track[i+1] + self.track[i] = self.track[i + 1] end end function inv:Get(pos) @@ -38,6 +38,16 @@ function inv:Serialize() for k,v in pairs(self.track) do ret[v.Name] = v:Serialize() end + return util.TableToJSON(ret) +end + +function inv:DeSerialize(str) + local tbl = util.JSONToTable(str) + local i = 1 + for k,v in pairs(tbl) do + local this_prayer = itm.GetItemByName(k):DeSerialize(v) + self:Put({i},this_prayer) + end end diff --git a/gamemode/inventorysystem/shapedinventory/cl_shaped.lua b/gamemode/inventorysystem/shapedinventory/cl_shaped.lua new file mode 100644 index 0000000..3bd84c2 --- /dev/null +++ b/gamemode/inventorysystem/shapedinventory/cl_shaped.lua @@ -0,0 +1,169 @@ + +local com = nrequire("cl_common.lua") + +local inv = {} + +local width = ScrW() +--local height = ScrH() +local iconsize = width / 40 + +local function default_paint(self,w,h) + draw.RoundedBox( 8, 0, 0, w, h, Color( 0, 0, 0 ) ) +end + +--[[ +local function calcposition(dimx,dimy,x,y) + return (y * dimx) + x +end +]] + +local function shapebounds(shape) + local maxx = 0 + local maxy = 0 + for rn, row in pairs(shape) do + if #row > maxx then maxx = #row end + maxy = rn + end + return maxx, maxy +end + +--Run a function on all the panels in a shape +local function runonshape(self,shape,x,y,func) + for i = 1,#shape do + for j = 1, #shape[i] do + if shape[i][j] then + print("Running on ",i,j) + print("Which translates to", x + j, y + i) + func(self.gridpanels[x + i - 1][y + j - 1]) + end + end + end +end + +--Draw the item in a position +local function drawitemat(self,x,y,item) + print("Drawing item at ",x,y) + local tp = self.gridpanels[x][y] + runonshape(self,item.Shape,x,y,function(panel) + panel:SetVisible(false) + end) + tp:SetVisible(true) + local sx,sy = shapebounds(item.Shape) + tp:SetSize(iconsize * sx, iconsize * sy) + tp.DoClick = function() + if item.GetOptions then + com.CreateMenuFor(tp,item:GetOptions()) + end + end +end + +--Reset the position, using the item and it's shape +local function undrawitemat(self,x,y) + local item = self:Get({x,y}) + runonshape(self,item.Shape,x,y,function(panel) + panel:SetVisible(true) + panel:SetSize(iconsize,iconsize) + panel.Paint = default_paint + panel.DoClick = function() end + end) +end + +--[[ +local function generatereceiver(tinv,x,y) + return function(self,panels,dropped,index,cx,cy) + if dropped then + local froment,toent = panels[1].info.owner,self.info.owner + local fromid,toid = panels[1].info.id,self.info.id + local frompos,topos = panels[1].info.pos,self.info.pos + local frominv,toinv = panels[1].info.inv,self.info.inv + print("Something was dropped on:",x,y) + PrintTable(panels) + print("froment:",froment) + print("toent:",toent) + print("fromid",fromid) + print("toid",toid) + print("frompos:",frompos) + PrintTable(panels[1].info.pos) + print("topos:",topos) + PrintTable(self.info.pos) + print("frominv",frominv) + print("toinv",toinv) + local item = frominv:Get(frompos) + print("item was", item) + --Fake remove the item, in case the position we want to move it to overlaps with where it is now. + frominv:Remove(frompos) + local cf = toinv:CanFitIn(topos,item) + frominv:Put(frompos,item) + print("canfit was:",cf) + if cf == true then + --Send the request + net.Start("art_RequestInvMove") + net.WriteEntity(froment) + net.WriteEntity(toent) + net.WriteUInt(fromid,32) + net.WriteUInt(toid,32) + net.WriteTable(frompos) + net.WriteTable(topos) + net.SendToServer() + end + end + end +end +]] + +inv.DrawOnDPanel = function(self,panel) + print("Drawing shaped on panel") + local DScrollPanel = vgui.Create( "DScrollPanel",panel) + DScrollPanel:SetPos( 0, 0 ) + DScrollPanel:Dock(FILL) + + local grid = vgui.Create( "DGrid", DScrollPanel ) + grid:SetPos(0, 0) + grid:SetCols(self.dimx) + grid:SetColWide(iconsize) + grid:SetRowHeight(iconsize) + self.grid = grid + + self.gridpanels = {} + + --Create the full grid of dpanels + for x = 1, self.dimx do + for y = 1, self.dimy do + local dp = vgui.Create("DButton") + dp:SetSize(iconsize,iconsize) + dp.Paint = default_paint + dp:Droppable("item") + dp:Receiver("item",com.generatereceiver(),{"one","two","three"}) + dp.info = {} + dp.info.owner = LocalPlayer() + dp.info.id = self.id + dp.info.pos = {x,y} + dp.info.inv = self + grid:AddItem(dp) + self.gridpanels[x] = self.gridpanels[x] or {} + self.gridpanels[x][y] = dp + end + end + + --Go through the items, and set the dpanels appropriately. + for k,v in pairs(self.tracker) do + if type(v) == "table" then + local px = k % self.dimx + local py = math.floor(k / self.dimy) + drawitemat(self,px,py,v) + end + end + + local observer = {} + observer.Put = function(obs,position,item) + print("Drawing item at",position[1],position[2]) + drawitemat(self,position[1],position[2],item) + end + observer.Remove = function(obs,position) + print("Undrawing item at",position[1],position[2]) + undrawitemat(self,position[1],position[2]) + end + return observer +end + +return inv diff --git a/gamemode/inventorysystem/shapedinventory/sh_shaped.lua b/gamemode/inventorysystem/shapedinventory/sh_shaped.lua new file mode 100644 index 0000000..de7ccd9 --- /dev/null +++ b/gamemode/inventorysystem/shapedinventory/sh_shaped.lua @@ -0,0 +1,147 @@ +--[[ + An inventory, with a shape! +]] + +local reg = nrequire("inventory/inventory.lua") +local itm = nrequire("item.lua") +local inv = {} +if CLIENT then inv = nrequire("cl_shaped.lua") end + +inv.Name = "Shaped Inventory" +inv.tracker = {} +inv.dimx = 5 +inv.dimy = 5 + +local function calcposition(dimx,dimy,x,y) + return ((x-1) * dimx) + y +end + +local function canfitin(self,x,y,shape) + print("Checking canfitin, tracker was") + PrintTable(self.tracker) + for rn,row in ipairs(shape) do + for cn,col in ipairs(row) do + local absx,absy = x + rn - 1, y + cn - 1 + local slot = calcposition(self.dimx,self.dimy,absx,absy) + print("Checking slot", slot) + if col and ((self.tracker[slot] ~= nil) or (slot > self.dimx * self.dimy)) then + return false + end + end + end + return true +end + +function inv:FindPlaceFor(item) + for x = 1, self.dimx do + for y = 1, self.dimy do + if canfitin(self,x,y,item.Shape) then + return {x,y} + end + end + end + return nil +end + +function inv:CanFitIn(tbl,item) + if canfitin(self,tbl[1],tbl[2],item.Shape) then + print("calculated, and can fit") + return true + else + print("calculated, could not fit") + return "Could not fit :(" + end +end + +function inv:Put(tbl,item) + print("Before putting ", item) + PrintTable(item) + print("tracker was") + PrintTable(self.tracker) + + --Set the item's shape to true + for rn,row in ipairs(item.Shape) do + for cn,col in ipairs(row) do + if col then + local slot = calcposition(self.dimx,self.dimy,tbl[1] + rn - 1,tbl[2] + cn - 1) + self.tracker[slot] = 1 + end + end + end + + --Now set the item in the correct slot + local slot = calcposition(self.dimx,self.dimy,tbl[1],tbl[2]) + self.tracker[slot] = item + print("After, tracker was ") + PrintTable(self.tracker) +end + +function inv:Has(ptr) + local compare_func = ptr + if type(ptr) == "string" then + compare_func = function(t) + return t.Name == ptr + end + end + for k,v in pairs(self.tracker) do + if type(v) == "table" and compare_func(v) then + local x = math.floor(k / self.dimx) + local y = k % self.dimx + return {x,y} + end + end + return nil +end + +function inv:Remove(tbl) + print("Removeing from",tbl[1],tbl[2]) + local slot = calcposition(self.dimx,self.dimy,tbl[1],tbl[2]) + print("Slot is",slot) + print("Tracking structure is:") + PrintTable(self.tracker) + local item = self.tracker[slot] + print("Removeing item",item) + PrintTable(item) + self.tracker[slot] = nil + for rn,row in ipairs(item.Shape) do + for cn,col in ipairs(row) do + if col then + slot = calcposition(self.dimx,self.dimy,tbl[1] + rn - 1,tbl[2] + cn - 1) + self.tracker[slot] = nil + end + end + end + print("After, tracker was") + PrintTable(self.tracker) +end + +function inv:Get(tbl) + local slot = calcposition(self.dimx,self.dimy,tbl[1],tbl[2]) + return self.tracker[slot] +end + +function inv:Serialize() + --Turn it into a sparse table + local ret = {} + for k,v in pairs(self.tracker) do + if type(v) == "table" then + ret[v.Name] = {k,v:Serialize()} + end + end + return util.TableToJSON(ret) +end + +function inv:DeSerialize(str) + print("Deserializeing from ", str) + --TODO:Implement + local tbl = util.JSONToTable(str) + for k,v in pairs(tbl) do + local name = k + local pos = v[1] + local data = v[2] + self.tracker[pos] = itm.GetItemFromData(name,data) + end +end + + +reg.RegisterInventory(inv) diff --git a/gamemode/itemsystem/exampleitem.lua b/gamemode/itemsystem/exampleitem.lua index 066e107..ab7dc50 100644 --- a/gamemode/itemsystem/exampleitem.lua +++ b/gamemode/itemsystem/exampleitem.lua @@ -28,6 +28,17 @@ function item.GetOptions(self) options["toste"] = function() print("You pressed toste!") end return options end +if CLIENT then + local svg = nrequire("cl_svg.lua") + local thismat = svg.MaterialFromSVG("materials/svg/delapouite/originals/svg/000000/transparent/anubis.svg") + function item.OnEqpPaint(panel,w,h) + if thismat.material then + surface.SetDrawColor(255,255,255) + surface.SetMaterial(thismat.material) + surface.DrawTexturedRect( 0, 0, w, h ) + end + end +end --Optional. Something run once when this item is drawn in a backpack function item.DoOnPanel(dimagebutton) @@ -58,7 +69,7 @@ item.Shape = { } --Optional, If this item can be equiped in any player slots, put them here. -item.Equipable = "Right" +item.Equipable = "Right Hand" --Optional, what to do when the player clicks, and this item is in the slot in inventory. only works for items equipable in left and right item.onClick = function(self,owner) @@ -82,4 +93,5 @@ end print("Hello from exampleitem.lua") --Don't forget to register the item! -nrequire("item.lua").RegisterItem(item) +local itm = nrequire("item.lua") +itm.RegisterItem(item) diff --git a/gamemode/nrequire.lua b/gamemode/nrequire.lua index c666332..702790c 100644 --- a/gamemode/nrequire.lua +++ b/gamemode/nrequire.lua @@ -1,5 +1,5 @@ --[[ - A replacement for require + A thing that kinda works like require, or at least, works how I wish require worked. ]] --Don't run ourselves, or we'll get stuck in a recursive loop! if nrequire ~= nil then return end @@ -24,7 +24,7 @@ local function TraverseFolder(dir, func) end --[[ - Creates a funny kind of table. The root points to tables with file names, each file name points to a table containing the folder name it is under. If that folder is under more folders, then the folder table points to more tables in reverse order. The leaf contains the file path. + Creates a funny kind of tree. The root points to tables with file names, each file name points to a table containing the folder name it is under. If that folder is under more folders, then the folder table points to more tables in reverse order. The leaf contains the file path. Ex: { [file.lua] = { @@ -130,7 +130,6 @@ end local pathstack = {} -local incyields = {} --[[ Returns the table returned by executing a file. The table is cached after is is loaded, so calling nrequire() on a file twice will only run it once. ]] @@ -145,7 +144,7 @@ function nrequire(req) assert(v ~= tpath,string.format("Circular dependancy detected:\n\t%s\n\t\t|\n\t\tV\n\t%s",table.concat(pathstack,"\n\t\t|\n\t\tV\n\t"),v)) end local tab_rep = {} - for k=1,#pathstack do tab_rep[k] = "\t" end + for k = 1, #pathstack do tab_rep[k] = "\t" end print(string.format("%sIncluding %q",table.concat(tab_rep),tpath)) pathstack[#pathstack + 1] = tpath reqtbl[tpath] = include(tpath) @@ -178,19 +177,9 @@ local function doincludes() end pathstack = {} end - - while #incyields > 0 do - for k,v in pairs(incyields) do - if coroutine.status(v) == "dead" then - incyields[k] = nil - else - coroutine.resume(v) - end - end - end end -doincludes() +doincludes() --Do it the first time through if SERVER then util.AddNetworkString("art_refresh") end if CLIENT then net.Receive("art_refresh",doincludes) end diff --git a/gamemode/shared/prayersystem/prayers/lesserevasion.lua b/gamemode/shared/prayersystem/prayers/lesserevasion.lua index 7e8a829..15077d3 100644 --- a/gamemode/shared/prayersystem/prayers/lesserevasion.lua +++ b/gamemode/shared/prayersystem/prayers/lesserevasion.lua @@ -1,3 +1,4 @@ +do return end --[[ An example item ]] diff --git a/gamemode/shared/prayersystem/prayers/ninelives.lua b/gamemode/shared/prayersystem/prayers/ninelives.lua index 1f5a4e6..44b3099 100644 --- a/gamemode/shared/prayersystem/prayers/ninelives.lua +++ b/gamemode/shared/prayersystem/prayers/ninelives.lua @@ -1,3 +1,4 @@ +do return end --[[ An example prayer ]] diff --git a/gamemode/shared/prayersystem/prayers/notdarkrp.lua b/gamemode/shared/prayersystem/prayers/notdarkrp.lua index 7820351..426500b 100644 --- a/gamemode/shared/prayersystem/prayers/notdarkrp.lua +++ b/gamemode/shared/prayersystem/prayers/notdarkrp.lua @@ -1,3 +1,4 @@ +do return end --[[ A default prayer given to new players who try to press f4 ]] diff --git a/gamemode/shared/prayersystem/prayers/preditorinstinct.lua b/gamemode/shared/prayersystem/prayers/preditorinstinct.lua index 988904c..e317dd5 100644 --- a/gamemode/shared/prayersystem/prayers/preditorinstinct.lua +++ b/gamemode/shared/prayersystem/prayers/preditorinstinct.lua @@ -1,3 +1,4 @@ +do return end --[[ An example item ]] diff --git a/gamemode/shared/prayersystem/prayers/thickskin.lua b/gamemode/shared/prayersystem/prayers/thickskin.lua index 739a8b9..71f1612 100644 --- a/gamemode/shared/prayersystem/prayers/thickskin.lua +++ b/gamemode/shared/prayersystem/prayers/thickskin.lua @@ -1,3 +1,4 @@ +do return end --[[ An example prayer ]] diff --git a/gamemode/shared/questsystem/examplequest.lua b/gamemode/shared/questsystem/examplequest.lua index 8605ab8..6473044 100644 --- a/gamemode/shared/questsystem/examplequest.lua +++ b/gamemode/shared/questsystem/examplequest.lua @@ -1,3 +1,4 @@ +do return end if SERVER then return end local quest = {} diff --git a/gamemode/shared/questsystem/subterr_generator.lua b/gamemode/shared/questsystem/subterr_generator.lua index 9bb90c3..f946a7a 100644 --- a/gamemode/shared/questsystem/subterr_generator.lua +++ b/gamemode/shared/questsystem/subterr_generator.lua @@ -1,3 +1,4 @@ +do return end if SERVER then return end local quest = {} |
