local UserInputService = game:GetService("UserInputService") local ReplicatedStorage = game:GetService("ReplicatedStorage") local Players = game:GetService("Players") local Debris = game:GetService("Debris") local Workspace = game:GetService("Workspace") local HitboxModule = require(ReplicatedStorage:WaitForChild("Modules"):WaitForChild("HitboxModule")) local Config = require(ReplicatedStorage:WaitForChild("Modules"):WaitForChild("Config")) local Remotes = ReplicatedStorage:WaitForChild("Remotes") local Player = Players.LocalPlayer local PlayerGui = Player.PlayerGui local MobileUI = PlayerGui:WaitForChild("MobileUI") local MainFrame_Mobile = MobileUI:WaitForChild("Main") local Attack_Mobile = MainFrame_Mobile:WaitForChild("Attack") local Block_Mobile = MainFrame_Mobile:WaitForChild("Block") local Temp = {} local Character: Model, Humanoid: Humanoid, Animator: Animator local AnimPrefix = "rbxassetid://" local HitAnimationId = 85710625600514 local DownslamAnimationId = 132755135725741 local UppercutAnimationId = 97693103786628 local BlockingAnimTrack local Data = { Punch = { OnDebounce = false; DebounceTime = 0.5; MaxDebounceTime = 1.5; OnNum = 0; MaxNum = 4; HitPlayers = {}; BlockingPlayers = {}; ResetTime = 2; PunchThread = nil; LastPunchTime = 0; Uppercut = false; }, } local function OnCharacterAdded(Char: Model) Character = Char :: Model Humanoid = Character:WaitForChild("Humanoid") :: Humanoid Animator = Humanoid:WaitForChild("Animator") :: Animator end OnCharacterAdded(Player.Character or Player.CharacterAdded:Wait()) local function PlayAnim(Id: string) local AnimId = AnimPrefix..Id local Animation = Instance.new("Animation") Animation.AnimationId = AnimId local AnimTrack = Animator:LoadAnimation(Animation) AnimTrack:Play() end local function CheckMobile() if UserInputService.TouchEnabled then MobileUI.Enabled = true end end local function IsInAir() local S = Humanoid:GetState() return (S == Enum.HumanoidStateType.Freefall or S == Enum.HumanoidStateType.FallingDown or S == Enum.HumanoidStateType.Jumping) end local function GetState() if IsInAir() and Data.Punch.OnNum == Data.Punch.MaxNum then warn("Downslam") return "Slam" end return "Normal" end local function _Input(Plr: Player, Char: Model) if Humanoid and Humanoid.Health <= 0 then return end local SelectedChar, CharDataTable = Remotes.GetCharacterInfo:InvokeServer() if not (SelectedChar and CharDataTable) then return end if Data.Punch.OnDebounce then return end Data.Punch.OnDebounce = true if Data.Punch.OnNum + 1 > Data.Punch.MaxNum then Data.Punch.OnNum = 1 else Data.Punch.OnNum += 1 end local State = GetState() if Data.Punch.Uppercut then State = "Uppercut" end Data.Punch.LastPunchTime = tick() if State == "Slam" then PlayAnim(DownslamAnimationId) elseif State == "Uppercut" then PlayAnim(UppercutAnimationId) else local AnimId = CharDataTable.Animations.PunchAnimations[Data.Punch.OnNum] if AnimId then PlayAnim(AnimId) end end Remotes.Attack:FireServer(Data.Punch.OnNum, State) if Data.Punch.PunchThread then task.cancel(Data.Punch.PunchThread) end Data.Punch.PunchThread = task.delay(Data.Punch.ResetTime, function() Data.Punch.OnNum = 0 Data.Punch.PunchThread = nil end) local WaitTime = (Data.Punch.OnNum == Data.Punch.MaxNum) and Data.Punch.MaxDebounceTime or Data.Punch.DebounceTime task.delay(WaitTime, function() Data.Punch.OnDebounce = false end) end CheckMobile() local function _Block(Plr: Player, Hum: Humanoid, IsBlocking: boolean) Remotes.Block:FireServer(IsBlocking) if IsBlocking then local SelectedCharacter = Player.SelectedCharacter.Value local Character = Player.Character if SelectedCharacter then local CharModule = require(ReplicatedStorage:WaitForChild("Modules"):WaitForChild("CharacterModule"):WaitForChild("Characters")[SelectedCharacter]) if CharModule then local BlockingAnim = CharModule.Animations.Blocking if BlockingAnim then local AnimId = AnimPrefix .. BlockingAnim local Animation = Instance.new("Animation") Animation.AnimationId = AnimId BlockingAnimTrack = Animator:LoadAnimation(Animation) BlockingAnimTrack:Play() end end end else if BlockingAnimTrack then BlockingAnimTrack:Stop() end end end Attack_Mobile.MouseButton1Click:Connect(function() _Input(Player, Character) end) Block_Mobile.MouseButton1Down:Connect(function() _Block(Player, Humanoid, true) end) Block_Mobile.MouseButton1Up:Connect(function() _Block(Player, Humanoid, false) end) Block_Mobile.MouseLeave:Connect(function() _Block(Player, Humanoid, false) end) UserInputService.InputBegan:Connect(function(Input: InputObject, GameProcessedEvent: boolean) if GameProcessedEvent then return end if Input.UserInputType == Enum.UserInputType.MouseButton1 then _Input(Player, Character) end if Input.KeyCode == Enum.KeyCode.F then _Block(Player, Humanoid, true) end if Input.UserInputType == Enum.UserInputType.Touch then _Block(Player, Humanoid, false) end if Input.KeyCode == Enum.KeyCode.Space then local DT = tick() - Data.Punch.LastPunchTime if DT <= 0.5 and Data.Punch.OnNum == Data.Punch.MaxNum then warn("Uppercut") Data.Punch.Uppercut = true _Input(Player, Character) Data.Punch.Uppercut = false end end end) UserInputService.InputEnded:Connect(function(Input: InputObject, GameProcessedEvent: boolean) if GameProcessedEvent then return end if Input.KeyCode == Enum.KeyCode.F then _Block(Player, Humanoid, false) end end) Player.CharacterAdded:Connect(OnCharacterAdded)