Advertisement
Exho

Untitled

Aug 17th, 2014
227
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.81 KB | None | 0 0
  1. if SERVER then
  2. AddCSLuaFile()
  3. end
  4.  
  5. -- The Sandbox version of my TTT Door Locker.
  6.  
  7. SWEP.PrintName = "Door Locker"
  8. SWEP.Author = "Exho"
  9. SWEP.Contact = ""
  10. SWEP.Purpose = ""
  11. SWEP.Instructions = "Left click to lock door, right click to unlock door!\n\nShoot the doors down to destroy them"
  12. SWEP.Category = "Door Locker"
  13.  
  14. SWEP.Slot = 3
  15. SWEP.SlotPos = 1
  16. SWEP.DrawAmmo = true
  17. SWEP.DrawCrosshair = true
  18. SWEP.HoldType = "normal"
  19. SWEP.Spawnable = true
  20. SWEP.AdminSpawnable = true
  21.  
  22. SWEP.Primary.Ammo = "none"
  23. SWEP.Primary.Delay = 2
  24. SWEP.Secondary.Delay = 2
  25. SWEP.Primary.ClipSize = 5
  26. SWEP.Primary.ClipMax = 5
  27. SWEP.Primary.DefaultClip = 5
  28. SWEP.Primary.Automatic = false
  29.  
  30. SWEP.ViewModel = "models/weapons/v_pistol.mdl"
  31. SWEP.WorldModel = "models/weapons/w_pistol.mdl"
  32. SWEP.ViewModelFlip = false
  33.  
  34.  
  35. SWEP.DoorHealth = 300
  36. SWEP.LockRange = 80 -- In Source Units
  37. SWEP.LockTime = 30
  38. SWEP.CooldownTime = 10
  39. SWEP.DoorLock = true -- Do the doors automatically unlock?
  40. SWEP.DoorBreak = true -- Do the doors break?
  41.  
  42. function SWEP:PrimaryAttack()
  43. --if not self:CanPrimaryAttack() then return end
  44. self:SetNextPrimaryFire(CurTime()+self.Primary.Delay)
  45. self:SetNextSecondaryFire(CurTime()+self.Secondary.Delay)
  46.  
  47. local pos = self.Owner:GetShootPos()
  48. local ang = self.Owner:GetAimVector()
  49. local tracedata = {}
  50. tracedata.start = pos
  51. tracedata.endpos = pos+(ang*self.LockRange)
  52. tracedata.filter = self.Owner
  53. local trace = util.TraceLine(tracedata)
  54.  
  55. local door = trace.Entity
  56. if DCheck( door, self.Owner ) then
  57.  
  58. if SERVER then -- I decided to do this instead of using SWEP delays.
  59. if door:GetNWBool("DoorCooldown") then
  60. local timel = timer.TimeLeft(door:EntIndex() .. "_CoolDown")
  61. local timel = math.Round( math.Clamp(timel, 0, self.CooldownTime))
  62. self.Owner:ChatPrint("This door is cooling down for " .. timel .. " more seconds!")
  63. return false
  64. end
  65. end
  66.  
  67. if not door:GetNWBool("SBLocked") then
  68. self:TakePrimaryAmmo(1)
  69.  
  70. if SERVER then
  71. door:SetNWString("SBDoorOwner", self.Owner) -- Sets the locker of that specific door
  72. door:EmitSound( "doors/door_metal_medium_close1.wav" )
  73. door:Fire("lock", "", 0)
  74. door:SetNWBool("SBLocked", true)
  75. local prehealth = self.DoorHealth
  76. door:SetNWInt(door:EntIndex() .. "_health", prehealth)
  77. math.Clamp(door:GetNWInt(door:EntIndex() .. "_health"), 0, self.DoorHealth)
  78. self.Owner:ChatPrint("Door locked!")
  79.  
  80. if self.DoorLock == true then
  81. timer.Create(door:EntIndex() .. "DoorLockedTime", self.LockTime, 1, function()
  82. door:Fire( "unlock", "", 0 )
  83. door:EmitSound( "doors/door1_move.wav" )
  84. door:SetNWBool("SBLocked", false)
  85. door:GetNWString("SBDoorOwner"):ChatPrint("One of your doors has unlocked due to time!")
  86. door:SetNWString("SBDoorOwner", nil)
  87. timer.Destroy(door:EntIndex() .. "DoorLockedTime")
  88. end)
  89. door:SetNWFloat("LockedUntil", CurTime() + self.LockTime) -- Used for the DrawHUD timer
  90. end
  91. end
  92. elseif door:GetNWBool("SBLocked") then
  93. if SERVER then
  94. self.Owner:ChatPrint("This door is already locked!")
  95. end
  96. end
  97. end
  98. end
  99.  
  100. function SWEP:SecondaryAttack()
  101. -- Allows the player to unlock their door
  102. if not self:CanSecondaryAttack() then return end
  103. self:SetNextPrimaryFire(CurTime()+self.Primary.Delay)
  104.  
  105. local pos = self.Owner:GetShootPos()
  106. local ang = self.Owner:GetAimVector()
  107. local tracedata = {}
  108. tracedata.start = pos
  109. tracedata.endpos = pos+(ang* (self.LockRange * 1.5))
  110. tracedata.filter = self.Owner
  111. local trace = util.TraceLine(tracedata)
  112.  
  113. local door = trace.Entity
  114.  
  115. if (door:GetNWBool("SBLocked") == true and DCheck( door, self.Owner ) ) then
  116. local locker = door:GetNWString("SBDoorOwner")
  117. local wannabe = self.Owner
  118.  
  119. if SERVER then
  120. if ( locker == wannabe and IsValid(locker) ) then
  121. locker:ChatPrint("Door Unlocked!")
  122. door:SetNWBool("SBLocked", false)
  123. door:EmitSound( "buttons/latchunlocked2.wav" )
  124. door:Fire( "unlock", "", 0 )
  125. timer.Destroy(door:EntIndex() .. "DoorLockedTime")
  126.  
  127. door:SetNWBool("DoorCooldown", true)
  128. timer.Create(door:EntIndex() .. "_CoolDown", self.CooldownTime, 1, function()
  129. door:SetNWBool("DoorCooldown", false)
  130. -- You lock then unlock a door and it will have to cool down for a short time before being used again.
  131. -- This is to prevent exploting of health with it
  132. end)
  133. elseif (locker ~= wannabe and IsValid(locker) ) then
  134. wannabe:ChatPrint("This is not your door to unlock!")
  135. locker:ChatPrint(Format("%s has tried to unlock your door!", wannabe:Nick() ))
  136. end
  137. end
  138. end
  139. end
  140.  
  141. function SWEP:DrawHUD()
  142. local tr = self.Owner:GetEyeTrace() -- Simplified trace because I dont care about distance
  143. local door = tr.Entity
  144. if door:GetNWBool("SBLocked") then
  145. local timeleft = math.Clamp( door:GetNWFloat("LockedUntil", 0)-CurTime(), 0, self.LockTime )
  146. local timeleft = math.Round(timeleft,1)
  147. local owner = door:GetNWString("SBDoorOwner")
  148. local dhealth = door:GetNWInt(door:EntIndex() .. "_health")
  149. self.DrawCrosshair = false -- Hides the crosshair to make things look neater
  150.  
  151. local w = ScrW()
  152. local h = ScrH()
  153. local x_axis, y_axis, width, height = w/2-w/14, h/2.8, w/7, h/20
  154. draw.RoundedBox(2, x_axis, y_axis, width , height, Color(10,10,10,200)) -- Onscreen stuff
  155. draw.SimpleText("Door locked by " ..owner:Nick(), "Trebuchet24", w/2, h/2.8 + height/2, Color(255, 40, 40,255), 1, 1)
  156. draw.RoundedBox(2, x_axis, y_axis * 1.3, width, height * 2, Color(10,10,10,200))
  157. draw.SimpleText("Health: "..dhealth, "Trebuchet24", w/2, h/2.8 + height*2.6, Color(255, 255, 255), 1, 1)
  158. if self.DoorLock == true then
  159. draw.SimpleText("Unlocks in: "..timeleft, "Trebuchet24", w/2, h/2.8 + height*3.5, Color(255, 255, 255), 1, 1)
  160. end
  161. else
  162. self.DrawCrosshair = true -- Shows the crosshair again
  163. end
  164. end
  165.  
  166. -- Runs the entity through a series of checks to make sure its the right type of door
  167. function DCheck( prop, ply )
  168. if not IsValid( prop ) then print("[Debug]: " .. tostring(prop) .. " is not valid" ) return false end
  169. -- Do NOT check if the player is valid, it causes issues with the Entity Damage function
  170.  
  171. -- These types will not work because they cannot recieve a health value no matter what I try
  172. local b_list = { "func_door", "func_door_rotating" }
  173. local object = prop:GetClass()
  174.  
  175. for h, i in pairs(b_list) do
  176. if (object == "prop_door_rotating" and IsValid(prop) and object ~= i) then
  177. return true
  178. elseif object == i then
  179. if SERVER then
  180. ply:ChatPrint("This door is incompatible with the Locker!")
  181. print("[Debug]: Player tried to use blacklisted door " .. tostring(i) )
  182. print("[Debug]: Send these to Exho if you have questions")
  183. end
  184. return false
  185. end
  186. end
  187. end
  188.  
  189. if SERVER then
  190. local function Sparkify( ent )
  191. -- Who doesnt like a little pyrotechnics eh?
  192. ent:EmitSound( "physics/wood/wood_crate_break3.wav" )
  193. local effectdata = EffectData()
  194. effectdata:SetOrigin( ent:GetPos() + ent:OBBCenter() )
  195. effectdata:SetMagnitude( 5 )
  196. effectdata:SetScale( 2 )
  197. effectdata:SetRadius( 5 )
  198. util.Effect( "Sparks", effectdata )
  199. end
  200. -- This could probably go in autorun too; it checks if the door needs to be destroyed.
  201. function DoorTakeDamage( prop, dmginfo )
  202. if ( DCheck( prop ) and prop:GetNWBool("SBLocked") ) then
  203. local doorhealth = prop:GetNWInt(prop:EntIndex() .. "_health")
  204. local dmgtaken = dmginfo:GetDamage()
  205.  
  206. prop:SetNWInt(prop:EntIndex() .. "_health", doorhealth - dmgtaken)
  207.  
  208. if doorhealth <= 0 then
  209. local d_own = prop:GetNWString("SBDoorOwner")
  210. d_own:ChatPrint("One of your doors has been destroyed!")
  211.  
  212. prop:Fire( "unlock", "", 0 )
  213. timer.Destroy(prop:EntIndex() .. "DoorLockedTime")
  214. timer.Destroy(prop:EntIndex() .. "_CoolDown")
  215. prop:SetNWBool("SBLocked", false)
  216. if self.DoorBreak == false then
  217. prop:Fire( "unlock", "", 0 )
  218. prop:Fire( "open", "", 0 )
  219. Sparkify(prop)
  220. else
  221. -- Now we create a prop version of the door to be knocked down for looks
  222. local dprop = ents.Create( "prop_physics" )
  223. dprop:SetCollisionGroup(COLLISION_GROUP_WEAPON) -- This
  224. dprop:SetMoveType(MOVETYPE_VPHYSICS) -- This
  225. dprop:SetSolid(SOLID_BBOX) -- And this, prevent against the prop from clipping horribly into the wall
  226. dprop:SetPos( prop:GetPos() + Vector(0, 0, 2))
  227. dprop:SetAngles( prop:GetAngles() )
  228. dprop:SetModel( prop:GetModel() )
  229. dprop:SetSkin( prop:GetSkin() ) -- This makes sure the doors are identical
  230. -- Removes the actual door and spawns the prop, might have to switch them around
  231. prop:Remove()
  232. dprop:Spawn()
  233. Sparkify(dprop)
  234. end
  235. end
  236. end
  237. end
  238. hook.Add("EntityTakeDamage","BreachAndClear2",DoorTakeDamage)
  239. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement