· 7 years ago · Nov 10, 2018, 05:58 AM
1-- Variables that are used on both client and server
2SWEP.Gun = ("tfa_sw73") -- must be the name of your swep but NO CAPITALS!
3if (GetConVar(SWEP.Gun.."_allowed")) != nil then
4 if not (GetConVar(SWEP.Gun.."_allowed"):GetBool()) then SWEP.Base = "tfa_blacklisted" SWEP.PrintName = SWEP.Gun return end
5end
6SWEP.Base = "tfa_shotty_base"
7SWEP.Category = "TFA Shotguns"
8SWEP.Author = "A Forgotten Architect"
9SWEP.Contact = ""
10SWEP.Purpose = ""
11SWEP.Instructions = ""
12SWEP.MuzzleAttachment = "1" -- Should be "1" for CSS models or "muzzle" for hl2 models
13SWEP.ShellEjectAttachment = "2" -- Should be "2" for CSS models or "1" for hl2 models
14SWEP.PrintName = "Scrap Winchester 73 Carbine" -- Weapon name (Shown on HUD)
15SWEP.Slot = 2 -- Slot in the weapon selection menu
16SWEP.SlotPos = 42 -- Position in the slot
17SWEP.DrawAmmo = false -- Should draw the default HL2 ammo counter
18SWEP.DrawWeaponInfoBox = false -- Should draw the weapon info box
19SWEP.BounceWeaponIcon = false -- Should the weapon icon bounce?
20SWEP.DrawCrosshair = true -- set false if you want no crosshair
21SWEP.Weight = 3 -- rank relative ot other weapons. bigger is better
22SWEP.AutoSwitchTo = false -- Auto switch to if we pick it up
23SWEP.AutoSwitchFrom = false -- Auto switch from if you pick up a better weapon
24SWEP.HoldType = "ar2" -- how others view you carrying the weapon
25SWEP.Spawnable = false
26SWEP.AdminSpawnable = true
27
28SWEP.Primary.Sound = Sound("Weapon_73.Single") -- script that calls the primary fire sound
29SWEP.Primary.RPM = 66 -- This is in Rounds Per Minute
30SWEP.Primary.ClipSize = 8 -- Size of a clip
31SWEP.Primary.DefaultClip = 0 -- Default number of bullets in a clip
32SWEP.Primary.KickUp = .2 -- Maximum up recoil (rise)
33SWEP.Primary.KickDown = 0 -- Maximum down recoil (skeet)
34SWEP.Primary.KickHorizontal = 0.1 -- Maximum up recoil (stock)
35SWEP.Primary.Automatic = false -- Automatic/Semi Auto
36SWEP.Primary.Ammo = "AirboatGun" -- pistol, 357, smg1, ar2, buckshot, slam, SniperPenetratedRound, AirboatGun
37
38SWEP.Secondary.IronFOV = 60
39
40SWEP.data = {} --The starting firemode
41SWEP.data.ironsights = 1
42
43SWEP.ShellTime = .54
44
45SWEP.Primary.NumShots = 1 -- How many bullets to shoot per trigger pull, AKA pellets
46SWEP.Primary.Damage = 85 -- Base damage per bullet
47SWEP.Primary.Spread = .01 -- Define from-the-hip accuracy 1 is terrible, .0001 is exact)
48SWEP.Primary.IronAccuracy = .001 -- Ironsight accuracy, should be the same for shotguns
49
50SWEP.ViewModelFOV = 70
51SWEP.ViewModelFlip = true
52SWEP.UseHands = false
53SWEP.ViewModel = "models/weapons/tfa_v_winchester1873.mdl"
54SWEP.WorldModel = "models/weapons/tfa_w_winchester_1873.mdl"
55SWEP.ShowViewModel = true
56SWEP.ShowWorldModel = false
57SWEP.ViewModelBoneMods = {
58 ["trigger"] = { scale = Vector(0.009, 0.009, 0.009), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) },
59 ["hammer"] = { scale = Vector(0.009, 0.009, 0.009), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) },
60 ["pumper"] = { scale = Vector(0.009, 0.009, 0.009), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) },
61 ["gun"] = { scale = Vector(0.009, 0.009, 0.009), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) }
62}
63SWEP.IronSightsPos = Vector(4.356, 0, 2.591)
64SWEP.IronSightsAng = Vector(0, 0, 0)
65SWEP.SightsPos = Vector(4.356, 0, 2.591)
66SWEP.SightsAng = Vector(0, 0, 0)
67SWEP.GSightsPos = Vector (0, 0, 0)
68SWEP.GSightsAng = Vector (0, 0, 0)
69SWEP.RunSightsPos = Vector (-2.3095, -3.0514, 2.3965)
70SWEP.RunSightsAng = Vector (-19.8471, -33.9181, 10)
71SWEP.VElements = {
72 USE THE ABILITY ON THE ADDON TO COPY THE FIRST PERSON CODE AND PASTE IT HERE
73}
74
75--[[
76SWEP.WElements = {
77
78}
79--]]
80
81SWEP.FireModeName = "Lever-Action"
82
83if (gmod.GetGamemode().Name == "Murderthon 9000") then
84
85 SWEP.Slot = 1 -- Slot in the weapon selection menu
86 SWEP.Weight = 3 -- rank relative ot other weapons. bigger is better
87
88end
89
90if GetConVar("sv_tfa_default_clip") == nil then
91 print("sv_tfa_default_clip is missing! You might've hit the lua limit. Contact the SWEP author(s).")
92else
93 if GetConVar("sv_tfa_default_clip"):GetInt() != -1 then
94 SWEP.Primary.DefaultClip = SWEP.Primary.ClipSize * GetConVar("sv_tfa_default_clip"):GetInt()
95 end
96end
97
98if GetConVar("sv_tfa_unique_slots") != nil then
99 if not (GetConVar("sv_tfa_unique_slots"):GetBool()) then
100 SWEP.SlotPos = 2
101 end
102end
103
104/********************************************************
105 SWEP Construction Kit base code
106 Created by Clavus
107 Available for public use, thread at:
108 facepunch.com/threads/1032378
109
110
111 DESCRIPTION:
112 This script is meant for experienced scripters
113 that KNOW WHAT THEY ARE DOING. Don't come to me
114 with basic Lua questions.
115
116 Just copy into your SWEP or SWEP base of choice
117 and merge with your own code.
118
119 The SWEP.VElements, SWEP.WElements and
120 SWEP.ViewModelBoneMods tables are all optional
121 and only have to be visible to the client.
122********************************************************/
123
124function SWEP:Initialize()
125
126 // other initialize code goes here
127
128 if CLIENT then
129
130 // Create a new table for every weapon instance
131 self.VElements = table.FullCopy( self.VElements )
132 self.WElements = table.FullCopy( self.WElements )
133 self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
134
135 self:CreateModels(self.VElements) // create viewmodels
136 self:CreateModels(self.WElements) // create worldmodels
137
138 // init view model bone build function
139 if IsValid(self.Owner) then
140 local vm = self.Owner:GetViewModel()
141 if IsValid(vm) then
142 self:ResetBonePositions(vm)
143
144 // Init viewmodel visibility
145 if (self.ShowViewModel == nil or self.ShowViewModel) then
146 vm:SetColor(Color(255,255,255,255))
147 else
148 // we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
149 vm:SetColor(Color(255,255,255,1))
150 // ^ stopped working in GMod 13 because you have to do Entity:SetRenderMode(1) for translucency to kick in
151 // 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
152 vm:SetMaterial("Debug/hsv")
153 end
154 end
155 end
156
157 end
158
159end
160
161function SWEP:Holster()
162
163 if CLIENT and IsValid(self.Owner) then
164 local vm = self.Owner:GetViewModel()
165 if IsValid(vm) then
166 self:ResetBonePositions(vm)
167 end
168 end
169
170 return true
171end
172
173function SWEP:OnRemove()
174 self:Holster()
175end
176
177if CLIENT then
178
179 SWEP.vRenderOrder = nil
180 function SWEP:ViewModelDrawn()
181
182 local vm = self.Owner:GetViewModel()
183 if !IsValid(vm) then return end
184
185 if (!self.VElements) then return end
186
187 self:UpdateBonePositions(vm)
188
189 if (!self.vRenderOrder) then
190
191 // we build a render order because sprites need to be drawn after models
192 self.vRenderOrder = {}
193
194 for k, v in pairs( self.VElements ) do
195 if (v.type == "Model") then
196 table.insert(self.vRenderOrder, 1, k)
197 elseif (v.type == "Sprite" or v.type == "Quad") then
198 table.insert(self.vRenderOrder, k)
199 end
200 end
201
202 end
203
204 for k, name in ipairs( self.vRenderOrder ) do
205
206 local v = self.VElements[name]
207 if (!v) then self.vRenderOrder = nil break end
208 if (v.hide) then continue end
209
210 local model = v.modelEnt
211 local sprite = v.spriteMaterial
212
213 if (!v.bone) then continue end
214
215 local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
216
217 if (!pos) then continue end
218
219 if (v.type == "Model" and IsValid(model)) then
220
221 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
222 ang:RotateAroundAxis(ang:Up(), v.angle.y)
223 ang:RotateAroundAxis(ang:Right(), v.angle.p)
224 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
225
226 model:SetAngles(ang)
227 //model:SetModelScale(v.size)
228 local matrix = Matrix()
229 matrix:Scale(v.size)
230 model:EnableMatrix( "RenderMultiply", matrix )
231
232 if (v.material == "") then
233 model:SetMaterial("")
234 elseif (model:GetMaterial() != v.material) then
235 model:SetMaterial( v.material )
236 end
237
238 if (v.skin and v.skin != model:GetSkin()) then
239 model:SetSkin(v.skin)
240 end
241
242 if (v.bodygroup) then
243 for k, v in pairs( v.bodygroup ) do
244 if (model:GetBodygroup(k) != v) then
245 model:SetBodygroup(k, v)
246 end
247 end
248 end
249
250 if (v.surpresslightning) then
251 render.SuppressEngineLighting(true)
252 end
253
254 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
255 render.SetBlend(v.color.a/255)
256 model:DrawModel()
257 render.SetBlend(1)
258 render.SetColorModulation(1, 1, 1)
259
260 if (v.surpresslightning) then
261 render.SuppressEngineLighting(false)
262 end
263
264 elseif (v.type == "Sprite" and sprite) then
265
266 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
267 render.SetMaterial(sprite)
268 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
269
270 elseif (v.type == "Quad" and v.draw_func) then
271
272 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
273 ang:RotateAroundAxis(ang:Up(), v.angle.y)
274 ang:RotateAroundAxis(ang:Right(), v.angle.p)
275 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
276
277 cam.Start3D2D(drawpos, ang, v.size)
278 v.draw_func( self )
279 cam.End3D2D()
280
281 end
282
283 end
284
285 end
286
287 SWEP.wRenderOrder = nil
288 function SWEP:DrawWorldModel()
289
290 if (self.ShowWorldModel == nil or self.ShowWorldModel) then
291 self:DrawModel()
292 end
293
294 if (!self.WElements) then return end
295
296 if (!self.wRenderOrder) then
297
298 self.wRenderOrder = {}
299
300 for k, v in pairs( self.WElements ) do
301 if (v.type == "Model") then
302 table.insert(self.wRenderOrder, 1, k)
303 elseif (v.type == "Sprite" or v.type == "Quad") then
304 table.insert(self.wRenderOrder, k)
305 end
306 end
307
308 end
309
310 if (IsValid(self.Owner)) then
311 bone_ent = self.Owner
312 else
313 // when the weapon is dropped
314 bone_ent = self
315 end
316
317 for k, name in pairs( self.wRenderOrder ) do
318
319 local v = self.WElements[name]
320 if (!v) then self.wRenderOrder = nil break end
321 if (v.hide) then continue end
322
323 local pos, ang
324
325 if (v.bone) then
326 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
327 else
328 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
329 end
330
331 if (!pos) then continue end
332
333 local model = v.modelEnt
334 local sprite = v.spriteMaterial
335
336 if (v.type == "Model" and IsValid(model)) then
337
338 model:SetPos(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 model:SetAngles(ang)
344 //model:SetModelScale(v.size)
345 local matrix = Matrix()
346 matrix:Scale(v.size)
347 model:EnableMatrix( "RenderMultiply", matrix )
348
349 if (v.material == "") then
350 model:SetMaterial("")
351 elseif (model:GetMaterial() != v.material) then
352 model:SetMaterial( v.material )
353 end
354
355 if (v.skin and v.skin != model:GetSkin()) then
356 model:SetSkin(v.skin)
357 end
358
359 if (v.bodygroup) then
360 for k, v in pairs( v.bodygroup ) do
361 if (model:GetBodygroup(k) != v) then
362 model:SetBodygroup(k, v)
363 end
364 end
365 end
366
367 if (v.surpresslightning) then
368 render.SuppressEngineLighting(true)
369 end
370
371 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
372 render.SetBlend(v.color.a/255)
373 model:DrawModel()
374 render.SetBlend(1)
375 render.SetColorModulation(1, 1, 1)
376
377 if (v.surpresslightning) then
378 render.SuppressEngineLighting(false)
379 end
380
381 elseif (v.type == "Sprite" and sprite) then
382
383 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
384 render.SetMaterial(sprite)
385 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
386
387 elseif (v.type == "Quad" and v.draw_func) then
388
389 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
390 ang:RotateAroundAxis(ang:Up(), v.angle.y)
391 ang:RotateAroundAxis(ang:Right(), v.angle.p)
392 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
393
394 cam.Start3D2D(drawpos, ang, v.size)
395 v.draw_func( self )
396 cam.End3D2D()
397
398 end
399
400 end
401
402 end
403
404 function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
405
406 local bone, pos, ang
407 if (tab.rel and tab.rel != "") then
408
409 local v = basetab[tab.rel]
410
411 if (!v) then return end
412
413 // Technically, if there exists an element with the same name as a bone
414 // you can get in an infinite loop. Let's just hope nobody's that stupid.
415 pos, ang = self:GetBoneOrientation( basetab, v, ent )
416
417 if (!pos) then return end
418
419 pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
420 ang:RotateAroundAxis(ang:Up(), v.angle.y)
421 ang:RotateAroundAxis(ang:Right(), v.angle.p)
422 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
423
424 else
425
426 bone = ent:LookupBone(bone_override or tab.bone)
427
428 if (!bone) then return end
429
430 pos, ang = Vector(0,0,0), Angle(0,0,0)
431 local m = ent:GetBoneMatrix(bone)
432 if (m) then
433 pos, ang = m:GetTranslation(), m:GetAngles()
434 end
435
436 if (IsValid(self.Owner) and self.Owner:IsPlayer() and
437 ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
438 ang.r = -ang.r // Fixes mirrored models
439 end
440
441 end
442
443 return pos, ang
444 end
445
446 function SWEP:CreateModels( tab )
447
448 if (!tab) then return end
449
450 // Create the clientside models here because Garry says we can't do it in the render hook
451 for k, v in pairs( tab ) do
452 if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
453 string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
454
455 v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
456 if (IsValid(v.modelEnt)) then
457 v.modelEnt:SetPos(self:GetPos())
458 v.modelEnt:SetAngles(self:GetAngles())
459 v.modelEnt:SetParent(self)
460 v.modelEnt:SetNoDraw(true)
461 v.createdModel = v.model
462 else
463 v.modelEnt = nil
464 end
465
466 elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
467 and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
468
469 local name = v.sprite.."-"
470 local params = { ["$basetexture"] = v.sprite }
471 // make sure we create a unique name based on the selected options
472 local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
473 for i, j in pairs( tocheck ) do
474 if (v[j]) then
475 params["$"..j] = 1
476 name = name.."1"
477 else
478 name = name.."0"
479 end
480 end
481
482 v.createdSprite = v.sprite
483 v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
484
485 end
486 end
487
488 end
489
490 local allbones
491 local hasGarryFixedBoneScalingYet = false
492
493 function SWEP:UpdateBonePositions(vm)
494
495 if self.ViewModelBoneMods then
496
497 if (!vm:GetBoneCount()) then return end
498
499 // !! WORKAROUND !! //
500 // We need to check all model names :/
501 local loopthrough = self.ViewModelBoneMods
502 if (!hasGarryFixedBoneScalingYet) then
503 allbones = {}
504 for i=0, vm:GetBoneCount() do
505 local bonename = vm:GetBoneName(i)
506 if (self.ViewModelBoneMods[bonename]) then
507 allbones[bonename] = self.ViewModelBoneMods[bonename]
508 else
509 allbones[bonename] = {
510 scale = Vector(1,1,1),
511 pos = Vector(0,0,0),
512 angle = Angle(0,0,0)
513 }
514 end
515 end
516
517 loopthrough = allbones
518 end
519 // !! ----------- !! //
520
521 for k, v in pairs( loopthrough ) do
522 local bone = vm:LookupBone(k)
523 if (!bone) then continue end
524
525 // !! WORKAROUND !! //
526 local s = Vector(v.scale.x,v.scale.y,v.scale.z)
527 local p = Vector(v.pos.x,v.pos.y,v.pos.z)
528 local ms = Vector(1,1,1)
529 if (!hasGarryFixedBoneScalingYet) then
530 local cur = vm:GetBoneParent(bone)
531 while(cur >= 0) do
532 local pscale = loopthrough[vm:GetBoneName(cur)].scale
533 ms = ms * pscale
534 cur = vm:GetBoneParent(cur)
535 end
536 end
537
538 s = s * ms
539 // !! ----------- !! //
540
541 if vm:GetManipulateBoneScale(bone) != s then
542 vm:ManipulateBoneScale( bone, s )
543 end
544 if vm:GetManipulateBoneAngles(bone) != v.angle then
545 vm:ManipulateBoneAngles( bone, v.angle )
546 end
547 if vm:GetManipulateBonePosition(bone) != p then
548 vm:ManipulateBonePosition( bone, p )
549 end
550 end
551 else
552 self:ResetBonePositions(vm)
553 end
554
555 end
556
557 function SWEP:ResetBonePositions(vm)
558
559 if (!vm:GetBoneCount()) then return end
560 for i=0, vm:GetBoneCount() do
561 vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
562 vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
563 vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
564 end
565
566 end
567
568 /**************************
569 Global utility code
570 **************************/
571
572 // Fully copies the table, meaning all tables inside this table are copied too and so on (normal table.Copy copies only their reference).
573 // Does not copy entities of course, only copies their reference.
574 // WARNING: do not use on tables that contain themselves somewhere down the line or you'll get an infinite loop
575 function table.FullCopy( tab )
576
577 if (!tab) then return nil end
578
579 local res = {}
580 for k, v in pairs( tab ) do
581 if (type(v) == "table") then
582 res[k] = table.FullCopy(v) // recursion ho!
583 elseif (type(v) == "Vector") then
584 res[k] = Vector(v.x, v.y, v.z)
585 elseif (type(v) == "Angle") then
586 res[k] = Angle(v.p, v.y, v.r)
587 else
588 res[k] = v
589 end
590 end
591
592 return res
593
594 end
595
596end