mathljn

Untitled

May 12th, 2024
16
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.45 KB | None | 0 0
  1. -- services
  2. local runService = game:GetService("RunService");
  3. local players = game:GetService("Players");
  4. local workspace = game:GetService("Workspace");
  5.  
  6. -- variables
  7. local localPlayer = players.LocalPlayer;
  8. local camera = workspace.CurrentCamera;
  9. local viewportSize = camera.ViewportSize;
  10. local container = Instance.new("Folder",
  11. gethui and gethui() or game:GetService("CoreGui"));
  12.  
  13. -- locals
  14. local floor = math.floor;
  15. local round = math.round;
  16. local sin = math.sin;
  17. local cos = math.cos;
  18. local clear = table.clear;
  19. local unpack = table.unpack;
  20. local find = table.find;
  21. local create = table.create;
  22. local fromMatrix = CFrame.fromMatrix;
  23.  
  24. -- methods
  25. local wtvp = camera.WorldToViewportPoint;
  26. local isA = workspace.IsA;
  27. local getPivot = workspace.GetPivot;
  28. local findFirstChild = workspace.FindFirstChild;
  29. local findFirstChildOfClass = workspace.FindFirstChildOfClass;
  30. local getChildren = workspace.GetChildren;
  31. local toOrientation = CFrame.identity.ToOrientation;
  32. local pointToObjectSpace = CFrame.identity.PointToObjectSpace;
  33. local lerpColor = Color3.new().Lerp;
  34. local min2 = Vector2.zero.Min;
  35. local max2 = Vector2.zero.Max;
  36. local lerp2 = Vector2.zero.Lerp;
  37. local min3 = Vector3.zero.Min;
  38. local max3 = Vector3.zero.Max;
  39.  
  40. -- constants
  41. local HEALTH_BAR_OFFSET = Vector2.new(5, 0);
  42. local HEALTH_TEXT_OFFSET = Vector2.new(3, 0);
  43. local HEALTH_BAR_OUTLINE_OFFSET = Vector2.new(0, 1);
  44. local NAME_OFFSET = Vector2.new(0, 2);
  45. local DISTANCE_OFFSET = Vector2.new(0, 2);
  46. local VERTICES = {
  47. Vector3.new(-1, -1, -1),
  48. Vector3.new(-1, 1, -1),
  49. Vector3.new(-1, 1, 1),
  50. Vector3.new(-1, -1, 1),
  51. Vector3.new(1, -1, -1),
  52. Vector3.new(1, 1, -1),
  53. Vector3.new(1, 1, 1),
  54. Vector3.new(1, -1, 1)
  55. };
  56.  
  57. -- functions
  58. local function isBodyPart(name)
  59. return name == "Head" or name:find("Torso") or name:find("Leg") or name:find("Arm");
  60. end
  61.  
  62. local function getBoundingBox(parts)
  63. local min, max;
  64. for i = 1, #parts do
  65. local part = parts[i];
  66. local cframe, size = part.CFrame, part.Size;
  67.  
  68. min = min3(min or cframe.Position, (cframe - size*0.5).Position);
  69. max = max3(max or cframe.Position, (cframe + size*0.5).Position);
  70. end
  71.  
  72. local center = (min + max)*0.5;
  73. local front = Vector3.new(center.X, center.Y, max.Z);
  74. return CFrame.new(center, front), max - min;
  75. end
  76.  
  77. local function worldToScreen(world)
  78. local screen, inBounds = wtvp(camera, world);
  79. return Vector2.new(screen.X, screen.Y), inBounds, screen.Z;
  80. end
  81.  
  82. local function calculateCorners(cframe, size)
  83. local corners = create(#VERTICES);
  84. for i = 1, #VERTICES do
  85. corners[i] = worldToScreen((cframe + size*0.5*VERTICES[i]).Position);
  86. end
  87.  
  88. local min = min2(viewportSize, unpack(corners));
  89. local max = max2(Vector2.zero, unpack(corners));
  90. return {
  91. corners = corners,
  92. topLeft = Vector2.new(floor(min.X), floor(min.Y)),
  93. topRight = Vector2.new(floor(max.X), floor(min.Y)),
  94. bottomLeft = Vector2.new(floor(min.X), floor(max.Y)),
  95. bottomRight = Vector2.new(floor(max.X), floor(max.Y))
  96. };
  97. end
  98.  
  99. local function rotateVector(vector, radians)
  100. -- https://stackoverflow.com/questions/28112315/how-do-i-rotate-a-vector
  101. local x, y = vector.X, vector.Y;
  102. local c, s = cos(radians), sin(radians);
  103. return Vector2.new(x*c - y*s, x*s + y*c);
  104. end
  105.  
  106. local function parseColor(self, color, isOutline)
  107. if color == "Team Color" or (self.interface.sharedSettings.useTeamColor and not isOutline) then
  108. return self.interface.getTeamColor(self.player) or Color3.new(1,1,1);
  109. end
  110. return color;
  111. end
  112.  
  113. -- esp object
  114. local EspObject = {};
  115. EspObject.__index = EspObject;
  116.  
  117. function EspObject.new(player, interface)
  118. local self = setmetatable({}, EspObject);
  119. self.player = assert(player, "Missing argument #1 (Player expected)");
  120. self.interface = assert(interface, "Missing argument #2 (table expected)");
  121. self:Construct();
  122. return self;
  123. end
  124.  
  125. function EspObject:_create(class, properties)
  126. local drawing = Drawing.new(class);
  127. for property, value in next, properties do
  128. pcall(function() drawing[property] = value; end);
  129. end
  130. self.bin[#self.bin + 1] = drawing;
  131. return drawing;
  132. end
  133.  
  134. function EspObject:Construct()
  135. self.charCache = {};
  136. self.childCount = 0;
  137. self.bin = {};
  138. self.drawings = {
  139. box3d = {
  140. {
  141. self:_create("Line", { Thickness = 1, Visible = false }),
  142. self:_create("Line", { Thickness = 1, Visible = false }),
  143. self:_create("Line", { Thickness = 1, Visible = false })
  144. },
  145. {
  146. self:_create("Line", { Thickness = 1, Visible = false }),
  147. self:_create("Line", { Thickness = 1, Visible = false }),
  148. self:_create("Line", { Thickness = 1, Visible = false })
  149. },
  150. {
  151. self:_create("Line", { Thickness = 1, Visible = false }),
  152. self:_create("Line", { Thickness = 1, Visible = false }),
  153. self:_create("Line", { Thickness = 1, Visible = false })
  154. },
  155. {
  156. self:_create("Line", { Thickness = 1, Visible = false }),
  157. self:_create("Line", { Thickness = 1, Visible = false }),
  158. self:_create("Line", { Thickness = 1, Visible = false })
  159. }
  160. },
  161. visible = {
  162. tracerOutline = self:_create("Line", { Thickness = 3, Visible = false }),
  163. tracer = self:_create("Line", { Thickness = 1, Visible = false }),
  164. boxFill = self:_create("Square", { Filled = true, Visible = false }),
  165. boxOutline = self:_create("Square", { Thickness = 3, Visible = false }),
  166. box = self:_create("Square", { Thickness = 1, Visible = false }),
  167. healthBarOutline = self:_create("Line", { Thickness = 3, Visible = false }),
  168. healthBar = self:_create("Line", { Thickness = 1, Visible = false }),
  169. healthText = self:_create("Text", { Center = true, Visible = false }),
  170. name = self:_create("Text", { Text = self.player.DisplayName, Center = true, Visible = false }),
  171. distance = self:_create("Text", { Center = true, Visible = false }),
  172. weapon = self:_create("Text", { Center = true, Visible = false }),
  173. },
  174. hidden = {
  175. arrowOutline = self:_create("Triangle", { Thickness = 3, Visible = false }),
  176. arrow = self:_create("Triangle", { Filled = true, Visible = false })
  177. }
  178. };
  179.  
  180. self.renderConnection = runService.Heartbeat:Connect(function(deltaTime)
  181. self:Update(deltaTime);
  182. self:Render(deltaTime);
  183. end);
  184. end
  185.  
  186. function EspObject:Destruct()
  187. self.renderConnection:Disconnect();
  188.  
  189. for i = 1, #self.bin do
  190. self.bin[i]:Remove();
  191. end
  192.  
  193. clear(self);
  194. end
  195.  
  196. function EspObject:Update()
  197. local interface = self.interface;
  198.  
  199. self.options = interface.teamSettings[interface.isFriendly(self.player) and "friendly" or "enemy"];
  200. self.character = interface.getCharacter(self.player);
  201. self.health, self.maxHealth = interface.getHealth(self.player);
  202. self.weapon = interface.getWeapon(self.player);
  203. self.enabled = self.options.enabled and self.character and not
  204. (#interface.whitelist > 0 and not find(interface.whitelist, self.player.UserId));
  205.  
  206. local head = self.enabled and findFirstChild(self.character, "Head");
  207. if not head then
  208. self.charCache = {};
  209. self.onScreen = false;
  210. return;
  211. end
  212.  
  213. local _, onScreen, depth = worldToScreen(head.Position);
  214. self.onScreen = onScreen;
  215. self.distance = depth;
  216.  
  217. if interface.sharedSettings.limitDistance and depth > interface.sharedSettings.maxDistance then
  218. self.onScreen = false;
  219. end
  220.  
  221. if self.onScreen then
  222. local cache = self.charCache;
  223. local children = getChildren(self.character);
  224. if not cache[1] or self.childCount ~= #children then
  225. clear(cache);
  226.  
  227. for i = 1, #children do
  228. local part = children[i];
  229. if isA(part, "BasePart") and isBodyPart(part.Name) then
  230. cache[#cache + 1] = part;
  231. end
  232. end
  233.  
  234. self.childCount = #children;
  235. end
  236.  
  237. self.corners = calculateCorners(getBoundingBox(cache));
  238. elseif self.options.offScreenArrow then
  239. local cframe = camera.CFrame;
  240. local flat = fromMatrix(cframe.Position, cframe.RightVector, Vector3.yAxis);
  241. local objectSpace = pointToObjectSpace(flat, head.Position);
  242. self.direction = Vector2.new(objectSpace.X, objectSpace.Z).Unit;
  243. end
  244. end
  245.  
  246. function EspObject:Render()
  247. local onScreen = self.onScreen or false;
  248. local enabled = self.enabled or false;
  249. local visible = self.drawings.visible;
  250. local hidden = self.drawings.hidden;
  251. local box3d = self.drawings.box3d;
  252. local interface = self.interface;
  253. local options = self.options;
  254. local corners = self.corners;
  255.  
  256. visible.box.Visible = enabled and onScreen and options.box;
  257. visible.boxOutline.Visible = visible.box.Visible and options.boxOutline;
  258. if visible.box.Visible then
  259. local box = visible.box;
  260. box.Position = corners.topLeft;
  261. box.Size = corners.bottomRight - corners.topLeft;
  262. box.Color = parseColor(self, options.boxColor[1]);
  263. box.Transparency = options.boxColor[2];
  264.  
  265. local boxOutline = visible.boxOutline;
  266. boxOutline.Position = box.Position;
  267. boxOutline.Size = box.Size;
  268. boxOutline.Color = parseColor(self, options.boxOutlineColor[1], true);
  269. boxOutline.Transparency = options.boxOutlineColor[2];
  270. end
  271.  
  272. visible.boxFill.Visible = enabled and onScreen and options.boxFill;
  273. if visible.boxFill.Visible then
  274. local boxFill = visible.boxFill;
  275. boxFill.Position = corners.topLeft;
  276. boxFill.Size = corners.bottomRight - corners.topLeft;
  277. boxFill.Color = parseColor(self, options.boxFillColor[1]);
  278. boxFill.Transparency = options.boxFillColor[2];
  279. end
  280.  
  281. visible.healthBar.Visible = enabled and onScreen and options.healthBar;
  282. visible.healthBarOutline.Visible = visible.healthBar.Visible and options.healthBarOutline;
  283. if visible.healthBar.Visible then
  284. local barFrom = corners.topLeft - HEALTH_BAR_OFFSET;
  285. local barTo = corners.bottomLeft - HEALTH_BAR_OFFSET;
  286.  
  287. local healthBar = visible.healthBar;
  288. healthBar.To = barTo;
  289. healthBar.From = lerp2(barTo, barFrom, self.health/self.maxHealth);
  290. healthBar.Color = lerpColor(options.dyingColor, options.healthyColor, self.health/self.maxHealth);
  291.  
  292. local healthBarOutline = visible.healthBarOutline;
  293. healthBarOutline.To = barTo + HEALTH_BAR_OUTLINE_OFFSET;
  294. healthBarOutline.From = barFrom - HEALTH_BAR_OUTLINE_OFFSET;
  295. healthBarOutline.Color = parseColor(self, options.healthBarOutlineColor[1], true);
  296. healthBarOutline.Transparency = options.healthBarOutlineColor[2];
  297. end
  298.  
  299. visible.healthText.Visible = enabled and onScreen and options.healthText;
  300. if visible.healthText.Visible then
  301. local barFrom = corners.topLeft - HEALTH_BAR_OFFSET;
  302. local barTo = corners.bottomLeft - HEALTH_BAR_OFFSET;
  303.  
  304. local healthText = visible.healthText;
  305. healthText.Text = round(self.health) .. "hp";
  306. healthText.Size = interface.sharedSettings.textSize;
  307. healthText.Font = interface.sharedSettings.textFont;
  308. healthText.Color = parseColor(self, options.healthTextColor[1]);
  309. healthText.Transparency = options.healthTextColor[2];
  310. healthText.Outline = options.healthTextOutline;
  311. healthText.OutlineColor = parseColor(self, options.healthTextOutlineColor, true);
  312. healthText.Position = lerp2(barTo, barFrom, self.health/self.maxHealth) - healthText.TextBounds*0.5 - HEALTH_TEXT_OFFSET;
  313. end
  314.  
  315. visible.name.Visible = enabled and onScreen and options.name;
  316. if visible.name.Visible then
  317. local name = visible.name;
  318. name.Size = interface.sharedSettings.textSize;
  319. name.Font = interface.sharedSettings.textFont;
  320. name.Color = parseColor(self, options.nameColor[1]);
  321. name.Transparency = options.nameColor[2];
  322. name.Outline = options.nameOutline;
  323. name.OutlineColor = parseColor(self, options.nameOutlineColor, true);
  324. name.Position = (corners.topLeft + corners.topRight)*0.5 - Vector2.yAxis*name.TextBounds.Y - NAME_OFFSET;
  325. end
  326.  
  327. visible.distance.Visible = enabled and onScreen and self.distance and options.distance;
  328. if visible.distance.Visible then
  329. local distance = visible.distance;
  330. distance.Text = round(self.distance) .. " studs";
  331. distance.Size = interface.sharedSettings.textSize;
  332. distance.Font = interface.sharedSettings.textFont;
  333. distance.Color = parseColor(self, options.distanceColor[1]);
  334. distance.Transparency = options.distanceColor[2];
  335. distance.Outline = options.distanceOutline;
  336. distance.OutlineColor = parseColor(self, options.distanceOutlineColor, true);
  337. distance.Position = (corners.bottomLeft + corners.bottomRight)*0.5 + DISTANCE_OFFSET;
  338. end
  339.  
  340. visible.weapon.Visible = enabled and onScreen and options.weapon;
  341. if visible.weapon.Visible then
  342. local weapon = visible.weapon;
  343. weapon.Text = self.weapon;
  344. weapon.Size = interface.sharedSettings.textSize;
  345. weapon.Font = interface.sharedSettings.textFont;
  346. weapon.Color = parseColor(self, options.weaponColor[1]);
  347. weapon.Transparency = options.weaponColor[2];
  348. weapon.Outline = options.weaponOutline;
  349. weapon.OutlineColor = parseColor(self, options.weaponOutlineColor, true);
  350. weapon.Position =
  351. (corners.bottomLeft + corners.bottomRight)*0.5 +
  352. (visible.distance.Visible and DISTANCE_OFFSET + Vector2.yAxis*visible.distance.TextBounds.Y or Vector2.zero);
  353. end
  354.  
  355. visible.tracer.Visible = enabled and onScreen and options.tracer;
  356. visible.tracerOutline.Visible = visible.tracer.Visible and options.tracerOutline;
  357. if visible.tracer.Visible then
  358. local tracer = visible.tracer;
  359. tracer.Color = parseColor(self, options.tracerColor[1]);
  360. tracer.Transparency = options.tracerColor[2];
  361. tracer.To = (corners.bottomLeft + corners.bottomRight)*0.5;
  362. tracer.From =
  363. options.tracerOrigin == "Middle" and viewportSize*0.5 or
  364. options.tracerOrigin == "Top" and viewportSize*Vector2.new(0.5, 0) or
  365. options.tracerOrigin == "Bottom" and viewportSize*Vector2.new(0.5, 1);
  366.  
  367. local tracerOutline = visible.tracerOutline;
  368. tracerOutline.Color = parseColor(self, options.tracerOutlineColor[1], true);
  369. tracerOutline.Transparency = options.tracerOutlineColor[2];
  370. tracerOutline.To = tracer.To;
  371. tracerOutline.From = tracer.From;
  372. end
  373.  
  374. hidden.arrow.Visible = enabled and (not onScreen) and options.offScreenArrow;
  375. hidden.arrowOutline.Visible = hidden.arrow.Visible and options.offScreenArrowOutline;
  376. if hidden.arrow.Visible and self.direction then
  377. local arrow = hidden.arrow;
  378. arrow.PointA = min2(max2(viewportSize*0.5 + self.direction*options.offScreenArrowRadius, Vector2.one*25), viewportSize - Vector2.one*25);
  379. arrow.PointB = arrow.PointA - rotateVector(self.direction, 0.45)*options.offScreenArrowSize;
  380. arrow.PointC = arrow.PointA - rotateVector(self.direction, -0.45)*options.offScreenArrowSize;
  381. arrow.Color = parseColor(self, options.offScreenArrowColor[1]);
  382. arrow.Transparency = options.offScreenArrowColor[2];
  383.  
  384. local arrowOutline = hidden.arrowOutline;
  385. arrowOutline.PointA = arrow.PointA;
  386. arrowOutline.PointB = arrow.PointB;
  387. arrowOutline.PointC = arrow.PointC;
  388. arrowOutline.Color = parseColor(self, options.offScreenArrowOutlineColor[1], true);
  389. arrowOutline.Transparency = options.offScreenArrowOutlineColor[2];
  390. end
  391.  
  392. local box3dEnabled = enabled and onScreen and options.box3d;
  393. for i = 1, #box3d do
  394. local face = box3d[i];
  395. for i2 = 1, #face do
  396. local line = face[i2];
  397. line.Visible = box3dEnabled;
  398. line.Color = parseColor(self, options.box3dColor[1]);
  399. line.Transparency = options.box3dColor[2];
  400. end
  401.  
  402. if box3dEnabled then
  403. local line1 = face[1];
  404. line1.From = corners.corners[i];
  405. line1.To = corners.corners[i == 4 and 1 or i+1];
  406.  
  407. local line2 = face[2];
  408. line2.From = corners.corners[i == 4 and 1 or i+1];
  409. line2.To = corners.corners[i == 4 and 5 or i+5];
  410.  
  411. local line3 = face[3];
  412. line3.From = corners.corners[i == 4 and 5 or i+5];
  413. line3.To = corners.corners[i == 4 and 8 or i+4];
  414. end
  415. end
  416. end
  417.  
  418. -- cham object
  419. local ChamObject = {};
  420. ChamObject.__index = ChamObject;
  421.  
  422. function ChamObject.new(player, interface)
  423. local self = setmetatable({}, ChamObject);
  424. self.player = assert(player, "Missing argument #1 (Player expected)");
  425. self.interface = assert(interface, "Missing argument #2 (table expected)");
  426. self:Construct();
  427. return self;
  428. end
  429.  
  430. function ChamObject:Construct()
  431. self.highlight = Instance.new("Highlight", container);
  432. self.updateConnection = runService.Heartbeat:Connect(function()
  433. self:Update();
  434. end);
  435. end
  436.  
  437. function ChamObject:Destruct()
  438. self.updateConnection:Disconnect();
  439. self.highlight:Destroy();
  440.  
  441. clear(self);
  442. end
  443.  
  444. function ChamObject:Update()
  445. local highlight = self.highlight;
  446. local interface = self.interface;
  447. local character = interface.getCharacter(self.player);
  448. local options = interface.teamSettings[interface.isFriendly(self.player) and "friendly" or "enemy"];
  449. local enabled = options.enabled and character and not
  450. (#interface.whitelist > 0 and not find(interface.whitelist, self.player.UserId));
  451.  
  452. highlight.Enabled = enabled and options.chams;
  453. if highlight.Enabled then
  454. highlight.Adornee = character;
  455. highlight.FillColor = parseColor(self, options.chamsFillColor[1]);
  456. highlight.FillTransparency = options.chamsFillColor[2];
  457. highlight.OutlineColor = parseColor(self, options.chamsOutlineColor[1], true);
  458. highlight.OutlineTransparency = options.chamsOutlineColor[2];
  459. highlight.DepthMode = options.chamsVisibleOnly and "Occluded" or "AlwaysOnTop";
  460. end
  461. end
  462.  
  463. -- instance class
  464. local InstanceObject = {};
  465. InstanceObject.__index = InstanceObject;
  466.  
  467. function InstanceObject.new(instance, options)
  468. local self = setmetatable({}, InstanceObject);
  469. self.instance = assert(instance, "Missing argument #1 (Instance Expected)");
  470. self.options = assert(options, "Missing argument #2 (table expected)");
  471. self:Construct();
  472. return self;
  473. end
  474.  
  475. function InstanceObject:Construct()
  476. local options = self.options;
  477. options.enabled = options.enabled == nil and true or options.enabled;
  478. options.text = options.text or "{name}";
  479. options.textColor = options.textColor or { Color3.new(1,1,1), 1 };
  480. options.textOutline = options.textOutline == nil and true or options.textOutline;
  481. options.textOutlineColor = options.textOutlineColor or Color3.new();
  482. options.textSize = options.textSize or 13;
  483. options.textFont = options.textFont or 2;
  484. options.limitDistance = options.limitDistance or false;
  485. options.maxDistance = options.maxDistance or 150;
  486.  
  487. self.text = Drawing.new("Text");
  488. self.text.Center = true;
  489.  
  490. self.renderConnection = runService.Heartbeat:Connect(function(deltaTime)
  491. self:Render(deltaTime);
  492. end);
  493. end
  494.  
  495. function InstanceObject:Destruct()
  496. self.renderConnection:Disconnect();
  497. self.text:Remove();
  498. end
  499.  
  500. function InstanceObject:Render()
  501. local instance = self.instance;
  502. if not instance or not instance.Parent then
  503. return self:Destruct();
  504. end
  505.  
  506. local text = self.text;
  507. local options = self.options;
  508. if not options.enabled then
  509. text.Visible = false;
  510. return;
  511. end
  512.  
  513. local world = getPivot(instance).Position;
  514. local position, visible, depth = worldToScreen(world);
  515. if options.limitDistance and depth > options.maxDistance then
  516. visible = false;
  517. end
  518.  
  519. text.Visible = visible;
  520. if text.Visible then
  521. text.Position = position;
  522. text.Color = options.textColor[1];
  523. text.Transparency = options.textColor[2];
  524. text.Outline = options.textOutline;
  525. text.OutlineColor = options.textOutlineColor;
  526. text.Size = options.textSize;
  527. text.Font = options.textFont;
  528. text.Text = options.text
  529. :gsub("{name}", instance.Name)
  530. :gsub("{distance}", round(depth))
  531. :gsub("{position}", tostring(world));
  532. end
  533. end
  534.  
  535. -- interface
  536. local EspInterface = {
  537. _hasLoaded = false,
  538. _objectCache = {},
  539. whitelist = {},
  540. sharedSettings = {
  541. textSize = 13,
  542. textFont = 2,
  543. limitDistance = false,
  544. maxDistance = 150,
  545. useTeamColor = false
  546. },
  547. teamSettings = {
  548. enemy = {
  549. enabled = false,
  550. box = false,
  551. boxColor = { Color3.new(1,0,0), 1 },
  552. boxOutline = true,
  553. boxOutlineColor = { Color3.new(), 1 },
  554. boxFill = false,
  555. boxFillColor = { Color3.new(1,0,0), 0.5 },
  556. healthBar = false,
  557. healthyColor = Color3.new(0,1,0),
  558. dyingColor = Color3.new(1,0,0),
  559. healthBarOutline = true,
  560. healthBarOutlineColor = { Color3.new(), 0.5 },
  561. healthText = false,
  562. healthTextColor = { Color3.new(1,1,1), 1 },
  563. healthTextOutline = true,
  564. healthTextOutlineColor = Color3.new(),
  565. box3d = false,
  566. box3dColor = { Color3.new(1,0,0), 1 },
  567. name = false,
  568. nameColor = { Color3.new(1,1,1), 1 },
  569. nameOutline = true,
  570. nameOutlineColor = Color3.new(),
  571. weapon = false,
  572. weaponColor = { Color3.new(1,1,1), 1 },
  573. weaponOutline = true,
  574. weaponOutlineColor = Color3.new(),
  575. distance = false,
  576. distanceColor = { Color3.new(1,1,1), 1 },
  577. distanceOutline = true,
  578. distanceOutlineColor = Color3.new(),
  579. tracer = false,
  580. tracerOrigin = "Bottom",
  581. tracerColor = { Color3.new(1,0,0), 1 },
  582. tracerOutline = true,
  583. tracerOutlineColor = { Color3.new(), 1 },
  584. offScreenArrow = false,
  585. offScreenArrowColor = { Color3.new(1,1,1), 1 },
  586. offScreenArrowSize = 15,
  587. offScreenArrowRadius = 150,
  588. offScreenArrowOutline = true,
  589. offScreenArrowOutlineColor = { Color3.new(), 1 },
  590. chams = false,
  591. chamsVisibleOnly = false,
  592. chamsFillColor = { Color3.new(0.2, 0.2, 0.2), 0.5 },
  593. chamsOutlineColor = { Color3.new(1,0,0), 0 },
  594. },
  595. friendly = {
  596. enabled = false,
  597. box = false,
  598. boxColor = { Color3.new(0,1,0), 1 },
  599. boxOutline = true,
  600. boxOutlineColor = { Color3.new(), 1 },
  601. boxFill = false,
  602. boxFillColor = { Color3.new(0,1,0), 0.5 },
  603. healthBar = false,
  604. healthyColor = Color3.new(0,1,0),
  605. dyingColor = Color3.new(1,0,0),
  606. healthBarOutline = true,
  607. healthBarOutlineColor = { Color3.new(), 0.5 },
  608. healthText = false,
  609. healthTextColor = { Color3.new(1,1,1), 1 },
  610. healthTextOutline = true,
  611. healthTextOutlineColor = Color3.new(),
  612. box3d = false,
  613. box3dColor = { Color3.new(0,1,0), 1 },
  614. name = false,
  615. nameColor = { Color3.new(1,1,1), 1 },
  616. nameOutline = true,
  617. nameOutlineColor = Color3.new(),
  618. weapon = false,
  619. weaponColor = { Color3.new(1,1,1), 1 },
  620. weaponOutline = true,
  621. weaponOutlineColor = Color3.new(),
  622. distance = false,
  623. distanceColor = { Color3.new(1,1,1), 1 },
  624. distanceOutline = true,
  625. distanceOutlineColor = Color3.new(),
  626. tracer = false,
  627. tracerOrigin = "Bottom",
  628. tracerColor = { Color3.new(0,1,0), 1 },
  629. tracerOutline = true,
  630. tracerOutlineColor = { Color3.new(), 1 },
  631. offScreenArrow = false,
  632. offScreenArrowColor = { Color3.new(1,1,1), 1 },
  633. offScreenArrowSize = 15,
  634. offScreenArrowRadius = 150,
  635. offScreenArrowOutline = true,
  636. offScreenArrowOutlineColor = { Color3.new(), 1 },
  637. chams = false,
  638. chamsVisibleOnly = false,
  639. chamsFillColor = { Color3.new(0.2, 0.2, 0.2), 0.5 },
  640. chamsOutlineColor = { Color3.new(0,1,0), 0 }
  641. }
  642. }
  643. };
  644.  
  645. function EspInterface.AddInstance(instance, options)
  646. local cache = EspInterface._objectCache;
  647. if cache[instance] then
  648. warn("Instance handler already exists.");
  649. else
  650. cache[instance] = { InstanceObject.new(instance, options) };
  651. end
  652. return cache[instance][1];
  653. end
  654.  
  655. function EspInterface.Load()
  656. assert(not EspInterface._hasLoaded, "Esp has already been loaded.");
  657.  
  658. local function createObject(player)
  659. EspInterface._objectCache[player] = {
  660. EspObject.new(player, EspInterface),
  661. ChamObject.new(player, EspInterface)
  662. };
  663. end
  664.  
  665. local function removeObject(player)
  666. local object = EspInterface._objectCache[player];
  667. if object then
  668. for i = 1, #object do
  669. object[i]:Destruct();
  670. end
  671. EspInterface._objectCache[player] = nil;
  672. end
  673. end
  674.  
  675. local plrs = players:GetPlayers();
  676. for i = 2, #plrs do
  677. createObject(plrs[i]);
  678. end
  679.  
  680. EspInterface.playerAdded = players.PlayerAdded:Connect(createObject);
  681. EspInterface.playerRemoving = players.PlayerRemoving:Connect(removeObject);
  682. EspInterface._hasLoaded = true;
  683. end
  684.  
  685. function EspInterface.Unload()
  686. assert(EspInterface._hasLoaded, "Esp has not been loaded yet.");
  687.  
  688. for index, object in next, EspInterface._objectCache do
  689. for i = 1, #object do
  690. object[i]:Destruct();
  691. end
  692. EspInterface._objectCache[index] = nil;
  693. end
  694.  
  695. EspInterface.playerAdded:Disconnect();
  696. EspInterface.playerRemoving:Disconnect();
  697. EspInterface._hasLoaded = false;
  698. end
  699.  
  700. -- game specific functions
  701. function EspInterface.getWeapon(player)
  702. return "Unknown";
  703. end
  704.  
  705. function EspInterface.isFriendly(player)
  706. return player.Team and player.Team == localPlayer.Team;
  707. end
  708.  
  709. function EspInterface.getTeamColor(player)
  710. return player.Team and player.Team.TeamColor and player.Team.TeamColor.Color;
  711. end
  712.  
  713. function EspInterface.getCharacter(player)
  714. return player.Character;
  715. end
  716.  
  717. function EspInterface.getHealth(player)
  718. local character = player and EspInterface.getCharacter(player);
  719. local humanoid = character and findFirstChildOfClass(character, "Humanoid");
  720. if humanoid then
  721. return humanoid.Health, humanoid.MaxHealth;
  722. end
  723. return 100, 100;
  724. end
  725.  
  726. return EspInterface;
Add Comment
Please, Sign In to add comment