--[[ By plusgiant5, IMGUI port by 0_Void Some code taken from original Replayability so credit to dong too Tasability V1.2.1 -- Improved Reading loop to fix all slowdowns -- Fixed animations bugs and delays. -- Added custom target fps. -- Fixed shiftlock freezes. -- Fixed some animations bugs. -- Added support for CSCD, ETOH ETC. AHKConnection is required to do mouse scroll inputs Get AHKConnection here: https://github.com/plusgiant5/Libraries/raw/d96e61f24d2439f0f9405087054f169e5a50e1c4/AHKConnection/AHKConnection.exe If you dont trust the exe, compile it yourself: https://raw.githubusercontent.com/plusgiant5/Libraries/main/AHKConnection/AHKConnection.ahk AHKConnection does not work well unless compiled ]] -- Config local FPS = 120 -- Put whatever FPS you want here, changes fps cap for the tas. local PlaybackInputs = false -- Sets if you want replays to playback your inputs when playing them (AHK connection is required for mouse scroll playback) local PlaybackMouseLocation = false -- Sets if you want replays to move your mouse when playing them (glitchy when loading checkpoints) local RoundDigits = 5 -- Rounds all numbers when writing, to greatly decrease file size (set to 50 to disable rounding) local ReplayStartTime = 1 -- Number of seconds to wait before starting to read the replay local FrameBacktrackCount = 500 -- Number of frames to backtrack when frozen to see which keys are currently pressed. Increase as much as your computer can handle local MinimumJSONFPS = 1/10 -- Lowest you want your FPS to go while encoding/decoding (higher = faster encoding/decoding, lower = better fps) 1/30: 30 fps, 1/60: 60 fps\ local BypassAntiExploit = true -- If this is true games with anti cheat (like beans) will not kick you, but there is a chance animations will be broken -- Advanced config -- Inputs that will not be recorded local InputBlacklist = { ["R"] = true; ["T"] = true; ["H"] = true; ["G"] = true; ["E"] = true; } -- Color codes for the color code frame local ColorCodes = { WaitingForInput = Color3.new(1,1,0); Recording = Color3.new(1,0,0); Reading = Color3.new(0,0,5,1); Idle = Color3.new(1,1,1); Frozen = Color3.new(0,1,1); None = Color3.new(0,0,0); } -- Data on Roblox's cursors local Cursors = { ["ArrowFarCursor"] = { Icon = "rbxasset://textures/Cursors/KeyboardMouse/ArrowFarCursor.png"; Size = UDim2.fromOffset(64,64); Offset = Vector2.new(-32,4); }; ["MouseLockedCursor"] = { Icon = "rbxasset://textures/MouseLockedCursor.png"; Size = UDim2.fromOffset(32,32); Offset = Vector2.new(-16,-16); }; } -- End of config -- Constants local Version = "V1.2.1 IMGUI Edition" local UserInputService = game:GetService("UserInputService") local RunService = game:GetService("RunService") local HttpService = game:GetService("HttpService") local ContextActionService = game:GetService("ContextActionService") local GuiService = game:GetService("GuiService") local VirtualInputManager = game:GetService("VirtualInputManager") local Player = game.Players.LocalPlayer local Mouse = Player:GetMouse() local random = math.random local min = math.min local max = math.max local floor = math.floor local ceil = math.ceil local ReplayFileBeginning = "{\"Replay\":" local ReplayFileEnding = "}" local PlayerModule = Player.PlayerScripts:WaitForChild("PlayerModule") local ShiftLockBoundKeys = PlayerModule:WaitForChild("CameraModule"):WaitForChild("MouseLockController"):WaitForChild("BoundKeys") local ShiftLockEnabled = false local GuiInset = GuiService:GetGuiInset() -- Variables local ExecutionTick = tick() local PlaceId = game.PlaceId -- These will be set later -- local Character = nil local Humanoid = nil local RootPart = nil local DefaultGravity = nil local DefaultJumpPower = nil local DefaultWalkSpeed = nil local Resolution = nil local ConsoleMessage = print ----------------------------- local Reading = false local Writing = false local Saving = false local AnimateDisabled = false local Checkpoints = {} local RenderSteppedConnections = {} local SteppedConnections = {} local FolderPath = "Tasability\\"..tostring(PlaceId) local ReplayPath = isfolder(FolderPath) and #listfiles(FolderPath) >= 1 and listfiles(FolderPath)[1] or FolderPath.."\\Replay.json" local AHKConnectionFolderPath = "Replayability+_AHK" local AHKConnectionRequestPath = "Replayability+_AHK/Request" local ReplayTable = {} -- Should always be used instead of the json string except when encoding or decoding local RecordingTable = {} -- List of frames that will be added to ReplayTable if recording is saved local ReplayTableIndex = 0 -- The index in ReplayTable that will be read from local AnimationQueue = {} -- Functions that were called by the animation script (clear every frame) local RunSpeed = 0 -- Set in the onRunning function, reset to 0 every frame (AnimationId 2) local ClimbSpeed = 0 -- Set in the onClimbing function, reset to 0 every frame (AnimationId 4) local HumanoidStateQueue = {} -- States that were activated on the humanoid (clear every frame) local InputBeganQueue = {} -- Inputs that have just began (for recording inputs) (clear every frame) local InputEndedQueue = {} -- Inputs that have just ended (for recording inputs) (clear every frame) local Cursor = Instance.new("ImageLabel") -- Fake cursor so the icon doesnt change all the time local CursorIcon = nil -- Icon of the cursor local CursorSize = nil -- Size of the cursor local CursorOffset = nil -- Offset of the cursor from UserInputService:GetMouseLocation() local Dead = false -- If the player is dead this is true local CameraCFrame = workspace.CurrentCamera.CFrame -- Used when reading so that nothing else can change the camera's CFrame local Pressed = {} -- Current keys that are pressed local IgnoreGameProcessed = false -- To ignore GameProcessed in InputBegan, InputChanged, InputEnded -- Tasability update local Frozen = false local FreezeFrame = 1 -- Frame to render while frozen local SeekDirection = 0 -- Stays 0 normally, -1 when going backwards while frozen, 1 when going fowards local SeekDirectionMultiplier = 1 -- To go faster or slower when seeking with R and T -- Converting inputs -- To add to this table, use https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes local InputCodes = { ["A"] = 0x41; ["B"] = 0x42; ["C"] = 0x43; ["D"] = 0x44; ["E"] = 0x45; ["F"] = 0x46; ["G"] = 0x47; ["H"] = 0x48; ["I"] = 0x49; ["J"] = 0x4A; ["K"] = 0x4B; ["L"] = 0x4C; ["M"] = 0x4D; ["N"] = 0x4E; ["O"] = 0x4F; ["P"] = 0x50; ["Q"] = 0x51; ["R"] = 0x52; ["S"] = 0x53; ["T"] = 0x54; ["U"] = 0x55; ["V"] = 0x56; ["W"] = 0x57; ["X"] = 0x58; ["Y"] = 0x59; ["Z"] = 0x5A; ["Space"] = 0x20; ["LeftShift"] = 0x10; ["RightShift"] = 0x10; } -- Compatibility mouse1press = mouse1press or mouse1down mouse2press = mouse2press or mouse2down mouse1release = mouse1release or mouse1up mouse2release = mouse2release or mouse2up keypress = keypress or keydown keyrelease = keyrelease or keyup -- Variables used in Animate script local pose = "Standing" -- The pose that is used in the move function local currentAnimSpeed = 1.0 -- Animation speed -- Other local GUIParent = Player:WaitForChild("PlayerGui") local json do -- Overwriting JSON json = (function() -- -- json.lua -- -- Copyright (c) 2020 rxi -- -- Permission is hereby granted, free of charge, to any person obtaining a copy of -- this software and associated documentation files (the "Software"), to deal in -- the Software without restriction, including without limitation the rights to -- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -- of the Software, and to permit persons to whom the Software is furnished to do -- so, subject to the following conditions: -- -- The above copyright notice and this permission notice shall be included in all -- copies or substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -- SOFTWARE. -- local json = { _version = "0.1.2" } local t = tick() local currentstr local lasti local function checkwait(i) if tick() - t > MinimumJSONFPS then lasti = lasti or i if i >= lasti then local Type = (type(currentstr) == "table" and "En") or (type(currentstr) == "string" and "De") if Type then ConsoleMessage(Type.."coding... ("..tostring(i).."/"..tostring(#currentstr)..")") end game:GetService("RunService").Stepped:Wait() t = tick() lasti = i end end end ------------------------------------------------------------------------------- -- Encode ------------------------------------------------------------------------------- local encode local escape_char_map = { [ "\\" ] = "\\", [ "\"" ] = "\"", [ "\b" ] = "b", [ "\f" ] = "f", [ "\n" ] = "n", [ "\r" ] = "r", [ "\t" ] = "t", } local escape_char_map_inv = { [ "/" ] = "/" } for k, v in pairs(escape_char_map) do escape_char_map_inv[v] = k end local function escape_char(c) return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte())) end local function encode_nil(val) return "null" end local function encode_table(val, stack) local res = {} stack = stack or {} -- Circular reference? if stack[val] then error("circular reference") end stack[val] = true if rawget(val, 1) ~= nil or next(val) == nil then -- Treat as array -- check keys are valid and it is not sparse local n = 0 for k in pairs(val) do if type(k) ~= "number" then error("invalid table: mixed or invalid key types") end n = n + 1 end if n ~= #val then error("invalid table: sparse array") end -- Encode for i, v in ipairs(val) do checkwait(i) table.insert(res, encode(v, stack)) end stack[val] = nil return "[" .. table.concat(res, ",") .. "]" else -- Treat as an object local i = 0 for k, v in pairs(val) do i = i + 1 if type(k) ~= "string" then error("invalid table: mixed or invalid key types") end checkwait(i) table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) end stack[val] = nil return "{" .. table.concat(res, ",") .. "}" end end local function encode_string(val) return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' end local function encode_number(val) -- Check for NaN, -inf and inf if val ~= val or val <= -math.huge or val >= math.huge then error("unexpected number value '" .. tostring(val) .. "'") end return string.format("%.14g", val) end local type_func_map = { [ "nil" ] = encode_nil, [ "table" ] = encode_table, [ "string" ] = encode_string, [ "number" ] = encode_number, [ "boolean" ] = tostring, } encode = function(val, stack) local t = type(val) local f = type_func_map[t] if f then t = tick() return f(val, stack) end error("unexpected type '" .. t .. "'") end function json.encode(val) currentstr = val lasti = nil return ( encode(val) ) end ------------------------------------------------------------------------------- -- Decode ------------------------------------------------------------------------------- local parse local function create_set(...) local res = {} for i = 1, select("#", ...) do res[ select(i, ...) ] = true end return res end local space_chars = create_set(" ", "\t", "\r", "\n") local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",") local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u") local literals = create_set("true", "false", "null") local literal_map = { [ "true" ] = true, [ "false" ] = false, [ "null" ] = nil, } local function next_char(str, idx, set, negate) for i = idx, #str do if set[str:sub(i, i)] ~= negate then return i end end return #str + 1 end local function decode_error(str, idx, msg) local line_count = 1 local col_count = 1 for i = 1, idx - 1 do col_count = col_count + 1 if str:sub(i, i) == "\n" then line_count = line_count + 1 col_count = 1 end end error( string.format("%s at line %d col %d", msg, line_count, col_count) ) end local function codepoint_to_utf8(n) -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa local f = math.floor if n <= 0x7f then return string.char(n) elseif n <= 0x7ff then return string.char(f(n / 64) + 192, n % 64 + 128) elseif n <= 0xffff then return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128) elseif n <= 0x10ffff then return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128, f(n % 4096 / 64) + 128, n % 64 + 128) end error( string.format("invalid unicode codepoint '%x'", n) ) end local function parse_unicode_escape(s) local n1 = tonumber( s:sub(1, 4), 16 ) local n2 = tonumber( s:sub(7, 10), 16 ) -- Surrogate pair? if n2 then return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) else return codepoint_to_utf8(n1) end end local function parse_string(str, i) local res = "" local j = i + 1 local k = j while j <= #str do local x = str:byte(j) if x < 32 then decode_error(str, j, "control character in string") elseif x == 92 then -- `\`: Escape res = res .. str:sub(k, j - 1) j = j + 1 local c = str:sub(j, j) if c == "u" then local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) or str:match("^%x%x%x%x", j + 1) or decode_error(str, j - 1, "invalid unicode escape in string") res = res .. parse_unicode_escape(hex) j = j + #hex else if not escape_chars[c] then decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string") end res = res .. escape_char_map_inv[c] end k = j + 1 elseif x == 34 then -- `"`: End of string res = res .. str:sub(k, j - 1) return res, j + 1 end j = j + 1 checkwait(i) end decode_error(str, i, "expected closing quote for string") end local function parse_number(str, i) local x = next_char(str, i, delim_chars) local s = str:sub(i, x - 1) local n = tonumber(s) if not n then decode_error(str, i, "invalid number '" .. s .. "'") end checkwait(i) return n, x end local function parse_literal(str, i) local x = next_char(str, i, delim_chars) local word = str:sub(i, x - 1) if not literals[word] then decode_error(str, i, "invalid literal '" .. word .. "'") end checkwait(i) return literal_map[word], x end local function parse_array(str, i) local res = {} local n = 1 i = i + 1 while 1 do local x i = next_char(str, i, space_chars, true) -- Empty / end of array? if str:sub(i, i) == "]" then i = i + 1 break end -- Read token x, i = parse(str, i) res[n] = x n = n + 1 -- Next token i = next_char(str, i, space_chars, true) local chr = str:sub(i, i) i = i + 1 checkwait(i) if chr == "]" then break end if chr ~= "," then decode_error(str, i, "expected ']' or ','") end end return res, i end local function parse_object(str, i) local res = {} i = i + 1 while 1 do local key, val i = next_char(str, i, space_chars, true) -- Empty / end of object? if str:sub(i, i) == "}" then i = i + 1 break end -- Read key if str:sub(i, i) ~= '"' then decode_error(str, i, "expected string for key") end key, i = parse(str, i) -- Read ':' delimiter i = next_char(str, i, space_chars, true) if str:sub(i, i) ~= ":" then decode_error(str, i, "expected ':' after key") end i = next_char(str, i + 1, space_chars, true) -- Read value val, i = parse(str, i) -- Set res[key] = val -- Next token i = next_char(str, i, space_chars, true) local chr = str:sub(i, i) i = i + 1 --print(tick() - t, 1/60) checkwait(i) if chr == "}" then break end if chr ~= "," then decode_error(str, i, "expected '}' or ','") end end return res, i end local char_func_map = { [ '"' ] = parse_string, [ "0" ] = parse_number, [ "1" ] = parse_number, [ "2" ] = parse_number, [ "3" ] = parse_number, [ "4" ] = parse_number, [ "5" ] = parse_number, [ "6" ] = parse_number, [ "7" ] = parse_number, [ "8" ] = parse_number, [ "9" ] = parse_number, [ "-" ] = parse_number, [ "t" ] = parse_literal, [ "f" ] = parse_literal, [ "n" ] = parse_literal, [ "[" ] = parse_array, [ "{" ] = parse_object, } parse = function(str, idx) local chr = str:sub(idx, idx) local f = char_func_map[chr] if f then return f(str, idx) end decode_error(str, idx, "unexpected character '" .. chr .. "'") end function json.decode(str) t = tick() currentstr = str lasti = nil if type(str) ~= "string" then error("expected argument of type string, got " .. type(str)) end local res, idx = parse(str, next_char(str, 1, space_chars, true)) idx = next_char(str, idx, space_chars, true) if idx <= #str then decode_error(str, idx, "trailing garbage") end return res end return json end)() end -- Functions -- General Functions -- Fast conversion functions for better performance local function FastTableToCFrame(t) return CFrame.new(t[1], t[2], t[3], t[4], t[5], t[6], t[7], t[8], t[9], t[10], t[11], t[12]) end local function FastTableToVector3(t) return Vector3.new(t[1], t[2], t[3]) end local function FastTableToVector2(t) return Vector2.new(t[1], t[2]) end local RandomString --RandomString() -> string local RoundNumber -- RoundNumber(Number,Digits) -> number local Vector3ToTable -- Vector3ToTable(Vector3) -> table local TableToVector3 -- TableToVector3(Table) -> vector3 local CFrameToTable -- CFrameToTable(CFrame) -> table local TableToCFrame -- TableToCFrame(Table) -> cframe local RoundVector3 -- RoundVector3(Vector3,Digits) -> vector3 local RoundCFrame -- RoundCFrame(CFrame,Digits) -> cframe local FindListIndex -- FindListIndex(Table,Search) -> number local WaitForInput -- WaitForInput() -> nil do RandomString = function() local str = "" for _ = 1,random(1,20) do local type = random(1,3) if type == 1 then str = str..string.char(random(97,122)) -- Lowercase elseif type == 2 then str = str..string.char(random(65,90)) -- Uppercase elseif type == 3 then str = str..string.char(random(48,57)) -- Numbers end end return str end RoundNumber = function(Number,Digits) local Mult = 10^max(tonumber(Digits) or 0,0) return floor(Number*Mult+0.5)/Mult end Vector3ToTable = function(V3) return {V3.X,V3.Y,V3.Z} end TableToVector3 = function(Table) return Vector3.new(unpack(Table)) end Vector2ToTable = function(V2) return {V2.X,V2.Y} end TableToVector2 = function(Table) return Vector2.new(unpack(Table)) end CFrameToTable = function(CF) return {CF:GetComponents()} end TableToCFrame = function(Table) return CFrame.new(unpack(Table)) end RoundTable = function(Table,Digits) local RoundedTable = {} for Index,Number in pairs(Table) do RoundedTable[Index] = RoundNumber(Number,Digits) end return RoundedTable end FindListIndex = function(Table,Search) for Index,Value in pairs(Table) do if Value == Search then return Index end end end WaitForInput = function() local KeyPressed = Instance.new("BindableEvent") local InputBeganConnection InputBeganConnection = UserInputService.InputBegan:Connect(function(Input) if Input.UserInputType == Enum.UserInputType.Keyboard then RunService.RenderStepped:Wait() KeyPressed:Fire() end end) KeyPressed.Event:Wait() InputBeganConnection:Disconnect() KeyPressed:Destroy() end end -- Making GUI local InsertService = game:GetService("InsertService") local ReGui = loadstring(game:HttpGet('https://raw.githubusercontent.com/depthso/Dear-ReGui/refs/heads/main/ReGui.lua'))() local PrefabsId = "rbxassetid://" .. ReGui.PrefabsId --// Declare the Prefabs asset ReGui:Init({ Prefabs = InsertService:LoadLocalAsset(PrefabsId) }) ReGui:DefineElement("Textbox", { Base = { Value = "", Placeholder = "", Label = "Input text", Callback = EmptyFunction, MultiLine = false, NoAutoTag = true, Disabled = false }, Create = function(Canvas, Config: InputText): InputText --// Unpack configuration local MultiLine = Config.MultiLine local Placeholder = Config.Placeholder local Label = Config.Label local Disabled = Config.Disabled local Value = Config.Value --// Create Text input object local Object = ReGui:InsertPrefab("InputBox", Config) local Frame = Object.Frame local TextBox = Frame.Input local Class = ReGui:MergeMetatables(Config, Object) Canvas:Label({ Parent = Object, Text = Label, AutomaticSize = Enum.AutomaticSize.X, Size = UDim2.fromOffset(0, 19), Position = UDim2.new(1, 4), LayoutOrder = 2 }) ReGui:SetProperties(TextBox, { PlaceholderText = Placeholder, MultiLine = MultiLine }) local function Callback(...) local Func = Config.Callback Func(Class, ...) end function Config:SetValue(Value: string?) TextBox.Text = tostring(Value) self.Value = Value return self end function Config:SetDisabled(Disabled: boolean) self.Disabled = Disabled Object.Interactable = not Disabled Canvas:SetColorTags({ [Label] = Disabled and "LabelDisabled" or "Label" }, true) return self end function Config:Clear() TextBox.Text = "" return self end local function TextChanged() local Value = TextBox.Text Config.Value = Value Callback(Value) end --// Connect events TextBox.FocusLost:Connect(function(enter, inputObject) TextChanged() end) --// Update object state Config:SetDisabled(Disabled) Config:SetValue(Value) Canvas:TagElements({ [TextBox] = "Frame" }) return Class, Object end, }) local Window = ReGui:Window({ Title = "Tasability FIX BY 9KWR "..Version, Size = UDim2.new(0, 600, 0, 400), -- If you have a window with a single element with Fill enabled, you should disable Scroll on the window -- Otherwise it will not fit correctly as automatic canvas size is enabled for the scrolling functionality NoScroll = false }) --Console window local ConsoleWindow = ReGui:Window({ Title = "Console", Size = UDim2.new(0, 400, 0, 300), -- If you have a window with a single element with Fill enabled, you should disable Scroll on the window -- Otherwise it will not fit correctly as automatic canvas size is enabled for the scrolling functionality NoScroll = true }) local console = ConsoleWindow:Console({ Enabled = true, ReadOnly = true, }) local ConsoleInput = ConsoleWindow:Textbox({ Label = "Enter command here", }) ConsoleWindow:ToggleVisibility() --Menu bar local menubar = Window:MenuBar() local Menu = menubar:MenuItem({ Text = "Menu" }) local CreateFile = Menu:Selectable({ Text = "Create File", Callback = function() local popup = Window:PopupModal({ Title = "Create file" }) popup:Textbox({ Text = "Enter file name", Placeholder = "File name...", Callback = function(_,name) if #name > 0 then writefile(FolderPath.."./"..name..".json", "") ReplayTable = {} ReplayPath = FolderPath.."./"..name..".json" end end }) popup:Button({ Text = "Done", Callback = function() popup:ClosePopup() end }) end }) local SaveToFileButton = Menu:Selectable({ Text = "Save to File", Callback = function() SaveToFile() end }) local LoadFileButton = Menu:Selectable({ Text = "Load File", Callback = function() local popup = Window:PopupModal({ Title = "Load file" }) popup:Combo({ Text = "Select file", Placeholder = "Select file here", GetItems = function() return listfiles(FolderPath) end, Callback = function(_,path) print(path) ReplayPath = path ReplayTable = #GetReplayFile() > 0 and ReplayDecode(GetReplayFile()) or {} end }) popup:Button({ Text = "Done", Callback = function() popup:ClosePopup() end }) end }) local DeleteFileButton = Menu:Selectable({ Text = "Delete File", Callback = function() local popup = Window:PopupModal({ Title = "Delete file" }) local filepath = popup:Combo({ Text = "Select file", Placeholder = "Select file here", GetItems = function() return listfiles(FolderPath) end, }) popup:Button({ Text = "Done", Callback = function() popup:ClosePopup() if #filepath.Value > 0 then delfile(filepath.Value) end end }) end }) local ConsoleButton = Menu:Selectable({ Text = "Console", Callback = function() ConsoleWindow:ToggleVisibility() end }) --Main local InfoHeader = Window:CollapsingHeader({ Title = "Info" }) RecordedFramesLabel = InfoHeader:Label({ Text = "Frames: 0" }) local PressedKeysLabel = InfoHeader:Label({ Text = "Pressed keys: |" }) local WritingPressedKeysLabel = InfoHeader:Label({ Text = "Writing Pressed keys: |" }) local ColorCodeFrame = InfoHeader:Label({ Text = "Status: " }) local CurrentFile = InfoHeader:Label({ Text = "Current File: " }) task.spawn(function() repeat task.wait() until type(ReplayPath) == "string" print(ReplayPath) local oldfilename = ReplayPath CurrentFile.Text = "Current File: "..string.split(ReplayPath, "\\")[3] while task.wait() do if ReplayPath ~= oldfilename then CurrentFile.Text = "Current File: "..string.split(ReplayPath, "\\")[3] oldfilename = ReplayPath end end end) local ConnectedLabel = InfoHeader:Label({ Text = "AHK folder not found", TextColor3 = Color3.fromRGB(255,0,0) }) local CurrentPlaceIdButton; CurrentPlaceIdButton = InfoHeader:Button({ Text = "Place id: "..tostring(PlaceId), Callback = function() if string.find(CurrentPlaceIdButton.Text, "Place") then local OldText = CurrentPlaceIdButton.Text setclipboard(tostring(PlaceId)) CurrentPlaceIdButton.Text = "Copied id" wait(.5) CurrentPlaceIdButton.Text = OldText end end }) local ControlsHeader = Window:CollapsingHeader({ Title = "Controls" }) local Frozentoidlerow = ControlsHeader:Row() Frozentoidlerow:Button({ Text = "Frozen to Idle", Callback = function() IdleButton_MouseButton1Click() end }) local Frozenkeybind = Frozentoidlerow:Keybind({ Label = "Keybind", Value = Enum.KeyCode.M, }) local IgnoreGameProcessedButton_MouseButton1Click local IgnoreGameProcessedButton = ControlsHeader:Checkbox({ Label = "Ignore Game Processed", Callback = function() IgnoreGameProcessed = not IgnoreGameProcessed end }) local movecameraonfroze = ControlsHeader:Checkbox({ Label = "Move camera while frozen" }) local ReadButtonrow = ControlsHeader:Row() ReadButtonrow:Button({ Text = "Read", Callback = function() ReadButton_MouseButton1Click() end }) local Readkeybind = ReadButtonrow:Keybind({ Label = "Keybind", Value = Enum.KeyCode.Z, }) local Abortrow = ControlsHeader:Row() local StopReading Abortrow:Button({ Text = "Abort", Callback = function() StopReading() end }) local Abortkeybind = Abortrow:Keybind({ Label = "Keybind", Value = Enum.KeyCode.L, }) local Hideuikeybind = ControlsHeader:Keybind({ Label = "Hide ui", Value = Enum.KeyCode.U }) local Recordkeybind = ControlsHeader:Keybind({ Label = "Record/Freeze keybind", Value = Enum.KeyCode.E }) local Goforwardkeybind = ControlsHeader:Keybind({ Label = "Go forward keybind", Value = Enum.KeyCode.H }) local Gobackwardskeybind = ControlsHeader:Keybind({ Label = "Go backwards keybind", Value = Enum.KeyCode.R }) local Frameadvanceforwardkeybind = ControlsHeader:Keybind({ Label = "Frame advance forward keybind", Value = Enum.KeyCode.T }) local Frameadvancebackwardskeybind = ControlsHeader:Keybind({ Label = "Frame advance backwards keybind", Value = Enum.KeyCode.G }) local Savekeybind = ControlsHeader:Keybind({ Label = "Save to file keybind", Value = Enum.KeyCode.P }) -- GUI Functions --local ConsoleMessage -- ConsoleMessage(...) -> nil local SetColorCodeFrame -- SetColorCodeFrame(Name) -> nil local GetColorCodeFrame -- GetColorCodeFrame() -> string do ConsoleMessage = function(...) setthreadidentity(8) console:AppendText(...) end ConsoleMessage("Tasability loading...") SetColorCodeFrame = function(Name) ColorCodeFrame.TextColor3 = ColorCodes[Name] or ColorCodes.None ColorCodeFrame.Text = "Status: "..(ColorCodes[Name] and Name or "None") end GetColorCodeFrame = function() return string.sub(ColorCodeFrame.Text, 9, #ColorCodeFrame.Text) end end do -- Anticheat bypasses do -- standard anti kick --// Variables local Players = game:GetService("Players") local OldNameCall = nil --// Anti Kick Hook local plr = game.Players.LocalPlayer OldNameCall = hookmetamethod(game, "__namecall", function(Self, ...) local NameCallMethod = getnamecallmethod() if not checkcaller() and Self == plr and NameCallMethod == "Kick" then if getgenv().SendNotifications == true then game:GetService("StarterGui"):SetCore("SendNotification", { Title = "Almost Kicked", Text = tostring(({...})[1]), Icon = "rbxassetid://6238540373", Duration = 3, }) end return nil end return OldNameCall(Self, ...) end) end pcall(function() -- Practice anticheat bypass game.ReplicatedStorage.Remotes.Send:Destroy() end) pcall(function() -- Slad anticheat bypass local sendremote = game.ReplicatedStorage.DefaultChatSystemChatEvents.ChannelNameColorUpdated local oldspawn oldspawn = hookfunction(getrenv().spawn, function(...) if not checkcaller() and (tostring(getcallingscript()) == "Animate" or tostring(getcallingscript()) == "RbxAnimateScript") then return oldspawn(function() end) end return oldspawn(...) end) sendremote:Destroy() end) -- ADONIS BYPASS local g = getinfo or debug.getinfo local d = false local h = {} local x, y setthreadidentity(2) for i, v in getgc(true) do if typeof(v) == "table" then local a = rawget(v, "Detected") local b = rawget(v, "Kill") if typeof(a) == "function" and not x then x = a local o; o = hookfunction(x, function(c, f, n) if c ~= "_" then if d then warn(`Adonis AntiCheat flagged\nMethod: {c}\nInfo: {f}`) end end return true end) table.insert(h, x) end if rawget(v, "Variables") and rawget(v, "Process") and typeof(b) == "function" and not y then y = b local o; o = hookfunction(y, function(f) if d then warn(`Adonis AntiCheat tried to kill (fallback): {f}`) end end) table.insert(h, y) end end end local o; o = hookfunction(getrenv().debug.info, newcclosure(function(...) local a, f = ... if x and a == x then if d then warn(`zins adonis bypassed`) end return coroutine.yield(coroutine.running()) end return o(...) end)) setthreadidentity(7) end -- Animation Functions local StopAllAnimations -- StopAllAnimations() -> nil local Reanimate -- Reanimate(Character) -> nil local GetAnimationFunctionFromId -- GetAnimationFunctionFromId(Id) -> function local onDied -- onDied() -> nil local onRunning -- onRunning(Speed) -> nil local onJumping -- onJumping() -> nil local onClimbing -- onClimbing(Speed) -> nil local onGettingUp -- onGettingUp() -> nil local onFreeFall -- onFreeFall() -> nil local onFallingDown -- onFallingDown() -> nil local onSeated -- onSeated() -> nil local onPlatformStanding -- onPlatformStanding() -> nil local onSwimming -- onSwimming() -> nil local PlayAnimation -- PlayAnimation() -> nil local setAnimationSpeed -- setAnimationSpeed() -> nil do StopAllAnimations = function() for _,v in pairs(Humanoid:GetPlayingAnimationTracks()) do v:Stop() end end GetAnimationFunctionFromId = function(Id) return ({ [1] = OnDied; [2] = onRunning; [3] = onJumping; [4] = onClimbing; [5] = onGettingUp; [6] = onFreeFall; [7] = onFallingDown; [8] = onSeated; [9] = onPlatformStanding; [10] = onSwimming; })[Id] end Reanimate = function(Character) if Character:WaitForChild("Animate",3) then for _, Animate in ipairs(Character:GetDescendants()) do if Animate:IsA("LocalScript") and Animate.Name == "Animate" then for _,Connection in pairs(getconnections(Animate.Changed)) do Connection:Disconnect() end if BypassAntiExploit then Animate.Disabled = true if setparentinternal then setparentinternal(Animate, game.Lighting) else ConsoleMessage("Your exploit does not support setparentinternal, expect animation glitches") end else Animate:Destroy() end end end else ConsoleMessage("[ERROR] Animate script could not be found, you probably executed twice") error("Animate script could not be found, you probably executed twice") end StopAllAnimations() do -- Animate script local Figure = Character local Torso = Figure:WaitForChild("Torso") local RightShoulder = Torso:WaitForChild("Right Shoulder") local LeftShoulder = Torso:WaitForChild("Left Shoulder") local RightHip = Torso:WaitForChild("Right Hip") local LeftHip = Torso:WaitForChild("Left Hip") local Neck = Torso:WaitForChild("Neck") local Humanoid = Figure:WaitForChild("Humanoid") local currentAnim = "" local currentAnimInstance = nil local currentAnimTrack = nil local currentAnimKeyframeHandler = nil --local currentAnimSpeed = 1.0 local animTable = {} local animNames = { idle = { { id = "http://www.roblox.com/asset/?id=180435571", weight = 8 }, { id = "http://www.roblox.com/asset/?id=180435792", weight = 1 } }, walk = { { id = "http://www.roblox.com/asset/?id=180426354", weight = 10 } }, run = { { id = "run.xml", weight = 10 } }, jump = { { id = "http://www.roblox.com/asset/?id=125750702", weight = 12 } }, fall = { { id = "http://www.roblox.com/asset/?id=180436148", weight = 9 } }, climb = { { id = "http://www.roblox.com/asset/?id=180436334", weight = 10 } }, sit = { { id = "http://www.roblox.com/asset/?id=178130996", weight = 10 } }, toolnone = { { id = "http://www.roblox.com/asset/?id=182393478", weight = 10 } }, toolslash = { { id = "http://www.roblox.com/asset/?id=129967390", weight = 10 } -- { id = "slash.xml", weight = 10 } }, toollunge = { { id = "http://www.roblox.com/asset/?id=129967478", weight = 10 } }, wave = { { id = "http://www.roblox.com/asset/?id=128777973", weight = 10 } }, point = { { id = "http://www.roblox.com/asset/?id=128853357", weight = 10 } }, dance1 = { { id = "http://www.roblox.com/asset/?id=182435998", weight = 10 }, { id = "http://www.roblox.com/asset/?id=182491037", weight = 10 }, { id = "http://www.roblox.com/asset/?id=182491065", weight = 10 } }, dance2 = { { id = "http://www.roblox.com/asset/?id=182436842", weight = 10 }, { id = "http://www.roblox.com/asset/?id=182491248", weight = 10 }, { id = "http://www.roblox.com/asset/?id=182491277", weight = 10 } }, dance3 = { { id = "http://www.roblox.com/asset/?id=182436935", weight = 10 }, { id = "http://www.roblox.com/asset/?id=182491368", weight = 10 }, { id = "http://www.roblox.com/asset/?id=182491423", weight = 10 } }, laugh = { { id = "http://www.roblox.com/asset/?id=129423131", weight = 10 } }, cheer = { { id = "http://www.roblox.com/asset/?id=129423030", weight = 10 } }, } local dances = {"dance1", "dance2", "dance3"} -- Existance in this list signifies that it is an emote, the value indicates if it is a looping emote local emoteNames = { wave = false, point = false, dance1 = true, dance2 = true, dance3 = true, laugh = false, cheer = false} function configureAnimationSet(name, fileList) if (animTable[name] ~= nil) then for _, connection in pairs(animTable[name].connections) do connection:disconnect() end end animTable[name] = {} animTable[name].count = 0 animTable[name].totalWeight = 0 animTable[name].connections = {} -- check for config values -- fallback to defaults if (animTable[name].count <= 0) then for idx, anim in pairs(fileList) do animTable[name][idx] = {} animTable[name][idx].anim = Instance.new("Animation") animTable[name][idx].anim.Name = name animTable[name][idx].anim.AnimationId = anim.id animTable[name][idx].weight = anim.weight animTable[name].count = animTable[name].count + 1 animTable[name].totalWeight = animTable[name].totalWeight + anim.weight -- print(name .. " [" .. idx .. "] " .. anim.id .. " (" .. anim.weight .. ")") end end end -- Setup animation objects -- Clear any existing animation tracks -- Fixes issue with characters that are moved in and out of the Workspace accumulating tracks local animator = Humanoid and Humanoid:FindFirstChildOfClass("Animator") or nil if animator then local animTracks = animator:GetPlayingAnimationTracks() for i,track in ipairs(animTracks) do track:Stop(0) track:Destroy() end end for name, fileList in pairs(animNames) do configureAnimationSet(name, fileList) end -- ANIMATION -- declarations local toolAnim = "None" local toolAnimTime = 0 local jumpAnimTime = 0 local jumpAnimDuration = 0.3 local toolTransitionTime = 0.1 local fallTransitionTime = 0.3 local jumpMaxLimbVelocity = 0.75 -- functions function stopAllAnimations() local oldAnim = currentAnim -- return to idle if finishing an emote if (emoteNames[oldAnim] ~= nil and emoteNames[oldAnim] == false) then oldAnim = "idle" end currentAnim = "" currentAnimInstance = nil if (currentAnimKeyframeHandler ~= nil) then currentAnimKeyframeHandler:disconnect() end if (currentAnimTrack ~= nil) then currentAnimTrack:Stop() currentAnimTrack:Destroy() currentAnimTrack = nil end return oldAnim end setAnimationSpeed = function(speed) if speed ~= currentAnimSpeed then currentAnimSpeed = speed currentAnimTrack:AdjustSpeed(currentAnimSpeed) end end function keyFrameReachedFunc(frameName) if (frameName == "End") then local repeatAnim = currentAnim -- return to idle if finishing an emote if (emoteNames[repeatAnim] ~= nil and emoteNames[repeatAnim] == false) then repeatAnim = "idle" end local animSpeed = currentAnimSpeed playAnimation(repeatAnim, 0.0, Humanoid) setAnimationSpeed(animSpeed) end end -- Preload animations playAnimation = function(animName, transitionTime, humanoid, bypassAnimateDisabled) --print(animName, transitionTime, humanoid, bypassAnimateDisabled) pcall(function() if AnimateDisabled and not bypassAnimateDisabled then return end table.insert(AnimationQueue,{animName,transitionTime}) local roll = math.random(1, animTable[animName].totalWeight) local origRoll = roll local idx = 1 while (roll > animTable[animName][idx].weight) do roll = roll - animTable[animName][idx].weight idx = idx + 1 end -- print(animName .. " " .. idx .. " [" .. origRoll .. "]") local anim = animTable[animName][idx].anim -- switch animation if (anim ~= currentAnimInstance) then if (currentAnimTrack ~= nil) then currentAnimTrack:Stop(transitionTime) currentAnimTrack:Destroy() end currentAnimSpeed = 1.0 -- load it to the humanoid; get AnimationTrack currentAnimTrack = humanoid:LoadAnimation(anim) currentAnimTrack.Priority = Enum.AnimationPriority.Core -- play the animation currentAnimTrack:Play(transitionTime) currentAnim = animName currentAnimInstance = anim -- set up keyframe name triggers if (currentAnimKeyframeHandler ~= nil) then currentAnimKeyframeHandler:disconnect() end currentAnimKeyframeHandler = currentAnimTrack.KeyframeReached:connect(keyFrameReachedFunc) end end) end ------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------- local toolAnimName = "" local toolAnimTrack = nil local toolAnimInstance = nil local currentToolAnimKeyframeHandler = nil function toolKeyFrameReachedFunc(frameName) if (frameName == "End") then -- print("Keyframe : ".. frameName) playToolAnimation(toolAnimName, 0.0, Humanoid) end end function playToolAnimation(animName, transitionTime, humanoid, priority) local roll = math.random(1, animTable[animName].totalWeight) local origRoll = roll local idx = 1 while (roll > animTable[animName][idx].weight) do roll = roll - animTable[animName][idx].weight idx = idx + 1 end -- print(animName .. " * " .. idx .. " [" .. origRoll .. "]") local anim = animTable[animName][idx].anim if (toolAnimInstance ~= anim) then if (toolAnimTrack ~= nil) then toolAnimTrack:Stop() toolAnimTrack:Destroy() transitionTime = 0 end -- load it to the humanoid; get AnimationTrack toolAnimTrack = humanoid:LoadAnimation(anim) if priority then toolAnimTrack.Priority = priority end -- play the animation toolAnimTrack:Play(transitionTime) toolAnimName = animName toolAnimInstance = anim currentToolAnimKeyframeHandler = toolAnimTrack.KeyframeReached:connect(toolKeyFrameReachedFunc) end end function stopToolAnimations() local oldAnim = toolAnimName if (currentToolAnimKeyframeHandler ~= nil) then currentToolAnimKeyframeHandler:disconnect() end toolAnimName = "" toolAnimInstance = nil if (toolAnimTrack ~= nil) then toolAnimTrack:Stop() toolAnimTrack:Destroy() toolAnimTrack = nil end return oldAnim end ------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------- onRunning = function(speed) if speed > 0.01 then playAnimation("walk", 0.1, Humanoid) if currentAnimInstance and currentAnimInstance.AnimationId == "http://www.roblox.com/asset/?id=180426354" then setAnimationSpeed(speed / 14.5) end pose = "Running" else if emoteNames[currentAnim] == nil then playAnimation("idle", 0.1, Humanoid) pose = "Standing" end end end onDied = function() pose = "Dead" end onJumping = function() playAnimation("jump", 0.1, Humanoid) jumpAnimTime = jumpAnimDuration pose = "Jumping" end onClimbing = function(speed) playAnimation("climb", 0.1, Humanoid) setAnimationSpeed(speed / 12.0) pose = "Climbing" end onGettingUp = function() pose = "GettingUp" end onFreeFall = function() if (jumpAnimTime <= 0) then playAnimation("fall", fallTransitionTime, Humanoid) end pose = "FreeFall" end onFallingDown = function() pose = "FallingDown" end onSeated = function() pose = "Seated" end onPlatformStanding = function() pose = "PlatformStanding" end onSwimming = function(speed) if speed > 0 then pose = "Running" else pose = "Standing" end end function getTool() for _, kid in ipairs(Figure:GetChildren()) do if kid.className == "Tool" then return kid end end return nil end function getToolAnim(tool) for _, c in ipairs(tool:GetChildren()) do if c.Name == "toolanim" and c.className == "StringValue" then return c end end return nil end function animateTool() if (toolAnim == "None") then playToolAnimation("toolnone", toolTransitionTime, Humanoid, Enum.AnimationPriority.Idle) return end if (toolAnim == "Slash") then playToolAnimation("toolslash", 0, Humanoid, Enum.AnimationPriority.Action) return end if (toolAnim == "Lunge") then playToolAnimation("toollunge", 0, Humanoid, Enum.AnimationPriority.Action) return end end function moveSit() RightShoulder.MaxVelocity = 0.15 LeftShoulder.MaxVelocity = 0.15 RightShoulder:SetDesiredAngle(3.14 /2) LeftShoulder:SetDesiredAngle(-3.14 /2) RightHip:SetDesiredAngle(3.14 /2) LeftHip:SetDesiredAngle(-3.14 /2) end local lastTick = 0 function move(time) if AnimateDisabled then return end local amplitude = 1 local frequency = 1 local deltaTime = time - lastTick lastTick = time local climbFudge = 0 local setAngles = false if (jumpAnimTime > 0) then jumpAnimTime = jumpAnimTime - deltaTime end if (pose == "FreeFall" and jumpAnimTime <= 0) then playAnimation("fall", fallTransitionTime, Humanoid) elseif (pose == "Seated") then playAnimation("sit", 0.5, Humanoid) return elseif (pose == "Running") then playAnimation("walk", 0.1, Humanoid) elseif (pose == "Dead" or pose == "GettingUp" or pose == "FallingDown" or pose == "Seated" or pose == "PlatformStanding") then -- print("Wha " .. pose) stopAllAnimations() amplitude = 0.1 frequency = 1 setAngles = true end if (setAngles) then local desiredAngle = amplitude * math.sin(time * frequency) RightShoulder:SetDesiredAngle(desiredAngle + climbFudge) LeftShoulder:SetDesiredAngle(desiredAngle - climbFudge) RightHip:SetDesiredAngle(-desiredAngle) LeftHip:SetDesiredAngle(-desiredAngle) end -- Tool Animation handling local tool = getTool() if tool and tool:FindFirstChild("Handle") then local animStringValueObject = getToolAnim(tool) if animStringValueObject then toolAnim = animStringValueObject.Value -- message recieved, delete StringValue animStringValueObject.Parent = nil toolAnimTime = time + .3 end if time > toolAnimTime then toolAnimTime = 0 toolAnim = "None" end animateTool() else stopToolAnimations() toolAnim = "None" toolAnimInstance = nil toolAnimTime = 0 end end -- connect events Humanoid.Died:connect(function(...) if AnimateDisabled then return end --table.insert(AnimationQueue,1) onDied(...) end) Humanoid.Running:connect(function(Speed) if AnimateDisabled then return end --table.insert(AnimationQueue,2) --RunSpeed = Speed onRunning(Speed) end) Humanoid.Jumping:connect(onJumping) Humanoid.Climbing:connect(function(Speed) if AnimateDisabled then return end --table.insert(AnimationQueue,4) --ClimbSpeed = Speed onClimbing(Speed) end) Humanoid.GettingUp:connect(function(...) if AnimateDisabled then return end --table.insert(AnimationQueue,5) onGettingUp(...) end) Humanoid.FreeFalling:connect(function(...) if AnimateDisabled then return end --table.insert(AnimationQueue,6) onFreeFall(...) end) Humanoid.FallingDown:connect(function(...) if AnimateDisabled then return end --table.insert(AnimationQueue,7) onFallingDown(...) end) Humanoid.Seated:connect(function(...) if AnimateDisabled then return end --table.insert(AnimationQueue,8) onSeated(...) end) Humanoid.PlatformStanding:connect(function(...) if AnimateDisabled then return end --table.insert(AnimationQueue,9) onPlatformStanding(...) end) Humanoid.Swimming:connect(function(...) if AnimateDisabled then return end --table.insert(AnimationQueue,10) onSwimming(...) end) -- setup emote chat hook game:GetService("Players").LocalPlayer.Chatted:connect(function(msg) local emote = "" if msg == "/e dance" then emote = dances[math.random(1, #dances)] elseif (string.sub(msg, 1, 3) == "/e ") then emote = string.sub(msg, 4) elseif (string.sub(msg, 1, 7) == "/emote ") then emote = string.sub(msg, 8) end if (pose == "Standing" and emoteNames[emote] ~= nil) then playAnimation(emote, 0.1, Humanoid) end end) -- main program -- initialize to idle playAnimation("idle", 0.1, Humanoid) pose = "Standing" spawn(function() while Figure.Parent ~= nil do local _, time = wait(0.1) move(time) end end) end end end -- Camera/Input Functions local GetZoom -- GetZoom() -> number local SetZoom -- SetZoom(Zoom) -> nil local GetShiftLockEnabled -- GetShiftLockEnabled() -> bool local SetShiftLockEnabled -- SetShiftLockEnabled(Enabled) -> nil local SetCameraCFrame -- SetCameraCFrame(NewCFrame) -> nil local BlockInputs -- BlockInputs() -> nil local UnlockInputs -- UnlockInputs() -> nil local SetCursorIcon -- SetCursorIcon(Icon) -> nil local SetCursorSize -- SetCursorSize(Size) -> nil local SetCursorOffset -- SetCursorOffset(Offset) -> nil local SetCursor -- SetCursorIcon(CursorName) -> nil do -- Load mouse lock action VirtualInputManager:SendKeyEvent(true, 304, false, workspace) wait() VirtualInputManager:SendKeyEvent(true, 304, false, workspace) wait() local ZoomControllers = {} do -- Get ZoomControllers from getgc for _,Table in pairs(getgc(true)) do if type(Table) == "table" then pcall(function() if type(Table.SetCameraToSubjectDistance) == "function" and type(Table.GetCameraToSubjectDistance) == "function" and Table.FIRST_PERSON_DISTANCE_THRESHOLD and Table.lastCameraTransform then table.insert(ZoomControllers,Table) end end) end end ConsoleMessage(tostring(#ZoomControllers).." ZoomController"..(#ZoomControllers == 1 and "" or "s")) end GetZoom = function() for _,ZoomController in pairs(ZoomControllers) do local Zoom = ZoomController:GetCameraToSubjectDistance() if Zoom and Zoom ~= 12.5 then -- Sometimes a ZoomController returns 12.5 so check if theres any other zoom levels before picking 12.5 return Zoom end end return 12.5 end SetZoom = function(Zoom) for _,ZoomController in pairs(ZoomControllers) do pcall(function() -- Sometimes a ZoomController errors and breaks the whole script ZoomController:SetCameraToSubjectDistance(Zoom) end) end end -- from original replayability -- from original replayability (optimized) GetShiftLockEnabled = function() return ShiftLockEnabled end -- Cache the mouse lock controller to avoid searching every time local cachedMouseLockController = nil local function getMouseLockController() if cachedMouseLockController and cachedMouseLockController.DoMouseLockSwitch then return cachedMouseLockController end -- Only search if cache is invalid for _, obj in getgc(true) do if type(obj) == "table" and rawget(obj, "activeMouseLockController") then cachedMouseLockController = obj.activeMouseLockController return cachedMouseLockController end end return nil end function shiftLock(active) local mouseLockController = getMouseLockController() if not mouseLockController then return end local isLocked = mouseLockController:GetIsMouseLocked() if (active and not isLocked) or (not active and isLocked) then mouseLockController:DoMouseLockSwitch("MouseLockSwitchAction", Enum.UserInputState.Begin, game) end end SetShiftLockEnabled = function(Enabled) if ShiftLockEnabled ~= Enabled then ShiftLockEnabled = Enabled if Enabled then SetCursor("MouseLockedCursor") else SetCursor("ArrowFarCursor") end shiftLock(Enabled) end end SetCameraCFrame = function(NewCFrame) CameraCFrame = NewCFrame workspace.CurrentCamera.CFrame = NewCFrame end local BlockGui = Instance.new("ScreenGui") local BlockFrame = Instance.new("TextButton") BlockFrame.Text = "" BlockFrame.BackgroundTransparency = 1 BlockFrame.Size = UDim2.fromScale(1,1) BlockFrame.Selectable = false BlockFrame.Selected = false BlockFrame.Parent = BlockGui BlockGui.Enabled = false BlockGui.Parent = GUIParent BlockInputs = function() BlockGui.Enabled = true end UnblockInputs = function() BlockGui.Enabled = false end local CursorHolder = Instance.new("ScreenGui") Cursor.BackgroundTransparency = 1 Cursor.ZIndex = 9999 Cursor.Parent = CursorHolder CursorHolder.ZIndexBehavior = Enum.ZIndexBehavior.Sibling CursorHolder.Parent = gethui() CursorHolder.DisplayOrder = 9999 Resolution = CursorHolder.AbsoluteSize SetCursor = function(CursorName) local CursorData = Cursors[CursorName] CursorIcon = CursorData.Icon CursorSize = CursorData.Size CursorOffset = CursorData.Offset end end -- AHK Functions local IsInstalled -- IsInstalled() -> bool local SendSignal -- SendSignal(Signal) -> nil do IsInstalled = function() return isfolder(AHKConnectionFolderPath) end SendSignal = function(Signal) if IsInstalled() then writefile(AHKConnectionRequestPath,Signal) else ConsoleMessage("AHK folder not found") end end end local Freeze -- Defined earlier so it can be used in replay functions -- Replay Functions local ReplayEncode -- ReplayEncode(Table) -> string local RecordReplay -- RecordReplay() -> nil [Event] local StartRecording -- StartRecording() -> nil local StopRecording -- StopRecording() -> nil local SaveRecording -- SaveRecording() -> nil local DiscardRecording -- DiscardRecording() -> nil local StartReading -- StartReading() -> nil local GetCheckpoint -- GetCheckpoint(CheckpointNumber?) -> number local SetCheckpoint -- SetCheckpoint(FrameIndex?) -> nil local GotoFrame -- GotoFrame(Index) -> nil do GetReplayFile = function() if not isfolder(string.split(FolderPath,"/")[1]) then makefolder(string.split(FolderPath,"/")[1]) end if not isfolder(FolderPath) then makefolder(FolderPath) end if not isfile(ReplayPath) then writefile(ReplayPath,ReplayFileBeginning) return ReplayFileBeginning end return readfile(ReplayPath) end ReplayEncode = function(Table) ConsoleMessage("Encoding "..tostring(#Table).." frames") local StartTick = tick() local Encoded = json.encode(Table) ConsoleMessage("Done encoding in",RoundNumber(tick()-StartTick,2),"seconds") return ReplayFileBeginning..Encoded..ReplayFileEnding end ReplayDecode = function(String) if String == ReplayFileBeginning or String == ReplayFileBeginning..ReplayFileEnding then ConsoleMessage("Nothing to read") return end ConsoleMessage("Decoding "..tostring(#String).." characters") local StartTick = tick() local Decoded = json.decode(String) ConsoleMessage("Done decoding in",RoundNumber(tick()-StartTick,2),"seconds") return Decoded.Replay end RecordReplay = function() ConsoleMessage("Waiting for input") if Writing then ConsoleMessage("Recording stopped") StopRecording() return end SetColorCodeFrame("WaitingForInput") WaitForInput() StartRecording() ConsoleMessage("Recording started") end StartRecording = function() if not Reading then SetColorCodeFrame("Recording") Writing = true end end StopRecording = function() if not Reading then Writing = false end end SaveToFile = function() local ReplayEncoded = ReplayEncode(ReplayTable) writefile(ReplayPath,ReplayEncoded) end SaveRecording = function() if #RecordingTable > 0 then local old = #ReplayTable for _,Frame in pairs(RecordingTable) do table.insert(ReplayTable,Frame) end RecordingTable = {} ConsoleMessage("Saved") end end DiscardRecording = function() if #RecordingTable > 0 then RecordingTable = {} ConsoleMessage("Discarded") end end StartReading = function() if not Reading then SaveToFile() ReplayTable = ReplayDecode(GetReplayFile()) -- Decode replay from file if ReplayTable then -- Decoding successful Freeze(false) -- Unfreeze AnimateDisabled = true -- Disable fake animate script Workspace.Gravity = 0 ReplayTableIndex = 1 BlockInputs() -- Disable scrolling and clicks Reading = true SetColorCodeFrame("Reading") ConsoleMessage("Reading started") ConsoleMessage("Length: "..RoundNumber(tostring(#ReplayTable/60)).." seconds") else -- Decoding failed ReplayTable = {} SetColorCodeFrame("Idle") end else ConsoleMessage("You are already reading") end end StopReading = function() if Reading then UnblockInputs() -- Enable scrolling and clicks Character.Head.CanCollide = true -- Fix character collisions Character.Torso.CanCollide = true -- Fix character collisions Character.HumanoidRootPart.CanCollide = true -- Fix character collisions AnimateDisabled = false -- Enable fake animate script Reading = false Character.Humanoid.JumpPower = DefaultJumpPower Character.Humanoid.WalkSpeed = DefaultWalkSpeed Workspace.Gravity = DefaultGravity SetColorCodeFrame("Idle") ConsoleMessage("Reading stopped") else ConsoleMessage("You are not reading") end end end -- Tasability functions --local Freeze -- Freeze(NewFrozen) -> nil do Freeze = function(NewFrozen,DoNotRecord) if Frozen ~= NewFrozen and not Reading then SeekDirection = 0 if NewFrozen then Frozen = true StopRecording() SaveRecording() FreezeFrame = #ReplayTable SetColorCodeFrame("Frozen") else --ConsoleMessage(#ReplayTable) --ConsoleMessage(FreezeFrame) if DoNotRecord then Frozen = false SetColorCodeFrame("Idle") else for Index = #ReplayTable,FreezeFrame,-1 do --ConsoleMessage(Index) ReplayTable[Index] = nil end Frozen = false StartRecording() SetColorCodeFrame("Recording") end end end end end -- Commands local Commands = {} do Commands["help"] = function(Args) if Args == "help" then ConsoleMessage("help : Shows a list of all commands, or a specific command") else local Command = Args[1] if Command then Command = string.lower(Command) if Commands[Command] then Commands[Command]("help") else ConsoleMessage("Command", Command, "was not found") end else for _,Command in pairs(Commands) do Command("help") end end end end Commands["erase"] = function(Args) if Args == "help" then ConsoleMessage("erase: Erases all data from the folder",PlaceId) else writefile(ReplayPath,ReplayFileBeginning) ReplayTable = {} return ReplayPath.." has been erased" end end Commands["setsdm"] = function(Args) if Args == "help" then ConsoleMessage("setsdm : Sets speed multiplier when using R and T while frozen") else local Number = tonumber(Args[1]) or 1 if Number then local OldValue = SeekDirectionMultiplier SeekDirectionMultiplier = Number return "SeekDirectionMultiplier has been set from "..tostring(OldValue).." to "..tostring(Number) end end end Commands["rejoin"] = function(Args) if Args == "help" then ConsoleMessage("rejoin : Sets one of the configs at the top of the script (PlaybackInputs, etc)") else local SaveReplay = Args[1] and string.lower(Args[1]) ConsoleMessage("Saving...") if SaveReplay == "true" or SaveReplay == "yes" or SaveReplay == "1" or SaveReplay == "save" then SaveToFile() end ConsoleMessage("Rejoining...") if #game.Players:GetPlayers() <= 1 then game.Players.LocalPlayer:Kick("\nRejoining...") wait() game:GetService("TeleportService"):Teleport(game.PlaceId, game.Players.LocalPlayer) else game:GetService("TeleportService"):TeleportToPlaceInstance(game.PlaceId, game.JobId, game.Players.LocalPlayer) end return "Sent request to rejoin" end end Commands["invite"] = function(Args) if Args == "help" then ConsoleMessage("invite: Invites you to Tasability Discord") else request({ Url = "http://127.0.0.1:6463/rpc?v=1", Method = "POST", Headers = { ["Content-Type"] = "application/json", ["origin"] = "https://discord.com", }, Body = game:GetService("HttpService"):JSONEncode({ ["args"] = { ["code"] = "Shyfsc2cJ9", }, ["cmd"] = "INVITE_BROWSER", ["nonce"] = "." }) }) return "Sent invite (if your exploit blocked it the invite is https://discord.gg/Shyfsc2cJ9)" end end end -- Connection Functions local StateChanged local CharacterAdded local InputBegan local RenderStepped local Stepped local CurrentCamera_Changed do StateChanged = function(_,State) table.insert(HumanoidStateQueue,State.Value) end CharacterAdded = function(NewCharacter) Humanoid = NewCharacter:WaitForChild("Humanoid") Humanoid.StateChanged:Connect(StateChanged) RootPart = NewCharacter:WaitForChild("HumanoidRootPart") DefaultJumpPower = Humanoid.JumpPower DefaultWalkSpeed = Humanoid.WalkSpeed Reanimate(NewCharacter) Character = NewCharacter Humanoid.Died:Connect(function() Dead = true end) Dead = false end InputBegan = function(Input,GameProcessed) if IgnoreGameProcessed then GameProcessed = false end if Input.UserInputType == Enum.UserInputType.MouseButton1 then table.insert(InputBeganQueue,"b1") elseif Input.UserInputType == Enum.UserInputType.MouseButton2 then table.insert(InputBeganQueue,"b2") elseif Input.UserInputType == Enum.UserInputType.Keyboard then local InputName = string.split(tostring(Input.KeyCode),".")[3] if not InputBlacklist[InputName] then table.insert(InputBeganQueue,InputName) end end if Input.KeyCode == Enum.KeyCode.LeftShift and not Reading and not GameProcessed then SetShiftLockEnabled(not ShiftLockEnabled) end if Input.KeyCode == Recordkeybind.Value and not GameProcessed then -- Freeze/Unfreeze Freeze(not Frozen) elseif Input.KeyCode == Gobackwardskeybind.Value and not GameProcessed then if not Reading then Freeze(true) if SeekDirection == 0 then SeekDirection = -1*SeekDirectionMultiplier -- Backwards end end elseif Input.KeyCode == Goforwardkeybind.Value and not GameProcessed then -- Seek fowards if not Reading then Freeze(true) if SeekDirection == 0 then SeekDirection = 1*SeekDirectionMultiplier -- Fowards end end elseif Input.KeyCode == Frameadvancebackwardskeybind.Value and not GameProcessed then -- Go 1 frame backwards Freeze(true) if Frozen and SeekDirection == 0 then local NewFreezeFrame = FreezeFrame - 1 if NewFreezeFrame > 0 and NewFreezeFrame <= #ReplayTable then FreezeFrame = NewFreezeFrame end end elseif Input.KeyCode == Frameadvanceforwardkeybind.Value and not GameProcessed then -- Go 1 frame fowards Freeze(true) if Frozen and SeekDirection == 0 then local NewFreezeFrame = FreezeFrame + 1 if NewFreezeFrame > 0 and NewFreezeFrame <= #ReplayTable then FreezeFrame = NewFreezeFrame end end elseif Input.KeyCode == Hideuikeybind.Value and not GameProcessed then -- Toggle UI Window:ToggleVisibility() elseif Input.KeyCode == Abortkeybind.Value and not GameProcessed then -- Stop reading StopReading() elseif Input.KeyCode == Savekeybind.Value and not GameProcessed then -- Save to file SaveToFile() elseif Input.KeyCode == Frozenkeybind.Value and not GameProcessed then -- Save to file IdleButton_MouseButton1Click() elseif Input.KeyCode == Readkeybind.Value and not GameProcessed then ReadButton_MouseButton1Click() end end InputChanged = function(Input,GameProcessed) if Input.UserInputType == Enum.UserInputType.MouseWheel then if Input.Position.Z > 0 then table.insert(InputBeganQueue,"u") else table.insert(InputBeganQueue,"d") end end end InputEnded = function(Input,GameProcessed) if Input.UserInputType == Enum.UserInputType.MouseButton1 then table.insert(InputEndedQueue,"b1") elseif Input.UserInputType == Enum.UserInputType.MouseButton2 then table.insert(InputEndedQueue,"b2") elseif Input.UserInputType == Enum.UserInputType.MouseWheel then if Input.Position.Z > 0 then table.insert(InputEndedQueue,"u") else table.insert(InputEndedQueue,"d") end elseif Input.UserInputType == Enum.UserInputType.Keyboard then local InputName = string.split(tostring(Input.KeyCode),".")[3] table.insert(InputEndedQueue,InputName) end if Input.KeyCode == Gobackwardskeybind.Value then -- Stop seeking backwards if SeekDirection == -1*SeekDirectionMultiplier then SeekDirection = 0 end elseif Input.KeyCode == Goforwardkeybind then -- Stop seeking fowards if SeekDirection == 1*SeekDirectionMultiplier then SeekDirection = 0 end end end RenderStepped = function(...) for _,Function in pairs(RenderSteppedConnections) do Function(...) end end Stepped = function(...) for _,Function in pairs(SteppedConnections) do Function(...) end end ReadButton_MouseButton1Click = function() if ReplayStartTime >= 1 then for i = ReplayStartTime,1,-1 do ConsoleMessage("Reading in "..tostring(i).." seconds") wait(1) end end StartReading() end IdleButton_MouseButton1Click = function() if GetColorCodeFrame() == "Frozen" then Freeze(false,true) end end CurrentCamera_Changed = function() if Reading then workspace.CurrentCamera.CFrame = CameraCFrame end end ConsoleInput.Callback = function(self, value) local Input = value local InputSplit = string.split(Input," ") local Command = Commands[string.lower(InputSplit[1])] if Command then table.remove(InputSplit,1) local ReturnMessage = Command(InputSplit) if ReturnMessage then ConsoleMessage(ReturnMessage) end else ConsoleMessage("Command",InputSplit[1],"was not found") end self:Clear() end end -- RenderStepped/Stepped connections do RenderSteppedConnections.UpdateFreezeFrame = function() RecordedFramesLabel.Text = "Frames: "..RoundNumber(FreezeFrame,0) end RenderSteppedConnections.SeekDirectionHandler = function() if Frozen then local NewFreezeFrame = FreezeFrame + SeekDirection if NewFreezeFrame < 1 then FreezeFrame = 1 elseif NewFreezeFrame > #ReplayTable then FreezeFrame = #ReplayTable else FreezeFrame = NewFreezeFrame end end end local PressedWriting = {} SteppedConnections.UpdateInputPreview = function() for _,Input in pairs(InputBeganQueue) do if Input == "u" or Input == "d" then return end Pressed[Input] = true end for _,Input in pairs(InputEndedQueue) do Pressed[Input] = nil end PressedKeysLabel.Text = "Pressed keys: |" for Input,_ in pairs(Pressed) do PressedKeysLabel.Text = PressedKeysLabel.Text..Input.."|" end -- MOVED TO FREEZE LOOP --[[if Writing then for _,Input in pairs(InputBeganQueue) do if Input == "u" or Input == "d" then return end PressedWriting[Input] = true end for _,Input in pairs(InputEndedQueue) do PressedWriting[Input] = nil end WritingPressedKeysLabel.Text = "|" for Input,_ in pairs(PressedWriting) do WritingPressedKeysLabel.Text = WritingPressedKeysLabel.Text..Input.."|" end end]] end end do -- Connections UserInputService.InputBegan:Connect(InputBegan) UserInputService.InputChanged:Connect(InputChanged) UserInputService.InputEnded:Connect(InputEnded) RunService.RenderStepped:Connect(RenderStepped) RunService.Stepped:Connect(Stepped) Player.CharacterAdded:Connect(CharacterAdded) workspace.CurrentCamera.Changed:Connect(CurrentCamera_Changed) end do -- Setup GetReplayFile() -- Create folders and files for Replayability+ if needed SetCursor("ArrowFarCursor") -- Add fake cursor UserInputService.MouseIconEnabled = false -- Remove real cursor DefaultGravity = Workspace.Gravity -- Set DefaultGravity ShiftLockBoundKeys.Value = "" -- Remove shift lock keybinds CharacterAdded(Player.Character) -- Set character SetColorCodeFrame("Idle") -- Set color code end local function findAnimateScript(character) if not character then return nil end -- common names local names = { "Animate", "AnimationScript", "CharacterAnimate", "PlayerAnimate" } -- check common names for _, name in ipairs(names) do local s = character:FindFirstChild(name, true) if s and s:IsA("LocalScript") then return s end end -- smart detection for _, obj in ipairs(character:GetDescendants()) do if obj:IsA("LocalScript") then for _, sub in ipairs(obj:GetChildren()) do local n = sub.Name:lower() if n == "idle" or n == "walk" or n == "run" or n == "jump" or n == "fall" then return obj end end end end return nil end spawn(function() -- Reading Loop lol local frameCache = {} local lastAnimations = {} local currentAnimTracks = {} while true do if Reading then local Frame = ReplayTable[ReplayTableIndex] -- Handle special frames (void/death) if Frame == 0 then Humanoid:ChangeState(15) for _,Descendant in pairs(Character:GetDescendants()) do if Descendant:IsA("BasePart") then Descendant:Destroy() end end repeat wait() until not Dead RunService.Heartbeat:Wait() ReplayTableIndex = ReplayTableIndex + 1 continue elseif Frame == 1 then Humanoid:ChangeState(15) workspace.Gravity = DefaultGravity repeat wait() until not Dead RunService.Heartbeat:Wait() ReplayTableIndex = ReplayTableIndex + 1 continue end if not Frame or typeof(Frame) == "string" then StopReading() continue end local animateScript = findAnimateScript(Character) if animateScript then animateScript.Disabled = true end AnimateDisabled = true workspace.Gravity = 0 Character.Humanoid.JumpPower = 0 Character.Humanoid.WalkSpeed = 0 if not Character:FindFirstChild("HumanoidRootPart") then RunService.Heartbeat:Wait() continue end local HRP = Character.HumanoidRootPart for _,v in pairs(Character:GetChildren()) do if v:IsA("BasePart") then v.CanCollide = false end end Humanoid.PlatformStand = true -- Cache local cache = frameCache[ReplayTableIndex] if not cache then cache = { hrpCFrame = FastTableToCFrame(Frame[1]), camCFrame = FastTableToCFrame(Frame[7]), hrpVel = FastTableToVector3(Frame[5]), hrpRotVel = FastTableToVector3(Frame[6]), mouseLocation = FastTableToVector2(Frame[11]) } frameCache[ReplayTableIndex] = cache end local Animations = Frame[2] local AnimationSpeed = Frame[3] local HumanoidState = Frame[4] local Zoom = Frame[8] local AnimatePose = Frame[9] local ShiftLockEnabled = (Frame[10] == 1) local InputBeganQueue = Frame[12][1] local InputEndedQueue = Frame[12][2] SetCameraCFrame(cache.camCFrame) SetZoom(Zoom) pose = AnimatePose Humanoid:ChangeState(HumanoidState) for _, Arguments in pairs(Animations) do local animName = Arguments[1] local transitionTime = Arguments[2] playAnimation(animName, transitionTime, Humanoid, true) end pcall(setAnimationSpeed, AnimationSpeed) if ShiftLockEnabled ~= GetShiftLockEnabled() then SetShiftLockEnabled(ShiftLockEnabled) end if PlaybackMouseLocation and not ShiftLockEnabled and Zoom > 0.52 then mousemoveabs(cache.mouseLocation.X, cache.mouseLocation.Y) else local CurrentGuiInset = GuiService:GetGuiInset() mousemoveabs( (Resolution.X/2) + CursorOffset.X - CurrentGuiInset.X, (Resolution.Y/2) + CursorOffset.Y - CurrentGuiInset.Y - 36 ) end -- Handle input playback if PlaybackInputs then local Signal = {} for _, Input in pairs(InputBeganQueue) do local Code = InputCodes[Input] if Code then keypress(Code) elseif Input == "b1" then mouse1press() elseif Input == "b2" then mouse2press() elseif Input == "u" or Input == "d" then table.insert(Signal, Input) end end for _, Input in pairs(InputEndedQueue) do local Code = InputCodes[Input] if Code then keyrelease(Code) elseif Input == "b1" then mouse1release() elseif Input == "b2" then mouse2release() end end if #Signal > 0 then SendSignal(table.concat(Signal, ",")) end end local alignPos = HRP:FindFirstChild("TAS_AlignPosition") local alignOrient = HRP:FindFirstChild("TAS_AlignOrientation") local attachment = HRP:FindFirstChild("TAS_Attachment") if not attachment then attachment = Instance.new("Attachment") attachment.Name = "TAS_Attachment" attachment.Parent = HRP end if not alignPos then alignPos = Instance.new("AlignPosition") alignPos.Name = "TAS_AlignPosition" alignPos.Attachment0 = attachment alignPos.Mode = Enum.PositionAlignmentMode.OneAttachment alignPos.MaxForce = 9e9 alignPos.MaxVelocity = 9e9 alignPos.Responsiveness = 200 alignPos.RigidityEnabled = true alignPos.Parent = HRP end if not alignOrient then alignOrient = Instance.new("AlignOrientation") alignOrient.Name = "TAS_AlignOrientation" alignOrient.Attachment0 = attachment alignOrient.Mode = Enum.OrientationAlignmentMode.OneAttachment alignOrient.MaxTorque = 9e9 alignOrient.MaxAngularVelocity = 9e9 alignOrient.Responsiveness = 200 alignOrient.RigidityEnabled = true alignOrient.Parent = HRP end alignPos.Position = cache.hrpCFrame.Position alignOrient.CFrame = cache.hrpCFrame HRP.Velocity = cache.hrpVel HRP.RotVelocity = cache.hrpRotVel HRP.CFrame = cache.hrpCFrame ReplayTableIndex = ReplayTableIndex + 1 -- Clear old cache if ReplayTableIndex > 100 then frameCache[ReplayTableIndex - 100] = nil for animName, frameIndex in pairs(lastAnimations) do if frameIndex < ReplayTableIndex - 100 then lastAnimations[animName] = nil end end end else workspace.Gravity = DefaultGravity pcall(function() if Character and Character:FindFirstChild("HumanoidRootPart") then local HRP = Character.HumanoidRootPart if HRP:FindFirstChild("TAS_AlignPosition") then HRP.TAS_AlignPosition:Destroy() end if HRP:FindFirstChild("TAS_AlignOrientation") then HRP.TAS_AlignOrientation:Destroy() end if HRP:FindFirstChild("TAS_Attachment") then HRP.TAS_Attachment:Destroy() end Character.Humanoid.PlatformStand = false end end) frameCache = {} lastAnimations = {} currentAnimTracks = {} end RunService.Heartbeat:Wait() end end) spawn(function() -- Writing while true do --print(currentAnimSpeed) --print(GetShiftLockEnabled()) --table.foreach(InputEndedQueue,print) --print(GetZoom()) if Writing then if (not Character or not Character.Parent) or (not Character:FindFirstChild("HumanoidRootPart")) then if type(RecordingTable[#RecordingTable]) == "table" then table.insert(RecordingTable,0) -- Voided end RunService.RenderStepped:Wait() continue end if (Humanoid.Health == 0) then if type(RecordingTable[#RecordingTable]) == "table" then table.insert(RecordingTable,1) -- Dead end RunService.RenderStepped:Wait() continue end local Frame = {} Frame[1] = RoundTable(CFrameToTable(Character.HumanoidRootPart.CFrame),RoundDigits) Frame[2] = AnimationQueue Frame[3] = RoundNumber(currentAnimSpeed,RoundDigits) Frame[4] = Humanoid:GetState().Value Frame[5] = RoundTable(Vector3ToTable(Character.HumanoidRootPart.Velocity),RoundDigits) Frame[6] = RoundTable(Vector3ToTable(Character.HumanoidRootPart.RotVelocity),RoundDigits) Frame[7] = RoundTable(CFrameToTable(workspace.CurrentCamera.CFrame),RoundDigits) Frame[8] = RoundNumber(GetZoom(),RoundDigits) Frame[9] = pose Frame[10] = (GetShiftLockEnabled() and 1) or 0 Frame[11] = RoundTable(Vector2ToTable(UserInputService:GetMouseLocation()),RoundDigits) Frame[12] = {InputBeganQueue,InputEndedQueue} table.insert(RecordingTable,Frame) end AnimationQueue = {} RunSpeed = 0 ClimbSpeed = 0 HumanoidStateQueue = {} if setfpscap then setfpscap(FPS) end RunService.RenderStepped:Wait() end end) -- Clear input queues RunService.Heartbeat:Connect(function() InputBeganQueue = {} InputEndedQueue = {} end) spawn(function() -- Check if connected while true do wait(1) if not Reading then local Installed = IsInstalled() if Installed then ConnectedLabel.Text = "AHK folder found" ConnectedLabel.TextColor3 = Color3.new(0,0.8,0) else ConnectedLabel.Text = "AHK folder not found" ConnectedLabel.TextColor3 = Color3.new(0.8,0,0) end end end end) spawn(function() -- Update cursor while true do Cursor.Image = CursorIcon Cursor.Size = CursorSize local MouseLocation = UserInputService:GetMouseLocation() local CurrentGuiInset = GuiService:GetGuiInset() if ShiftLockEnabled or UserInputService.MouseBehavior == Enum.MouseBehavior.LockCenter then Cursor.Position = UDim2.fromOffset( (Resolution.X / 2) + CursorOffset.X - CurrentGuiInset.X, (Resolution.Y / 2) + CursorOffset.Y - CurrentGuiInset.Y - 36 ) else Cursor.Position = UDim2.fromOffset( MouseLocation.X + CursorOffset.X - CurrentGuiInset.X, MouseLocation.Y + CursorOffset.Y - CurrentGuiInset.Y - 36 ) end RunService.RenderStepped:Wait() end end) --[[local oldprint oldprint = hookfunction(print,function(...) if checkcaller() then return oldprint(...) end end)]] spawn(function() -- Handling freezing while true do if Frozen then Character.HumanoidRootPart.Anchored = true if FreezeFrame > 0 and FreezeFrame <= #ReplayTable then local RoundedFreezeFrame = RoundNumber(FreezeFrame,0) print(FreezeFrame, RoundedFreezeFrame) local Frame = ReplayTable[RoundedFreezeFrame] if type(Frame) == "table" then local AnimatePose -- -2 local Animation -- -1 for Index = RoundedFreezeFrame,1,-1 do if AnimatePose and Animation then break end local Frame = ReplayTable[Index] if type(Frame) == "table" then AnimatePose = Frame[9] Animation = Frame[2][#Frame[2]] end end local CurrentPressedKeys = {} for Index = RoundedFreezeFrame-math.max(FrameBacktrackCount,0),RoundedFreezeFrame do local Frame = ReplayTable[Index] if Frame and type(Frame) == "table" then local BeganInputs,EndedInputs = unpack(Frame[12]) for _,Key in pairs(BeganInputs) do if Key ~= "u" and Key ~= "d" then -- Exclude scroll inputs CurrentPressedKeys[Key] = true end end for _,Key in pairs(EndedInputs) do -- Scroll inputs don't show up in EndedInputs CurrentPressedKeys[Key] = nil end end end -- Display keys pressed on WritingPressedKeysLabel WritingPressedKeysLabel.Text = "Writing Pressed keys: |" for Input,_ in pairs(CurrentPressedKeys) do WritingPressedKeysLabel.Text = WritingPressedKeysLabel.Text..Input.."|" end local HumanoidRootPartCFrame = TableToCFrame(Frame[1]) -- 4 local AnimationSpeed = Frame[3] -- 9 local HumanoidState = Frame[4] -- 1 local HumanoidRootPartVelocity = TableToVector3(Frame[5]) -- 2 local HumanoidRootPartRotVelocity = TableToVector3(Frame[6]) -- 3 local CameraCFrame = TableToCFrame(Frame[7]) -- 5 local Zoom = Frame[8] -- 6 local ShiftLockEnabled = (Frame[10] == 1 and true) or false -- 7 local MouseLocation = TableToVector2(Frame[11]) -- 8 local CurrentState = Humanoid:GetState().Value -- -1 if Animation then if Animation[1] == "walk" then if Humanoid.FloorMaterial ~= Enum.Material.Air and CurrentState ~= 3 then playAnimation("walk",Animation[2],Humanoid,true) end else playAnimation(Animation[1],Animation[2],Humanoid,true) end end pcall(setAnimationSpeed,AnimationSpeed) -- 9 pose = AnimatePose -- -2 Humanoid:ChangeState(HumanoidState) -- 1 Character.HumanoidRootPart.Velocity = HumanoidRootPartVelocity -- 2 Character.HumanoidRootPart.RotVelocity = HumanoidRootPartRotVelocity -- 3 Character.HumanoidRootPart.CFrame = HumanoidRootPartCFrame -- 4 if not movecameraonfroze.Value then workspace.CurrentCamera.CFrame = CameraCFrame --5 SetZoom(Zoom) -- 6 if ShiftLockEnabled ~= GetShiftLockEnabled() then SetShiftLockEnabled(ShiftLockEnabled) -- 7 end end if PlaybackMouseLocation then mousemoveabs(MouseLocation.X,MouseLocation.Y) -- 8 end else -- Frame is not a table RunService.RenderStepped:Wait() end else --ConsoleMessage("FreezeFrame is",FreezeFrame,"(not in range)") end else pcall(function() Character.HumanoidRootPart.Anchored = false end) end RunService.RenderStepped:Wait() end end) do -- Set checkpoint ConsoleMessage("Loading from file...") ReplayTable = ReplayDecode(GetReplayFile()) -- Decode replay from file if not ReplayTable then ReplayTable = {} ConsoleMessage("There is no replay folder for",PlaceId) end end ConsoleMessage("Tasability",Version,"loaded in",RoundNumber(tick()-ExecutionTick,2),"seconds") ConsoleMessage("Type help to see all commands")