· 9 years ago · Nov 06, 2016, 08:16 PM
1AddCSLuaFile()
2
3/// For Santos RP DarkRP servers -- Nykez //
4
5if SERVER then
6 AddCSLuaFile("cl_menu.lua")
7end
8
9if CLIENT then
10 SWEP.PrintName = "Keys"
11 SWEP.Slot = 1
12 SWEP.SlotPos = 1
13 SWEP.DrawAmmo = false
14 SWEP.DrawCrosshair = false
15
16 include("cl_menu.lua")
17end
18
19AddCSLuaFile()
20
21if SERVER then
22 AddCSLuaFile("cl_menu.lua")
23end
24
25if CLIENT then
26 SWEP.PrintName = "Keys"
27 SWEP.Slot = 1
28 SWEP.SlotPos = 1
29 SWEP.DrawAmmo = false
30 SWEP.DrawCrosshair = false
31
32 include("cl_menu.lua")
33end
34
35
36-- Variables that are used on both client and server
37
38SWEP.Author = "Nykez/DarkRP"
39SWEP.Contact = ""
40SWEP.Purpose = "Darkrp Keys"
41SWEP.Instructions = ""
42
43SWEP.HoldType = "slam"
44SWEP.ViewModelFOV = 60
45SWEP.Sound = "doors/door_latch3.wav"
46SWEP.ViewModelFlip = false
47SWEP.ViewModel = "models/weapons/c_arms_citizen.mdl"
48SWEP.WorldModel = "models/sentry/pgkey.mdl"
49SWEP.ShowViewModel = true
50SWEP.ShowWorldModel = true
51SWEP.ViewModelBoneMods = {
52 ["ValveBiped.Bip01_R_Finger31"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(0, -62.857, 0) },
53 ["ValveBiped.Bip01_R_Finger11"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(0, -11.429, 0) },
54 ["ValveBiped.Bip01_R_Finger02"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(-1.905, 15.237, 0) },
55 ["ValveBiped.Bip01_R_UpperArm"] = { scale = Vector(1, 1, 1), pos = Vector(15.237, 4.443, -1.905), angle = Angle(5.714, -64.763, -19.049) },
56 ["ValveBiped.Bip01_R_Finger42"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(0, 11, 0) },
57 ["ValveBiped.Bip01_R_Finger01"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(0, -20.952, 0) },
58 ["ValveBiped.Bip01_R_Finger22"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(0, -13.334, 0) },
59 ["ValveBiped.Bip01_R_Hand"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(0, -32.382, 0) },
60 ["ValveBiped.Bip01_R_Finger41"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(-7.619, -70.476, 7.618) },
61 ["ValveBiped.Bip01_R_Finger1"] = { scale = Vector(1, 1, 1), pos = Vector(0.2, -0, -0.318), angle = Angle(-7.619, -38.096, 0) },
62 ["ValveBiped.Bip01_R_Finger21"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(0, -78.096, 0) },
63 ["ValveBiped.Bip01_R_Finger0"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, -0.201), angle = Angle(0, 34.285, 0) },
64 ["ValveBiped.Bip01_R_Finger4"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(0, -13.334, 0) },
65 ["ValveBiped.Bip01_R_Forearm"] = { scale = Vector(1, 1, 1), pos = Vector(4.443, 0.952, 0.317), angle = Angle(-51.43, 68.57, -45.715) },
66 ["ValveBiped.Bip01_R_Finger12"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(0, -74.287, 0) },
67 ["ValveBiped.Bip01_R_Finger2"] = { scale = Vector(1, 1, 1), pos = Vector(0.2, 0, 0), angle = Angle(0, -20.952, 0) },
68 ["ValveBiped.Bip01_R_Finger32"] = { scale = Vector(1, 1, 1), pos = Vector(0, 0, 0), angle = Angle(0, -24.762, 0) },
69 ["ValveBiped.Bip01_Spine4"] = { scale = Vector(1, 1, 1), pos = Vector(1.269, 2.539, 6.666), angle = Angle(-180, 40, 129.524) },
70 ["ValveBiped.Bip01_R_Finger3"] = { scale = Vector(1, 1, 1), pos = Vector(0.2, 0, 0), angle = Angle(0, -20.952, 0) },
71 ["ValveBiped.Bip01_L_UpperArm"] = { scale = Vector(1, 1, 1), pos = Vector(14.286, 0, 0), angle = Angle(0, 0, 0) }
72}
73
74
75
76SWEP.Primary.ClipSize = -1
77SWEP.Primary.DefaultClip = -1
78SWEP.Primary.Automatic = false
79SWEP.Primary.Ammo = "none"
80
81SWEP.Secondary.ClipSize = -1
82SWEP.Secondary.DefaultClip = -1
83SWEP.Secondary.Automatic = false
84SWEP.Secondary.Ammo = "none"
85
86SWEP.PrintName = "Keys"
87SWEP.Slot = 1
88SWEP.SlotPos = 1
89SWEP.DrawAmmo = false
90SWEP.DrawCrosshair = false
91SWEP.Spawnable = true
92SWEP.AdminSpawnable = true
93SWEP.UseHands = true
94
95
96SWEP.IronSightsPos = Vector(-25.441, 0, -71.84)
97SWEP.IronSightsAng = Vector(0, 0, 0)
98
99if ( SERVER ) then
100
101 SWEP.Weight = 5
102 SWEP.AutoSwitchTo = false
103 SWEP.AutoSwitchFrom = false
104
105end
106
107SWEP.VElements = {
108 ["v_iphone"] = { type = "Model", model = "models/sentry/pgkey.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(8, 2.399, -1.3), angle = Angle(-23.524, 90, -90), size = Vector(.7, 0.8, 0.8), color = Color(255, 255, 0, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
109}
110
111SWEP.WElements = {
112 ["element_name"] = { type = "Model", model = "models/sentry/pgkey.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(8.899, 1.799, -1.601), angle = Angle(-90, 42, -129.887), size = Vector(0.5, 0.5, 0.5), color = Color(255, 255, 0, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
113}
114
115--[[---------------------------------------------------------
116 Initialize Stuff
117-----------------------------------------------------------]]
118function SWEP:Initialize()
119 self:SetWeaponHoldType(self.HoldType)
120
121
122 if CLIENT then
123
124 // Create a new table for every weapon instance
125 self.VElements = table.FullCopy( self.VElements )
126 self.WElements = table.FullCopy( self.WElements )
127
128 self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
129
130 self:CreateModels(self.VElements) // create viewmodels
131 self:CreateModels(self.WElements) // create worldmodels
132
133 // init view model bone build function
134 if IsValid(self.Owner) then
135 local vm = self.Owner:GetViewModel()
136 if IsValid(vm) then
137 self:ResetBonePositions(vm)
138
139 // Init viewmodel visibility
140 if (self.ShowViewModel == nil or self.ShowViewModel) then
141 vm:SetColor(Color(255,255,255,255))
142 else
143 // we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
144 vm:SetColor(Color(255,255,255,1))
145 // ^ stopped working in GMod 13 because you have to do Entity:SetRenderMode(1) for translucency to kick in
146 // 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
147 vm:SetMaterial("Debug/hsv")
148 end
149 end
150 end
151
152 end
153
154end
155
156--[[---------------------------------------------------------
157 Precache Stuff
158-----------------------------------------------------------]]
159function SWEP:Precache()
160
161end
162
163--[[---------------------------------------------------------
164 Reload does nothing
165-----------------------------------------------------------]]
166function SWEP:Reload()
167 local trace = self:GetOwner():GetEyeTrace()
168 if not IsValid(trace.Entity) or (IsValid(trace.Entity) and ((not trace.Entity:isDoor() and not trace.Entity:IsVehicle()) or self.Owner:EyePos():DistToSqr(trace.HitPos) > 40000)) then
169 if CLIENT then RunConsoleCommand("_DarkRP_AnimationMenu") end
170 return
171 end
172 if SERVER then
173 umsg.Start("KeysMenu", self:GetOwner())
174 umsg.End()
175 end
176end
177
178local function lookingAtLockable(ply, ent)
179 local eyepos = ply:EyePos()
180 return IsValid(ent) and
181 ent:isKeysOwnable() and
182 (
183 ent:isDoor() and eyepos:DistToSqr(ent:GetPos()) < 4225
184 or
185 ent:IsVehicle() and eyepos:DistToSqr(ent:NearestPoint(eyepos)) < 10000
186 )
187
188end
189
190local function lockUnlockAnimation(ply, snd)
191 ply:EmitSound("npc/metropolice/gear" .. math.floor(math.Rand(1,7)) .. ".wav")
192 timer.Simple(0.9, function() if IsValid(ply) then ply:EmitSound(snd) end end)
193
194 local RP = RecipientFilter()
195 RP:AddAllPlayers()
196
197 umsg.Start("anim_keys", RP)
198 umsg.Entity(ply)
199 umsg.String("usekeys")
200 umsg.End()
201
202end
203
204local function doKnock(ply, sound)
205 ply:EmitSound(sound, 100, math.random(90, 110))
206 umsg.Start("anim_keys")
207 umsg.Entity(ply)
208 umsg.String("knocking")
209 umsg.End()
210
211 ply:AnimRestartGesture(GESTURE_SLOT_ATTACK_AND_RELOAD, ACT_HL2MP_GESTURE_RANGE_ATTACK_FIST, true)
212end
213
214--[[---------------------------------------------------------
215 PrimaryAttack
216-----------------------------------------------------------]]
217function SWEP:PrimaryAttack()
218 if CLIENT then return end
219
220 local trace = self:GetOwner():GetEyeTrace()
221
222 if not lookingAtLockable(self:GetOwner(), trace.Entity) then return end
223
224 self:SetNextPrimaryFire(CurTime() + 0.3)
225
226 if CLIENT then return end
227
228 if self:GetOwner():canKeysLock(trace.Entity) then
229 trace.Entity:keysLock() -- Lock the door immediately so it won't annoy people
230 lockUnlockAnimation(self:GetOwner(), self.Sound)
231 elseif trace.Entity:IsVehicle() then
232 DarkRP.notify(self:GetOwner(), 1, 3, DarkRP.getPhrase("do_not_own_ent"))
233 else
234 doKnock(self:GetOwner(), "physics/wood/wood_crate_impact_hard2.wav")
235 end
236
237end
238
239--[[---------------------------------------------------------
240 SecondaryAttack
241-----------------------------------------------------------]]
242function SWEP:SecondaryAttack()
243 if CLIENT then return end
244
245 local trace = self:GetOwner():GetEyeTrace()
246
247 if not lookingAtLockable(self:GetOwner(), trace.Entity) then return end
248
249 self:SetNextSecondaryFire(CurTime() + 0.3)
250
251 if CLIENT then return end
252
253 if self:GetOwner():canKeysUnlock(trace.Entity) then
254 trace.Entity:keysUnLock() -- Unlock the door immediately so it won't annoy people
255 lockUnlockAnimation(self:GetOwner(), self.Sound)
256 elseif trace.Entity:IsVehicle() then
257 DarkRP.notify(self:GetOwner(), 1, 3, DarkRP.getPhrase("do_not_own_ent"))
258 else
259 doKnock(self:GetOwner(), "physics/wood/wood_crate_impact_hard3.wav")
260 end
261end
262
263--[[---------------------------------------------------------
264
265-----------------------------------------------------------]]
266
267function SWEP:GetViewModelPosition( pos, ang )
268 //self.Owner:Note(tostring(pos))
269 local Mul = 1.0
270 local Offset = self.IronSightsPos
271
272 self.IronSightsAng = self.IronSightsAng + Vector(0, 0, 0)
273
274 if (self.IronSightsAng) then
275 ang = ang * 1
276 ang:RotateAroundAxis(ang:Right(), self.IronSightsAng.x * Mul)
277 ang:RotateAroundAxis(ang:Up(), self.IronSightsAng.y * Mul)
278 ang:RotateAroundAxis(ang:Forward(), self.IronSightsAng.z * Mul)
279 end
280
281 local Right = ang:Right()
282 local Up = ang:Up()
283 local Forward = ang:Forward()
284
285 pos = pos + Offset.x * Right * Mul
286 pos = pos + Offset.y * Forward * Mul
287 pos = pos + Offset.z * Up * Mul
288
289 return pos, ang
290
291end
292
293function SWEP:Holster()
294
295 if CLIENT and IsValid(self.Owner) then
296 local vm = self.Owner:GetViewModel()
297 if IsValid(vm) then
298 self:ResetBonePositions(vm)
299 end
300 end
301
302 return true
303end
304
305function SWEP:OnRemove()
306 self:Holster()
307end
308
309if CLIENT then
310
311 SWEP.vRenderOrder = nil
312 function SWEP:ViewModelDrawn()
313
314 local vm = self.Owner:GetViewModel()
315 if !IsValid(vm) then return end
316
317 if (!self.VElements) then return end
318
319 self:UpdateBonePositions(vm)
320
321 if (!self.vRenderOrder) then
322
323 // we build a render order because sprites need to be drawn after models
324 self.vRenderOrder = {}
325
326 for k, v in pairs( self.VElements ) do
327 if (v.type == "Model") then
328 table.insert(self.vRenderOrder, 1, k)
329 elseif (v.type == "Sprite" or v.type == "Quad") then
330 table.insert(self.vRenderOrder, k)
331 end
332 end
333
334 end
335
336 for k, name in ipairs( self.vRenderOrder ) do
337
338 local v = self.VElements[name]
339 if (!v) then self.vRenderOrder = nil break end
340 if (v.hide) then continue end
341
342 local model = v.modelEnt
343 local sprite = v.spriteMaterial
344
345 if (!v.bone) then continue end
346
347 local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
348
349 if (!pos) then continue end
350
351 if (v.type == "Model" and IsValid(model)) then
352
353 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
354 ang:RotateAroundAxis(ang:Up(), v.angle.y)
355 ang:RotateAroundAxis(ang:Right(), v.angle.p)
356 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
357
358 model:SetAngles(ang)
359 //model:SetModelScale(v.size)
360 local matrix = Matrix()
361 matrix:Scale(v.size)
362 model:EnableMatrix( "RenderMultiply", matrix )
363
364 if (v.material == "") then
365 model:SetMaterial("")
366 elseif (model:GetMaterial() != v.material) then
367 model:SetMaterial( v.material )
368 end
369
370 if (v.skin and v.skin != model:GetSkin()) then
371 model:SetSkin(v.skin)
372 end
373
374 if (v.bodygroup) then
375 for k, v in pairs( v.bodygroup ) do
376 if (model:GetBodygroup(k) != v) then
377 model:SetBodygroup(k, v)
378 end
379 end
380 end
381
382 if (v.surpresslightning) then
383 render.SuppressEngineLighting(true)
384 end
385
386 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
387 render.SetBlend(v.color.a/255)
388 model:DrawModel()
389 render.SetBlend(1)
390 render.SetColorModulation(1, 1, 1)
391
392 if (v.surpresslightning) then
393 render.SuppressEngineLighting(false)
394 end
395
396 elseif (v.type == "Sprite" and sprite) then
397
398 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
399 render.SetMaterial(sprite)
400 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
401
402 elseif (v.type == "Quad" and v.draw_func) then
403
404 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
405 ang:RotateAroundAxis(ang:Up(), v.angle.y)
406 ang:RotateAroundAxis(ang:Right(), v.angle.p)
407 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
408
409 cam.Start3D2D(drawpos, ang, v.size)
410 v.draw_func( self )
411 cam.End3D2D()
412
413 end
414
415 end
416
417 end
418
419 SWEP.wRenderOrder = nil
420 function SWEP:DrawWorldModel()
421
422 if (self.ShowWorldModel == nil or self.ShowWorldModel) then
423 self:DrawModel()
424 end
425
426 if (!self.WElements) then return end
427
428 if (!self.wRenderOrder) then
429
430 self.wRenderOrder = {}
431
432 for k, v in pairs( self.WElements ) do
433 if (v.type == "Model") then
434 table.insert(self.wRenderOrder, 1, k)
435 elseif (v.type == "Sprite" or v.type == "Quad") then
436 table.insert(self.wRenderOrder, k)
437 end
438 end
439
440 end
441
442 if (IsValid(self.Owner)) then
443 bone_ent = self.Owner
444 else
445 // when the weapon is dropped
446 bone_ent = self
447 end
448
449 for k, name in pairs( self.wRenderOrder ) do
450
451 local v = self.WElements[name]
452 if (!v) then self.wRenderOrder = nil break end
453 if (v.hide) then continue end
454
455 local pos, ang
456
457 if (v.bone) then
458 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
459 else
460 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
461 end
462
463 if (!pos) then continue end
464
465 local model = v.modelEnt
466 local sprite = v.spriteMaterial
467
468 if (v.type == "Model" and IsValid(model)) then
469
470 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
471 ang:RotateAroundAxis(ang:Up(), v.angle.y)
472 ang:RotateAroundAxis(ang:Right(), v.angle.p)
473 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
474
475 model:SetAngles(ang)
476 //model:SetModelScale(v.size)
477 local matrix = Matrix()
478 matrix:Scale(v.size)
479 model:EnableMatrix( "RenderMultiply", matrix )
480
481 if (v.material == "") then
482 model:SetMaterial("")
483 elseif (model:GetMaterial() != v.material) then
484 model:SetMaterial( v.material )
485 end
486
487 if (v.skin and v.skin != model:GetSkin()) then
488 model:SetSkin(v.skin)
489 end
490
491 if (v.bodygroup) then
492 for k, v in pairs( v.bodygroup ) do
493 if (model:GetBodygroup(k) != v) then
494 model:SetBodygroup(k, v)
495 end
496 end
497 end
498
499 if (v.surpresslightning) then
500 render.SuppressEngineLighting(true)
501 end
502
503 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
504 render.SetBlend(v.color.a/255)
505 model:DrawModel()
506 render.SetBlend(1)
507 render.SetColorModulation(1, 1, 1)
508
509 if (v.surpresslightning) then
510 render.SuppressEngineLighting(false)
511 end
512
513 elseif (v.type == "Sprite" and sprite) then
514
515 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
516 render.SetMaterial(sprite)
517 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
518
519 elseif (v.type == "Quad" and v.draw_func) then
520
521 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
522 ang:RotateAroundAxis(ang:Up(), v.angle.y)
523 ang:RotateAroundAxis(ang:Right(), v.angle.p)
524 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
525
526 cam.Start3D2D(drawpos, ang, v.size)
527 v.draw_func( self )
528 cam.End3D2D()
529
530 end
531
532 end
533
534 end
535
536 function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
537
538 local bone, pos, ang
539 if (tab.rel and tab.rel != "") then
540
541 local v = basetab[tab.rel]
542
543 if (!v) then return end
544
545 // Technically, if there exists an element with the same name as a bone
546 // you can get in an infinite loop. Let's just hope nobody's that stupid.
547 pos, ang = self:GetBoneOrientation( basetab, v, ent )
548
549 if (!pos) then return end
550
551 pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
552 ang:RotateAroundAxis(ang:Up(), v.angle.y)
553 ang:RotateAroundAxis(ang:Right(), v.angle.p)
554 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
555
556 else
557
558 bone = ent:LookupBone(bone_override or tab.bone)
559
560 if (!bone) then return end
561
562 pos, ang = Vector(0,0,0), Angle(0,0,0)
563 local m = ent:GetBoneMatrix(bone)
564 if (m) then
565 pos, ang = m:GetTranslation(), m:GetAngles()
566 end
567
568 if (IsValid(self.Owner) and self.Owner:IsPlayer() and
569 ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
570 ang.r = -ang.r // Fixes mirrored models
571 end
572
573 end
574
575 return pos, ang
576 end
577
578 function SWEP:CreateModels( tab )
579
580 if (!tab) then return end
581
582 // Create the clientside models here because Garry says we can't do it in the render hook
583 for k, v in pairs( tab ) do
584 if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
585 string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
586
587 v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
588 if (IsValid(v.modelEnt)) then
589 v.modelEnt:SetPos(self:GetPos())
590 v.modelEnt:SetAngles(self:GetAngles())
591 v.modelEnt:SetParent(self)
592 v.modelEnt:SetNoDraw(true)
593 v.createdModel = v.model
594 else
595 v.modelEnt = nil
596 end
597
598 elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
599 and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
600
601 local name = v.sprite.."-"
602 local params = { ["$basetexture"] = v.sprite }
603 // make sure we create a unique name based on the selected options
604 local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
605 for i, j in pairs( tocheck ) do
606 if (v[j]) then
607 params["$"..j] = 1
608 name = name.."1"
609 else
610 name = name.."0"
611 end
612 end
613
614 v.createdSprite = v.sprite
615 v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
616
617 end
618 end
619
620 end
621
622 local allbones
623 local hasGarryFixedBoneScalingYet = false
624
625 function SWEP:UpdateBonePositions(vm)
626
627 if self.ViewModelBoneMods then
628
629 if (!vm:GetBoneCount()) then return end
630
631 // !! WORKAROUND !! //
632 // We need to check all model names :/
633 local loopthrough = self.ViewModelBoneMods
634 if (!hasGarryFixedBoneScalingYet) then
635 allbones = {}
636 for i=0, vm:GetBoneCount() do
637 local bonename = vm:GetBoneName(i)
638 if (self.ViewModelBoneMods[bonename]) then
639 allbones[bonename] = self.ViewModelBoneMods[bonename]
640 else
641 allbones[bonename] = {
642 scale = Vector(1,1,1),
643 pos = Vector(0,0,0),
644 angle = Angle(0,0,0)
645 }
646 end
647 end
648
649 loopthrough = allbones
650 end
651 // !! ----------- !! //
652
653 for k, v in pairs( loopthrough ) do
654 local bone = vm:LookupBone(k)
655 if (!bone) then continue end
656
657 // !! WORKAROUND !! //
658 local s = Vector(v.scale.x,v.scale.y,v.scale.z)
659 local p = Vector(v.pos.x,v.pos.y,v.pos.z)
660 local ms = Vector(1,1,1)
661 if (!hasGarryFixedBoneScalingYet) then
662 local cur = vm:GetBoneParent(bone)
663 while(cur >= 0) do
664 local pscale = loopthrough[vm:GetBoneName(cur)].scale
665 ms = ms * pscale
666 cur = vm:GetBoneParent(cur)
667 end
668 end
669
670 s = s * ms
671 // !! ----------- !! //
672
673 if vm:GetManipulateBoneScale(bone) != s then
674 vm:ManipulateBoneScale( bone, s )
675 end
676 if vm:GetManipulateBoneAngles(bone) != v.angle then
677 vm:ManipulateBoneAngles( bone, v.angle )
678 end
679 if vm:GetManipulateBonePosition(bone) != p then
680 vm:ManipulateBonePosition( bone, p )
681 end
682 end
683 else
684 self:ResetBonePositions(vm)
685 end
686
687 end
688
689 function SWEP:ResetBonePositions(vm)
690
691 if (!vm:GetBoneCount()) then return end
692 for i=0, vm:GetBoneCount() do
693 vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
694 vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
695 vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
696 end
697
698 end
699
700 /**************************
701 Global utility code
702 **************************/
703
704 // Fully copies the table, meaning all tables inside this table are copied too and so on (normal table.Copy copies only their reference).
705 // Does not copy entities of course, only copies their reference.
706 // WARNING: do not use on tables that contain themselves somewhere down the line or you'll get an infinite loop
707 function table.FullCopy( tab )
708
709 if (!tab) then return nil end
710
711 local res = {}
712 for k, v in pairs( tab ) do
713 if (type(v) == "table") then
714 res[k] = table.FullCopy(v) // recursion ho!
715 elseif (type(v) == "Vector") then
716 res[k] = Vector(v.x, v.y, v.z)
717 elseif (type(v) == "Angle") then
718 res[k] = Angle(v.p, v.y, v.r)
719 else
720 res[k] = v
721 end
722 end
723
724 return res
725
726 end
727
728end