· 8 years ago · Jun 15, 2018, 03:00 AM
1/*
2 ©2018 Walrusking
3 This was created by Walrusking[
4 SteamID: STEAM_0:0:103519394
5 Link to profile: http://steamcommunity.com/id/Walrusking_1/
6 ]
7 Covered by Attribution-NonCommercial-NoDerivatives 4.0 International
8 http://creativecommons.org/licenses/by-nc-nd/4.0/
9 http://creativecommons.org/licenses/by-nc-nd/4.0/legalcode
10*/
11
12AddCSLuaFile()
13
14SWEP.PrintName = "Ironman Hand Repulsor"
15SWEP.Author = "Walrusking"
16SWEP.Category = "Iron man"
17SWEP.Instructions = "Left click to shoot."
18SWEP.Slot = 1
19SWEP.SlotPos = 1
20SWEP.DrawCrosshair = true
21SWEP.DrawAmmo = false
22SWEP.Spawnable = true
23SWEP.AdminSpawnable = false
24SWEP.ViewModel = "models/weapons/c_arms.mdl"
25SWEP.WorldModel = "models/weapons/c_arms.mdl"
26SWEP.UseHands = true
27SWEP.Primary.ClipSize = 1
28SWEP.Primary.DefaultClip = 2
29SWEP.Primary.Automatic = false
30SWEP.Primary.Ammo = "none"
31SWEP.Primary.Delay = 4
32SWEP.Secondary.ClipSize = -1
33SWEP.Secondary.DefaultClip = -1
34SWEP.Secondary.Automatic = true
35SWEP.Secondary.Ammo = "none"
36SWEP.DealDamage = 0.2
37SWEP.EntityForce = 15
38SWEP.PlayerForce = 15
39SWEP.NPCForce = 20
40SWEP.WElements = {
41 ["repulsor"] = { type = "Model", model = "models/repulsor/repulsor.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(3, 1.409, 0), angle = Angle(-90, 0, 54), size = Vector(0.5, 0.5, 0.5), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 0, bodygroup = {} }
42}
43
44function SWEP:DrawHUD()
45 local h = ScrH()
46 local w = ScrW()
47 draw.RoundedBox(0,w - 160,h - 200,150,50,Color(135,226,250,190))
48 draw.RoundedBox(0,w - 160,h - 200,self.Owner:GetInfo("ironman_repulsor_power", "50") * 1.5,50,Color(0,191,255,190))
49 draw.SimpleText("Power: "..self.Owner:GetInfo("ironman_repulsor_power", "50").."%","stark",w - 150,h - 193,Color(255,255,255))
50end
51
52function SWEP:Initialize()
53 self:SetHoldType( "magic" )
54end
55
56
57function SWEP:Think()
58 if tonumber(self.Owner:GetInfo("ironman_repulsor_power", "50")) > 100 then
59 self.Owner:ConCommand("ironman_repulsor_power 100")
60 elseif tonumber(self.Owner:GetInfo("ironman_repulsor_power", "50")) < 0 then
61 self.Owner:ConCommand("ironman_repulsor_power 0")
62 end
63end
64
65function SWEP:PrimaryAttack()
66 if tonumber(self.Owner:GetInfo("ironman_repulsor_power", "50")) > 100 then
67 return self.Owner:ChatPrint("This weapon will not work because your power is over 100%!")
68 end
69 self:SetNextPrimaryFire(CurTime() + 4)
70 self.Owner:EmitSound("Repulsor Start",self.Owner:GetPos())
71 ParticleEffectAttach( "vortigaunt_hand_glow_c", PATTACH_POINT_FOLLOW, self.Owner, 4 )
72 timer.Create(self.Owner:Nick().."im_repulser_start", 1, 1,function()
73 self.Owner:StopParticles()
74 local tr = self.Owner:GetEyeTrace()
75 if SERVER then util.ParticleTracerEx("vortigaunt_beam",self.Owner:GetShootPos(), tr.HitPos, false, self.Owner:EntIndex(), 4 ) end
76 self.Owner:EmitSound("Repulsor Fire",self.Owner:GetPos())
77 if tr.Hit then
78 local ent = tr.Entity
79 if !self.Owner:IsPlayer() or !IsValid(self.Owner) or !self.Owner:Alive() then return end
80 if SERVER then
81 if IsEntity(ent) then
82 local phys = ent:GetPhysicsObject()
83 phys:AddAngleVelocity(self.Owner:GetAimVector() + Vector(0,-3000,0))
84 phys:SetVelocity(self.Owner:GetAimVector() * self.EntityForce * tonumber(self.Owner:GetInfo("ironman_repulsor_power", "50")))
85 ent:TakeDamage(self.DealDamage * tonumber(self.Owner:GetInfo("ironman_repulsor_power", "50")),self.Owner,self.Owner)
86 end
87 if ent:IsPlayer() then
88 ent:SetVelocity(self.Owner:GetAimVector() * self.PlayerForce * tonumber(self.Owner:GetInfo("ironman_repulsor_power", "50")))
89 ent:TakeDamage(self.DealDamage * tonumber(self.Owner:GetInfo("ironman_repulsor_power", "50")),self.Owner,self.Owner)
90 elseif ent:IsNPC() then
91 ent:SetVelocity(self.Owner:GetAimVector() * self.NPCForce * tonumber(self.Owner:GetInfo("ironman_repulsor_power", "50")))
92 ent:TakeDamage(self.DealDamage * tonumber(self.Owner:GetInfo("ironman_repulsor_power", "50")),self.Owner,self.Owner)
93 end
94 end
95 end
96 timer.Create(self.Owner:Nick().."im_repulser_end", 1.5, 1,function()
97 if SERVER then
98 self.Owner:EmitSound("Repulsor End",self.Owner:GetPos())
99 end
100 end)
101 end)
102end
103
104function SWEP:SecondaryAttack()
105 return false
106end
107
108function SWEP:Deploy()
109 self:SetHoldType( "magic" )
110 return true
111end
112
113function SWEP:Holster()
114 if !self.Owner:IsPlayer() or !IsValid(self.Owner) or !self.Owner:Alive() then return end
115 if timer.Exists(self.Owner:Nick().."im_repulser_start") then
116 return false
117 elseif timer.Exists(self.Owner:Nick().."im_repulser_end") then
118 return false
119 else
120 if CLIENT and IsValid(self.Owner) then
121 local vm = self.Owner:GetViewModel()
122 if IsValid(vm) then
123 self:ResetBonePositions(vm)
124 end
125 end
126 return true
127 end
128end
129/********************************************************
130 SWEP Construction Kit base code
131 Created by Clavus
132 Available for public use, thread at:
133 facepunch.com/threads/1032378
134
135
136 DESCRIPTION:
137 This script is meant for experienced scripters
138 that KNOW WHAT THEY ARE DOING. Don't come to me
139 with basic Lua questions.
140
141 Just copy into your SWEP or SWEP base of choice
142 and merge with your own code.
143
144 The SWEP.VElements, SWEP.WElements and
145 SWEP.ViewModelBoneMods tables are all optional
146 and only have to be visible to the client.
147********************************************************/
148
149function SWEP:Initialize()
150
151 // other initialize code goes here
152
153 if CLIENT then
154
155 // Create a new table for every weapon instance
156 self.VElements = table.FullCopy( self.VElements )
157 self.WElements = table.FullCopy( self.WElements )
158 self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
159
160 self:CreateModels(self.VElements) // create viewmodels
161 self:CreateModels(self.WElements) // create worldmodels
162
163 // init view model bone build function
164 if IsValid(self.Owner) then
165 local vm = self.Owner:GetViewModel()
166 if IsValid(vm) then
167 self:ResetBonePositions(vm)
168
169 // Init viewmodel visibility
170 if (self.ShowViewModel == nil or self.ShowViewModel) then
171 vm:SetColor(Color(255,255,255,255))
172 else
173 // we set the alpha to 1 instead of 0 because else ViewModelDrawn stops being called
174 vm:SetColor(Color(255,255,255,1))
175 // ^ stopped working in GMod 13 because you have to do Entity:SetRenderMode(1) for translucency to kick in
176 // 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
177 vm:SetMaterial("Debug/hsv")
178 end
179 end
180 end
181
182 end
183
184end
185
186function SWEP:OnRemove()
187 self:Holster()
188end
189
190if CLIENT then
191
192 SWEP.vRenderOrder = nil
193 function SWEP:ViewModelDrawn()
194
195 local vm = self.Owner:GetViewModel()
196 if !IsValid(vm) then return end
197
198 if (!self.VElements) then return end
199
200 self:UpdateBonePositions(vm)
201
202 if (!self.vRenderOrder) then
203
204 // we build a render order because sprites need to be drawn after models
205 self.vRenderOrder = {}
206
207 for k, v in pairs( self.VElements ) do
208 if (v.type == "Model") then
209 table.insert(self.vRenderOrder, 1, k)
210 elseif (v.type == "Sprite" or v.type == "Quad") then
211 table.insert(self.vRenderOrder, k)
212 end
213 end
214
215 end
216
217 for k, name in ipairs( self.vRenderOrder ) do
218
219 local v = self.VElements[name]
220 if (!v) then self.vRenderOrder = nil break end
221 if (v.hide) then continue end
222
223 local model = v.modelEnt
224 local sprite = v.spriteMaterial
225
226 if (!v.bone) then continue end
227
228 local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
229
230 if (!pos) then continue end
231
232 if (v.type == "Model" and IsValid(model)) then
233
234 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
235 ang:RotateAroundAxis(ang:Up(), v.angle.y)
236 ang:RotateAroundAxis(ang:Right(), v.angle.p)
237 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
238
239 model:SetAngles(ang)
240 //model:SetModelScale(v.size)
241 local matrix = Matrix()
242 matrix:Scale(v.size)
243 model:EnableMatrix( "RenderMultiply", matrix )
244
245 if (v.material == "") then
246 model:SetMaterial("")
247 elseif (model:GetMaterial() != v.material) then
248 model:SetMaterial( v.material )
249 end
250
251 if (v.skin and v.skin != model:GetSkin()) then
252 model:SetSkin(v.skin)
253 end
254
255 if (v.bodygroup) then
256 for k, v in pairs( v.bodygroup ) do
257 if (model:GetBodygroup(k) != v) then
258 model:SetBodygroup(k, v)
259 end
260 end
261 end
262
263 if (v.surpresslightning) then
264 render.SuppressEngineLighting(true)
265 end
266
267 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
268 render.SetBlend(v.color.a/255)
269 model:DrawModel()
270 render.SetBlend(1)
271 render.SetColorModulation(1, 1, 1)
272
273 if (v.surpresslightning) then
274 render.SuppressEngineLighting(false)
275 end
276
277 elseif (v.type == "Sprite" and sprite) then
278
279 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
280 render.SetMaterial(sprite)
281 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
282
283 elseif (v.type == "Quad" and v.draw_func) then
284
285 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
286 ang:RotateAroundAxis(ang:Up(), v.angle.y)
287 ang:RotateAroundAxis(ang:Right(), v.angle.p)
288 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
289
290 cam.Start3D2D(drawpos, ang, v.size)
291 v.draw_func( self )
292 cam.End3D2D()
293
294 end
295
296 end
297
298 end
299
300 SWEP.wRenderOrder = nil
301 function SWEP:DrawWorldModel()
302
303 if (self.ShowWorldModel == nil or self.ShowWorldModel) then
304 self:DrawModel()
305 end
306
307 if (!self.WElements) then return end
308
309 if (!self.wRenderOrder) then
310
311 self.wRenderOrder = {}
312
313 for k, v in pairs( self.WElements ) do
314 if (v.type == "Model") then
315 table.insert(self.wRenderOrder, 1, k)
316 elseif (v.type == "Sprite" or v.type == "Quad") then
317 table.insert(self.wRenderOrder, k)
318 end
319 end
320
321 end
322
323 if (IsValid(self.Owner)) then
324 bone_ent = self.Owner
325 else
326 // when the weapon is dropped
327 bone_ent = self
328 end
329
330 for k, name in pairs( self.wRenderOrder ) do
331
332 local v = self.WElements[name]
333 if (!v) then self.wRenderOrder = nil break end
334 if (v.hide) then continue end
335
336 local pos, ang
337
338 if (v.bone) then
339 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
340 else
341 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
342 end
343
344 if (!pos) then continue end
345
346 local model = v.modelEnt
347 local sprite = v.spriteMaterial
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 function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
418
419 local bone, pos, ang
420 if (tab.rel and tab.rel != "") then
421
422 local v = basetab[tab.rel]
423
424 if (!v) then return end
425
426 // Technically, if there exists an element with the same name as a bone
427 // you can get in an infinite loop. Let's just hope nobody's that stupid.
428 pos, ang = self:GetBoneOrientation( basetab, v, ent )
429
430 if (!pos) then return end
431
432 pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
433 ang:RotateAroundAxis(ang:Up(), v.angle.y)
434 ang:RotateAroundAxis(ang:Right(), v.angle.p)
435 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
436
437 else
438
439 bone = ent:LookupBone(bone_override or tab.bone)
440
441 if (!bone) then return end
442
443 pos, ang = Vector(0,0,0), Angle(0,0,0)
444 local m = ent:GetBoneMatrix(bone)
445 if (m) then
446 pos, ang = m:GetTranslation(), m:GetAngles()
447 end
448
449 if (IsValid(self.Owner) and self.Owner:IsPlayer() and
450 ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
451 ang.r = -ang.r // Fixes mirrored models
452 end
453
454 end
455
456 return pos, ang
457 end
458
459 function SWEP:CreateModels( tab )
460
461 if (!tab) then return end
462
463 // Create the clientside models here because Garry says we can't do it in the render hook
464 for k, v in pairs( tab ) do
465 if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
466 string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
467
468 v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
469 if (IsValid(v.modelEnt)) then
470 v.modelEnt:SetPos(self:GetPos())
471 v.modelEnt:SetAngles(self:GetAngles())
472 v.modelEnt:SetParent(self)
473 v.modelEnt:SetNoDraw(true)
474 v.createdModel = v.model
475 else
476 v.modelEnt = nil
477 end
478
479 elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
480 and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
481
482 local name = v.sprite.."-"
483 local params = { ["$basetexture"] = v.sprite }
484 // make sure we create a unique name based on the selected options
485 local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
486 for i, j in pairs( tocheck ) do
487 if (v[j]) then
488 params["$"..j] = 1
489 name = name.."1"
490 else
491 name = name.."0"
492 end
493 end
494
495 v.createdSprite = v.sprite
496 v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
497
498 end
499 end
500
501 end
502
503 local allbones
504 local hasGarryFixedBoneScalingYet = false
505
506 function SWEP:UpdateBonePositions(vm)
507
508 if self.ViewModelBoneMods then
509
510 if (!vm:GetBoneCount()) then return end
511
512 // !! WORKAROUND !! //
513 // We need to check all model names :/
514 local loopthrough = self.ViewModelBoneMods
515 if (!hasGarryFixedBoneScalingYet) then
516 allbones = {}
517 for i=0, vm:GetBoneCount() do
518 local bonename = vm:GetBoneName(i)
519 if (self.ViewModelBoneMods[bonename]) then
520 allbones[bonename] = self.ViewModelBoneMods[bonename]
521 else
522 allbones[bonename] = {
523 scale = Vector(1,1,1),
524 pos = Vector(0,0,0),
525 angle = Angle(0,0,0)
526 }
527 end
528 end
529
530 loopthrough = allbones
531 end
532 // !! ----------- !! //
533
534 for k, v in pairs( loopthrough ) do
535 local bone = vm:LookupBone(k)
536 if (!bone) then continue end
537
538 // !! WORKAROUND !! //
539 local s = Vector(v.scale.x,v.scale.y,v.scale.z)
540 local p = Vector(v.pos.x,v.pos.y,v.pos.z)
541 local ms = Vector(1,1,1)
542 if (!hasGarryFixedBoneScalingYet) then
543 local cur = vm:GetBoneParent(bone)
544 while(cur >= 0) do
545 local pscale = loopthrough[vm:GetBoneName(cur)].scale
546 ms = ms * pscale
547 cur = vm:GetBoneParent(cur)
548 end
549 end
550
551 s = s * ms
552 // !! ----------- !! //
553
554 if vm:GetManipulateBoneScale(bone) != s then
555 vm:ManipulateBoneScale( bone, s )
556 end
557 if vm:GetManipulateBoneAngles(bone) != v.angle then
558 vm:ManipulateBoneAngles( bone, v.angle )
559 end
560 if vm:GetManipulateBonePosition(bone) != p then
561 vm:ManipulateBonePosition( bone, p )
562 end
563 end
564 else
565 self:ResetBonePositions(vm)
566 end
567
568 end
569
570 function SWEP:ResetBonePositions(vm)
571
572 if (!vm:GetBoneCount()) then return end
573 for i=0, vm:GetBoneCount() do
574 vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
575 vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
576 vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
577 end
578
579 end
580
581 /**************************
582 Global utility code
583 **************************/
584
585 // Fully copies the table, meaning all tables inside this table are copied too and so on (normal table.Copy copies only their reference).
586 // Does not copy entities of course, only copies their reference.
587 // WARNING: do not use on tables that contain themselves somewhere down the line or you'll get an infinite loop
588 function table.FullCopy( tab )
589
590 if (!tab) then return nil end
591
592 local res = {}
593 for k, v in pairs( tab ) do
594 if (type(v) == "table") then
595 res[k] = table.FullCopy(v) // recursion ho!
596 elseif (type(v) == "Vector") then
597 res[k] = Vector(v.x, v.y, v.z)
598 elseif (type(v) == "Angle") then
599 res[k] = Angle(v.p, v.y, v.r)
600 else
601 res[k] = v
602 end
603 end
604
605 return res
606
607 end
608
609end