local DefaultRiposteDistance = 15 -- To be used when the blade size can't be determined local Autoparry = true -- H to toggle local Players = game:GetService("Players") local Player = Players.LocalPlayer if Player == nil then Players:GetPropertyChangedSignal("LocalPlayer"):Wait() Player = Players.LocalPlayer end local Mouse = Player:GetMouse() local namecall local newindex local PlayerWeapon = { --[[ ["Instance"] = nil; ["Stats"] = nil; ["RiposteTrack"] = nil; ["RiposteLength"] = nil; --]] } local Monitoring = { --[[ PlayerName = { Sound = Instance; Connection = Connection; } --]] } local WeaponAnimations = require(game:GetService("ReplicatedStorage"):WaitForChild("ClientModule"):WaitForChild("WeaponAnimations")) namecall = hookmetamethod(game, "__namecall", function(self, ...) local Method = getnamecallmethod() if Method == "FireServer" or Method == "InvokeServer" then local Args = {...} local RemoteName = tostring(self) if RemoteName == "ChangeVal" and Autoparry and not checkcaller() then if Args[2] == "" then return end if Args[2] ~= "Riposte" and Args[2] ~= "Release" and Args[2] ~= "Idle" and Args[2] ~= "Equip" and Args[2] ~= "" then if PlayerWeapon.Instance ~= nil and PlayerWeapon.Instance.Stance.Value == "Riposte" then self.FireServer(self,Args[1],"RiposteDelay") end if PlayerWeapon.Instance ~= nil and PlayerWeapon.Instance.Stance.Value == "Parrying" then self.FireServer(self,Args[1],"UnParry") end self.FireServer(self,Args[1],"Idle") elseif Args[2] == "Riposte" then self.FireServer(self,Args[1],"Idle") end if PlayerWeapon["RiposteTrack"] ~= nil and PlayerWeapon["RiposteTrack"].IsPlaying then PlayerWeapon["RiposteTrack"].Stop(PlayerWeapon["RiposteTrack"],1) end end end return namecall(self, ...) end) newindex = hookmetamethod(game, "__newindex", function(self, index, value) if tostring(self) == "Stance" and index == "Value" then return end return newindex(self, index, value) end) local function CheckDescendant(Desc) if Desc:IsA("Tool") and Players:GetPlayerFromCharacter(Desc.Parent) ~= nil and Desc.Parent.Name == Player.Name and PlayerWeapon["Instance"] ~= Desc then -- while I'm checking for every descendant added to the workspace..... PlayerWeapon.Instance = Desc local SettingsModule = Desc:FindFirstChild("Settings") if SettingsModule ~= nil then PlayerWeapon.Stats = require(SettingsModule) if WeaponAnimations[PlayerWeapon.Stats.Type] ~= nil and Player.Character:FindFirstChild("Humanoid") then local NewRiposte = Instance.new("Animation") NewRiposte.AnimationId = "rbxassetid://"..WeaponAnimations[PlayerWeapon.Stats.Type].Riposte PlayerWeapon["RiposteTrack"] = Player.Character.Humanoid:LoadAnimation(NewRiposte) PlayerWeapon["RiposteLength"] = PlayerWeapon["RiposteTrack"].Length end end end if Desc:IsA("Sound") and Desc.Name == "Swing" and Desc:FindFirstAncestorOfClass("Tool") then local Character = Desc:FindFirstAncestorOfClass("Model") if Character ~= nil and Character.Name ~= Player.Name and Players:GetPlayerFromCharacter(Character) ~= nil then if Monitoring[Character.Name] ~= nil and Monitoring[Character.Name].Sound == Desc then return end if Monitoring[Character.Name] ~= nil and Monitoring[Character.Name].Connection ~= nil then Monitoring[Character.Name].Connection:Disconnect() Monitoring[Character.Name].Connection = nil -- not sure if this is redundant due to the next step end local Tool = Desc:FindFirstAncestorOfClass("Tool") local Blade = Tool:FindFirstChild("Blade") local BodyAttach = Tool:FindFirstChild("BodyAttach") or Character:FindFirstChild("HumanoidRootPart") local ComfortDistance = DefaultRiposteDistance if Blade ~= nil and BodyAttach.Name == "BodyAttach" then local BladeTip = (Blade.CFrame * CFrame.new(0,Blade.Size.Y/2,0)) ComfortDistance = (BodyAttach.Position - BladeTip.p).magnitude + 15 -- ON GODDDDDD if Tool.Name == "Spear" or Tool.Name == "Zweihander" or Tool.Name == "Halberd" or Tool.Name == "Executioner's Axe" or Tool.Name == "Billhook" then ComfortDistance = ComfortDistance + 6 if Tool.Name == "Executioner's Axe" then ComfortDistance = ComfortDistance + 5 -- ON GOD end end end Monitoring[Character.Name] = {} Monitoring[Character.Name].Sound = Desc Monitoring[Character.Name].Connection = Desc:GetPropertyChangedSignal("Playing"):Connect(function() -- should be fine since swing only plays after windup stage, and therefore can't be canceled if Autoparry and Players:FindFirstChild(Character.Name).Team ~= Player.Team and Desc.Playing == true and Player.Character ~= nil and Player.Character:FindFirstChild("HumanoidRootPart") and (Player.Character.HumanoidRootPart.Position - BodyAttach.Position).magnitude <= ComfortDistance then local YourTool = PlayerWeapon.Instance or Player.Character:FindFirstChildOfClass("Tool") if YourTool == nil or not YourTool:FindFirstChild("Stance") or YourTool.Stance.Value ~= "Idle" then return end if YourTool.Stance.Value ~= "Riposte" and YourTool.Stance.Value ~= "Release" then if YourTool.Stance.Value == "Windup" then game:GetService("ReplicatedStorage").RemoteEvents.ToServer.ChangeVal:FireServer(YourTool.Stance, "Winddown") end game:GetService("ReplicatedStorage").RemoteEvents.ToServer.ChangeVal:FireServer(YourTool.Stance, "Idle") game:GetService("ReplicatedStorage").RemoteEvents.ToServer.ChangeVal:FireServer(YourTool.Stance, "Riposte") end if PlayerWeapon["RiposteTrack"] ~= nil then PlayerWeapon["RiposteTrack"]:Play(0.1) PlayerWeapon["RiposteTrack"]:AdjustSpeed(0) end local AlreadyStopped = false spawn(function() task.wait(0.2) if not AlreadyStopped and YourTool.Stance.Value ~= "Riposte" and YourTool.Stance.Value ~= "RiposteDelay" then game:GetService("ReplicatedStorage").RemoteEvents.ToServer.ChangeVal:FireServer(YourTool.Stance, "Parrying") end end) spawn(function() Desc:GetPropertyChangedSignal("Playing"):Wait() if not AlreadyStopped and YourTool.Stance.Value == "Riposte" or not AlreadyStopped and YourTool.Stance.Value == "Parrying" then AlreadyStopped = true if PlayerWeapon["RiposteTrack"] ~= nil and PlayerWeapon["RiposteTrack"].IsPlaying then PlayerWeapon["RiposteTrack"]:Stop(1) end if YourTool.Stance.Value == "Riposte" then game:GetService("ReplicatedStorage").RemoteEvents.ToServer.ChangeVal:FireServer(YourTool.Stance, "RiposteDelay") elseif YourTool.Stance.Value == "Parrying" then game:GetService("ReplicatedStorage").RemoteEvents.ToServer.ChangeVal:FireServer(YourTool.Stance, "UnParry") end task.wait() game:GetService("ReplicatedStorage").RemoteEvents.ToServer.ChangeVal:FireServer(YourTool.Stance, "Idle") end end) task.wait(1.2) if not AlreadyStopped and YourTool.Stance.Value == "Riposte" or not AlreadyStopped and YourTool.Stance.Value == "Parrying" then AlreadyStopped = true if PlayerWeapon["RiposteTrack"] ~= nil and PlayerWeapon["RiposteTrack"].IsPlaying then PlayerWeapon["RiposteTrack"]:Stop(1) end if YourTool.Stance.Value == "Riposte" then game:GetService("ReplicatedStorage").RemoteEvents.ToServer.ChangeVal:FireServer(YourTool.Stance, "RiposteDelay") elseif YourTool.Stance.Value == "Parrying" then game:GetService("ReplicatedStorage").RemoteEvents.ToServer.ChangeVal:FireServer(YourTool.Stance, "UnParry") end task.wait() game:GetService("ReplicatedStorage").RemoteEvents.ToServer.ChangeVal:FireServer(YourTool.Stance, "Idle") end end end) end end end game.Workspace.DescendantAdded:Connect(CheckDescendant) for i,v in pairs(game.Workspace:GetDescendants()) do CheckDescendant(v) end Mouse.KeyDown:Connect(function(Key) if Key == "h" then Autoparry = not Autoparry if Autoparry == true then currenttext = "Autoparry is now ON!" else currenttext = "Autoparry is now OFF!" end game.StarterGui:SetCore("SendNotification", { Title = "notification"; Text = currenttext; Icon = "rbxassetid://2541869220"; Duration = 3; }) end end) game.StarterGui:SetCore("SendNotification", { Title = "Bulwark Autoparry"; Text = "SUCCESSFULLY INJECTED,\n(MADE BY AIDEZ)"; Icon = "rbxassetid://2541869220"; Duration = 7; })