Advertisement
Guest User

awp base

a guest
Jul 27th, 2015
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 41.92 KB | None | 0 0
  1. -- Variables that are used on both client and server
  2. SWEP.Category = ""
  3. SWEP.Gun = ""
  4. SWEP.Author = "Generic Default, Worshipper, Clavus, and Bob"
  5. SWEP.Contact = ""
  6. SWEP.Purpose = ""
  7. SWEP.Instructions = ""
  8. SWEP.MuzzleAttachment = "1" -- Should be "1" for CSS models or "muzzle" for hl2 models
  9. SWEP.DrawCrosshair = true -- Hell no, crosshairs r 4 nubz!
  10. SWEP.ViewModelFOV = 65 -- How big the gun will look
  11. SWEP.ViewModelFlip = true -- True for CSS models, False for HL2 models
  12.  
  13. SWEP.Spawnable = false
  14. SWEP.AdminSpawnable = false
  15.  
  16. SWEP.Primary.Sound = Sound("") -- Sound of the gun
  17. SWEP.Primary.Round = ("") -- What kind of bullet?
  18. SWEP.Primary.Cone = 0.2 -- Accuracy of NPCs
  19. SWEP.Primary.Recoil = 10
  20. SWEP.Primary.Damage = 10
  21. SWEP.Primary.Spread = .01 --define from-the-hip accuracy (1 is terrible, .0001 is exact)
  22. SWEP.Primary.NumShots = 1
  23. SWEP.Primary.RPM = 50 -- This is in Rounds Per Minute
  24. SWEP.Primary.ClipSize = 5 -- Size of a clip
  25. SWEP.Primary.ClipMax = 5
  26. SWEP.Primary.DefaultClip = 5 -- Default number of bullets in a clip
  27. SWEP.Primary.KickUp = 0 -- Maximum up recoil (rise)
  28. SWEP.Primary.KickDown = 0 -- Maximum down recoil (skeet)
  29. SWEP.Primary.KickHorizontal = 0 -- Maximum side recoil (koolaid)
  30. SWEP.Primary.Automatic = true -- Automatic/Semi Auto
  31. SWEP.Primary.Ammo = "none" -- What kind of ammo
  32.  
  33. SWEP.Secondary.ClipSize = 0 -- Size of a clip
  34. SWEP.Secondary.DefaultClip = 0 -- Default number of bullets in a clip
  35. SWEP.Secondary.Automatic = false -- Automatic/Semi Auto
  36. SWEP.Secondary.Ammo = "none"
  37. SWEP.Secondary.IronFOV = 0 -- How much you 'zoom' in. Less is more!
  38.  
  39. SWEP.Penetration = true
  40. SWEP.Ricochet = true
  41. SWEP.MaxRicochet = 1
  42. SWEP.RicochetCoin = 1
  43. SWEP.BoltAction = false
  44. SWEP.Scoped = false
  45. SWEP.ShellTime = .35
  46. SWEP.Tracer = 0
  47. SWEP.CanBeSilenced = false
  48. SWEP.Silenced = false
  49. SWEP.NextSilence = 0
  50. SWEP.SelectiveFire = false
  51. SWEP.NextFireSelect = 0
  52. SWEP.OrigCrossHair = true
  53.  
  54. local PainMulti = 1
  55.  
  56. if GetConVar("M9KDamageMultiplier") == nil then
  57. PainMulti = 1
  58. print("M9KDamageMultiplier is missing! You may have hit the lua limit! Reverting multiplier to 1.")
  59. else
  60. PainMulti = GetConVar("M9KDamageMultiplier"):GetFloat()
  61. if PainMulti < 0 then
  62. PainMulti = PainMulti * -1
  63. print("Your damage multiplier was in the negatives. It has been reverted to a positive number. Your damage multiplier is now "..PainMulti)
  64. end
  65. end
  66.  
  67. function NewM9KDamageMultiplier(cvar, previous, new)
  68. print("multiplier has been changed ")
  69. if GetConVar("M9KDamageMultiplier") == nil then
  70. PainMulti = 1
  71. print("M9KDamageMultiplier is missing! You may have hit the lua limit! Reverting multiplier to 1, you will notice no changes.")
  72. else
  73. PainMulti = GetConVar("M9KDamageMultiplier"):GetFloat()
  74. if PainMulti < 0 then
  75. PainMulti = PainMulti * -1
  76. print("Your damage multiplier was in the negatives. It has been reverted to a positive number. Your damage multiplier is now "..PainMulti)
  77. end
  78. end
  79. end
  80. cvars.AddChangeCallback("M9KDamageMultiplier", NewM9KDamageMultiplier)
  81.  
  82. function NewDefClips(cvar, previous, new)
  83. print("Default clip multiplier has changed. A server restart will be required for these changes to take effect.")
  84. end
  85. cvars.AddChangeCallback("M9KDefaultClip", NewDefClips)
  86.  
  87. if GetConVar("M9KDefaultClip") == nil then
  88. print("M9KDefaultClip is missing! You may have hit the lua limit!")
  89. else
  90. if GetConVar("M9KDefaultClip"):GetFloat() >= 0 then
  91. print("M9K Weapons will now spawn with "..GetConVar("M9KDefaultClip"):GetFloat().." clips.")
  92. else
  93. print("Default clips will be not be modified")
  94. end
  95. end
  96.  
  97. SWEP.IronSightsPos = Vector (2.4537, 1.0923, 0.2696)
  98. SWEP.IronSightsAng = Vector (0.0186, -0.0547, 0)
  99.  
  100. SWEP.VElements = {}
  101. SWEP.WElements = {}
  102.  
  103. function SWEP:Initialize()
  104.  
  105. self.Reloadaftershoot = 0 -- Can't reload when firing
  106. self:SetHoldType(self.HoldType)
  107. self.OrigCrossHair = self.DrawCrosshair
  108. if SERVER and self.Owner:IsNPC() then
  109. self:SetNPCMinBurst(3)
  110. self:SetNPCMaxBurst(10) -- None of this really matters but you need it here anyway
  111. self:SetNPCFireRate(1/(self.Primary.RPM/60))
  112. self:SetCurrentWeaponProficiency( WEAPON_PROFICIENCY_VERY_GOOD )
  113. end
  114.  
  115. if CLIENT then
  116.  
  117. -- // Create a new table for every weapon instance
  118. self.VElements = table.FullCopy( self.VElements )
  119. self.WElements = table.FullCopy( self.WElements )
  120. self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
  121.  
  122. self:CreateModels(self.VElements) -- create viewmodels
  123. self:CreateModels(self.WElements) -- create worldmodels
  124.  
  125. -- // init view model bone build function
  126. if IsValid(self.Owner) and self.Owner:IsPlayer() then
  127. if self.Owner:Alive() then
  128. local vm = self.Owner:GetViewModel()
  129. if IsValid(vm) then
  130. self:ResetBonePositions(vm)
  131. -- // Init viewmodel visibility
  132. if (self.ShowViewModel == nil or self.ShowViewModel) then
  133. vm:SetColor(Color(255,255,255,255))
  134. else
  135. -- // 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
  136. vm:SetMaterial("Debug/hsv")
  137. end
  138. end
  139.  
  140. end
  141. end
  142.  
  143. end
  144.  
  145. if CLIENT then
  146. local oldpath = "vgui/hud/name" -- the path goes here
  147. local newpath = string.gsub(oldpath, "name", self.Gun)
  148. self.WepSelectIcon = surface.GetTextureID(newpath)
  149. end
  150.  
  151. end
  152.  
  153. function SWEP:Deploy()
  154. self:SetIronsights(false, self.Owner) -- Set the ironsight false
  155. self:SetHoldType(self.HoldType)
  156.  
  157. if self.Silenced then
  158. self.Weapon:SendWeaponAnim( ACT_VM_DRAW_SILENCED )
  159. else
  160. self.Weapon:SendWeaponAnim( ACT_VM_DRAW )
  161. end
  162.  
  163. self.Weapon:SetNWBool("Reloading", false)
  164.  
  165. if !self.Owner:IsNPC() and self.Owner != nil then
  166. if self.ResetSights and self.Owner:GetViewModel() != nil then
  167. self.ResetSights = CurTime() + self.Owner:GetViewModel():SequenceDuration()
  168. end
  169. end
  170. return true
  171. end
  172.  
  173. function SWEP:Holster()
  174.  
  175. if CLIENT and IsValid(self.Owner) and not self.Owner:IsNPC() then
  176. local vm = self.Owner:GetViewModel()
  177. if IsValid(vm) then
  178. self:ResetBonePositions(vm)
  179. end
  180. end
  181.  
  182. return true
  183. end
  184.  
  185. function SWEP:OnRemove()
  186.  
  187. if CLIENT and IsValid(self.Owner) and not self.Owner:IsNPC() then
  188. local vm = self.Owner:GetViewModel()
  189. if IsValid(vm) then
  190. self:ResetBonePositions(vm)
  191. end
  192. end
  193.  
  194. end
  195.  
  196. function SWEP:GetCapabilities()
  197. return CAP_WEAPON_RANGE_ATTACK1, CAP_INNATE_RANGE_ATTACK1
  198. end
  199.  
  200. function SWEP:Precache()
  201. util.PrecacheSound(self.Primary.Sound)
  202. util.PrecacheModel(self.ViewModel)
  203. util.PrecacheModel(self.WorldModel)
  204. end
  205.  
  206. function SWEP:PrimaryAttack()
  207. if self:CanPrimaryAttack() and self.Owner:IsPlayer() then
  208. if !self.Owner:KeyDown(IN_SPEED) and !self.Owner:KeyDown(IN_RELOAD) then
  209. self:ShootBulletInformation()
  210. self.Weapon:TakePrimaryAmmo(1)
  211.  
  212. if self.Silenced then
  213. self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK_SILENCED )
  214. self.Weapon:EmitSound(self.Primary.SilencedSound)
  215. else
  216. self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK )
  217. self.Weapon:EmitSound(self.Primary.Sound)
  218. end
  219.  
  220. local fx = EffectData()
  221. fx:SetEntity(self.Weapon)
  222. fx:SetOrigin(self.Owner:GetShootPos())
  223. fx:SetNormal(self.Owner:GetAimVector())
  224. fx:SetAttachment(self.MuzzleAttachment)
  225. if GetConVar("M9KGasEffect") != nil then
  226. if GetConVar("M9KGasEffect"):GetBool() then
  227. util.Effect("m9k_rg_muzzle_rifle",fx)
  228. end
  229. end
  230. self.Owner:SetAnimation( PLAYER_ATTACK1 )
  231. self.Owner:MuzzleFlash()
  232. self.Weapon:SetNextPrimaryFire(CurTime()+1/(self.Primary.RPM/60))
  233. self:CheckWeaponsAndAmmo()
  234. self.RicochetCoin = (math.random(1,4))
  235. if self.BoltAction then self:BoltBack() end
  236. end
  237. elseif self:CanPrimaryAttack() and self.Owner:IsNPC() then
  238. self:ShootBulletInformation()
  239. self.Weapon:TakePrimaryAmmo(1)
  240. self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK )
  241. self.Weapon:EmitSound(self.Primary.Sound)
  242. self.Owner:SetAnimation( PLAYER_ATTACK1 )
  243. self.Owner:MuzzleFlash()
  244. self.Weapon:SetNextPrimaryFire(CurTime()+1/(self.Primary.RPM/60))
  245. self.RicochetCoin = (math.random(1,4))
  246. end
  247. end
  248.  
  249. function SWEP:CheckWeaponsAndAmmo()
  250. if SERVER and self.Weapon != nil and (GetConVar("M9KWeaponStrip"):GetBool()) then
  251. if self.Weapon:Clip1() == 0 && self.Owner:GetAmmoCount( self.Weapon:GetPrimaryAmmoType() ) == 0 then
  252. timer.Simple(.1, function() if SERVER then if not IsValid(self) then return end
  253. if self.Owner == nil then return end
  254. self.Owner:StripWeapon(self.Gun)
  255. end end)
  256. end
  257. end
  258. end
  259.  
  260.  
  261. /*---------------------------------------------------------
  262. Name: SWEP:ShootBulletInformation()
  263. Desc: This func add the damage, the recoil, the number of shots and the cone on the bullet.
  264. ---------------------------------------------------------*/
  265. function SWEP:ShootBulletInformation()
  266.  
  267. local CurrentDamage
  268. local CurrentRecoil
  269. local CurrentCone
  270. local basedamage
  271.  
  272. if (self:GetIronsights() == true) and self.Owner:KeyDown(IN_ATTACK2) then
  273. CurrentCone = self.Primary.IronAccuracy
  274. else
  275. CurrentCone = self.Primary.Spread
  276. end
  277. local damagedice = math.Rand(.85,1.3)
  278.  
  279. basedamage = PainMulti * self.Primary.Damage
  280. CurrentDamage = basedamage * damagedice
  281. CurrentRecoil = self.Primary.Recoil
  282.  
  283. -- Player is aiming
  284. if (self:GetIronsights() == true) and self.Owner:KeyDown(IN_ATTACK2) then
  285. self:ShootBullet(CurrentDamage, CurrentRecoil / 6, self.Primary.NumShots, CurrentCone)
  286. -- Player is not aiming
  287. else
  288. self:ShootBullet(CurrentDamage, CurrentRecoil, self.Primary.NumShots, CurrentCone)
  289. end
  290.  
  291. end
  292.  
  293. /*---------------------------------------------------------
  294. Name: SWEP:ShootBullet()
  295. Desc: A convenience func to shoot bullets.
  296. ---------------------------------------------------------*/
  297. local TracerName = "Tracer"
  298.  
  299. function SWEP:ShootBullet(damage, recoil, num_bullets, aimcone)
  300.  
  301. num_bullets = num_bullets or 1
  302. aimcone = aimcone or 0
  303.  
  304. self:ShootEffects()
  305.  
  306. if self.Tracer == 1 then
  307. TracerName = "Ar2Tracer"
  308. elseif self.Tracer == 2 then
  309. TracerName = "AirboatGunHeavyTracer"
  310. else
  311. TracerName = "Tracer"
  312. end
  313.  
  314. local bullet = {}
  315. bullet.Num = num_bullets
  316. bullet.Src = self.Owner:GetShootPos() -- Source
  317. bullet.Dir = self.Owner:GetAimVector() -- Dir of bullet
  318. bullet.Spread = Vector(aimcone, aimcone, 0) -- Aim Cone
  319. bullet.Tracer = 3 -- Show a tracer on every x bullets
  320. bullet.TracerName = TracerName
  321. bullet.Force = damage * 0.25 -- Amount of force to give to phys objects
  322. bullet.Damage = damage
  323. bullet.Callback = function(attacker, tracedata, dmginfo)
  324.  
  325. return self:RicochetCallback(0, attacker, tracedata, dmginfo)
  326. end
  327.  
  328. self.Owner:FireBullets(bullet)
  329. -- if SERVER and !self.Owner:IsNPC() then
  330. -- local anglo = Angle(math.Rand(-self.Primary.KickDown,-self.Primary.KickUp), math.Rand(-self.Primary.KickHorizontal,self.Primary.KickHorizontal), 0)
  331. -- self.Owner:ViewPunch(anglo)
  332.  
  333. -- local eyes = self.Owner:EyeAngles()
  334. -- eyes.pitch = eyes.pitch + anglo.pitch
  335. -- eyes.yaw = eyes.yaw + anglo.yaw
  336. -- if game.SinglePlayer() then self.Owner:SetEyeAngles(eyes) end
  337. -- end
  338.  
  339. local anglo1 = Angle(math.Rand(-self.Primary.KickDown,-self.Primary.KickUp), math.Rand(-self.Primary.KickHorizontal,self.Primary.KickHorizontal), 0)
  340. self.Owner:ViewPunch(anglo1)
  341.  
  342. if SERVER and game.SinglePlayer() and !self.Owner:IsNPC() then
  343. local offlineeyes = self.Owner:EyeAngles()
  344. offlineeyes.pitch = offlineeyes.pitch + anglo1.pitch
  345. offlineeyes.yaw = offlineeyes.yaw + anglo1.yaw
  346. if GetConVar("M9KDynamicRecoil"):GetBool() then
  347. self.Owner:SetEyeAngles(offlineeyes)
  348. end
  349. end
  350.  
  351. if CLIENT and !game.SinglePlayer() and !self.Owner:IsNPC() then
  352. local anglo = Angle(math.Rand(-self.Primary.KickDown,-self.Primary.KickUp), math.Rand(-self.Primary.KickHorizontal,self.Primary.KickHorizontal), 0)
  353.  
  354. local eyes = self.Owner:EyeAngles()
  355. eyes.pitch = eyes.pitch + (anglo.pitch/3)
  356. eyes.yaw = eyes.yaw + (anglo.yaw/3)
  357. if GetConVar("M9KDynamicRecoil"):GetBool() then
  358. self.Owner:SetEyeAngles(eyes)
  359. end
  360. end
  361.  
  362. end
  363.  
  364. /*---------------------------------------------------------
  365. Name: SWEP:RicochetCallback()
  366. ---------------------------------------------------------*/
  367.  
  368. function SWEP:RicochetCallback(bouncenum, attacker, tr, dmginfo)
  369.  
  370. if not IsFirstTimePredicted() then
  371. return {damage = false, effects = false}
  372. end
  373.  
  374. local PenetrationChecker = false
  375.  
  376. if GetConVar("M9KDisablePenetration") == nil then
  377. PenetrationChecker = false
  378. else
  379. PenetrationChecker = GetConVar("M9KDisablePenetration"):GetBool()
  380. end
  381.  
  382. if PenetrationChecker then return {damage = true, effects = DoDefaultEffect} end
  383.  
  384. bulletmiss = {}
  385. bulletmiss[1]=Sound("weapons/fx/nearmiss/bulletLtoR03.wav")
  386. bulletmiss[2]=Sound("weapons/fx/nearmiss/bulletLtoR04.wav")
  387. bulletmiss[3]=Sound("weapons/fx/nearmiss/bulletLtoR06.wav")
  388. bulletmiss[4]=Sound("weapons/fx/nearmiss/bulletLtoR07.wav")
  389. bulletmiss[5]=Sound("weapons/fx/nearmiss/bulletLtoR09.wav")
  390. bulletmiss[6]=Sound("weapons/fx/nearmiss/bulletLtoR10.wav")
  391. bulletmiss[7]=Sound("weapons/fx/nearmiss/bulletLtoR13.wav")
  392. bulletmiss[8]=Sound("weapons/fx/nearmiss/bulletLtoR14.wav")
  393.  
  394. local DoDefaultEffect = true
  395. if (tr.HitSky) then return end
  396.  
  397. // -- Can we go through whatever we hit?
  398. if (self.Penetration) and (self:BulletPenetrate(bouncenum, attacker, tr, dmginfo)) then
  399. return {damage = true, effects = DoDefaultEffect}
  400. end
  401.  
  402. // -- Your screen will shake and you'll hear the savage hiss of an approaching bullet which passing if someone is shooting at you.
  403. if (tr.MatType != MAT_METAL) then
  404. if (SERVER) then
  405. util.ScreenShake(tr.HitPos, 5, 0.1, 0.5, 64)
  406. sound.Play(table.Random(bulletmiss), tr.HitPos, 75, math.random(75,150), 1)
  407. end
  408.  
  409. if self.Tracer == 0 or self.Tracer == 1 or self.Tracer == 2 then
  410. local effectdata = EffectData()
  411. effectdata:SetOrigin(tr.HitPos)
  412. effectdata:SetNormal(tr.HitNormal)
  413. effectdata:SetScale(20)
  414. util.Effect("AR2Impact", effectdata)
  415. elseif self.Tracer == 3 then
  416. local effectdata = EffectData()
  417. effectdata:SetOrigin(tr.HitPos)
  418. effectdata:SetNormal(tr.HitNormal)
  419. effectdata:SetScale(20)
  420. util.Effect("StunstickImpact", effectdata)
  421. end
  422.  
  423. return
  424. end
  425.  
  426. if (self.Ricochet == false) then return {damage = true, effects = DoDefaultEffect} end
  427.  
  428. if self.Primary.Ammo == "SniperPenetratedRound" then -- .50 Ammo
  429. self.MaxRicochet = 12
  430. elseif self.Primary.Ammo == "pistol" then -- pistols
  431. self.MaxRicochet = 2
  432. elseif self.Primary.Ammo == "357" then -- revolvers with big ass bullets
  433. self.MaxRicochet = 4
  434. elseif self.Primary.Ammo == "smg1" then -- smgs
  435. self.MaxRicochet = 5
  436. elseif self.Primary.Ammo == "ar2" then -- assault rifles
  437. self.MaxRicochet = 8
  438. elseif self.Primary.Ammo == "buckshot" then -- shotguns
  439. self.MaxRicochet = 1
  440. elseif self.Primary.Ammo == "slam" then -- secondary shotguns
  441. self.MaxRicochet = 1
  442. elseif self.Primary.Ammo == "AirboatGun" then -- metal piercing shotgun pellet
  443. self.MaxRicochet = 8
  444. end
  445.  
  446. if (bouncenum > self.MaxRicochet) then return end
  447.  
  448. // -- Bounce vector
  449. local trace = {}
  450. trace.start = tr.HitPos
  451. trace.endpos = trace.start + (tr.HitNormal * 16384)
  452.  
  453. local trace = util.TraceLine(trace)
  454.  
  455. local DotProduct = tr.HitNormal:Dot(tr.Normal * -1)
  456.  
  457. local ricochetbullet = {}
  458. ricochetbullet.Num = 1
  459. ricochetbullet.Src = tr.HitPos + (tr.HitNormal * 5)
  460. ricochetbullet.Dir = ((2 * tr.HitNormal * DotProduct) + tr.Normal) + (VectorRand() * 0.05)
  461. ricochetbullet.Spread = Vector(0, 0, 0)
  462. ricochetbullet.Tracer = 1
  463. ricochetbullet.TracerName = "m9k_effect_mad_ricochet_trace"
  464. ricochetbullet.Force = dmginfo:GetDamage() * 0.15
  465. ricochetbullet.Damage = dmginfo:GetDamage() * 0.5
  466. ricochetbullet.Callback = function(a, b, c)
  467. if (self.Ricochet) then
  468. local impactnum
  469. if tr.MatType == MAT_GLASS then impactnum = 0 else impactnum = 1 end
  470. return self:RicochetCallback(bouncenum + impactnum, a, b, c) end
  471. end
  472.  
  473. timer.Simple(0, function() attacker:FireBullets(ricochetbullet) end)
  474.  
  475. return {damage = true, effects = DoDefaultEffect}
  476. end
  477.  
  478.  
  479. /*---------------------------------------------------------
  480. Name: SWEP:BulletPenetrate()
  481. ---------------------------------------------------------*/
  482. function SWEP:BulletPenetrate(bouncenum, attacker, tr, paininfo)
  483.  
  484. local MaxPenetration
  485.  
  486. if self.Primary.Ammo == "SniperPenetratedRound" then -- .50 Ammo
  487. MaxPenetration = 20
  488. elseif self.Primary.Ammo == "pistol" then -- pistols
  489. MaxPenetration = 9
  490. elseif self.Primary.Ammo == "357" then -- revolvers with big ass bullets
  491. MaxPenetration = 12
  492. elseif self.Primary.Ammo == "smg1" then -- smgs
  493. MaxPenetration = 14
  494. elseif self.Primary.Ammo == "ar2" then -- assault rifles
  495. MaxPenetration = 16
  496. elseif self.Primary.Ammo == "buckshot" then -- shotguns
  497. MaxPenetration = 5
  498. elseif self.Primary.Ammo == "slam" then -- secondary shotguns
  499. MaxPenetration = 5
  500. elseif self.Primary.Ammo == "AirboatGun" then -- metal piercing shotgun pellet
  501. MaxPenetration = 17
  502. else
  503. MaxPenetration = 14
  504. end
  505.  
  506. local DoDefaultEffect = true
  507. // -- Don't go through metal, sand or player
  508.  
  509. if self.Primary.Ammo == "pistol" or
  510. self.Primary.Ammo == "buckshot" or
  511. self.Primary.Ammo == "slam" then self.Ricochet = true
  512. else
  513. if self.RicochetCoin == 1 then
  514. self.Ricochet = true
  515. elseif self.RicochetCoin >= 2 then
  516. self.Ricochet = false
  517. end
  518. end
  519.  
  520. if self.Primary.Ammo == "SniperPenetratedRound" then self.Ricochet = true end
  521.  
  522. if self.Primary.Ammo == "SniperPenetratedRound" then -- .50 Ammo
  523. self.MaxRicochet = 10
  524. elseif self.Primary.Ammo == "pistol" then -- pistols
  525. self.MaxRicochet = 2
  526. elseif self.Primary.Ammo == "357" then -- revolvers with big ass bullets
  527. self.MaxRicochet = 5
  528. elseif self.Primary.Ammo == "smg1" then -- smgs
  529. self.MaxRicochet = 4
  530. elseif self.Primary.Ammo == "ar2" then -- assault rifles
  531. self.MaxRicochet = 5
  532. elseif self.Primary.Ammo == "buckshot" then -- shotguns
  533. self.MaxRicochet = 0
  534. elseif self.Primary.Ammo == "slam" then -- secondary shotguns
  535. self.MaxRicochet = 0
  536. elseif self.Primary.Ammo == "AirboatGun" then -- metal piercing shotgun pellet
  537. self.MaxRicochet = 8
  538. end
  539.  
  540. if (tr.MatType == MAT_METAL and self.Ricochet == true and self.Primary.Ammo != "SniperPenetratedRound" ) then return false end
  541.  
  542. // -- Don't go through more than 3 times
  543. if (bouncenum > self.MaxRicochet) then return false end
  544.  
  545. // -- Direction (and length) that we are going to penetrate
  546. local PenetrationDirection = tr.Normal * MaxPenetration
  547.  
  548. if (tr.MatType == MAT_GLASS or tr.MatType == MAT_PLASTIC or tr.MatType == MAT_WOOD or tr.MatType == MAT_FLESH or tr.MatType == MAT_ALIENFLESH) then
  549. PenetrationDirection = tr.Normal * (MaxPenetration * 2)
  550. end
  551.  
  552. local trace = {}
  553. trace.endpos = tr.HitPos
  554. trace.start = tr.HitPos + PenetrationDirection
  555. trace.mask = MASK_SHOT
  556. trace.filter = {self.Owner}
  557.  
  558. local trace = util.TraceLine(trace)
  559.  
  560. // -- Bullet didn't penetrate.
  561. if (trace.StartSolid or trace.Fraction >= 1.0 or tr.Fraction <= 0.0) then return false end
  562.  
  563. // -- Damage multiplier depending on surface
  564. local fDamageMulti = 0.5
  565.  
  566. if self.Primary.Ammo == "SniperPenetratedRound" then
  567. fDamageMulti = 1
  568. elseif(tr.MatType == MAT_CONCRETE or tr.MatType == MAT_METAL) then
  569. fDamageMulti = 0.3
  570. elseif (tr.MatType == MAT_WOOD or tr.MatType == MAT_PLASTIC or tr.MatType == MAT_GLASS) then
  571. fDamageMulti = 0.8
  572. elseif (tr.MatType == MAT_FLESH or tr.MatType == MAT_ALIENFLESH) then
  573. fDamageMulti = 0.9
  574. end
  575.  
  576. local damagedice = math.Rand(.85,1.3)
  577. local newdamage = self.Primary.Damage * damagedice
  578.  
  579. // -- Fire bullet from the exit point using the original trajectory
  580. local penetratedbullet = {}
  581. penetratedbullet.Num = 1
  582. penetratedbullet.Src = trace.HitPos
  583. penetratedbullet.Dir = tr.Normal
  584. penetratedbullet.Spread = Vector(0, 0, 0)
  585. penetratedbullet.Tracer = 2
  586. penetratedbullet.TracerName = "m9k_effect_mad_penetration_trace"
  587. penetratedbullet.Force = 5
  588. penetratedbullet.Damage = paininfo:GetDamage() * fDamageMulti
  589. penetratedbullet.Callback = function(a, b, c) if (self.Ricochet) then
  590. local impactnum
  591. if tr.MatType == MAT_GLASS then impactnum = 0 else impactnum = 1 end
  592. return self:RicochetCallback(bouncenum + impactnum, a,b,c) end end
  593.  
  594. timer.Simple(0, function() if attacker != nil then attacker:FireBullets(penetratedbullet) end end)
  595.  
  596. return true
  597. end
  598.  
  599.  
  600. function SWEP:SecondaryAttack()
  601. return false
  602. end
  603.  
  604. function SWEP:Reload()
  605. if not IsValid(self) then return end if not IsValid(self.Owner) then return end
  606.  
  607. if self.Owner:IsNPC() then
  608. self.Weapon:DefaultReload(ACT_VM_RELOAD)
  609. return end
  610.  
  611. if self.Owner:KeyDown(IN_USE) then return end
  612.  
  613. if self.Silenced then
  614. self.Weapon:DefaultReload(ACT_VM_RELOAD_SILENCED)
  615. else
  616. self.Weapon:DefaultReload(ACT_VM_RELOAD)
  617. end
  618.  
  619. if !self.Owner:IsNPC() then
  620. if self.Owner:GetViewModel() == nil then self.ResetSights = CurTime() + 3 else
  621. self.ResetSights = CurTime() + self.Owner:GetViewModel():SequenceDuration()
  622. end
  623. end
  624.  
  625. if SERVER and self.Weapon != nil then
  626. if ( self.Weapon:Clip1() < self.Primary.ClipSize ) and !self.Owner:IsNPC() then
  627. -- When the current clip < full clip and the rest of your ammo > 0, then
  628. self.Owner:SetFOV( 0, 0.3 )
  629. -- Zoom = 0
  630. self:SetIronsights(false)
  631. -- Set the ironsight to false
  632. self.Weapon:SetNWBool("Reloading", true)
  633. end
  634. local waitdammit = (self.Owner:GetViewModel():SequenceDuration())
  635. timer.Simple(waitdammit + .1,
  636. function()
  637. if self.Weapon == nil then return end
  638. self.Weapon:SetNWBool("Reloading", false)
  639. if self.Owner:KeyDown(IN_ATTACK2) and self.Weapon:GetClass() == self.Gun then
  640. if CLIENT then return end
  641. if self.Scoped == false then
  642. self.Owner:SetFOV( self.Secondary.IronFOV, 0.3 )
  643. self.IronSightsPos = self.SightsPos -- Bring it up
  644. self.IronSightsAng = self.SightsAng -- Bring it up
  645. self:SetIronsights(true, self.Owner)
  646. self.DrawCrosshair = false
  647. else return end
  648. elseif self.Owner:KeyDown(IN_SPEED) and self.Weapon:GetClass() == self.Gun then
  649. if self.Weapon:GetNextPrimaryFire() <= (CurTime() + .03) then
  650. self.Weapon:SetNextPrimaryFire(CurTime()+0.3) -- Make it so you can't shoot for another quarter second
  651. end
  652. self.IronSightsPos = self.RunSightsPos -- Hold it down
  653. self.IronSightsAng = self.RunSightsAng -- Hold it down
  654. self:SetIronsights(true, self.Owner) -- Set the ironsight true
  655. self.Owner:SetFOV( 0, 0.3 )
  656. else return end
  657. end)
  658. end
  659. end
  660.  
  661. function SWEP:PostReloadScopeCheck()
  662. if self.Weapon == nil then return end
  663. self.Weapon:SetNWBool("Reloading", false)
  664. if self.Owner:KeyDown(IN_ATTACK2) and self.Weapon:GetClass() == self.Gun then
  665. if CLIENT then return end
  666. if self.Scoped == false then
  667. self.Owner:SetFOV( self.Secondary.IronFOV, 0.3 )
  668. self.IronSightsPos = self.SightsPos -- Bring it up
  669. self.IronSightsAng = self.SightsAng -- Bring it up
  670. self:SetIronsights(true, self.Owner)
  671. self.DrawCrosshair = false
  672. else return end
  673. elseif self.Owner:KeyDown(IN_SPEED) and self.Weapon:GetClass() == self.Gun then
  674. if self.Weapon:GetNextPrimaryFire() <= (CurTime() + .03) then
  675. self.Weapon:SetNextPrimaryFire(CurTime()+0.3) -- Make it so you can't shoot for another quarter second
  676. end
  677. self.IronSightsPos = self.RunSightsPos -- Hold it down
  678. self.IronSightsAng = self.RunSightsAng -- Hold it down
  679. self:SetIronsights(true, self.Owner) -- Set the ironsight true
  680. self.Owner:SetFOV( 0, 0.3 )
  681. else return end
  682. end
  683.  
  684. function SWEP:Silencer()
  685.  
  686. if self.NextSilence > CurTime() then return end
  687.  
  688. if self.Weapon != nil then
  689. self.Owner:SetFOV( 0, 0.3 )
  690. self:SetIronsights(false)
  691. self.Weapon:SetNWBool("Reloading", true) -- i know we're not reloading but it works
  692. end
  693.  
  694. if self.Silenced then
  695. self:SendWeaponAnim(ACT_VM_DETACH_SILENCER)
  696. self.Silenced = false
  697. elseif not self.Silenced then
  698. self:SendWeaponAnim(ACT_VM_ATTACH_SILENCER)
  699. self.Silenced = true
  700. end
  701.  
  702. siltimer = CurTime() + (self.Owner:GetViewModel():SequenceDuration()) + 0.1
  703. if self.Weapon:GetNextPrimaryFire() <= siltimer then
  704. self.Weapon:SetNextPrimaryFire(siltimer)
  705. end
  706. self.NextSilence = siltimer
  707.  
  708. timer.Simple( ((self.Owner:GetViewModel():SequenceDuration()) + 0.1),
  709. function()
  710. if self.Weapon != nil then
  711. self.Weapon:SetNWBool("Reloading", false)
  712. if self.Owner:KeyDown(IN_ATTACK2) and self.Weapon:GetClass() == self.Gun then
  713. if CLIENT then return end
  714. if self.Scoped == false then
  715. self.Owner:SetFOV( self.Secondary.IronFOV, 0.3 )
  716. self.IronSightsPos = self.SightsPos -- Bring it up
  717. self.IronSightsAng = self.SightsAng -- Bring it up
  718. self:SetIronsights(true, self.Owner)
  719. self.DrawCrosshair = false
  720. else return end
  721. elseif self.Owner:KeyDown(IN_SPEED) and self.Weapon:GetClass() == self.Gun then
  722. if self.Weapon:GetNextPrimaryFire() <= (CurTime()+0.3) then
  723. self.Weapon:SetNextPrimaryFire(CurTime()+0.3) -- Make it so you can't shoot for another quarter second
  724. end
  725. self.IronSightsPos = self.RunSightsPos -- Hold it down
  726. self.IronSightsAng = self.RunSightsAng -- Hold it down
  727. self:SetIronsights(true, self.Owner) -- Set the ironsight true
  728. self.Owner:SetFOV( 0, 0.3 )
  729. else return end
  730. end
  731. end)
  732.  
  733. end
  734.  
  735. function SWEP:SelectFireMode()
  736.  
  737. if self.Primary.Automatic then
  738. self.Primary.Automatic = false
  739. self.NextFireSelect = CurTime() + .5
  740. if CLIENT then
  741. self.Owner:PrintMessage(HUD_PRINTTALK, "Semi-automatic selected.")
  742. end
  743. self.Weapon:EmitSound("Weapon_AR2.Empty")
  744. else
  745. self.Primary.Automatic = true
  746. self.NextFireSelect = CurTime() + .5
  747. if CLIENT then
  748. self.Owner:PrintMessage(HUD_PRINTTALK, "Automatic selected.")
  749. end
  750. self.Weapon:EmitSound("Weapon_AR2.Empty")
  751. end
  752. end
  753.  
  754.  
  755. /*---------------------------------------------------------
  756. IronSight
  757. ---------------------------------------------------------*/
  758. function SWEP:IronSight()
  759.  
  760. if not IsValid(self) then return end
  761. if not IsValid(self.Owner) then return end
  762.  
  763. if !self.Owner:IsNPC() then
  764. if self.ResetSights and CurTime() >= self.ResetSights then
  765. self.ResetSights = nil
  766.  
  767. if self.Silenced then
  768. self:SendWeaponAnim(ACT_VM_IDLE_SILENCED)
  769. else
  770. self:SendWeaponAnim(ACT_VM_IDLE)
  771. end
  772. end end
  773.  
  774. if self.CanBeSilenced and self.NextSilence < CurTime() then
  775. if self.Owner:KeyDown(IN_USE) and self.Owner:KeyPressed(IN_ATTACK2) then
  776. self:Silencer()
  777. end
  778. end
  779.  
  780. if self.SelectiveFire and self.NextFireSelect < CurTime() and not (self.Weapon:GetNWBool("Reloading")) then
  781. if self.Owner:KeyDown(IN_USE) and self.Owner:KeyPressed(IN_RELOAD) then
  782. self:SelectFireMode()
  783. end
  784. end
  785.  
  786. --copy this...
  787. if self.Owner:KeyPressed(IN_SPEED) and not (self.Weapon:GetNWBool("Reloading")) then -- If you are running
  788. if self.Weapon:GetNextPrimaryFire() <= (CurTime()+0.3) then
  789. self.Weapon:SetNextPrimaryFire(CurTime()+0.3) -- Make it so you can't shoot for another quarter second
  790. end
  791. self.IronSightsPos = self.RunSightsPos -- Hold it down
  792. self.IronSightsAng = self.RunSightsAng -- Hold it down
  793. self:SetIronsights(true, self.Owner) -- Set the ironsight true
  794. self.Owner:SetFOV( 0, 0.3 )
  795. self.DrawCrosshair = false
  796. end
  797.  
  798. if self.Owner:KeyReleased (IN_SPEED) then -- If you release run then
  799. self:SetIronsights(false, self.Owner) -- Set the ironsight true
  800. self.Owner:SetFOV( 0, 0.3 )
  801. self.DrawCrosshair = self.OrigCrossHair
  802. end -- Shoulder the gun
  803.  
  804. --down to this
  805. if !self.Owner:KeyDown(IN_USE) and !self.Owner:KeyDown(IN_SPEED) then
  806. -- If the key E (Use Key) is not pressed, then
  807.  
  808. if self.Owner:KeyPressed(IN_ATTACK2) and not (self.Weapon:GetNWBool("Reloading")) then
  809. self.Owner:SetFOV( self.Secondary.IronFOV, 0.3 )
  810. self.IronSightsPos = self.SightsPos -- Bring it up
  811. self.IronSightsAng = self.SightsAng -- Bring it up
  812. self:SetIronsights(true, self.Owner)
  813. self.DrawCrosshair = false
  814. -- Set the ironsight true
  815.  
  816. if CLIENT then return end
  817. end
  818. end
  819.  
  820. if self.Owner:KeyReleased(IN_ATTACK2) and !self.Owner:KeyDown(IN_USE) and !self.Owner:KeyDown(IN_SPEED) then
  821. -- If the right click is released, then
  822. self.Owner:SetFOV( 0, 0.3 )
  823. self.DrawCrosshair = self.OrigCrossHair
  824. self:SetIronsights(false, self.Owner)
  825. -- Set the ironsight false
  826.  
  827. if CLIENT then return end
  828. end
  829.  
  830. if self.Owner:KeyDown(IN_ATTACK2) and !self.Owner:KeyDown(IN_USE) and !self.Owner:KeyDown(IN_SPEED) then
  831. self.SwayScale = 0.05
  832. self.BobScale = 0.05
  833. else
  834. self.SwayScale = 1.0
  835. self.BobScale = 1.0
  836. end
  837. end
  838.  
  839. /*---------------------------------------------------------
  840. Think
  841. ---------------------------------------------------------*/
  842. function SWEP:Think()
  843.  
  844. self:IronSight()
  845.  
  846. end
  847.  
  848. /*---------------------------------------------------------
  849. GetViewModelPosition
  850. ---------------------------------------------------------*/
  851. local IRONSIGHT_TIME = 0.3
  852. -- Time to enter in the ironsight mod
  853.  
  854. function SWEP:GetViewModelPosition(pos, ang)
  855.  
  856. if (not self.IronSightsPos) then return pos, ang end
  857.  
  858. local bIron = self.Weapon:GetNWBool("Ironsights")
  859.  
  860. if (bIron != self.bLastIron) then
  861. self.bLastIron = bIron
  862. self.fIronTime = CurTime()
  863.  
  864. end
  865.  
  866. local fIronTime = self.fIronTime or 0
  867.  
  868. if (not bIron and fIronTime < CurTime() - IRONSIGHT_TIME) then
  869. return pos, ang
  870. end
  871.  
  872. local Mul = 1.0
  873.  
  874. if (fIronTime > CurTime() - IRONSIGHT_TIME) then
  875. Mul = math.Clamp((CurTime() - fIronTime) / IRONSIGHT_TIME, 0, 1)
  876.  
  877. if not bIron then Mul = 1 - Mul end
  878. end
  879.  
  880. local Offset = self.IronSightsPos
  881.  
  882. if (self.IronSightsAng) then
  883. ang = ang * 1
  884. ang:RotateAroundAxis(ang:Right(), self.IronSightsAng.x * Mul)
  885. ang:RotateAroundAxis(ang:Up(), self.IronSightsAng.y * Mul)
  886. ang:RotateAroundAxis(ang:Forward(), self.IronSightsAng.z * Mul)
  887. end
  888.  
  889. local Right = ang:Right()
  890. local Up = ang:Up()
  891. local Forward = ang:Forward()
  892.  
  893. pos = pos + Offset.x * Right * Mul
  894. pos = pos + Offset.y * Forward * Mul
  895. pos = pos + Offset.z * Up * Mul
  896.  
  897. return pos, ang
  898. end
  899.  
  900. /*---------------------------------------------------------
  901. SetIronsights
  902. ---------------------------------------------------------*/
  903. function SWEP:SetIronsights(b)
  904. self.Weapon:SetNWBool("Ironsights", b)
  905. end
  906.  
  907. function SWEP:GetIronsights()
  908. return self.Weapon:GetNWBool("Ironsights")
  909. end
  910.  
  911.  
  912. if CLIENT then
  913.  
  914. SWEP.vRenderOrder = nil
  915. function SWEP:ViewModelDrawn()
  916.  
  917. local vm = self.Owner:GetViewModel()
  918. if !IsValid(vm) then return end
  919.  
  920. if (!self.VElements) then return end
  921.  
  922. self:UpdateBonePositions(vm)
  923.  
  924. if (!self.vRenderOrder) then
  925.  
  926. -- // we build a render order because sprites need to be drawn after models
  927. self.vRenderOrder = {}
  928.  
  929. for k, v in pairs( self.VElements ) do
  930. if (v.type == "Model") then
  931. table.insert(self.vRenderOrder, 1, k)
  932. elseif (v.type == "Sprite" or v.type == "Quad") then
  933. table.insert(self.vRenderOrder, k)
  934. end
  935. end
  936.  
  937. end
  938.  
  939. for k, name in ipairs( self.vRenderOrder ) do
  940.  
  941. local v = self.VElements[name]
  942. if (!v) then self.vRenderOrder = nil break end
  943. if (v.hide) then continue end
  944.  
  945. local model = v.modelEnt
  946. local sprite = v.spriteMaterial
  947.  
  948. if (!v.bone) then continue end
  949.  
  950. local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
  951.  
  952. if (!pos) then continue end
  953.  
  954. if (v.type == "Model" and IsValid(model)) then
  955.  
  956. model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
  957. ang:RotateAroundAxis(ang:Up(), v.angle.y)
  958. ang:RotateAroundAxis(ang:Right(), v.angle.p)
  959. ang:RotateAroundAxis(ang:Forward(), v.angle.r)
  960.  
  961. model:SetAngles(ang)
  962. -- //model:SetModelScale(v.size)
  963. local matrix = Matrix()
  964. matrix:Scale(v.size)
  965. model:EnableMatrix( "RenderMultiply", matrix )
  966.  
  967. if (v.material == "") then
  968. model:SetMaterial("")
  969. elseif (model:GetMaterial() != v.material) then
  970. model:SetMaterial( v.material )
  971. end
  972.  
  973. if (v.skin and v.skin != model:GetSkin()) then
  974. model:SetSkin(v.skin)
  975. end
  976.  
  977. if (v.bodygroup) then
  978. for k, v in pairs( v.bodygroup ) do
  979. if (model:GetBodygroup(k) != v) then
  980. model:SetBodygroup(k, v)
  981. end
  982. end
  983. end
  984.  
  985. if (v.surpresslightning) then
  986. render.SuppressEngineLighting(true)
  987. end
  988.  
  989. render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
  990. render.SetBlend(v.color.a/255)
  991. model:DrawModel()
  992. render.SetBlend(1)
  993. render.SetColorModulation(1, 1, 1)
  994.  
  995. if (v.surpresslightning) then
  996. render.SuppressEngineLighting(false)
  997. end
  998.  
  999. elseif (v.type == "Sprite" and sprite) then
  1000.  
  1001. local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
  1002. render.SetMaterial(sprite)
  1003. render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
  1004.  
  1005. elseif (v.type == "Quad" and v.draw_func) then
  1006.  
  1007. local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
  1008. ang:RotateAroundAxis(ang:Up(), v.angle.y)
  1009. ang:RotateAroundAxis(ang:Right(), v.angle.p)
  1010. ang:RotateAroundAxis(ang:Forward(), v.angle.r)
  1011.  
  1012. cam.Start3D2D(drawpos, ang, v.size)
  1013. v.draw_func( self )
  1014. cam.End3D2D()
  1015.  
  1016. end
  1017.  
  1018. end
  1019.  
  1020. end
  1021.  
  1022. SWEP.wRenderOrder = nil
  1023. function SWEP:DrawWorldModel()
  1024.  
  1025. if (self.ShowWorldModel == nil or self.ShowWorldModel) then
  1026. self:DrawModel()
  1027. end
  1028.  
  1029. if (!self.WElements) then return end
  1030.  
  1031. if (!self.wRenderOrder) then
  1032.  
  1033. self.wRenderOrder = {}
  1034.  
  1035. for k, v in pairs( self.WElements ) do
  1036. if (v.type == "Model") then
  1037. table.insert(self.wRenderOrder, 1, k)
  1038. elseif (v.type == "Sprite" or v.type == "Quad") then
  1039. table.insert(self.wRenderOrder, k)
  1040. end
  1041. end
  1042.  
  1043. end
  1044.  
  1045. if (IsValid(self.Owner)) then
  1046. bone_ent = self.Owner
  1047. else
  1048. -- // when the weapon is dropped
  1049. bone_ent = self
  1050. end
  1051.  
  1052. for k, name in pairs( self.wRenderOrder ) do
  1053.  
  1054. local v = self.WElements[name]
  1055. if (!v) then self.wRenderOrder = nil break end
  1056. if (v.hide) then continue end
  1057.  
  1058. local pos, ang
  1059.  
  1060. if (v.bone) then
  1061. pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
  1062. else
  1063. pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
  1064. end
  1065.  
  1066. if (!pos) then continue end
  1067.  
  1068. local model = v.modelEnt
  1069. local sprite = v.spriteMaterial
  1070.  
  1071. if (v.type == "Model" and IsValid(model)) then
  1072.  
  1073. model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
  1074. ang:RotateAroundAxis(ang:Up(), v.angle.y)
  1075. ang:RotateAroundAxis(ang:Right(), v.angle.p)
  1076. ang:RotateAroundAxis(ang:Forward(), v.angle.r)
  1077.  
  1078. model:SetAngles(ang)
  1079. -- //model:SetModelScale(v.size)
  1080. local matrix = Matrix()
  1081. matrix:Scale(v.size)
  1082. model:EnableMatrix( "RenderMultiply", matrix )
  1083.  
  1084. if (v.material == "") then
  1085. model:SetMaterial("")
  1086. elseif (model:GetMaterial() != v.material) then
  1087. model:SetMaterial( v.material )
  1088. end
  1089.  
  1090. if (v.skin and v.skin != model:GetSkin()) then
  1091. model:SetSkin(v.skin)
  1092. end
  1093.  
  1094. if (v.bodygroup) then
  1095. for k, v in pairs( v.bodygroup ) do
  1096. if (model:GetBodygroup(k) != v) then
  1097. model:SetBodygroup(k, v)
  1098. end
  1099. end
  1100. end
  1101.  
  1102. if (v.surpresslightning) then
  1103. render.SuppressEngineLighting(true)
  1104. end
  1105.  
  1106. render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
  1107. render.SetBlend(v.color.a/255)
  1108. model:DrawModel()
  1109. render.SetBlend(1)
  1110. render.SetColorModulation(1, 1, 1)
  1111.  
  1112. if (v.surpresslightning) then
  1113. render.SuppressEngineLighting(false)
  1114. end
  1115.  
  1116. elseif (v.type == "Sprite" and sprite) then
  1117.  
  1118. local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
  1119. render.SetMaterial(sprite)
  1120. render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
  1121.  
  1122. elseif (v.type == "Quad" and v.draw_func) then
  1123.  
  1124. local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
  1125. ang:RotateAroundAxis(ang:Up(), v.angle.y)
  1126. ang:RotateAroundAxis(ang:Right(), v.angle.p)
  1127. ang:RotateAroundAxis(ang:Forward(), v.angle.r)
  1128.  
  1129. cam.Start3D2D(drawpos, ang, v.size)
  1130. v.draw_func( self )
  1131. cam.End3D2D()
  1132.  
  1133. end
  1134.  
  1135. end
  1136.  
  1137. end
  1138.  
  1139. function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
  1140.  
  1141. local bone, pos, ang
  1142. if (tab.rel and tab.rel != "") then
  1143.  
  1144. local v = basetab[tab.rel]
  1145.  
  1146. if (!v) then return end
  1147.  
  1148. -- // Technically, if there exists an element with the same name as a bone
  1149. -- // you can get in an infinite loop. Let's just hope nobody's that stupid.
  1150. pos, ang = self:GetBoneOrientation( basetab, v, ent )
  1151.  
  1152. if (!pos) then return end
  1153.  
  1154. pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
  1155. ang:RotateAroundAxis(ang:Up(), v.angle.y)
  1156. ang:RotateAroundAxis(ang:Right(), v.angle.p)
  1157. ang:RotateAroundAxis(ang:Forward(), v.angle.r)
  1158.  
  1159. else
  1160.  
  1161. bone = ent:LookupBone(bone_override or tab.bone)
  1162.  
  1163. if (!bone) then return end
  1164.  
  1165. pos, ang = Vector(0,0,0), Angle(0,0,0)
  1166. local m = ent:GetBoneMatrix(bone)
  1167. if (m) then
  1168. pos, ang = m:GetTranslation(), m:GetAngles()
  1169. end
  1170.  
  1171. if (IsValid(self.Owner) and self.Owner:IsPlayer() and
  1172. ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
  1173. ang.r = -ang.r --// Fixes mirrored models
  1174. end
  1175.  
  1176. end
  1177.  
  1178. return pos, ang
  1179. end
  1180.  
  1181. function SWEP:CreateModels( tab )
  1182.  
  1183. if (!tab) then return end
  1184.  
  1185. -- // Create the clientside models here because Garry says we can't do it in the render hook
  1186. for k, v in pairs( tab ) do
  1187. if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
  1188. string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
  1189.  
  1190. v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
  1191. if (IsValid(v.modelEnt)) then
  1192. v.modelEnt:SetPos(self:GetPos())
  1193. v.modelEnt:SetAngles(self:GetAngles())
  1194. v.modelEnt:SetParent(self)
  1195. v.modelEnt:SetNoDraw(true)
  1196. v.createdModel = v.model
  1197. else
  1198. v.modelEnt = nil
  1199. end
  1200.  
  1201. elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
  1202. and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
  1203.  
  1204. local name = v.sprite.."-"
  1205. local params = { ["$basetexture"] = v.sprite }
  1206. -- // make sure we create a unique name based on the selected options
  1207. local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
  1208. for i, j in pairs( tocheck ) do
  1209. if (v[j]) then
  1210. params["$"..j] = 1
  1211. name = name.."1"
  1212. else
  1213. name = name.."0"
  1214. end
  1215. end
  1216.  
  1217. v.createdSprite = v.sprite
  1218. v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
  1219.  
  1220. end
  1221. end
  1222.  
  1223. end
  1224.  
  1225. local allbones
  1226. local hasGarryFixedBoneScalingYet = false
  1227.  
  1228. function SWEP:UpdateBonePositions(vm)
  1229.  
  1230. if self.ViewModelBoneMods then
  1231.  
  1232. if (!vm:GetBoneCount()) then return end
  1233.  
  1234. -- // !! WORKAROUND !! --//
  1235. -- // We need to check all model names :/
  1236. local loopthrough = self.ViewModelBoneMods
  1237. if (!hasGarryFixedBoneScalingYet) then
  1238. allbones = {}
  1239. for i=0, vm:GetBoneCount() do
  1240. local bonename = vm:GetBoneName(i)
  1241. if (self.ViewModelBoneMods[bonename]) then
  1242. allbones[bonename] = self.ViewModelBoneMods[bonename]
  1243. else
  1244. allbones[bonename] = {
  1245. scale = Vector(1,1,1),
  1246. pos = Vector(0,0,0),
  1247. angle = Angle(0,0,0)
  1248. }
  1249. end
  1250. end
  1251.  
  1252. loopthrough = allbones
  1253. end
  1254. //!! ----------- !! --
  1255.  
  1256. for k, v in pairs( loopthrough ) do
  1257. local bone = vm:LookupBone(k)
  1258. if (!bone) then continue end
  1259.  
  1260. -- // !! WORKAROUND !! --//
  1261. local s = Vector(v.scale.x,v.scale.y,v.scale.z)
  1262. local p = Vector(v.pos.x,v.pos.y,v.pos.z)
  1263. local ms = Vector(1,1,1)
  1264. if (!hasGarryFixedBoneScalingYet) then
  1265. local cur = vm:GetBoneParent(bone)
  1266. while(cur >= 0) do
  1267. local pscale = loopthrough[vm:GetBoneName(cur)].scale
  1268. ms = ms * pscale
  1269. cur = vm:GetBoneParent(cur)
  1270. end
  1271. end
  1272.  
  1273. s = s * ms
  1274. //!! ----------- !! --
  1275.  
  1276. if vm:GetManipulateBoneScale(bone) != s then
  1277. vm:ManipulateBoneScale( bone, s )
  1278. end
  1279. if vm:GetManipulateBoneAngles(bone) != v.angle then
  1280. vm:ManipulateBoneAngles( bone, v.angle )
  1281. end
  1282. if vm:GetManipulateBonePosition(bone) != p then
  1283. vm:ManipulateBonePosition( bone, p )
  1284. end
  1285. end
  1286. else
  1287. self:ResetBonePositions(vm)
  1288. end
  1289.  
  1290. end
  1291.  
  1292. function SWEP:ResetBonePositions(vm)
  1293.  
  1294. if (!vm:GetBoneCount()) then return end
  1295. for i=0, vm:GetBoneCount() do
  1296. vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
  1297. vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
  1298. vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
  1299. end
  1300.  
  1301. end
  1302.  
  1303. /**************************
  1304. Global utility code
  1305. **************************/
  1306.  
  1307. -- // Fully copies the table, meaning all tables inside this table are copied too and so on (normal table.Copy copies only their reference).
  1308. -- // Does not copy entities of course, only copies their reference.
  1309. -- // WARNING: do not use on tables that contain themselves somewhere down the line or you'll get an infinite loop
  1310. function table.FullCopy( tab )
  1311.  
  1312. if (!tab) then return nil end
  1313.  
  1314. local res = {}
  1315. for k, v in pairs( tab ) do
  1316. if (type(v) == "table") then
  1317. res[k] = table.FullCopy(v) --// recursion ho!
  1318. elseif (type(v) == "Vector") then
  1319. res[k] = Vector(v.x, v.y, v.z)
  1320. elseif (type(v) == "Angle") then
  1321. res[k] = Angle(v.p, v.y, v.r)
  1322. else
  1323. res[k] = v
  1324. end
  1325. end
  1326.  
  1327. return res
  1328.  
  1329. end
  1330.  
  1331. end
  1332.  
  1333. if not (GetConVar("M9KUniqueSlots"):GetBool()) then
  1334. SWEP.SlotPos = 2
  1335. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement