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