Advertisement
SHCREW

simplifyadmin

Oct 23rd, 2020
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.20 KB | None | 0 0
  1. local stopSpectating, startFreeRoam
  2. local isSpectating = false
  3. local specEnt
  4. local thirdperson = true
  5. local isRoaming = false
  6. local roamPos -- the position when roaming free
  7. local roamVelocity = Vector(0)
  8. local thirdPersonDistance = 100
  9.  
  10. --[[---------------------------------------------------------------------------
  11. startHooks
  12. FAdmin tab buttons
  13. ---------------------------------------------------------------------------]]
  14. hook.Add("Initialize", "FSpectate", function()
  15. surface.CreateFont("UiBold", {
  16. size = 16,
  17. weight = 800,
  18. antialias = true,
  19. shadow = false,
  20. font = "Default"
  21. })
  22.  
  23. if not FAdmin then return end
  24.  
  25. FAdmin.StartHooks["zzSpectate"] = function()
  26. FAdmin.Commands.AddCommand("Spectate", nil, "<Player>")
  27.  
  28. -- Right click option
  29. FAdmin.ScoreBoard.Main.AddPlayerRightClick("Spectate", function(ply)
  30. if not IsValid(ply) then return end
  31. RunConsoleCommand("FSpectate", ply:UserID())
  32. end)
  33.  
  34. local canSpectate = false
  35.  
  36. CAMI.PlayerHasAccess(LocalPlayer(), "FSpectate", function(b, _)
  37. canSpectate = true
  38. end)
  39.  
  40. -- Spectate option in player menu
  41. FAdmin.ScoreBoard.Player:AddActionButton("Spectate", "fadmin/icons/spectate", Color(0, 200, 0, 255), function(ply) return canSpectate and ply ~= LocalPlayer() end, function(ply)
  42. if not IsValid(ply) then return end
  43. RunConsoleCommand("FSpectate", ply:UserID())
  44. end)
  45. end
  46. end)
  47.  
  48. --[[---------------------------------------------------------------------------
  49. Get the thirdperson position
  50. ---------------------------------------------------------------------------]]
  51. local function getThirdPersonPos(ent)
  52. local aimvector = LocalPlayer():GetAimVector()
  53. local startPos = ent:IsPlayer() and ent:GetShootPos() or ent:LocalToWorld(ent:OBBCenter())
  54. local endpos = startPos - aimvector * thirdPersonDistance
  55.  
  56. local tracer = {
  57. start = startPos,
  58. endpos = endpos,
  59. filter = specEnt
  60. }
  61.  
  62. local trace = util.TraceLine(tracer)
  63.  
  64. return trace.HitPos + trace.HitNormal * 10
  65. end
  66.  
  67. --[[---------------------------------------------------------------------------
  68. Get the CalcView table
  69. ---------------------------------------------------------------------------]]
  70. local view = {}
  71.  
  72. local function getCalcView()
  73. if not isRoaming then
  74. if thirdperson then
  75. view.origin = getThirdPersonPos(specEnt)
  76. view.angles = LocalPlayer():EyeAngles()
  77. else
  78. view.origin = specEnt:IsPlayer() and specEnt:GetShootPos() or specEnt:LocalToWorld(specEnt:OBBCenter())
  79. view.angles = specEnt:IsPlayer() and specEnt:EyeAngles() or specEnt:GetAngles()
  80. end
  81.  
  82. roamPos = view.origin
  83. view.drawviewer = false
  84.  
  85. return view
  86. end
  87.  
  88. view.origin = roamPos
  89. view.angles = LocalPlayer():EyeAngles()
  90. view.drawviewer = true
  91.  
  92. return view
  93. end
  94.  
  95. --[[---------------------------------------------------------------------------
  96. specCalcView
  97. Override the view for the player to look through the spectated player's eyes
  98. ---------------------------------------------------------------------------]]
  99. local function specCalcView(ply, origin, angles, fov)
  100. if not IsValid(specEnt) and not isRoaming then
  101. startFreeRoam()
  102.  
  103. return
  104. end
  105.  
  106. view = getCalcView()
  107.  
  108. if IsValid(specEnt) then
  109. specEnt:SetNoDraw(not thirdperson)
  110. end
  111.  
  112. return view
  113. end
  114.  
  115. --[[---------------------------------------------------------------------------
  116. Find the right player to spectate
  117. ---------------------------------------------------------------------------]]
  118. local function findNearestObject()
  119. local aimvec = LocalPlayer():GetAimVector()
  120. local fromPos = isRoaming and roamPos or specEnt:EyePos()
  121. local lookingAt = util.QuickTrace(fromPos, aimvec * 5000, LocalPlayer())
  122. if IsValid(lookingAt.Entity) then return lookingAt.Entity end
  123. local foundPly, foundDot = nil, 0
  124.  
  125. for _, ply in pairs(player.GetAll()) do
  126. if ply == LocalPlayer() then continue end
  127. local pos = ply:GetShootPos()
  128. local dot = (pos - fromPos):GetNormalized():Dot(aimvec)
  129. -- Discard players you're not looking at
  130. if dot < 0.97 then continue end
  131. -- not a better alternative
  132. if dot < foundDot then continue end
  133. local trace = util.QuickTrace(fromPos, pos - fromPos, ply)
  134. if trace.Hit then continue end
  135. foundPly, foundDot = ply, dot
  136. end
  137.  
  138. return foundPly
  139. end
  140.  
  141. --[[---------------------------------------------------------------------------
  142. Spectate the person you're looking at while you're roaming
  143. ---------------------------------------------------------------------------]]
  144. local function spectateLookingAt()
  145. local obj = findNearestObject()
  146. if not IsValid(obj) then return end
  147. isRoaming = false
  148. specEnt = obj
  149. net.Start("FSpectateTarget")
  150. net.WriteEntity(obj)
  151. net.SendToServer()
  152. end
  153.  
  154. --[[---------------------------------------------------------------------------
  155. specBinds
  156. Change binds to perform spectate specific tasks
  157. ---------------------------------------------------------------------------]]
  158. -- Manual keysDown table, so I can return true in plyBindPress and still detect key presses
  159. local keysDown = {}
  160.  
  161. local function specBinds(ply, bind, pressed)
  162. local key = input.LookupBinding(bind)
  163.  
  164. if bind == "+jump" then
  165. stopSpectating()
  166.  
  167. return true
  168. elseif bind == "+reload" and pressed then
  169. local pos = getCalcView().origin - Vector(0, 0, 64)
  170. RunConsoleCommand("FTPToPos", string.format("%d, %d, %d", pos.x, pos.y, pos.z), string.format("%d, %d, %d", roamVelocity.x, roamVelocity.y, roamVelocity.z))
  171. stopSpectating()
  172. elseif bind == "+attack" and pressed then
  173. if not isRoaming then
  174. startFreeRoam()
  175. else
  176. spectateLookingAt()
  177. end
  178.  
  179. return true
  180. elseif bind == "+attack2" and pressed then
  181. if isRoaming then
  182. roamPos = roamPos + LocalPlayer():GetAimVector() * 500
  183.  
  184. return true
  185. end
  186.  
  187. thirdperson = not thirdperson
  188.  
  189. return true
  190. elseif isRoaming and not LocalPlayer():KeyDown(IN_USE) then
  191. local keybind = string.lower(string.match(bind, "+([a-z A-Z 0-9]+)") or "")
  192. if not keybind or keybind == "use" or keybind == "showscores" or string.find(bind, "messagemode") then return end
  193. keysDown[keybind:upper()] = pressed
  194.  
  195. return true
  196. elseif not isRoaming and thirdperson and (key == "MWHEELDOWN" or key == "MWHEELUP") then
  197. thirdPersonDistance = thirdPersonDistance + 10 * (key == "MWHEELDOWN" and 1 or -1)
  198. end
  199. -- Do not return otherwise, spectating admins should be able to move to avoid getting detected
  200. end
  201.  
  202. --[[---------------------------------------------------------------------------
  203. Scoreboardshow
  204. Set to main view when roaming, open on a player when spectating
  205. ---------------------------------------------------------------------------]]
  206. local function fadminmenushow()
  207. if isRoaming then
  208. FAdmin.ScoreBoard.ChangeView("Main")
  209. elseif IsValid(specEnt) and specEnt:IsPlayer() then
  210. FAdmin.ScoreBoard.ChangeView("Main")
  211. FAdmin.ScoreBoard.ChangeView("Player", specEnt)
  212. end
  213. end
  214.  
  215. --[[---------------------------------------------------------------------------
  216. RenderScreenspaceEffects
  217. Draws the lines from players' eyes to where they are looking
  218. ---------------------------------------------------------------------------]]
  219. local LineMat = Material("cable/new_cable_lit")
  220. local linesToDraw = {}
  221.  
  222. local function lookingLines()
  223. if not linesToDraw[0] then return end
  224. render.SetMaterial(LineMat)
  225. cam.Start3D(view.origin, view.angles)
  226.  
  227. for i = 0, #linesToDraw, 3 do
  228. render.DrawBeam(linesToDraw[i], linesToDraw[i + 1], 4, 0.01, 10, linesToDraw[i + 2])
  229. end
  230.  
  231. cam.End3D()
  232. end
  233.  
  234. --[[---------------------------------------------------------------------------
  235. gunpos
  236. Gets the position of a player's gun
  237. ---------------------------------------------------------------------------]]
  238. local function gunpos(ply)
  239. local wep = ply:GetActiveWeapon()
  240. if not IsValid(wep) then return ply:EyePos() end
  241. local att = wep:GetAttachment(1)
  242. if not att then return ply:EyePos() end
  243.  
  244. return att.Pos
  245. end
  246.  
  247. --[[---------------------------------------------------------------------------
  248. Spectate think
  249. Free roaming position updates
  250. ---------------------------------------------------------------------------]]
  251. local function specThink()
  252. local ply = LocalPlayer()
  253. -- Update linesToDraw
  254. local pls = player.GetAll()
  255. local lastPly = 0
  256. local skip = 0
  257.  
  258. for i = 0, #pls - 1 do
  259. local p = pls[i + 1]
  260.  
  261. if not isRoaming and p == specEnt and not thirdperson then
  262. skip = skip + 3
  263. continue
  264. end
  265.  
  266. local tr = p:GetEyeTrace()
  267. local sp = gunpos(p)
  268. local pos = i * 3 - skip
  269. linesToDraw[pos] = tr.HitPos
  270. linesToDraw[pos + 1] = sp
  271. linesToDraw[pos + 2] = team.GetColor(p:Team())
  272. lastPly = i
  273. end
  274.  
  275. -- Remove entries from linesToDraw that don't match with a player anymore
  276. for i = #linesToDraw, lastPly * 3 + 3, -1 do
  277. linesToDraw[i] = nil
  278. end
  279.  
  280. if not isRoaming or keysDown["USE"] then return end
  281. local roamSpeed = 1000
  282. local aimVec = ply:GetAimVector()
  283. local direction
  284. local frametime = RealFrameTime()
  285.  
  286. if keysDown["FORWARD"] then
  287. direction = aimVec
  288. elseif keysDown["BACK"] then
  289. direction = -aimVec
  290. end
  291.  
  292. if keysDown["MOVELEFT"] then
  293. local right = aimVec:Angle():Right()
  294. direction = direction and (direction - right):GetNormalized() or -right
  295. elseif keysDown["MOVERIGHT"] then
  296. local right = aimVec:Angle():Right()
  297. direction = direction and (direction + right):GetNormalized() or right
  298. end
  299.  
  300. if keysDown["SPEED"] then
  301. roamSpeed = 2500
  302. elseif keysDown["WALK"] or keysDown["DUCK"] then
  303. roamSpeed = 300
  304. end
  305.  
  306. roamVelocity = (direction or Vector(0, 0, 0)) * roamSpeed
  307. roamPos = roamPos + roamVelocity * frametime
  308. end
  309.  
  310. --[[---------------------------------------------------------------------------
  311. Draw help on the screen
  312. ---------------------------------------------------------------------------]]
  313. local uiForeground, uiBackground = Color(240, 240, 255, 255), Color(20, 20, 20, 120)
  314. local red = Color(255, 0, 0, 255)
  315.  
  316. local function drawHelp()
  317. local scrHalfH = math.floor(ScrH() / 2)
  318. draw.WordBox(2, 10, scrHalfH, "Left click: (Un)select player to spectate", "UiBold", uiBackground, uiForeground)
  319. draw.WordBox(2, 10, scrHalfH + 20, isRoaming and "Right click: quickly move forwards" or "Right click: toggle thirdperson", "UiBold", uiBackground, uiForeground)
  320. draw.WordBox(2, 10, scrHalfH + 40, "Jump: Stop spectating", "UiBold", uiBackground, uiForeground)
  321. draw.WordBox(2, 10, scrHalfH + 60, "Reload: Stop spectating and teleport", "UiBold", uiBackground, uiForeground)
  322.  
  323. if FAdmin then
  324. draw.WordBox(2, 10, scrHalfH + 80, "Opening FAdmin's menu while spectating a player", "UiBold", uiBackground, uiForeground)
  325. draw.WordBox(2, 10, scrHalfH + 100, "\twill open their page!", "UiBold", uiBackground, uiForeground)
  326. end
  327.  
  328. local target = findNearestObject()
  329. local pls = player.GetAll()
  330.  
  331. for i = 1, #pls do
  332. local ply = pls[i]
  333. if not isRoaming and ply == specEnt then continue end
  334. local pos = ply:GetShootPos():ToScreen()
  335. if not pos.visible then continue end
  336. local x, y = pos.x, pos.y
  337. draw.WordBox(2, x, y - alignment, ply:Nick(), "UiBold", uiBackground, uiForeground)
  338.  
  339. if ply:Armor() == 0 then
  340. draw.WordBox(2, x, y - (alignment - 20), "Health: " .. ply:Health(), "UiBold", uiBackground, uiForeground)
  341. else
  342. draw.WordBox(2, x, y - (alignment - 20), "Health: " .. ply:Health() .. " / Armor: " .. ply:Armor(), "UiBold", uiBackground, uiForeground)
  343. end
  344.  
  345. if ply:GetActiveWeapon():IsValid() then
  346. draw.WordBox(2, x, y - (alignment - 40), ply:GetActiveWeapon():GetPrintName(), "UiBold", uiBackground, uiForeground)
  347. draw.WordBox(2, x, y - (alignment - 60), ply:GetUserGroup(), "UiBold", uiBackground, uiForeground)
  348. draw.RoundedBox(2, x, y - (alignment - 80), 12, 12, team.GetColor(ply:Team()))
  349. else
  350. draw.WordBox(2, x, y - (alignment - 40), ply:GetUserGroup(), "UiBold", uiBackground, uiForeground)
  351. draw.RoundedBox(2, x, y - (alignment - 60), 12, 12, team.GetColor(ply:Team()))
  352. end
  353. end
  354.  
  355. if not isRoaming then return end
  356. if not IsValid(target) then return end
  357. local center = target:LocalToWorld(target:OBBCenter())
  358. local eyeAng = EyeAngles()
  359. local rightUp = eyeAng:Right() * 16 + eyeAng:Up() * 36
  360. local topRight = (center + rightUp):ToScreen()
  361. local bottomLeft = (center - rightUp):ToScreen()
  362. draw.RoundedBox(12, bottomLeft.x, bottomLeft.y, math.max(20, topRight.x - bottomLeft.x), topRight.y - bottomLeft.y, red)
  363. draw.WordBox(2, bottomLeft.x, bottomLeft.y + 12, "Left click to spectate!", "UiBold", uiBackground, uiForeground)
  364. end
  365.  
  366. --[[---------------------------------------------------------------------------
  367. Start roaming free, rather than spectating a given player
  368. ---------------------------------------------------------------------------]]
  369. startFreeRoam = function()
  370. if IsValid(specEnt) and specEnt:IsPlayer() then
  371. roamPos = thirdperson and getThirdPersonPos(specEnt) or specEnt:GetShootPos()
  372. specEnt:SetNoDraw(false)
  373. else
  374. roamPos = isSpectating and roamPos or LocalPlayer():GetShootPos()
  375. end
  376.  
  377. specEnt = nil
  378. isRoaming = true
  379. keysDown = {}
  380. end
  381.  
  382. --[[---------------------------------------------------------------------------
  383. specEnt
  384. Spectate a player
  385. ---------------------------------------------------------------------------]]
  386. local function startSpectate(um)
  387. isRoaming = net.ReadBool()
  388. specEnt = net.ReadEntity()
  389. specEnt = IsValid(specEnt) and specEnt or nil
  390.  
  391. if isRoaming then
  392. startFreeRoam()
  393. end
  394.  
  395. isSpectating = true
  396. keysDown = {}
  397. hook.Add("CalcView", "FSpectate", specCalcView)
  398. hook.Add("PlayerBindPress", "FSpectate", specBinds)
  399. hook.Add("ShouldDrawLocalPlayer", "FSpectate", function() return isRoaming or thirdperson end)
  400. hook.Add("Think", "FSpectate", specThink)
  401. hook.Add("HUDPaint", "FSpectate", drawHelp)
  402. hook.Add("FAdmin_ShowFAdminMenu", "FSpectate", fadminmenushow)
  403. hook.Add("RenderScreenspaceEffects", "FSpectate", lookingLines)
  404.  
  405. timer.Create("FSpectatePosUpdate", 0.5, 0, function()
  406. if not isRoaming then return end
  407. RunConsoleCommand("_FSpectatePosUpdate", roamPos.x, roamPos.y, roamPos.z)
  408. end)
  409. end
  410.  
  411. net.Receive("FSpectate", startSpectate)
  412.  
  413. --[[---------------------------------------------------------------------------
  414. stopSpectating
  415. Stop spectating a player
  416. ---------------------------------------------------------------------------]]
  417. stopSpectating = function()
  418. hook.Remove("CalcView", "FSpectate")
  419. hook.Remove("PlayerBindPress", "FSpectate")
  420. hook.Remove("ShouldDrawLocalPlayer", "FSpectate")
  421. hook.Remove("Think", "FSpectate")
  422. hook.Remove("HUDPaint", "FSpectate")
  423. hook.Remove("FAdmin_ShowFAdminMenu", "FSpectate")
  424. hook.Remove("RenderScreenspaceEffects", "FSpectate")
  425. timer.Remove("FSpectatePosUpdate")
  426.  
  427. if IsValid(specEnt) then
  428. specEnt:SetNoDraw(false)
  429. end
  430.  
  431. RunConsoleCommand("FSpectate_StopSpectating")
  432. isSpectating = false
  433. end
  434.  
  435. hook.Add("PlayerButtonDown", "CopySteamidToClipboard", function(ply, button)
  436. if button == KEY_E then
  437. if not IsFirstTimePredicted() then return end
  438. PlyTraceEye = ply:GetEyeTrace().Entity
  439.  
  440. if PlyTraceEye:IsPlayer() then
  441. SetClipboardText(PlyTraceEye:SteamID())
  442. chat.AddText(Color(255, 0, 0), "SteamID de : ", Color(255, 255, 255), PlyTraceEye:Nick(), Color(255, 0, 0), " copié !")
  443. end
  444. end
  445.  
  446. if button == KEY_A then
  447. if not IsFirstTimePredicted() then return end
  448.  
  449. --HSVToColor( ( CurTime() * 100 ) % 360, 1, 1 )
  450. --Color(math.random(1, 255), math.random(1, 255), math.random(1, 255))
  451. for k, v in ipairs(player.GetAll()) do
  452. if v:IsAdmin() or v:IsSuperAdmin() then
  453. chat.AddText(HSVToColor((CurTime() * 100) % 360, 1, 1), "[" .. v:GetUserGroup() .. "] " .. v:Nick() .. " est un staff")
  454. end
  455. end
  456. end
  457. end)
  458.  
  459. function BasicAim()
  460. local pls = player.GetAll()
  461. alignment = 66
  462.  
  463. for i = 1, #pls do
  464. local ply = pls[i]
  465. if not isRoaming and ply == specEnt then continue end
  466. local pos = ply:GetShootPos():ToScreen()
  467. if not pos.visible then continue end
  468. local x, y = pos.x, pos.y
  469. if isSpectating then return end
  470. draw.WordBox(2, x, y - alignment, ply:Nick(), "UiBold", uiBackground, uiForeground)
  471.  
  472. if ply:Armor() == 0 then
  473. draw.WordBox(2, x, y - (alignment - 20), "Health: " .. ply:Health(), "UiBold", uiBackground, uiForeground)
  474. else
  475. draw.WordBox(2, x, y - (alignment - 20), "Health: " .. ply:Health() .. " / Armor: " .. ply:Armor(), "UiBold", uiBackground, uiForeground)
  476. end
  477.  
  478. if ply:GetActiveWeapon():IsValid() then
  479. draw.WordBox(2, x, y - (alignment - 40), ply:GetActiveWeapon():GetPrintName(), "UiBold", uiBackground, uiForeground)
  480. draw.WordBox(2, x, y - (alignment - 60), ply:GetUserGroup(), "UiBold", uiBackground, uiForeground)
  481. draw.RoundedBox(2, x, y - (alignment - 80), 12, 12, team.GetColor(ply:Team()))
  482. else
  483. draw.WordBox(2, x, y - (alignment - 40), ply:GetUserGroup(), "UiBold", uiBackground, uiForeground)
  484. draw.RoundedBox(2, x, y - (alignment - 60), 12, 12, team.GetColor(ply:Team()))
  485. end
  486. end
  487. end
  488.  
  489. hook.Add("HUDPaint", "CoucouleBoss", BasicAim)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement