-- Parent REQUIRED: this Script must be a child of the RemoteEvent named "Server"
-- Structure expected:
-- HitboxSettingsRapierStyle (Folder)
-- Server (RemoteEvent)
-- Handler (Script) ← this file
-- A1..A6, ParryAnim, GBFX/BlockFX/PBFX folders, DmgCounter, HitFX, PunchSound,
DirtParticle, Slide, SmokeWave, Rock, GB, etc.
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local Players = game:GetService("Players")
local CombatFolder = ReplicatedStorage:WaitForChild("Combat")
-- Values (safe shim so we never crash if CreateValue signature differs)
local okValues, Values = pcall(function()
return require(CombatFolder:WaitForChild("Values"))
end)
local function createValue(className, parent, name, initialValue, lifetimeSeconds)
if okValues and type(Values) == "table" and type([Link]) ==
"function" then
local fn = [Link]
local ok1 = pcall(function() fn(className, parent, name, initialValue,
lifetimeSeconds) end)
if ok1 then return end
pcall(function() fn(Values, className, parent, name, initialValue,
lifetimeSeconds) end)
return
end
local instOk, inst = pcall([Link], className)
if not instOk then return end
[Link] = name or className
if inst:IsA("BoolValue") and typeof(initialValue) == "boolean" then
[Link] = initialValue
elseif inst:IsA("NumberValue") and typeof(initialValue) == "number" then
[Link] = initialValue
elseif inst:IsA("StringValue") and typeof(initialValue) == "string" then
[Link] = initialValue
end
[Link] = parent
if typeof(lifetimeSeconds) == "number" and lifetimeSeconds > 0 then
[Link]:AddItem(inst, lifetimeSeconds)
end
end
local StunController = require(CombatFolder:WaitForChild("StunController"))
local HitConfirmed = CombatFolder:WaitForChild("HitConfirmed")
local PostureService = require(CombatFolder:WaitForChild("PostureService"))
local function hasActiveFlag(model, name)
local inst = model:FindFirstChild(name)
if not inst then return false end
if inst:IsA("BoolValue") then
return [Link] == true
end
return true
end
local DamageConfig = {
M1ByCombo = { [1]=5, [2]=5, [3]=5, [4]=5, [5]=10 },
A6PerHit = 3, -- 4 hits => total 12
}
-- Stress per blocked hit (tune for rapier cadence)
local STRESS_PER_BLOCKED_HIT = 20
local function getServerDamage(comboNumber)
comboNumber = tonumber(comboNumber) or 1
if comboNumber == 6 then
return DamageConfig.A6PerHit
end
return DamageConfig.M1ByCombo[comboNumber] or DamageConfig.M1ByCombo[1]
end
local function Curve(t,p0,p1,p2)
local A = p0:Lerp(p1,t)
local B = p1:Lerp(p2,t)
return A:Lerp(B,t)
end
local function attackerHardBlocked(attackerChar)
if not attackerChar then return true end
return hasActiveFlag(attackerChar, "Stun")
or hasActiveFlag(attackerChar, "Parried")
or hasActiveFlag(attackerChar, "StopStun")
end
-- CLASH SYSTEM helpers
local function facingEachOther(HumRP, EhumRP)
if not HumRP or not EhumRP then return false end
local toTarget = ([Link] - [Link])
local toAttacker = ([Link] - [Link])
if [Link] < 0.001 or [Link] < 0.001 then return
false end
toTarget = [Link]
toAttacker = [Link]
local f1 = [Link]:Dot(toTarget) > 0.5
local f2 = [Link]:Dot(toAttacker) > 0.5
return f1 and f2
end
local function doClashFX(attackerPlr, attackerChar, targetPlr, targetChar, Hum,
HumRP, Ehum, EhumRP, scriptRef)
if not HumRP or not EhumRP then return end
local midPos = ([Link] + [Link]) * 0.5
local soundAnchor = [Link]("Part")
[Link] = "ClashSoundAnchor"
[Link] = true
[Link] = false
[Link] = 1
[Link] = [Link](0.2, 0.2, 0.2)
[Link] = [Link](midPos)
[Link] = workspace
[Link]:AddItem(soundAnchor, 2)
local clashVFX = scriptRef:FindFirstChild("ClashVFX")
if clashVFX then
local fxTemplate = clashVFX:FindFirstChild("HitFX") or clashVFX
local fxA = fxTemplate:Clone(); [Link] = HumRP;
[Link]:AddItem(fxA, 2)
for _, obj in ipairs(fxA:GetChildren()) do
local emit = obj:GetAttribute("EmitCount")
if emit then obj:Emit(emit) end
end
local fxB = fxTemplate:Clone(); [Link] = EhumRP;
[Link]:AddItem(fxB, 2)
for _, obj in ipairs(fxB:GetChildren()) do
local emit = obj:GetAttribute("EmitCount")
if emit then obj:Emit(emit) end
end
end
local clashSound = scriptRef:FindFirstChild("ClashSound")
if clashSound then
local snd = clashSound:Clone()
[Link] = soundAnchor
snd:Play()
[Link]:AddItem(snd, 3)
end
do
local DmgCounter = scriptRef:WaitForChild("DmgCounter"):Clone()
[Link] = workspace
[Link] = midPos
[Link] = "Clash"
[Link].TextColor3 = [Link](255,255,127)
[Link].TextStrokeColor3 =
[Link](255,255,255)
local info = TweenService:Create([Link],
[Link](.1, [Link], [Link], 0, true, 0),
{TextColor3 = [Link](255,255,255)})
info:Play()
[Link]:AddItem(DmgCounter, .4)
local P1 = midPos
local P2 = midPos + [Link]([Link](-3,3), [Link](2,10),
[Link](-3,3))
local P3 = P2 + [Link](0, -15, 0)
[Link](function()
for i = 0, 1, 0.045 do
local newpos = Curve(i, P1, P2, P3)
[Link] = newpos
[Link]()
end
end)
end
[Link](function()
[Link](0.2)
local tracksA = Hum:GetPlayingAnimationTracks()
local tracksB = Ehum:GetPlayingAnimationTracks()
for _, tr in ipairs(tracksA) do pcall(function() tr:AdjustSpeed(0) end)
end
for _, tr in ipairs(tracksB) do pcall(function() tr:AdjustSpeed(0) end)
end
delay(0.25, function()
for _, tr in ipairs(tracksA) do pcall(function()
tr:AdjustSpeed(1) end) end
for _, tr in ipairs(tracksB) do pcall(function()
tr:AdjustSpeed(1) end) end
end)
end)
do
local dirAtoB = ([Link] - [Link])
if [Link] > 0.001 then
dirAtoB = [Link]
local KB = 18
local t = 0.2
local BVtgt = [Link]("BodyVelocity")
[Link] = [Link](dirAtoB.X, 0, dirAtoB.Z) * KB
[Link] = [Link](30000, 0, 30000)
[Link] = EhumRP
[Link]:AddItem(BVtgt, t)
local BVatk = [Link]("BodyVelocity")
[Link] = [Link](-dirAtoB.X, 0, -dirAtoB.Z) * KB
[Link] = [Link](30000, 0, 30000)
[Link] = HumRP
[Link]:AddItem(BVatk, t)
end
end
[Link](attackerChar, 0.15)
[Link](targetChar, 0.15)
if attackerPlr then [Link]:FireClient(attackerPlr, "CLASH") end
if targetPlr then [Link]:FireClient(targetPlr, "CLASH") end
end
local function doGBFX(attackerChar, targetChar, Ehum, EhumRP, HumRP, scriptRef)
-- ... INCHANGÉ ...
local BlockFX = scriptRef:WaitForChild("GBFX"):WaitForChild("HitFX"):Clone()
[Link] = EhumRP
[Link]:AddItem(BlockFX,2)
-- Stop blocking, stop victim anims, play GB anim
for _,bv in ipairs(targetChar:GetChildren()) do
if [Link] == "Blocking" then bv:Destroy() end
end
for _,tr in ipairs(Ehum:GetPlayingAnimationTracks()) do tr:Stop() end
local GB = Ehum:LoadAnimation(scriptRef:WaitForChild("GB"))
GB:Play()
delay(1.5,function() if [Link] then GB:Stop() end end)
local Sound = scriptRef:WaitForChild("BB"):Clone()
[Link] = EhumRP
Sound:Play()
[Link]:AddItem(Sound,3)
local DmgCounter = scriptRef:WaitForChild("DmgCounter"):Clone()
[Link] = workspace
[Link] = [Link]
[Link] = "Broken"
TweenService:Create([Link],
[Link](.1,[Link],[Link],0,true,0),
{TextColor3 = [Link](255,255,255)}):Play()
[Link]:AddItem(DmgCounter,.4)
local P1 = [Link]
local P2 = [Link] + [Link]([Link](-3,3),
[Link](2,10), [Link](-3,3))
local P3 = P2 + [Link](0,-15,0)
[Link](function()
for i = 0,1,0.045 do
local newpos = Curve(i,P1,P2,P3)
[Link] = newpos
[Link]()
end
end)
local BV = [Link]("BodyVelocity",EhumRP)
[Link] = [Link] * 10
[Link] = [Link](15000,15000,15000)
[Link]:AddItem(BV,.2)
local BV2 = [Link]("BodyVelocity",HumRP)
[Link] = [Link] * 10
[Link] = [Link](15000,15000,15000)
[Link]:AddItem(BV2,.2)
for _,fx in ipairs(BlockFX:GetChildren()) do
local EmitCount = fx:GetAttribute("EmitCount")
if EmitCount then fx:Emit(EmitCount) end
end
[Link](targetChar, 0.2)
end
local function processHit(attackerPlr, attackerChar, targetChar, Hum, HumRP, A2,
Last, Air, ComboNumber, scriptRef)
local Ehum = targetChar:FindFirstChild("Humanoid")
local EhumRP = targetChar:FindFirstChild("HumanoidRootPart")
if not Ehum or not EhumRP or not Hum or not HumRP then return end
-- === CLASH SYSTEM === (prioritaire, ajouté)
do
local atkSwing = attackerChar:FindFirstChild("Swinging")
local tgtSwing = targetChar:FindFirstChild("Swinging")
local targetIsParrying = targetChar:FindFirstChild("PB")
local targetIsBlocking = targetChar:FindFirstChild("Blocking")
local attackerIsParrying = attackerChar:FindFirstChild("PB")
local attackerIsBlocking = attackerChar:FindFirstChild("Blocking")
if atkSwing and tgtSwing
and not targetIsParrying and not targetIsBlocking
and not attackerIsParrying and not attackerIsBlocking
and facingEachOther(HumRP, EhumRP)
then
local gotA = [Link](attackerChar, 0.2)
local gotB = [Link](targetChar, 0.2)
if gotA and gotB then
local targetPlr =
Players:GetPlayerFromCharacter(targetChar)
doClashFX(attackerPlr, attackerChar, targetPlr, targetChar,
Hum, HumRP, Ehum, EhumRP, scriptRef)
return
end
end
end
-- ... LE RESTE DE LA LOGIQUE ORIGINALE INCHANGÉE ...
local isMultiHit = (tonumber(ComboNumber) == 6)
local lockDuration = isMultiHit and (Last and 0.15 or 0.05) or 0.18
if not [Link](targetChar, lockDuration) then
return
end
if ComboNumber and ComboNumber >= 1 and ComboNumber <= 3 then
HitConfirmed:FireClient(attackerPlr, ComboNumber)
end
local LookVector1 = ([Link] - [Link]).Unit
local LookVector2 = [Link]
local DotProduct = [Link]([Link](LookVector2:Dot(LookVector1), -1,
1))
if targetChar:FindFirstChild("PB") then
local BlockFX =
scriptRef:WaitForChild("PBFX"):WaitForChild("HitFX"):Clone()
[Link] = EhumRP
[Link]:AddItem(BlockFX,2)
local AnimTracks = Hum:GetPlayingAnimationTracks()
[Link]:FireClient(attackerPlr,"PB")
[Link](function()
for _,track in ipairs(AnimTracks) do
[Link](.2)
track:AdjustSpeed(0)
delay(0.2, function() track:AdjustSpeed(1) end)
end
end)
Ehum:LoadAnimation(scriptRef:WaitForChild("ParryAnim")):Play()
local Sound = scriptRef:WaitForChild("PB"):Clone()
[Link] = EhumRP
Sound:Play()
[Link]:AddItem(Sound,3)
local DmgCounter = scriptRef:WaitForChild("DmgCounter"):Clone()
[Link] = workspace
[Link] = [Link]
[Link] = "Parry"
[Link].TextColor3 = [Link](255, 255, 127)
[Link].TextStrokeColor3 = [Link](255, 255,
255)
TweenService:Create([Link],
[Link](.1,[Link],[Link],0,true,0),
{TextColor3 = [Link](255,255,255)}):Play()
[Link]:AddItem(DmgCounter,.4)
local P1 = [Link]
local P2 = [Link] + [Link]([Link](-3,3),
[Link](2,10), [Link](-3,3))
local P3 = P2 + [Link](0,-15,0)
[Link](function()
for i = 0,1,0.045 do
local newpos = Curve(i,P1,P2,P3)
[Link] = newpos
[Link]()
end
end)
for _,fx in ipairs(BlockFX:GetChildren()) do
local EmitCount = fx:GetAttribute("EmitCount")
if EmitCount then fx:Emit(EmitCount) end
end
[Link](attackerChar)
createValue("BoolValue", attackerChar, "StopStun", false, 1)
return
end
if targetChar:FindFirstChild("Blocking") and DotProduct > 1 then
local _, _, broke = [Link](targetChar,
STRESS_PER_BLOCKED_HIT)
if broke then
doGBFX(attackerChar, targetChar, Ehum, EhumRP, HumRP, scriptRef)
return
end
local BlockFX =
scriptRef:WaitForChild("BlockFX"):WaitForChild("HitFX"):Clone()
[Link] = EhumRP
[Link]:AddItem(BlockFX,2)
local Sound = scriptRef:WaitForChild("Blocked"):Clone()
[Link] = EhumRP
Sound:Play()
[Link]:AddItem(Sound,1)
local DmgCounter = scriptRef:WaitForChild("DmgCounter"):Clone()
[Link] = workspace
[Link] = [Link]
[Link] = "Blocked"
[Link].TextColor3 = [Link](199,199,199)
[Link].TextStrokeColor3 =
[Link](152,152,152)
TweenService:Create([Link],
[Link](.1,[Link],[Link],0,true,0),
{TextColor3 = [Link](255,255,255)}):Play()
[Link]:AddItem(DmgCounter,.4)
local P1 = [Link]
local P2 = [Link] + [Link]([Link](-3,3),
[Link](2,10), [Link](-3,3))
local P3 = P2 + [Link](0,-15,0)
[Link](function()
for i = 0,1,0.045 do
local newpos = Curve(i,P1,P2,P3)
[Link] = newpos
[Link]()
end
end)
local BV = [Link]("BodyVelocity",EhumRP)
[Link] = [Link] * 10
[Link] = [Link](15000,15000,15000)
[Link]:AddItem(BV,.2)
local BV2 = [Link]("BodyVelocity",HumRP)
[Link] = [Link] * 10
[Link] = [Link](15000,15000,15000)
[Link]:AddItem(BV2,.2)
for _,fx in ipairs(BlockFX:GetChildren()) do
local EmitCount = fx:GetAttribute("EmitCount")
if EmitCount then fx:Emit(EmitCount) end
end
[Link](targetChar, 0.15)
return
end
-- Normal hit
local appliedDamage = getServerDamage(ComboNumber)
local stunDur = (Air and not Last) and 0.9 or 0.6
[Link](targetChar, "Stun", stunDur)
if tonumber(ComboNumber) == 6 then
if Last then [Link](targetChar, 0.15) end
else
[Link](targetChar, 0.12)
end
local DmgCounter = scriptRef:WaitForChild("DmgCounter"):Clone()
[Link] = workspace
[Link] = [Link]
[Link] = "-"..appliedDamage
TweenService:Create([Link],
[Link](.1,[Link],[Link],0,true,0),
{TextColor3 = [Link](255,255,255)}):Play()
[Link]:AddItem(DmgCounter,.4)
local P1 = [Link]
local P2 = [Link] + [Link]([Link](-3,3),
[Link](2,10), [Link](-3,3))
local P3 = P2 + [Link](0,-15,0)
[Link](function()
for i = 0,1,0.045 do
local newpos = Curve(i,P1,P2,P3)
[Link] = newpos
[Link]()
end
end)
if A2 then
Ehum:LoadAnimation(A2):Play()
end
local Sound = scriptRef:WaitForChild("PunchSound"):Clone()
[Link] = EhumRP
Sound:Play()
[Link]:AddItem(Sound,1)
if Last == false and Air == false then
local BV = [Link]("BodyVelocity",EhumRP)
[Link] = [Link] * 10
[Link] = [Link](15000,15000,15000)
[Link]:AddItem(BV,.2)
elseif Last == true and Air == false then
local BV = [Link]("BodyVelocity",EhumRP)
[Link] = [Link] * 50
[Link] = [Link](55000,55000,55000)
[Link]:AddItem(BV,.4)
local rp = [Link]()
[Link] = [Link]
[Link] = {attackerChar,[Link]}
[Link] = true
local NewRay = workspace:Raycast([Link], [Link](0,-5,0),
rp)
if NewRay then
for _,vName in ipairs({"Left Leg","Right Leg"}) do
local trueColor = [Link]
local DirtParticle =
scriptRef:WaitForChild("DirtParticle"):Clone()
[Link] = [Link]{
[Link](0,trueColor),
[Link](0.5,trueColor),
[Link](1,trueColor),
}
[Link]:AddItem(DirtParticle,1)
local limb = [Link]:FindFirstChild(vName)
if limb then
local Slide = scriptRef:WaitForChild("Slide"):Clone()
[Link] = EhumRP
[Link]:AddItem(Slide,1)
[Link] = limb
delay(.5,function() [Link] = true end)
end
end
end
end
if Air == false then
local BV2 = [Link]("BodyVelocity",HumRP)
[Link] = [Link] * 10
[Link] = [Link](15000,15000,15000)
[Link]:AddItem(BV2,.2)
end
if A2 and typeof(A2) == "Instance" and A2:IsA("Animation") and [Link] ==
"TargetSlam" and Last == true then
local rp = [Link]()
[Link] = [Link]
[Link] = {attackerChar, [Link]}
[Link] = true
local hit = workspace:Raycast([Link], [Link](0,-60,0),
rp)
if hit then
if EhumRP:FindFirstChild("HoldBP") then [Link]:Destroy()
end
if HumRP:FindFirstChild("HoldBP") then [Link]:Destroy() end
local BVdown = [Link]("BodyVelocity", EhumRP)
[Link] = [Link](0,-60,0)
[Link] = [Link](55000,55000,55000)
[Link]:AddItem(BVdown, .25)
[Link](0.12, function()
local SmokeWave =
scriptRef:WaitForChild("SmokeWave"):Clone()
[Link] = workspace
[Link] = [Link] + [Link](0,.7,0)
[Link]:AddItem(SmokeWave, 1.5)
[Link]:Emit(20)
[Link]:Emit(10)
[Link]:Play()
end)
end
return
end
if Air == true and Last == false then
local BV = [Link]("BodyVelocity",EhumRP)
[Link] = [Link] * 30
[Link] = [Link](55000,55000,55000)
[Link]:AddItem(BV,.6)
local BV2 = [Link]("BodyVelocity",HumRP)
[Link] = [Link] * 30
[Link] = [Link](55000,55000,55000)
[Link]:AddItem(BV2,.6)
createValue("BoolValue", attackerChar, "Using Move", false, .31)
delay(.3,function()
local BP = [Link]("BodyPosition",EhumRP)
[Link] = [Link]
[Link] = [Link](200000,200000,200000)
BP.P = 400
[Link] = "HoldBP"
[Link]:AddItem(BP,2.0)
local BP2 = [Link]("BodyPosition",HumRP)
[Link] = [Link]
[Link] = [Link](200000,200000,200000)
BP2.P = 400
[Link] = "HoldBP"
[Link]:AddItem(BP2,2.0)
end)
end
if Air == true and Last == true then
local StartPos = ([Link] * 20) + [Link]
local Direction = [Link](0,-40,0)
local RayParams = [Link]()
[Link] = {attackerChar,[Link]}
[Link] = [Link]
[Link] = true
local Raycast = workspace:Raycast(StartPos,Direction,RayParams)
if Raycast then
if EhumRP:FindFirstChild("HoldBP") then [Link]:Destroy()
end
if HumRP:FindFirstChild("HoldBP") then [Link]:Destroy() end
local function Lerp(i,A,B) return A:Lerp(B,i) end
[Link](function()
for i = 0,1,.03 do
local newpos =
Lerp(i,[Link],[Link] + [Link](0,3,0))
[Link]:MoveTo(newpos)
[Link]()
end
end)
delay(.15,function()
local NumOFParts = 14
createValue("BoolValue", attackerChar, "BigShake",
false, .1)
local SmokeWave =
scriptRef:WaitForChild("SmokeWave"):Clone()
[Link] = workspace
[Link] = [Link] + [Link](0,.7,0)
[Link]:AddItem(SmokeWave,2)
[Link]:Emit(50)
[Link]:Emit(25)
[Link]:Play()
end)
end
end
local HitFX = scriptRef:WaitForChild("HitFX"):WaitForChild("HitFX"):Clone()
[Link] = EhumRP
[Link]:AddItem(HitFX,1)
for _,fx in ipairs(HitFX:GetChildren()) do
if [Link] == "Crescents" then fx:Emit(5) end
if [Link] == "Gradient" then fx:Emit(1) end
if [Link] == "Shards" then fx:Emit(10) end
if [Link] == "Specs" then fx:Emit(10) end
end
Ehum:TakeDamage(getServerDamage(ComboNumber))
end
-- Important: [Link] must be the RemoteEvent named "Server"
[Link]:Connect(function(plr, Type, A1, A2, size, Last, Air,
ComboNumber, ClientTargets, BoxCFrame)
local Char = [Link]
if not Char then return end
local Hum = Char:FindFirstChild("Humanoid")
local HumRP = Char:FindFirstChild("HumanoidRootPart")
if not Hum or not HumRP then return end
local scriptRef = script -- assets resolved relative to this script
-- Attacker animation replication
if Type == "Animation" and A1 ~= nil then
Hum:LoadAnimation(A1):Play()
createValue("BoolValue", Char, "Swinging", false, .2)
return
end
if Type ~= "ClientHit" then
return
end
if attackerHardBlocked(Char) then
return
end
-- Validate client-provided targets and box
if typeof(ClientTargets) ~= "table" or #ClientTargets == 0 then
return
end
-- Small no-jump window
createValue("BoolValue", Char, "NoJump", false, 1)
local seen = {}
local applied = 0
local MAX_CLIENT_TARGETS = 5
for _, hrp in ipairs(ClientTargets) do
if applied >= MAX_CLIENT_TARGETS then break end
if typeof(hrp) == "Instance" and hrp:IsA("BasePart") and
hrp:IsDescendantOf(workspace) then
local targetChar = hrp:FindFirstAncestorOfClass("Model")
if targetChar and not seen[targetChar] then
seen[targetChar] = true
if serverValidateTarget(Char, targetChar, BoxCFrame, size)
then
applied += 1
local ok, err = pcall(processHit, plr, Char,
targetChar, Hum, HumRP, A2, Last, Air, ComboNumber, scriptRef)
if not ok then
warn("[RapierStyle] processHit error: ", err)
end
end
end
end
end
end)