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