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