--------------------- -- Your Name is Benny --------------------- ITEMS = {} local itemmeta = {} function itemmeta:__tostring() return "ItemDef [" .. self.ClassName .. "]" end local ITEMHELPER = { Get = function( self, key ) return self.key end, GetRaw = function( self, key ) return rawget( self, key ) end, } function itemmeta.__index( self, key ) if ITEMHELPER[key] then return ITEMHELPER[key] end if rawget(self, "BaseClass") then return rawget(self, "BaseClass")[key] end end function AddItem( itemname, item ) if item then ITEMS[itemname] = item item.ClassName = itemname item.BaseClass = ITEMS[item.Base] setmetatable( item, itemmeta ) else return ITEMS[itemname] end end AddItem( "base", { PrintName = "Base Item", Description = "Beginning item base.", Category = "base", Vars = { ["Float"] = { "Acquisition", "HolsterIn", }, }, HoldType = "slam", ["Initialize"] = function( class, ent, handler ) print( class, "Initialized base initialization" ) end, ["Deploy"] = function( class, ent, handler ) end, ["Holster"] = function( class, ent, handler ) end, ["Attack"] = function( class, ent, handler ) end, ["AttackAlt"] = function( class, ent, handler ) end, ["Think"] = function( class, ent, handler ) end, ["Reload"] = function( class, ent, handler ) end, }) local AnimationLookup = { ["fire"] = { ["handgun"] = "fire_handgun", ["rifle"] = "rifle_fire", }, ["reload"] = { ["handgun"] = "reload_handgun", ["rifle"] = "rifle_reload", }, ["reload_rack"] = { ["handgun"] = "reload_handgun_rack", ["rifle"] = "rifle_reload_rack", }, ["reload_insert"] = { ["handgun"] = "reload_handgun_insert", ["rifle"] = "rifle_reload_insert", }, ["deploy"] = { ["handgun"] = "deploy_handgun", ["rifle"] = "rifle_deploy", }, ["holster"] = { ["handgun"] = "holster_handgun", ["rifle"] = "holster_handgun", }, } SLIDE_FORWARD = 0 -- loaded SLIDE_EMPTY = 1 -- empty SLIDE_BACK = 2 -- back AddItem( "base_firearm", { PrintName = "Base Firearm", Description = "Item base for firearms.", Category = "base", Base = "base", FirearmHelper = true, Vars = { ["Bool"] = { "Loaded", }, ["Int"] = { "Clip", "BurstCount", "Firemode", "SlideState", -- 0 = forward and loaded, 1 = forward and empty, 2 = back and empty }, ["Float"] = { "Delay", "DelayBurst", "RefillTime", "Accuracy_Reset", "Accuracy_Amount", "DelayReload", }, }, HoldType = "rpg", Delay = 0.1, Pellets = 1, Accuracy = 1, ClipSize = 15, BurstCount = math.huge, BurstRunaway = false, BurstAuto = false, BurstDelay = 0, FireSound = "benny/weapons/m16a2/01.ogg", MagOutSound = "benny/weapons/m16a2/magout.ogg", MagInSound = "benny/weapons/m16a2/magin.ogg", BoltDropSound = "benny/weapons/m16a2/cock.ogg", BoltPullSound = "benny/weapons/fnc/cock.ogg", ["Initialize"] = function( class, ent, handler ) ITEMS["base"].Initialize( class, ent, handler ) ent:SetClip( class.ClipSize ) ent:SetLoaded(true) print( class, "Initialized a firearm" ) end, ["Think"] = function( class, ent, handler ) local InProcess = ent:GetBurstCount() > 0 local Topped = ent:GetBurstCount() == class.BurstCount local Runaway = class.BurstRunaway local BAuto = class.BurstAuto local Firedown = handler:GetOwner():KeyDown( IN_ATTACK ) if Runaway and InProcess and !Topped then class["Attack"]( class, ent, handler ) else if !Firedown then if !Topped and InProcess then ent:SetDelayBurst( CurTime() + class.BurstDelay ) end ent:SetBurstCount( 0 ) end if Topped and BAuto then ent:SetBurstCount( 0 ) ent:SetDelayBurst( CurTime() + class.BurstDelay ) end end if ent:GetRefillTime() != 0 and ent:GetRefillTime() <= CurTime() then ent:SetClip( class.ClipSize ) ent:SetRefillTime( 0 ) end end, ["Attack"] = function( class, ent, handler ) --if ent:GetClip() <= 0 then return end if ent:GetDelay() > CurTime() then return end if ent:GetDelayBurst() > CurTime() then return end if ent:GetBurstCount() >= class.BurstCount then return end if ent:GetSlideState() != SLIDE_FORWARD then handler:EmitSound( "benny/weapons/noammo.ogg", 70, 150, 0.4, CHAN_STATIC ) ent:SetDelay( CurTime() + 0.25 ) ent:SetBurstCount( 0 ) return end local Runaway = class.BurstRunaway local BAuto = class.BurstAuto ent:SetBurstCount( ent:GetBurstCount() + 1 ) if ent:GetBurstCount() >= class.BurstCount then ent:SetDelayBurst( CurTime() + class.BurstDelay ) if BAuto then ent:SetBurstCount( 0 ) end end ent:SetSlideState( SLIDE_BACK ) --if ent:GetClip() == 0 then if ent:GetClip() > 0 then ent:SetClip( ent:GetClip() - 1 ) ent:SetSlideState( SLIDE_FORWARD ) else handler:EmitSound( "benny/weapons/1911/slidedrop.ogg", 70, 100, 0.4, CHAN_STATIC ) if !ent:GetLoaded() then ent:SetSlideState( SLIDE_EMPTY ) end end ent:SetDelay( CurTime() + class.Delay ) handler:EmitSound( istable(class.FireSound) and TSelShared(class.FireSound, "FireSound") or class.FireSound, 140, 100, 0.4, CHAN_STATIC ) local acc = math.rad( class.Accuracy or 0 ) local p = handler:GetOwner() handler:FireBullets( { Attacker = p, Damage = 1, Force = 1, Num = class.Pellets, Dir = p:GetAimVector(), Src = p:GetShootPos(), Spread = Vector( acc, acc, 0 ), } ) local ply = handler:GetOwner() ply:AddVCDSequenceToGestureSlot( GESTURE_SLOT_ATTACK_AND_RELOAD, ply:LookupSequence( AnimationLookup["fire"][class.HoldType] ), 0, true ) end, ["Reload"] = function( class, ent, handler ) --if ent:GetClip() >= class.ClipSize then return end --handler:EmitSound( "weapons/m4a1/m4a1_boltpull.wav", 70, 125, 0.4, CHAN_STATIC ) --ent:SetRefillTime( CurTime() + 0.1 ) --handler:EmitSound( "benny/weapons/basic.ogg", 70, 100, 0.4, CHAN_STATIC ) if ent:GetDelay() > CurTime() then return end ent:SetDelay( CurTime() + 0.6 ) local ply = handler:GetOwner() if (ent:GetClip() > 0) and ent:GetSlideState() == SLIDE_BACK then handler:EmitSound( class.BoltDropSound, 70, 100, 0.4, CHAN_STATIC ) ent:SetSlideState( SLIDE_FORWARD ) ent:SetClip( ent:GetClip() - 1 ) ply:AddVCDSequenceToGestureSlot( GESTURE_SLOT_ATTACK_AND_RELOAD, ply:LookupSequence( AnimationLookup["reload_rack"][class.HoldType] ), 0, true ) elseif (ent:GetClip() > 0) and ent:GetSlideState() == SLIDE_EMPTY then handler:EmitSound( class.BoltPullSound, 70, 100, 0.4, CHAN_STATIC ) ent:SetSlideState( SLIDE_FORWARD ) ent:SetClip( ent:GetClip() - 1 ) ply:AddVCDSequenceToGestureSlot( GESTURE_SLOT_ATTACK_AND_RELOAD, ply:LookupSequence( AnimationLookup["reload_rack"][class.HoldType] ), 0, true ) elseif ent:GetLoaded() then handler:EmitSound( class.MagOutSound, 70, 100, 0.4, CHAN_STATIC ) ent:SetLoaded( false ) ent:SetClip( 0 ) ply:AddVCDSequenceToGestureSlot( GESTURE_SLOT_ATTACK_AND_RELOAD, ply:LookupSequence( AnimationLookup["reload"][class.HoldType] ), 0, true ) else handler:EmitSound( class.MagInSound, 70, 100, 0.4, CHAN_STATIC ) ent:SetLoaded( true ) ent:SetRefillTime( CurTime() + 0.5 ) ply:AddVCDSequenceToGestureSlot( GESTURE_SLOT_ATTACK_AND_RELOAD, ply:LookupSequence( AnimationLookup["reload_insert"][class.HoldType] ), 0, true ) end end, ["Deploy"] = function( class, ent, handler ) handler:EmitSound( "weapons/usp/usp_slideback.wav", 70, 125, 0.4, CHAN_STATIC ) ent:SetDelay( CurTime() + 0.25 ) local ply = handler:GetOwner() ply:AddVCDSequenceToGestureSlot( GESTURE_SLOT_ATTACK_AND_RELOAD, ply:LookupSequence( AnimationLookup["deploy"][class.HoldType] ), 0, true ) end, ["Holster"] = function( class, ent, handler ) ent:SetRefillTime( 0 ) handler:EmitSound( "weapons/m4a1/m4a1_deploy.wav", 70, 125, 0.4, CHAN_STATIC ) ent:SetDelay( CurTime() + 0.25 ) if ent:GetSlideState() == SLIDE_BACK then ent:SetSlideState( SLIDE_EMPTY ) end local ply = handler:GetOwner() ply:AddVCDSequenceToGestureSlot( GESTURE_SLOT_ATTACK_AND_RELOAD, ply:LookupSequence( AnimationLookup["holster"][class.HoldType] ), 0, true ) end, }) AddItem( "base_firearm_ubgl", { PrintName = "Base Firearm w/ UBGL", Description = "Item base for firearms that include grenade launchers.", Category = "base", Base = "base_firearm", Vars = { ["Int"] = { "Clip2", }, ["Float"] = { "Delay2", "DelayBurst2", "RefillTime2", "Accuracy_Reset2", "Accuracy_Amount2", }, }, Delay2 = 0.25, ClipSize2 = 4, ["Initialize"] = function( class, ent, handler ) ITEMS["base_firearm"].Initialize( class, ent, handler ) ent:SetClip2( class.ClipSize2 ) end, ["Attack"] = function( class, ent, handler ) if ent:GetFiremode() == 1 then class:Attack2( ent, handler ) else ITEMS["base_firearm"].Attack( class, ent, handler ) end end, ["Reload"] = function( class, ent, handler ) if ent:GetFiremode() == 1 then class:Reload2( ent, handler ) else ITEMS["base_firearm"].Reload( class, ent, handler ) end end, ["Alt"] = function( class, ent, handler ) ent:SetFiremode( ent:GetFiremode() == 1 and 0 or 1 ) end, ["Think"] = function( class, ent, handler ) ITEMS["base_firearm"].Think( class, ent, handler ) if ent:GetRefillTime2() != 0 and ent:GetRefillTime2() <= CurTime() then ent:SetClip2( class.ClipSize2 ) ent:SetRefillTime2( 0 ) end end, ["Reload2"] = function( class, ent, handler ) if ent:GetClip2() >= class.ClipSize2 then return end if ent:GetDelay2() > CurTime() then return end handler:EmitSound( "weapons/m4a1/m4a1_boltpull.wav", 70, 125, 0.4, CHAN_STATIC ) ent:SetDelay2( CurTime() + 0.25 ) ent:SetRefillTime2( CurTime() + 0.1 ) end, ["Attack2"] = function( class, ent, handler ) if ent:GetClip2() <= 0 then return end if ent:GetDelay2() > CurTime() then return end if ent:GetDelayBurst2() > CurTime() then return end if ent:GetBurstCount() >= class.BurstCount then return end ent:SetClip2( ent:GetClip2() - 1 ) ent:SetDelay2( CurTime() + class.Delay2 ) handler:EmitSound( "weapons/ar2/ar2_altfire.wav", 140, 100, 0.4, CHAN_STATIC ) end, }) AddItem( "satchels", { PrintName = "#Item.satchels.Name", Description = "#Item.satchels.Description", Category = "utility", Base = "base", Model = "models/benny/weapons/testgun.mdl", HoldType = "handgun", Vars = { ["Float"] = { "Delay", }, }, ["Attack"] = function( class, ent, handler ) if ent:GetDelay() > CurTime() then return end ent:SetDelay( CurTime() + 0.5 ) if SERVER then for k, v in ipairs( ents.FindByClass( "b-satchel" ) ) do if v:GetOwner() == ent:GetOwner() then v:Detonate() end end end end, ["AttackAlt"] = function( class, ent, handler ) if ent:GetDelay() > CurTime() then return end ent:SetDelay( CurTime() + 0.5 ) local ply = ent:GetOwner() if SERVER then local bomb = ents.Create("b-satchel") bomb:SetPos( ply:EyePos() + (ply:GetAimVector() * 32) ) bomb:SetAngles( ply:EyeAngles() ) bomb:SetOwner( ply ) bomb:Spawn() local phy = bomb:GetPhysicsObject() phy:SetVelocity( ply:GetAimVector() * 400 ) phy:SetAngleVelocity( Vector( 0, 360, 0 ) ) end end, }) AddItem( "mk23", { PrintName = "#Item.mk23.Name", Description = "#Item.mk23.Description", Category = "pistol", Base = "base_firearm", Model = "models/benny/weapons/testgun.mdl", HoldType = "handgun", ClipSize = 12, Delay = (60/350), FireSound = { "benny/weapons/usp/01.ogg", "benny/weapons/usp/02.ogg", "benny/weapons/usp/03.ogg", }, MagOutSound = "benny/weapons/1911/magout.ogg", MagInSound = "benny/weapons/1911/magin.ogg", BoltDropSound = "benny/weapons/1911/slidedrop.ogg", BoltPullSound = "benny/weapons/glock/cock.ogg", Accuracy = 5/60, BurstCount = 1, Accuracy_Add = 0.5, Accuracy_Reset = 0.4, Accuracy_Decay = 5, }) AddItem( "fnc", { PrintName = "#Item.fnc.Name", Description = "#Item.fnc.Description", Base = "base_firearm_ubgl", Model = "models/benny/weapons/testrifle2.mdl",--"models/weapons/w_rif_ar556.mdl", HoldType = "rifle", ClipSize = 30, Delay = (60/750), FireSound = { "benny/weapons/m16a2/01.ogg", "benny/weapons/m16a2/02.ogg", "benny/weapons/m16a2/03.ogg", }, Accuracy = 1, Accuracy_Add = 0.4, Accuracy_Reset = 0.4, Accuracy_Decay = 12, }) AddItem( "m16a2", { PrintName = "#Item.m16a2.Name", Description = "#Item.m16a2.Description", Base = "base_firearm", Model = "models/benny/weapons/testrifle3.mdl",--"models/weapons/w_rif_m16a2.mdl", HoldType = "rifle", ClipSize = 30, Delay = (60/900), BurstCount = 3, BurstRunaway = true, BurstAuto = true, BurstDelay = 0.2, FireSound = { "benny/weapons/m16a2/01.ogg", "benny/weapons/m16a2/02.ogg", "benny/weapons/m16a2/03.ogg", }, Accuracy = 1, Accuracy_Add = 0.4, Accuracy_Reset = 0.4, Accuracy_Decay = 12, }) AddItem( "spas12", { PrintName = "#Item.spas12.Name", Description = "#Item.spas12.Description", Base = "base_firearm", Model = "models/weapons/w_shotgun.mdl", HoldType = "rifle", ClipSize = 8, Pellets = 8, Delay = 0.4, BurstCount = 1, FireSound = { "benny/weapons/spas12/01.ogg", "benny/weapons/spas12/02.ogg", "benny/weapons/spas12/03.ogg", }, MagOutSound = "benny/weapons/spas12/magout-01.ogg", MagInSound = "benny/weapons/spas12/magout-02.ogg", BoltDropSound = "benny/weapons/spas12/magin.ogg", BoltPullSound = "benny/weapons/glock/magin.ogg", Accuracy = 8, Accuracy_Add = 0.4, Accuracy_Reset = 0.4, Accuracy_Decay = 12, }) for ID, Data in pairs(ITEMS) do local tent = {} tent.Base = "b-itembase" tent.PrintName = Data.PrintName or ID tent.ID = ID tent.Class = ITEMS[ID] tent.Spawnable = true tent.AdminOnly = false tent.Category = "Other" -- print("aei_" .. ID) scripted_ents.Register( tent, "b-item_" .. ID ) end