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