· 10 years ago · Aug 31, 2016, 02:38 PM
1--[[
2 U97 Nautilus (C)Alex5511
3]]--
4// self.Owner:ConCommand("strider")
5// General Settings & Options \\
6if SERVER then
7 AddCSLuaFile("shared.lua");
8end
9
10
11
12SWEP.ShowViewModel = true
13SWEP.ShowWorldModel = false
14SWEP.ViewModelBoneMods = {
15 ["ValveBiped.Bip01"] = { scale = Vector(0.009, 0.009, 0.009), pos = Vector(-1.905, 1.587, -0.953), angle = Angle(0, 0, 0) }
16}
17
18SWEP.Weight = 10
19
20SWEP.AutoSwitchTo = false
21
22SWEP.Slot = 2
23
24SWEP.AutoSwitchFrom = false
25
26SWEP.FiresUnderwater = true
27
28
29
30
31SWEP.base = "weapon_base"
32
33SWEP.BounceWeaponIcon = false
34
35
36if ( CLIENT ) then
37
38SWEP.PrintName = "Nautilus Death Wand" // The name of the Swep
39SWEP.Author = "Alex5511" // Authors name
40SWEP.Instructions = "Left click to fire a very powerfull beam!" // How do people use your swep?
41SWEP.Contact = "Bluevortexdev@gmail.com" // How people chould contact you if they were to find bugs, errors, etc~
42SWEP.Purpose = "The purpose is to Destroy." // What is the purpose with this Swep?
43
44SWEP.Category = "Other"
45
46SWEP.Slot = 2 // Deside wich slot you want your swep do be in 1 2 3 4 5 6
47
48SWEP.SlotPos = 0
49
50SWEP.DrawAmmo = false
51
52SWEP.DrawCrosshair = true
53
54end
55
56SWEP.Spawnable = true
57SWEP.AdminOnly = true
58
59SWEP.ViewModel = "models/weapons/v_crowbar.mdl"
60SWEP.WorldModel = "models/weapons/w_stunbaton.mdl"
61
62function SWEP:SecondaryAttack()
63end
64
65
66// PrimaryFire Settings \\
67SWEP.Primary.Sound = "/npc/strider/fire.wav" // The sound played upon firing
68SWEP.Primary.Damage = 999 // Total damage the Primaryfire funcion deals
69SWEP.Primary.TakeAmmo = 0 // How much ammo does it take for each shot?
70SWEP.Primary.ClipSize = 1 // The clipsize
71SWEP.Primary.Ammo = "none" // Ammo type? (pistol / smg1)
72SWEP.Primary.DefaultClip = 1 // The amount of ammo the Swep has upon Spawning
73SWEP.Primary.Spread = 0.1 // Does the bullets spread all over, if you want it fire exactly where you are aiming leave it o.1
74SWEP.Primary.NumberofShots = 100 // The amount of bullets fired per shot
75SWEP.Primary.Automatic = false // Is the swep automatic?
76SWEP.Primary.Recoil = 0 // How much we should punch the view
77SWEP.Primary.Force = 100 // The force of the shot
78// PrimaryFire settings \\
79function SWEP:throw_attack (model_file)
80 local tr = self.Owner:GetEyeTrace();
81 self.Weapon:EmitSound (self.Secondary.Sound);
82 self.BaseClass.ShootEffects (self);
83 if (!SERVER) then return end;
84 local ent = ents.Create ("prop_physics");
85 ent:SetModel (model_file);
86 ent:SetPos (self.Owner:EyePos() + (self.Owner:GetAimVector() * 16));
87 ent:SetAngles (self.Owner:EyeAngles());
88 ent:Spawn();
89 local phys = ent:GetPhysicsObject();
90 local shot_length = tr.HitPos:Length();
91 phys:ApplyForceCenter (self.Owner:GetAimVector():GetNormalized() * math.pow (shot_length, 3));
92 cleanup.Add (self.Owner, "props", ent);
93 undo.Create ("Thrown model");
94 undo.AddEntity (ent);
95 undo.SetPlayer (self.Owner);
96 undo.Finish();
97end
98
99
100
101//SWEP:PrimaryFire()\\
102function SWEP:PrimaryAttack()
103 if ( !self:CanPrimaryAttack() ) then return end
104 self.Weapon:SendWeaponAnim(ACT_VM_PRIMARYATTACK);
105 self:ShootEffects()
106 self.Weapon:EmitSound(Sound(self.Primary.Sound))
107 self.Owner:ViewPunch( Angle( rnda,rndb,rnda ) )
108 self:TakePrimaryAmmo(self.Primary.TakeAmmo)
109 self.Weapon:SetNextPrimaryFire( CurTime() + 1.0 )
110 self.Weapon:SetNextSecondaryFire( CurTime() + 1.0 )
111 local eyetrace = self.Owner:GetEyeTrace()
112 local trace = self.Owner:GetEyeTrace()
113 local effectdata3 = EffectData() effectdata3:SetOrigin( trace.HitPos ) effectdata3:SetNormal( trace.HitNormal ) effectdata3:SetEntity( trace.Entity ) effectdata3:SetAttachment( trace.PhysicsBone ) util.Effect( "WandHit", effectdata3 )
114 local effectdata = EffectData() effectdata:SetOrigin( trace.HitPos ) effectdata:SetStart( self.Owner:GetShootPos() ) effectdata:SetAttachment( 1 ) effectdata:GetMagnitude() effectdata:SetEntity( self.Weapon ) util.Effect( "WandSP", effectdata )
115 local effectdata = EffectData() effectdata:SetOrigin( trace.HitPos ) effectdata:SetStart( self.Owner:GetShootPos() ) effectdata:SetAttachment( 1 ) effectdata:GetMagnitude() effectdata:SetEntity( self.Weapon ) util.Effect( "WandLaser", effectdata )
116 if(SERVER) then
117 local damage = ents.Create ( "point_hurt" )
118 damage:SetKeyValue ( "DamageRadius", 100 )
119 damage:SetKeyValue ( "Damage" , 100000 )
120 damage:SetKeyValue ( "DamageDelay", 0 )
121 damage:SetKeyValue ( "DamageType" ,"67108864" )
122 damage:SetPos ( trace.HitPos )
123 damage:Fire ( "TurnOn" , "", 0 )
124 damage:Fire ( "TurnOff" , "", 0.5 )
125 damage:Fire ( "kill","", 0.5 )
126 end
127
128end
129SWEP.ViewModelBoneMods = {
130 ["ValveBiped.Bip01"] = { scale = Vector(0.009,0.009,0.009), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) }
131}
132
133function SWEP:Deploy()
134if (IsValid(self.Weapon)) then
135 self.Weapon:SendWeaponAnim(ACT_VM_DRAW); -- Animation
136 end
137end
138//view model
139SWEP.VElements = {
140 ["element_names"] = { type = "Model", model = "models/Gibs/HGIBS_spine.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(4.091, -3.182, -7.728), angle = Angle(-25.569, 88.976, 15.34), size = Vector(1.003, 1.003, 1.401), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} },
141 ["effect"] = { type = "Model", model = "models/Gibs/HGIBS.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(3.181, -0.655, -15), angle = Angle(17.385, 1.023, -180), size = Vector(0.947, 0.947, 0.947), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
142}
143//world model
144SWEP.WElements = {
145 ["eye2+"] = { type = "Sprite", sprite = "sprites/grav_flare", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(8, 2.7, -12.174), size = { x = 2.99, y = 2.99 }, color = Color(0, 160, 255, 255), nocull = true, additive = true, vertexalpha = true, vertexcolor = true, ignorez = false},
146 ["element_name"] = { type = "Model", model = "models/Gibs/HGIBS.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(5.908, 0.455, -12.273), angle = Angle(21.476, -21.477, -180), size = Vector(1.003, 1.003, 1.003), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} },
147 ["eye2"] = { type = "Sprite", sprite = "sprites/grav_flare", bone = "ValveBiped.Bip01_R_Hand", rel = "eye1", pos = Vector(0, 0, 0), size = { x = 2.99, y = 2.99 }, color = Color(0, 160, 255, 255), nocull = true, additive = true, vertexalpha = true, vertexcolor = true, ignorez = false},
148 ["eye1"] = { type = "Model", model = "models/hunter/misc/sphere025x025.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(9, -0, -12), angle = Angle(0, 0, 0), size = Vector(0.009, 0.009, 0.009), color = Color(0, 0, 0, 0), surpresslightning = false, material = "models/shiny", skin = 0, bodygroup = {} },
149 ["gun"] = { type = "Model", model = "models/Gibs/HGIBS_spine.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(4.5, 0.455, -7.728), angle = Angle(13.295, 17.385, -7.159), size = Vector(0.833, 0.833, 1.401), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
150}
151
152function SWEP:Initialize()
153 self:SetWeaponHoldType( "melee" )
154 // other initialize code goes here
155
156 if CLIENT then
157
158 // Create a new table for every weapon instance
159 self.VElements = table.FullCopy( self.VElements )
160 self.WElements = table.FullCopy( self.WElements )
161 self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
162
163 self:CreateModels(self.VElements) // create viewmodels
164 self:CreateModels(self.WElements) // create worldmodels
165
166 // init view model bone build function
167 if IsValid(self.Owner) then
168 local vm = self.Owner:GetViewModel()
169 if IsValid(vm) then
170 self:ResetBonePositions(vm)
171
172 // Init viewmodel visibility
173 if (self.ShowViewModel == nil or self.ShowViewModel) then
174 vm:SetColor(Color(255,255,255,255))
175 else
176 // we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
177 vm:SetColor(Color(255,255,255,1))
178 // ^ stopped working in GMod 13 because you have to do Entity:SetRenderMode(1) for translucency to kick in
179 // 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
180 vm:SetMaterial("Debug/hsv")
181 end
182 end
183 end
184
185 end
186
187end
188
189function SWEP:Holster()
190 if CLIENT and IsValid(self.Owner) then
191 local vm = self.Owner:GetViewModel()
192 if IsValid(vm) then
193 self:ResetBonePositions(vm)
194 end
195 end
196
197 return true
198end
199
200function SWEP:OnRemove()
201 self:Holster()
202end
203
204if CLIENT then
205
206 SWEP.vRenderOrder = nil
207 function SWEP:ViewModelDrawn()
208
209 local vm = self.Owner:GetViewModel()
210 if !IsValid(vm) then return end
211
212 if (!self.VElements) then return end
213
214 self:UpdateBonePositions(vm)
215
216 if (!self.vRenderOrder) then
217
218 // we build a render order because sprites need to be drawn after models
219 self.vRenderOrder = {}
220
221 for k, v in pairs( self.VElements ) do
222 if (v.type == "Model") then
223 table.insert(self.vRenderOrder, 1, k)
224 elseif (v.type == "Sprite" or v.type == "Quad") then
225 table.insert(self.vRenderOrder, k)
226 end
227 end
228
229 end
230
231 for k, name in ipairs( self.vRenderOrder ) do
232
233 local v = self.VElements[name]
234 if (!v) then self.vRenderOrder = nil break end
235 if (v.hide) then continue end
236
237 local model = v.modelEnt
238 local sprite = v.spriteMaterial
239
240 if (!v.bone) then continue end
241
242 local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
243
244 if (!pos) then continue end
245
246 if (v.type == "Model" and IsValid(model)) then
247
248 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
249 ang:RotateAroundAxis(ang:Up(), v.angle.y)
250 ang:RotateAroundAxis(ang:Right(), v.angle.p)
251 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
252
253 model:SetAngles(ang)
254 //model:SetModelScale(v.size)
255 local matrix = Matrix()
256 matrix:Scale(v.size)
257 model:EnableMatrix( "RenderMultiply", matrix )
258
259 if (v.material == "") then
260 model:SetMaterial("")
261 elseif (model:GetMaterial() != v.material) then
262 model:SetMaterial( v.material )
263 end
264
265 if (v.skin and v.skin != model:GetSkin()) then
266 model:SetSkin(v.skin)
267 end
268
269 if (v.bodygroup) then
270 for k, v in pairs( v.bodygroup ) do
271 if (model:GetBodygroup(k) != v) then
272 model:SetBodygroup(k, v)
273 end
274 end
275 end
276
277 if (v.surpresslightning) then
278 render.SuppressEngineLighting(true)
279 end
280
281 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
282 render.SetBlend(v.color.a/255)
283 model:DrawModel()
284 render.SetBlend(1)
285 render.SetColorModulation(1, 1, 1)
286
287 if (v.surpresslightning) then
288 render.SuppressEngineLighting(false)
289 end
290
291 elseif (v.type == "Sprite" and sprite) then
292
293 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
294 render.SetMaterial(sprite)
295 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
296
297 elseif (v.type == "Quad" and v.draw_func) then
298
299 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
300 ang:RotateAroundAxis(ang:Up(), v.angle.y)
301 ang:RotateAroundAxis(ang:Right(), v.angle.p)
302 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
303
304 cam.Start3D2D(drawpos, ang, v.size)
305 v.draw_func( self )
306 cam.End3D2D()
307
308 end
309
310 end
311
312 end
313
314 SWEP.wRenderOrder = nil
315 function SWEP:DrawWorldModel()
316
317 if (self.ShowWorldModel == nil or self.ShowWorldModel) then
318 self:DrawModel()
319 end
320
321 if (!self.WElements) then return end
322
323 if (!self.wRenderOrder) then
324
325 self.wRenderOrder = {}
326
327 for k, v in pairs( self.WElements ) do
328 if (v.type == "Model") then
329 table.insert(self.wRenderOrder, 1, k)
330 elseif (v.type == "Sprite" or v.type == "Quad") then
331 table.insert(self.wRenderOrder, k)
332 end
333 end
334
335 end
336
337 if (IsValid(self.Owner)) then
338 bone_ent = self.Owner
339 else
340 // when the weapon is dropped
341 bone_ent = self
342 end
343
344 for k, name in pairs( self.wRenderOrder ) do
345
346 local v = self.WElements[name]
347 if (!v) then self.wRenderOrder = nil break end
348 if (v.hide) then continue end
349
350 local pos, ang
351
352 if (v.bone) then
353 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
354 else
355 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
356 end
357
358 if (!pos) then continue end
359
360 local model = v.modelEnt
361 local sprite = v.spriteMaterial
362
363 if (v.type == "Model" and IsValid(model)) then
364
365 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
366 ang:RotateAroundAxis(ang:Up(), v.angle.y)
367 ang:RotateAroundAxis(ang:Right(), v.angle.p)
368 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
369
370 model:SetAngles(ang)
371 //model:SetModelScale(v.size)
372 local matrix = Matrix()
373 matrix:Scale(v.size)
374 model:EnableMatrix( "RenderMultiply", matrix )
375
376 if (v.material == "") then
377 model:SetMaterial("")
378 elseif (model:GetMaterial() != v.material) then
379 model:SetMaterial( v.material )
380 end
381
382 if (v.skin and v.skin != model:GetSkin()) then
383 model:SetSkin(v.skin)
384 end
385
386 if (v.bodygroup) then
387 for k, v in pairs( v.bodygroup ) do
388 if (model:GetBodygroup(k) != v) then
389 model:SetBodygroup(k, v)
390 end
391 end
392 end
393
394 if (v.surpresslightning) then
395 render.SuppressEngineLighting(true)
396 end
397
398 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
399 render.SetBlend(v.color.a/255)
400 model:DrawModel()
401 render.SetBlend(1)
402 render.SetColorModulation(1, 1, 1)
403
404 if (v.surpresslightning) then
405 render.SuppressEngineLighting(false)
406 end
407
408 elseif (v.type == "Sprite" and sprite) then
409
410 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
411 render.SetMaterial(sprite)
412 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
413
414 elseif (v.type == "Quad" and v.draw_func) then
415
416 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
417 ang:RotateAroundAxis(ang:Up(), v.angle.y)
418 ang:RotateAroundAxis(ang:Right(), v.angle.p)
419 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
420
421 cam.Start3D2D(drawpos, ang, v.size)
422 v.draw_func( self )
423 cam.End3D2D()
424
425 end
426
427 end
428
429 end
430
431 function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
432
433 local bone, pos, ang
434 if (tab.rel and tab.rel != "") then
435
436 local v = basetab[tab.rel]
437
438 if (!v) then return end
439
440 // Technically, if there exists an element with the same name as a bone
441 // you can get in an infinite loop. Let's just hope nobody's that stupid.
442 pos, ang = self:GetBoneOrientation( basetab, v, ent )
443
444 if (!pos) then return end
445
446 pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
447 ang:RotateAroundAxis(ang:Up(), v.angle.y)
448 ang:RotateAroundAxis(ang:Right(), v.angle.p)
449 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
450
451 else
452
453 bone = ent:LookupBone(bone_override or tab.bone)
454
455 if (!bone) then return end
456
457 pos, ang = Vector(0,0,0), Angle(0,0,0)
458 local m = ent:GetBoneMatrix(bone)
459 if (m) then
460 pos, ang = m:GetTranslation(), m:GetAngles()
461 end
462
463 if (IsValid(self.Owner) and self.Owner:IsPlayer() and
464 ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
465 ang.r = -ang.r // Fixes mirrored models
466 end
467
468 end
469
470 return pos, ang
471 end
472
473 function SWEP:CreateModels( tab )
474
475 if (!tab) then return end
476
477 // Create the clientside models here because Garry says we can't do it in the render hook
478 for k, v in pairs( tab ) do
479 if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
480 string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
481
482 v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
483 if (IsValid(v.modelEnt)) then
484 v.modelEnt:SetPos(self:GetPos())
485 v.modelEnt:SetAngles(self:GetAngles())
486 v.modelEnt:SetParent(self)
487 v.modelEnt:SetNoDraw(true)
488 v.createdModel = v.model
489 else
490 v.modelEnt = nil
491 end
492
493 elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
494 and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
495
496 local name = v.sprite.."-"
497 local params = { ["$basetexture"] = v.sprite }
498 // make sure we create a unique name based on the selected options
499 local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
500 for i, j in pairs( tocheck ) do
501 if (v[j]) then
502 params["$"..j] = 1
503 name = name.."1"
504 else
505 name = name.."0"
506 end
507 end
508
509 v.createdSprite = v.sprite
510 v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
511
512 end
513 end
514
515 end
516
517 local allbones
518 local hasGarryFixedBoneScalingYet = false
519
520 function SWEP:UpdateBonePositions(vm)
521
522 if self.ViewModelBoneMods then
523
524 if (!vm:GetBoneCount()) then return end
525
526 // !! WORKAROUND !! //
527 // We need to check all model names :/
528 local loopthrough = self.ViewModelBoneMods
529 if (!hasGarryFixedBoneScalingYet) then
530 allbones = {}
531 for i=0, vm:GetBoneCount() do
532 local bonename = vm:GetBoneName(i)
533 if (self.ViewModelBoneMods[bonename]) then
534 allbones[bonename] = self.ViewModelBoneMods[bonename]
535 else
536 allbones[bonename] = {
537 scale = Vector(1,1,1),
538 pos = Vector(0,0,0),
539 angle = Angle(0,0,0)
540 }
541 end
542 end
543
544 loopthrough = allbones
545 end
546 // !! ----------- !! //
547
548 for k, v in pairs( loopthrough ) do
549 local bone = vm:LookupBone(k)
550 if (!bone) then continue end
551
552 // !! WORKAROUND !! //
553 local s = Vector(v.scale.x,v.scale.y,v.scale.z)
554 local p = Vector(v.pos.x,v.pos.y,v.pos.z)
555 local ms = Vector(1,1,1)
556 if (!hasGarryFixedBoneScalingYet) then
557 local cur = vm:GetBoneParent(bone)
558 while(cur >= 0) do
559 local pscale = loopthrough[vm:GetBoneName(cur)].scale
560 ms = ms * pscale
561 cur = vm:GetBoneParent(cur)
562 end
563 end
564
565 s = s * ms
566 // !! ----------- !! //
567
568 if vm:GetManipulateBoneScale(bone) != s then
569 vm:ManipulateBoneScale( bone, s )
570 end
571 if vm:GetManipulateBoneAngles(bone) != v.angle then
572 vm:ManipulateBoneAngles( bone, v.angle )
573 end
574 if vm:GetManipulateBonePosition(bone) != p then
575 vm:ManipulateBonePosition( bone, p )
576 end
577 end
578 else
579 self:ResetBonePositions(vm)
580 end
581
582 end
583
584 function SWEP:ResetBonePositions(vm)
585
586 if (!vm:GetBoneCount()) then return end
587 for i=0, vm:GetBoneCount() do
588 vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
589 vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
590 vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
591 end
592
593 end
594
595 /**************************
596 Global utility code
597 **************************/
598
599 // Fully copies the table, meaning all tables inside this table are copied too and so on (normal table.Copy copies only their reference).
600 // Does not copy entities of course, only copies their reference.
601 // WARNING: do not use on tables that contain themselves somewhere down the line or you'll get an infinite loop
602 function table.FullCopy( tab )
603
604 if (!tab) then return nil end
605
606 local res = {}
607 for k, v in pairs( tab ) do
608 if (type(v) == "table") then
609 res[k] = table.FullCopy(v) // recursion ho!
610 elseif (type(v) == "Vector") then
611 res[k] = Vector(v.x, v.y, v.z)
612 elseif (type(v) == "Angle") then
613 res[k] = Angle(v.p, v.y, v.r)
614 else
615 res[k] = v
616 end
617 end
618
619 return res
620
621 end
622
623end