· 9 years ago · Feb 01, 2017, 07:00 PM
1if ( SERVER ) then
2
3 AddCSLuaFile( "shared.lua" )
4
5end
6
7if ( CLIENT ) then
8
9 SWEP.PrintName = "E-11 Stealth"
10 SWEP.Author = "Doctor Jew"
11 SWEP.ViewModelFOV = 50
12 SWEP.Slot = 2
13 SWEP.SlotPos = 3
14 SWEP.WepSelectIcon = surface.GetTextureID("HUD/killicons/DC15S")
15
16 killicon.Add( "weapon_jew_dc19", "HUD/killicons/DC15S", Color( 255, 80, 0, 255 ) )
17
18SWEP.ViewModelBoneMods = {
19 ["v_e11_reference001"] = { scale = Vector(0.009, 0.009, 0.009), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) }
20}
21
22SWEP.VElements = {
23 ["dc15s"] = { type = "Model", model = "models/weapons/blaster.mdl", bone = "v_e11_reference001", rel = "", pos = Vector(-0.719, 6.392, -3.484), angle = Angle(0, -90, 0), size = Vector(1, 1, 1), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
24}
25
26SWEP.WElements = {
27 ["dc15_s"] = { type = "Model", model = "models/weapons/blaster.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(10.159, 1.044, 0.764), angle = Angle(-16, 1.636, 180), size = Vector(1, 1, 1), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
28}
29
30end
31
32SWEP.HoldType = "ar2"
33SWEP.Base = "weapon_jew_base"
34
35SWEP.Category = "Star Wars - Assault Rifles"
36
37SWEP.Spawnable = true
38SWEP.AdminSpawnable = true
39
40--SWEP.ViewModel = "models/weapons/synbf3/c_t21.mdl"
41SWEP.ViewModel = "models/weapons/synbf3/c_e11.mdl"
42SWEP.WorldModel = "models/weapons/synbf3/w_a280.mdl"
43
44SWEP.ViewModelFOV = 47
45SWEP.ViewModelFlip = false
46SWEP.UseHands = true
47
48SWEP.Weight = 10
49SWEP.AutoSwitchTo = false
50SWEP.AutoSwitchFrom = false
51
52local FireSound = Sound ("weapons/DC15S_fire.wav");
53local ReloadSound = Sound ("weapons/synbf3/e11_reload.wav")
54local EmptySound = Sound ("weapons/sw_noammo.wav")
55local FireModeSound = Sound ("weapons/sw_detonator/sw_detonator_select.wav")
56
57SWEP.Primary.Recoil = 0.5
58SWEP.Primary.Damage = 30
59SWEP.Primary.NumShots = 1
60SWEP.Primary.Cone = 0.0125
61SWEP.Primary.ClipSize = 50
62SWEP.Primary.Delay = 0.2
63SWEP.Primary.DefaultClip = 150
64SWEP.Primary.Automatic = true
65SWEP.Primary.Ammo = "ar2"
66SWEP.Primary.Tracer = "effect_sw_laser_red"
67
68SWEP.Secondary.Automatic = true
69SWEP.Secondary.Ammo = "none"
70
71SWEP.IronSightsPos = Vector(-2.655, -9.554, 3.038)
72SWEP.IronSightsAng = Vector(0.787, 0.035, 0)
73
74// Custom values for fire switching
75SWEP.SelectiveFire = true
76SWEP.NextFireSelect = CurTime()
77SWEP.SMode = 1
78
79function SWEP:Precache()
80 util.PrecacheSound("weapons/DC15S_fire.wav")
81 util.PrecacheSound("weapons/synbf3/e11_reload.wav")
82 util.PrecacheSound("weapons/sw_noammo.wav")
83 util.PrecacheSound("weapons/sw_detonator/sw_detonator_select.wav")
84end
85
86function SWEP:Think()
87 if self.SelectiveFire and self.NextFireSelect < CurTime() then
88 if self.Owner:KeyDown(IN_SPEED) and self.Owner:KeyDown(IN_USE) then
89 self:SelectFireMode()
90 elseif self.Owner:KeyDown(IN_WALK) then
91 self:PrintMode()
92 end
93 end
94end
95
96local FireModeMessage = {"Stealth mode selected.","Stun mode selected.","Vaporize mode selected.","Normal mode selected."}
97function SWEP:SelectFireMode()
98 if CLIENT then
99 self.Owner:PrintMessage(HUD_PRINTTALK,FireModeMessage[self.SMode])
100 --self.Owner:PrintMessage(HUD_PRINTTALK,"OLD MODE: " .. self.SMode)
101 end
102 self.NextFireSelect = CurTime() + 3
103 self.Weapon:EmitSound(FireModeSound)
104 self.SMode = math.fmod((self.SMode + 1), 5)
105 if self.SMode < 1 then
106 self.SMode = 1
107 end
108 --if CLIENT then
109 -- self.Owner:PrintMessage(HUD_PRINTTALK,"NEW MODE: " .. self.SMode)
110 --end
111end
112
113local PrintModeMessage = {"Normal mode selected.","Stealth mode selected.","Stun mode selected.","Vaporize mode selected."}
114function SWEP:PrintMode()
115 if CLIENT then
116 self.Owner:PrintMessage(HUD_PRINTTALK,PrintModeMessage[self.SMode])
117 --self.Owner:PrintMessage(HUD_PRINTTALK,self.SMode)
118 self.NextFireSelect = CurTime() + 1.5
119 end
120end
121
122function SWEP:PrimaryAttack()
123 if self.SMode == 1 then
124 self:NormalFire()
125 elseif self.SMode == 2 then
126 self:StealthFire()
127 elseif self.SMode == 3 then
128 self:Stun()
129 elseif self.SMode == 4 then
130 self:Vaporize()
131 end
132end
133
134function SWEP:NormalFire()
135 self.Primary.Recoil = 0.01
136 self.Primary.Damage = 18.75
137 self.Primary.NumShots = 1
138 self.Primary.Cone = 0.0125
139 self.Primary.ClipSize = 50
140 self.Primary.Delay = 0.18
141 self.Primary.DefaultClip = 50
142 self.Primary.Automatic = true
143 self.Primary.Ammo = "ar2"
144 self.Primary.Tracer = "effect_sw_laser_blue"
145
146 self.Weapon:SetNextSecondaryFire( CurTime() + self.Primary.Delay )
147 self.Weapon:SetNextPrimaryFire( CurTime() + self.Primary.Delay )
148
149 if ( !self:CanPrimaryAttack() ) then return end
150
151 if self:Clip1() < 1 then
152 self.Weapon:EmitSound( EmptyAmmo )
153 return
154 end
155
156 self.Weapon:EmitSound( FireSound )
157
158 self:CSShootBullet( self.Primary.Damage, self.Primary.Recoil, self.Primary.NumShots, self.Primary.Cone )
159
160 self:TakePrimaryAmmo( 1 )
161
162 if ( self.Owner:IsNPC() ) then return end
163
164 self.Owner:ViewPunch( Angle( math.Rand(-0.2,-0.1) * self.Primary.Recoil, math.Rand(-0.1,0.1) *self.Primary.Recoil, 0 ) )
165
166 // In singleplayer this function doesn't get called on the client, so we use a networked float
167 // to send the last shoot time. In multiplayer this is predicted clientside so we don't need to
168 // send the float.
169 if ( (game.SinglePlayer() && SERVER) || CLIENT ) then
170 self.Weapon:SetNetworkedFloat( "LastShootTime", CurTime() )
171 end
172end
173
174function SWEP:CSShootBullet( dmg, recoil, numbul, cone )
175
176 numbul = numbul or 1
177 cone = cone or 0.01
178
179 local bullet = {}
180 bullet.Num = numbul
181 bullet.Src = self.Owner:GetShootPos() // Source
182 bullet.Dir = self.Owner:GetAimVector() // Dir of bullet
183 bullet.Spread = Vector( cone, cone, 0 ) // Aim Cone
184 bullet.Tracer = 1 // Show a tracer on every x bullets
185 bullet.TracerName = self.Primary.Tracer
186 bullet.Force = 5 // Amount of force to give to phys objects
187 bullet.Damage = dmg
188
189 self.Owner:FireBullets( bullet )
190 self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK ) // View model animation
191 self.Owner:MuzzleFlash() // Crappy muzzle light
192 self.Owner:SetAnimation( PLAYER_ATTACK1 ) // 3rd Person Animation
193
194 if ( self.Owner:IsNPC() ) then return end
195
196 // CUSTOM RECOIL !
197 if ( (game.SinglePlayer() && SERVER) || ( !game.SinglePlayer() && CLIENT && IsFirstTimePredicted() ) ) then
198
199 local eyeang = self.Owner:EyeAngles()
200 eyeang.pitch = eyeang.pitch - recoil
201 self.Owner:SetEyeAngles( eyeang )
202 end
203end
204
205function SWEP:Reload()
206 if self.SMode == 1 or self.SMode == 2 or self.SMode == 3 or self.SMode == 4 then
207 if (self.Weapon:Clip1() < self.Primary.ClipSize) then
208 if self.Owner:GetAmmoCount(self.Primary.Ammo) > 0 then
209 self.Weapon:EmitSound( ReloadSound )
210 end
211 self.Weapon:DefaultReload( ACT_VM_RELOAD );
212 self:SetIronsights( false )
213 end
214 end
215end
216
217/********************************************************
218 SWEP Construction Kit base code
219 Created by Clavus
220 Available for public use, thread at:
221 facepunch.com/threads/1032378
222
223
224 DESCRIPTION:
225 This script is meant for experienced scripters
226 that KNOW WHAT THEY ARE DOING. Don't come to me
227 with basic Lua questions.
228
229 Just copy into your SWEP or SWEP base of choice
230 and merge with your own code.
231
232 The SWEP.VElements, SWEP.WElements and
233 SWEP.ViewModelBoneMods tables are all optional
234 and only have to be visible to the client.
235********************************************************/
236
237function SWEP:Initialize()
238
239 self:SetWeaponHoldType( self.HoldType )
240
241 if CLIENT then
242
243 // Create a new table for every weapon instance
244 self.VElements = table.FullCopy( self.VElements )
245 self.WElements = table.FullCopy( self.WElements )
246 self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
247
248 self:CreateModels(self.VElements) // create viewmodels
249 self:CreateModels(self.WElements) // create worldmodels
250
251 // init view model bone build function
252 if IsValid(self.Owner) then
253 local vm = self.Owner:GetViewModel()
254 if IsValid(vm) then
255 self:ResetBonePositions(vm)
256
257 // Init viewmodel visibility
258 if (self.ShowViewModel == nil or self.ShowViewModel) then
259 vm:SetColor(Color(255,255,255,255))
260 else
261 // we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
262 vm:SetColor(Color(255,255,255,1))
263 // ^ stopped working in GMod 13 because you have to do Entity:SetRenderMode(1) for translucency to kick in
264 // 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
265 vm:SetMaterial("Debug/hsv")
266 end
267 end
268 end
269
270 end
271
272end
273
274function SWEP:Holster()
275
276 if CLIENT and IsValid(self.Owner) then
277 local vm = self.Owner:GetViewModel()
278 if IsValid(vm) then
279 self:ResetBonePositions(vm)
280 end
281 end
282
283 return true
284end
285
286function SWEP:OnRemove()
287 self:Holster()
288end
289
290if CLIENT then
291
292 SWEP.vRenderOrder = nil
293 function SWEP:ViewModelDrawn()
294
295 local vm = self.Owner:GetViewModel()
296 if !IsValid(vm) then return end
297
298 if (!self.VElements) then return end
299
300 self:UpdateBonePositions(vm)
301
302 if (!self.vRenderOrder) then
303
304 // we build a render order because sprites need to be drawn after models
305 self.vRenderOrder = {}
306
307 for k, v in pairs( self.VElements ) do
308 if (v.type == "Model") then
309 table.insert(self.vRenderOrder, 1, k)
310 elseif (v.type == "Sprite" or v.type == "Quad") then
311 table.insert(self.vRenderOrder, k)
312 end
313 end
314
315 end
316
317 for k, name in ipairs( self.vRenderOrder ) do
318
319 local v = self.VElements[name]
320 if (!v) then self.vRenderOrder = nil break end
321 if (v.hide) then continue end
322
323 local model = v.modelEnt
324 local sprite = v.spriteMaterial
325
326 if (!v.bone) then continue end
327
328 local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
329
330 if (!pos) then continue end
331
332 if (v.type == "Model" and IsValid(model)) then
333
334 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
335 ang:RotateAroundAxis(ang:Up(), v.angle.y)
336 ang:RotateAroundAxis(ang:Right(), v.angle.p)
337 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
338
339 model:SetAngles(ang)
340 //model:SetModelScale(v.size)
341 local matrix = Matrix()
342 matrix:Scale(v.size)
343 model:EnableMatrix( "RenderMultiply", matrix )
344
345 if (v.material == "") then
346 model:SetMaterial("")
347 elseif (model:GetMaterial() != v.material) then
348 model:SetMaterial( v.material )
349 end
350
351 if (v.skin and v.skin != model:GetSkin()) then
352 model:SetSkin(v.skin)
353 end
354
355 if (v.bodygroup) then
356 for k, v in pairs( v.bodygroup ) do
357 if (model:GetBodygroup(k) != v) then
358 model:SetBodygroup(k, v)
359 end
360 end
361 end
362
363 if (v.surpresslightning) then
364 render.SuppressEngineLighting(true)
365 end
366
367 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
368 render.SetBlend(v.color.a/255)
369 model:DrawModel()
370 render.SetBlend(1)
371 render.SetColorModulation(1, 1, 1)
372
373 if (v.surpresslightning) then
374 render.SuppressEngineLighting(false)
375 end
376
377 elseif (v.type == "Sprite" and sprite) then
378
379 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
380 render.SetMaterial(sprite)
381 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
382
383 elseif (v.type == "Quad" and v.draw_func) then
384
385 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
386 ang:RotateAroundAxis(ang:Up(), v.angle.y)
387 ang:RotateAroundAxis(ang:Right(), v.angle.p)
388 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
389
390 cam.Start3D2D(drawpos, ang, v.size)
391 v.draw_func( self )
392 cam.End3D2D()
393
394 end
395
396 end
397
398 end
399
400 SWEP.wRenderOrder = nil
401 function SWEP:DrawWorldModel()
402
403 if (self.ShowWorldModel == nil or self.ShowWorldModel) then
404 self:DrawModel()
405 end
406
407 if (!self.WElements) then return end
408
409 if (!self.wRenderOrder) then
410
411 self.wRenderOrder = {}
412
413 for k, v in pairs( self.WElements ) do
414 if (v.type == "Model") then
415 table.insert(self.wRenderOrder, 1, k)
416 elseif (v.type == "Sprite" or v.type == "Quad") then
417 table.insert(self.wRenderOrder, k)
418 end
419 end
420
421 end
422
423 if (IsValid(self.Owner)) then
424 bone_ent = self.Owner
425 else
426 // when the weapon is dropped
427 bone_ent = self
428 end
429
430 for k, name in pairs( self.wRenderOrder ) do
431
432 local v = self.WElements[name]
433 if (!v) then self.wRenderOrder = nil break end
434 if (v.hide) then continue end
435
436 local pos, ang
437
438 if (v.bone) then
439 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
440 else
441 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
442 end
443
444 if (!pos) then continue end
445
446 local model = v.modelEnt
447 local sprite = v.spriteMaterial
448
449 if (v.type == "Model" and IsValid(model)) then
450
451 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
452 ang:RotateAroundAxis(ang:Up(), v.angle.y)
453 ang:RotateAroundAxis(ang:Right(), v.angle.p)
454 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
455
456 model:SetAngles(ang)
457 //model:SetModelScale(v.size)
458 local matrix = Matrix()
459 matrix:Scale(v.size)
460 model:EnableMatrix( "RenderMultiply", matrix )
461
462 if (v.material == "") then
463 model:SetMaterial("")
464 elseif (model:GetMaterial() != v.material) then
465 model:SetMaterial( v.material )
466 end
467
468 if (v.skin and v.skin != model:GetSkin()) then
469 model:SetSkin(v.skin)
470 end
471
472 if (v.bodygroup) then
473 for k, v in pairs( v.bodygroup ) do
474 if (model:GetBodygroup(k) != v) then
475 model:SetBodygroup(k, v)
476 end
477 end
478 end
479
480 if (v.surpresslightning) then
481 render.SuppressEngineLighting(true)
482 end
483
484 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
485 render.SetBlend(v.color.a/255)
486 model:DrawModel()
487 render.SetBlend(1)
488 render.SetColorModulation(1, 1, 1)
489
490 if (v.surpresslightning) then
491 render.SuppressEngineLighting(false)
492 end
493
494 elseif (v.type == "Sprite" and sprite) then
495
496 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
497 render.SetMaterial(sprite)
498 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
499
500 elseif (v.type == "Quad" and v.draw_func) then
501
502 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
503 ang:RotateAroundAxis(ang:Up(), v.angle.y)
504 ang:RotateAroundAxis(ang:Right(), v.angle.p)
505 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
506
507 cam.Start3D2D(drawpos, ang, v.size)
508 v.draw_func( self )
509 cam.End3D2D()
510
511 end
512
513 end
514
515 end
516
517 function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
518
519 local bone, pos, ang
520 if (tab.rel and tab.rel != "") then
521
522 local v = basetab[tab.rel]
523
524 if (!v) then return end
525
526 // Technically, if there exists an element with the same name as a bone
527 // you can get in an infinite loop. Let's just hope nobody's that stupid.
528 pos, ang = self:GetBoneOrientation( basetab, v, ent )
529
530 if (!pos) then return end
531
532 pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
533 ang:RotateAroundAxis(ang:Up(), v.angle.y)
534 ang:RotateAroundAxis(ang:Right(), v.angle.p)
535 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
536
537 else
538
539 bone = ent:LookupBone(bone_override or tab.bone)
540
541 if (!bone) then return end
542
543 pos, ang = Vector(0,0,0), Angle(0,0,0)
544 local m = ent:GetBoneMatrix(bone)
545 if (m) then
546 pos, ang = m:GetTranslation(), m:GetAngles()
547 end
548
549 if (IsValid(self.Owner) and self.Owner:IsPlayer() and
550 ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
551 ang.r = -ang.r // Fixes mirrored models
552 end
553
554 end
555
556 return pos, ang
557 end
558
559 function SWEP:CreateModels( tab )
560
561 if (!tab) then return end
562
563 // Create the clientside models here because Garry says we can't do it in the render hook
564 for k, v in pairs( tab ) do
565 if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
566 string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
567
568 v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
569 if (IsValid(v.modelEnt)) then
570 v.modelEnt:SetPos(self:GetPos())
571 v.modelEnt:SetAngles(self:GetAngles())
572 v.modelEnt:SetParent(self)
573 v.modelEnt:SetNoDraw(true)
574 v.createdModel = v.model
575 else
576 v.modelEnt = nil
577 end
578
579 elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
580 and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
581
582 local name = v.sprite.."-"
583 local params = { ["$basetexture"] = v.sprite }
584 // make sure we create a unique name based on the selected options
585 local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
586 for i, j in pairs( tocheck ) do
587 if (v[j]) then
588 params["$"..j] = 1
589 name = name.."1"
590 else
591 name = name.."0"
592 end
593 end
594
595 v.createdSprite = v.sprite
596 v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
597
598 end
599 end
600
601 end
602
603 local allbones
604 local hasGarryFixedBoneScalingYet = false
605
606 function SWEP:UpdateBonePositions(vm)
607
608 if self.ViewModelBoneMods then
609
610 if (!vm:GetBoneCount()) then return end
611
612 // !! WORKAROUND !! //
613 // We need to check all model names :/
614 local loopthrough = self.ViewModelBoneMods
615 if (!hasGarryFixedBoneScalingYet) then
616 allbones = {}
617 for i=0, vm:GetBoneCount() do
618 local bonename = vm:GetBoneName(i)
619 if (self.ViewModelBoneMods[bonename]) then
620 allbones[bonename] = self.ViewModelBoneMods[bonename]
621 else
622 allbones[bonename] = {
623 scale = Vector(1,1,1),
624 pos = Vector(0,0,0),
625 angle = Angle(0,0,0)
626 }
627 end
628 end
629
630 loopthrough = allbones
631 end
632 // !! ----------- !! //
633
634 for k, v in pairs( loopthrough ) do
635 local bone = vm:LookupBone(k)
636 if (!bone) then continue end
637
638 // !! WORKAROUND !! //
639 local s = Vector(v.scale.x,v.scale.y,v.scale.z)
640 local p = Vector(v.pos.x,v.pos.y,v.pos.z)
641 local ms = Vector(1,1,1)
642 if (!hasGarryFixedBoneScalingYet) then
643 local cur = vm:GetBoneParent(bone)
644 while(cur >= 0) do
645 local pscale = loopthrough[vm:GetBoneName(cur)].scale
646 ms = ms * pscale
647 cur = vm:GetBoneParent(cur)
648 end
649 end
650
651 s = s * ms
652 // !! ----------- !! //
653
654 if vm:GetManipulateBoneScale(bone) != s then
655 vm:ManipulateBoneScale( bone, s )
656 end
657 if vm:GetManipulateBoneAngles(bone) != v.angle then
658 vm:ManipulateBoneAngles( bone, v.angle )
659 end
660 if vm:GetManipulateBonePosition(bone) != p then
661 vm:ManipulateBonePosition( bone, p )
662 end
663 end
664 else
665 self:ResetBonePositions(vm)
666 end
667
668 end
669
670 function SWEP:ResetBonePositions(vm)
671
672 if (!vm:GetBoneCount()) then return end
673 for i=0, vm:GetBoneCount() do
674 vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
675 vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
676 vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
677 end
678
679 end
680
681 /**************************
682 Global utility code
683 **************************/
684
685 // Fully copies the table, meaning all tables inside this table are copied too and so on (normal table.Copy copies only their reference).
686 // Does not copy entities of course, only copies their reference.
687 // WARNING: do not use on tables that contain themselves somewhere down the line or you'll get an infinite loop
688 function table.FullCopy( tab )
689
690 if (!tab) then return nil end
691
692 local res = {}
693 for k, v in pairs( tab ) do
694 if (type(v) == "table") then
695 res[k] = table.FullCopy(v) // recursion ho!
696 elseif (type(v) == "Vector") then
697 res[k] = Vector(v.x, v.y, v.z)
698 elseif (type(v) == "Angle") then
699 res[k] = Angle(v.p, v.y, v.r)
700 else
701 res[k] = v
702 end
703 end
704
705 return res
706
707 end
708
709end