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