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