· 10 years ago · Aug 21, 2016, 09:32 AM
1// Variables that are used on both client and server
2if (CLIENT) then
3
4 SWEP.PrintName = "Golden Gun";
5 SWEP.Slot = 1;
6 SWEP.SlotPos = 1;
7 SWEP.DrawAmmo = true;
8 SWEP.DrawCrosshair = false;
9
10 SWEP.WepSelectIcon = surface.GetTextureID("vgui/entities/weapon_goldengun")
11 SWEP.BounceWeaponIcon = false
12 SWEP.Icon = "VGUI/ttt/icon_gold_gun"
13end
14
15SWEP.VElements = {
16 ["element_name"] = { type = "Model", model = "models/goldengun.mdl", bone = "Object03", rel = "", pos = Vector(16.1, -0.057, 0.5), angle = Angle(-1.065, -180, -90.282), size = Vector(1,1,1), color = Color(255, 255, 255, 255), surpresslightning = false, material = "models/player/shared/gold_player", skin = 0, bodygroup = {} }
17}
18SWEP.WElements = {
19 ["element_name"] = { type = "Model", model = "models/goldengun.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(-12.855, 1.567, 0.054), angle = Angle(-3.962, 0, 173.091), size = Vector(0.935, 0.935, 0.935), color = Color(255, 255, 255, 255), surpresslightning = false, material = "models/player/shared/gold_player", skin = 0, bodygroup = {} }
20}
21
22
23SWEP.RunArmOffset = Vector (0, -4.919, -2.623)
24SWEP.RunArmAngle = Vector (33.852, 0, 0)
25
26
27SWEP.Category = "Babel Industries"
28
29SWEP.Author = "Babel Ind. (model ripped by Asteroidrules)";
30SWEP.Contact = "Babel Industries";
31SWEP.Purpose = "";
32SWEP.Instructions = "If you've ever played Goldeneye 64's multiplayer into the morning hours with friends, you know what this does.";
33SWEP.IconLetter = "m"
34
35
36SWEP.Base = "weapon_mad_base"
37
38SWEP.HoldType = "pistol"
39SWEP.ViewModelFOV = 80
40SWEP.ViewModelFlip = true
41SWEP.ViewModel = "models/weapons/v_pist_xiveseven.mdl"
42SWEP.WorldModel = "models/weapons/w_pistol.mdl"
43SWEP.ShowViewModel = true
44SWEP.ShowWorldModel = false
45SWEP.ViewModelBoneMods = {
46 ["R 09"] = { scale = Vector(1, 1, 1), pos = Vector(0.901, 0.603, -0.12), angle = Angle(0, 0, 0) },
47 ["Object03"] = { scale = Vector(0.128, 0.128, 0.128), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) }
48}
49
50 // TTT Convertion Code \\
51
52SWEP.Base = "weapon_tttbase"
53SWEP.Kind = WEAPON_PISTOL
54SWEP.AutoSpawnable = false
55SWEP.AmmoEnt = "item_ammo_revolver_ttt"
56SWEP.InLoadoutFor = nil
57SWEP.AllowDrop = true
58SWEP.IsSilent = false
59SWEP.NoSights = false
60
61SWEP.IronSightsPos = Vector(4, 5, 1.519)
62SWEP.IronSightsAng = Vector(0, 1, 0.068)
63
64function SWEP:Reload()
65 if !( ( self.Weapon:Clip1() ) < ( self.Primary.ClipSize ) ) then return end
66 self.Weapon:DefaultReload( ACT_VM_RELOAD )
67 self:EmitSound( "weapons/goldengun/reload2.wav" )
68
69end
70function SWEP:Deploy()
71 self.Weapon:SendWeaponAnim( ACT_VM_DRAW )
72
73
74 return true;
75end
76
77
78
79
80SWEP.Spawnable = true
81SWEP.AdminSpawnable = false
82
83SWEP.Primary.Sound = Sound("weapons/goldengun/gg-shoot2.wav")
84SWEP.Primary.Recoil = .35
85SWEP.Primary.Damage = 35
86SWEP.Primary.NumShots = 2
87SWEP.Primary.Cone = 0
88SWEP.Primary.Delay = .1
89SWEP.Primary.Force = 0;
90
91SWEP.Primary.ClipSize = 1 // Size of a clip
92SWEP.Primary.DefaultClip = 30 // Default number of bullets in a clip
93SWEP.Primary.Automatic = false // Automatic/Semi Auto
94SWEP.Primary.Ammo = "Pistol"
95
96SWEP.Secondary.ClipSize = -1 // Size of a clip
97SWEP.Secondary.DefaultClip = -1 // Default number of bullets in a clip
98SWEP.Secondary.Automatic = false // Automatic/Semi Auto
99SWEP.Secondary.Ammo = "none"
100
101
102
103function SWEP:Initialize()
104
105 // other initialize code goes here
106
107 if CLIENT then
108
109 // Create a new table for every weapon instance
110 self.VElements = table.FullCopy( self.VElements )
111 self.WElements = table.FullCopy( self.WElements )
112 self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
113
114 self:CreateModels(self.VElements) // create viewmodels
115 self:CreateModels(self.WElements) // create worldmodels
116
117 // Init viewmodel visibility
118 if (self.ShowViewModel == nil or self.ShowViewModel) then
119 vm:SetColor(Color(255,255,255,255))
120 else
121 // we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
122 vm:SetColor(Color(255,255,255,1))
123 // ^ stopped working in GMod 13 because you have to do Entity:SetRenderMode(1) for translucency to kick in
124 // 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
125 vm:SetMaterial("Debug/hsv")
126 end
127
128 end
129
130end
131
132function SWEP:Holster()
133
134 if CLIENT then
135 local vm = self.Owner:GetViewModel()
136 if IsValid(vm) then
137 self:ResetBonePositions(vm)
138 end
139 end
140
141 return true
142end
143
144if CLIENT then
145
146 SWEP.vRenderOrder = nil
147 function SWEP:ViewModelDrawn()
148
149 local vm = self.Owner:GetViewModel()
150 if !IsValid(vm) then return end
151
152 if (!self.VElements) then return end
153
154 self:UpdateBonePositions(vm)
155
156 if (!self.vRenderOrder) then
157
158 // we build a render order because sprites need to be drawn after models
159 self.vRenderOrder = {}
160
161 for k, v in pairs( self.VElements ) do
162 if (v.type == "Model") then
163 table.insert(self.vRenderOrder, 1, k)
164 elseif (v.type == "Sprite" or v.type == "Quad") then
165 table.insert(self.vRenderOrder, k)
166 end
167 end
168
169 end
170
171 for k, name in ipairs( self.vRenderOrder ) do
172
173 local v = self.VElements[name]
174 if (!v) then self.vRenderOrder = nil break end
175 if (v.hide) then continue end
176
177 local model = v.modelEnt
178 local sprite = v.spriteMaterial
179
180 if (!v.bone) then continue end
181
182 local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
183
184 if (!pos) then continue end
185
186 if (v.type == "Model" and IsValid(model)) then
187
188 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
189 ang:RotateAroundAxis(ang:Up(), v.angle.y)
190 ang:RotateAroundAxis(ang:Right(), v.angle.p)
191 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
192
193 model:SetAngles(ang)
194 //model:SetModelScale(v.size)
195 local matrix = Matrix()
196 matrix:Scale(v.size)
197 model:EnableMatrix( "RenderMultiply", matrix )
198
199 if (v.material == "") then
200 model:SetMaterial("")
201 elseif (model:GetMaterial() != v.material) then
202 model:SetMaterial( v.material )
203 end
204
205 if (v.skin and v.skin != model:GetSkin()) then
206 model:SetSkin(v.skin)
207 end
208
209 if (v.bodygroup) then
210 for k, v in pairs( v.bodygroup ) do
211 if (model:GetBodygroup(k) != v) then
212 model:SetBodygroup(k, v)
213 end
214 end
215 end
216
217 if (v.surpresslightning) then
218 render.SuppressEngineLighting(true)
219 end
220
221 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
222 render.SetBlend(v.color.a/255)
223 model:DrawModel()
224 render.SetBlend(1)
225 render.SetColorModulation(1, 1, 1)
226
227 if (v.surpresslightning) then
228 render.SuppressEngineLighting(false)
229 end
230
231 elseif (v.type == "Sprite" and sprite) then
232
233 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
234 render.SetMaterial(sprite)
235 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
236
237 elseif (v.type == "Quad" and v.draw_func) then
238
239 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
240 ang:RotateAroundAxis(ang:Up(), v.angle.y)
241 ang:RotateAroundAxis(ang:Right(), v.angle.p)
242 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
243
244 cam.Start3D2D(drawpos, ang, v.size)
245 v.draw_func( self )
246 cam.End3D2D()
247
248 end
249
250 end
251
252 end
253
254 SWEP.wRenderOrder = nil
255 function SWEP:DrawWorldModel()
256
257 if (self.ShowWorldModel == nil or self.ShowWorldModel) then
258 self:DrawModel()
259 end
260
261 if (!self.WElements) then return end
262
263 if (!self.wRenderOrder) then
264
265 self.wRenderOrder = {}
266
267 for k, v in pairs( self.WElements ) do
268 if (v.type == "Model") then
269 table.insert(self.wRenderOrder, 1, k)
270 elseif (v.type == "Sprite" or v.type == "Quad") then
271 table.insert(self.wRenderOrder, k)
272 end
273 end
274
275 end
276
277 if (IsValid(self.Owner)) then
278 bone_ent = self.Owner
279 else
280 // when the weapon is dropped
281 bone_ent = self
282 end
283
284 for k, name in pairs( self.wRenderOrder ) do
285
286 local v = self.WElements[name]
287 if (!v) then self.wRenderOrder = nil break end
288 if (v.hide) then continue end
289
290 local pos, ang
291
292 if (v.bone) then
293 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
294 else
295 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
296 end
297
298 if (!pos) then continue end
299
300 local model = v.modelEnt
301 local sprite = v.spriteMaterial
302
303 if (v.type == "Model" and IsValid(model)) then
304
305 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
306 ang:RotateAroundAxis(ang:Up(), v.angle.y)
307 ang:RotateAroundAxis(ang:Right(), v.angle.p)
308 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
309
310 model:SetAngles(ang)
311 //model:SetModelScale(v.size)
312 local matrix = Matrix()
313 matrix:Scale(v.size)
314 model:EnableMatrix( "RenderMultiply", matrix )
315
316 if (v.material == "") then
317 model:SetMaterial("")
318 elseif (model:GetMaterial() != v.material) then
319 model:SetMaterial( v.material )
320 end
321
322 if (v.skin and v.skin != model:GetSkin()) then
323 model:SetSkin(v.skin)
324 end
325
326 if (v.bodygroup) then
327 for k, v in pairs( v.bodygroup ) do
328 if (model:GetBodygroup(k) != v) then
329 model:SetBodygroup(k, v)
330 end
331 end
332 end
333
334 if (v.surpresslightning) then
335 render.SuppressEngineLighting(true)
336 end
337
338 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
339 render.SetBlend(v.color.a/255)
340 model:DrawModel()
341 render.SetBlend(1)
342 render.SetColorModulation(1, 1, 1)
343
344 if (v.surpresslightning) then
345 render.SuppressEngineLighting(false)
346 end
347
348 elseif (v.type == "Sprite" and sprite) then
349
350 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
351 render.SetMaterial(sprite)
352 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
353
354 elseif (v.type == "Quad" and v.draw_func) then
355
356 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
357 ang:RotateAroundAxis(ang:Up(), v.angle.y)
358 ang:RotateAroundAxis(ang:Right(), v.angle.p)
359 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
360
361 cam.Start3D2D(drawpos, ang, v.size)
362 v.draw_func( self )
363 cam.End3D2D()
364
365 end
366
367 end
368
369 end
370
371 function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
372
373 local bone, pos, ang
374 if (tab.rel and tab.rel != "") then
375
376 local v = basetab[tab.rel]
377
378 if (!v) then return end
379
380 // Technically, if there exists an element with the same name as a bone
381 // you can get in an infinite loop. Let's just hope nobody's that stupid.
382 pos, ang = self:GetBoneOrientation( basetab, v, ent )
383
384 if (!pos) then return end
385
386 pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
387 ang:RotateAroundAxis(ang:Up(), v.angle.y)
388 ang:RotateAroundAxis(ang:Right(), v.angle.p)
389 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
390
391 else
392
393 bone = ent:LookupBone(bone_override or tab.bone)
394
395 if (!bone) then return end
396
397 pos, ang = Vector(0,0,0), Angle(0,0,0)
398 local m = ent:GetBoneMatrix(bone)
399 if (m) then
400 pos, ang = m:GetTranslation(), m:GetAngles()
401 end
402
403 if (IsValid(self.Owner) and self.Owner:IsPlayer() and
404 ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
405 ang.r = -ang.r // Fixes mirrored models
406 end
407
408 end
409
410 return pos, ang
411 end
412
413 function SWEP:CreateModels( tab )
414
415 if (!tab) then return end
416
417 // Create the clientside models here because Garry says we can't do it in the render hook
418 for k, v in pairs( tab ) do
419 if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
420 string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
421
422 v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
423 if (IsValid(v.modelEnt)) then
424 v.modelEnt:SetPos(self:GetPos())
425 v.modelEnt:SetAngles(self:GetAngles())
426 v.modelEnt:SetParent(self)
427 v.modelEnt:SetNoDraw(true)
428 v.createdModel = v.model
429 else
430 v.modelEnt = nil
431 end
432
433 elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
434 and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
435
436 local name = v.sprite.."-"
437 local params = { ["$basetexture"] = v.sprite }
438 // make sure we create a unique name based on the selected options
439 local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
440 for i, j in pairs( tocheck ) do
441 if (v[j]) then
442 params["$"..j] = 1
443 name = name.."1"
444 else
445 name = name.."0"
446 end
447 end
448
449 v.createdSprite = v.sprite
450 v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
451
452 end
453 end
454
455 end
456
457 local allbones
458 local hasGarryFixedBoneScalingYet = false
459
460 function SWEP:UpdateBonePositions(vm)
461
462 if self.ViewModelBoneMods then
463
464 if (!vm:GetBoneCount()) then return end
465
466 // !! WORKAROUND !! //
467 // We need to check all model names :/
468 local loopthrough = self.ViewModelBoneMods
469 if (!hasGarryFixedBoneScalingYet) then
470 allbones = {}
471 for i=0, vm:GetBoneCount() do
472 local bonename = vm:GetBoneName(i)
473 if (self.ViewModelBoneMods[bonename]) then
474 allbones[bonename] = self.ViewModelBoneMods[bonename]
475 else
476 allbones[bonename] = {
477 scale = Vector(1,1,1),
478 pos = Vector(0,0,0),
479 angle = Angle(0,0,0)
480 }
481 end
482 end
483
484 loopthrough = allbones
485 end
486 // !! ----------- !! //
487
488 for k, v in pairs( loopthrough ) do
489 local bone = vm:LookupBone(k)
490 if (!bone) then continue end
491
492 // !! WORKAROUND !! //
493 local s = Vector(v.scale.x,v.scale.y,v.scale.z)
494 local p = Vector(v.pos.x,v.pos.y,v.pos.z)
495 local ms = Vector(1,1,1)
496 if (!hasGarryFixedBoneScalingYet) then
497 local cur = vm:GetBoneParent(bone)
498 while(cur >= 0) do
499 local pscale = loopthrough[vm:GetBoneName(cur)].scale
500 ms = ms * pscale
501 cur = vm:GetBoneParent(cur)
502 end
503 end
504
505 s = s * ms
506 // !! ----------- !! //
507
508 if vm:GetManipulateBoneScale(bone) != s then
509 vm:ManipulateBoneScale( bone, s )
510 end
511 if vm:GetManipulateBoneAngles(bone) != v.angle then
512 vm:ManipulateBoneAngles( bone, v.angle )
513 end
514 if vm:GetManipulateBonePosition(bone) != p then
515 vm:ManipulateBonePosition( bone, p )
516 end
517 end
518 else
519 self:ResetBonePositions(vm)
520 end
521
522 end
523
524 function SWEP:ResetBonePositions(vm)
525
526 if (!vm:GetBoneCount()) then return end
527 for i=0, vm:GetBoneCount() do
528 vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
529 vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
530 vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
531 end
532
533 end
534
535 /**************************
536 Global utility code
537 **************************/
538
539 // Fully copies the table, meaning all tables inside this table are copied too and so on (normal table.Copy copies only their reference).
540 // Does not copy entities of course, only copies their reference.
541 // WARNING: do not use on tables that contain themselves somewhere down the line or you'll get an infinite loop
542 function table.FullCopy( tab )
543
544 if (!tab) then return nil end
545
546 local res = {}
547 for k, v in pairs( tab ) do
548 if (type(v) == "table") then
549 res[k] = table.FullCopy(v) // recursion ho!
550 elseif (type(v) == "Vector") then
551 res[k] = Vector(v.x, v.y, v.z)
552 elseif (type(v) == "Angle") then
553 res[k] = Angle(v.p, v.y, v.r)
554 else
555 res[k] = v
556 end
557 end
558
559 return res
560
561 end
562
563end