· 7 years ago · Sep 05, 2018, 02:37 PM
1// Fortifications Builder Tablet by Alydus
2// If you'd like to modify this, go ahead, but please leave credit, thank you!
3
4AddCSLuaFile()
5
6if CLIENT then
7 SWEP.PrintName = "Fortifications Tablet"
8 SWEP.Slot = 1
9 SWEP.SlotPos = 1
10 SWEP.DrawAmmo = false
11 SWEP.DrawCrosshair = false
12
13 surface.CreateFont("Alydus.FortificationsTablet.Title", {font = "Roboto Condensed", size = 70})
14 surface.CreateFont("Alydus.FortificationsTablet.Subtitle", {font = "Roboto Condensed", size = 55})
15
16 if GAMEMODE.IsSandboxDerived then
17 language.Add("SBoxLimit_fortifications", "You've hit the Fortification limit!")
18 end
19
20 language.Add("Undone_Fortification", "Undone Fortification")
21
22 language.Add("Cleanup_fortifications", "Fortifications")
23 language.Add("Cleaned_fortifications", "Cleaned up all fortifications")
24elseif SERVER then
25 CreateConVar("sbox_maxfortifications", 10)
26end
27
28SWEP.Author = "Alydus"
29SWEP.Instructions = "A utility weapon that allows the user to build fortifications."
30SWEP.Contact = ""
31SWEP.Purpose = ""
32SWEP.WorldModel = ""
33SWEP.Spawnable = true
34SWEP.AdminOnly = false
35SWEP.Category = "Alydus's Weapons"
36
37SWEP.Primary.ClipSize = -1
38SWEP.Primary.DefaultClip = -1
39SWEP.Primary.Automatic = false
40SWEP.Primary.Ammo = "none"
41SWEP.Primary.Delay = 3.5
42
43SWEP.Secondary.ClipSize = -1
44SWEP.Secondary.DefaultClip = -1
45SWEP.Secondary.Automatic = false
46SWEP.Secondary.Ammo = "none"
47SWEP.Secondary.Delay = 3.5
48
49SWEP.HoldType = "slam"
50SWEP.ViewModelFOV = 65
51SWEP.ViewModelFlip = false
52SWEP.UseHands = false
53SWEP.ViewModel = "models/weapons/v_grenade.mdl"
54SWEP.WorldModel = ""
55SWEP.ShowViewModel = true
56SWEP.ShowWorldModel = true
57SWEP.ViewModelBoneMods = {
58 ["ValveBiped.Grenade_body"] = { scale = Vector(0.009, 0.009, 0.009), pos = Vector(0, 0, 0), angle = Angle(0, 0, 0) }
59}
60
61SWEP.IronSightsPos = Vector(12.72, 0, 0.36)
62SWEP.IronSightsAng = Vector(0, 0, 0)
63
64SWEP.Fortifications = {
65 {name = "Sandbags Corner 1", model = "models/props_fortifications/sandbags_corner1.mdl"},
66 {name = "Sandbags Corner 1 Tall", model = "models/props_fortifications/sandbags_corner1_tall.mdl"},
67 {name = "Sandbags Corner 2", model = "models/props_fortifications/sandbags_corner2.mdl"},
68 {name = "Sandbags Corner 2 Tall", model = "models/props_fortifications/sandbags_corner2_tall.mdl"},
69 {name = "Sandbags Corner 3", model = "models/props_fortifications/sandbags_corner3.mdl"},
70 {name = "Sandbags Line 1", model = "models/props_fortifications/sandbags_line1.mdl"},
71 {name = "Sandbags Line 1 Tall", model = "models/props_fortifications/sandbags_line1_tall.mdl"},
72 {name = "Sandbags Line 2", model = "models/props_fortifications/sandbags_line2.mdl"},
73 {name = "Sandbags Line 2 Tall", model = "models/props_fortifications/sandbags_line2_tall.mdl"},
74 {name = "Sandbags Line 3", model = "models/props_fortifications/sandbags_line2b.mdl"},
75 {name = "Concrete Wall", model = "models/props_fortifications/concrete_wall001_96_reference.mdl"},
76 {name = "Concrete Barrier 1", model = "models/props_c17/concrete_barrier001a.mdl"},
77 {name = "Concrete Barrier 2 Small", model = "models/props_fortifications/concrete_barrier001_96_reference.mdl"},
78 {name = "Concrete Barrier 2 Large", model = "models/props_fortifications/concrete_barrier001_128_reference.mdl"},
79 {name = "Concrete Barrier 3", model = "models/jbarnes/props/concrete barricade.mdl"},
80 {name = "Small Fence", model = "models/props_c17/fence01b.mdl"},
81 {name = "Medium Fence", model = "models/props_c17/fence01a.mdl"},
82 {name = "Large Fence", model = "models/props_c17/fence03a.mdl"},
83 {name = "Small Anti-Climb Fence", model = "models/props_wasteland/exterior_fence002b.mdl",},
84 {name = "Medium Anti-Climb Fence", model = "models/props_wasteland/exterior_fence002c.mdl"},
85 {name = "Large Anti-Climb Fence", model = "models/props_wasteland/exterior_fence002d.mdl"},
86 {name = "Police Barricade Single", model = "models/props_street/police_barricade.mdl"},
87 {name = "Police Barricade Triple", model = "models/props_street/police_barricade2.mdl"},
88 {name = "Hesco Small", model = "models/static_afghan/prop_fortification_hesco_small.mdl"},
89 {name = "Hesco Tall", model = "models/iraq/ir_hesco_basket_01.mdl"},
90 {name = "Hesco Tall Leaning", model = "models/iraq/ir_hesco_basket_01b.mdl"}
91}
92
93hook.Add("Alydus.FortificationBuilderTablet.AddFortification", "Alydus_FortificationBuilderTablet_AddFortificationHook", function(fortification)
94 if fortification["name"] and fortification["model"] then
95 table.insert(SWEP.Fortifications, fortification)
96 else
97 print("Invalid fortification data, failed to add fortification. Please include name, and model.")
98 end
99end)
100
101SWEP.FortificationsModelList = {}
102
103print("Caching fortifications models for builder tablet...")
104
105for _, fortification in pairs(SWEP.Fortifications) do
106 util.PrecacheModel(fortification["model"])
107 table.insert(SWEP.FortificationsModelList, fortification["model"])
108end
109
110print("Fortifications models successfully cached.")
111
112SWEP.VElements = {
113 ["tablet"] = { type = "Model", model = "models/nirrti/tablet/tablet_sfm.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(5.714, 5.714, -3.636), angle = Angle(15.194, 118.052, -127.403), size = Vector(0.95, 0.95, 0.95), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 1, bodygroup = {} }
114}
115
116SWEP.WElements = {
117 ["tablet"] = { type = "Model", model = "models/nirrti/tablet/tablet_sfm.mdl", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(6.513, 5.714, -2.597), angle = Angle(26.882, 113.376, -127.403), size = Vector(0.82, 0.82, 0.82), color = Color(255, 255, 255, 255), surpresslightning = false, material = "", skin = 1, bodygroup = {} },
118 ["light"] = { type = "Sprite", sprite = "sprites/blueglow1", bone = "ValveBiped.Bip01_R_Hand", rel = "", pos = Vector(4.675, 1, -2.398), size = { x = 1.729, y = 1.729 }, color = Color(255, 255, 255, 255), nocull = true, additive = true, vertexalpha = true, vertexcolor = true, ignorez = false}
119}
120
121
122
123------------
124
125
126
127-- Playerdeath initialspawn keypress hook rewrite (better write)
128
129
130
131
132-----------------
133
134
135
136
137if SERVER then
138
139hook.Add("PlayerInitialSpawn", "HACK_SetupVars", function(ply)
140 ply:SetNWBool("IsHacking", false)
141 end)
142
143
144
145hook.Add("PlayerDeath","destroytimeronrespawnwhilevuild", function(ply)
146ply:SetNWBool("IsHacking", false)
147if ( timer.Exists("HACK_StartedHacking"..ply:UniqueID()) ) then
148ply.fortificationPlacedHologram:Remove()
149timer.Destroy("HACK_StartedHacking"..ply:UniqueID())
150end
151end)
152util.AddNetworkString("HACK_SetTimer")
153
154
155
156 hook.Add("KeyPress", "Alydus_KeyPress_HandleBuildTabletHologramFinished", function(ply, key)
157
158
159
160
161
162 if key == IN_USE and IsValid(ply) and ply:Alive() and IsValid(ply:GetActiveWeapon()) and ply:GetActiveWeapon():GetClass() == "alydus_fortificationbuildertablet" and ply:GetActiveWeapon().fortificationSelection then
163
164
165 storedpos = ply:GetEyeTrace().HitPos - ply:GetEyeTrace().HitNormal * ply.fortificationHologram:OBBMins().z
166 storedangles = Angle(0, ply:EyeAngles().y - 180, 0)
167 storedmodel = ply:GetActiveWeapon().Fortifications[ply:GetActiveWeapon().fortificationSelection]["model"]
168
169
170 if ( timer.Exists("HACK_StartedHacking"..ply:UniqueID()) ) then return end
171
172 if ply:GetCount("fortifications") < GetConVar("sbox_maxfortifications"):GetInt() then
173 if (ply:GetEyeTrace().Entity and ply:GetEyeTrace().Entity:IsPlayer() or ply:GetEyeTrace().HitPos:Distance(ply:GetPos()) >= 250) or ply:Crouching() or (IsValid(ply:GetEyeTrace().Entity) and table.HasValue(ply:GetActiveWeapon().FortificationsModelList, ply:GetEyeTrace().Entity:GetModel())) or hook.Call("Alydus.FortificationBuilderTablet.CanBuildFortification", ply) or (IsValid(ply:GetActiveWeapon()) and ply:GetActiveWeapon():GetClass() == "alydus_fortificationbuildertablet" and ply:GetActiveWeapon():GetNWBool("tabletBootup", false) == true) then
174 ply:ChatPrint("Failed to deploy fortification.")
175 else
176
177
178
179
180 if not IsValid(ply.fortificationPlacedHologram) then
181 ply.fortificationPlacedHologram = ents.Create("prop_physics")
182 if IsValid(ply.fortificationPlacedHologram) then
183 ply.fortificationPlacedHologram:SetAngles(storedangles)
184 ply.fortificationPlacedHologram:SetPos(storedpos)
185 ply.fortificationPlacedHologram:SetColor(Color(46, 204, 113, 200))
186 ply.fortificationPlacedHologram:SetModel(storedmodel)
187 ply.fortificationPlacedHologram:SetCollisionGroup(COLLISION_GROUP_IN_VEHICLE)
188 ply.fortificationPlacedHologram:SetRenderMode(RENDERMODE_TRANSALPHA)
189 ply.fortificationPlacedHologram:Spawn()
190 else
191 ply.fortificationPlacedHologram = nil
192 end
193 end
194
195 local physhologram = ply.fortificationPlacedHologram:GetPhysicsObject()
196 if IsValid(physhologram) then
197 physhologram:SetMass(50000)
198 physhologram:EnableMotion(false)
199 end
200
201
202
203 net.Start("HACK_SetTimer")
204 net.WriteFloat(CurTime() + 2)
205 net.WriteEntity(ply)
206 net.Broadcast()
207 ply:SetNWBool("IsHacking", true)
208 timer.Create("HACK_StartedHacking"..ply:UniqueID(), 2, 1, function()
209 ply:SetNWBool("IsHacking", false)
210 ply.fortification = ents.Create("prop_physics")
211 ply.fortification:SetAngles(ply.fortificationPlacedHologram:GetAngles()) --here you should make a hologram shared function that gets the setting from the hologram prebuild
212 ply.fortification:SetPos(ply.fortificationPlacedHologram:GetPos())
213 ply.fortification:SetModel(ply.fortificationPlacedHologram:GetModel())
214 ply.fortification:Spawn()
215 ply.fortification:SetGravity(150)
216 ply.fortification.isPlayerPlacedFortification = ply
217 ply.fortification:EmitSound("physics/concrete/rock_impact_hard" .. math.random(1, 6) .. ".wav")
218 ply.fortification:SetColor(Color(255, 255, 255, 255))
219 ply.fortification:SetCollisionGroup(COLLISION_GROUP_NONE)
220 ply.fortification:SetRenderMode(RENDERMODE_TRANSALPHA)
221
222 ply.fortificationPlacedHologram:Remove()
223
224 ply:AddCount("fortifications", ply.fortification)
225 ply:AddCleanup("fortifications", ply.fortification)
226
227
228 local phys = ply.fortification:GetPhysicsObject()
229 if IsValid(phys) then
230 phys:SetMass(50000)
231 phys:EnableMotion(false)
232 end
233
234
235 if table.HasValue({"sandbox", "darkrp", "starwarsrp"}, engine.ActiveGamemode()) then
236 undo.Create("fortification")
237 undo.AddEntity(ply.fortification)
238 undo.SetPlayer(ply)
239 undo.Finish()
240 end
241
242 timer.Destroy("HACK_StartedHacking"..ply:UniqueID())
243 end)
244 end
245 else
246 ply:LimitHit("fortifications")
247 end
248
249 end
250
251 end)
252
253 hook.Add("PlayerSwitchWeapon", "Alydus_PlayerSwitchWeapon_FortificationBuilderTabletBootup", function(ply, oldWep, newWep)
254 if newWep:GetClass() == "alydus_fortificationbuildertablet" and newWep:GetNWBool("tabletBootup", false) != true then
255 newWep:SetNWBool("tabletBootup", true)
256 newWep.fortificationSelection = newWep.fortificationSelection or 1
257 ply:EmitSound("ambient/machines/thumper_startup1.wav")
258 timer.Simple(2.5, function()
259 if ply:GetNWBool("tabletBootup", false) == false and ply:HasWeapon("alydus_fortificationbuildertablet") then
260 ply:EmitSound("npc/scanner/combat_scan4.wav")
261 newWep:SetNWBool("tabletBootup", false)
262 end
263 end)
264 elseif ply:HasWeapon("alydus_fortificationbuildertablet") and IsValid(oldWep) and oldWep:GetClass() == "alydus_fortificationbuildertablet" then
265 ply:EmitSound("npc/roller/mine/combine_mine_deactivate1.wav")
266
267 if ply.fortificationHologram != nil and IsValid(ply.fortificationHologram) then
268 ply.fortificationHologram:Remove()
269 ply.fortificationHologram = nil
270 end
271 end
272 end)
273 hook.Add("PlayerTick", "Alydus_Think_FortificationBuilderTabletHologram", function(ply, mv)
274 local wep = ply:GetActiveWeapon()
275 local ang = ply:GetAngles()
276 local tr = ply:GetEyeTrace()
277
278 if IsValid(ply) and ply:Alive() and ply:HasWeapon("alydus_fortificationbuildertablet") and IsValid(wep) and wep:GetClass() == "alydus_fortificationbuildertablet" and wep:GetNWBool("tabletBootup", false) == false and wep.fortificationSelection != nil then
279 if not IsValid(ply.fortificationHologram) then
280 ply.fortificationHologram = ents.Create("prop_physics")
281 if IsValid(ply.fortificationHologram) then
282 ply.fortificationHologram:SetAngles(Angle(0, ply:EyeAngles().y - 180, 0))
283 ply.fortificationHologram:SetPos(tr.HitPos - tr.HitNormal * ply.fortificationHologram:OBBMins().z)
284 ply.fortificationHologram:SetColor(Color(46, 204, 113, 200))
285 ply.fortificationHologram:SetModel(wep.Fortifications[wep.fortificationSelection]["model"])
286 ply.fortificationHologram:SetCollisionGroup(COLLISION_GROUP_IN_VEHICLE)
287 ply.fortificationHologram:SetRenderMode(RENDERMODE_TRANSALPHA)
288 ply.fortificationHologram:Spawn()
289 ply.fortificationHologram:SetNWString("alydusFortificationHologramName", wep.Fortifications[wep.fortificationSelection]["name"])
290 ply.fortificationHologram:EmitSound("physics/concrete/rock_impact_hard1.wav")
291 else
292 ply.fortificationHologram = nil
293 end
294 elseif IsValid(ply.fortificationHologram) then
295 if ply:Crouching() or
296 --ply:GetVelocity():Length() > 15
297 (IsValid(tr.Entity) and table.HasValue(wep.FortificationsModelList, tr.Entity:GetModel())) then
298 ply.fortificationHologram:SetColor(Color(255, 255, 255, 0))
299 else
300 if ply.fortificationHologram:GetModel() != wep.Fortifications[wep.fortificationSelection]["model"] then
301 ply.fortificationHologram:SetModel(wep.Fortifications[wep.fortificationSelection]["model"])
302 ply.fortificationHologram:SetNWString("alydusFortificationHologramName", wep.Fortifications[wep.fortificationSelection]["name"])
303 end
304 ply.fortificationHologram:SetPos(tr.HitPos - tr.HitNormal * ply.fortificationHologram:OBBMins().z)
305 ply.fortificationHologram:SetAngles(Angle(0, ply:EyeAngles().y - 180, 0))
306 if tr.HitPos:Distance(ply:GetPos()) >= 250 then
307 ply.fortificationHologram:SetColor(Color(255, 255, 255, 0))
308 elseif ply.fortificationHologram:GetColor().a == 0 then
309 ply.fortificationHologram:SetColor(Color(46, 204, 113, 200))
310 end
311 end
312 end
313 elseif ply.fortificationHologram != nil and IsValid(ply.fortificationHologram) then
314 ply.fortificationHologram:Remove()
315 ply.fortificationHologram = nil
316 end
317 end)
318else
319 hook.Add("PostDrawTranslucentRenderables","Lobby_PostDrawOpaqueRenderables_EntityDisplays", function()
320 local ply = LocalPlayer()
321
322 -- Selected Fortification Display
323 if IsValid(ply) and ply:Alive() and not ply:Crouching()
324 --and ply:GetVelocity():Length() < 25 --draw text while moving
325
326 then
327 for _, v in pairs(ents.GetAll()) do
328 if IsValid(v) and v:GetPos():Distance(LocalPlayer():GetPos()) <= 250 then
329 if v:GetClass() == "prop_physics" and v:GetNWString("alydusFortificationHologramName", false) != false then
330 local offset = Vector(0, 0, 50)
331 local ang = LocalPlayer():EyeAngles()
332 local pos = v:GetPos() + offset + ang:Up()
333
334 ang:RotateAroundAxis(ang:Forward(), 90)
335 ang:RotateAroundAxis(ang:Right(), 90)
336
337 local fade = math.abs(math.sin(CurTime() * 3))
338
339 cam.Start3D2D(pos, Angle(0, ang.y, 90), 0.10)
340 draw.DrawText("Fortification Selection", "Alydus.FortificationsTablet.Title", 0, 0, Color(255, 255, 255), TEXT_ALIGN_CENTER)
341 draw.DrawText(v:GetNWString("alydusFortificationHologramName", "Unknown Fortification"), "Alydus.FortificationsTablet.Subtitle", 0, 60, Color(150, 150, 150), TEXT_ALIGN_CENTER)
342 cam.End3D2D()
343 end
344 end
345 end
346 end
347 end)
348end
349
350function SWEP:PrimaryAttack()
351 if SERVER then
352 local ply = self:GetOwner()
353 if IsValid(ply) and ply:Alive() and IsValid(ply.fortificationHologram) and self.fortificationSelection != nil and not ply:Crouching()
354 -- and ply:GetVelocity():Length() < 25 --allow to change baricade type while moving
355
356 then
357 if ply:GetEyeTrace().HitPos:Distance(ply:GetPos()) >= 250 then
358 ply:SendLua("surface.PlaySound(\"common/warning.wav\")")
359 return
360 end
361 if self.Fortifications[self.fortificationSelection + 1] then
362 self.fortificationSelection = self.fortificationSelection + 1
363 else
364 self.fortificationSelection = 1
365 end
366 ply.fortificationHologram:EmitSound("physics/concrete/rock_impact_hard1.wav")
367 end
368 end
369end
370
371function SWEP:SecondaryAttack()
372 if SERVER then
373 local ply = self:GetOwner()
374 if IsValid(ply) and ply:Alive() and IsValid(ply.fortificationHologram) and self.fortificationSelection != nil and not ply:Crouching()
375 --and ply:GetVelocity():Length() < 25 --allow to change baricade type while moving
376
377 then
378 if ply:GetEyeTrace().HitPos:Distance(ply:GetPos()) >= 250 then
379 ply:SendLua("surface.PlaySound(\"common/warning.wav\")")
380 return
381 end
382 if self.Fortifications[self.fortificationSelection - 1] then
383 self.fortificationSelection = self.fortificationSelection - 1
384 else
385 self.fortificationSelection = table.Count(self.Fortifications)
386 end
387 ply.fortificationHologram:EmitSound("physics/concrete/rock_impact_hard3.wav")
388 end
389 end
390end
391
392function SWEP:Reload()
393 if SERVER then
394 local ply = self:GetOwner()
395 if not self.Owner:KeyPressed(IN_RELOAD) then
396 return
397 end
398 if IsValid(ply) and ply:Alive() and IsValid(ply:GetActiveWeapon()) and ply:GetActiveWeapon():GetClass() == "alydus_fortificationbuildertablet" and ply:GetActiveWeapon().fortificationSelection then
399 if ply:GetEyeTrace().Entity.isPlayerPlacedFortification == ply then
400 ply:GetEyeTrace().Entity:EmitSound("physics/concrete/rock_impact_hard" .. math.random(1, 6) .. ".wav")
401 ply:GetEyeTrace().Entity:Remove()
402 end
403 end
404 return
405 end
406end
407----------------------------------------------------------------------
408--------------------------------------------------------------------------------------------------------------------------------------------
409--------------------------------------------------------------------------------------------------------------------------------------------
410--------------------------------------------------------------------------------------------------------------------------------------------
411--------------------------------------------------------------------------------------------------------------------------------------------
412--------------------------------------------------------------------------------------------------------------------------------------------
413--------------------------------------------------------------------------------------------------------------------------------------------
414--------------------------------------------------------------------------------------------------------------------------------------------
415--------------------------------------------------------------------------------------------------------------------------------------------
416--------------------------------------------------------------------------------------------------------------------------------------------
417--------------------------------------------------------------------------------------------------------------------------------------------
418--------------------------------------------------------------------------------------------------------------------------------------------
419--------------------------------------------------------------------------------------------------------------------------------------------
420--------------------------------------------------------------------------------------------------------------------------------------------
421----------------------------------------------------------------------
422if CLIENT then
423 local Timer = 0
424
425 surface.CreateFont("HACK_Font_1", {
426 font = "Arial",
427 extended = false,
428 size = 24,
429 weight = 1000,
430 })
431
432 net.Receive("HACK_SetTimer", function()
433 local time = net.ReadFloat()
434 local ply = net.ReadEntity()
435 ply.Timer = time
436 end)
437
438
439
440
441 hook.Add("PostDrawOpaqueRenderables", "HACK_DrawBar", function()
442 local ply = LocalPlayer()
443 local CurTime = CurTime()
444
445 for k, v in pairs(player.GetAll()) do
446 if ( ply:GetPos():Distance(v:GetPos()) < 1100 and v.Timer and v.Timer > CurTime and v:GetNWBool("IsHacking") ) then
447 local pos = v:GetPos()
448 local PlayersAngle = ply:GetAngles()
449 local ang = Angle( 0, PlayersAngle.y - 180 , 0 )
450
451 ang:RotateAroundAxis(ang:Right(), -90)
452 ang:RotateAroundAxis(ang:Up(), 90)
453
454 local v1 = 200/2
455 local v2 = (v.Timer - CurTime)*v1
456 local v3 = v2
457
458 cam.Start3D2D(pos, ang, 0.2)
459 surface.SetDrawColor(Color(30,30,30,255))
460 surface.DrawRect(-100,-420,200,25)
461
462 surface.SetDrawColor(Color(33,255,0,255))
463 surface.DrawRect(-100,-420,200-v3,25)
464
465 draw.SimpleTextOutlined("Platziere Barrikade...", "HACK_Font_1", 0, -450, Color(255,255,255,255), TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP, 1, Color(0,0,0,255))
466 cam.End3D2D()
467 end
468 end
469 end)
470----------------------------------------------------------------------
471--------------------------------------------------------------------------------------------------------------------------------------------
472--------------------------------------------------------------------------------------------------------------------------------------------
473--------------------------------------------------------------------------------------------------------------------------------------------
474--------------------------------------------------------------------------------------------------------------------------------------------
475--------------------------------------------------------------------------------------------------------------------------------------------
476--------------------------------------------------------------------------------------------------------------------------------------------
477--------------------------------------------------------------------------------------------------------------------------------------------
478----------------------------------------------------------------------
479
480 language.Add("#Undone_Fortification", "Undone Fortification")
481
482 local wrenchMat = Material("alydus/icons/wrench.png")
483 local nextMat = Material("alydus/icons/next.png")
484 local lastMat = Material("alydus/icons/last.png")
485 local shieldMat = Material("alydus/icons/shield.png")
486 local refreshMat = Material("alydus/icons/refresh.png")
487
488 local useBind = string.upper(input.LookupBinding("+use")) or "E"
489 local reloadBind = string.upper(input.LookupBinding("+reload")) or "R"
490
491 function SWEP:PostDrawViewModel(vm, wep, ply)
492 if IsValid(vm) then
493 local atch = vm:GetBoneMatrix(vm:LookupBone("ValveBiped.Bip01_R_Hand"))
494 local pos, ang = vm:GetBonePosition(vm:LookupBone("ValveBiped.Bip01_R_Hand")), vm:GetBoneMatrix(vm:LookupBone("ValveBiped.Bip01_R_Hand")):GetAngles()
495 ang:RotateAroundAxis(ang:Right(), 90)
496
497 cam.Start3D2D(pos - ang:Right() * 3 - ang:Forward() * 8.25 + ang:Right() * 7.4, Angle(0, ply:EyeAngles().y, ang.z) + Angle(180, 90, 160), 0.01)
498 surface.SetDrawColor(255, 255, 255, 255)
499 if self:GetNWBool("tabletBootup", false) == false then
500 draw.SimpleText("Fortification Builder", "Alydus.FortificationsTablet.Title", 15, 0, Color(255, 255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
501
502 surface.SetMaterial(nextMat)
503 surface.DrawTexturedRect(230, 42, 40, 40)
504 surface.SetMaterial(lastMat)
505 surface.DrawTexturedRect(-235, 38, 40, 40)
506
507 draw.SimpleText("LMB: Last | RMB: Next", "Alydus.FortificationsTablet.Subtitle", 15, 60, Color(150, 150, 150, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
508
509 surface.SetMaterial(wrenchMat)
510 surface.DrawTexturedRect(-215, 98, 40, 40)
511
512 draw.SimpleText(" [" .. useBind .. "]: Build | [" .. reloadBind .. "]: Remove", "Alydus.FortificationsTablet.Subtitle", 15, 120, Color(150, 150, 150, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
513
514 surface.SetMaterial(shieldMat)
515 surface.DrawTexturedRect(-237, 162, 40, 40)
516
517 draw.SimpleText(" " .. table.Count(self.Fortifications) .. " Fortifications Available", "Alydus.FortificationsTablet.Subtitle", 15, 180, Color(100, 100, 100, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
518 else
519 draw.SimpleText("Fortification Builder", "Alydus.FortificationsTablet.Title", 15, 30, Color(255, 255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
520
521 surface.SetMaterial(refreshMat)
522 surface.DrawTexturedRect(-130, 70, 40, 40)
523
524 draw.SimpleText(" Booting up...", "Alydus.FortificationsTablet.Subtitle", 15, 90, Color(150, 150, 150, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
525 end
526 cam.End3D2D()
527 end
528 end
529end
530
531function SWEP:GetViewModelPosition( pos, ang )
532 self.SwayScale = 0;
533 self.BobScale = 0.1;
534
535 return pos, ang;
536end
537
538function SWEP:Initialize()
539 self:SetHoldType("slam")
540 if CLIENT then
541 self.VElements = table.FullCopy( self.VElements )
542 self.WElements = table.FullCopy( self.WElements )
543 self.ViewModelBoneMods = table.FullCopy( self.ViewModelBoneMods )
544
545 self:CreateModels(self.VElements)
546 self:CreateModels(self.WElements)
547
548 if IsValid(self.Owner) then
549 local vm = self.Owner:GetViewModel()
550 if IsValid(vm) then
551 self:ResetBonePositions(vm)
552
553 if (self.ShowViewModel == nil or self.ShowViewModel) then
554 vm:SetColor(Color(255,255,255,255))
555 else
556 vm:SetColor(Color(255,255,255,1))
557 vm:SetMaterial("Debug/hsv")
558 end
559 end
560 end
561
562 end
563
564end
565
566function SWEP:Holster()
567
568 if CLIENT and IsValid(self.Owner) then
569 local vm = self.Owner:GetViewModel()
570 if IsValid(vm) then
571 self:ResetBonePositions(vm)
572 end
573 end
574
575 return true
576end
577
578function SWEP:OnRemove()
579 self:Holster()
580end
581
582if CLIENT then
583
584 SWEP.vRenderOrder = nil
585 function SWEP:ViewModelDrawn()
586
587 local vm = self.Owner:GetViewModel()
588 if !IsValid(vm) then return end
589
590 if (!self.VElements) then return end
591
592 self:UpdateBonePositions(vm)
593
594 if (!self.vRenderOrder) then
595
596 // we build a render order because sprites need to be drawn after models
597 self.vRenderOrder = {}
598
599 for k, v in pairs( self.VElements ) do
600 if (v.type == "Model") then
601 table.insert(self.vRenderOrder, 1, k)
602 elseif (v.type == "Sprite" or v.type == "Quad") then
603 table.insert(self.vRenderOrder, k)
604 end
605 end
606
607 end
608
609 for k, name in ipairs( self.vRenderOrder ) do
610
611 local v = self.VElements[name]
612 if (!v) then self.vRenderOrder = nil break end
613 if (v.hide) then continue end
614
615 local model = v.modelEnt
616 local sprite = v.spriteMaterial
617
618 if (!v.bone) then continue end
619
620 local pos, ang = self:GetBoneOrientation( self.VElements, v, vm )
621
622 if (!pos) then continue end
623
624 if (v.type == "Model" and IsValid(model)) then
625
626 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
627 ang:RotateAroundAxis(ang:Up(), v.angle.y)
628 ang:RotateAroundAxis(ang:Right(), v.angle.p)
629 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
630
631 model:SetAngles(ang)
632 //model:SetModelScale(v.size)
633 local matrix = Matrix()
634 matrix:Scale(v.size)
635 model:EnableMatrix( "RenderMultiply", matrix )
636
637 if (v.material == "") then
638 model:SetMaterial("")
639 elseif (model:GetMaterial() != v.material) then
640 model:SetMaterial( v.material )
641 end
642
643 if (v.skin and v.skin != model:GetSkin()) then
644 model:SetSkin(v.skin)
645 end
646
647 if (v.bodygroup) then
648 for k, v in pairs( v.bodygroup ) do
649 if (model:GetBodygroup(k) != v) then
650 model:SetBodygroup(k, v)
651 end
652 end
653 end
654
655 if (v.surpresslightning) then
656 render.SuppressEngineLighting(true)
657 end
658
659 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
660 render.SetBlend(v.color.a/255)
661 model:DrawModel()
662 render.SetBlend(1)
663 render.SetColorModulation(1, 1, 1)
664
665 if (v.surpresslightning) then
666 render.SuppressEngineLighting(false)
667 end
668
669 elseif (v.type == "Sprite" and sprite) then
670
671 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
672 render.SetMaterial(sprite)
673 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
674
675 elseif (v.type == "Quad" and v.draw_func) then
676
677 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
678 ang:RotateAroundAxis(ang:Up(), v.angle.y)
679 ang:RotateAroundAxis(ang:Right(), v.angle.p)
680 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
681
682 cam.Start3D2D(drawpos, ang, v.size)
683 v.draw_func( self )
684 cam.End3D2D()
685
686 end
687
688 end
689
690 end
691
692 SWEP.wRenderOrder = nil
693 function SWEP:DrawWorldModel()
694
695 if (self.ShowWorldModel == nil or self.ShowWorldModel) then
696 self:DrawModel()
697 end
698
699 if (!self.WElements) then return end
700
701 if (!self.wRenderOrder) then
702
703 self.wRenderOrder = {}
704
705 for k, v in pairs( self.WElements ) do
706 if (v.type == "Model") then
707 table.insert(self.wRenderOrder, 1, k)
708 elseif (v.type == "Sprite" or v.type == "Quad") then
709 table.insert(self.wRenderOrder, k)
710 end
711 end
712
713 end
714
715 if (IsValid(self.Owner)) then
716 bone_ent = self.Owner
717 else
718 // when the weapon is dropped
719 bone_ent = self
720 end
721
722 for k, name in pairs( self.wRenderOrder ) do
723
724 local v = self.WElements[name]
725 if (!v) then self.wRenderOrder = nil break end
726 if (v.hide) then continue end
727
728 local pos, ang
729
730 if (v.bone) then
731 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent )
732 else
733 pos, ang = self:GetBoneOrientation( self.WElements, v, bone_ent, "ValveBiped.Bip01_R_Hand" )
734 end
735
736 if (!pos) then continue end
737
738 local model = v.modelEnt
739 local sprite = v.spriteMaterial
740
741 if (v.type == "Model" and IsValid(model)) then
742
743 model:SetPos(pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z )
744 ang:RotateAroundAxis(ang:Up(), v.angle.y)
745 ang:RotateAroundAxis(ang:Right(), v.angle.p)
746 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
747
748 model:SetAngles(ang)
749 //model:SetModelScale(v.size)
750 local matrix = Matrix()
751 matrix:Scale(v.size)
752 model:EnableMatrix( "RenderMultiply", matrix )
753
754 if (v.material == "") then
755 model:SetMaterial("")
756 elseif (model:GetMaterial() != v.material) then
757 model:SetMaterial( v.material )
758 end
759
760 if (v.skin and v.skin != model:GetSkin()) then
761 model:SetSkin(v.skin)
762 end
763
764 if (v.bodygroup) then
765 for k, v in pairs( v.bodygroup ) do
766 if (model:GetBodygroup(k) != v) then
767 model:SetBodygroup(k, v)
768 end
769 end
770 end
771
772 if (v.surpresslightning) then
773 render.SuppressEngineLighting(true)
774 end
775
776 render.SetColorModulation(v.color.r/255, v.color.g/255, v.color.b/255)
777 render.SetBlend(v.color.a/255)
778 model:DrawModel()
779 render.SetBlend(1)
780 render.SetColorModulation(1, 1, 1)
781
782 if (v.surpresslightning) then
783 render.SuppressEngineLighting(false)
784 end
785
786 elseif (v.type == "Sprite" and sprite) then
787
788 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
789 render.SetMaterial(sprite)
790 render.DrawSprite(drawpos, v.size.x, v.size.y, v.color)
791
792 elseif (v.type == "Quad" and v.draw_func) then
793
794 local drawpos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
795 ang:RotateAroundAxis(ang:Up(), v.angle.y)
796 ang:RotateAroundAxis(ang:Right(), v.angle.p)
797 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
798
799 cam.Start3D2D(drawpos, ang, v.size)
800 v.draw_func( self )
801 cam.End3D2D()
802
803 end
804
805 end
806
807 end
808
809 function SWEP:GetBoneOrientation( basetab, tab, ent, bone_override )
810
811 local bone, pos, ang
812 if (tab.rel and tab.rel != "") then
813
814 local v = basetab[tab.rel]
815
816 if (!v) then return end
817
818 // Technically, if there exists an element with the same name as a bone
819 // you can get in an infinite loop. Let's just hope nobody's that stupid.
820 pos, ang = self:GetBoneOrientation( basetab, v, ent )
821
822 if (!pos) then return end
823
824 pos = pos + ang:Forward() * v.pos.x + ang:Right() * v.pos.y + ang:Up() * v.pos.z
825 ang:RotateAroundAxis(ang:Up(), v.angle.y)
826 ang:RotateAroundAxis(ang:Right(), v.angle.p)
827 ang:RotateAroundAxis(ang:Forward(), v.angle.r)
828
829 else
830
831 bone = ent:LookupBone(bone_override or tab.bone)
832
833 if (!bone) then return end
834
835 pos, ang = Vector(0,0,0), Angle(0,0,0)
836 local m = ent:GetBoneMatrix(bone)
837 if (m) then
838 pos, ang = m:GetTranslation(), m:GetAngles()
839 end
840
841 if (IsValid(self.Owner) and self.Owner:IsPlayer() and
842 ent == self.Owner:GetViewModel() and self.ViewModelFlip) then
843 ang.r = -ang.r // Fixes mirrored models
844 end
845
846 end
847
848 return pos, ang
849 end
850
851 function SWEP:CreateModels( tab )
852
853 if (!tab) then return end
854
855 // Create the clientside models here because Garry says we can't do it in the render hook
856 for k, v in pairs( tab ) do
857 if (v.type == "Model" and v.model and v.model != "" and (!IsValid(v.modelEnt) or v.createdModel != v.model) and
858 string.find(v.model, ".mdl") and file.Exists (v.model, "GAME") ) then
859
860 v.modelEnt = ClientsideModel(v.model, RENDER_GROUP_VIEW_MODEL_OPAQUE)
861 if (IsValid(v.modelEnt)) then
862 v.modelEnt:SetPos(self:GetPos())
863 v.modelEnt:SetAngles(self:GetAngles())
864 v.modelEnt:SetParent(self)
865 v.modelEnt:SetNoDraw(true)
866 v.createdModel = v.model
867 else
868 v.modelEnt = nil
869 end
870
871 elseif (v.type == "Sprite" and v.sprite and v.sprite != "" and (!v.spriteMaterial or v.createdSprite != v.sprite)
872 and file.Exists ("materials/"..v.sprite..".vmt", "GAME")) then
873
874 local name = v.sprite.."-"
875 local params = { ["$basetexture"] = v.sprite }
876 // make sure we create a unique name based on the selected options
877 local tocheck = { "nocull", "additive", "vertexalpha", "vertexcolor", "ignorez" }
878 for i, j in pairs( tocheck ) do
879 if (v[j]) then
880 params["$"..j] = 1
881 name = name.."1"
882 else
883 name = name.."0"
884 end
885 end
886
887 v.createdSprite = v.sprite
888 v.spriteMaterial = CreateMaterial(name,"UnlitGeneric",params)
889
890 end
891 end
892
893 end
894
895 local allbones
896 local hasGarryFixedBoneScalingYet = false
897
898 function SWEP:UpdateBonePositions(vm)
899
900 if self.ViewModelBoneMods then
901
902 if (!vm:GetBoneCount()) then return end
903
904 local loopthrough = self.ViewModelBoneMods
905 if (!hasGarryFixedBoneScalingYet) then
906 allbones = {}
907 for i=0, vm:GetBoneCount() do
908 local bonename = vm:GetBoneName(i)
909 if (self.ViewModelBoneMods[bonename]) then
910 allbones[bonename] = self.ViewModelBoneMods[bonename]
911 else
912 allbones[bonename] = {
913 scale = Vector(1,1,1),
914 pos = Vector(0,0,0),
915 angle = Angle(0,0,0)
916 }
917 end
918 end
919
920 loopthrough = allbones
921 end
922
923 for k, v in pairs( loopthrough ) do
924 local bone = vm:LookupBone(k)
925 if (!bone) then continue end
926
927 local s = Vector(v.scale.x,v.scale.y,v.scale.z)
928 local p = Vector(v.pos.x,v.pos.y,v.pos.z)
929 local ms = Vector(1,1,1)
930 if (!hasGarryFixedBoneScalingYet) then
931 local cur = vm:GetBoneParent(bone)
932 while(cur >= 0) do
933 local pscale = loopthrough[vm:GetBoneName(cur)].scale
934 ms = ms * pscale
935 cur = vm:GetBoneParent(cur)
936 end
937 end
938
939 s = s * ms
940
941 if vm:GetManipulateBoneScale(bone) != s then
942 vm:ManipulateBoneScale( bone, s )
943 end
944 if vm:GetManipulateBoneAngles(bone) != v.angle then
945 vm:ManipulateBoneAngles( bone, v.angle )
946 end
947 if vm:GetManipulateBonePosition(bone) != p then
948 vm:ManipulateBonePosition( bone, p )
949 end
950 end
951 else
952 self:ResetBonePositions(vm)
953 end
954
955 end
956
957 function SWEP:ResetBonePositions(vm)
958
959 if (!vm:GetBoneCount()) then return end
960 for i=0, vm:GetBoneCount() do
961 vm:ManipulateBoneScale( i, Vector(1, 1, 1) )
962 vm:ManipulateBoneAngles( i, Angle(0, 0, 0) )
963 vm:ManipulateBonePosition( i, Vector(0, 0, 0) )
964 end
965
966 end
967
968 function table.FullCopy( tab )
969
970 if (!tab) then return nil end
971
972 local res = {}
973 for k, v in pairs( tab ) do
974 if (type(v) == "table") then
975 res[k] = table.FullCopy(v)
976 elseif (type(v) == "Vector") then
977 res[k] = Vector(v.x, v.y, v.z)
978 elseif (type(v) == "Angle") then
979 res[k] = Angle(v.p, v.y, v.r)
980 else
981 res[k] = v
982 end
983 end
984
985 return res
986
987 end
988
989end