USER
heres a swep gmod
if CLIENT then
SWEP.WepSelectIcon = surface.GetTextureID("vgui/hud/weapon_l4d2rifle")
SWEP.DrawWeaponInfoBox = false
SWEP.BounceWeaponIcon = false
killicon.Add( "weapon_l4d2rifle", "vgui/hud/weapon_l4d2rifle", Color( 255, 80, 0, 255 ) )
end
SWEP.PrintName = "M16A2"
SWEP.Category = "L4D2 Sweps"
SWEP.Spawnable= true
SWEP.AdminSpawnable= true
SWEP.AdminOnly = false
SWEP.Recoil = 0
SWEP.RecoilUp = 0
--SWEP.Recoil1 = 0 unused
SWEP.ViewModelFOV = 54
SWEP.ViewModel = "models/v_models/v_rifle.mdl"
SWEP.WorldModel = "models/weapons/w_smg1.mdl"
SWEP.ViewModelFlip = false
SWEP.ShowViewModel = true
SWEP.ShowWorldModel = false
SWEP.ViewModelBoneMods = {}
SWEP.AutoSwitchTo = false
SWEP.AutoSwitchFrom = false
SWEP.Slot = 2
SWEP.SlotPos = 0
SWEP.UseHands = false
SWEP.HoldType = "ar2"
SWEP.FiresUnderwater = false
SWEP.DrawCrosshair = true
SWEP.DrawAmmo = true
SWEP.Base = "weapon_base"
SWEP.CSMuzzleFlashes = true
SWEP.CSMuzzleX = true
SWEP.Primary.Sound = Sound("weapons/rifle/gunfire/rifle_fire_1.wav")
SWEP.Primary.Damage = 33
SWEP.Primary.TakeAmmo = 1
SWEP.Primary.ClipSize = 50
SWEP.Primary.Ammo = "ar2"
SWEP.Primary.DefaultClip = 410
SWEP.Primary.Spread = 0.2
SWEP.Primary.NumberofShots = 1
SWEP.Primary.Automatic = true
SWEP.Primary.Recoil = 4
SWEP.Primary.Delay = 0.0875
SWEP.Primary.Force = 3
SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = false
SWEP.Secondary.Ammo = "None"
SWEP.VElements = {}
SWEP.WElements = {
["wm"] = { type = "Model", model = "models/w_models/weapons/w_rifle_m16a2.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(0, 1, 0), angle = Angle(-175, 180, 0), size = Vector(1, 1, 1), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
}
function SWEP:FireAnimationEvent( pos, ang, event, options )
if ( !self.CSMuzzleFlashes ) then return end
-- CS Muzzle flashes
if ( event == tonumber(AE_MUZZLEFLASH) ) then
local data = EffectData()
data:SetFlags( 0 )
data:SetEntity( self:GetOwner():GetViewModel() )
data:SetAttachment( 3 )
data:SetScale( 1 )
if ( self.CSMuzzleX ) then
util.Effect( "CS_MuzzleFlash_X", data )
else
util.Effect( "CS_MuzzleFlash", data )
end
return true
end
end
function SWEP:Initialize()
self.Weapon:SetWeaponHoldType( self.HoldType )
if CLIENT then
// Create a new table for every weapon instance
self.VElements = table.FullCopy( self.VElements )
self.WElements = table.FullCopy( self.WElements )
self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
self:CreateModels(self.VElements) // create viewmodels
self:CreateModels(self.WElements) // create worldmodels
--// init view model bone build function
if IsValid(self.Owner) then
local vm = self.Owner:GetViewModel()
if IsValid(vm) then
self:ResetBonePositions(vm)
// Init viewmodel visibility
if (self.ShowViewModel == nil or self.ShowViewModel) then
vm:SetColor(Color(255,255,255,255))
else
// we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
vm:SetColor(Color(255,255,255,1))
--// ^ stopped working in GMod 13 because you have to do Entity:SetRenderMode(1) for translucency to kick in
// however for some reason the view model resets to render mode 0 every frame so we just apply a debug material to prevent it from drawing
vm:SetMaterial("Debug/hsv")
end
end
end
end
end
function SWEP:Holster()
if CLIENT and IsValid(self.Owner) then
local vm = self.Owner:GetViewModel()
if IsValid(vm) then
self:ResetBonePositions(vm)
end
end
timer.Remove( "RecoilCustom"..self:EntIndex())
return true
end
function SWEP:OnRemove()
self:Holster()
end
if CLIENT then
SWEP.vRenderOrder = nil
function SWEP:ViewModelDrawn()
if (CLIENT) then
if not self.Hands then self:DrawHands() end
if self.Hands then self.Hands:DrawModel() end
end
local vm = self.Owner:GetViewModel()
if !IsValid(vm) then return end
if (!self.VElements) then return end
self:UpdateBonePositions(vm)
if (!self.vRenderOrder) then
// we build a render order because sprites need to be drawn after models
self.vRenderOrder = {}
for k, v in pairs( self.VElements ) do
if (v.type == "Model") then
table.insert(self.vRenderOrder, 1, k)
elseif (v.type == "Sprite" or v.type == "Quad") then
table.insert(self.vRenderOrder, k)
end
end
end
for k, name in ipairs( self.vRenderOrder ) do
local v = self.VElements[name]
if (!v) then self.vRenderOrder = nil break end
if (v.hide) then continue end
local model = v.modelEnt
local sprite = v.spriteMaterial
if (!v.bone) then continue end
local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
if (!pos) then continue end
if (v.type == "Model" and IsValid(model)) then
model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
ang:RotateAroundAxis(ang:Up(), v.angle.y)
ang:RotateAroundAxis(ang:Right(), v.angle.p)
ang:RotateAroundAxis(ang:Forward(), v.angle.r)
model:SetAngles(ang)
//model:SetModelScale(v.size)
local matrix = Matrix()
matrix:Scale(v.size)
model:EnableMatrix( "RenderMultiply", matrix )
if (v.material == "") then
model:SetMaterial("")
elseif (model:GetMaterial() != v.material) then
model:SetMaterial( v.material )
end
if (v.skin and v.skin != model:GetSkin()) then
model:SetSkin(v.skin)
end
if (v.bodygroup) then
for k, v in pairs( v.bodygroup ) do
if (model:GetBodygroup(k) != v) then
model:SetBodygroup(k, v)
end
end
end
if (v.surpresslightning) then
render.SuppressEngineLighting(true)
end
render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
render.SetBlend(v.color.a/255)
model:DrawModel()
render.SetBlend(1)
render.SetColorModulation(1, 1, 1)
if (v.surpresslightning) then
render.SuppressEngineLighting(false)
end
elseif (v.type == "Sprite" and sprite) then
local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
render.SetMaterial(sprite)
render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
elseif (v.type == "Quad" and v.draw_func) then
local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
ang:RotateAroundAxis(ang:Up(), v.angle.y)
ang:RotateAroundAxis(ang:Right(), v.angle.p)
ang:RotateAroundAxis(ang:Forward(), v.angle.r)
cam.Start3D2D(drawpos, ang, v.size)
v.draw_func( self )
cam.End3D2D()
end
end
end
SWEP.wRenderOrder = nil
function SWEP:DrawWorldModel()
if (self.ShowWorldModel == nil or self.ShowWorldModel) then
self:DrawModel()
end
if (!self.WElements) then return end
if (!self.wRenderOrder) then
self.wRenderOrder = {}
for k, v in pairs( self.WElements ) do
if (v.type == "Model") then
table.insert(self.wRenderOrder, 1, k)
elseif (v.type == "Sprite" or v.type == "Quad") then
table.insert(self.wRenderOrder, k)
end
end
end
if (IsValid(self.Owner)) then
bone_ent = self.Owner
else
// when the weapon is dropped
bone_ent = self
end
for k, name in pairs( self.wRenderOrder ) do
local v = self.WElements[name]
if (!v) then self.wRenderOrder = nil break end
if (v.hide) then continue end
local pos, ang
if (v.bone) then
pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
else
pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
end
if (!pos) then continue end
local model = v.modelEnt
local sprite = v.spriteMaterial
if (v.type == "Model" and IsValid(model)) then
model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
ang:RotateAroundAxis(ang:Up(), v.angle.y)
ang:RotateAroundAxis(ang:Right(), v.angle.p)
ang:RotateAroundAxis(ang:Forward(), v.angle.r)
model:SetAngles(ang)
//model:SetModelScale(v.size)
local matrix = Matrix()
matrix:Scale(v.size)
model:EnableMatrix( "RenderMultiply", matrix )
if (v.material == "") then
model:SetMaterial("")
elseif (model:GetMaterial() != v.material) then
model:SetMaterial( v.material )
end
if (v.skin and v.skin != model:GetSkin()) then
model:SetSkin(v.skin)
end
if (v.bodygroup) then
for k, v in pairs( v.bodygroup ) do
if (model:GetBodygroup(k) != v) then
model:SetBodygroup(k, v)
end
end
end
if (v.surpresslightning) then
render.SuppressEngineLighting(true)
end
render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
render.SetBlend(v.color.a/255)
model:DrawModel()
render.SetBlend(1)
render.SetColorModulation(1, 1, 1)
if (v.surpresslightning) then
render.SuppressEngineLighting(false)
end
elseif (v.type == "Sprite" and sprite) then
local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
render.SetMaterial(sprite)
render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
elseif (v.type == "Quad" and v.draw_func) then
local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
ang:RotateAroundAxis(ang:Up(), v.angle.y)
ang:RotateAroundAxis(ang:Right(), v.angle.p)
ang:RotateAroundAxis(ang:Forward(), v.angle.r)
cam.Start3D2D(drawpos, ang, v.size)
v.draw_func( self )
cam.End3D2D()
end
end
end
function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
local bone, pos, ang
if (tab.rel and tab.rel != "") then
local v = basetab[tab.rel]
if (!v) then return end
--Technically, if there exists an element with the same name as a bone
// you can get in an infinite loop. Let's just hope nobody's that stupid.
pos, ang = self:GetBoneOrientation( basetab, v, ent )
if (!pos) then return end
pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
ang:RotateAroundAxis(ang:Up(), v.angle.y)
ang:RotateAroundAxis(ang:Right(), v.angle.p)
ang:RotateAroundAxis(ang:Forward(), v.angle.r)
else
bone = ent:LookupBone(bone_override or tab.bone)
if (!bone) then return end
pos, ang = Vector(0,0,0), Angle(0,0,0)
local m = ent:GetBoneMatrix(bone)
if (m) then
pos, ang = m:GetTranslation(), m:GetAngles()
end
if (IsValid(self.Owner) and self.Owner:IsPlayer() and
ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
ang.r = -ang.r // Fixes mirrored models
end
end
return pos, ang
end
function SWEP:CreateModels( tab )
if (!tab) then return end
// Create the clientside models here because Garry says we can't do it in the render hook
for k, v in pairs( tab ) do
if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
if (IsValid(v.modelEnt)) then
v.modelEnt:SetPos(self:GetPos())
v.modelEnt:SetAngles(self:GetAngles())
v.modelEnt:SetParent(self)
v.modelEnt:SetNoDraw(true)
v.createdModel = v.model
else
v.modelEnt = nil
end
elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
local name = v.sprite.."-"
local params = { ["$basetexture"] = v.sprite }
// make sure we create a unique name based on the selected options
local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
for i, j in pairs( tocheck ) do
if (v[j]) then
params["$"..j] = 1
name = name.."1"
else
name = name.."0"
end
end
v.createdSprite = v.sprite
v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
end
end
end
local allbones
local hasGarryFixedBoneScalingYet = false
function SWEP:UpdateBonePositions(vm)
if self.ViewModelBoneMods then
if (!vm:GetBoneCount()) then return end
// !! WORKAROUND !! //
// We need to check all model names :/
local loopthrough = self.ViewModelBoneMods
if (!hasGarryFixedBoneScalingYet) then
allbones = {}
for i=0, vm:GetBoneCount() do
local bonename = vm:GetBoneName(i)
if (self.ViewModelBoneMods[bonename]) then
allbones[bonename] = self.ViewModelBoneMods[bonename]
else
allbones[bonename] = {
scale = Vector(1,1,1),
pos = Vector(0,0,0),
angle = Angle(0,0,0)
}
end
end
loopthrough = allbones
end
// !! ----------- !! //
for k, v in pairs( loopthrough ) do
local bone = vm:LookupBone(k)
if (!bone) then continue end
// !! WORKAROUND !! //
local s = Vector(v.scale.x,v.scale.y,v.scale.z)
local p = Vector(v.pos.x,v.pos.y,v.pos.z)
local ms = Vector(1,1,1)
if (!hasGarryFixedBoneScalingYet) then
local cur = vm:GetBoneParent(bone)
while(cur >= 0) do
local pscale = loopthrough[vm:GetBoneName(cur)].scale
ms = ms * pscale
cur = vm:GetBoneParent(cur)
end
end
s = s * ms
// !! ----------- !! //
if vm:GetManipulateBoneScale(bone) != s then
vm:ManipulateBoneScale( bone, s )
end
if vm:GetManipulateBoneAngles(bone) != v.angle then
vm:ManipulateBoneAngles( bone, v.angle )
end
if vm:GetManipulateBonePosition(bone) != p then
vm:ManipulateBonePosition( bone, p )
end
end
else
self:ResetBonePositions(vm)
end
end
function SWEP:ResetBonePositions(vm)
if (!vm:GetBoneCount()) then return end
for i=0, vm:GetBoneCount() do
vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
end
end
/**************************
Global utility code
**************************/
// Fully copies the table, meaning all tables inside this table are copied too and so on (normal table.Copy copies only their reference).
// Does not copy entities of course, only copies their reference.
--// WARNING: do not use on tables that contain themselves somewhere down the line or you'll get an infinite loop
function table.FullCopy( tab )
if (!tab) then return nil end
local res = {}
for k, v in pairs( tab ) do
if (type(v) == "table") then
res[k] = table.FullCopy(v) // recursion ho!
elseif (type(v) == "Vector") then
res[k] = Vector(v.x, v.y, v.z)
elseif (type(v) == "Angle") then
res[k] = Angle(v.p, v.y, v.r)
else
res[k] = v
end
end
return res
end
end
function SWEP:DrawHands()
if (CLIENT) then
self.Hands = ClientsideModel("models/weapons/arms/v_arms_mechanic_new.mdl", RENDERGROUP_VIEWMODEL)
local vm = self.Owner:GetViewModel()
self.Hands:SetPos(vm:GetPos())
self.Hands:SetAngles(vm:GetAngles())
self.Hands:AddEffects(EF_BONEMERGE)
self.Hands:SetNoDraw(true)
self.Hands:SetParent(vm)
self.Hands:DrawModel()
end
end
function SWEP:Deploy()
self:SendWeaponAnim( ACT_VM_DEPLOY )
self:SetNextPrimaryFire( CurTime() + self.Owner:GetViewModel():SequenceDuration())
self:SetNextSecondaryFire( CurTime() + self.Owner:GetViewModel():SequenceDuration())
self.Weapon:EmitSound( "weapons/rifle/gunother/rifle_deploy_1.wav" )
timer.Create( "RecoilCustom"..self:EntIndex(),0,0, function()
if IsValid(self.Owner) and (self.Owner:IsNPC() or !self.Owner:Alive()) or !IsValid(self.Owner) or !IsValid(self) then timer.Remove( "RecoilCustom"..self:EntIndex()) return end
if self.Recoil > 0 then
self.Recoil = self.Recoil - 0.25
end
self.Owner:SetViewPunchAngles( Angle( -self.Recoil, 0, 0 ) )
end )
self.RecoilUp = 0
--self.Recoil1 = 0
end
function SWEP:PrimaryAttack()
if ( !self:CanPrimaryAttack() ) then return end
local vecDirShooting, vecRight, vecUp
shootAngles = self.Owner:EyeAngles() + self.Owner:GetViewPunchAngles()
vecDirShooting = shootAngles:Forward()
vecRight = shootAngles:Right()
vecUp = shootAngles:Up()
local x, y, z = 0, 0, 0
if self.Owner:IsPlayer() then
x = util.SharedRandom("SpreadX1", -0.5, 0.5,math.random(1,2e9)) + util.SharedRandom("SpreadX2", -0.5, 0.5,math.random(1,2e9))
y = util.SharedRandom("SpreadY1", -0.5, 0.5,math.random(1,2e9)) + util.SharedRandom("SpreadY2", -0.5, 0.5,math.random(1,2e9))
end
local vecDir = vecDirShooting + (x * 0.03 * vecRight) + (y * 0.03 * vecUp)
vecDir:Normalize()
local vecEnd = self.Owner:GetShootPos() + vecDir * 30000
local bullet = {}
bullet.Num = self.Primary.NumberofShots
bullet.Src = self.Owner:GetShootPos()
bullet.Dir = vecDir
bullet.Spread = 0
bullet.Tracer = 0
bullet.Force = self.Primary.Force
bullet.Damage = self.Primary.Damage
bullet.AmmoType = self.Primary.Ammo
local rnda = self.Primary.Recoil * -1
local rndb = self.Primary.Recoil * math.random(-1, 1)
self.RecoilUp = self.RecoilUp + 0.5
--self.Recoil1 = math.Rand(-3,3) unused
self:ShootEffects()
self.Owner:FireBullets( bullet )
self:EmitSound(Sound(self.Primary.Sound))
self.Owner:ViewPunch( Angle( math.Rand(-0.4,-0.2) * self.Primary.Recoil, 0, 0 ) )
self:TakePrimaryAmmo(self.Primary.TakeAmmo)
self.Recoil = self.RecoilUp
self:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
self:SetNextSecondaryFire( CurTime() + self.Primary.Delay )
end
function SWEP:SecondaryAttack()
if !(self.Weapon:GetNextSecondaryFire() < CurTime()) then return end
local tr = self.Owner:GetEyeTrace()
if (tr.HitPos - self.Owner:GetShootPos()):Length() < 64 then
if IsValid(tr.Entity) and SERVER then
local dmginfo = DamageInfo()
dmginfo:SetDamageType(DMG_CLUB)
dmginfo:SetAttacker(self.Owner)
dmginfo:SetInflictor(self)
dmginfo:SetDamage(15)
if tr.Entity:IsNPC() or tr.Entity:IsPlayer() then
dmginfo:SetDamageForce(self.Owner:GetForward()*3000)
else
if IsValid(tr.Entity:GetPhysicsObject()) then
tr.Entity:GetPhysicsObject():ApplyForceCenter(self.Owner:GetForward()*1000)
end
end
tr.Entity:TakeDamageInfo(dmginfo)
end
local vm = self.Owner:GetViewModel()
vm:SendViewModelMatchingSequence( vm:LookupSequence( "melee" ) )
self.Owner:SetAnimation( PLAYER_ATTACK1 )
self:SetNextSecondaryFire( CurTime() + 0.65 )
if SERVER then
self.Owner:EmitSound(Sound("player/survivor/hit/rifle_swing_hit_world.wav"))
end
else
if SERVER then
self.Owner:EmitSound(Sound("player/survivor/swing/swish_weaponswing_swipe"..math.random(5, 6)..".wav"))
end
local vm = self.Owner:GetViewModel()
vm:SendViewModelMatchingSequence( vm:LookupSequence( "melee" ) )
self.Owner:SetAnimation( PLAYER_ATTACK1 )
self:SetNextSecondaryFire( CurTime() + 1 )
end
end
function SWEP:Think()
self.Owner:SetViewPunchAngles( Angle( -self.Recoil, 0, 0 ) )
if self.Owner:KeyReleased( IN_ATTACK ) and !self.Owner:KeyDown( IN_ATTACK ) then
self.RecoilUp = 0
end
end
function SWEP:Reload()
if ( self.Weapon:Ammo1() <= 0 ) then return end
if ( self.Weapon:Clip1() >= self.Primary.ClipSize ) then return end
self.Weapon:DefaultReload( ACT_VM_RELOAD );
self.RecoilUp = 0
timer.Simple(0.4,function() self:EmitSound("weapons/rifle/gunother/rifle_clip_out_1.wav") end)
timer.Simple(0.9,function() self:EmitSound("weapons/rifle/gunother/rifle_clip_in_1.wav") end)
timer.Simple(1.1,function() self:EmitSound("weapons/rifle/gunother/rifle_clip_locked_1.wav") end)
timer.Simple(1.6,function() self:EmitSound("weapons/rifle/gunother/rifle_fullautobutton_1.wav") end)
end