1 | assert(Drawing, 'exploit not supported') |
2 | |
3 | if not syn and not PROTOSMASHER_LOADED then print'Unnamed ESP only officially supports Synapse and Protosmasher! If you\'re an exploit developer and have added drawing API to your exploit, try setting syn as true then checking if that works, otherwise, DM me on discord @ cppbook.org#1968 or add an issue to the Unnamed ESP Github Repository and I\'ll see it through email!' end |
4 | |
5 | if not cloneref then cloneref = function(o) return o end end |
6 | |
7 | local UserInputService = cloneref(game:GetService'UserInputService') |
8 | local HttpService = cloneref(game:GetService'HttpService') |
9 | local TweenService = cloneref(game:GetService'TweenService') |
10 | local RunService = cloneref(game:GetService'RunService') |
11 | local Players = game:GetService'Players' |
12 | local LocalPlayer = Players.LocalPlayer |
13 | local Camera = workspace.CurrentCamera |
14 | local Mouse = LocalPlayer:GetMouse() |
15 | local V2New = Vector2.new |
16 | local V3New = Vector3.new |
17 | local WTVP = Camera.WorldToViewportPoint |
18 | local WorldToViewport = function(...) return WTVP(Camera, ...) end |
19 | local Menu = {} |
20 | local MouseHeld = false |
21 | local LastRefresh = 0 |
22 | local OptionsFile = 'IC3_ESP_SETTINGS.dat' |
23 | local Binding = false |
24 | local BindedKey = nil |
25 | local OIndex = 0 |
26 | local LineBox = {} |
27 | local UIButtons = {} |
28 | local Sliders = {} |
29 | local ColorPicker = { Loading = false, LastGenerated = 0 } |
30 | local Dragging = false |
31 | local DraggingUI = false |
32 | local Rainbow = false |
33 | local DragOffset = V2New() |
34 | local DraggingWhat = nil |
35 | local OldData = {} |
36 | local IgnoreList = {} |
37 | local EnemyColor = Color3.new(1, 0, 0) |
38 | local TeamColor = Color3.new(0, 1, 0) |
39 | local MenuLoaded = false |
40 | local ErrorLogging = false |
41 | local TracerPosition = V2New(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y - 135) |
42 | local DragTracerPosition = false |
43 | local SubMenu = {} |
44 | local IsSynapse = syn and not PROTOSMASHER_LOADED |
45 | local Connections = { Active = {} } |
46 | local Signal = {} Signal.__index = Signal |
47 | local GetCharacter, CurrentColorPicker, Spectating |
48 | |
49 | local QUAD_SUPPORTED_EXPLOIT = pcall(function() Drawing.new('Quad'):Remove() end) |
50 | |
51 | shared.MenuDrawingData = shared.MenuDrawingData or { Instances = {} } |
52 | shared.InstanceData = shared.InstanceData or {} |
53 | shared.RSName = shared.RSName or ('UnnamedESP_by_ic3-' .. HttpService:GenerateGUID(false)) |
54 | |
55 | local GetDataName = shared.RSName .. '-GetData' |
56 | local UpdateName = shared.RSName .. '-Update' |
57 | |
58 | local Debounce = setmetatable({}, { |
59 | __index = function(t, i) |
60 | return rawget(t, i) or false |
61 | end |
62 | }) |
63 | |
64 | if shared.UESP_InputChangedCon then shared.UESP_InputChangedCon:Disconnect() end |
65 | if shared.UESP_InputBeganCon then shared.UESP_InputBeganCon:Disconnect() end |
66 | if shared.UESP_InputEndedCon then shared.UESP_InputEndedCon:Disconnect() end |
67 | if shared.CurrentColorPicker then shared.CurrentColorPicker:Dispose() end |
68 | |
69 | local function IsStringEmpty(String) |
70 | if type(String) == 'string' then |
71 | return String:match'^%s+$' ~= nil or #String == 0 or String == '' or false; |
72 | end |
73 | |
74 | return false; |
75 | end |
76 | |
77 | local function Set(t, i, v) t[i] = v end |
78 | |
79 | local Teams = {}; |
80 | local CustomTeams = { -- Games that don't use roblox's team system |
81 | [2563455047] = { |
82 | Initialize = function() |
83 | Teams.Sheriffs = {}; -- prevent big error |
84 | Teams.Bandits = {}; -- prevent big error |
85 | local Func = game:GetService'ReplicatedStorage':WaitForChild('RogueFunc', 1); |
86 | local Event = game:GetService'ReplicatedStorage':WaitForChild('RogueEvent', 1); |
87 | local S, B = Func:InvokeServer'AllTeamData'; |
88 | |
89 | Teams.Sheriffs = S; |
90 | Teams.Bandits = B; |
91 | |
92 | Event.OnClientEvent:Connect(function(id, PlayerName, Team, Remove) -- stolen straight from decompiled src lul |
93 | if id == 'UpdateTeam' then |
94 | local TeamTable, NotTeamTable |
95 | if Team == 'Bandits' then |
96 | TeamTable = TDM.Bandits |
97 | NotTeamTable = TDM.Sheriffs |
98 | else |
99 | TeamTable = TDM.Sheriffs |
100 | NotTeamTable = TDM.Bandits |
101 | end |
102 | if Remove then |
103 | TeamTable[PlayerName] = nil |
104 | else |
105 | TeamTable[PlayerName] = true |
106 | NotTeamTable[PlayerName] = nil |
107 | end |
108 | if PlayerName == LocalPlayer.Name then |
109 | TDM.Friendlys = TeamTable |
110 | TDM.Enemies = NotTeamTable |
111 | end |
112 | end |
113 | end) |
114 | end; |
115 | CheckTeam = function(Player) |
116 | local LocalTeam = Teams.Sheriffs[LocalPlayer.Name] and Teams.Sheriffs or Teams.Bandits; |
117 | |
118 | return LocalTeam[Player.Name] and true or false; |
119 | end; |
120 | }; |
121 | [5208655184] = { |
122 | CheckTeam = function(Player) |
123 | local LocalLastName = LocalPlayer:GetAttribute'LastName' if not LocalLastName or IsStringEmpty(LocalLastName) then return true end |
124 | local PlayerLastName = Player:GetAttribute'LastName' if not PlayerLastName then return false end |
125 | |
126 | return PlayerLastName == LocalLastName |
127 | end |
128 | }; |
129 | [3541987450] = { |
130 | CheckTeam = function(Player) |
131 | local LocalStats = LocalPlayer:FindFirstChild'leaderstats'; |
132 | local LocalLastName = LocalStats and LocalStats:FindFirstChild'LastName'; if not LocalLastName or IsStringEmpty(LocalLastName.Value) then return true; end |
133 | local PlayerStats = Player:FindFirstChild'leaderstats'; |
134 | local PlayerLastName = PlayerStats and PlayerStats:FindFirstChild'LastName'; if not PlayerLastName then return false; end |
135 | |
136 | return PlayerLastName.Value == LocalLastName.Value; |
137 | end; |
138 | }; |
139 | [6032399813] = { |
140 | CheckTeam = function(Player) |
141 | local LocalStats = LocalPlayer:FindFirstChild'leaderstats'; |
142 | local LocalGuildName = LocalStats and LocalStats:FindFirstChild'Guild'; if not LocalGuildName or IsStringEmpty(LocalGuildName.Value) then return true; end |
143 | local PlayerStats = Player:FindFirstChild'leaderstats'; |
144 | local PlayerGuildName = PlayerStats and PlayerStats:FindFirstChild'Guild'; if not PlayerGuildName then return false; end |
145 | |
146 | return PlayerGuildName.Value == LocalGuildName.Value; |
147 | end; |
148 | }; |
149 | [5735553160] = { |
150 | CheckTeam = function(Player) |
151 | local LocalStats = LocalPlayer:FindFirstChild'leaderstats'; |
152 | local LocalGuildName = LocalStats and LocalStats:FindFirstChild'Guild'; if not LocalGuildName or IsStringEmpty(LocalGuildName.Value) then return true; end |
153 | local PlayerStats = Player:FindFirstChild'leaderstats'; |
154 | local PlayerGuildName = PlayerStats and PlayerStats:FindFirstChild'Guild'; if not PlayerGuildName then return false; end |
155 | |
156 | return PlayerGuildName.Value == LocalGuildName.Value; |
157 | end; |
158 | }; |
159 | }; |
160 | |
161 | local RenderList = {Instances = {}}; |
162 | |
163 | function RenderList:AddOrUpdateInstance(Instance, Obj2Draw, Text, Color) |
164 | RenderList.Instances[Instance] = { ParentInstance = Instance; Instance = Obj2Draw; Text = Text; Color = Color }; |
165 | return RenderList.Instances[Instance]; |
166 | end |
167 | |
168 | local CustomPlayerTag; |
169 | local CustomESP; |
170 | local CustomCharacter; |
171 | local GetHealth; |
172 | local GetAliveState; |
173 | local CustomRootPartName; |
174 | |
175 | local Modules = { |
176 | [292439477] = { |
177 | Initialize = function() |
178 | if not create_comm_channel or not get_comm_channel then return end |
179 | |
180 | local run_on_actor = runonactor or run_on_actor |
181 | local EventID, Event = create_comm_channel() |
182 | Event.Event:Connect(function(List) |
183 | PF_CharList = List |
184 | end) |
185 | |
186 | for Index, Actor in pairs(getactors()) do |
187 | run_on_actor(Actor, [[ |
188 | local Event = get_comm_channel(...) |
189 | |
190 | if not getrenv().shared.require then return end |
191 | |
192 | local RunService = game:GetService'RunService' |
193 | local Cache = debug.getupvalues(getrenv().shared.require)[1]._cache if not Cache then return end |
194 | local ReplicationInterface = rawget(rawget(Cache, 'ReplicationInterface'), 'module') if not ReplicationInterface then return end |
195 | local getEntry = rawget(ReplicationInterface, 'getEntry') |
196 | |
197 | if shared.UNPFHB then shared.UNPFHB:Disconnect() end |
198 | |
199 | shared.UNPFHB = RunService.Heartbeat:Connect(function() |
200 | local CharacterList = {} |
201 | |
202 | for Player, Entry in pairs(debug.getupvalues(getEntry)[1]) do |
203 | local TPO = rawget(Entry, '_thirdPersonObject') if not TPO then continue end |
204 | local Character = rawget(TPO, '_characterHash') if not Character then continue end |
205 | local Torso = rawget(Character, 'Torso') if not Torso then continue end |
206 | local HealthState = rawget(Entry, '_healthstate') |
207 | |
208 | CharacterList[Player.Name] = { |
209 | Head = Character.Head, |
210 | Torso = Character.Torso, |
211 | Health = HealthState and rawget(HealthState, 'health0') or 100, |
212 | Alive = rawget(Entry, '_alive') |
213 | } |
214 | end |
215 | |
216 | Event:Fire(CharacterList) |
217 | end) |
218 | ]], EventID) |
219 | end |
220 | end, |
221 | |
222 | CustomCharacter = function(Player) |
223 | if not shared.PF_CharMT then |
224 | shared.PF_CharMT = {} |
225 | shared.PF_CharMT.__index = shared.PF_CharMT |
226 | |
227 | function shared.PF_CharMT:FindFirstChild(Name) |
228 | return rawget(self, Name) |
229 | end |
230 | |
231 | function shared.PF_CharMT:FindFirstChildOfClass() end |
232 | end |
233 | |
234 | if PF_CharList and PF_CharList[Player.Name] then |
235 | local Character = PF_CharList[Player.Name] |
236 | |
237 | setmetatable(Character, shared.PF_CharMT) |
238 | |
239 | return Character |
240 | end |
241 | end, |
242 | |
243 | GetHealth = function(Player) |
244 | if PF_CharList and PF_CharList[Player.Name] then |
245 | return PF_CharList[Player.Name].Health |
246 | end |
247 | end, |
248 | |
249 | GetAliveState = function(Player) |
250 | if PF_CharList and PF_CharList[Player.Name] then |
251 | return PF_CharList[Player.Name].Alive |
252 | end |
253 | end, |
254 | |
255 | CustomRootPartName = 'Torso', |
256 | }; |
257 | [2950983942] = { |
258 | CustomCharacter = function(Player) |
259 | if workspace:FindFirstChild'Players' then |
260 | return workspace.Players:FindFirstChild(Player.Name); |
261 | end |
262 | end |
263 | }; |
264 | [2262441883] = { |
265 | CustomPlayerTag = function(Player) |
266 | return Player:FindFirstChild'Job' and (' [' .. Player.Job.Value .. ']') or ''; |
267 | end; |
268 | CustomESP = function() |
269 | if workspace:FindFirstChild'MoneyPrinters' then |
270 | for i, v in pairs(workspace.MoneyPrinters:GetChildren()) do |
271 | local Main = v:FindFirstChild'Main'; |
272 | local Owner = v:FindFirstChild'TrueOwner'; |
273 | local Money = v:FindFirstChild'Int' and v.Int:FindFirstChild'Money' or nil; |
274 | if Main and Owner and Money then |
275 | local O = tostring(Owner.Value); |
276 | local M = tostring(Money.Value); |
277 | |
278 | pcall(RenderList.AddOrUpdateInstance, RenderList, v, Main, string.format('Money Printer\nOwned by %s\n[%s]', O, M), Color3.fromRGB(13, 255, 227)); |
279 | end |
280 | end |
281 | end |
282 | end; |
283 | }; |
284 | -- [4581966615] = { |
285 | -- CustomESP = function() |
286 | -- if workspace:FindFirstChild'Entities' then |
287 | -- for i, v in pairs(workspace.Entities:GetChildren()) do |
288 | -- if not v.Name:match'Printer' then continue end |
289 | |
290 | -- local Properties = v:FindFirstChild'Properties' if not Properties then continue end |
291 | -- local Main = v:FindFirstChild'hitbox'; |
292 | -- local Owner = Properties:FindFirstChild'Owner'; |
293 | -- local Money = Properties:FindFirstChild'CurrentPrinted' |
294 | |
295 | -- if Main and Owner and Money then |
296 | -- local O = Owner.Value and tostring(Owner.Value) or 'no one'; |
297 | -- local M = tostring(Money.Value); |
298 | |
299 | -- pcall(RenderList.AddOrUpdateInstance, RenderList, v, Main, string.format('Money Printer\nOwned by %s\n[%s]', O, M), Color3.fromRGB(13, 255, 227)); |
300 | -- end |
301 | -- end |
302 | -- end |
303 | -- end; |
304 | -- }; |
305 | [4801598506] = { |
306 | CustomESP = function() |
307 | if workspace:FindFirstChild'Mobs' and workspace.Mobs:FindFirstChild'Forest1' then |
308 | for i, v in pairs(workspace.Mobs.Forest1:GetChildren()) do |
309 | local Main = v:FindFirstChild'Head'; |
310 | local Hum = v:FindFirstChild'Mob'; |
311 | |
312 | if Main and Hum then |
313 | pcall(RenderList.AddOrUpdateInstance, RenderList, v, Main, string.format('[%s] [%s/%s]', v.Name, Hum.Health, Hum.MaxHealth), Color3.fromRGB(13, 255, 227)); |
314 | end |
315 | end |
316 | end |
317 | end; |
318 | }; |
319 | [2555873122] = { |
320 | CustomESP = function() |
321 | if workspace:FindFirstChild'WoodPlanks' then |
322 | for i, v in pairs(workspace:GetChildren()) do |
323 | if v.Name == 'WoodPlanks' then |
324 | local Main = v:FindFirstChild'Wood'; |
325 | |
326 | if Main then |
327 | pcall(RenderList.AddOrUpdateInstance, RenderList, v, Main, 'Wood Planks', Color3.fromRGB(13, 255, 227)); |
328 | end |
329 | end |
330 | end |
331 | end |
332 | end; |
333 | }; |
334 | [5208655184] = { |
335 | CustomESP = function() |
336 | -- if workspace:FindFirstChild'Live' then |
337 | -- for i, v in pairs(workspace.Live:GetChildren()) do |
338 | -- if v.Name:sub(1, 1) == '.' then |
339 | -- local Main = v:FindFirstChild'Head'; |
340 | |
341 | -- if Main then |
342 | -- pcall(RenderList.AddOrUpdateInstance, RenderList, v, Main, v.Name:sub(2), Color3.fromRGB(250, 50, 40)); |
343 | -- end |
344 | -- end |
345 | -- end |
346 | -- end |
347 | end; |
348 | CustomPlayerTag = function(Player) |
349 | if game.PlaceVersion < 457 then return '' end |
350 | |
351 | local Name = ''; |
352 | local FirstName = Player:GetAttribute'FirstName' |
353 | |
354 | if typeof(FirstName) == 'string' and #FirstName > 0 then |
355 | local Prefix = ''; |
356 | local Extra = {}; |
357 | Name = Name .. '\n['; |
358 | |
359 | if Player:GetAttribute'Prestige' > 0 then |
360 | Name = Name .. '#' .. tostring(Player:GetAttribute'Prestige') .. ' '; |
361 | end |
362 | if not IsStringEmpty(Player:GetAttribute'HouseRank') then |
363 | Prefix = Player:GetAttribute'HouseRank' == 'Owner' and (Player:GetAttribute'Gender' == 'Female' and 'Lady ' or 'Lord ') or ''; |
364 | end |
365 | if not IsStringEmpty(FirstName) then |
366 | Name = Name .. '' .. Prefix .. FirstName; |
367 | end |
368 | if not IsStringEmpty(Player:GetAttribute'LastName') then |
369 | Name = Name .. ' ' .. Player:GetAttribute'LastName'; |
370 | end |
371 | |
372 | if not IsStringEmpty(Name) then Name = Name .. ']'; end |
373 | |
374 | local Character = GetCharacter(Player); |
375 | |
376 | if Character then |
377 | if Character and Character:FindFirstChild'Danger' then table.insert(Extra, 'D'); end |
378 | if Character:FindFirstChild'ManaAbilities' and Character.ManaAbilities:FindFirstChild'ManaSprint' then table.insert(Extra, 'D1'); end |
379 | |
380 | if Character:FindFirstChild'Mana' then table.insert(Extra, 'M' .. math.floor(Character.Mana.Value)); end |
381 | if Character:FindFirstChild'Vampirism' then table.insert(Extra, 'V'); end |
382 | if Character:FindFirstChild'Observe' then table.insert(Extra, 'ILL'); end |
383 | if Character:FindFirstChild'Inferi' then table.insert(Extra, 'NEC'); end |
384 | if Character:FindFirstChild'World\'s Pulse' then table.insert(Extra, 'DZIN'); end |
385 | if Character:FindFirstChild'Shift' then table.insert(Extra, 'MAD'); end |
386 | if Character:FindFirstChild'Head' and Character.Head:FindFirstChild'FacialMarking' then |
387 | local FM = Character.Head:FindFirstChild'FacialMarking'; |
388 | if FM.Texture == 'http://www.roblox.com/asset/?id=4072968006' then |
389 | table.insert(Extra, 'HEALER'); |
390 | elseif FM.Texture == 'http://www.roblox.com/asset/?id=4072914434' then |
391 | table.insert(Extra, 'SEER'); |
392 | elseif FM.Texture == 'http://www.roblox.com/asset/?id=4094417635' then |
393 | table.insert(Extra, 'JESTER'); |
394 | elseif FM.Texture == 'http://www.roblox.com/asset/?id=4072968656' then |
395 | table.insert(Extra, 'BLADE'); |
396 | end |
397 | end |
398 | end |
399 | if Player:FindFirstChild'Backpack' then |
400 | if Player.Backpack:FindFirstChild'Observe' then table.insert(Extra, 'ILL'); end |
401 | if Player.Backpack:FindFirstChild'Inferi' then table.insert(Extra, 'NEC'); end |
402 | if Player.Backpack:FindFirstChild'World\'s Pulse' then table.insert(Extra, 'DZIN'); end |
403 | if Player.Backpack:FindFirstChild'Shift' then table.insert(Extra, 'MAD'); end |
404 | end |
405 | |
406 | if #Extra > 0 then Name = Name .. ' [' .. table.concat(Extra, '-') .. ']'; end |
407 | end |
408 | |
409 | return Name; |
410 | end; |
411 | }; |
412 | [3541987450] = { |
413 | CustomPlayerTag = function(Player) |
414 | local Name = ''; |
415 | |
416 | if Player:FindFirstChild'leaderstats' then |
417 | Name = Name .. '\n['; |
418 | local Prefix = ''; |
419 | local Extra = {}; |
420 | if Player.leaderstats:FindFirstChild'Prestige' and Player.leaderstats.Prestige.ClassName == 'IntValue' and Player.leaderstats.Prestige.Value > 0 then |
421 | Name = Name .. '#' .. tostring(Player.leaderstats.Prestige.Value) .. ' '; |
422 | end |
423 | if Player.leaderstats:FindFirstChild'HouseRank' and Player.leaderstats:FindFirstChild'Gender' and Player.leaderstats.HouseRank.ClassName == 'StringValue' and not IsStringEmpty(Player.leaderstats.HouseRank.Value) then |
424 | Prefix = Player.leaderstats.HouseRank.Value == 'Owner' and (Player.leaderstats.Gender.Value == 'Female' and 'Lady ' or 'Lord ') or ''; |
425 | end |
426 | if Player.leaderstats:FindFirstChild'FirstName' and Player.leaderstats.FirstName.ClassName == 'StringValue' and not IsStringEmpty(Player.leaderstats.FirstName.Value) then |
427 | Name = Name .. '' .. Prefix .. Player.leaderstats.FirstName.Value; |
428 | end |
429 | if Player.leaderstats:FindFirstChild'LastName' and Player.leaderstats.LastName.ClassName == 'StringValue' and not IsStringEmpty(Player.leaderstats.LastName.Value) then |
430 | Name = Name .. ' ' .. Player.leaderstats.LastName.Value; |
431 | end |
432 | if Player.leaderstats:FindFirstChild'UberTitle' and Player.leaderstats.UberTitle.ClassName == 'StringValue' and not IsStringEmpty(Player.leaderstats.UberTitle.Value) then |
433 | Name = Name .. ', ' .. Player.leaderstats.UberTitle.Value; |
434 | end |
435 | |
436 | if not IsStringEmpty(Name) then Name = Name .. ']'; end |
437 | |
438 | local Character = GetCharacter(Player); |
439 | |
440 | if Character then |
441 | if Character and Character:FindFirstChild'Danger' then table.insert(Extra, 'D'); end |
442 | if Character:FindFirstChild'ManaAbilities' and Character.ManaAbilities:FindFirstChild'ManaSprint' then table.insert(Extra, 'D1'); end |
443 | |
444 | if Character:FindFirstChild'Mana' then table.insert(Extra, 'M' .. math.floor(Character.Mana.Value)); end |
445 | if Character:FindFirstChild'Vampirism' then table.insert(Extra, 'V'); end |
446 | if Character:FindFirstChild'Observe' then table.insert(Extra, 'ILL'); end |
447 | if Character:FindFirstChild'Inferi' then table.insert(Extra, 'NEC'); end |
448 | |
449 | if Character:FindFirstChild'World\'s Pulse' then table.insert(Extra, 'DZIN'); end |
450 | if Character:FindFirstChild'Head' and Character.Head:FindFirstChild'FacialMarking' then |
451 | local FM = Character.Head:FindFirstChild'FacialMarking'; |
452 | if FM.Texture == 'http://www.roblox.com/asset/?id=4072968006' then |
453 | table.insert(Extra, 'HEALER'); |
454 | elseif FM.Texture == 'http://www.roblox.com/asset/?id=4072914434' then |
455 | table.insert(Extra, 'SEER'); |
456 | elseif FM.Texture == 'http://www.roblox.com/asset/?id=4094417635' then |
457 | table.insert(Extra, 'JESTER'); |
458 | end |
459 | end |
460 | end |
461 | if Player:FindFirstChild'Backpack' then |
462 | if Player.Backpack:FindFirstChild'Observe' then table.insert(Extra, 'ILL'); end |
463 | if Player.Backpack:FindFirstChild'Inferi' then table.insert(Extra, 'NEC'); end |
464 | if Player.Backpack:FindFirstChild'World\'s Pulse' then table.insert(Extra, 'DZIN'); end |
465 | end |
466 | |
467 | if #Extra > 0 then Name = Name .. ' [' .. table.concat(Extra, '-') .. ']'; end |
468 | end |
469 | |
470 | return Name; |
471 | end; |
472 | }; |
473 | |
474 | [4691401390] = { -- Vast Realm |
475 | CustomCharacter = function(Player) |
476 | if workspace:FindFirstChild'Players' then |
477 | return workspace.Players:FindFirstChild(Player.Name); |
478 | end |
479 | end |
480 | }; |
481 | |
482 | [6032399813] = { -- Deepwoken [Etrean] |
483 | CustomPlayerTag = function(Player) |
484 | local Name = ''; |
485 | CharacterName = Player:GetAttribute'CharacterName'; -- could use leaderstats but lazy |
486 | |
487 | if not IsStringEmpty(CharacterName) then |
488 | Name = ('\n[%s]'):format(CharacterName); |
489 | local Character = GetCharacter(Player); |
490 | local Extra = {}; |
491 | |
492 | if Character then |
493 | local Blood, Armor = Character:FindFirstChild('Blood'), Character:FindFirstChild('Armor'); |
494 | |
495 | if Blood and Blood.ClassName == 'DoubleConstrainedValue' then |
496 | table.insert(Extra, ('B%d'):format(Blood.Value)); |
497 | end |
498 | |
499 | if Armor and Armor.ClassName == 'DoubleConstrainedValue' then |
500 | table.insert(Extra, ('A%d'):format(math.floor(Armor.Value / 10))); |
501 | end |
502 | end |
503 | |
504 | local BackpackChildren = Player.Backpack:GetChildren() |
505 | |
506 | for index = 1, #BackpackChildren do |
507 | local Oath = BackpackChildren[index] |
508 | if Oath.ClassName == 'Folder' and Oath.Name:find('Talent:Oath') then |
509 | local OathName = Oath.Name:gsub('Talent:Oath: ', '') |
510 | table.insert(Extra, OathName); |
511 | end |
512 | end |
513 | |
514 | if #Extra > 0 then Name = Name .. ' [' .. table.concat(Extra, '-') .. ']'; end |
515 | end |
516 | |
517 | return Name; |
518 | end; |
519 | }; |
520 | |
521 | [5735553160] = { -- Deepwoken [Depths] |
522 | CustomPlayerTag = function(Player) |
523 | local Name = ''; |
524 | CharacterName = Player:GetAttribute'CharacterName'; -- could use leaderstats but lazy |
525 | |
526 | if not IsStringEmpty(CharacterName) then |
527 | Name = ('\n[%s]'):format(CharacterName); |
528 | local Character = GetCharacter(Player); |
529 | local Extra = {}; |
530 | |
531 | if Character then |
532 | local Blood, Armor = Character:FindFirstChild('Blood'), Character:FindFirstChild('Armor'); |
533 | |
534 | if Blood and Blood.ClassName == 'DoubleConstrainedValue' then |
535 | table.insert(Extra, ('B%d'):format(Blood.Value)); |
536 | end |
537 | |
538 | if Armor and Armor.ClassName == 'DoubleConstrainedValue' then |
539 | table.insert(Extra, ('A%d'):format(math.floor(Armor.Value / 10))); |
540 | end |
541 | end |
542 | |
543 | local BackpackChildren = Player.Backpack:GetChildren() |
544 | |
545 | for index = 1, #BackpackChildren do |
546 | local Oath = BackpackChildren[index] |
547 | if Oath.ClassName == 'Folder' and Oath.Name:find('Talent:Oath') then |
548 | local OathName = Oath.Name:gsub('Talent:Oath: ', '') |
549 | table.insert(Extra, OathName); |
550 | end |
551 | end |
552 | |
553 | if #Extra > 0 then Name = Name .. ' [' .. table.concat(Extra, '-') .. ']'; end |
554 | end |
555 | |
556 | return Name; |
557 | end; |
558 | }; |
559 | |
560 | [3127094264] = { |
561 | CustomCharacter = function(Player) |
562 | if not _FIRST then |
563 | _FIRST = true |
564 | |
565 | pcall(function() |
566 | local GPM = rawget(require(LocalPlayer.PlayerScripts:WaitForChild('Client', 1e9):WaitForChild('Player', 1e9)), 'GetPlayerModel') |
567 | PList = debug.getupvalue(GPM, 1) |
568 | end) |
569 | end |
570 | |
571 | if PList then |
572 | local Player = rawget(PList, Player.UserId) |
573 | |
574 | if Player and Player.model then |
575 | return Player.model |
576 | end |
577 | end |
578 | end |
579 | } |
580 | }; |
581 | |
582 | if Modules[game.PlaceId] ~= nil or Modules[game.GameId] ~= nil then |
583 | local Module = Modules[game.PlaceId] or Modules[game.GameId] |
584 | |
585 | if Module.Initialize then |
586 | Module.Initialize() |
587 | end |
588 | |
589 | CustomPlayerTag = Module.CustomPlayerTag or nil |
590 | CustomESP = Module.CustomESP or nil |
591 | CustomCharacter = Module.CustomCharacter or nil |
592 | GetHealth = Module.GetHealth or nil |
593 | GetAliveState = Module.GetAliveState or nil |
594 | CustomRootPartName = Module.CustomRootPartName or nil |
595 | end |
596 | |
597 | function GetCharacter(Player) |
598 | return CustomCharacter and CustomCharacter(Player) or Player.Character |
599 | end |
600 | |
601 | function GetMouseLocation() |
602 | return UserInputService:GetMouseLocation(); |
603 | end |
604 | |
605 | function MouseHoveringOver(Values) |
606 | local X1, Y1, X2, Y2 = Values[1], Values[2], Values[3], Values[4] |
607 | local MLocation = GetMouseLocation(); |
608 | return (MLocation.x >= X1 and MLocation.x <= (X1 + (X2 - X1))) and (MLocation.y >= Y1 and MLocation.y <= (Y1 + (Y2 - Y1))); |
609 | end |
610 | |
611 | function GetTableData(t) -- basically table.foreach i dont even know why i made this |
612 | if typeof(t) ~= 'table' then return end |
613 | |
614 | return setmetatable(t, { |
615 | __call = function(t, func) |
616 | if typeof(func) ~= 'function' then return end; |
617 | for i, v in pairs(t) do |
618 | pcall(func, i, v); |
619 | end |
620 | end; |
621 | }); |
622 | end |
623 | local function Format(format, ...) |
624 | return string.format(format, ...); |
625 | end |
626 | function CalculateValue(Min, Max, Percent) |
627 | return Min + math.floor(((Max - Min) * Percent) + .5); |
628 | end |
629 | |
630 | function NewDrawing(InstanceName) |
631 | local Instance = Drawing.new(InstanceName) |
632 | |
633 | return (function(Properties) |
634 | for i, v in pairs(Properties) do |
635 | pcall(Set, Instance, i, v) |
636 | end |
637 | |
638 | return Instance |
639 | end) |
640 | end |
641 | |
642 | function Menu:AddMenuInstance(Name, DrawingType, Properties) |
643 | local Instance; |
644 | |
645 | if shared.MenuDrawingData.Instances[Name] ~= nil then |
646 | Instance = shared.MenuDrawingData.Instances[Name]; |
647 | for i, v in pairs(Properties) do |
648 | pcall(Set, Instance, i, v); |
649 | end |
650 | else |
651 | Instance = NewDrawing(DrawingType)(Properties); |
652 | end |
653 | |
654 | shared.MenuDrawingData.Instances[Name] = Instance; |
655 | |
656 | return Instance; |
657 | end |
658 | function Menu:UpdateMenuInstance(Name) |
659 | local Instance = shared.MenuDrawingData.Instances[Name]; |
660 | if Instance ~= nil then |
661 | return (function(Properties) |
662 | for i, v in pairs(Properties) do |
663 | pcall(Set, Instance, i, v); |
664 | end |
665 | return Instance; |
666 | end) |
667 | end |
668 | end |
669 | function Menu:GetInstance(Name) |
670 | return shared.MenuDrawingData.Instances[Name]; |
671 | end |
672 | |
673 | local Options = setmetatable({}, { |
674 | __call = function(t, ...) |
675 | local Arguments = {...}; |
676 | local Name = Arguments[1]; |
677 | OIndex = OIndex + 1; |
678 | rawset(t, Name, setmetatable({ |
679 | Name = Arguments[1]; |
680 | Text = Arguments[2]; |
681 | Value = Arguments[3]; |
682 | DefaultValue = Arguments[3]; |
683 | AllArgs = Arguments; |
684 | Index = OIndex; |
685 | }, { |
686 | __call = function(t, v, force) |
687 | local self = t; |
688 | |
689 | if typeof(t.Value) == 'function' then |
690 | t.Value(); |
691 | elseif typeof(t.Value) == 'EnumItem' then |
692 | local BT = Menu:GetInstance(Format('%s_BindText', t.Name)); |
693 | if not force then |
694 | Binding = true; |
695 | local Val = 0 |
696 | while Binding do |
697 | wait(); |
698 | Val = (Val + 1) % 17; |
699 | BT.Text = Val <= 8 and '|' or ''; |
700 | end |
701 | end |
702 | t.Value = force and v or BindedKey; |
703 | if BT and t.BasePosition and t.BaseSize then |
704 | BT.Text = tostring(t.Value):match'%w+%.%w+%.(.+)'; |
705 | BT.Position = t.BasePosition + V2New(t.BaseSize.X - BT.TextBounds.X - 20, -10); |
706 | end |
707 | else |
708 | local NewValue = v; |
709 | if NewValue == nil then NewValue = not t.Value; end |
710 | rawset(t, 'Value', NewValue); |
711 | |
712 | if Arguments[2] ~= nil and Menu:GetInstance'TopBar'.Visible then |
713 | if typeof(Arguments[3]) == 'number' then |
714 | local AMT = Menu:GetInstance(Format('%s_AmountText', t.Name)); |
715 | if AMT then |
716 | AMT.Text = tostring(t.Value); |
717 | end |
718 | else |
719 | local Inner = Menu:GetInstance(Format('%s_InnerCircle', t.Name)); |
720 | if Inner then Inner.Visible = t.Value; end |
721 | end |
722 | end |
723 | end |
724 | end; |
725 | })); |
726 | end; |
727 | }) |
728 | |
729 | function Load() |
730 | local _, Result = pcall(readfile, OptionsFile); |
731 | |
732 | if _ then -- extremely ugly code yea i know but i dont care p.s. i hate pcall |
733 | local _, Table = pcall(HttpService.JSONDecode, HttpService, Result); |
734 | if _ and typeof(Table) == 'table' then |
735 | for i, v in pairs(Table) do |
736 | if typeof(Options[i]) == 'table' and Options[i].Value ~= nil and (typeof(Options[i].Value) == 'boolean' or typeof(Options[i].Value) == 'number') then |
737 | Options[i].Value = v.Value; |
738 | pcall(Options[i], v.Value); |
739 | end |
740 | end |
741 | |
742 | if Table.TeamColor then TeamColor = Color3.new(Table.TeamColor.R, Table.TeamColor.G, Table.TeamColor.B) end |
743 | if Table.EnemyColor then EnemyColor = Color3.new(Table.EnemyColor.R, Table.EnemyColor.G, Table.EnemyColor.B) end |
744 | |
745 | if typeof(Table.MenuKey) == 'string' then Options.MenuKey(Enum.KeyCode[Table.MenuKey], true) end |
746 | if typeof(Table.ToggleKey) == 'string' then Options.ToggleKey(Enum.KeyCode[Table.ToggleKey], true) end |
747 | end |
748 | end |
749 | end |
750 | |
751 | Options('Enabled', 'ESP Enabled', true); |
752 | Options('ShowTeam', 'Show Team', true); |
753 | Options('ShowTeamColor', 'Show Team Color', false); |
754 | Options('ShowName', 'Show Names', true); |
755 | Options('ShowDistance', 'Show Distance', true); |
756 | Options('ShowHealth', 'Show Health', true); |
757 | Options('ShowBoxes', 'Show Boxes', true); |
758 | Options('ShowTracers', 'Show Tracers', true); |
759 | Options('ShowDot', 'Show Head Dot', false); |
760 | Options('VisCheck', 'Visibility Check', false); |
761 | Options('Crosshair', 'Crosshair', false); |
762 | Options('TextOutline', 'Text Outline', true); |
763 | -- Options('Rainbow', 'Rainbow Mode', false); |
764 | Options('TextSize', 'Text Size', syn and 18 or 14, 10, 24); -- cuz synapse fonts look weird??? |
765 | Options('MaxDistance', 'Max Distance', 2500, 100, 25000); |
766 | Options('RefreshRate', 'Refresh Rate (ms)', 5, 1, 200); |
767 | Options('YOffset', 'Y Offset', 0, -200, 200); |
768 | Options('MenuKey', 'Menu Key', Enum.KeyCode.F4, 1); |
769 | Options('ToggleKey', 'Toggle Key', Enum.KeyCode.F3, 1); |
770 | Options('ChangeColors', SENTINEL_LOADED and 'Sentinel Unsupported' or 'Change Colors', function() |
771 | if SENTINEL_LOADED then return end |
772 | |
773 | SubMenu:Show(GetMouseLocation(), 'Unnamed Colors', { |
774 | { |
775 | Type = 'Color'; Text = 'Team Color'; Color = TeamColor; |
776 | |
777 | Function = function(Circ, Position) |
778 | if tick() - ColorPicker.LastGenerated < 1 then return; end |
779 | |
780 | if shared.CurrentColorPicker then shared.CurrentColorPicker:Dispose() end |
781 | local ColorPicker = ColorPicker.new(Position - V2New(-10, 50)); |
782 | CurrentColorPicker = ColorPicker; |
783 | shared.CurrentColorPicker = CurrentColorPicker; |
784 | ColorPicker.ColorChanged:Connect(function(Color) Circ.Color = Color TeamColor = Color Options.TeamColor = Color end); |
785 | end |
786 | }; |
787 | { |
788 | Type = 'Color'; Text = 'Enemy Color'; Color = EnemyColor; |
789 | |
790 | Function = function(Circ, Position) |
791 | if tick() - ColorPicker.LastGenerated < 1 then return; end |
792 | |
793 | if shared.CurrentColorPicker then shared.CurrentColorPicker:Dispose() end |
794 | local ColorPicker = ColorPicker.new(Position - V2New(-10, 50)); |
795 | CurrentColorPicker = ColorPicker; |
796 | shared.CurrentColorPicker = CurrentColorPicker; |
797 | ColorPicker.ColorChanged:Connect(function(Color) Circ.Color = Color EnemyColor = Color Options.EnemyColor = Color end); |
798 | end |
799 | }; |
800 | { |
801 | Type = 'Button'; Text = 'Reset Colors'; |
802 | |
803 | Function = function() |
804 | EnemyColor = Color3.new(1, 0, 0); |
805 | TeamColor = Color3.new(0, 1, 0); |
806 | |
807 | local C1 = Menu:GetInstance'Sub-ColorPreview.1'; if C1 then C1.Color = TeamColor end |
808 | local C2 = Menu:GetInstance'Sub-ColorPreview.2'; if C2 then C2.Color = EnemyColor end |
809 | end |
810 | }; |
811 | { |
812 | Type = 'Button'; Text = 'Rainbow Mode'; |
813 | |
814 | Function = function() |
815 | Rainbow = not Rainbow; |
816 | end |
817 | }; |
818 | }); |
819 | end, 2); |
820 | Options('ResetSettings', 'Reset Settings', function() |
821 | for i, v in pairs(Options) do |
822 | if Options[i] ~= nil and Options[i].Value ~= nil and Options[i].Text ~= nil and (typeof(Options[i].Value) == 'boolean' or typeof(Options[i].Value) == 'number' or typeof(Options[i].Value) == 'EnumItem') then |
823 | Options[i](Options[i].DefaultValue, true); |
824 | end |
825 | end |
826 | end, 5); |
827 | Options('LoadSettings', 'Load Settings', Load, 4); |
828 | Options('SaveSettings', 'Save Settings', function() |
829 | local COptions = {}; |
830 | |
831 | for i, v in pairs(Options) do |
832 | COptions[i] = v; |
833 | end |
834 | |
835 | if typeof(TeamColor) == 'Color3' then COptions.TeamColor = { R = TeamColor.R; G = TeamColor.G; B = TeamColor.B } end |
836 | if typeof(EnemyColor) == 'Color3' then COptions.EnemyColor = { R = EnemyColor.R; G = EnemyColor.G; B = EnemyColor.B } end |
837 | |
838 | if typeof(COptions.MenuKey.Value) == 'EnumItem' then COptions.MenuKey = COptions.MenuKey.Value.Name end |
839 | if typeof(COptions.ToggleKey.Value) == 'EnumItem' then COptions.ToggleKey = COptions.ToggleKey.Value.Name end |
840 | |
841 | writefile(OptionsFile, HttpService:JSONEncode(COptions)); |
842 | end, 3); |
843 | |
844 | Load(1); |
845 | |
846 | Options('MenuOpen', nil, true); |
847 | |
848 | local function Combine(...) |
849 | local Output = {}; |
850 | for i, v in pairs{...} do |
851 | if typeof(v) == 'table' then |
852 | table.foreach(v, function(i, v) |
853 | Output[i] = v; |
854 | end) |
855 | end |
856 | end |
857 | return Output |
858 | end |
859 | |
860 | function LineBox:Create(Properties) |
861 | local Box = { Visible = true }; -- prevent errors not really though dont worry bout the Visible = true thing |
862 | |
863 | local Properties = Combine({ |
864 | Transparency = 1; |
865 | Thickness = 3; |
866 | Visible = true; |
867 | }, Properties); |
868 | |
869 | if shared.am_ic3 then -- sory just my preference, dynamic boxes will be optional in unnamed esp v2 |
870 | Box['OutlineSquare']= NewDrawing'Square'(Properties); |
871 | Box['Square'] = NewDrawing'Square'(Properties); |
872 | elseif QUAD_SUPPORTED_EXPLOIT then |
873 | Box['Quad'] = NewDrawing'Quad'(Properties); |
874 | else |
875 | Box['TopLeft'] = NewDrawing'Line'(Properties); |
876 | Box['TopRight'] = NewDrawing'Line'(Properties); |
877 | Box['BottomLeft'] = NewDrawing'Line'(Properties); |
878 | Box['BottomRight'] = NewDrawing'Line'(Properties); |
879 | end |
880 | |
881 | function Box:Update(CF, Size, Color, Properties, Parts) |
882 | if not CF or not Size then return end |
883 | |
884 | if shared.am_ic3 and typeof(Parts) == 'table' then |
885 | local AllCorners = {}; |
886 | |
887 | for i, v in pairs(Parts) do |
888 | -- if not v:IsA'BasePart' then continue end |
889 | |
890 | local CF, Size = v.CFrame, v.Size; |
891 | -- CF, Size = v.Parent:GetBoundingBox(); |
892 | |
893 | local Corners = { |
894 | Vector3.new(CF.X + Size.X / 2, CF.Y + Size.Y / 2, CF.Z + Size.Z / 2); |
895 | Vector3.new(CF.X - Size.X / 2, CF.Y + Size.Y / 2, CF.Z + Size.Z / 2); |
896 | Vector3.new(CF.X - Size.X / 2, CF.Y - Size.Y / 2, CF.Z - Size.Z / 2); |
897 | Vector3.new(CF.X + Size.X / 2, CF.Y - Size.Y / 2, CF.Z - Size.Z / 2); |
898 | Vector3.new(CF.X - Size.X / 2, CF.Y + Size.Y / 2, CF.Z - Size.Z / 2); |
899 | Vector3.new(CF.X + Size.X / 2, CF.Y + Size.Y / 2, CF.Z - Size.Z / 2); |
900 | Vector3.new(CF.X - Size.X / 2, CF.Y - Size.Y / 2, CF.Z + Size.Z / 2); |
901 | Vector3.new(CF.X + Size.X / 2, CF.Y - Size.Y / 2, CF.Z + Size.Z / 2); |
902 | }; |
903 | |
904 | for i, v in pairs(Corners) do |
905 | table.insert(AllCorners, v); |
906 | end |
907 | |
908 | -- break |
909 | end |
910 | |
911 | local xMin, yMin = Camera.ViewportSize.X, Camera.ViewportSize.Y; |
912 | local xMax, yMax = 0, 0; |
913 | local Vs = true; |
914 | |
915 | for i, v in pairs(AllCorners) do |
916 | local Position, V = WorldToViewport(v); |
917 | |
918 | if VS and not V then Vs = false break end |
919 | |
920 | if Position.X > xMax then |
921 | xMax = Position.X; |
922 | end |
923 | if Position.X < xMin then |
924 | xMin = Position.X; |
925 | end |
926 | if Position.Y > yMax then |
927 | yMax = Position.Y; |
928 | end |
929 | if Position.Y < yMin then |
930 | yMin = Position.Y; |
931 | end |
932 | end |
933 | |
934 | local xSize, ySize = xMax - xMin, yMax - yMin; |
935 | |
936 | local Outline = Box['OutlineSquare']; |
937 | local Square = Box['Square']; |
938 | Outline.Visible = Vs; |
939 | Square.Visible = Vs; |
940 | Square.Position = V2New(xMin, yMin); |
941 | Square.Color = Color; |
942 | Square.Thickness = math.floor(Outline.Thickness * 0.3); |
943 | -- Square.Position = V2New(xMin, yMin); |
944 | Square.Size = V2New(xSize, ySize); |
945 | Outline.Position = Square.Position; |
946 | Outline.Size = Square.Size; |
947 | Outline.Color = Color3.new(0.12, 0.12, 0.12); |
948 | Outline.Transparency = 0.75; |
949 | |
950 | return |
951 | end |
952 | |
953 | local TLPos, Visible1 = WorldToViewport((CF * CFrame.new( Size.X, Size.Y, 0)).Position); |
954 | local TRPos, Visible2 = WorldToViewport((CF * CFrame.new(-Size.X, Size.Y, 0)).Position); |
955 | local BLPos, Visible3 = WorldToViewport((CF * CFrame.new( Size.X, -Size.Y, 0)).Position); |
956 | local BRPos, Visible4 = WorldToViewport((CF * CFrame.new(-Size.X, -Size.Y, 0)).Position); |
957 | |
958 | local Quad = Box['Quad']; |
959 | |
960 | if QUAD_SUPPORTED_EXPLOIT then |
961 | if Visible1 and Visible2 and Visible3 and Visible4 then |
962 | Quad.Visible = true; |
963 | Quad.Color = Color; |
964 | Quad.PointA = V2New(TLPos.X, TLPos.Y); |
965 | Quad.PointB = V2New(TRPos.X, TRPos.Y); |
966 | Quad.PointC = V2New(BRPos.X, BRPos.Y); |
967 | Quad.PointD = V2New(BLPos.X, BLPos.Y); |
968 | else |
969 | Box['Quad'].Visible = false; |
970 | end |
971 | else |
972 | Visible1 = TLPos.Z > 0 -- (commented | reason: random flashes); |
973 | Visible2 = TRPos.Z > 0 -- (commented | reason: random flashes); |
974 | Visible3 = BLPos.Z > 0 -- (commented | reason: random flashes); |
975 | Visible4 = BRPos.Z > 0 -- (commented | reason: random flashes); |
976 | |
977 | -- ## BEGIN UGLY CODE |
978 | if Visible1 then |
979 | Box['TopLeft'].Visible = true; |
980 | Box['TopLeft'].Color = Color; |
981 | Box['TopLeft'].From = V2New(TLPos.X, TLPos.Y); |
982 | Box['TopLeft'].To = V2New(TRPos.X, TRPos.Y); |
983 | else |
984 | Box['TopLeft'].Visible = false; |
985 | end |
986 | if Visible2 then |
987 | Box['TopRight'].Visible = true; |
988 | Box['TopRight'].Color = Color; |
989 | Box['TopRight'].From = V2New(TRPos.X, TRPos.Y); |
990 | Box['TopRight'].To = V2New(BRPos.X, BRPos.Y); |
991 | else |
992 | Box['TopRight'].Visible = false; |
993 | end |
994 | if Visible3 then |
995 | Box['BottomLeft'].Visible = true; |
996 | Box['BottomLeft'].Color = Color; |
997 | Box['BottomLeft'].From = V2New(BLPos.X, BLPos.Y); |
998 | Box['BottomLeft'].To = V2New(TLPos.X, TLPos.Y); |
999 | else |
1000 | Box['BottomLeft'].Visible = false; |
1001 | end |
1002 | if Visible4 then |
1003 | Box['BottomRight'].Visible = true; |
1004 | Box['BottomRight'].Color = Color; |
1005 | Box['BottomRight'].From = V2New(BRPos.X, BRPos.Y); |
1006 | Box['BottomRight'].To = V2New(BLPos.X, BLPos.Y); |
1007 | else |
1008 | Box['BottomRight'].Visible = false; |
1009 | end |
1010 | if Properties and typeof(Properties) == 'table' then |
1011 | GetTableData(Properties)(function(i, v) |
1012 | pcall(Set, Box['TopLeft'], i, v); |
1013 | pcall(Set, Box['TopRight'], i, v); |
1014 | pcall(Set, Box['BottomLeft'], i, v); |
1015 | pcall(Set, Box['BottomRight'], i, v); |
1016 | end) |
1017 | end |
1018 | -- ## END UGLY CODE |
1019 | end |
1020 | end |
1021 | function Box:SetVisible(bool) |
1022 | if shared.am_ic3 then |
1023 | Box['Square'].Visible = bool; |
1024 | Box['OutlineSquare'].Visible = bool; |
1025 | elseif self.Quad then |
1026 | self.Quad.Visible = false |
1027 | elseif self.TopLeft and self.TopRight and self.BottomLeft and self.BottomRight then |
1028 | self.TopLeft.Visible = bool |
1029 | self.TopRight.Visible = bool |
1030 | self.BottomLeft.Visible = bool |
1031 | self.BottomRight.Visible = bool |
1032 | end |
1033 | end |
1034 | function Box:Remove() |
1035 | self:SetVisible(false) |
1036 | |
1037 | if shared.am_ic3 then |
1038 | Box['Square']:Remove() |
1039 | Box['OutlineSquare']:Remove() |
1040 | elseif self.Quad then |
1041 | Box['Quad']:Remove() |
1042 | elseif self.TopLeft and self.TopRight and self.BottomLeft and self.BottomRight then |
1043 | self.TopLeft:Remove() |
1044 | self.TopRight:Remove() |
1045 | self.BottomLeft:Remove() |
1046 | self.BottomRight:Remove() |
1047 | end |
1048 | end |
1049 | |
1050 | return Box; |
1051 | end |
1052 | |
1053 | local Colors = { |
1054 | White = Color3.fromHex'ffffff', |
1055 | Primary = { |
1056 | Main = Color3.fromHex'424242', |
1057 | Light = Color3.fromHex'6d6d6d', |
1058 | Dark = Color3.fromHex'1b1b1b' |
1059 | }, |
1060 | Secondary = { |
1061 | Main = Color3.fromHex'e0e0e0', |
1062 | Light = Color3.fromHex'ffffff', |
1063 | Dark = Color3.fromHex'aeaeae' |
1064 | } |
1065 | } |
1066 | |
1067 | function Connections:Listen(Connection, Function) |
1068 | local NewConnection = Connection:Connect(Function); |
1069 | table.insert(self.Active, NewConnection); |
1070 | return NewConnection; |
1071 | end |
1072 | |
1073 | function Connections:DisconnectAll() |
1074 | for Index, Connection in pairs(self.Active) do |
1075 | if Connection.Connected then |
1076 | Connection:Disconnect(); |
1077 | end |
1078 | end |
1079 | |
1080 | self.Active = {}; |
1081 | end |
1082 | |
1083 | function Signal.new() |
1084 | local self = setmetatable({ _BindableEvent = Instance.new'BindableEvent' }, Signal); |
1085 | |
1086 | return self; |
1087 | end |
1088 | |
1089 | function Signal:Connect(Callback) |
1090 | assert(typeof(Callback) == 'function', 'function expected; got ' .. typeof(Callback)); |
1091 | |
1092 | return self._BindableEvent.Event:Connect(function(...) Callback(...) end); |
1093 | end |
1094 | |
1095 | function Signal:Fire(...) |
1096 | self._BindableEvent:Fire(...); |
1097 | end |
1098 | |
1099 | function Signal:Wait() |
1100 | local Arguments = self._BindableEvent:Wait(); |
1101 | |
1102 | return Arguments; |
1103 | end |
1104 | |
1105 | function Signal:Disconnect() |
1106 | if self._BindableEvent then |
1107 | self._BindableEvent:Destroy(); |
1108 | end |
1109 | end |
1110 | |
1111 | local function GetMouseLocation() |
1112 | return UserInputService:GetMouseLocation(); |
1113 | end |
1114 | |
1115 | local function IsMouseOverDrawing(Drawing, MousePosition) |
1116 | local TopLeft = Drawing.Position; |
1117 | local BottomRight = Drawing.Position + Drawing.Size; |
1118 | local MousePosition = MousePosition or GetMouseLocation(); |
1119 | |
1120 | return MousePosition.X > TopLeft.X and MousePosition.Y > TopLeft.Y and MousePosition.X < BottomRight.X and MousePosition.Y < BottomRight.Y; |
1121 | end |
1122 | |
1123 | local ImageCache = {}; |
1124 | |
1125 | local function SetImage(Drawing, Url) |
1126 | local Data = IsSynapse and game:HttpGet(Url) or Url; |
1127 | |
1128 | Drawing[IsSynapse and 'Data' or 'Uri'] = ImageCache[Url] or Data; |
1129 | ImageCache[Url] = Data; |
1130 | |
1131 | if not IsSynapse then repeat wait() until Drawing.Loaded; end |
1132 | end |
1133 | |
1134 | -- oh god unnamed esp needs an entire rewrite, someone make a better one pls im too lazy |
1135 | -- btw the color picker was made seperately so it doesnt fit with the code of unnamed esp |
1136 | |
1137 | local function CreateDrawingsTable() |
1138 | local Drawings = { __Objects = {} }; |
1139 | local Metatable = {}; |
1140 | |
1141 | function Metatable.__index(self, Index) |
1142 | local Object = rawget(self.__Objects, Index); |
1143 | |
1144 | if not Object or (IsSynapse and not Object.__SELF.__OBJECT_EXISTS) then |
1145 | local Type = Index:sub(1, Index:find'-' - 1); |
1146 | |
1147 | Success, Object = pcall(Drawing.new, Type); |
1148 | |
1149 | if not Object or not Success then return function() end; end |
1150 | |
1151 | self.__Objects[Index] = setmetatable({ __SELF = Object; Type = Type }, { |
1152 | __call = function(self, Properties) |
1153 | local Object = rawget(self, '__SELF'); if IsSynapse and not Object.__OBJECT_EXISTS then return false, 'render object destroyed'; end |
1154 | |
1155 | if Properties == false then |
1156 | Object.Visible = false; |
1157 | Object.Transparency = 0; |
1158 | Object:Remove(); |
1159 | |
1160 | return true; |
1161 | end |
1162 | |
1163 | if typeof(Properties) == 'table' then |
1164 | for Property, Value in pairs(Properties) do |
1165 | local CanSet = true; |
1166 | |
1167 | if self.Type == 'Image' and not IsSynapse and Property == 'Size' and typeof(Value) == 'Vector2' then |
1168 | CanSet = false; |
1169 | |
1170 | spawn(function() |
1171 | repeat wait() until Object.Loaded; |
1172 | if not self.DefaultSize then rawset(self, 'DefaultSize', Object.Size) end |
1173 | |
1174 | Property = 'ScaleFactor'; |
1175 | Value = Value.X / self.DefaultSize.X; |
1176 | |
1177 | Object[Property] = Value |
1178 | end) |
1179 | end |
1180 | |
1181 | if CanSet then Object[Property] = Value end |
1182 | end |
1183 | end |
1184 | |
1185 | return Object; |
1186 | end |
1187 | }); |
1188 | |
1189 | Object.Visible = true; |
1190 | Object.Transparency = 1; -- Transparency is really Opacity with drawing api (1 being visible, 0 being invisible) |
1191 | |
1192 | if Type == 'Text' then |
1193 | if Drawing.Fonts then Object.Font = Drawing.Fonts.Monospace end |
1194 | Object.Size = 20; |
1195 | Object.Color = Color3.new(1, 1, 1); |
1196 | Object.Center = true; |
1197 | Object.Outline = true; |
1198 | OutlineOpacity = 0.5; |
1199 | elseif Type == 'Square' or Type == 'Rectangle' then |
1200 | Object.Thickness = 2; |
1201 | Object.Filled = false; |
1202 | end |
1203 | |
1204 | return self.__Objects[Index]; |
1205 | end |
1206 | |
1207 | return Object; |
1208 | end |
1209 | |
1210 | function Metatable.__call(self, Delete, ...) |
1211 | local Arguments = {Delete, ...}; |
1212 | |
1213 | if Delete == false then |
1214 | for Index, Drawing in pairs(rawget(self, '__Objects')) do |
1215 | Drawing(false); |
1216 | end |
1217 | end |
1218 | end |
1219 | |
1220 | return setmetatable(Drawings, Metatable); |
1221 | end |
1222 | |
1223 | local Images = {} |
1224 | |
1225 | spawn(function() |
1226 | Images.Ring = 'https://i.imgur.com/q4qx26f.png' |
1227 | Images.Overlay = 'https://i.imgur.com/gOCxbsR.png' |
1228 | end) |
1229 | |
1230 | function ColorPicker.new(Position, Size, Color) |
1231 | ColorPicker.LastGenerated = tick(); |
1232 | ColorPicker.Loading = true; |
1233 | |
1234 | local self = { Color = Color or Color3.new(1, 1, 1); HSV = { H = 0, S = 1, V = 1 } }; |
1235 | local Drawings = CreateDrawingsTable(); |
1236 | local Position = Position or V2New(); |
1237 | local Size = Size or 150; |
1238 | local Padding = { 10, 10, 10, 10 }; |
1239 | |
1240 | self.ColorChanged = Signal.new(); |
1241 | |
1242 | local Background = Drawings['Square-Background'] { |
1243 | Color = Color3.fromRGB(33, 33, 33); |
1244 | Filled = false; |
1245 | Visible = false; |
1246 | Position = Position - V2New(Padding[4], Padding[1]); |
1247 | Size = V2New(Size, Size) + V2New(Padding[4] + Padding[2], Padding[1] + Padding[3]); |
1248 | }; |
1249 | local ColorPreview = Drawings['Circle-Preview'] { |
1250 | Position = Position + (V2New(Size, Size) / 2); |
1251 | Radius = Size / 2 - 8; |
1252 | Filled = true; |
1253 | Thickness = 0; |
1254 | NumSides = 20; |
1255 | Color = Color3.new(1, 0, 0); |
1256 | }; |
1257 | local Main = Drawings['Image-Main'] { |
1258 | Position = Position; |
1259 | Size = V2New(Size, Size); |
1260 | }; SetImage(Main, Images.Ring); |
1261 | local Preview = Drawings['Square-Preview'] { |
1262 | Position = Main.Position + (Main.Size / 4.5); |
1263 | Size = Main.Size / 1.75; |
1264 | Color = Color3.new(1, 0, 0); |
1265 | Filled = true; |
1266 | Thickness = 0; |
1267 | }; |
1268 | local Overlay = Drawings['Image-Overlay'] { |
1269 | Position = Preview.Position; |
1270 | Size = Preview.Size; |
1271 | Transparency = 1; |
1272 | }; SetImage(Overlay, Images.Overlay); |
1273 | local CursorOutline = Drawings['Circle-CursorOutline'] { |
1274 | Radius = 4; |
1275 | Thickness = 2; |
1276 | Filled = false; |
1277 | Color = Color3.new(0.2, 0.2, 0.2); |
1278 | Position = V2New(Main.Position.X + Main.Size.X - 10, Main.Position.Y + (Main.Size.Y / 2)); |
1279 | }; |
1280 | local Cursor = Drawings['Circle-Cursor'] { |
1281 | Radius = 3; |
1282 | Transparency = 1; |
1283 | Filled = true; |
1284 | Color = Color3.new(1, 1, 1); |
1285 | Position = CursorOutline.Position; |
1286 | }; |
1287 | local CursorOutline = Drawings['Circle-CursorOutlineSquare'] { |
1288 | Radius = 4; |
1289 | Thickness = 2; |
1290 | Filled = false; |
1291 | Color = Color3.new(0.2, 0.2, 0.2); |
1292 | Position = V2New(Preview.Position.X + Preview.Size.X - 2, Preview.Position.Y + 2); |
1293 | }; |
1294 | Drawings['Circle-CursorSquare'] { |
1295 | Radius = 3; |
1296 | Transparency = 1; |
1297 | Filled = true; |
1298 | Color = Color3.new(1, 1, 1); |
1299 | Position = CursorOutline.Position; |
1300 | }; |
1301 | |
1302 | function self:UpdatePosition(Input) |
1303 | local MousePosition = V2New(Input.Position.X, Input.Position.Y + 33); |
1304 | |
1305 | if self.MouseHeld then |
1306 | if self.Item == 'Ring' then |
1307 | local Main = self.Drawings['Image-Main'] (); |
1308 | local Preview = self.Drawings['Square-Preview'] (); |
1309 | local Bounds = Main.Size / 2; |
1310 | local Center = Main.Position + Bounds; |
1311 | local Relative = MousePosition - Center; |
1312 | local Direction = Relative.unit; |
1313 | local Position = Center + Direction * Main.Size.X / 2.15; |
1314 | local H = (math.atan2(Position.Y - Center.Y, Position.X - Center.X)) * 60; |
1315 | if H < 0 then H = 360 + H; end |
1316 | H = H / 360; |
1317 | self.HSV.H = H; |
1318 | local EndColor = Color3.fromHSV(H, self.HSV.S, self.HSV.V); if EndColor ~= self.Color then self.ColorChanged:Fire(self.Color); end |
1319 | local Pointer = self.Drawings['Circle-Cursor'] { Position = Position }; |
1320 | self.Drawings['Circle-CursorOutline'] { Position = Pointer.Position }; |
1321 | Bounds = Bounds * 2; |
1322 | Preview.Color = Color3.fromHSV(H, 1, 1); |
1323 | self.Color = EndColor; |
1324 | self.Drawings['Circle-Preview'] { Color = EndColor }; |
1325 | elseif self.Item == 'HL' then |
1326 | local Preview = self.Drawings['Square-Preview'] (); |
1327 | local HSV = self.HSV; |
1328 | local Position = V2New(math.clamp(MousePosition.X, Preview.Position.X, Preview.Position.X + Preview.Size.X), math.clamp(MousePosition.Y, Preview.Position.Y, Preview.Position.Y + Preview.Size.Y)); |
1329 | HSV.S = (Position.X - Preview.Position.X) / Preview.Size.X; |
1330 | HSV.V = 1 - (Position.Y - Preview.Position.Y) / Preview.Size.Y; |
1331 | local EndColor = Color3.fromHSV(HSV.H, HSV.S, HSV.V); if EndColor ~= self.Color then self.ColorChanged:Fire(self.Color); end |
1332 | self.Color = EndColor; |
1333 | self.Drawings['Circle-Preview'] { Color = EndColor }; |
1334 | local Pointer = self.Drawings['Circle-CursorSquare'] { Position = Position }; |
1335 | self.Drawings['Circle-CursorOutlineSquare'] { Position = Pointer.Position }; |
1336 | end |
1337 | end |
1338 | end |
1339 | |
1340 | function self:HandleInput(Input, P, Type) |
1341 | if Type == 'Began' then |
1342 | if Input.UserInputType.Name == 'MouseButton1' then |
1343 | local Main = self.Drawings['Image-Main'] (); |
1344 | local SquareSV = self.Drawings['Square-Preview'] (); |
1345 | local MousePosition = V2New(Input.Position.X, Input.Position.Y + 33); |
1346 | self.MouseHeld = true; |
1347 | local Bounds = Main.Size / 2; |
1348 | local Center = Main.Position + Bounds; |
1349 | local R = (MousePosition - Center); |
1350 | |
1351 | if R.Magnitude < Bounds.X and R.Magnitude > Bounds.X - 20 then |
1352 | self.Item = 'Ring'; |
1353 | end |
1354 | |
1355 | if MousePosition.X > SquareSV.Position.X and MousePosition.Y > SquareSV.Position.Y and MousePosition.X < SquareSV.Position.X + SquareSV.Size.X and MousePosition.Y < SquareSV.Position.Y + SquareSV.Size.Y then |
1356 | self.Item = 'HL'; |
1357 | end |
1358 | |
1359 | self:UpdatePosition(Input, P); |
1360 | end |
1361 | elseif Type == 'Changed' then |
1362 | if Input.UserInputType.Name == 'MouseMovement' then |
1363 | self:UpdatePosition(Input, P); |
1364 | end |
1365 | elseif Type == 'Ended' and Input.UserInputType.Name == 'MouseButton1' then |
1366 | self.Item = nil; |
1367 | end |
1368 | end |
1369 | |
1370 | function self:Dispose() |
1371 | self.Drawings(false); |
1372 | self.UpdatePosition = nil; |
1373 | self.HandleInput = nil; |
1374 | Connections:DisconnectAll(); -- scuffed tbh |
1375 | end |
1376 | |
1377 | Connections:Listen(UserInputService.InputBegan, function(Input, Process) |
1378 | self:HandleInput(Input, Process, 'Began'); |
1379 | end); |
1380 | Connections:Listen(UserInputService.InputChanged, function(Input, Process) |
1381 | if Input.UserInputType.Name == 'MouseMovement' then |
1382 | local MousePosition = V2New(Input.Position.X, Input.Position.Y + 33); |
1383 | local Cursor = self.Drawings['Triangle-Cursor'] { |
1384 | Filled = true; |
1385 | Color = Color3.new(0.9, 0.9, 0.9); |
1386 | PointA = MousePosition + V2New(0, 0); |
1387 | PointB = MousePosition + V2New(12, 14); |
1388 | PointC = MousePosition + V2New(0, 18); |
1389 | Thickness = 0; |
1390 | }; |
1391 | end |
1392 | self:HandleInput(Input, Process, 'Changed'); |
1393 | end); |
1394 | Connections:Listen(UserInputService.InputEnded, function(Input, Process) |
1395 | self:HandleInput(Input, Process, 'Ended'); |
1396 | |
1397 | if Input.UserInputType.Name == 'MouseButton1' then |
1398 | self.MouseHeld = false |
1399 | end |
1400 | end) |
1401 | |
1402 | ColorPicker.Loading = false |
1403 | |
1404 | self.Drawings = Drawings |
1405 | |
1406 | return self |
1407 | end |
1408 | |
1409 | function SubMenu:Show(Position, Title, Options) |
1410 | self.Open = true; |
1411 | |
1412 | local Visible = true; |
1413 | local BasePosition = Position; |
1414 | local BaseSize = V2New(200, 140); |
1415 | local End = BasePosition + BaseSize; |
1416 | |
1417 | self.Bounds = { BasePosition.X, BasePosition.Y, End.X, End.Y }; |
1418 | |
1419 | delay(0.025, function() |
1420 | if not self.Open then return; end |
1421 | |
1422 | Menu:AddMenuInstance('Sub-Main', 'Square', { |
1423 | Size = BaseSize; |
1424 | Position = BasePosition; |
1425 | Filled = false; |
1426 | Color = Colors.Primary.Main; |
1427 | Thickness = 3; |
1428 | Visible = Visible; |
1429 | }); |
1430 | end); |
1431 | Menu:AddMenuInstance('Sub-TopBar', 'Square', { |
1432 | Position = BasePosition; |
1433 | Size = V2New(BaseSize.X, 10); |
1434 | Color = Colors.Primary.Dark; |
1435 | Filled = true; |
1436 | Visible = Visible; |
1437 | }); |
1438 | Menu:AddMenuInstance('Sub-TopBarTwo', 'Square', { |
1439 | Position = BasePosition + V2New(0, 10); |
1440 | Size = V2New(BaseSize.X, 20); |
1441 | Color = Colors.Primary.Main; |
1442 | Filled = true; |
1443 | Visible = Visible; |
1444 | }); |
1445 | Menu:AddMenuInstance('Sub-TopBarText', 'Text', { |
1446 | Size = 20; |
1447 | Position = shared.MenuDrawingData.Instances['Sub-TopBarTwo'].Position + V2New(15, -3); |
1448 | Text = Title or ''; |
1449 | Color = Colors.Secondary.Light; |
1450 | Visible = Visible; |
1451 | }); |
1452 | Menu:AddMenuInstance('Sub-Filling', 'Square', { |
1453 | Size = BaseSize - V2New(0, 30); |
1454 | Position = BasePosition + V2New(0, 30); |
1455 | Filled = true; |
1456 | Color = Colors.Secondary.Main; |
1457 | Transparency= .75; |
1458 | Visible = Visible; |
1459 | }); |
1460 | |
1461 | if Options then |
1462 | for Index, Option in pairs(Options) do -- currently only supports color and button(but color is a button so), planning on fully rewriting or something |
1463 | local function GetName(Name) return ('Sub-%s.%d'):format(Name, Index) end |
1464 | local Position = shared.MenuDrawingData.Instances['Sub-Filling'].Position + V2New(20, Index * 25 - 10); |
1465 | -- local BasePosition = shared.MenuDrawingData.Instances.Filling.Position + V2New(30, v.Index * 25 - 10); |
1466 | |
1467 | if Option.Type == 'Color' then |
1468 | local ColorPreview = Menu:AddMenuInstance(GetName'ColorPreview', 'Circle', { |
1469 | Position = Position; |
1470 | Color = Option.Color; |
1471 | Radius = IsSynapse and 10 or 10; |
1472 | NumSides = 10; |
1473 | Filled = true; |
1474 | Visible = true; |
1475 | }); |
1476 | local Text = Menu:AddMenuInstance(GetName'Text', 'Text', { |
1477 | Text = Option.Text; |
1478 | Position = ColorPreview.Position + V2New(15, -8); |
1479 | Size = 16; |
1480 | Color = Colors.Primary.Dark; |
1481 | Visible = true; |
1482 | }); |
1483 | UIButtons[#UIButtons + 1] = { |
1484 | FromSubMenu = true; |
1485 | Option = function() return Option.Function(ColorPreview, BasePosition + V2New(BaseSize.X, 0)) end; |
1486 | Instance = Menu:AddMenuInstance(Format('%s_Hitbox', GetName'Button'), 'Square', { |
1487 | Position = Position - V2New(20, 12); |
1488 | Size = V2New(BaseSize.X, 25); |
1489 | Visible = false; |
1490 | }); |
1491 | }; |
1492 | elseif Option.Type == 'Button' then |
1493 | UIButtons[#UIButtons + 1] = { |
1494 | FromSubMenu = true; |
1495 | Option = Option.Function; |
1496 | Instance = Menu:AddMenuInstance(Format('%s_Hitbox', GetName'Button'), 'Square', { |
1497 | Size = V2New(BaseSize.X, 20) - V2New(20, 0); |
1498 | Visible = true; |
1499 | Transparency= .5; |
1500 | Position = Position - V2New(10, 10); |
1501 | Color = Colors.Secondary.Light; |
1502 | Filled = true; |
1503 | }); |
1504 | }; |
1505 | local Text = Menu:AddMenuInstance(Format('%s_Text', GetName'Text'), 'Text', { |
1506 | Text = Option.Text; |
1507 | Size = 18; |
1508 | Position = Position + V2New(5, -10); |
1509 | Visible = true; |
1510 | Color = Colors.Primary.Dark; |
1511 | }); |
1512 | end |
1513 | end |
1514 | end |
1515 | end |
1516 | |
1517 | function SubMenu:Hide() |
1518 | self.Open = false; |
1519 | |
1520 | for i, v in pairs(shared.MenuDrawingData.Instances) do |
1521 | if i:sub(1, 3) == 'Sub' then |
1522 | v.Visible = false; |
1523 | |
1524 | if i:sub(4, 4) == ':' then -- ';' = Temporary so remove |
1525 | v:Remove(); |
1526 | shared.MenuDrawingData.Instance[i] = nil; |
1527 | end |
1528 | end |
1529 | end |
1530 | |
1531 | for i, Button in pairs(UIButtons) do |
1532 | if Button.FromSubMenu then |
1533 | UIButtons[i] = nil; |
1534 | end |
1535 | end |
1536 | |
1537 | spawn(function() -- stupid bug happens if i dont use this |
1538 | for i = 1, 10 do |
1539 | if shared.CurrentColorPicker then -- dont know why 'CurrentColorPicker' isnt a variable in this |
1540 | shared.CurrentColorPicker:Dispose(); |
1541 | end |
1542 | wait(0.1); |
1543 | end |
1544 | end) |
1545 | |
1546 | CurrentColorPicker = nil; |
1547 | end |
1548 | |
1549 | function CreateMenu(NewPosition) -- Create Menu |
1550 | MenuLoaded = false; |
1551 | UIButtons = {}; |
1552 | Sliders = {}; |
1553 | |
1554 | local BaseSize = V2New(300, 625); |
1555 | local BasePosition = NewPosition or V2New(Camera.ViewportSize.X / 8 - (BaseSize.X / 2), Camera.ViewportSize.Y / 2 - (BaseSize.Y / 2)); |
1556 | |
1557 | BasePosition = V2New(math.clamp(BasePosition.X, 0, Camera.ViewportSize.X), math.clamp(BasePosition.Y, 0, Camera.ViewportSize.Y)); |
1558 | |
1559 | Menu:AddMenuInstance('CrosshairX', 'Line', { |
1560 | Visible = false; |
1561 | Color = Color3.new(0, 1, 0); |
1562 | Transparency = 1; |
1563 | Thickness = 1; |
1564 | }); |
1565 | Menu:AddMenuInstance('CrosshairY', 'Line', { |
1566 | Visible = false; |
1567 | Color = Color3.new(0, 1, 0); |
1568 | Transparency = 1; |
1569 | Thickness = 1; |
1570 | }); |
1571 | |
1572 | delay(.025, function() -- since zindex doesnt exist |
1573 | Menu:AddMenuInstance('Main', 'Square', { |
1574 | Size = BaseSize; |
1575 | Position = BasePosition; |
1576 | Filled = false; |
1577 | Color = Colors.Primary.Main; |
1578 | Thickness = 3; |
1579 | Visible = true; |
1580 | }); |
1581 | end); |
1582 | Menu:AddMenuInstance('TopBar', 'Square', { |
1583 | Position = BasePosition; |
1584 | Size = V2New(BaseSize.X, 15); |
1585 | Color = Colors.Primary.Dark; |
1586 | Filled = true; |
1587 | Visible = true; |
1588 | }); |
1589 | Menu:AddMenuInstance('TopBarTwo', 'Square', { |
1590 | Position = BasePosition + V2New(0, 15); |
1591 | Size = V2New(BaseSize.X, 45); |
1592 | Color = Colors.Primary.Main; |
1593 | Filled = true; |
1594 | Visible = true; |
1595 | }); |
1596 | Menu:AddMenuInstance('TopBarText', 'Text', { |
1597 | Size = 25; |
1598 | Position = shared.MenuDrawingData.Instances.TopBarTwo.Position + V2New(25, 10); |
1599 | Text = 'Unnamed ESP'; |
1600 | Color = Colors.Secondary.Light; |
1601 | Visible = true; |
1602 | Transparency= 1; -- proto outline fix |
1603 | Outline = true; |
1604 | OutlineOpacity = 0.5; |
1605 | }); |
1606 | Menu:AddMenuInstance('TopBarTextBR', 'Text', { |
1607 | Size = 18; |
1608 | Position = shared.MenuDrawingData.Instances.TopBarTwo.Position + V2New(BaseSize.X - 75, 25); |
1609 | Text = 'by ic3w0lf'; |
1610 | Color = Colors.Secondary.Light; |
1611 | Visible = true; |
1612 | Transparency= 1; |
1613 | Outline = true; |
1614 | OutlineOpacity = 0.5; |
1615 | }); |
1616 | Menu:AddMenuInstance('Filling', 'Square', { |
1617 | Size = BaseSize - V2New(0, 60); |
1618 | Position = BasePosition + V2New(0, 60); |
1619 | Filled = true; |
1620 | Color = Colors.Secondary.Main; |
1621 | Transparency= .35; |
1622 | Visible = true; |
1623 | }); |
1624 | |
1625 | local CPos = 0; |
1626 | |
1627 | GetTableData(Options)(function(i, v) |
1628 | if typeof(v.Value) == 'boolean' and not IsStringEmpty(v.Text) and v.Text ~= nil then |
1629 | CPos = CPos + 25; |
1630 | local BaseSize = V2New(BaseSize.X, 30); |
1631 | local BasePosition = shared.MenuDrawingData.Instances.Filling.Position + V2New(30, v.Index * 25 - 10); |
1632 | UIButtons[#UIButtons + 1] = { |
1633 | Option = v; |
1634 | Instance = Menu:AddMenuInstance(Format('%s_Hitbox', v.Name), 'Square', { |
1635 | Position = BasePosition - V2New(30, 15); |
1636 | Size = BaseSize; |
1637 | Visible = false; |
1638 | }); |
1639 | }; |
1640 | Menu:AddMenuInstance(Format('%s_OuterCircle', v.Name), 'Circle', { |
1641 | Radius = 10; |
1642 | Position = BasePosition; |
1643 | Color = Colors.Secondary.Light; |
1644 | Filled = true; |
1645 | Visible = true; |
1646 | }); |
1647 | Menu:AddMenuInstance(Format('%s_InnerCircle', v.Name), 'Circle', { |
1648 | Radius = 7; |
1649 | Position = BasePosition; |
1650 | Color = Colors.Secondary.Dark; |
1651 | Filled = true; |
1652 | Visible = v.Value; |
1653 | }); |
1654 | Menu:AddMenuInstance(Format('%s_Text', v.Name), 'Text', { |
1655 | Text = v.Text; |
1656 | Size = 20; |
1657 | Position = BasePosition + V2New(20, -10); |
1658 | Visible = true; |
1659 | Color = Colors.Secondary.Light; |
1660 | Transparency= 1; |
1661 | Outline = true; |
1662 | OutlineOpacity = 0.5; |
1663 | }); |
1664 | end |
1665 | end) |
1666 | GetTableData(Options)(function(i, v) -- just to make sure certain things are drawn before or after others, too lazy to actually sort table |
1667 | if typeof(v.Value) == 'number' then |
1668 | CPos = CPos + 25; |
1669 | |
1670 | local BaseSize = V2New(BaseSize.X, 30); |
1671 | local BasePosition = shared.MenuDrawingData.Instances.Filling.Position + V2New(0, CPos - 10); |
1672 | |
1673 | local Line = Menu:AddMenuInstance(Format('%s_SliderLine', v.Name), 'Square', { |
1674 | Transparency = 1; |
1675 | Color = Colors.Secondary.Light; |
1676 | -- Thickness = 3; |
1677 | Filled = true; |
1678 | Visible = true; |
1679 | Position = BasePosition + V2New(15, -5); |
1680 | Size = BaseSize - V2New(30, 10); |
1681 | Transparency = 0.5; |
1682 | }); |
1683 | local Slider = Menu:AddMenuInstance(Format('%s_Slider', v.Name), 'Square', { |
1684 | Visible = true; |
1685 | Filled = true; |
1686 | Color = Colors.Primary.Dark; |
1687 | Size = V2New(5, Line.Size.Y); |
1688 | Transparency = 0.5; |
1689 | }); |
1690 | local Text = Menu:AddMenuInstance(Format('%s_Text', v.Name), 'Text', { |
1691 | Text = v.Text; |
1692 | Size = 20; |
1693 | Center = true; |
1694 | Transparency = 1; |
1695 | Outline = true; |
1696 | OutlineOpacity = 0.5; |
1697 | Visible = true; |
1698 | Color = Colors.White; |
1699 | }); Text.Position = Line.Position + (Line.Size / 2) - V2New(0, Text.TextBounds.Y / 1.75); |
1700 | local AMT = Menu:AddMenuInstance(Format('%s_AmountText', v.Name), 'Text', { |
1701 | Text = tostring(v.Value); |
1702 | Size = 22; |
1703 | Center = true; |
1704 | Transparency = 1; |
1705 | Outline = true; |
1706 | OutlineOpacity = 0.5; |
1707 | Visible = true; |
1708 | Color = Colors.White; |
1709 | Position = Text.Position; |
1710 | }); |
1711 | |
1712 | local CSlider = {Slider = Slider; Line = Line; Min = v.AllArgs[4]; Max = v.AllArgs[5]; Option = v}; |
1713 | local Dummy = Instance.new'NumberValue'; |
1714 | |
1715 | Dummy:GetPropertyChangedSignal'Value':Connect(function() |
1716 | Text.Transparency = Dummy.Value; |
1717 | -- Text.OutlineTransparency = 1 - Dummy.Value; |
1718 | AMT.Transparency = 1 - Dummy.Value; |
1719 | end); |
1720 | |
1721 | Dummy.Value = 1; |
1722 | |
1723 | function CSlider:ShowValue(Bool) |
1724 | self.ShowingValue = Bool; |
1725 | |
1726 | TweenService:Create(Dummy, TweenInfo.new(0.5, Enum.EasingStyle.Quart, Enum.EasingDirection.Out), { Value = Bool and 0 or 1 }):Play(); |
1727 | end |
1728 | |
1729 | Sliders[#Sliders + 1] = CSlider; |
1730 | |
1731 | -- local Percent = (v.Value / CSlider.Max) * 100; |
1732 | -- local Size = math.abs(Line.From.X - Line.To.X); |
1733 | -- local Value = Size * (Percent / 100); -- this shit's inaccurate but fuck it i'm not even gonna bother fixing it |
1734 | |
1735 | Slider.Position = Line.Position + V2New(35, 0); |
1736 | |
1737 | v.BaseSize = BaseSize; |
1738 | v.BasePosition = BasePosition; |
1739 | -- AMT.Position = BasePosition + V2New(BaseSize.X - AMT.TextBounds.X - 10, -10) |
1740 | end |
1741 | end) |
1742 | local FirstItem = false; |
1743 | GetTableData(Options)(function(i, v) -- just to make sure certain things are drawn before or after others, too lazy to actually sort table |
1744 | if typeof(v.Value) == 'EnumItem' then |
1745 | CPos = CPos + (not FirstItem and 30 or 25); |
1746 | FirstItem = true; |
1747 | |
1748 | local BaseSize = V2New(BaseSize.X, FirstItem and 30 or 25); |
1749 | local BasePosition = shared.MenuDrawingData.Instances.Filling.Position + V2New(0, CPos - 10); |
1750 | |
1751 | UIButtons[#UIButtons + 1] = { |
1752 | Option = v; |
1753 | Instance = Menu:AddMenuInstance(Format('%s_Hitbox', v.Name), 'Square', { |
1754 | Size = V2New(BaseSize.X, 20) - V2New(30, 0); |
1755 | Visible = true; |
1756 | Transparency= .5; |
1757 | Position = BasePosition + V2New(15, -10); |
1758 | Color = Colors.Secondary.Light; |
1759 | Filled = true; |
1760 | }); |
1761 | }; |
1762 | local Text = Menu:AddMenuInstance(Format('%s_Text', v.Name), 'Text', { |
1763 | Text = v.Text; |
1764 | Size = 20; |
1765 | Position = BasePosition + V2New(20, -10); |
1766 | Visible = true; |
1767 | Color = Colors.Secondary.Light; |
1768 | Transparency= 1; |
1769 | Outline = true; |
1770 | OutlineOpacity = 0.5; |
1771 | }); |
1772 | local BindText = Menu:AddMenuInstance(Format('%s_BindText', v.Name), 'Text', { |
1773 | Text = tostring(v.Value):match'%w+%.%w+%.(.+)'; |
1774 | Size = 20; |
1775 | Position = BasePosition; |
1776 | Visible = true; |
1777 | Color = Colors.Secondary.Light; |
1778 | Transparency= 1; |
1779 | Outline = true; |
1780 | OutlineOpacity = 0.5; |
1781 | }); |
1782 | |
1783 | Options[i].BaseSize = BaseSize; |
1784 | Options[i].BasePosition = BasePosition; |
1785 | BindText.Position = BasePosition + V2New(BaseSize.X - BindText.TextBounds.X - 20, -10); |
1786 | end |
1787 | end) |
1788 | GetTableData(Options)(function(i, v) -- just to make sure certain things are drawn before or after others, too lazy to actually sort table |
1789 | if typeof(v.Value) == 'function' then |
1790 | local BaseSize = V2New(BaseSize.X, 30); |
1791 | local BasePosition = shared.MenuDrawingData.Instances.Filling.Position + V2New(0, CPos + (25 * v.AllArgs[4]) - 35); |
1792 | |
1793 | UIButtons[#UIButtons + 1] = { |
1794 | Option = v; |
1795 | Instance = Menu:AddMenuInstance(Format('%s_Hitbox', v.Name), 'Square', { |
1796 | Size = V2New(BaseSize.X, 20) - V2New(30, 0); |
1797 | Visible = true; |
1798 | Transparency= .5; |
1799 | Position = BasePosition + V2New(15, -10); |
1800 | Color = Colors.Secondary.Light; |
1801 | Filled = true; |
1802 | }); |
1803 | }; |
1804 | local Text = Menu:AddMenuInstance(Format('%s_Text', v.Name), 'Text', { |
1805 | Text = v.Text; |
1806 | Size = 20; |
1807 | Position = BasePosition + V2New(20, -10); |
1808 | Visible = true; |
1809 | Color = Colors.Secondary.Light; |
1810 | Transparency= 1; |
1811 | Outline = true; |
1812 | OutlineOpacity = 0.5; |
1813 | }); |
1814 | |
1815 | -- BindText.Position = BasePosition + V2New(BaseSize.X - BindText.TextBounds.X - 10, -10); |
1816 | end |
1817 | end) |
1818 | |
1819 | delay(.1, function() |
1820 | MenuLoaded = true; |
1821 | end); |
1822 | |
1823 | -- this has to be at the bottom cuz proto drawing api doesnt have zindex :triumph: |
1824 | Menu:AddMenuInstance('Cursor1', 'Line', { |
1825 | Visible = false; |
1826 | Color = Color3.new(1, 0, 0); |
1827 | Transparency = 1; |
1828 | Thickness = 2; |
1829 | }); |
1830 | Menu:AddMenuInstance('Cursor2', 'Line', { |
1831 | Visible = false; |
1832 | Color = Color3.new(1, 0, 0); |
1833 | Transparency = 1; |
1834 | Thickness = 2; |
1835 | }); |
1836 | Menu:AddMenuInstance('Cursor3', 'Line', { |
1837 | Visible = false; |
1838 | Color = Color3.new(1, 0, 0); |
1839 | Transparency = 1; |
1840 | Thickness = 2; |
1841 | }); |
1842 | end |
1843 | |
1844 | CreateMenu(); |
1845 | delay(0.1, function() |
1846 | SubMenu:Show(V2New()); -- Create the submenu |
1847 | SubMenu:Hide(); |
1848 | end); |
1849 | |
1850 | shared.UESP_InputChangedCon = UserInputService.InputChanged:Connect(function(input) |
1851 | if input.UserInputType.Name == 'MouseMovement' and Options.MenuOpen.Value then |
1852 | for i, v in pairs(Sliders) do |
1853 | local Values = { |
1854 | v.Line.Position.X; |
1855 | v.Line.Position.Y; |
1856 | v.Line.Position.X + v.Line.Size.X; |
1857 | v.Line.Position.Y + v.Line.Size.Y; |
1858 | }; |
1859 | if MouseHoveringOver(Values) then |
1860 | v:ShowValue(true); |
1861 | else |
1862 | if not MouseHeld then v:ShowValue(false); end |
1863 | end |
1864 | end |
1865 | end |
1866 | end) |
1867 | shared.UESP_InputBeganCon = UserInputService.InputBegan:Connect(function(input) |
1868 | if input.UserInputType.Name == 'MouseButton1' and Options.MenuOpen.Value then |
1869 | MouseHeld = true; |
1870 | local Bar = Menu:GetInstance'TopBar'; |
1871 | local Values = { |
1872 | Bar.Position.X; |
1873 | Bar.Position.Y; |
1874 | Bar.Position.X + Bar.Size.X; |
1875 | Bar.Position.Y + Bar.Size.Y; |
1876 | } |
1877 | if MouseHoveringOver(Values) then |
1878 | DraggingUI = true; |
1879 | DragOffset = Menu:GetInstance'Main'.Position - GetMouseLocation(); |
1880 | else |
1881 | for i, v in pairs(Sliders) do |
1882 | local Values = { |
1883 | v.Line.Position.X; |
1884 | v.Line.Position.Y; |
1885 | v.Line.Position.X + v.Line.Size.X; |
1886 | v.Line.Position.Y + v.Line.Size.Y; |
1887 | -- v.Line.From.X - (v.Slider.Radius); |
1888 | -- v.Line.From.Y - (v.Slider.Radius); |
1889 | -- v.Line.To.X + (v.Slider.Radius); |
1890 | -- v.Line.To.Y + (v.Slider.Radius); |
1891 | }; |
1892 | if MouseHoveringOver(Values) then |
1893 | DraggingWhat = v; |
1894 | Dragging = true; |
1895 | break |
1896 | end |
1897 | end |
1898 | |
1899 | if not Dragging then |
1900 | local Values = { |
1901 | TracerPosition.X - 10; |
1902 | TracerPosition.Y - 10; |
1903 | TracerPosition.X + 10; |
1904 | TracerPosition.Y + 10; |
1905 | }; |
1906 | if MouseHoveringOver(Values) then |
1907 | DragTracerPosition = true; |
1908 | end |
1909 | end |
1910 | end |
1911 | end |
1912 | end) |
1913 | shared.UESP_InputEndedCon = UserInputService.InputEnded:Connect(function(input) |
1914 | if input.UserInputType.Name == 'MouseButton1' and Options.MenuOpen.Value then |
1915 | MouseHeld = false; |
1916 | DragTracerPosition = false; |
1917 | local IgnoreOtherInput = false; |
1918 | |
1919 | if SubMenu.Open and not MouseHoveringOver(SubMenu.Bounds) then |
1920 | if CurrentColorPicker and IsMouseOverDrawing(CurrentColorPicker.Drawings['Square-Background']()) then IgnoreOtherInput = true; end |
1921 | if not IgnoreOtherInput then SubMenu:Hide() end |
1922 | end |
1923 | |
1924 | if not IgnoreOtherInput then |
1925 | for i, v in pairs(UIButtons) do |
1926 | if SubMenu.Open and MouseHoveringOver(SubMenu.Bounds) and not v.FromSubMenu then continue end |
1927 | |
1928 | local Values = { |
1929 | v.Instance.Position.X; |
1930 | v.Instance.Position.Y; |
1931 | v.Instance.Position.X + v.Instance.Size.X; |
1932 | v.Instance.Position.Y + v.Instance.Size.Y; |
1933 | }; |
1934 | if MouseHoveringOver(Values) then |
1935 | v.Option(); |
1936 | IgnoreOtherInput = true; |
1937 | break -- prevent clicking 2 options |
1938 | end |
1939 | end |
1940 | for i, v in pairs(Sliders) do |
1941 | if IgnoreOtherInput then break end |
1942 | |
1943 | local Values = { |
1944 | v.Line.Position.X; |
1945 | v.Line.Position.Y; |
1946 | v.Line.Position.X + v.Line.Size.X; |
1947 | v.Line.Position.Y + v.Line.Size.Y; |
1948 | }; |
1949 | if not MouseHoveringOver(Values) then |
1950 | v:ShowValue(false); |
1951 | end |
1952 | end |
1953 | end |
1954 | elseif input.UserInputType.Name == 'MouseButton2' and Options.MenuOpen.Value and not DragTracerPosition then |
1955 | local Values = { |
1956 | TracerPosition.X - 10; |
1957 | TracerPosition.Y - 10; |
1958 | TracerPosition.X + 10; |
1959 | TracerPosition.Y + 10; |
1960 | } |
1961 | if MouseHoveringOver(Values) then |
1962 | DragTracerPosition = false; |
1963 | TracerPosition = V2New(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y - 135); |
1964 | end |
1965 | elseif input.UserInputType.Name == 'Keyboard' then |
1966 | if Binding then |
1967 | BindedKey = input.KeyCode; |
1968 | Binding = false; |
1969 | elseif input.KeyCode == Options.MenuKey.Value or (input.KeyCode == Enum.KeyCode.Home and UserInputService:IsKeyDown(Enum.KeyCode.LeftControl)) then |
1970 | Options.MenuOpen(); |
1971 | elseif input.KeyCode == Options.ToggleKey.Value then |
1972 | Options.Enabled(); |
1973 | elseif input.KeyCode.Name == 'F1' and UserInputService:IsMouseButtonPressed(1) and shared.am_ic3 then -- hehe hiden spectate feature cuz why not |
1974 | local HD, LPlayer, LCharacter = 0.95; |
1975 | |
1976 | for i, Player in pairs(Players:GetPlayers()) do |
1977 | local Character = GetCharacter(Player); |
1978 | |
1979 | if Player ~= LocalPlayer and Player ~= Spectating and Character and Character:FindFirstChild'HumanoidRootPart' then |
1980 | local Head = Character:FindFirstChild'Head'; |
1981 | local Humanoid = Character:FindFirstChildOfClass'Humanoid'; |
1982 | |
1983 | if Head then |
1984 | local Distance = (Camera.CFrame.Position - Head.Position).Magnitude; |
1985 | |
1986 | if Distance > Options.MaxDistance.Value then continue; end |
1987 | |
1988 | local Direction = -(Camera.CFrame.Position - Mouse.Hit.Position).unit; |
1989 | local Relative = Character.Head.Position - Camera.CFrame.Position; |
1990 | local Unit = Relative.unit; |
1991 | |
1992 | local DP = Direction:Dot(Unit); |
1993 | |
1994 | if DP > HD then |
1995 | HD = DP; |
1996 | LPlayer = Player; |
1997 | LCharacter = Character; |
1998 | end |
1999 | end |
2000 | end |
2001 | end |
2002 | |
2003 | if LPlayer and LPlayer ~= Spectating and LCharacter then |
2004 | Camera.CameraSubject = LCharacter.Head; |
2005 | Spectating = LPlayer; |
2006 | else |
2007 | if LocalPlayer.Character and LocalPlayer.Character:FindFirstChildOfClass'Humanoid' then |
2008 | Camera.CameraSubject = LocalPlayer.Character:FindFirstChildOfClass'Humanoid'; |
2009 | Spectating = nil; |
2010 | end |
2011 | end |
2012 | end |
2013 | end |
2014 | end) |
2015 | |
2016 | local function CameraCon() -- unnamed esp v1 sucks |
2017 | workspace.CurrentCamera:GetPropertyChangedSignal'ViewportSize':Connect(function() |
2018 | TracerPosition = V2New(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y - 135); |
2019 | end); |
2020 | end |
2021 | |
2022 | CameraCon(); |
2023 | |
2024 | local function ToggleMenu() |
2025 | if Options.MenuOpen.Value then |
2026 | GetTableData(shared.MenuDrawingData.Instances)(function(i, v) |
2027 | if OldData[v] then |
2028 | pcall(Set, v, 'Visible', true); |
2029 | end |
2030 | end) |
2031 | else |
2032 | GetTableData(shared.MenuDrawingData.Instances)(function(i, v) |
2033 | OldData[v] = v.Visible; |
2034 | if v.Visible then |
2035 | pcall(Set, v, 'Visible', false); |
2036 | end |
2037 | end) |
2038 | end |
2039 | end |
2040 | |
2041 | local LastRayIgnoreUpdate, RayIgnoreList = 0, {} |
2042 | |
2043 | local function CheckRay(Instance, Distance, Position, Unit) |
2044 | local Pass = true; |
2045 | local Model = Instance; |
2046 | |
2047 | if Distance > 999 then return false; end |
2048 | |
2049 | if Instance.ClassName == 'Player' then |
2050 | Model = GetCharacter(Instance); |
2051 | end |
2052 | |
2053 | if not Model then |
2054 | Model = Instance.Parent; |
2055 | |
2056 | if Model.Parent == workspace then |
2057 | Model = Instance; |
2058 | end |
2059 | end |
2060 | |
2061 | if not Model then return false end |
2062 | |
2063 | local _Ray = Ray.new(Position, Unit * Distance) |
2064 | |
2065 | if tick() - LastRayIgnoreUpdate > 3 then |
2066 | LastRayIgnoreUpdate = tick() |
2067 | |
2068 | table.clear(RayIgnoreList) |
2069 | |
2070 | table.insert(RayIgnoreList, LocalPlayer.Character) |
2071 | table.insert(RayIgnoreList, Camera) |
2072 | |
2073 | if Mouse.TargetFilter then table.insert(RayIgnoreList, Mouse.TargetFilter) end |
2074 | |
2075 | if #IgnoreList > 64 then |
2076 | while #IgnoreList > 64 do |
2077 | table.remove(IgnoreList, 1) |
2078 | end |
2079 | end |
2080 | |
2081 | for i, v in pairs(IgnoreList) do table.insert(RayIgnoreList, v) end |
2082 | end |
2083 | |
2084 | local Hit = workspace:FindPartOnRayWithIgnoreList(_Ray, RayIgnoreList) |
2085 | |
2086 | if Hit and not Hit:IsDescendantOf(Model) then |
2087 | Pass = false; |
2088 | if Hit.Transparency >= .3 or not Hit.CanCollide and Hit.ClassName ~= Terrain then -- Detect invisible walls |
2089 | table.insert(IgnoreList, Hit) |
2090 | -- IgnoreList[#IgnoreList + 1] = Hit; |
2091 | end |
2092 | end |
2093 | |
2094 | return Pass; |
2095 | end |
2096 | |
2097 | local function CheckTeam(Player) |
2098 | if Player.Neutral and LocalPlayer.Neutral then return true; end |
2099 | return Player.TeamColor == LocalPlayer.TeamColor; |
2100 | end |
2101 | |
2102 | local CustomTeam = CustomTeams[game.PlaceId]; |
2103 | |
2104 | if CustomTeam ~= nil then |
2105 | if CustomTeam.Initialize then ypcall(CustomTeam.Initialize) end |
2106 | |
2107 | CheckTeam = CustomTeam.CheckTeam; |
2108 | end |
2109 | |
2110 | local function CheckPlayer(Player, Character) |
2111 | if not Options.Enabled.Value then return false end |
2112 | |
2113 | local Pass = true; |
2114 | local Distance = 0; |
2115 | |
2116 | if Player ~= LocalPlayer and Character then |
2117 | if not Options.ShowTeam.Value and CheckTeam(Player) then |
2118 | Pass = false; |
2119 | end |
2120 | |
2121 | local Head = Character:FindFirstChild'Head'; |
2122 | |
2123 | if Pass and Character and Head then |
2124 | Distance = (Camera.CFrame.Position - Head.Position).Magnitude; |
2125 | if Options.VisCheck.Value then |
2126 | Pass = CheckRay(Player, Distance, Camera.CFrame.Position, (Head.Position - Camera.CFrame.Position).unit); |
2127 | end |
2128 | if Distance > Options.MaxDistance.Value then |
2129 | Pass = false; |
2130 | end |
2131 | end |
2132 | else |
2133 | Pass = false; |
2134 | end |
2135 | |
2136 | return Pass, Distance; |
2137 | end |
2138 | |
2139 | local function CheckDistance(Instance) |
2140 | if not Options.Enabled.Value then return false end |
2141 | |
2142 | local Pass = true; |
2143 | local Distance = 0; |
2144 | |
2145 | if Instance ~= nil then |
2146 | Distance = (Camera.CFrame.Position - Instance.Position).Magnitude; |
2147 | if Options.VisCheck.Value then |
2148 | Pass = CheckRay(Instance, Distance, Camera.CFrame.Position, (Instance.Position - Camera.CFrame.Position).unit); |
2149 | end |
2150 | if Distance > Options.MaxDistance.Value then |
2151 | Pass = false; |
2152 | end |
2153 | else |
2154 | Pass = false; |
2155 | end |
2156 | |
2157 | return Pass, Distance; |
2158 | end |
2159 | |
2160 | local function UpdatePlayerData() |
2161 | if (tick() - LastRefresh) > (Options.RefreshRate.Value / 1000) then |
2162 | LastRefresh = tick(); |
2163 | if CustomESP and Options.Enabled.Value then |
2164 | local a, b = pcall(CustomESP); |
2165 | end |
2166 | for i, v in pairs(RenderList.Instances) do |
2167 | if v.Instance ~= nil and v.Instance.Parent ~= nil and v.Instance:IsA'BasePart' then |
2168 | local Data = shared.InstanceData[v.Instance:GetDebugId()] or { Instances = {}; DontDelete = true }; |
2169 | |
2170 | Data.Instance = v.Instance; |
2171 | |
2172 | Data.Instances['OutlineTracer'] = Data.Instances['OutlineTracer'] or NewDrawing'Line'{ |
2173 | Transparency = 0.75; |
2174 | Thickness = 5; |
2175 | Color = Color3.new(0.1, 0.1, 0.1); |
2176 | } |
2177 | Data.Instances['Tracer'] = Data.Instances['Tracer'] or NewDrawing'Line'{ |
2178 | Transparency = 1; |
2179 | Thickness = 2; |
2180 | } |
2181 | Data.Instances['NameTag'] = Data.Instances['NameTag'] or NewDrawing'Text'{ |
2182 | Size = Options.TextSize.Value; |
2183 | Center = true; |
2184 | Outline = Options.TextOutline.Value; |
2185 | Visible = true; |
2186 | }; |
2187 | Data.Instances['DistanceTag'] = Data.Instances['DistanceTag'] or NewDrawing'Text'{ |
2188 | Size = Options.TextSize.Value - 1; |
2189 | Center = true; |
2190 | Outline = Options.TextOutline.Value; |
2191 | Visible = true; |
2192 | }; |
2193 | |
2194 | local NameTag = Data.Instances['NameTag']; |
2195 | local DistanceTag = Data.Instances['DistanceTag']; |
2196 | local Tracer = Data.Instances['Tracer']; |
2197 | local OutlineTracer = Data.Instances['OutlineTracer']; |
2198 | |
2199 | local Pass, Distance = CheckDistance(v.Instance); |
2200 | |
2201 | if Pass then |
2202 | local ScreenPosition, Vis = WorldToViewport(v.Instance.Position); |
2203 | local Color = v.Color; |
2204 | local OPos = Camera.CFrame:pointToObjectSpace(v.Instance.Position); |
2205 | |
2206 | if ScreenPosition.Z < 0 then |
2207 | local AT = math.atan2(OPos.Y, OPos.X) + math.pi; |
2208 | OPos = CFrame.Angles(0, 0, AT):vectorToWorldSpace((CFrame.Angles(0, math.rad(89.9), 0):vectorToWorldSpace(V3New(0, 0, -1)))); |
2209 | end |
2210 | |
2211 | local Position = WorldToViewport(Camera.CFrame:pointToWorldSpace(OPos)); |
2212 | |
2213 | if Options.ShowTracers.Value then |
2214 | Tracer.Transparency = math.clamp(Distance / 200, 0.45, 0.8); |
2215 | Tracer.Visible = true; |
2216 | Tracer.From = TracerPosition; |
2217 | Tracer.To = V2New(Position.X, Position.Y); |
2218 | Tracer.Color = Color; |
2219 | OutlineTracer.Visible = true; |
2220 | OutlineTracer.Transparency = Tracer.Transparency - 0.1; |
2221 | OutlineTracer.From = Tracer.From; |
2222 | OutlineTracer.To = Tracer.To; |
2223 | OutlineTracer.Color = Color3.new(0.1, 0.1, 0.1); |
2224 | else |
2225 | Tracer.Visible = false; |
2226 | OutlineTracer.Visible = false; |
2227 | end |
2228 | |
2229 | if ScreenPosition.Z > 0 then |
2230 | local ScreenPositionUpper = ScreenPosition; |
2231 | |
2232 | if Options.ShowName.Value then |
2233 | LocalPlayer.NameDisplayDistance = 0; |
2234 | NameTag.Visible = true; |
2235 | NameTag.Text = v.Text; |
2236 | NameTag.Size = Options.TextSize.Value; |
2237 | NameTag.Outline = Options.TextOutline.Value; |
2238 | NameTag.Position = V2New(ScreenPositionUpper.X, ScreenPositionUpper.Y); |
2239 | NameTag.Color = Color; |
2240 | if Drawing.Fonts and shared.am_ic3 then -- CURRENTLY SYNAPSE ONLY :MEGAHOLY: |
2241 | NameTag.Font = Drawing.Fonts.Monospace; |
2242 | end |
2243 | else |
2244 | LocalPlayer.NameDisplayDistance = 100; |
2245 | NameTag.Visible = false; |
2246 | end |
2247 | if Options.ShowDistance.Value or Options.ShowHealth.Value then |
2248 | DistanceTag.Visible = true; |
2249 | DistanceTag.Size = Options.TextSize.Value - 1; |
2250 | DistanceTag.Outline = Options.TextOutline.Value; |
2251 | DistanceTag.Color = Color3.new(1, 1, 1); |
2252 | if Drawing.Fonts and shared.am_ic3 then -- CURRENTLY SYNAPSE ONLY :MEGAHOLY: |
2253 | NameTag.Font = Drawing.Fonts.Monospace; |
2254 | end |
2255 | |
2256 | local Str = ''; |
2257 | |
2258 | if Options.ShowDistance.Value then |
2259 | Str = Str .. Format('[%d] ', Distance); |
2260 | end |
2261 | |
2262 | DistanceTag.Text = Str; |
2263 | DistanceTag.Position = V2New(ScreenPositionUpper.X, ScreenPositionUpper.Y) + V2New(0, NameTag.TextBounds.Y); |
2264 | else |
2265 | DistanceTag.Visible = false; |
2266 | end |
2267 | else |
2268 | NameTag.Visible = false; |
2269 | DistanceTag.Visible = false; |
2270 | end |
2271 | else |
2272 | NameTag.Visible = false; |
2273 | DistanceTag.Visible = false; |
2274 | Tracer.Visible = false; |
2275 | OutlineTracer.Visible = false; |
2276 | end |
2277 | |
2278 | Data.Instances['NameTag'] = NameTag; |
2279 | Data.Instances['DistanceTag'] = DistanceTag; |
2280 | Data.Instances['Tracer'] = Tracer; |
2281 | Data.Instances['OutlineTracer'] = OutlineTracer; |
2282 | |
2283 | shared.InstanceData[v.Instance:GetDebugId()] = Data; |
2284 | end |
2285 | end |
2286 | for i, v in pairs(Players:GetPlayers()) do |
2287 | local Data = shared.InstanceData[v.Name] or { Instances = {}; }; |
2288 | |
2289 | Data.Instances['Box'] = Data.Instances['Box'] or LineBox:Create{Thickness = 4}; |
2290 | Data.Instances['OutlineTracer'] = Data.Instances['OutlineTracer'] or NewDrawing'Line'{ |
2291 | Transparency = 1; |
2292 | Thickness = 3; |
2293 | Color = Color3.new(0.1, 0.1, 0.1); |
2294 | } |
2295 | Data.Instances['Tracer'] = Data.Instances['Tracer'] or NewDrawing'Line'{ |
2296 | Transparency = 1; |
2297 | Thickness = 1; |
2298 | } |
2299 | Data.Instances['HeadDot'] = Data.Instances['HeadDot'] or NewDrawing'Circle'{ |
2300 | Filled = true; |
2301 | NumSides = 30; |
2302 | } |
2303 | Data.Instances['NameTag'] = Data.Instances['NameTag'] or NewDrawing'Text'{ |
2304 | Size = Options.TextSize.Value; |
2305 | Center = true; |
2306 | Outline = Options.TextOutline.Value; |
2307 | OutlineOpacity = 1; |
2308 | Visible = true; |
2309 | }; |
2310 | Data.Instances['DistanceHealthTag'] = Data.Instances['DistanceHealthTag'] or NewDrawing'Text'{ |
2311 | Size = Options.TextSize.Value - 1; |
2312 | Center = true; |
2313 | Outline = Options.TextOutline.Value; |
2314 | OutlineOpacity = 1; |
2315 | Visible = true; |
2316 | }; |
2317 | |
2318 | local NameTag = Data.Instances['NameTag']; |
2319 | local DistanceTag = Data.Instances['DistanceHealthTag']; |
2320 | local Tracer = Data.Instances['Tracer']; |
2321 | local OutlineTracer = Data.Instances['OutlineTracer']; |
2322 | local HeadDot = Data.Instances['HeadDot']; |
2323 | local Box = Data.Instances['Box']; |
2324 | |
2325 | local Character = GetCharacter(v); |
2326 | local Pass, Distance = CheckPlayer(v, Character); |
2327 | |
2328 | if Pass and Character then |
2329 | local Humanoid = Character:FindFirstChildOfClass'Humanoid'; |
2330 | local Head = Character:FindFirstChild'Head'; |
2331 | local HumanoidRootPart = Character:FindFirstChild(CustomRootPartName or 'HumanoidRootPart') |
2332 | |
2333 | local Dead = (Humanoid and Humanoid:GetState().Name == 'Dead') |
2334 | |
2335 | if type(GetAliveState) == 'function' then |
2336 | Dead = (not GetAliveState(v, Character)) |
2337 | end |
2338 | |
2339 | if Character ~= nil and Head and HumanoidRootPart and not Dead then |
2340 | local ScreenPosition, Vis = WorldToViewport(Head.Position); |
2341 | local Color = Rainbow and Color3.fromHSV(tick() * 128 % 255/255, 1, 1) or (CheckTeam(v) and TeamColor or EnemyColor); Color = Options.ShowTeamColor.Value and v.TeamColor.Color or Color; |
2342 | local OPos = Camera.CFrame:pointToObjectSpace(Head.Position); |
2343 | |
2344 | if ScreenPosition.Z < 0 then |
2345 | local AT = math.atan2(OPos.Y, OPos.X) + math.pi; |
2346 | OPos = CFrame.Angles(0, 0, AT):vectorToWorldSpace((CFrame.Angles(0, math.rad(89.9), 0):vectorToWorldSpace(V3New(0, 0, -1)))); |
2347 | end |
2348 | |
2349 | local Position = WorldToViewport(Camera.CFrame:pointToWorldSpace(OPos)); |
2350 | |
2351 | if Options.ShowTracers.Value then |
2352 | if TracerPosition.X >= Camera.ViewportSize.X or TracerPosition.Y >= Camera.ViewportSize.Y or TracerPosition.X < 0 or TracerPosition.Y < 0 then |
2353 | TracerPosition = V2New(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y - 135); |
2354 | end |
2355 | |
2356 | Tracer.Visible = true; |
2357 | Tracer.Transparency = math.clamp(1 - (Distance / 200), 0.25, 0.75); |
2358 | Tracer.From = TracerPosition; |
2359 | Tracer.To = V2New(Position.X, Position.Y); |
2360 | Tracer.Color = Color; |
2361 | OutlineTracer.From = Tracer.From; |
2362 | OutlineTracer.To = Tracer.To; |
2363 | OutlineTracer.Transparency = Tracer.Transparency - 0.15; |
2364 | OutlineTracer.Visible = true; |
2365 | else |
2366 | Tracer.Visible = false; |
2367 | OutlineTracer.Visible = false; |
2368 | end |
2369 | |
2370 | if ScreenPosition.Z > 0 then |
2371 | local ScreenPositionUpper = WorldToViewport((HumanoidRootPart:GetRenderCFrame() * CFrame.new(0, Head.Size.Y + HumanoidRootPart.Size.Y + (Options.YOffset.Value / 25), 0)).Position); |
2372 | local Scale = Head.Size.Y / 2; |
2373 | |
2374 | if Options.ShowName.Value then |
2375 | NameTag.Visible = true; |
2376 | NameTag.Text = v.Name .. (CustomPlayerTag and CustomPlayerTag(v) or ''); |
2377 | NameTag.Size = Options.TextSize.Value; |
2378 | NameTag.Outline = Options.TextOutline.Value; |
2379 | NameTag.Position = V2New(ScreenPositionUpper.X, ScreenPositionUpper.Y) - V2New(0, NameTag.TextBounds.Y); |
2380 | NameTag.Color = Color; |
2381 | NameTag.Color = Color; |
2382 | NameTag.OutlineColor= Color3.new(0.05, 0.05, 0.05); |
2383 | NameTag.Transparency= 0.85; |
2384 | if Drawing.Fonts and shared.am_ic3 then -- CURRENTLY SYNAPSE ONLY :MEGAHOLY: |
2385 | NameTag.Font = Drawing.Fonts.Monospace; |
2386 | end |
2387 | else |
2388 | NameTag.Visible = false; |
2389 | end |
2390 | if Options.ShowDistance.Value or Options.ShowHealth.Value then |
2391 | DistanceTag.Visible = true; |
2392 | DistanceTag.Size = Options.TextSize.Value - 1; |
2393 | DistanceTag.Outline = Options.TextOutline.Value; |
2394 | DistanceTag.Color = Color3.new(1, 1, 1); |
2395 | DistanceTag.Transparency= 0.85; |
2396 | if Drawing.Fonts and shared.am_ic3 then -- CURRENTLY SYNAPSE ONLY :MEGAHOLY: |
2397 | NameTag.Font = Drawing.Fonts.Monospace; |
2398 | end |
2399 | |
2400 | local Str = ''; |
2401 | |
2402 | if Options.ShowDistance.Value then |
2403 | Str = Str .. Format('[%d] ', Distance); |
2404 | end |
2405 | if Options.ShowHealth.Value then |
2406 | if typeof(Humanoid) == 'Instance' then |
2407 | Str = Str .. Format('[%d/%d] [%s%%]', Humanoid.Health, Humanoid.MaxHealth, math.floor(Humanoid.Health / Humanoid.MaxHealth * 100)); |
2408 | elseif type(GetHealth) == 'function' then |
2409 | local health, maxHealth = GetHealth(v) |
2410 | |
2411 | if type(health) == 'number' and type(maxHealth) == 'number' then |
2412 | Str = Str .. Format('[%d/%d] [%s%%]', health, maxHealth, math.floor(health / maxHealth * 100)) |
2413 | end |
2414 | end |
2415 | end |
2416 | |
2417 | DistanceTag.Text = Str; |
2418 | DistanceTag.OutlineColor = Color3.new(0.05, 0.05, 0.05); |
2419 | DistanceTag.Position = (NameTag.Visible and NameTag.Position + V2New(0, NameTag.TextBounds.Y) or V2New(ScreenPositionUpper.X, ScreenPositionUpper.Y)); |
2420 | else |
2421 | DistanceTag.Visible = false; |
2422 | end |
2423 | if Options.ShowDot.Value and Vis then |
2424 | local Top = WorldToViewport((Head.CFrame * CFrame.new(0, Scale, 0)).Position); |
2425 | local Bottom = WorldToViewport((Head.CFrame * CFrame.new(0, -Scale, 0)).Position); |
2426 | local Radius = math.abs((Top - Bottom).Y); |
2427 | |
2428 | HeadDot.Visible = true; |
2429 | HeadDot.Color = Color; |
2430 | HeadDot.Position = V2New(ScreenPosition.X, ScreenPosition.Y); |
2431 | HeadDot.Radius = Radius; |
2432 | else |
2433 | HeadDot.Visible = false; |
2434 | end |
2435 | if Options.ShowBoxes.Value and Vis and HumanoidRootPart then |
2436 | local Body = { |
2437 | Head; |
2438 | Character:FindFirstChild'Left Leg' or Character:FindFirstChild'LeftLowerLeg'; |
2439 | Character:FindFirstChild'Right Leg' or Character:FindFirstChild'RightLowerLeg'; |
2440 | Character:FindFirstChild'Left Arm' or Character:FindFirstChild'LeftLowerArm'; |
2441 | Character:FindFirstChild'Right Arm' or Character:FindFirstChild'RightLowerArm'; |
2442 | } |
2443 | Box:Update(HumanoidRootPart.CFrame, V3New(2, 3, 1) * (Scale * 2), Color, nil, shared.am_ic3 and Body); |
2444 | else |
2445 | Box:SetVisible(false); |
2446 | end |
2447 | else |
2448 | NameTag.Visible = false; |
2449 | DistanceTag.Visible = false; |
2450 | HeadDot.Visible = false; |
2451 | |
2452 | Box:SetVisible(false); |
2453 | end |
2454 | else |
2455 | NameTag.Visible = false; |
2456 | DistanceTag.Visible = false; |
2457 | HeadDot.Visible = false; |
2458 | Tracer.Visible = false; |
2459 | OutlineTracer.Visible = false; |
2460 | |
2461 | Box:SetVisible(false); |
2462 | end |
2463 | else |
2464 | NameTag.Visible = false; |
2465 | DistanceTag.Visible = false; |
2466 | HeadDot.Visible = false; |
2467 | Tracer.Visible = false; |
2468 | OutlineTracer.Visible = false; |
2469 | |
2470 | Box:SetVisible(false); |
2471 | end |
2472 | |
2473 | shared.InstanceData[v.Name] = Data; |
2474 | end |
2475 | end |
2476 | end |
2477 | |
2478 | local LastInvalidCheck = 0; |
2479 | |
2480 | local function Update() |
2481 | if tick() - LastInvalidCheck > 0.3 then |
2482 | LastInvalidCheck = tick(); |
2483 | |
2484 | if Camera.Parent ~= workspace then |
2485 | Camera = workspace.CurrentCamera; |
2486 | CameraCon(); |
2487 | WTVP = Camera.WorldToViewportPoint; |
2488 | end |
2489 | |
2490 | for i, v in pairs(shared.InstanceData) do |
2491 | if not Players:FindFirstChild(tostring(i)) then |
2492 | if not shared.InstanceData[i].DontDelete then |
2493 | GetTableData(v.Instances)(function(i, obj) |
2494 | obj.Visible = false; |
2495 | obj:Remove(); |
2496 | v.Instances[i] = nil; |
2497 | end) |
2498 | shared.InstanceData[i] = nil; |
2499 | else |
2500 | if shared.InstanceData[i].Instance == nil or shared.InstanceData[i].Instance.Parent == nil then |
2501 | GetTableData(v.Instances)(function(i, obj) |
2502 | obj.Visible = false; |
2503 | obj:Remove(); |
2504 | v.Instances[i] = nil; |
2505 | end) |
2506 | shared.InstanceData[i] = nil; |
2507 | end |
2508 | end |
2509 | end |
2510 | end |
2511 | end |
2512 | |
2513 | local CX = Menu:GetInstance'CrosshairX'; |
2514 | local CY = Menu:GetInstance'CrosshairY'; |
2515 | |
2516 | if Options.Crosshair.Value then |
2517 | CX.Visible = true; |
2518 | CY.Visible = true; |
2519 | |
2520 | CX.To = V2New((Camera.ViewportSize.X / 2) - 8, (Camera.ViewportSize.Y / 2)); |
2521 | CX.From = V2New((Camera.ViewportSize.X / 2) + 8, (Camera.ViewportSize.Y / 2)); |
2522 | CY.To = V2New((Camera.ViewportSize.X / 2), (Camera.ViewportSize.Y / 2) - 8); |
2523 | CY.From = V2New((Camera.ViewportSize.X / 2), (Camera.ViewportSize.Y / 2) + 8); |
2524 | else |
2525 | CX.Visible = false; |
2526 | CY.Visible = false; |
2527 | end |
2528 | |
2529 | if Options.MenuOpen.Value and MenuLoaded then |
2530 | local MLocation = GetMouseLocation(); |
2531 | shared.MenuDrawingData.Instances.Main.Color = Color3.fromHSV(tick() * 24 % 255/255, 1, 1); |
2532 | local MainInstance = Menu:GetInstance'Main'; |
2533 | |
2534 | local Values = { |
2535 | MainInstance.Position.X; |
2536 | MainInstance.Position.Y; |
2537 | MainInstance.Position.X + MainInstance.Size.X; |
2538 | MainInstance.Position.Y + MainInstance.Size.Y; |
2539 | }; |
2540 | |
2541 | if MainInstance and (MouseHoveringOver(Values) or (SubMenu.Open and MouseHoveringOver(SubMenu.Bounds))) then |
2542 | Debounce.CursorVis = true; |
2543 | |
2544 | Menu:UpdateMenuInstance'Cursor1'{ |
2545 | Visible = true; |
2546 | From = V2New(MLocation.x, MLocation.y); |
2547 | To = V2New(MLocation.x + 5, MLocation.y + 6); |
2548 | } |
2549 | Menu:UpdateMenuInstance'Cursor2'{ |
2550 | Visible = true; |
2551 | From = V2New(MLocation.x, MLocation.y); |
2552 | To = V2New(MLocation.x, MLocation.y + 8); |
2553 | } |
2554 | Menu:UpdateMenuInstance'Cursor3'{ |
2555 | Visible = true; |
2556 | From = V2New(MLocation.x, MLocation.y + 6); |
2557 | To = V2New(MLocation.x + 5, MLocation.y + 5); |
2558 | } |
2559 | else |
2560 | if Debounce.CursorVis then |
2561 | Debounce.CursorVis = false; |
2562 | |
2563 | Menu:UpdateMenuInstance'Cursor1'{Visible = false}; |
2564 | Menu:UpdateMenuInstance'Cursor2'{Visible = false}; |
2565 | Menu:UpdateMenuInstance'Cursor3'{Visible = false}; |
2566 | end |
2567 | end |
2568 | if MouseHeld then |
2569 | local MousePos = GetMouseLocation(); |
2570 | |
2571 | if Dragging then |
2572 | DraggingWhat.Slider.Position = V2New(math.clamp(MLocation.X - DraggingWhat.Slider.Size.X / 2, DraggingWhat.Line.Position.X, DraggingWhat.Line.Position.X + DraggingWhat.Line.Size.X - DraggingWhat.Slider.Size.X), DraggingWhat.Slider.Position.Y); |
2573 | local Percent = (DraggingWhat.Slider.Position.X - DraggingWhat.Line.Position.X) / ((DraggingWhat.Line.Position.X + DraggingWhat.Line.Size.X - DraggingWhat.Line.Position.X) - DraggingWhat.Slider.Size.X); |
2574 | local Value = CalculateValue(DraggingWhat.Min, DraggingWhat.Max, Percent); |
2575 | DraggingWhat.Option(Value); |
2576 | elseif DraggingUI then |
2577 | Debounce.UIDrag = true; |
2578 | local Main = Menu:GetInstance'Main'; |
2579 | Main.Position = MousePos + DragOffset; |
2580 | elseif DragTracerPosition then |
2581 | TracerPosition = MousePos; |
2582 | end |
2583 | else |
2584 | Dragging = false; |
2585 | DragTracerPosition = false; |
2586 | if DraggingUI and Debounce.UIDrag then |
2587 | Debounce.UIDrag = false; |
2588 | DraggingUI = false; |
2589 | CreateMenu(Menu:GetInstance'Main'.Position); |
2590 | end |
2591 | end |
2592 | if not Debounce.Menu then |
2593 | Debounce.Menu = true; |
2594 | ToggleMenu(); |
2595 | end |
2596 | elseif Debounce.Menu and not Options.MenuOpen.Value then |
2597 | Debounce.Menu = false; |
2598 | ToggleMenu(); |
2599 | end |
2600 | end |
2601 | |
2602 | RunService:UnbindFromRenderStep(GetDataName); |
2603 | RunService:UnbindFromRenderStep(UpdateName); |
2604 | |
2605 | RunService:BindToRenderStep(GetDataName, 300, UpdatePlayerData); |
2606 | RunService:BindToRenderStep(UpdateName, 199, Update); |