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