From 3975ebf158698a1bafd073c91aeb96a259c4c125 Mon Sep 17 00:00:00 2001 From: Fesiug Date: Tue, 8 Oct 2024 20:46:36 -0400 Subject: [PATCH] new Inventory system --- .../benny/entities/entities/inventory.lua | 159 +++++++++++++ .../benny/entities/weapons/itemhandler.lua | 64 +++--- gamemodes/benny/gamemode/debugmenu.lua | 4 +- gamemodes/benny/gamemode/hud.lua | 212 +++++++++++------ gamemodes/benny/gamemode/inventory.lua | 214 ++++-------------- gamemodes/benny/gamemode/items.lua | 16 ++ gamemodes/benny/gamemode/items/base.lua | 21 ++ gamemodes/benny/gamemode/items/firearms.lua | 91 +++++++- gamemodes/benny/gamemode/player.lua | 2 + gamemodes/benny/gamemode/player_class.lua | 1 + 10 files changed, 517 insertions(+), 267 deletions(-) create mode 100644 gamemodes/benny/entities/entities/inventory.lua diff --git a/gamemodes/benny/entities/entities/inventory.lua b/gamemodes/benny/entities/entities/inventory.lua new file mode 100644 index 0000000..800a09b --- /dev/null +++ b/gamemodes/benny/entities/entities/inventory.lua @@ -0,0 +1,159 @@ + +AddCSLuaFile() + +ENT.Type = "point" + +function ENT:SetupDataTables() + for i=1, 32 do + self:NetworkVar("Entity", i-1, "Item" .. i ) + end + self:NetworkVar( "Int", "ReservedSlots" ) +end + +function ENT:Initialize() + self:AddEFlags( EFL_FORCE_CHECK_TRANSMIT ) + self:SetTransmitWithParent( true ) -- Transmit only when the owner does +end + +function ENT:Think() + if !self:GetOwner():IsValid() then + self:Print("existing without an owner." ) + end +end + +function ENT:Print( ... ) + print( "[Inventory[" .. self:EntIndex() .. "], " .. tostring(self:GetOwner()) .. "]", ...) +end + +function ENT:UpdateTransmitState() + return TRANSMIT_ALWAYS +end + +function ENT:ReevalRecreate() + self:RemoveEFlags( EFL_KEEP_ON_RECREATE_ENTITIES ) + if self:GetOwner():IsValid() then + if self:GetOwner():IsEFlagSet( EFL_KEEP_ON_RECREATE_ENTITIES ) then + self:AddEFlags( EFL_KEEP_ON_RECREATE_ENTITIES ) + self:Print("To be saved during recreate.") + return + else + self:Print("Will NOT be saved during recreate.") + return + end + end + self:Print("Will NOT be saved during recreate. No owner either") + return +end + +function ENT:AttachToEntity( ent ) + if ent.SetInventory then + ent:SetInventory( self ) + else + error( "[Inventory " .. tostring(self) .. "] " .. tostring(ent) .. " doesn't have a SetInventory function. Not attaching.") + return + end + + self:SetOwner( ent ) + self:SetParent( ent ) + self:SetPos( vector_origin ) + self:SetAngles( angle_zero ) + self:ReevalRecreate() + self:Print("Attached to: " .. tostring(ent)) +end + +function ENT:GetItems() + local itemlist = {} + + for i=1, 32 do + local curr = self["GetItem"..i](self) + if curr == NULL then continue end + table.insert( itemlist, curr ) + end + + return itemlist +end + +function ENT:GetWeighted() + local itemlist = {} + + for i, v in pairs(self:GetItems()) do + if i == 0 then continue end + table.insert( itemlist, v ) + end + + table.sort( itemlist, function( a, b ) + return a:GetAcquisition() < b:GetAcquisition() + end) + + return itemlist +end + +function ENT:AddItem( ent ) + if !ent:IsValid() then + self:Print("Invalid entity, printing trace" ) + debug.Trace() + return false + end + + for i=1+self:GetReservedSlots(), 32 do + local curr = self["GetItem"..i](self) + if curr == NULL then continue end + if curr == ent then self:Print("We already own this entity " .. tostring(ent) ) return false end + end + + for i=1+self:GetReservedSlots(), 32 do + local curr = self["GetItem"..i](self) + if curr == NULL then + self["SetItem"..i](self, ent) + ent:SetParent( self:GetOwner() ) + ent:SetOwner( self:GetOwner() ) + self:ReevalRecreate() -- Why do I have to do this. + if ent.GetInventory then ent:GetInventory():ReevalRecreate() end + return true + end + end + + self:Print("Inventory full, can't fit " .. tostring(ent) ) + return false +end + +function ENT:RemoveItem( ent ) + if !ent:IsValid() then + self:Print("Invalid entity, printing trace" ) + debug.Trace() + return false + end + + for i=1+self:GetReservedSlots(), 32 do + local curr = self["GetItem"..i](self) + if curr == ent then + self["SetItem"..i](self, NULL) + ent:SetParent( NULL ) + ent:SetOwner( NULL ) + self:ReevalRecreate() -- Why do I have to do this. + if ent.GetInventory then ent:GetInventory():ReevalRecreate() end + return true + end + end + + self:Print("Couldn't remove " .. tostring(ent) .. " from inventory." ) + return false +end + +function ENT:GetItem( ent ) + if !ent:IsValid() then + self:Print("Invalid entity, printing trace" ) + debug.Trace() + return false + end + + for i=1+self:GetReservedSlots(), 32 do + local curr = self["GetItem"..i](self) + if curr == ent then + return curr, i + end + end + + self:Print("Couldn't find " .. tostring(ent) .. " in inventory." ) + return false +end \ No newline at end of file diff --git a/gamemodes/benny/entities/weapons/itemhandler.lua b/gamemodes/benny/entities/weapons/itemhandler.lua index 401952c..c446d22 100644 --- a/gamemodes/benny/entities/weapons/itemhandler.lua +++ b/gamemodes/benny/entities/weapons/itemhandler.lua @@ -62,11 +62,14 @@ end function SWEP:SetActive( ent ) local p = self:GetOwner() if ent:GetOwner() != p then return false end - --if self:GetActiveR():IsValid() then self:Deactive() end self:SetActiveR( ent ) - if self:GetActiveR():IsValid() then - self:GetActiveR():Deploy() - self:GetActiveR():SetNoDraw( false ) + if ent:IsValid() then + ent:Deploy() + ent:SetNoDraw( false ) + -- LAZY FIX + for i, v in ipairs(ent:GetChildren()) do + v:SetNoDraw(false) + end end return true end @@ -75,7 +78,6 @@ function SWEP:Deactive() end function SWEP:PrimaryAttack() - local p = self:GetOwner() if self:GetActiveR():IsValid() then self:GetActiveR():Attack() end @@ -88,7 +90,6 @@ function SWEP:Reload() end function SWEP:SecondaryAttack() - local p = self:GetOwner() if self:GetActiveR():IsValid() then self:GetActiveR():AttackAlt() end @@ -121,27 +122,34 @@ function SWEP:EquipItem( ent ) end print("[equip]", ent) - self:SetDesireR( ent ) + --self:SetDesireR( ent ) + ent:SetHandler( self ) ent:AddEFlags( EFL_KEEP_ON_RECREATE_ENTITIES ) - ent:AddEffects( EF_BONEMERGE + EF_BONEMERGE_FASTCULL ) + ent:AddEffects( EF_BONEMERGE + EF_BONEMERGE_FASTCULL + EF_NOINTERP ) ent:PhysicsInit( SOLID_NONE ) ent:SetMoveType( MOVETYPE_NONE ) + ent:SetAcquisition( CurTime() ) + + -- Inventory + local inv = p:GetInventory() + local result = inv:AddItem( ent ) + if !result then + print("[EquipItem " .. tostring(self) .. "] AddItem failed! " .. tostring(ent)) + return + end + ent:SetNoDraw( true ) - ent:SetParent( p ) - ent:SetOwner( p ) - ent:SetHandler( self ) + -- LAZY FIX + for i, v in ipairs(ent:GetChildren()) do + v:SetNoDraw(true) + end ent:SetLocalPos( vector_origin ) ent:SetLocalAngles( angle_zero ) - ent:SetAcquisition( CurTime() ) ent:EmitSound( "ae/items/pickup.ogg", 70, 100, 1, CHAN_STATIC ) - --self:SetActive( ent ) - local inv = p:GetInventory() - inv[ent] = true - inv:Sync() - + -- Start prediction net.Start("AEINV_PredictItem") net.WriteEntity( ent ) net.WriteBool( true ) @@ -156,9 +164,6 @@ function SWEP:DropItem() if CLIENT then print("[drop] DropItem called on cl not allowed") return end self:SetDesireR( NULL ) - - ent:SetParent( NULL ) - ent:SetOwner( NULL ) ent:SetHandler( NULL ) ent:RemoveEFlags( EFL_KEEP_ON_RECREATE_ENTITIES ) @@ -166,15 +171,22 @@ function SWEP:DropItem() ent:PhysicsInit( SOLID_VPHYSICS ) ent:SetMoveType( MOVETYPE_VPHYSICS ) ent:SetCollisionGroup( COLLISION_GROUP_PROJECTILE ) - ent:SetNoDraw( false ) + -- Inventory + local inv = p:GetInventory() + local result = inv:RemoveItem( ent ) + if !result then + print("[DropItem " .. tostring(self) .. "] RemoveItem failed! " .. tostring(ent)) + return + end + + ent:SetNoDraw( false ) + -- LAZY FIX + for i, v in ipairs(ent:GetChildren()) do + v:SetNoDraw(false) + end ent:SetPos( p:EyePos() + p:GetAimVector() * 0 ) ent:SetAngles( p:EyeAngles() + Angle( 0, 180, 0 ) ) - - - local inv = p:GetInventory() - inv[ent] = nil - inv:Sync() local ep = ent:GetPhysicsObject() ep:SetVelocity( p:GetAimVector() * 800 ) diff --git a/gamemodes/benny/gamemode/debugmenu.lua b/gamemodes/benny/gamemode/debugmenu.lua index ff31486..54c5293 100644 --- a/gamemodes/benny/gamemode/debugmenu.lua +++ b/gamemodes/benny/gamemode/debugmenu.lua @@ -368,6 +368,6 @@ function printallbones( ent ) end end -concommand.Add("b-debug_listbones", function( ply, cmd ) - printallbones( ply ) +concommand.Add("b-debug_listbones", function( ply, cmd, args ) + printallbones( args[1] and Entity(args[1]) or ply ) end) \ No newline at end of file diff --git a/gamemodes/benny/gamemode/hud.lua b/gamemodes/benny/gamemode/hud.lua index 1d2577d..28ecb2a 100644 --- a/gamemodes/benny/gamemode/hud.lua +++ b/gamemodes/benny/gamemode/hud.lua @@ -369,77 +369,81 @@ function GM:HUDPaint() S_Pop() if handler then - -- Inventory - local Pw, Ph, Pg = 110, 30, 10 - local thespace = 0 - for i, v in ipairs( p:GetInventory():GetWeighted() ) do - thespace = thespace + Pw + Pg - end - thespace = thespace - Pg - thespace = thespace/2 - - S_Push( ScrW()/2 - thespace, ScrH() - 20 - Ph ) + if !p:GetInventory():IsValid() then + hTextS( "No inventory entity!!", "HUD_36", ScrW()/2, ScrH() - 20 - 36, COLOR_MAIN, TEXT_ALIGN_CENTER, nil, COLOR_DARK ) + else + -- Inventory + local Pw, Ph, Pg = 110, 30, 10 + local thespace = 0 for i, v in ipairs( p:GetInventory():GetWeighted() ) do - hCol( v == handler:GetDesireR() and COLOR_BRIGHT or COLOR_DARK ) - hRect( (i-1)*(Pw+Pg), 0, Pw, Ph ) - if v == handler:GetActiveR() then - hCol( COLOR_MAIN ) - hORect( (i-1)*(Pw+Pg)+1, 1, Pw-2, Ph-2, 1 ) - end - local x, y = (i-1)*(Pw+Pg), 0 - hText( l8( v.Class.PrintName ), "HUD_24", x + Pw/2, y + 5, COLOR_MAIN, TEXT_ALIGN_CENTER ) - hText( i, "HUD_16", x + 4, y + 2, COLOR_MAIN ) + thespace = thespace + Pw + Pg end - S_Pop() + thespace = thespace - Pg + thespace = thespace/2 - local wep = handler:GetDesireR() - if wep and wep.GetClip then - local Bw, Bh = 8+(8+2)*30-2+8, 160 - S_Push( w - 20 - Bw, h - 20 - Bh ) - hCol( COLOR_DARK ) - hRect( 0, 0, Bw, Bh ) - - S_Push( 0, 0 ) - hCol( COLOR_MAIN ) - local leng = Bw-8-8 - hRect( 8, 8, leng-70, 26 ) - hRect( 8 + leng - 70 + 4, 8, leng-(leng-70)-4, 26 ) - hText( l8( wep.Class.PrintName ), "HUD_36", 12, 6, COLOR_DARK ) - local bc = wep.Class.BurstCount - hText( fmlookup[bc] or bc .. "RND", "HUD_24", 10 + (leng - 70) + 70/2, 11, COLOR_DARK, TEXT_ALIGN_CENTER ) - S_Pop() - - local Tw, Th = 6, 18 - - if wep.Class.ClipSize>45 then - Tw = 3 - Th = 13 - elseif wep.Class.ClipSize<14 then - Tw = 8 - Th = 22 + S_Push( ScrW()/2 - thespace, ScrH() - 20 - Ph ) + for i, v in ipairs( p:GetInventory():GetWeighted() ) do + hCol( v == handler:GetDesireR() and COLOR_BRIGHT or COLOR_DARK ) + hRect( (i-1)*(Pw+Pg), 0, Pw, Ph ) + if v == handler:GetActiveR() then + hCol( COLOR_MAIN ) + hORect( (i-1)*(Pw+Pg)+1, 1, Pw-2, Ph-2, 1 ) + end + local x, y = (i-1)*(Pw+Pg), 0 + hText( l8( v.Class.PrintName ), "HUD_24", x + Pw/2, y + 5, COLOR_MAIN, TEXT_ALIGN_CENTER ) + hText( i, "HUD_16", x + 4, y + 2, COLOR_MAIN ) end - - S_Push( Bw - Tw - 8, Bh - Th - 8 ) - for i=0, wep.Class.ClipSize-1 do - if i>29 then - hCol( COLOR_DARK ) - hRect( (0 - Tw - 2)*i-4, -4, Tw+2, Th+8 ) - end - end - for i=0, wep.Class.ClipSize-1 do - if wep:GetClip() >= (i+1) then - hCol( COLOR_MAIN ) - hRect( (0 - Tw - 2)*i, 0, Tw, Th ) - hCol( COLOR_DARK ) - hRect( (0 - Tw - 2)*i, Th-4, Tw, 2 ) - else - hCol( COLOR_BRIGHT ) - hORect( (0 - Tw - 2)*i, 0, Tw, Th ) - --hORect( (0 - 8 - 2)*i+1, 1, 8-2, 18-2 ) - end - end - S_Pop() S_Pop() + + local wep = handler:GetDesireR() + if wep and wep.GetClip then + local Bw, Bh = 8+(8+2)*30-2+8, 160 + S_Push( w - 20 - Bw, h - 20 - Bh ) + hCol( COLOR_DARK ) + hRect( 0, 0, Bw, Bh ) + + S_Push( 0, 0 ) + hCol( COLOR_MAIN ) + local leng = Bw-8-8 + hRect( 8, 8, leng-70, 26 ) + hRect( 8 + leng - 70 + 4, 8, leng-(leng-70)-4, 26 ) + hText( l8( wep.Class.PrintName ), "HUD_36", 12, 6, COLOR_DARK ) + local bc = wep.Class.BurstCount + hText( fmlookup[bc] or bc .. "RND", "HUD_24", 10 + (leng - 70) + 70/2, 11, COLOR_DARK, TEXT_ALIGN_CENTER ) + S_Pop() + + local Tw, Th = 6, 18 + + if wep.Class.ClipSize>45 then + Tw = 3 + Th = 13 + elseif wep.Class.ClipSize<14 then + Tw = 8 + Th = 22 + end + + S_Push( Bw - Tw - 8, Bh - Th - 8 ) + for i=0, wep.Class.ClipSize-1 do + if i>29 then + hCol( COLOR_DARK ) + hRect( (0 - Tw - 2)*i-4, -4, Tw+2, Th+8 ) + end + end + for i=0, wep.Class.ClipSize-1 do + if wep:GetClip() >= (i+1) then + hCol( COLOR_MAIN ) + hRect( (0 - Tw - 2)*i, 0, Tw, Th ) + hCol( COLOR_DARK ) + hRect( (0 - Tw - 2)*i, Th-4, Tw, 2 ) + else + hCol( COLOR_BRIGHT ) + hORect( (0 - Tw - 2)*i, 0, Tw, Th ) + --hORect( (0 - 8 - 2)*i+1, 1, 8-2, 18-2 ) + end + end + S_Pop() + S_Pop() + end end end @@ -873,6 +877,82 @@ local function QuickDrawStat( wide, data, first ) return gap end +local c_swag = HSVToColor( 120, 0.5, 1 ) +local c_swag2 = HSVToColor( 60, 0.5, 1 ) +local c_swag3 = HSVToColor( 180, 0.5, 1 ) + +local function recurse( ent, y ) + local p = LocalPlayer() + local h = p:HandlerCheck() + local inv = ent:GetInventory() + local irs = inv:GetReservedSlots() + + S_Push( 20, 0 ) + hTextS( "Inventory [" .. inv:EntIndex() .. "]", "HUD_16", 0, y, nil, nil, nil, color_black ) + y = y + 12 + for i=1, 32 do + local curr = inv["GetItem"..i](self) + if irs < i and curr == NULL then continue end + local ofinterest = curr != NULL and + ((curr == h:GetActiveR() or curr == h:GetActiveL()) and c_swag or + (curr == h:GetDesireR() or curr == h:GetDesireL()) and c_swag2) or + irs >= i and c_swag3 or nil + + local entname = curr == NULL and (irs >= i and "Reserved" or "Null") or tostring(curr) + hTextS( i, "HUD_16", 0, y, ofinterest, nil, nil, color_black ) + hTextS( entname, "HUD_16", 20, y, ofinterest, nil, nil, color_black ) + y = y + 12 + if curr.GetInventory then + y = recurse( curr, y ) + end + end + S_Pop() + + return y +end + +hook.Add("HUDPaint", "Benny_HUDPaint_Debug", function() + local p = LocalPlayer() + stack = util.Stack() + + local y = 0 + S_Push( 20, 120 ) + hTextS( p, "HUD_16", 0, y, nil, nil, nil, color_black ) + y = y + 12 + + local h = p:HandlerCheck() + if h then + hTextS( "Handler:", "HUD_16", 20, y, nil, nil, nil, color_black ) + y = y + 12 + + hTextS( "R Active: " .. tostring(h:GetActiveR()), "HUD_16", 40, y, nil, nil, nil, color_black ) + y = y + 12 + hTextS( "R Desire: " .. tostring(h:GetDesireR()), "HUD_16", 40, y, nil, nil, nil, color_black ) + y = y + 12 + hTextS( "L Active: " .. tostring(h:GetActiveL()), "HUD_16", 40, y, nil, nil, nil, color_black ) + y = y + 12 + hTextS( "L Desire: " .. tostring(h:GetDesireL()), "HUD_16", 40, y, nil, nil, nil, color_black ) + y = y + 12 + end + + local x = 20+20 + y = recurse( p, y ) + + if false then + hTextS( "Inventory (Weighted):", "HUD_16", 20, y, nil, nil, nil, color_black ) + y = y + 12 + + for i, v in ipairs(p:GetInventory():GetWeighted()) do + hTextS( i .. ": " .. tostring(v), "HUD_16", 20+20, y, nil, nil, nil, color_black ) + y = y + 12 + end + end + S_Pop() + + if stack:Size() != 0 then print("Stack unfinished.") end + return +end) + local ScoreWide = 600 function GM:ScoreboardShow() drawscoreboard = true diff --git a/gamemodes/benny/gamemode/inventory.lua b/gamemodes/benny/gamemode/inventory.lua index b95cd2b..8bff747 100644 --- a/gamemodes/benny/gamemode/inventory.lua +++ b/gamemodes/benny/gamemode/inventory.lua @@ -1,179 +1,64 @@ ---------------------- --- Your Name is Benny ---------------------- +local Emeta = FindMetaTable("Entity") -local PT = FindMetaTable("Player") +local qt2 = { + ["slot1"] = 1, + ["slot2"] = 2, + ["slot3"] = 3, + ["slot4"] = 4, + ["slot5"] = 5, + ["slot6"] = 6, + ["slot7"] = 7, + ["slot8"] = 8, + ["slot9"] = 9, + ["slot0"] = 0, +} +local qt = { + ["invprev"] = -1, + ["invnext"] = 1, +} -function PT:GetItems() - return -end +hook.Add( "PlayerBindPress", "Benny_PlayerBindPress_Original", function( ply, bind, pressed, code ) + if qt2[bind] then + local Num = qt2[bind] + if pressed then + local inv = ply:GetInventory():GetWeighted() + local wep = ply:HandlerCheck() + local invf = table.Flip( inv ) -InventoryMeta = {} + local NumOfActive = 0 + NumOfActive = invf[wep:GetDesireR()] -function InventoryMeta:Destroy() - local p = self[0].Owner - p.Inventory = nil - p:GetInventory() -end - -function InventoryMeta:BugCheck() - for i, v in pairs(self) do - if i != 0 and !i:IsValid() then - self[i] = nil - end - end -end - -function InventoryMeta:GetWeighted() - local itemlist = {} - - for i, v in pairs(self) do - if i == 0 then continue end - table.insert( itemlist, i ) - end - - table.sort( itemlist, function( a, b ) - return a:GetAcquisition() < b:GetAcquisition() - end) - - return itemlist -end - -function InventoryMeta:Sync() - if SERVER then - net.Start("AEINV_InvSync") - local count = table.Count( self )-1 -- The header is included - net.WriteUInt( count, 8 ) - for key, _ in pairs( self ) do - if key == 0 then continue end - net.WriteEntity( key ) + if Num == NumOfActive then + Num = 0 end - net.Send( self[0].Owner ) + input.SelectWeapon( ply:GetWeapon("goat_"..Num) ) + end + return true end -end + if qt[bind] then + if pressed then + local Num = 0 -InventoryMeta.__index = InventoryMeta + local inv = ply:GetInventory():GetWeighted() + local wep = ply:HandlerCheck() + local invf = table.Flip( inv ) + local invc = #inv + + Num = wep:GetDesireR() and invf[wep:GetDesireR()] or 0 + Num = Num + qt[bind] -function PT:GetInventory() - if !self.Inventory then - print("[inventory] new inventory created: ", self) - self.Inventory = {} - self.Inventory[0] = { Owner = self } - setmetatable( self.Inventory, InventoryMeta ) - - if SERVER then - for i, v in pairs( self:GetChildren() ) do - if v.AEItem then - print( "[inventory] regen: adding", v) - self.Inventory[v] = true - end + if Num > invc then + Num = 0 + elseif Num < 0 then + Num = invc end - self.Inventory:Sync() + + input.SelectWeapon( ply:GetWeapon("goat_"..Num) ) end + return true end - - self.Inventory:BugCheck() - - return self.Inventory -end - -gameevent.Listen( "OnRequestFullUpdate" ) -hook.Add( "OnRequestFullUpdate", "Benny_OnRequestFullUpdate_Inventory", function( data ) - local name = data.name // Same as Player:Nick() - local steamid = data.networkid // Same as Player:SteamID() - local id = data.userid // Same as Player:UserID() - local index = data.index // Same as Entity:EntIndex() minus one - - if SERVER then - print("[inventory]", Player(id), "FullUpdate resync") - Player(id):GetInventory():Sync() - end -end ) - -if SERVER then - util.AddNetworkString("AEINV_InvSync") -else - net.Receive("AEINV_InvSync", function() - print("[inventory] sync start:") - local p = LocalPlayer() - p.Inventory = nil - if p.GetInventory then - local inv = p:GetInventory() - local count = net.ReadUInt(8) - for i=1, count do - local key = net.ReadEntity() - print( "\tadded", key) - inv[key] = true - end - else - print("\ti don't have an inventory, maybe you asked too early!!") - end - print("\tsync done") - end) -end - - -do - local qt2 = { - ["slot1"] = 1, - ["slot2"] = 2, - ["slot3"] = 3, - ["slot4"] = 4, - ["slot5"] = 5, - ["slot6"] = 6, - ["slot7"] = 7, - ["slot8"] = 8, - ["slot9"] = 9, - ["slot0"] = 0, - } - local qt = { - ["invprev"] = -1, - ["invnext"] = 1, - } - - hook.Add( "PlayerBindPress", "Benny_PlayerBindPress_Original", function( ply, bind, pressed, code ) - if qt2[bind] then - local Num = qt2[bind] - if pressed then - local inv = ply:GetInventory():GetWeighted() - local wep = ply:HandlerCheck() - local invf = table.Flip( inv ) - - local NumOfActive = 0 - NumOfActive = invf[wep:GetDesireR()] - - if Num == NumOfActive then - Num = 0 - end - input.SelectWeapon( ply:GetWeapon("goat_"..Num) ) - end - return true - end - if qt[bind] then - if pressed then - local Num = 0 - - local inv = ply:GetInventory():GetWeighted() - local wep = ply:HandlerCheck() - local invf = table.Flip( inv ) - local invc = #inv - - Num = wep:GetDesireR() and invf[wep:GetDesireR()] or 0 - Num = Num + qt[bind] - - if Num > invc then - Num = 0 - elseif Num < 0 then - Num = invc - end - - input.SelectWeapon( ply:GetWeapon("goat_"..Num) ) - end - return true - end - end) -end +end) hook.Add( "PlayerSwitchWeapon", "Benny_PlayerSwitchWeapon_Goat", function( ply, old, ent ) if ent.BennyItemHandler then return true end -- what happened? @@ -195,7 +80,6 @@ end) for i=0, 9 do local tent = {} - --tent.Base = "goat" tent.Goat = i weapons.Register( tent, "goat_" .. i ) diff --git a/gamemodes/benny/gamemode/items.lua b/gamemodes/benny/gamemode/items.lua index b252e46..982ec3e 100644 --- a/gamemodes/benny/gamemode/items.lua +++ b/gamemodes/benny/gamemode/items.lua @@ -19,6 +19,22 @@ function Emeta:__index( key ) return Emetaindex( self, key ) end +function Emeta:SetupInventory() + local oldinv = self:GetInventory() + if IsValid( oldinv ) then + print( "[Inventory " .. tostring(oldinv) .. "] Removing to create a new inv" ) + oldinv:Remove() + end + + local inventory = ents.Create( "inventory" ) + if IsValid( inventory ) then + inventory:AttachToEntity( self ) + inventory:Spawn() + return inventory + end + return false +end + local Itemmeta = {} function Itemmeta:__tostring() diff --git a/gamemodes/benny/gamemode/items/base.lua b/gamemodes/benny/gamemode/items/base.lua index b608e7b..69a0623 100644 --- a/gamemodes/benny/gamemode/items/base.lua +++ b/gamemodes/benny/gamemode/items/base.lua @@ -53,6 +53,23 @@ do -- Base p:DoCustomAnimEvent( BGESTURE_ITEM1_RIGHT, p:LookupSequence( seqname ) ) end + -- Use after children added. + function ITEM:ReevalRecreate() + self:RemoveEFlags( EFL_KEEP_ON_RECREATE_ENTITIES ) + if self:GetOwner():IsValid() then + if self:GetOwner():IsEFlagSet( EFL_KEEP_ON_RECREATE_ENTITIES ) then + self:AddEFlags( EFL_KEEP_ON_RECREATE_ENTITIES ) + print( "[Item " .. tostring(self) .. "] To be saved during recreate.") + return + else + print( "[Item " .. tostring(self) .. "] Will NOT be saved during recreate.") + return + end + end + print( "[Item " .. tostring(self) .. "] Will NOT be saved during recreate. No owner either") + return + end + function ITEM:EntThink() end function ITEM:EntPhysicsCollide() end function ITEM:Reload() end @@ -71,6 +88,10 @@ do -- Base self:GetHandler():SetActiveR( NULL ) self:SetNoDraw( true ) + -- LAZY FIX + for i, v in ipairs(self:GetChildren()) do + v:SetNoDraw(true) + end end function ITEM:CancelHolster() diff --git a/gamemodes/benny/gamemode/items/firearms.lua b/gamemodes/benny/gamemode/items/firearms.lua index af08ee7..26e1893 100644 --- a/gamemodes/benny/gamemode/items/firearms.lua +++ b/gamemodes/benny/gamemode/items/firearms.lua @@ -1,5 +1,4 @@ - do -- Base Firearm local AnimationLookup = { ["fire"] = { @@ -42,7 +41,6 @@ do -- Base Firearm "Clip", "BurstCount", "Firemode", - "ReloadStage", }, ["Float"] = { "Delay", @@ -52,6 +50,9 @@ do -- Base Firearm "Accuracy_Amount", "DelayReload", }, + ["Entity"] = { + "Inventory" + }, } ITEM.Delay = 0.2 @@ -71,6 +72,10 @@ do -- Base Firearm function ITEM:EntInitialize() Base.EntInitialize( self ) + if SERVER then + local inv = self:SetupInventory() + inv:SetReservedSlots( 1 ) + end end function ITEM:Attack() @@ -133,8 +138,27 @@ do -- Base Firearm end end if self:GetRefillTime() != 0 and self:GetRefillTime() <= CurTime() then - self:SetClip( class.ClipSize ) + self:SetClip( self.ClipSize ) self:SetRefillTime( 0 ) + + if SERVER then + local inv = self:GetInventory() + local ent = ents.Create("b-item_mag_m16a2") + if IsValid(ent) then + ent:AddEffects( EF_BONEMERGE + EF_BONEMERGE_FASTCULL ) + ent:SetOwner( self ) + ent:SetParent( self ) + ent:SetLocalPos( vector_origin ) + ent:SetLocalAngles( angle_zero ) + ent:Spawn() + self:ReevalRecreate() + ent:ReevalRecreate() + + ent:SetMoveType( MOVETYPE_NONE ) + + inv:SetItem1( ent ) + end + end end Base.Think( self ) end @@ -150,23 +174,52 @@ do -- Base Firearm local p = self:GetOwner() local time = 0.4 - if self:GetReloadStage() == 0 then -- Mag loaded + if self:GetInventory():GetItem1():IsValid() then -- Mag loaded -- Unload the mag - self:SetReloadStage(1) self:SetClip( 0 ) self:Sound( self.MagOutSound, 70, 100, 0.4 ) self:PlayerAnimation( AnimationLookup["reload"][self.HoldType] ) self:PlayAnimation( self:LookupSequence( "magout" ) ) time = 0.4 + + if CLIENT then + local inv = self:GetInventory() + local curr = inv:GetItem1() + if curr:IsValid() then + local bm = self:GetBoneMatrix( self:LookupBone("Weapon") ) + debugoverlay.Cross( bm:GetTranslation(), 16, 0.5 ) + + local class = ITEMS["mag_m16a2"] + local ent = ents.CreateClientProp( class.Model ) --- TO BE A SHARED ENTITY IN THE FUTURE :3 + ent:SetPos( bm:GetTranslation() ) + ent:SetAngles( bm:GetAngles() + Angle( 0, -90, -90 ) ) + ent:Spawn() + end + end + + if SERVER then + local inv = self:GetInventory() + local curr = inv:GetItem1() + if curr:IsValid() then + inv:SetItem1( NULL ) + curr:SetOwner( NULL ) + curr:SetParent( NULL ) + + curr:Remove() + self:ReevalRecreate() + -- curr:SetMoveType( MOVETYPE_VPHYSICS ) + -- curr:GetPhysicsObject():Wake() + end + end else -- Load it - self:SetReloadStage(0) - self:SetClip( self.ClipSize ) + self:SetRefillTime( CurTime() + 0.4 ) self:Sound( self.MagInSound, 70, 100, 0.4 ) self:PlayerAnimation( AnimationLookup["reload_insert"][self.HoldType] ) self:PlayAnimation( self:LookupSequence( "magin" ) ) - time = 0.8 end + + time = 0.8 self:SetDelay( CurTime() + time ) end @@ -186,6 +239,14 @@ do -- Base Firearm Base.CancelHolster( self ) end + do -- Base Mag + local ITEM, Base = CreateItem( "base_mag", "base" ) + + ITEM.PrintName = "Magazine Base" + ITEM.Description = "Testing testing" + ITEM.Category = "base" + end + do -- Handguns do -- G18 local ITEM, Base = CreateItem( "g18", "base_firearm" ) @@ -262,6 +323,20 @@ do -- Base Firearm ITEM.MagInSound = bSound("weapons/m16a2/magin.ogg") ITEM.BoltDropSound = bSound("weapons/m16a2/cock.ogg") ITEM.BoltPullSound = bSound("weapons/fnc/cock.ogg") + + do + local ITEM, Base = CreateItem( "mag_m16a2", "base_mag" ) + + ITEM.PrintName = "#Item.mag_m16a2.Name" + ITEM.Description = "#Item.mag_m16a2.Description" + ITEM.Category = "magazine" + + ITEM.Model = bModel("weapons/test_m16a2_mag") + ITEM.DefaultBodygroups = {} + ITEM.HoldType = "magazine" + + ITEM.ClipSize = 30 + end end end end diff --git a/gamemodes/benny/gamemode/player.lua b/gamemodes/benny/gamemode/player.lua index 6942c6c..c038563 100644 --- a/gamemodes/benny/gamemode/player.lua +++ b/gamemodes/benny/gamemode/player.lua @@ -44,6 +44,8 @@ function GM:PlayerSpawn( ply ) ply:SetHealth_Blood( 1000 ) ply:SetHealth_Stamina( 1000 ) + ply:SetupInventory() + ply:MakeCharacter() end diff --git a/gamemodes/benny/gamemode/player_class.lua b/gamemodes/benny/gamemode/player_class.lua index 670f49c..9fa14ad 100644 --- a/gamemodes/benny/gamemode/player_class.lua +++ b/gamemodes/benny/gamemode/player_class.lua @@ -47,6 +47,7 @@ function PLAYER:SetupDataTables() self.Player:NetworkVar( "Float", "DivedAt" ) self.Player:NetworkVar( "Float", "TouchedObjectiveTime" ) + self.Player:NetworkVar( "Entity", "Inventory" ) self.Player:NetworkVar( "Entity", "TouchedObjective" ) self.Player:NetworkVar( "Vector", "VaultPos1")