· 7 years ago · Nov 10, 2018, 06:08 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 = { look here for world model
77
78}
79
80SWEP.FireModeName = "Lever-Action"
81
82if (gmod.GetGamemode().Name == "Murderthon 9000") then
83
84 SWEP.Slot = 1 -- Slot in the weapon selection menu
85 SWEP.Weight = 3 -- rank relative ot other weapons. bigger is better
86
87end
88
89if GetConVar("sv_tfa_default_clip") == nil then
90 print("sv_tfa_default_clip is missing! You might've hit the lua limit. Contact the SWEP author(s).")
91else
92 if GetConVar("sv_tfa_default_clip"):GetInt() != -1 then
93 SWEP.Primary.DefaultClip = SWEP.Primary.ClipSize * GetConVar("sv_tfa_default_clip"):GetInt()
94 end
95end
96
97if GetConVar("sv_tfa_unique_slots") != nil then
98 if not (GetConVar("sv_tfa_unique_slots"):GetBool()) then
99 SWEP.SlotPos = 2
100 end
101end
102
103/********************************************************
104 SWEP Construction Kit base code
105 Created by Clavus
106 Available for public use, thread at:
107 facepunch.com/threads/1032378
108
109
110 DESCRIPTION:
111 This script is meant for experienced scripters
112 that KNOW WHAT THEY ARE DOING. Don't come to me
113 with basic Lua questions.
114
115 Just copy into your SWEP or SWEP base of choice
116 and merge with your own code.
117
118 The SWEP.VElements, SWEP.WElements and
119 SWEP.ViewModelBoneMods tables are all optional
120 and only have to be visible to the client.
121********************************************************/
122
123function SWEP:Initialize()
124
125 // other initialize code goes here
126
127 if CLIENT then
128
129 // Create a new table for every weapon instance
130 self.VElements = table.FullCopy( self.VElements )
131 self.WElements = table.FullCopy( self.WElements )
132 self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
133
134 self:CreateModels(self.VElements) // create viewmodels
135 self:CreateModels(self.WElements) // create worldmodels
136
137 // init view model bone build function
138 if IsValid(self.Owner) then
139 local vm = self.Owner:GetViewModel()
140 if IsValid(vm) then
141 self:ResetBonePositions(vm)
142
143 // Init viewmodel visibility
144 if (self.ShowViewModel == nil or self.ShowViewModel) then
145 vm:SetColor(Color(255,255,255,255))
146 else
147 // we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
148 vm:SetColor(Color(255,255,255,1))
149 // ^ stopped working in GMod 13 because you have to do Entity:SetRenderMode(1) for translucency to kick in
150 // 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
151 vm:SetMaterial("Debug/hsv")
152 end
153 end
154 end
155
156 end
157
158end
159
160function SWEP:Holster()
161
162 if CLIENT and IsValid(self.Owner) then
163 local vm = self.Owner:GetViewModel()
164 if IsValid(vm) then
165 self:ResetBonePositions(vm)
166 end
167 end
168
169 return true
170end
171
172function SWEP:OnRemove()
173 self:Holster()
174end
175
176if CLIENT then
177
178 SWEP.vRenderOrder = nil
179 function SWEP:ViewModelDrawn()
180
181 local vm = self.Owner:GetViewModel()
182 if !IsValid(vm) then return end
183
184 if (!self.VElements) then return end
185
186 self:UpdateBonePositions(vm)
187
188 if (!self.vRenderOrder) then
189
190 // we build a render order because sprites need to be drawn after models
191 self.vRenderOrder = {}
192
193 for k, v in pairs( self.VElements ) do
194 if (v.type == "Model") then
195 table.insert(self.vRenderOrder, 1, k)
196 elseif (v.type == "Sprite" or v.type == "Quad") then
197 table.insert(self.vRenderOrder, k)
198 end
199 end
200
201 end
202
203 for k, name in ipairs( self.vRenderOrder ) do
204
205 local v = self.VElements[name]
206 if (!v) then self.vRenderOrder = nil break end
207 if (v.hide) then continue end
208
209 local model = v.modelEnt
210 local sprite = v.spriteMaterial
211
212 if (!v.bone) then continue end
213
214 local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
215
216 if (!pos) then continue end
217
218 if (v.type == "Model" and IsValid(model)) then
219
220 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
221 ang:RotateAroundAxis(ang:Up(), v.angle.y)
222 ang:RotateAroundAxis(ang:Right(), v.angle.p)
223 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
224
225 model:SetAngles(ang)
226 //model:SetModelScale(v.size)
227 local matrix = Matrix()
228 matrix:Scale(v.size)
229 model:EnableMatrix( "RenderMultiply", matrix )
230
231 if (v.material == "") then
232 model:SetMaterial("")
233 elseif (model:GetMaterial() != v.material) then
234 model:SetMaterial( v.material )
235 end
236
237 if (v.skin and v.skin != model:GetSkin()) then
238 model:SetSkin(v.skin)
239 end
240
241 if (v.bodygroup) then
242 for k, v in pairs( v.bodygroup ) do
243 if (model:GetBodygroup(k) != v) then
244 model:SetBodygroup(k, v)
245 end
246 end
247 end
248
249 if (v.surpresslightning) then
250 render.SuppressEngineLighting(true)
251 end
252
253 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
254 render.SetBlend(v.color.a/255)
255 model:DrawModel()
256 render.SetBlend(1)
257 render.SetColorModulation(1, 1, 1)
258
259 if (v.surpresslightning) then
260 render.SuppressEngineLighting(false)
261 end
262
263 elseif (v.type == "Sprite" and sprite) then
264
265 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
266 render.SetMaterial(sprite)
267 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
268
269 elseif (v.type == "Quad" and v.draw_func) then
270
271 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
272 ang:RotateAroundAxis(ang:Up(), v.angle.y)
273 ang:RotateAroundAxis(ang:Right(), v.angle.p)
274 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
275
276 cam.Start3D2D(drawpos, ang, v.size)
277 v.draw_func( self )
278 cam.End3D2D()
279
280 end
281
282 end
283
284 end
285
286 SWEP.wRenderOrder = nil
287 function SWEP:DrawWorldModel()
288
289 if (self.ShowWorldModel == nil or self.ShowWorldModel) then
290 self:DrawModel()
291 end
292
293 if (!self.WElements) then return end
294
295 if (!self.wRenderOrder) then
296
297 self.wRenderOrder = {}
298
299 for k, v in pairs( self.WElements ) do
300 if (v.type == "Model") then
301 table.insert(self.wRenderOrder, 1, k)
302 elseif (v.type == "Sprite" or v.type == "Quad") then
303 table.insert(self.wRenderOrder, k)
304 end
305 end
306
307 end
308
309 if (IsValid(self.Owner)) then
310 bone_ent = self.Owner
311 else
312 // when the weapon is dropped
313 bone_ent = self
314 end
315
316 for k, name in pairs( self.wRenderOrder ) do
317
318 local v = self.WElements[name]
319 if (!v) then self.wRenderOrder = nil break end
320 if (v.hide) then continue end
321
322 local pos, ang
323
324 if (v.bone) then
325 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
326 else
327 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
328 end
329
330 if (!pos) then continue end
331
332 local model = v.modelEnt
333 local sprite = v.spriteMaterial
334
335 if (v.type == "Model" and IsValid(model)) then
336
337 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
338 ang:RotateAroundAxis(ang:Up(), v.angle.y)
339 ang:RotateAroundAxis(ang:Right(), v.angle.p)
340 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
341
342 model:SetAngles(ang)
343 //model:SetModelScale(v.size)
344 local matrix = Matrix()
345 matrix:Scale(v.size)
346 model:EnableMatrix( "RenderMultiply", matrix )
347
348 if (v.material == "") then
349 model:SetMaterial("")
350 elseif (model:GetMaterial() != v.material) then
351 model:SetMaterial( v.material )
352 end
353
354 if (v.skin and v.skin != model:GetSkin()) then
355 model:SetSkin(v.skin)
356 end
357
358 if (v.bodygroup) then
359 for k, v in pairs( v.bodygroup ) do
360 if (model:GetBodygroup(k) != v) then
361 model:SetBodygroup(k, v)
362 end
363 end
364 end
365
366 if (v.surpresslightning) then
367 render.SuppressEngineLighting(true)
368 end
369
370 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
371 render.SetBlend(v.color.a/255)
372 model:DrawModel()
373 render.SetBlend(1)
374 render.SetColorModulation(1, 1, 1)
375
376 if (v.surpresslightning) then
377 render.SuppressEngineLighting(false)
378 end
379
380 elseif (v.type == "Sprite" and sprite) then
381
382 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
383 render.SetMaterial(sprite)
384 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
385
386 elseif (v.type == "Quad" and v.draw_func) then
387
388 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
389 ang:RotateAroundAxis(ang:Up(), v.angle.y)
390 ang:RotateAroundAxis(ang:Right(), v.angle.p)
391 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
392
393 cam.Start3D2D(drawpos, ang, v.size)
394 v.draw_func( self )
395 cam.End3D2D()
396
397 end
398
399 end
400
401 end
402
403 function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
404
405 local bone, pos, ang
406 if (tab.rel and tab.rel != "") then
407
408 local v = basetab[tab.rel]
409
410 if (!v) then return end
411
412 // Technically, if there exists an element with the same name as a bone
413 // you can get in an infinite loop. Let's just hope nobody's that stupid.
414 pos, ang = self:GetBoneOrientation( basetab, v, ent )
415
416 if (!pos) then return end
417
418 pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
419 ang:RotateAroundAxis(ang:Up(), v.angle.y)
420 ang:RotateAroundAxis(ang:Right(), v.angle.p)
421 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
422
423 else
424
425 bone = ent:LookupBone(bone_override or tab.bone)
426
427 if (!bone) then return end
428
429 pos, ang = Vector(0,0,0), Angle(0,0,0)
430 local m = ent:GetBoneMatrix(bone)
431 if (m) then
432 pos, ang = m:GetTranslation(), m:GetAngles()
433 end
434
435 if (IsValid(self.Owner) and self.Owner:IsPlayer() and
436 ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
437 ang.r = -ang.r // Fixes mirrored models
438 end
439
440 end
441
442 return pos, ang
443 end
444
445 function SWEP:CreateModels( tab )
446
447 if (!tab) then return end
448
449 // Create the clientside models here because Garry says we can't do it in the render hook
450 for k, v in pairs( tab ) do
451 if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
452 string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
453
454 v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
455 if (IsValid(v.modelEnt)) then
456 v.modelEnt:SetPos(self:GetPos())
457 v.modelEnt:SetAngles(self:GetAngles())
458 v.modelEnt:SetParent(self)
459 v.modelEnt:SetNoDraw(true)
460 v.createdModel = v.model
461 else
462 v.modelEnt = nil
463 end
464
465 elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
466 and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
467
468 local name = v.sprite.."-"
469 local params = { ["$basetexture"] = v.sprite }
470 // make sure we create a unique name based on the selected options
471 local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
472 for i, j in pairs( tocheck ) do
473 if (v[j]) then
474 params["$"..j] = 1
475 name = name.."1"
476 else
477 name = name.."0"
478 end
479 end
480
481 v.createdSprite = v.sprite
482 v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
483
484 end
485 end
486
487 end
488
489 local allbones
490 local hasGarryFixedBoneScalingYet = false
491
492 function SWEP:UpdateBonePositions(vm)
493
494 if self.ViewModelBoneMods then
495
496 if (!vm:GetBoneCount()) then return end
497
498 // !! WORKAROUND !! //
499 // We need to check all model names :/
500 local loopthrough = self.ViewModelBoneMods
501 if (!hasGarryFixedBoneScalingYet) then
502 allbones = {}
503 for i=0, vm:GetBoneCount() do
504 local bonename = vm:GetBoneName(i)
505 if (self.ViewModelBoneMods[bonename]) then
506 allbones[bonename] = self.ViewModelBoneMods[bonename]
507 else
508 allbones[bonename] = {
509 scale = Vector(1,1,1),
510 pos = Vector(0,0,0),
511 angle = Angle(0,0,0)
512 }
513 end
514 end
515
516 loopthrough = allbones
517 end
518 // !! ----------- !! //
519
520 for k, v in pairs( loopthrough ) do
521 local bone = vm:LookupBone(k)
522 if (!bone) then continue end
523
524 // !! WORKAROUND !! //
525 local s = Vector(v.scale.x,v.scale.y,v.scale.z)
526 local p = Vector(v.pos.x,v.pos.y,v.pos.z)
527 local ms = Vector(1,1,1)
528 if (!hasGarryFixedBoneScalingYet) then
529 local cur = vm:GetBoneParent(bone)
530 while(cur >= 0) do
531 local pscale = loopthrough[vm:GetBoneName(cur)].scale
532 ms = ms * pscale
533 cur = vm:GetBoneParent(cur)
534 end
535 end
536
537 s = s * ms
538 // !! ----------- !! //
539
540 if vm:GetManipulateBoneScale(bone) != s then
541 vm:ManipulateBoneScale( bone, s )
542 end
543 if vm:GetManipulateBoneAngles(bone) != v.angle then
544 vm:ManipulateBoneAngles( bone, v.angle )
545 end
546 if vm:GetManipulateBonePosition(bone) != p then
547 vm:ManipulateBonePosition( bone, p )
548 end
549 end
550 else
551 self:ResetBonePositions(vm)
552 end
553
554 end
555
556 function SWEP:ResetBonePositions(vm)
557
558 if (!vm:GetBoneCount()) then return end
559 for i=0, vm:GetBoneCount() do
560 vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
561 vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
562 vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
563 end
564
565 end
566
567 /**************************
568 Global utility code
569 **************************/
570
571 // Fully copies the table, meaning all tables inside this table are copied too and so on (normal table.Copy copies only their reference).
572 // Does not copy entities of course, only copies their reference.
573 // WARNING: do not use on tables that contain themselves somewhere down the line or you'll get an infinite loop
574 function table.FullCopy( tab )
575
576 if (!tab) then return nil end
577
578 local res = {}
579 for k, v in pairs( tab ) do
580 if (type(v) == "table") then
581 res[k] = table.FullCopy(v) // recursion ho!
582 elseif (type(v) == "Vector") then
583 res[k] = Vector(v.x, v.y, v.z)
584 elseif (type(v) == "Angle") then
585 res[k] = Angle(v.p, v.y, v.r)
586 else
587 res[k] = v
588 end
589 end
590
591 return res
592
593 end
594
595end