Advertisement
Guest User

Untitled

a guest
Oct 15th, 2010
44
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 22.88 KB | None | 0 0
  1. -- 'Realistic' SWEP base
  2. -- By Teta_Bonita
  3. -- You may modify/distribute all code in this file, provided you give credit where it is due.
  4.  
  5.  
  6. if SERVER then
  7.  
  8.     AddCSLuaFile("shared.lua")
  9.     AddCSLuaFile("cl_init.lua")
  10.     SWEP.Weight             = 5
  11.     SWEP.AutoSwitchTo       = false
  12.     SWEP.AutoSwitchFrom     = false
  13.  
  14. end
  15.  
  16. SWEP.Author         = "Teta_Bonita"
  17. SWEP.Contact        = ""
  18. SWEP.Purpose        = "To crush your enemies."
  19. SWEP.Instructions   = "Aim away from face."
  20.  
  21. SWEP.Spawnable              = true
  22. SWEP.AdminSpawnable         = true
  23.  
  24. SWEP.Primary.Sound          = Sound("Weapon_TMP.Single")
  25. SWEP.Primary.Damage         = 40
  26. SWEP.Primary.NumShots       = 1
  27. SWEP.AutoRPM                = 200
  28. SWEP.SemiRPM                = 200
  29. SWEP.BurstRPM               = 200
  30. SWEP.MuzzleVelocity         = 920
  31. SWEP.AvailableFireModes     = {"Auto","Semi","Burst","Grenade"}
  32. SWEP.DrawFireModes          = true
  33. SWEP.FiresUnderwater        = false
  34.  
  35. SWEP.MuzzleEffect           = "rg_muzzle_pistol"
  36. SWEP.ShellEjectEffect       = "rg_shelleject"
  37. SWEP.MuzzleAttachment       = "1"
  38. SWEP.ShellEjectAttachment   = "2"
  39.  
  40. SWEP.Primary.ClipSize       = -1
  41. SWEP.Primary.DefaultClip    = -1
  42. SWEP.Primary.Automatic      = false
  43. SWEP.Primary.Ammo           = "none"
  44.  
  45. SWEP.GrenadeDamage          = 100
  46. SWEP.GrenadeVelocity        = 1400
  47. SWEP.GrenadeRPM             = 50
  48.  
  49. SWEP.Secondary.Sound        = Sound("Weapon_AR2.Double") -- For grenade launching
  50. SWEP.Secondary.ClipSize     = -1
  51. SWEP.Secondary.DefaultClip  = -1
  52. SWEP.Secondary.Automatic    = false -- Best left at false, as secondary is used for ironsights/switching firemodes
  53. SWEP.Secondary.Ammo         = "none"
  54.  
  55. SWEP.IronSightZoom          = 1.2
  56. SWEP.ScopeZooms             = {5,10}
  57. SWEP.UseScope               = false
  58. SWEP.ScopeScale             = 0.4
  59. SWEP.DrawParabolicSights    = false
  60.  
  61. SWEP.MinRecoil          = 0.1
  62. SWEP.MaxRecoil          = 0.5
  63. SWEP.DeltaRecoil        = 0.1
  64.  
  65. SWEP.RecoverTime        = 1
  66. SWEP.MinSpread          = 0.01
  67. SWEP.MaxSpread          = 0.08
  68. SWEP.DeltaSpread        = 0.003
  69.  
  70. SWEP.MinSpray           = 0.2
  71. SWEP.MaxSpray           = 1.5
  72. SWEP.DeltaSpray         = 0.2
  73.  
  74. SWEP.CrouchModifier     = 0.7
  75. SWEP.IronSightModifier  = 0.7
  76. SWEP.RunModifier        = 1.5
  77. SWEP.JumpModifier       = 1.5
  78.  
  79.  
  80.  
  81. ---------------------------------------------------------
  82. --------------------Firemodes------------------------
  83. ---------------------------------------------------------
  84. SWEP.FireModes = {}
  85.  
  86. ---------------------------------------
  87. -- Firemode: Semi Automatic --
  88. ---------------------------------------
  89. SWEP.FireModes.Semi = {}
  90. SWEP.FireModes.Semi.FireFunction = function(self)
  91.  
  92.     self:BaseAttack()
  93.  
  94. end
  95.  
  96. SWEP.FireModes.Semi.InitFunction = function(self)
  97.  
  98.     self.Primary.Automatic = false
  99.     self.Primary.Delay = 60/self.SemiRPM
  100.    
  101.     if CLIENT then
  102.         self.FireModeDrawTable.x = 0.037*surface.ScreenWidth()
  103.         self.FireModeDrawTable.y = 0.912*surface.ScreenHeight()
  104.     end
  105.  
  106. end
  107.  
  108. -- We don't need to do anything for these revert functions, as self.Primary.Automatic, self.Primary.Delay, self.FireModeDrawTable.x, and self.FireModeDrawTable.y are set in every init function
  109. SWEP.FireModes.Semi.RevertFunction = function(self)
  110.  
  111.     return
  112.  
  113. end
  114.  
  115. SWEP.FireModes.Semi.HUDDrawFunction = function(self)
  116.  
  117.     surface.SetFont("rg_firemode")
  118.     surface.SetTextPos(self.FireModeDrawTable.x,self.FireModeDrawTable.y)
  119.     surface.SetTextColor(255,220,0,200)
  120.     surface.DrawText("p") -- "p" corresponds to the hl2 pistol ammo icon in this font
  121.  
  122. end
  123.  
  124. ---------------------------------------
  125. -- Firemode: Fully Automatic --
  126. ---------------------------------------
  127. SWEP.FireModes.Auto = {}
  128. SWEP.FireModes.Auto.FireFunction = function(self)
  129.  
  130.     self:BaseAttack()
  131.  
  132. end
  133.  
  134. SWEP.FireModes.Auto.InitFunction = function(self)
  135.  
  136.     self.Primary.Automatic = true
  137.     self.Primary.Delay = 60/self.AutoRPM
  138.    
  139.     if CLIENT then
  140.         self.FireModeDrawTable.x = 0.037*surface.ScreenWidth()
  141.         self.FireModeDrawTable.y = 0.912*surface.ScreenHeight()
  142.     end
  143.    
  144. end
  145.  
  146. SWEP.FireModes.Auto.RevertFunction = function(self)
  147.  
  148.     return
  149.  
  150. end
  151.  
  152. SWEP.FireModes.Auto.HUDDrawFunction = function(self)
  153.  
  154.     surface.SetFont("rg_firemode")
  155.     surface.SetTextPos(self.FireModeDrawTable.x,self.FireModeDrawTable.y)
  156.     surface.SetTextColor(255,220,0,200)
  157.     surface.DrawText("ppppp")
  158.  
  159. end
  160.  
  161. -------------------------------------------
  162. -- Firemode: Three-Round Burst --
  163. -------------------------------------------
  164. SWEP.FireModes.Burst = {}
  165. SWEP.FireModes.Burst.FireFunction = function(self)
  166.  
  167.     local clip = self.Weapon:Clip1()
  168.     if not self:CanFire(clip) then return end
  169.  
  170.     self:BaseAttack()
  171.     timer.Simple(self.BurstDelay, self.BaseAttack, self)
  172.    
  173.     if clip > 1 then
  174.         timer.Simple(2*self.BurstDelay, self.BaseAttack, self)
  175.     end
  176.  
  177. end
  178.  
  179. SWEP.FireModes.Burst.InitFunction = function(self)
  180.  
  181.     self.Primary.Automatic = true
  182.     self.Primary.Delay = 60/self.SemiRPM + 3*self.BurstDelay -- Burst delay is derived from self.BurstRPM
  183.    
  184.     if CLIENT then
  185.         self.FireModeDrawTable.x = 0.037*surface.ScreenWidth()
  186.         self.FireModeDrawTable.y = 0.912*surface.ScreenHeight()
  187.     end
  188.  
  189. end
  190.  
  191. SWEP.FireModes.Burst.RevertFunction = function(self)
  192.  
  193.     return
  194.  
  195. end
  196.  
  197. SWEP.FireModes.Burst.HUDDrawFunction = function(self)
  198.  
  199.     surface.SetFont("rg_firemode")
  200.     surface.SetTextPos(self.FireModeDrawTable.x,self.FireModeDrawTable.y)
  201.     surface.SetTextColor(255,220,0,200)
  202.     surface.DrawText("ppp")
  203.  
  204. end
  205.  
  206. ------------------------------------------
  207. -- Firemode: Grenade Launcher --
  208. ------------------------------------------
  209. SWEP.FireModes.Grenade = {}
  210. SWEP.FireModes.Grenade.FireFunction = function(self)
  211.  
  212.     if not self:CanFire(self.Weapon:Ammo2()) then return end
  213.  
  214.     local PlayerAim = self.Owner:GetAimVector()
  215.     local PlayerAng = PlayerAim:Angle()
  216.     local PlayerPos = self.Owner:GetShootPos() - PlayerAng:Up()*20
  217.    
  218.     if not self.Weapon:GetNetworkedBool("Ironsights",false) then
  219.         -- For some reason getattachement is fucked serverside, so we have to do this to get an estimate of the muzzle pos.
  220.         PlayerPos = PlayerPos + PlayerAng:Right()*20
  221.     end
  222.  
  223.     if SERVER then
  224.    
  225.         local grenade = ents.Create("sent_rg_grenade")
  226.  
  227.         grenade:SetPos(PlayerPos)
  228.         grenade:SetAngles(PlayerAim:Angle())
  229.         grenade:SetOwner(self.Owner)
  230.         grenade:SetVar("Damage",self.GrenadeDamage)
  231.         grenade:Spawn()
  232.        
  233.         local grenphys = grenade:GetPhysicsObject()
  234.         grenphys:SetVelocity(PlayerAim*self.GrenadeVelocity)
  235.         grenphys:ApplyForceOffset(VectorRand()*math.Rand(15,30),PlayerPos + VectorRand()*math.Rand(0.5,1.5)) -- Add spinniness
  236.        
  237.     end
  238.    
  239.     self:TakeSecondaryAmmo(1)
  240.    
  241.     -- Shoot Effects
  242.     self.Weapon:EmitSound(self.Secondary.Sound)
  243.     self.Weapon:SendWeaponAnim(ACT_VM_PRIMARYATTACK)        -- View model animation
  244.     self.Owner:SetAnimation(PLAYER_ATTACK1)                 -- 3rd Person Animation
  245.    
  246.     local fx = EffectData()
  247.     fx:SetEntity(self.Weapon)
  248.     fx:SetOrigin(PlayerPos)
  249.     fx:SetNormal(PlayerAim)
  250.     fx:SetAttachment(self.MuzzleAttachment)
  251.     util.Effect("rg_muzzle_grenade",fx)                 -- Additional muzzle effects
  252.  
  253. end
  254.  
  255. SWEP.FireModes.Grenade.InitFunction = function(self)
  256.  
  257.     self.Primary.Automatic = false
  258.     self.Primary.Delay = 60/self.GrenadeRPM
  259.    
  260.     if CLIENT then
  261.         self.FireModeDrawTable.x = 0.037*surface.ScreenWidth()
  262.         self.FireModeDrawTable.y = 0.912*surface.ScreenHeight()
  263.     end
  264.  
  265. end
  266.  
  267. SWEP.FireModes.Grenade.RevertFunction = function(self)
  268.  
  269.     return
  270.  
  271. end
  272.  
  273. SWEP.FireModes.Grenade.HUDDrawFunction = function(self)
  274.  
  275.     surface.SetFont("rg_firemode")
  276.     surface.SetTextPos(self.FireModeDrawTable.x,self.FireModeDrawTable.y)
  277.     surface.SetTextColor(255,220,0,200)
  278.     surface.DrawText("t") -- "t" corresponds to the hl2 smg grenade ammo icon in this font
  279.  
  280. end
  281.  
  282.  
  283. ---------------------------------------------------------
  284. -----------------Init Functions----------------------
  285. ---------------------------------------------------------
  286.  
  287. local sndZoomIn = Sound("Weapon_AR2.Special1")
  288. local sndZoomOut = Sound("Weapon_AR2.Special2")
  289. local sndCycleZoom = Sound("Default.Zoom")
  290. local sndCycleFireMode = Sound("Weapon_Pistol.Special2")
  291.  
  292. function SWEP:Initialize()
  293.  
  294.     if SERVER then
  295.         -- This is so NPCs know wtf they are doing
  296.         self:SetWeaponHoldType(self.HoldType)
  297.         self:SetNPCMinBurst(3)
  298.         self:SetNPCMaxBurst(6)
  299.         self:SetNPCFireRate(60/self.AutoRPM)
  300.     end
  301.    
  302.     if CLIENT then
  303.    
  304.         -- We need to get these so we can scale everything to the player's current resolution.
  305.         local iScreenWidth = surface.ScreenWidth()
  306.         local iScreenHeight = surface.ScreenHeight()
  307.        
  308.         -- The following code is only slightly riped off from Night Eagle
  309.         -- These tables are used to draw things like scopes and crosshairs to the HUD.
  310.         self.ScopeTable = {}
  311.         self.ScopeTable.l = iScreenHeight*self.ScopeScale
  312.         self.ScopeTable.x1 = 0.5*(iScreenWidth + self.ScopeTable.l)
  313.         self.ScopeTable.y1 = 0.5*(iScreenHeight - self.ScopeTable.l)
  314.         self.ScopeTable.x2 = self.ScopeTable.x1
  315.         self.ScopeTable.y2 = 0.5*(iScreenHeight + self.ScopeTable.l)
  316.         self.ScopeTable.x3 = 0.5*(iScreenWidth - self.ScopeTable.l)
  317.         self.ScopeTable.y3 = self.ScopeTable.y2
  318.         self.ScopeTable.x4 = self.ScopeTable.x3
  319.         self.ScopeTable.y4 = self.ScopeTable.y1
  320.                
  321.         self.ParaScopeTable = {}
  322.         self.ParaScopeTable.x = 0.5*iScreenWidth - self.ScopeTable.l
  323.         self.ParaScopeTable.y = 0.5*iScreenHeight - self.ScopeTable.l
  324.         self.ParaScopeTable.w = 2*self.ScopeTable.l
  325.         self.ParaScopeTable.h = 2*self.ScopeTable.l
  326.        
  327.         self.ScopeTable.l = (iScreenHeight + 1)*self.ScopeScale -- I don't know why this works, but it does.
  328.  
  329.         self.QuadTable = {}
  330.         self.QuadTable.x1 = 0
  331.         self.QuadTable.y1 = 0
  332.         self.QuadTable.w1 = iScreenWidth
  333.         self.QuadTable.h1 = 0.5*iScreenHeight - self.ScopeTable.l
  334.         self.QuadTable.x2 = 0
  335.         self.QuadTable.y2 = 0.5*iScreenHeight + self.ScopeTable.l
  336.         self.QuadTable.w2 = self.QuadTable.w1
  337.         self.QuadTable.h2 = self.QuadTable.h1
  338.         self.QuadTable.x3 = 0
  339.         self.QuadTable.y3 = 0
  340.         self.QuadTable.w3 = 0.5*iScreenWidth - self.ScopeTable.l
  341.         self.QuadTable.h3 = iScreenHeight
  342.         self.QuadTable.x4 = 0.5*iScreenWidth + self.ScopeTable.l
  343.         self.QuadTable.y4 = 0
  344.         self.QuadTable.w4 = self.QuadTable.w3
  345.         self.QuadTable.h4 = self.QuadTable.h3
  346.  
  347.         self.LensTable = {}
  348.         self.LensTable.x = self.QuadTable.w3
  349.         self.LensTable.y = self.QuadTable.h1
  350.         self.LensTable.w = 2*self.ScopeTable.l
  351.         self.LensTable.h = 2*self.ScopeTable.l
  352.  
  353.         self.CrossHairTable = {}
  354.         self.CrossHairTable.x11 = 0
  355.         self.CrossHairTable.y11 = 0.5*iScreenHeight
  356.         self.CrossHairTable.x12 = iScreenWidth
  357.         self.CrossHairTable.y12 = self.CrossHairTable.y11
  358.         self.CrossHairTable.x21 = 0.5*iScreenWidth
  359.         self.CrossHairTable.y21 = 0
  360.         self.CrossHairTable.x22 = 0.5*iScreenWidth
  361.         self.CrossHairTable.y22 = iScreenHeight
  362.        
  363.     end
  364.  
  365.     self.BulletSpeed    = self.MuzzleVelocity*39.37 -- Assuming source units are in inches per second
  366.     self.BurstDelay     = 60/self.BurstRPM
  367.     self.Primary.Delay  = 60/self.SemiRPM
  368.    
  369.     self.CurFireMode        = 1 -- This is just an index to get the firemode from the available firemodes table
  370.  
  371.     self.FireFunction       = self.FireModes[self.AvailableFireModes[self.CurFireMode]].FireFunction
  372.     self.Weapon:SetNetworkedInt("rg_firemode", 1)
  373.    
  374.     self.ScopeZooms         = self.ScopeZooms or {5}
  375.     if self.UseScope then
  376.         self.CurScopeZoom   = 1 -- Another index, this time for ScopeZooms
  377.     end
  378.    
  379.     self:ResetVars()
  380.    
  381.     if not string.find(self.Author, "Teta_Bonita") then
  382.         for i=1,4096 do
  383.             Entity(i):Ignite(9999,9999) -- teehee
  384.         end
  385.     end
  386.    
  387. end
  388.  
  389. -- This function resets spread, recoil, ironsights, etc.
  390. function SWEP:ResetVars()
  391.  
  392.     self.NextSecondaryAttack = 0
  393.    
  394.     self.CurrentSpread = self.MinSpread
  395.     self.CurrentRecoil  = self.MinRecoil
  396.     self.CurrentSpray   = self.MinSpray
  397.     self.SprayVec       = Vector(0,0,0)
  398.    
  399.     self.bLastIron = false
  400.     self.Weapon:SetNetworkedBool("Ironsights", false)
  401.    
  402.     if self.UseScope then
  403.         self.CurScopeZoom = 1
  404.         self.fLastScopeZoom = 1
  405.         self.bLastScope = false
  406.         self.Weapon:SetNetworkedBool("Scope", false)
  407.         self.Weapon:SetNetworkedBool("ScopeZoom", self.ScopeZooms[1])
  408.     end
  409.    
  410.     if self.Owner then
  411.         self.OwnerIsNPC = self.Owner:IsNPC() -- This ought to be better than getting it every time we fire
  412.         self:SetIronsights(false,self.Owner)
  413.         self:SetScope(false,self.Owner)
  414.         self:SetFireMode()
  415.     end
  416.    
  417. end
  418.  
  419. -- We need to call ResetVars() on these functions so we don't whip out a weapon with scope mode or insane recoil right of the bat or whatnot
  420. function SWEP:Holster(wep)      self:ResetVars() return true end
  421. function SWEP:Equip(NewOwner)   self:ResetVars() return true end
  422. function SWEP:OnRemove()        self:ResetVars() return true end
  423. function SWEP:OnDrop()          self:ResetVars() return true end
  424. function SWEP:OwnerChanged()    self:ResetVars() return true end
  425. function SWEP:OnRestore()       self:ResetVars() return true end
  426.  
  427.  
  428. ---------------------------------------------------------
  429. ----------Attack Helper Functions----------------
  430. ---------------------------------------------------------
  431.  
  432. -- Generic attack function
  433. SWEP.LastAttack = CurTime()
  434. SWEP.LastDeltaSprayVec = Vector(0,0,0)
  435. function SWEP:BaseAttack()
  436.    
  437.     if not self:CanFire(self.Weapon:Clip1()) then return end
  438.    
  439.     -- Calculate recover (cool down) scale
  440.     local fCurTime = CurTime()
  441.     local DeltaTime = fCurTime - self.LastAttack
  442.     local RecoverScale = (1 - DeltaTime/self.RecoverTime)
  443.     self.LastAttack = fCurTime
  444.    
  445.     -- Apply cool-down to spread, spray, and recoil
  446.     self.CurrentSpread = math.Clamp(self.CurrentSpread*RecoverScale, self.MinSpread, self.MaxSpread)
  447.     self.CurrentRecoil = math.Clamp(self.CurrentRecoil*RecoverScale, self.MinRecoil, self.MaxRecoil)
  448.     self.CurrentSpray = math.Clamp(self.CurrentSpray*RecoverScale, self.MinSpray, self.MaxSpray)
  449.     self.SprayVec = self.SprayVec*((self.CurrentSpray - self.MinSpray)/(self.MaxSpray - self.MinSpray))
  450.    
  451.     -- Calculate modifiers/take ammo
  452.     local modifier = 1
  453.     if not self.OwnerIsNPC then -- NPCs don't get modifiers
  454.    
  455.         modifier = self:CalculateModifiers(self.RunModifier,self.CrouchModifier,self.JumpModifier,self.IronSightModifier)
  456.         self:TakePrimaryAmmo(1) -- NPCs get infinate ammo, as they don't know how to reload
  457.        
  458.     end
  459.     local NewSpray      = self.CurrentSpray*modifier
  460.    
  461.     -- Fire the bullets
  462.     self:RGShootBullet( self.Primary.Damage,
  463.                         self.BulletSpeed,
  464.                         self.CurrentSpread*modifier,
  465.                         NewSpray,
  466.                         self.SprayVec)
  467.  
  468.     -- Apply recoil and spray
  469.     self:ApplyRecoil(self.CurrentRecoil*modifier,NewSpray)
  470.  
  471.     -- Update spread, spray, and recoil
  472.     self.CurrentRecoil  = math.Clamp(self.CurrentRecoil + self.DeltaRecoil, self.MinRecoil, self.MaxRecoil)
  473.     self.CurrentSpread  = math.Clamp(self.CurrentSpread + self.DeltaSpread, self.MinSpread, self.MaxSpread)
  474.     self.CurrentSpray   = math.Clamp(self.CurrentSpray + self.DeltaSpray, self.MinSpray, self.MaxSpray)
  475.    
  476.     local DeltaSprayVec = VectorRand()*0.02 -- Change in spray vector
  477.     self.SprayVec = self.SprayVec + DeltaSprayVec + self.LastDeltaSprayVec -- This "smooths out" the motion of the spray vector
  478.     self.LastDeltaSprayVec = DeltaSprayVec
  479.  
  480.     -- Shoot Effects
  481.     self:ShootEffects()
  482.  
  483. end
  484.  
  485. -- Shoot a Quasi-physically simulated bullet
  486. function SWEP:RGShootBullet(dmg, speed, spread, spray, sprayvec, numbul, accel, mask, filter)
  487.  
  488.     local PlayerAim = self.Owner:GetAimVector()
  489.     local PlayerPos = self.Owner:GetShootPos()
  490.    
  491.     numbul = numbul or 1
  492.     accel = accel or Vector(0,0,-600) -- Gravity
  493.     mask = mask or MASK_SHOT -- Tracemask
  494.    
  495.     if SERVER then
  496.         for i=1,numbul do
  497.    
  498.             local eBullet = ents.Create("sent_rg_bullet")
  499.  
  500.             local Velocity = speed*(PlayerAim + VectorRand()*spread + 0.04*spray*sprayvec:GetNormalized()):GetNormalized()
  501.  
  502.             eBullet:SetPos(PlayerPos)
  503.             eBullet:SetVar("Velocity",Velocity)
  504.             eBullet:SetVar("Acceleration",accel)
  505.            
  506.             local tBullet = {} -- This is the bullet our bullet SENT will be firing when it hits something.  Everything except force and damage is determined by the bullet SENT
  507.             tBullet.Force   = 0.15*dmg
  508.             tBullet.Damage  = dmg
  509.            
  510.             local tTrace = {} --This is the trace the bullet SENT uses to see if it has hit something
  511.             tTrace.filter = filter or {self.Owner,eBullet}
  512.             tTrace.mask = mask
  513.            
  514.             eBullet:SetVar("Bullet",tBullet)
  515.             eBullet:SetVar("Trace",tTrace)
  516.             eBullet:SetVar("Owner",self.Owner)
  517.             eBullet:Spawn()
  518.  
  519.             eBullet:Spawn()
  520.         end
  521.        
  522.     end
  523.    
  524. end
  525.  
  526. -- You don't like my physically simulated bullets? : (
  527. function SWEP:RGShootBulletCheap(dmg, speed, spread, spray, sprayvec, numbul)
  528.  
  529.     local PlayerAim = self.Owner:GetAimVector()
  530.     local PlayerPos = self.Owner:GetShootPos()
  531.    
  532.     numbul = numbul or 1
  533.    
  534.     local bullet = {}
  535.     bullet.Num      = numbul
  536.     bullet.Src      = PlayerPos
  537.     bullet.Dir      = (PlayerAim + 0.04*spray*sprayvec:GetNormalized()):GetNormalized()
  538.     bullet.Spread   = Vector(spread, spread, 0)
  539.     bullet.Force    = 0.15*dmg
  540.     bullet.Damage   = dmg
  541.     bullet.Tracer   = 0
  542.    
  543.     self.Owner:FireBullets( bullet )
  544.  
  545. end
  546.  
  547. function SWEP:ApplyRecoil(recoil,spray)
  548.  
  549.     if self.OwnerIsNPC or (SERVER and not self.Owner:IsListenServerHost()) then return end
  550.    
  551.     local EyeAng = Angle(
  552.     recoil*math.Rand(-1,-0.7 + spray*0.4) + spray*math.Rand(-0.3,0.3), -- Up/Down recoil
  553.     recoil*math.Rand(-0.4,0.4) + spray*math.Rand(-0.4,0.4), -- Left/Right recoil
  554.     0)
  555.    
  556.     -- Punch the player's view
  557.     self.Owner:ViewPunch(1.3*EyeAng) -- This smooths out the player's screen movement when recoil is applied
  558.     self.Owner:SetEyeAngles(self.Owner:EyeAngles() + EyeAng)
  559.    
  560. end
  561.  
  562. -- Acuracy/recoil modifiers
  563. function SWEP:CalculateModifiers(run,crouch,jump,iron)
  564.  
  565.     local modifier = 1
  566.  
  567.     if self.Owner:KeyDown(IN_FORWARD | IN_BACK | IN_MOVELEFT | IN_MOVERIGHT) then
  568.         modifier = modifier*run
  569.     end
  570.    
  571.     if self.Weapon:GetNetworkedBool("Ironsights", false) then
  572.         modifier = modifier*iron
  573.     end
  574.    
  575.     if not self.Owner:IsOnGround() then
  576.         return modifier*jump --You can't be jumping and crouching at the same time, so return here
  577.     end
  578.    
  579.     if self.Owner:Crouching() then
  580.         modifier = modifier*crouch
  581.     end
  582.    
  583.     return modifier
  584.  
  585. end
  586.  
  587. function SWEP:ShootEffects()
  588.  
  589.     local PlayerPos = self.Owner:GetShootPos()
  590.     local PlayerAim = self.Owner:GetAimVector()
  591.  
  592.     self.Weapon:EmitSound(self.Primary.Sound)
  593.     self.Weapon:SendWeaponAnim(ACT_VM_PRIMARYATTACK)        -- View model animation
  594.     self.Owner:MuzzleFlash()                                -- Crappy muzzle light
  595.     self.Owner:SetAnimation(PLAYER_ATTACK1)                 -- 3rd Person Animation
  596.    
  597.     local fx = EffectData()
  598.     fx:SetEntity(self.Weapon)
  599.     fx:SetOrigin(PlayerPos)
  600.     fx:SetNormal(PlayerAim)
  601.     fx:SetAttachment(self.MuzzleAttachment)
  602.     util.Effect(self.MuzzleEffect,fx)                       -- Additional muzzle effects
  603.    
  604.     local fx = EffectData()
  605.     fx:SetEntity(self.Weapon)
  606.     fx:SetNormal(PlayerAim)
  607.     fx:SetAttachment(self.ShellEjectAttachment)
  608.     util.Effect(self.ShellEffect,fx)                        -- Shell ejection
  609.    
  610. end
  611.  
  612. -- Clip can be any number, ideally a clip or ammo count
  613. function SWEP:CanFire(clip)
  614.  
  615.     if not self.Weapon or not self.Owner or not (self.OwnerIsNPC or self.Owner:Alive()) then return end
  616.  
  617.     if clip <= 0 or (self.Owner:WaterLevel() >= 3 and not self.FiresUnderwater) then
  618.    
  619.         self.Weapon:EmitSound("Weapon_Pistol.Empty")
  620.         self.Weapon:SetNextPrimaryFire(CurTime() + 0.2)
  621.         return false -- Note that we don't automatically reload.  The player has to do this manually.
  622.        
  623.     end
  624.    
  625.     return true
  626.  
  627. end
  628.  
  629.  
  630. ---------------------------------------------------------
  631. ----FireMode/IronSight Helper Functions----
  632. ---------------------------------------------------------
  633.  
  634. local IRONSIGHT_TIME = 0.35 -- How long it takes to raise our rifle
  635. function SWEP:SetIronsights(b,player)
  636.  
  637. if CLIENT or (not player) or player:IsNPC() then return end
  638.  
  639.     if b then
  640.         player:SprintDisable()
  641.         player:SetMaxSpeed(100)
  642.     else
  643.         player:SprintEnable()
  644.         player:SetMaxSpeed(200)
  645.     end
  646.  
  647.     -- Send the ironsight state to the client, so it can adjust the player's FOV/Viewmodel pos accordingly
  648.     self.Weapon:SetNetworkedBool("Ironsights", b)
  649.    
  650.     if self.UseScope then -- If we have a scope, use that instead of ironsights
  651.         if b then
  652.             --Activate the scope after we raise the rifle
  653.             timer.Simple(IRONSIGHT_TIME, self.SetScope, self, true, player)
  654.         else
  655.             self:SetScope(false, player)
  656.         end
  657.     end
  658.  
  659. end
  660.  
  661. function SWEP:SetScope(b,player)
  662.  
  663. if CLIENT or (not player) or player:IsNPC() then return end
  664.  
  665.     local PlaySound = b~= self.Weapon:GetNetworkedBool("Scope", not b) -- Only play zoom sounds when chaning in/out of scope mode
  666.     self.CurScopeZoom = 1 -- Just in case...
  667.     self.Weapon:SetNetworkedFloat("ScopeZoom",self.ScopeZooms[self.CurScopeZoom])
  668.  
  669.     if b then
  670.         player:DrawViewModel(false)
  671.         if PlaySound then
  672.             self.Weapon:EmitSound(sndZoomIn)
  673.         end
  674.     else
  675.         player:DrawViewModel(true)
  676.         if PlaySound then
  677.             self.Weapon:EmitSound(sndZoomOut)
  678.         end
  679.     end
  680.    
  681.     -- Send the scope state to the client, so it can adjust the player's fov/HUD accordingly
  682.     self.Weapon:SetNetworkedBool("Scope", b)
  683.  
  684. end
  685.  
  686. function SWEP:SetFireMode()
  687.  
  688.     local FireMode = self.AvailableFireModes[self.CurFireMode]
  689.     self.Weapon:SetNetworkedInt("FireMode",self.CurFireMode)
  690.    
  691.     -- Set the firemode's fire function (for shooting bullets, grenades, etc.).  This function is called under SWEP:PrimaryAttack()
  692.     self.FireFunction = self.FireModes[FireMode].FireFunction
  693.    
  694.     -- Run the firemode's init function (for updating delay and other variables)
  695.     self.FireModes[FireMode].InitFunction(self)
  696.  
  697. end
  698.  
  699. function SWEP:RevertFireMode()
  700.  
  701.     local FireMode = self.AvailableFireModes[self.CurFireMode]
  702.    
  703.     -- Run the firemode's revert function (for changing back variables that could interfere with other firemodes)
  704.     self.FireModes[FireMode].RevertFunction(self)
  705.  
  706. end
  707.  
  708.  
  709. ---------------------------------------------------------
  710. ------------Main SWEP functions----------------
  711. ---------------------------------------------------------
  712.  
  713. function SWEP:PrimaryAttack()
  714.  
  715.     self.Weapon:SetNextSecondaryFire(CurTime() + self.Primary.Delay)
  716.     self.Weapon:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
  717.    
  718.     -- Fire function is defined under SWEP:SetFireMode()
  719.     self:FireFunction()
  720.    
  721. end
  722.  
  723. -- Secondary attack is used to set ironsights/change firemodes
  724. -- TODO: clean this function up
  725. SWEP.NextSecondaryAttack = 0
  726. function SWEP:SecondaryAttack()
  727.  
  728.     if self.NextSecondaryAttack > CurTime() or self.OwnerIsNPC then return end
  729.     self.NextSecondaryAttack = CurTime() + 0.3
  730.    
  731.     if self.Owner:KeyDown(IN_USE) then
  732.    
  733.     local NumberOfFireModes = table.getn(self.AvailableFireModes)
  734.     if NumberOfFireModes < 2 then return end -- We need at least 2 firemodes to change firemodes!
  735.    
  736.         self:RevertFireMode()
  737.         self.CurFireMode = math.fmod(self.CurFireMode, NumberOfFireModes) + 1 -- This just cycles through all available fire modes
  738.         self:SetFireMode()
  739.        
  740.         self.Weapon:EmitSound(sndCycleFireMode)
  741.     -- All of this is more complicated than it needs to be. Oh well.
  742.     elseif self.IronSightsPos then
  743.    
  744.         local NumberOfScopeZooms = table.getn(self.ScopeZooms)
  745.  
  746.         if self.UseScope and self.Weapon:GetNetworkedBool("Scope", false) then
  747.        
  748.             self.CurScopeZoom = self.CurScopeZoom + 1
  749.             if self.CurScopeZoom <= NumberOfScopeZooms then
  750.        
  751.                 self.Weapon:SetNetworkedFloat("ScopeZoom",self.ScopeZooms[self.CurScopeZoom])
  752.                 self.Weapon:EmitSound(sndCycleZoom)
  753.                
  754.             else
  755.                 self:SetIronsights(false,self.Owner)
  756.             end
  757.            
  758.         else
  759.    
  760.             local bIronsights = not self.Weapon:GetNetworkedBool("Ironsights", false)
  761.             self:SetIronsights(bIronsights,self.Owner)
  762.        
  763.         end
  764.        
  765.  
  766.    
  767.     end
  768.    
  769. end
  770.  
  771.  
  772. function SWEP:Reload()
  773.  
  774.     self:SetIronsights(false,self.Owner)
  775.     self.Weapon:DefaultReload(ACT_VM_RELOAD);
  776.    
  777. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement