Advertisement
Guest User

Untitled

a guest
Feb 13th, 2016
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.35 KB | None | 0 0
  1. /********************************************************
  2. SWEP Construction Kit base code
  3. Created by Clavus
  4. Available for public use, thread at:
  5. facepunch.com/threads/1032378
  6.  
  7.  
  8. DESCRIPTION:
  9. This script is meant for experienced scripters
  10. that KNOW WHAT THEY ARE DOING. Don't come to me
  11. with basic Lua questions.
  12.  
  13. Just copy into your SWEP or SWEP base of choice
  14. and merge with your own code.
  15.  
  16. The SWEP.VElements, SWEP.WElements and
  17. SWEP.ViewModelBoneMods tables are all optional
  18. and only have to be visible to the client.
  19. ********************************************************/
  20.  
  21. function SWEP:Initialize()
  22.  
  23. // other initialize code goes here
  24.  
  25. if CLIENT then
  26.  
  27. // Create a new table for every weapon instance
  28. self.VElements = table.FullCopy( self.VElements )
  29. self.WElements = table.FullCopy( self.WElements )
  30. self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
  31.  
  32. self:CreateModels(self.VElements) // create viewmodels
  33. self:CreateModels(self.WElements) // create worldmodels
  34.  
  35. // init view model bone build function
  36. if IsValid(self.Owner) then
  37. local vm = self.Owner:GetViewModel()
  38. if IsValid(vm) then
  39. self:ResetBonePositions(vm)
  40.  
  41. // Init viewmodel visibility
  42. if (self.ShowViewModel == nil or self.ShowViewModel) then
  43. vm:SetColor(Color(255,255,255,255))
  44. else
  45. // we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
  46. vm:SetColor(Color(255,255,255,1))
  47. // ^ stopped working in GMod 13 because you have to do Entity:SetRenderMode(1) for translucency to kick in
  48. // 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
  49. vm:SetMaterial("Debug/hsv")
  50. end
  51. end
  52. end
  53.  
  54. end
  55.  
  56. end
  57.  
  58. function SWEP:Holster()
  59.  
  60. if CLIENT and IsValid(self.Owner) then
  61. local vm = self.Owner:GetViewModel()
  62. if IsValid(vm) then
  63. self:ResetBonePositions(vm)
  64. end
  65. end
  66.  
  67. return true
  68. end
  69.  
  70. function SWEP:OnRemove()
  71. self:Holster()
  72. end
  73.  
  74. if CLIENT then
  75.  
  76. SWEP.vRenderOrder = nil
  77. function SWEP:ViewModelDrawn()
  78.  
  79. local vm = self.Owner:GetViewModel()
  80. if !IsValid(vm) then return end
  81.  
  82. if (!self.VElements) then return end
  83.  
  84. self:UpdateBonePositions(vm)
  85.  
  86. if (!self.vRenderOrder) then
  87.  
  88. // we build a render order because sprites need to be drawn after models
  89. self.vRenderOrder = {}
  90.  
  91. for k, v in pairs( self.VElements ) do
  92. if (v.type == "Model") then
  93. table.insert(self.vRenderOrder, 1, k)
  94. elseif (v.type == "Sprite" or v.type == "Quad") then
  95. table.insert(self.vRenderOrder, k)
  96. end
  97. end
  98.  
  99. end
  100.  
  101. for k, name in ipairs( self.vRenderOrder ) do
  102.  
  103. local v = self.VElements[name]
  104. if (!v) then self.vRenderOrder = nil break end
  105. if (v.hide) then continue end
  106.  
  107. local model = v.modelEnt
  108. local sprite = v.spriteMaterial
  109.  
  110. if (!v.bone) then continue end
  111.  
  112. local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
  113.  
  114. if (!pos) then continue end
  115.  
  116. if (v.type == "Model" and IsValid(model)) then
  117.  
  118. model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
  119. ang:RotateAroundAxis(ang:Up(), v.angle.y)
  120. ang:RotateAroundAxis(ang:Right(), v.angle.p)
  121. ang:RotateAroundAxis(ang:Forward(), v.angle.r)
  122.  
  123. model:SetAngles(ang)
  124. //model:SetModelScale(v.size)
  125. local matrix = Matrix()
  126. matrix:Scale(v.size)
  127. model:EnableMatrix( "RenderMultiply", matrix )
  128.  
  129. if (v.material == "") then
  130. model:SetMaterial("")
  131. elseif (model:GetMaterial() != v.material) then
  132. model:SetMaterial( v.material )
  133. end
  134.  
  135. if (v.skin and v.skin != model:GetSkin()) then
  136. model:SetSkin(v.skin)
  137. end
  138.  
  139. if (v.bodygroup) then
  140. for k, v in pairs( v.bodygroup ) do
  141. if (model:GetBodygroup(k) != v) then
  142. model:SetBodygroup(k, v)
  143. end
  144. end
  145. end
  146.  
  147. if (v.surpresslightning) then
  148. render.SuppressEngineLighting(true)
  149. end
  150.  
  151. render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
  152. render.SetBlend(v.color.a/255)
  153. model:DrawModel()
  154. render.SetBlend(1)
  155. render.SetColorModulation(1, 1, 1)
  156.  
  157. if (v.surpresslightning) then
  158. render.SuppressEngineLighting(false)
  159. end
  160.  
  161. elseif (v.type == "Sprite" and sprite) then
  162.  
  163. local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
  164. render.SetMaterial(sprite)
  165. render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
  166.  
  167. elseif (v.type == "Quad" and v.draw_func) then
  168.  
  169. local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
  170. ang:RotateAroundAxis(ang:Up(), v.angle.y)
  171. ang:RotateAroundAxis(ang:Right(), v.angle.p)
  172. ang:RotateAroundAxis(ang:Forward(), v.angle.r)
  173.  
  174. cam.Start3D2D(drawpos, ang, v.size)
  175. v.draw_func( self )
  176. cam.End3D2D()
  177.  
  178. end
  179.  
  180. end
  181.  
  182. end
  183.  
  184. SWEP.wRenderOrder = nil
  185. function SWEP:DrawWorldModel()
  186.  
  187. if (self.ShowWorldModel == nil or self.ShowWorldModel) then
  188. self:DrawModel()
  189. end
  190.  
  191. if (!self.WElements) then return end
  192.  
  193. if (!self.wRenderOrder) then
  194.  
  195. self.wRenderOrder = {}
  196.  
  197. for k, v in pairs( self.WElements ) do
  198. if (v.type == "Model") then
  199. table.insert(self.wRenderOrder, 1, k)
  200. elseif (v.type == "Sprite" or v.type == "Quad") then
  201. table.insert(self.wRenderOrder, k)
  202. end
  203. end
  204.  
  205. end
  206.  
  207. if (IsValid(self.Owner)) then
  208. bone_ent = self.Owner
  209. else
  210. // when the weapon is dropped
  211. bone_ent = self
  212. end
  213.  
  214. for k, name in pairs( self.wRenderOrder ) do
  215.  
  216. local v = self.WElements[name]
  217. if (!v) then self.wRenderOrder = nil break end
  218. if (v.hide) then continue end
  219.  
  220. local pos, ang
  221.  
  222. if (v.bone) then
  223. pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
  224. else
  225. pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
  226. end
  227.  
  228. if (!pos) then continue end
  229.  
  230. local model = v.modelEnt
  231. local sprite = v.spriteMaterial
  232.  
  233. if (v.type == "Model" and IsValid(model)) then
  234.  
  235. model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
  236. ang:RotateAroundAxis(ang:Up(), v.angle.y)
  237. ang:RotateAroundAxis(ang:Right(), v.angle.p)
  238. ang:RotateAroundAxis(ang:Forward(), v.angle.r)
  239.  
  240. model:SetAngles(ang)
  241. //model:SetModelScale(v.size)
  242. local matrix = Matrix()
  243. matrix:Scale(v.size)
  244. model:EnableMatrix( "RenderMultiply", matrix )
  245.  
  246. if (v.material == "") then
  247. model:SetMaterial("")
  248. elseif (model:GetMaterial() != v.material) then
  249. model:SetMaterial( v.material )
  250. end
  251.  
  252. if (v.skin and v.skin != model:GetSkin()) then
  253. model:SetSkin(v.skin)
  254. end
  255.  
  256. if (v.bodygroup) then
  257. for k, v in pairs( v.bodygroup ) do
  258. if (model:GetBodygroup(k) != v) then
  259. model:SetBodygroup(k, v)
  260. end
  261. end
  262. end
  263.  
  264. if (v.surpresslightning) then
  265. render.SuppressEngineLighting(true)
  266. end
  267.  
  268. render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
  269. render.SetBlend(v.color.a/255)
  270. model:DrawModel()
  271. render.SetBlend(1)
  272. render.SetColorModulation(1, 1, 1)
  273.  
  274. if (v.surpresslightning) then
  275. render.SuppressEngineLighting(false)
  276. end
  277.  
  278. elseif (v.type == "Sprite" and sprite) then
  279.  
  280. local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
  281. render.SetMaterial(sprite)
  282. render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
  283.  
  284. elseif (v.type == "Quad" and v.draw_func) then
  285.  
  286. local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
  287. ang:RotateAroundAxis(ang:Up(), v.angle.y)
  288. ang:RotateAroundAxis(ang:Right(), v.angle.p)
  289. ang:RotateAroundAxis(ang:Forward(), v.angle.r)
  290.  
  291. cam.Start3D2D(drawpos, ang, v.size)
  292. v.draw_func( self )
  293. cam.End3D2D()
  294.  
  295. end
  296.  
  297. end
  298.  
  299. end
  300.  
  301. function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
  302.  
  303. local bone, pos, ang
  304. if (tab.rel and tab.rel != "") then
  305.  
  306. local v = basetab[tab.rel]
  307.  
  308. if (!v) then return end
  309.  
  310. // Technically, if there exists an element with the same name as a bone
  311. // you can get in an infinite loop. Let's just hope nobody's that stupid.
  312. pos, ang = self:GetBoneOrientation( basetab, v, ent )
  313.  
  314. if (!pos) then return end
  315.  
  316. pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
  317. ang:RotateAroundAxis(ang:Up(), v.angle.y)
  318. ang:RotateAroundAxis(ang:Right(), v.angle.p)
  319. ang:RotateAroundAxis(ang:Forward(), v.angle.r)
  320.  
  321. else
  322.  
  323. bone = ent:LookupBone(bone_override or tab.bone)
  324.  
  325. if (!bone) then return end
  326.  
  327. pos, ang = Vector(0,0,0), Angle(0,0,0)
  328. local m = ent:GetBoneMatrix(bone)
  329. if (m) then
  330. pos, ang = m:GetTranslation(), m:GetAngles()
  331. end
  332.  
  333. if (IsValid(self.Owner) and self.Owner:IsPlayer() and
  334. ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
  335. ang.r = -ang.r // Fixes mirrored models
  336. end
  337.  
  338. end
  339.  
  340. return pos, ang
  341. end
  342.  
  343. function SWEP:CreateModels( tab )
  344.  
  345. if (!tab) then return end
  346.  
  347. // Create the clientside models here because Garry says we can't do it in the render hook
  348. for k, v in pairs( tab ) do
  349. if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
  350. string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
  351.  
  352. v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
  353. if (IsValid(v.modelEnt)) then
  354. v.modelEnt:SetPos(self:GetPos())
  355. v.modelEnt:SetAngles(self:GetAngles())
  356. v.modelEnt:SetParent(self)
  357. v.modelEnt:SetNoDraw(true)
  358. v.createdModel = v.model
  359. else
  360. v.modelEnt = nil
  361. end
  362.  
  363. elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
  364. and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
  365.  
  366. local name = v.sprite.."-"
  367. local params = { ["$basetexture"] = v.sprite }
  368. // make sure we create a unique name based on the selected options
  369. local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
  370. for i, j in pairs( tocheck ) do
  371. if (v[j]) then
  372. params["$"..j] = 1
  373. name = name.."1"
  374. else
  375. name = name.."0"
  376. end
  377. end
  378.  
  379. v.createdSprite = v.sprite
  380. v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
  381.  
  382. end
  383. end
  384.  
  385. end
  386.  
  387. local allbones
  388. local hasGarryFixedBoneScalingYet = false
  389.  
  390. function SWEP:UpdateBonePositions(vm)
  391.  
  392. if self.ViewModelBoneMods then
  393.  
  394. if (!vm:GetBoneCount()) then return end
  395.  
  396. // !! WORKAROUND !! //
  397. // We need to check all model names :/
  398. local loopthrough = self.ViewModelBoneMods
  399. if (!hasGarryFixedBoneScalingYet) then
  400. allbones = {}
  401. for i=0, vm:GetBoneCount() do
  402. local bonename = vm:GetBoneName(i)
  403. if (self.ViewModelBoneMods[bonename]) then
  404. allbones[bonename] = self.ViewModelBoneMods[bonename]
  405. else
  406. allbones[bonename] = {
  407. scale = Vector(1,1,1),
  408. pos = Vector(0,0,0),
  409. angle = Angle(0,0,0)
  410. }
  411. end
  412. end
  413.  
  414. loopthrough = allbones
  415. end
  416. // !! ----------- !! //
  417.  
  418. for k, v in pairs( loopthrough ) do
  419. local bone = vm:LookupBone(k)
  420. if (!bone) then continue end
  421.  
  422. // !! WORKAROUND !! //
  423. local s = Vector(v.scale.x,v.scale.y,v.scale.z)
  424. local p = Vector(v.pos.x,v.pos.y,v.pos.z)
  425. local ms = Vector(1,1,1)
  426. if (!hasGarryFixedBoneScalingYet) then
  427. local cur = vm:GetBoneParent(bone)
  428. while(cur >= 0) do
  429. local pscale = loopthrough[vm:GetBoneName(cur)].scale
  430. ms = ms * pscale
  431. cur = vm:GetBoneParent(cur)
  432. end
  433. end
  434.  
  435. s = s * ms
  436. // !! ----------- !! //
  437.  
  438. if vm:GetManipulateBoneScale(bone) != s then
  439. vm:ManipulateBoneScale( bone, s )
  440. end
  441. if vm:GetManipulateBoneAngles(bone) != v.angle then
  442. vm:ManipulateBoneAngles( bone, v.angle )
  443. end
  444. if vm:GetManipulateBonePosition(bone) != p then
  445. vm:ManipulateBonePosition( bone, p )
  446. end
  447. end
  448. else
  449. self:ResetBonePositions(vm)
  450. end
  451.  
  452. end
  453.  
  454. function SWEP:ResetBonePositions(vm)
  455.  
  456. if (!vm:GetBoneCount()) then return end
  457. for i=0, vm:GetBoneCount() do
  458. vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
  459. vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
  460. vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
  461. end
  462.  
  463. end
  464.  
  465. /**************************
  466. Global utility code
  467. **************************/
  468.  
  469. // Fully copies the table, meaning all tables inside this table are copied too and so on (normal table.Copy copies only their reference).
  470. // Does not copy entities of course, only copies their reference.
  471. // WARNING: do not use on tables that contain themselves somewhere down the line or you'll get an infinite loop
  472. function table.FullCopy( tab )
  473.  
  474. if (!tab) then return nil end
  475.  
  476. local res = {}
  477. for k, v in pairs( tab ) do
  478. if (type(v) == "table") then
  479. res[k] = table.FullCopy(v) // recursion ho!
  480. elseif (type(v) == "Vector") then
  481. res[k] = Vector(v.x, v.y, v.z)
  482. elseif (type(v) == "Angle") then
  483. res[k] = Angle(v.p, v.y, v.r)
  484. else
  485. res[k] = v
  486. end
  487. end
  488.  
  489. return res
  490.  
  491. end
  492.  
  493. end
  494.  
  495.  
  496.  
  497. SWEP.PrintName = "Shoot 'n' Reload"
  498.  
  499. SWEP.Author = "Old Bill"
  500. SWEP.Contact = "oldbillandmedic@gmail.com"
  501. SWEP.Purpose = "To shoot noobs"
  502. SWEP.Instructions = "Left click to shoot, right click does nothing so don't use it."
  503.  
  504. SWEP.Category = "Decent Weapons"
  505.  
  506. SWEP.Spawnable= true
  507. SWEP.AdminSpawnable= true
  508. SWEP.AdminOnly = false
  509. SWEP.WElements = {
  510. ["Shoot 'N' Reload"] = { type = "Model", model = "models/oldbill/w_pistoltest.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(3.299, 1.5, 2.2), angle = Angle(0, 0, 180), size = Vector(1.34, 1.34, 1.34), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
  511. }
  512. SWEP.ViewModelFOV = 70
  513. SWEP.ViewModel = "models/weapons/c_pistoltest_gun.mdl"
  514. SWEP.WorldModel = "models/oldbill/w_pistoltest.mdl"
  515.  
  516. SWEP.ViewModelFlip = false
  517.  
  518. SWEP.AutoSwitchTo = false
  519. SWEP.AutoSwitchFrom = false
  520.  
  521. SWEP.Slot = 1
  522. SWEP.SlotPos = 1
  523.  
  524. SWEP.UseHands = true
  525.  
  526. SWEP.HoldType = "Pistol"
  527.  
  528. SWEP.FiresUnderwater = true
  529.  
  530. SWEP.DrawCrosshair = true
  531.  
  532. SWEP.DrawAmmo = true
  533.  
  534. SWEP.ReloadSound = "weapons/pistol/pistol_reload1.wav"
  535.  
  536. SWEP.Base = "weapon_base"
  537.  
  538. SWEP.Primary.Sound = Sound("weapons/pistol/pistol_fire2.wav")
  539. SWEP.Primary.Damage = 30
  540. SWEP.Primary.TakeAmmo = 1
  541. SWEP.Primary.ClipSize = 12
  542. SWEP.Primary.Ammo = "Pistol"
  543. SWEP.Primary.DefaultClip = 12
  544. SWEP.Primary.Spread = 0.2
  545. SWEP.Primary.NumberofShots = 1
  546. SWEP.Primary.Automatic = false
  547. SWEP.Primary.Recoil = 0.1
  548. SWEP.Primary.Delay = 0.02
  549. SWEP.Primary.Force = 1
  550.  
  551. SWEP.Secondary.ClipSize = 0
  552. SWEP.Secondary.DefaultClip = 0
  553. SWEP.Secondary.Automatic = false
  554. SWEP.Secondary.Ammo = "none"
  555.  
  556. SWEP.CSMuzzleFlashes = false
  557.  
  558. function SWEP:Initialize()
  559. util.PrecacheSound(self.Primary.Sound)
  560. util.PrecacheSound(self.ReloadSound)
  561. self:SetWeaponHoldType( self.HoldType )
  562. end
  563.  
  564. function SWEP:PrimaryAttack()
  565.  
  566. if ( !self:CanPrimaryAttack() ) then return end
  567.  
  568. local bullet = {}
  569. bullet.Num = self.Primary.NumberofShots
  570. bullet.Src = self.Owner:GetShootPos()
  571. bullet.Dir = self.Owner:GetAimVector()
  572. bullet.Spread = Vector( self.Primary.Spread * 0.1 , self.Primary.Spread * 0.1, 0)
  573. bullet.Tracer = 0
  574. bullet.Force = self.Primary.Force
  575. bullet.Damage = self.Primary.Damage
  576. bullet.AmmoType = self.Primary.Ammo
  577.  
  578. local rnda = self.Primary.Recoil * -1
  579. local rndb = self.Primary.Recoil * math.random(-1, 1)
  580.  
  581. self:ShootEffects()
  582.  
  583. self.Owner:FireBullets( bullet )
  584. self:EmitSound(Sound(self.Primary.Sound))
  585. self.Owner:ViewPunch( Angle( rnda,rndb,rnda ) )
  586. self:TakePrimaryAmmo(self.Primary.TakeAmmo)
  587.  
  588. self:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
  589. self:SetNextSecondaryFire( CurTime() + self.Primary.Delay )
  590. end
  591.  
  592. function SWEP:SecondaryAttack()
  593. end
  594.  
  595. function SWEP:Reload()
  596. self:EmitSound(Sound(self.ReloadSound))
  597. self.Weapon:DefaultReload( ACT_VM_RELOAD );
  598. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement