· 6 years ago · Aug 16, 2019, 07:54 AM
1if( SERVER ) then
2 AddCSLuaFile( "shared.lua" );
3end
4
5SWEP.Contact = "steamcommunity.com/id/ms-dosja"
6SWEP.Author = "MS-DOS"
7
8SWEP.Spawnable = true
9SWEP.AdminSpawnable = true
10SWEP.HoldType = "pistol"
11SWEP.ViewModelFOV = 47
12SWEP.ViewModelFlip = false
13SWEP.ViewModel = "models/np_geiger_sw/np_geiger_sw.mdl"
14SWEP.WorldModel = "models/np_geiger/np_geiger.mdl"
15SWEP.ShowViewModel = true
16SWEP.ShowWorldModel = true
17SWEP.UseHands = true
18SWEP.ViewModelBoneMods = {}
19SWEP.m_WeaponDeploySpeed = 1
20SWEP.DrawAmmo = false
21
22SWEP.FiresUnderwater = true
23SWEP.Primary.Damage = 0
24SWEP.base = "weapon_base"
25SWEP.Primary.ClipSize = -1
26SWEP.Primary.DefaultClip = -1
27SWEP.Primary.Automatic = true
28SWEP.Primary.Ammo = "none"
29SWEP.Primary.Delay = 0.4
30
31SWEP.Secondary.Ammo = "none"
32SWEP.Secondary.ClipSize = -1
33SWEP.Secondary.DefaultClip = -1
34SWEP.Secondary.Automatic = false
35SWEP.Secondary.Delay = 0.7
36
37SWEP.WElements = {
38 ["element_name"] = { type = "Model", model = "models/np_geiger/np_geiger.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(5.714, 1.557, 7), angle = Angle(178.83, -92.338, -97.014), size = Vector(1.144, 1.144, 1.144), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
39}
40
41SWEP.Weight = 50
42SWEP.AutoSwitchTo = false
43SWEP.AutoSwitchFrom = false
44
45SWEP.Category = "HNPS"
46SWEP.PrintName = "Geiger Counter SWEP"
47SWEP.Slot = 1
48SWEP.SlotPos = 1
49SWEP.DrawAmmo = true
50SWEP.DrawCrosshair = true
51
52SWEP.m_bPlayPickupSound = true
53
54function SWEP:Think()
55end
56
57function SWEP:Initialize()
58 self:SetWeaponHoldType( self.HoldType )
59
60
61 if CLIENT then
62
63 // Create a new table for every weapon instance
64 self.VElements = table.FullCopy( self.VElements )
65 self.WElements = table.FullCopy( self.WElements )
66 self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
67
68 self:CreateModels(self.VElements) // create viewmodels
69 self:CreateModels(self.WElements) // create worldmodels
70
71 // init view model bone build function
72 if IsValid(self.Owner) then
73 local vm = self.Owner:GetViewModel()
74 if IsValid(vm) then
75 self:ResetBonePositions(vm)
76
77 // Init viewmodel visibility
78 if (self.ShowViewModel == nil or self.ShowViewModel) then
79 vm:SetColor(Color(255,255,255,255))
80 else
81 // we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
82 vm:SetColor(Color(255,255,255,1))
83 // ^ stopped working in GMod 13 because you have to do Entity:SetRenderMode(1) for translucency to kick in
84 // 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
85 vm:SetMaterial("Debug/hsv")
86 end
87 end
88 end
89
90 end
91end
92
93function SWEP:Think()
94 if self.Owner:IsBot() then self:SetColor(Color(0,255,0,255)) else -- Bots create a shipload of errors since they don't have any client vars on them so let's set them all green (or i'm just stupid)
95 end
96end
97
98function SWEP:Deploy()
99 self:SetWeaponHoldType( self.HoldType )
100 return true
101end
102
103function SWEP:Reload()
104 return true
105end
106
107function SWEP:PrimaryAttack()
108 self.Weapon:SetNextPrimaryFire(CurTime() + self.Primary.Delay)
109 local LookingEntity = self.Owner:GetEyeTrace().Entity
110 if LookingEntity:GetClass() == "np_station" then
111 if self.Owner:GetPos():Distance( LookingEntity:GetPos() ) > 80 then return end
112 local RadiationLevelGet = LookingEntity:GetVar("RadiationLevel")
113 if(RadiationLevelGet) == 3 then
114 self.Owner:EmitSound("radiation_t/nn_radiation_high.wav", 90, 150)
115 elseif (RadiationLevelGet) == 2 then
116 self.Owner:EmitSound("radiation_t/nn_radiation_middle.wav", 90, 150)
117 elseif (RadiationLevelGet) == 1 then
118 self.Owner:EmitSound("radiation_t/nn_radiation_low.wav", 90, 150)
119 end
120 end
121 return true
122end
123
124
125function SWEP:Holster()
126 if CLIENT and IsValid(self.Owner) then
127 local vm = self.Owner:GetViewModel()
128 if IsValid(vm) then
129 self:ResetBonePositions(vm)
130 end
131 end
132 return true
133end
134
135function SWEP:OnRemove()
136 self:Holster()
137end
138
139if CLIENT then
140
141 SWEP.vRenderOrder = nil
142 function SWEP:ViewModelDrawn()
143
144 local vm = self.Owner:GetViewModel()
145 if !IsValid(vm) then return end
146
147 if (!self.VElements) then return end
148
149 self:UpdateBonePositions(vm)
150
151 if (!self.vRenderOrder) then
152
153 // we build a render order because sprites need to be drawn after models
154 self.vRenderOrder = {}
155
156 for k, v in pairs( self.VElements ) do
157 if (v.type == "Model") then
158 table.insert(self.vRenderOrder, 1, k)
159 elseif (v.type == "Sprite" or v.type == "Quad") then
160 table.insert(self.vRenderOrder, k)
161 end
162 end
163
164 end
165
166 for k, name in ipairs( self.vRenderOrder ) do
167
168 local v = self.VElements[name]
169 if (!v) then self.vRenderOrder = nil break end
170 if (v.hide) then continue end
171
172 local model = v.modelEnt
173 local sprite = v.spriteMaterial
174
175 if (!v.bone) then continue end
176
177 local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
178
179 if (!pos) then continue end
180
181 if (v.type == "Model" and IsValid(model)) then
182
183 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
184 ang:RotateAroundAxis(ang:Up(), v.angle.y)
185 ang:RotateAroundAxis(ang:Right(), v.angle.p)
186 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
187
188 model:SetAngles(ang)
189 //model:SetModelScale(v.size)
190 local matrix = Matrix()
191 matrix:Scale(v.size)
192 model:EnableMatrix( "RenderMultiply", matrix )
193
194 if (v.material == "") then
195 model:SetMaterial("")
196 elseif (model:GetMaterial() != v.material) then
197 model:SetMaterial( v.material )
198 end
199
200 if (v.skin and v.skin != model:GetSkin()) then
201 model:SetSkin(v.skin)
202 end
203
204 if (v.bodygroup) then
205 for k, v in pairs( v.bodygroup ) do
206 if (model:GetBodygroup(k) != v) then
207 model:SetBodygroup(k, v)
208 end
209 end
210 end
211
212 if (v.surpresslightning) then
213 render.SuppressEngineLighting(true)
214 end
215
216 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
217 render.SetBlend(v.color.a/255)
218 model:DrawModel()
219 render.SetBlend(1)
220 render.SetColorModulation(1, 1, 1)
221
222 if (v.surpresslightning) then
223 render.SuppressEngineLighting(false)
224 end
225
226 elseif (v.type == "Sprite" and sprite) then
227
228 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
229 render.SetMaterial(sprite)
230 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
231
232 elseif (v.type == "Quad" and v.draw_func) then
233
234 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
235 ang:RotateAroundAxis(ang:Up(), v.angle.y)
236 ang:RotateAroundAxis(ang:Right(), v.angle.p)
237 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
238
239 cam.Start3D2D(drawpos, ang, v.size)
240 v.draw_func( self )
241 cam.End3D2D()
242
243 end
244
245 end
246
247 end
248
249 SWEP.wRenderOrder = nil
250 function SWEP:DrawWorldModel()
251
252 if (!self.WElements) then return end
253
254 if (!self.wRenderOrder) then
255
256 self.wRenderOrder = {}
257
258 for k, v in pairs( self.WElements ) do
259 if (v.type == "Model") then
260 table.insert(self.wRenderOrder, 1, k)
261 elseif (v.type == "Sprite" or v.type == "Quad") then
262 table.insert(self.wRenderOrder, k)
263 end
264 end
265
266 end
267
268 if (IsValid(self.Owner)) then
269 bone_ent = self.Owner
270 else
271 // when the weapon is dropped
272 bone_ent = self
273 end
274
275 for k, name in pairs( self.wRenderOrder ) do
276
277 local v = self.WElements[name]
278 if (!v) then self.wRenderOrder = nil break end
279 if (v.hide) then continue end
280
281 local pos, ang
282
283 if (v.bone) then
284 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
285 else
286 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
287 end
288
289 if (!pos) then continue end
290
291 local model = v.modelEnt
292 local sprite = v.spriteMaterial
293
294 if (v.type == "Model" and IsValid(model)) then
295
296 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
297 ang:RotateAroundAxis(ang:Up(), v.angle.y)
298 ang:RotateAroundAxis(ang:Right(), v.angle.p)
299 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
300
301 model:SetAngles(ang)
302 //model:SetModelScale(v.size)
303 local matrix = Matrix()
304 matrix:Scale(v.size)
305 model:EnableMatrix( "RenderMultiply", matrix )
306
307 if (v.material == "") then
308 model:SetMaterial("")
309 elseif (model:GetMaterial() != v.material) then
310 model:SetMaterial( v.material )
311 end
312
313 if (v.skin and v.skin != model:GetSkin()) then
314 model:SetSkin(v.skin)
315 end
316
317 if (v.bodygroup) then
318 for k, v in pairs( v.bodygroup ) do
319 if (model:GetBodygroup(k) != v) then
320 model:SetBodygroup(k, v)
321 end
322 end
323 end
324
325 if (v.surpresslightning) then
326 render.SuppressEngineLighting(true)
327 end
328
329 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
330 render.SetBlend(v.color.a/255)
331 model:DrawModel()
332 render.SetBlend(1)
333 render.SetColorModulation(1, 1, 1)
334
335 if (v.surpresslightning) then
336 render.SuppressEngineLighting(false)
337 end
338
339 elseif (v.type == "Sprite" and sprite) then
340
341 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
342 render.SetMaterial(sprite)
343 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
344
345 elseif (v.type == "Quad" and v.draw_func) then
346
347 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
348 ang:RotateAroundAxis(ang:Up(), v.angle.y)
349 ang:RotateAroundAxis(ang:Right(), v.angle.p)
350 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
351
352 cam.Start3D2D(drawpos, ang, v.size)
353 v.draw_func( self )
354 cam.End3D2D()
355
356 end
357
358 end
359
360 end
361
362 function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
363
364 local bone, pos, ang
365 if (tab.rel and tab.rel != "") then
366
367 local v = basetab[tab.rel]
368
369 if (!v) then return end
370
371 // Technically, if there exists an element with the same name as a bone
372 // you can get in an infinite loop. Let's just hope nobody's that stupid.
373 pos, ang = self:GetBoneOrientation( basetab, v, ent )
374
375 if (!pos) then return end
376
377 pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
378 ang:RotateAroundAxis(ang:Up(), v.angle.y)
379 ang:RotateAroundAxis(ang:Right(), v.angle.p)
380 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
381
382 else
383
384 bone = ent:LookupBone(bone_override or tab.bone)
385
386 if (!bone) then return end
387
388 pos, ang = Vector(0,0,0), Angle(0,0,0)
389 local m = ent:GetBoneMatrix(bone)
390 if (m) then
391 pos, ang = m:GetTranslation(), m:GetAngles()
392 end
393
394 if (IsValid(self.Owner) and self.Owner:IsPlayer() and
395 ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
396 ang.r = -ang.r // Fixes mirrored models
397 end
398
399 end
400
401 return pos, ang
402 end
403
404 function SWEP:CreateModels( tab )
405
406 if (!tab) then return end
407
408 // Create the clientside models here because Garry says we can't do it in the render hook
409 for k, v in pairs( tab ) do
410 if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
411 string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
412
413 v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
414 if (IsValid(v.modelEnt)) then
415 v.modelEnt:SetPos(self:GetPos())
416 v.modelEnt:SetAngles(self:GetAngles())
417 v.modelEnt:SetParent(self)
418 v.modelEnt:SetNoDraw(true)
419 v.createdModel = v.model
420 else
421 v.modelEnt = nil
422 end
423
424 elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
425 and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
426
427 local name = v.sprite.."-"
428 local params = { ["$basetexture"] = v.sprite }
429 // make sure we create a unique name based on the selected options
430 local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
431 for i, j in pairs( tocheck ) do
432 if (v[j]) then
433 params["$"..j] = 1
434 name = name.."1"
435 else
436 name = name.."0"
437 end
438 end
439
440 v.createdSprite = v.sprite
441 v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
442
443 end
444 end
445
446 end
447
448 local allbones
449 local hasGarryFixedBoneScalingYet = false
450
451 function SWEP:UpdateBonePositions(vm)
452
453 if self.ViewModelBoneMods then
454
455 if (!vm:GetBoneCount()) then return end
456
457 // !! WORKAROUND !! //
458 // We need to check all model names :/
459 local loopthrough = self.ViewModelBoneMods
460 if (!hasGarryFixedBoneScalingYet) then
461 allbones = {}
462 for i=0, vm:GetBoneCount() do
463 local bonename = vm:GetBoneName(i)
464 if (self.ViewModelBoneMods[bonename]) then
465 allbones[bonename] = self.ViewModelBoneMods[bonename]
466 else
467 allbones[bonename] = {
468 scale = Vector(1,1,1),
469 pos = Vector(0,0,0),
470 angle = Angle(0,0,0)
471 }
472 end
473 end
474
475 loopthrough = allbones
476 end
477 // !! ----------- !! //
478
479 for k, v in pairs( loopthrough ) do
480 local bone = vm:LookupBone(k)
481 if (!bone) then continue end
482
483 // !! WORKAROUND !! //
484 local s = Vector(v.scale.x,v.scale.y,v.scale.z)
485 local p = Vector(v.pos.x,v.pos.y,v.pos.z)
486 local ms = Vector(1,1,1)
487 if (!hasGarryFixedBoneScalingYet) then
488 local cur = vm:GetBoneParent(bone)
489 while(cur >= 0) do
490 local pscale = loopthrough[vm:GetBoneName(cur)].scale
491 ms = ms * pscale
492 cur = vm:GetBoneParent(cur)
493 end
494 end
495
496 s = s * ms
497 // !! ----------- !! //
498
499 if vm:GetManipulateBoneScale(bone) != s then
500 vm:ManipulateBoneScale( bone, s )
501 end
502 if vm:GetManipulateBoneAngles(bone) != v.angle then
503 vm:ManipulateBoneAngles( bone, v.angle )
504 end
505 if vm:GetManipulateBonePosition(bone) != p then
506 vm:ManipulateBonePosition( bone, p )
507 end
508 end
509 else
510 self:ResetBonePositions(vm)
511 end
512
513 end
514
515 function SWEP:ResetBonePositions(vm)
516
517 if (!vm:GetBoneCount()) then return end
518 for i=0, vm:GetBoneCount() do
519 vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
520 vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
521 vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
522 end
523
524 end
525
526/**************************
527 Global utility code
528**************************/
529
530// Fully copies the table, meaning all tables inside this table are copied too and so on (normal table.Copy copies only their reference).
531// Does not copy entities of course, only copies their reference.
532// WARNING: do not use on tables that contain themselves somewhere down the line or you'll get an infinite loop
533 function table.FullCopy( tab )
534
535 if (!tab) then return nil end
536
537 local res = {}
538 for k, v in pairs( tab ) do
539 if (type(v) == "table") then
540 res[k] = table.FullCopy(v) // recursion ho!
541 elseif (type(v) == "Vector") then
542 res[k] = Vector(v.x, v.y, v.z)
543 elseif (type(v) == "Angle") then
544 res[k] = Angle(v.p, v.y, v.r)
545 else
546 res[k] = v
547 end
548 end
549
550 return res
551
552 end
553
554end