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