· 8 years ago · May 25, 2018, 03:44 AM
1if (CLIENT) then
2SWEP.VElements = {
3 ["rifle"] = { type = "Model", model = "models/Halokiller38/fallout/weapons/Rifles/huntingriflescoped.mdl", bone = "v_weapon.awm_parent", rel = "", pos = Vector(0.654, -1.989, -5.069), angle = Angle(0.174, 0.112, 90), size = Vector(1, 1, 1), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
4}
5SWEP.WElements = {
6 ["rifle"] = { type = "Model", model = "models/Halokiller38/fallout/weapons/Rifles/huntingriflescoped.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(-2.869, 1.391, 3.48), angle = Angle(0, 90, -172.67), size = Vector(1, 1, 1), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
7}
8end
9
10SWEP.PrintName = "Hunting Rifle (w/ Scope)" // 'Nice' Weapon name (Shown on HUD)
11SWEP.Base = "boh_scoped_base"
12SWEP.Category = "Fallout Sweps - Rifles"
13SWEP.Spawnable = true
14SWEP.AdminSpawnable = false
15
16SWEP.HoldType = "ar2"
17SWEP.ViewModelFOV = 50
18SWEP.ViewModelFlip = true
19SWEP.ViewModel = "models/weapons/v_snip_awp.mdl"
20SWEP.WorldModel = "models/Halokiller38/fallout/weapons/Rifles/huntingriflescoped.mdl"
21SWEP.ShowViewModel = true
22SWEP.ShowWorldModel = false
23SWEP.ViewModelBoneMods = {
24 ["v_weapon.awm_parent"] = { scale = Vector(0.009, 0.009, 0.009), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) },
25 ["v_weapon.Right_Arm"] = { scale = Vector(1, 1, 1), pos = Vector(-3.175, 3.174, -1.905), angle = Angle(0, 0, 0) }
26}
27
28SWEP.Primary.Sound = Sound("weapons/riflehunting/wpn_huntingrifle.wav")
29SWEP.Primary.RPM = 40 -- This is in Rounds Per Minute
30SWEP.Primary.ClipSize = 5 -- Size of a clip
31SWEP.Primary.DefaultClip = 0 -- Bullets you start with
32SWEP.Primary.KickUp = 4 -- Maximum up recoil (rise)
33SWEP.Primary.KickDown = .1 -- Maximum down recoil (skeet)
34SWEP.Primary.KickHorizontal = .4 -- Maximum up recoil (stock)
35SWEP.Primary.Automatic = false -- Automatic/Semi Auto
36SWEP.Primary.Ammo = "308"
37
38SWEP.Secondary.ScopeZoom = 10
39SWEP.Secondary.UseACOG = false -- Choose one scope type
40SWEP.Secondary.UseMilDot = true -- I mean it, only one
41SWEP.Secondary.UseSVD = false -- If you choose more than one, your scope will not show up at all
42SWEP.Secondary.UseParabolic = false
43SWEP.Secondary.UseElcan = false
44SWEP.Secondary.UseGreenDuplex = false
45SWEP.Secondary.UseAimpoint = false
46SWEP.Secondary.UseMatador = false
47
48SWEP.data = {}
49SWEP.data.ironsights = 1
50SWEP.ScopeScale = 0.7
51
52SWEP.Primary.NumShots = 1 --how many bullets to shoot per trigger pull
53SWEP.Primary.Damage = 76 --base damage per bullet
54SWEP.Primary.Spread = .025 --define from-the-hip accuracy 1 is terrible, .0001 is exact)
55SWEP.Primary.IronAccuracy = .0005 -- ironsight accuracy, should be the same for shotguns
56
57-- enter iron sight info and bone mod info below
58
59SWEP.RunArmOffset = Vector (-2.6657, 0, 3.5)
60SWEP.RunArmAngle = Vector (-20.0824, -20.5693, 0)
61SWEP.IronSightsPos = Vector(6.225, 0, 1.519)
62SWEP.IronSightsAng = Vector(0, 0.279, 0)
63
64/********************************************************
65 SWEP Construction Kit base code
66 Created by Clavus
67 Available for public use, thread at:
68 facepunch.com/threads/1032378
69
70
71 DESCRIPTION:
72 This script is meant for experienced scripters
73 that KNOW WHAT THEY ARE DOING. Don't come to me
74 with basic Lua questions.
75
76 Just copy into your SWEP or SWEP base of choice
77 and merge with your own code.
78
79 The SWEP.VElements, SWEP.WElements and
80 SWEP.ViewModelBoneMods tables are all optional
81 and only have to be visible to the client.
82********************************************************/
83
84function SWEP:Initialize()
85
86 // other initialize code goes here
87
88 if CLIENT then
89
90 // Create a new table for every weapon instance
91 self.VElements = table.FullCopy( self.VElements )
92 self.WElements = table.FullCopy( self.WElements )
93 self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
94
95 self:CreateModels(self.VElements) // create viewmodels
96 self:CreateModels(self.WElements) // create worldmodels
97
98 // init view model bone build function
99 if IsValid(self.Owner) then
100 local vm = self.Owner:GetViewModel()
101 if IsValid(vm) then
102 self:ResetBonePositions(vm)
103
104 // Init viewmodel visibility
105 if (self.ShowViewModel == nil or self.ShowViewModel) then
106 vm:SetColor(Color(255,255,255,255))
107 else
108 // we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
109 vm:SetColor(Color(255,255,255,1))
110 // ^ stopped working in GMod 13 because you have to do Entity:SetRenderMode(1) for translucency to kick in
111 // 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
112 vm:SetMaterial("Debug/hsv")
113 end
114 end
115 end
116
117 end
118
119end
120
121function SWEP:Holster()
122
123 if CLIENT and IsValid(self.Owner) then
124 local vm = self.Owner:GetViewModel()
125 if IsValid(vm) then
126 self:ResetBonePositions(vm)
127 end
128 end
129
130 return true
131end
132
133function SWEP:OnRemove()
134 self:Holster()
135end
136
137if CLIENT then
138
139 SWEP.vRenderOrder = nil
140 function SWEP:ViewModelDrawn()
141
142 local vm = self.Owner:GetViewModel()
143 if !IsValid(vm) then return end
144
145 if (!self.VElements) then return end
146
147 self:UpdateBonePositions(vm)
148
149 if (!self.vRenderOrder) then
150
151 // we build a render order because sprites need to be drawn after models
152 self.vRenderOrder = {}
153
154 for k, v in pairs( self.VElements ) do
155 if (v.type == "Model") then
156 table.insert(self.vRenderOrder, 1, k)
157 elseif (v.type == "Sprite" or v.type == "Quad") then
158 table.insert(self.vRenderOrder, k)
159 end
160 end
161
162 end
163
164 for k, name in ipairs( self.vRenderOrder ) do
165
166 local v = self.VElements[name]
167 if (!v) then self.vRenderOrder = nil break end
168 if (v.hide) then continue end
169
170 local model = v.modelEnt
171 local sprite = v.spriteMaterial
172
173 if (!v.bone) then continue end
174
175 local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
176
177 if (!pos) then continue end
178
179 if (v.type == "Model" and IsValid(model)) then
180
181 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
182 ang:RotateAroundAxis(ang:Up(), v.angle.y)
183 ang:RotateAroundAxis(ang:Right(), v.angle.p)
184 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
185
186 model:SetAngles(ang)
187 //model:SetModelScale(v.size)
188 local matrix = Matrix()
189 matrix:Scale(v.size)
190 model:EnableMatrix( "RenderMultiply", matrix )
191
192 if (v.material == "") then
193 model:SetMaterial("")
194 elseif (model:GetMaterial() != v.material) then
195 model:SetMaterial( v.material )
196 end
197
198 if (v.skin and v.skin != model:GetSkin()) then
199 model:SetSkin(v.skin)
200 end
201
202 if (v.bodygroup) then
203 for k, v in pairs( v.bodygroup ) do
204 if (model:GetBodygroup(k) != v) then
205 model:SetBodygroup(k, v)
206 end
207 end
208 end
209
210 if (v.surpresslightning) then
211 render.SuppressEngineLighting(true)
212 end
213
214 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
215 render.SetBlend(v.color.a/255)
216 model:DrawModel()
217 render.SetBlend(1)
218 render.SetColorModulation(1, 1, 1)
219
220 if (v.surpresslightning) then
221 render.SuppressEngineLighting(false)
222 end
223
224 elseif (v.type == "Sprite" and sprite) then
225
226 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
227 render.SetMaterial(sprite)
228 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
229
230 elseif (v.type == "Quad" and v.draw_func) then
231
232 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
233 ang:RotateAroundAxis(ang:Up(), v.angle.y)
234 ang:RotateAroundAxis(ang:Right(), v.angle.p)
235 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
236
237 cam.Start3D2D(drawpos, ang, v.size)
238 v.draw_func( self )
239 cam.End3D2D()
240
241 end
242
243 end
244
245 end
246
247 SWEP.wRenderOrder = nil
248 function SWEP:DrawWorldModel()
249
250 if (self.ShowWorldModel == nil or self.ShowWorldModel) then
251 self:DrawModel()
252 end
253
254 if (!self.WElements) then return end
255
256 if (!self.wRenderOrder) then
257
258 self.wRenderOrder = {}
259
260 for k, v in pairs( self.WElements ) do
261 if (v.type == "Model") then
262 table.insert(self.wRenderOrder, 1, k)
263 elseif (v.type == "Sprite" or v.type == "Quad") then
264 table.insert(self.wRenderOrder, k)
265 end
266 end
267
268 end
269
270 if (IsValid(self.Owner)) then
271 bone_ent = self.Owner
272 else
273 // when the weapon is dropped
274 bone_ent = self
275 end
276
277 for k, name in pairs( self.wRenderOrder ) do
278
279 local v = self.WElements[name]
280 if (!v) then self.wRenderOrder = nil break end
281 if (v.hide) then continue end
282
283 local pos, ang
284
285 if (v.bone) then
286 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
287 else
288 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
289 end
290
291 if (!pos) then continue end
292
293 local model = v.modelEnt
294 local sprite = v.spriteMaterial
295
296 if (v.type == "Model" and IsValid(model)) then
297
298 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
299 ang:RotateAroundAxis(ang:Up(), v.angle.y)
300 ang:RotateAroundAxis(ang:Right(), v.angle.p)
301 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
302
303 model:SetAngles(ang)
304 //model:SetModelScale(v.size)
305 local matrix = Matrix()
306 matrix:Scale(v.size)
307 model:EnableMatrix( "RenderMultiply", matrix )
308
309 if (v.material == "") then
310 model:SetMaterial("")
311 elseif (model:GetMaterial() != v.material) then
312 model:SetMaterial( v.material )
313 end
314
315 if (v.skin and v.skin != model:GetSkin()) then
316 model:SetSkin(v.skin)
317 end
318
319 if (v.bodygroup) then
320 for k, v in pairs( v.bodygroup ) do
321 if (model:GetBodygroup(k) != v) then
322 model:SetBodygroup(k, v)
323 end
324 end
325 end
326
327 if (v.surpresslightning) then
328 render.SuppressEngineLighting(true)
329 end
330
331 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
332 render.SetBlend(v.color.a/255)
333 model:DrawModel()
334 render.SetBlend(1)
335 render.SetColorModulation(1, 1, 1)
336
337 if (v.surpresslightning) then
338 render.SuppressEngineLighting(false)
339 end
340
341 elseif (v.type == "Sprite" and sprite) then
342
343 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
344 render.SetMaterial(sprite)
345 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
346
347 elseif (v.type == "Quad" and v.draw_func) then
348
349 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
350 ang:RotateAroundAxis(ang:Up(), v.angle.y)
351 ang:RotateAroundAxis(ang:Right(), v.angle.p)
352 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
353
354 cam.Start3D2D(drawpos, ang, v.size)
355 v.draw_func( self )
356 cam.End3D2D()
357
358 end
359
360 end
361
362 end
363
364 function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
365
366 local bone, pos, ang
367 if (tab.rel and tab.rel != "") then
368
369 local v = basetab[tab.rel]
370
371 if (!v) then return end
372
373 // Technically, if there exists an element with the same name as a bone
374 // you can get in an infinite loop. Let's just hope nobody's that stupid.
375 pos, ang = self:GetBoneOrientation( basetab, v, ent )
376
377 if (!pos) then return end
378
379 pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
380 ang:RotateAroundAxis(ang:Up(), v.angle.y)
381 ang:RotateAroundAxis(ang:Right(), v.angle.p)
382 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
383
384 else
385
386 bone = ent:LookupBone(bone_override or tab.bone)
387
388 if (!bone) then return end
389
390 pos, ang = Vector(0,0,0), Angle(0,0,0)
391 local m = ent:GetBoneMatrix(bone)
392 if (m) then
393 pos, ang = m:GetTranslation(), m:GetAngles()
394 end
395
396 if (IsValid(self.Owner) and self.Owner:IsPlayer() and
397 ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
398 ang.r = -ang.r // Fixes mirrored models
399 end
400
401 end
402
403 return pos, ang
404 end
405
406 function SWEP:CreateModels( tab )
407
408 if (!tab) then return end
409
410 // Create the clientside models here because Garry says we can't do it in the render hook
411 for k, v in pairs( tab ) do
412 if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
413 string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
414
415 v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
416 if (IsValid(v.modelEnt)) then
417 v.modelEnt:SetPos(self:GetPos())
418 v.modelEnt:SetAngles(self:GetAngles())
419 v.modelEnt:SetParent(self)
420 v.modelEnt:SetNoDraw(true)
421 v.createdModel = v.model
422 else
423 v.modelEnt = nil
424 end
425
426 elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
427 and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
428
429 local name = v.sprite.."-"
430 local params = { ["$basetexture"] = v.sprite }
431 // make sure we create a unique name based on the selected options
432 local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
433 for i, j in pairs( tocheck ) do
434 if (v[j]) then
435 params["$"..j] = 1
436 name = name.."1"
437 else
438 name = name.."0"
439 end
440 end
441
442 v.createdSprite = v.sprite
443 v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
444
445 end
446 end
447
448 end
449
450 local allbones
451 local hasGarryFixedBoneScalingYet = false
452
453 function SWEP:UpdateBonePositions(vm)
454
455 if self.ViewModelBoneMods then
456
457 if (!vm:GetBoneCount()) then return end
458
459 // !! WORKAROUND !! //
460 // We need to check all model names :/
461 local loopthrough = self.ViewModelBoneMods
462 if (!hasGarryFixedBoneScalingYet) then
463 allbones = {}
464 for i=0, vm:GetBoneCount() do
465 local bonename = vm:GetBoneName(i)
466 if (self.ViewModelBoneMods[bonename]) then
467 allbones[bonename] = self.ViewModelBoneMods[bonename]
468 else
469 allbones[bonename] = {
470 scale = Vector(1,1,1),
471 pos = Vector(0,0,0),
472 angle = Angle(0,0,0)
473 }
474 end
475 end
476
477 loopthrough = allbones
478 end
479 // !! ----------- !! //
480
481 for k, v in pairs( loopthrough ) do
482 local bone = vm:LookupBone(k)
483 if (!bone) then continue end
484
485 // !! WORKAROUND !! //
486 local s = Vector(v.scale.x,v.scale.y,v.scale.z)
487 local p = Vector(v.pos.x,v.pos.y,v.pos.z)
488 local ms = Vector(1,1,1)
489 if (!hasGarryFixedBoneScalingYet) then
490 local cur = vm:GetBoneParent(bone)
491 while(cur >= 0) do
492 local pscale = loopthrough[vm:GetBoneName(cur)].scale
493 ms = ms * pscale
494 cur = vm:GetBoneParent(cur)
495 end
496 end
497
498 s = s * ms
499 // !! ----------- !! //
500
501 if vm:GetManipulateBoneScale(bone) != s then
502 vm:ManipulateBoneScale( bone, s )
503 end
504 if vm:GetManipulateBoneAngles(bone) != v.angle then
505 vm:ManipulateBoneAngles( bone, v.angle )
506 end
507 if vm:GetManipulateBonePosition(bone) != p then
508 vm:ManipulateBonePosition( bone, p )
509 end
510 end
511 else
512 self:ResetBonePositions(vm)
513 end
514
515 end
516
517 function SWEP:ResetBonePositions(vm)
518
519 if (!vm:GetBoneCount()) then return end
520 for i=0, vm:GetBoneCount() do
521 vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
522 vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
523 vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
524 end
525
526 end
527
528 /**************************
529 Global utility code
530 **************************/
531
532 // Fully copies the table, meaning all tables inside this table are copied too and so on (normal table.Copy copies only their reference).
533 // Does not copy entities of course, only copies their reference.
534 // WARNING: do not use on tables that contain themselves somewhere down the line or you'll get an infinite loop
535 function table.FullCopy( tab )
536
537 if (!tab) then return nil end
538
539 local res = {}
540 for k, v in pairs( tab ) do
541 if (type(v) == "table") then
542 res[k] = table.FullCopy(v) // recursion ho!
543 elseif (type(v) == "Vector") then
544 res[k] = Vector(v.x, v.y, v.z)
545 elseif (type(v) == "Angle") then
546 res[k] = Angle(v.p, v.y, v.r)
547 else
548 res[k] = v
549 end
550 end
551
552 return res
553
554 end
555
556end