There are 2 scripts that manage the code. The local script and the server script. The local script handles player input and animations. The server script on the other hand creates the damage and blood and sound effects, while also checking for suspicious behavior. I’m posting this here because of how messy and unoptimized the code seems to me.
I’ve considered removing the connect function in the local script wrapping around so many lines.
Local script:
local replicatedStorage = game:GetService("ReplicatedStorage")
local player = game.Players.LocalPlayer
player.CharacterAdded:Connect(function(character)
local humanoid = character:WaitForChild("Humanoid")
local tool = script.Parent
local cooldown = .35
local slashPick = math.random(1,2)
local isActive = false
local canDamage = false
local animationList = {
Animation_1 = humanoid:LoadAnimation(tool:WaitForChild("Animations"):WaitForChild("Slash1")),
Animation_2 = humanoid:LoadAnimation(tool:WaitForChild("Animations"):WaitForChild("Slash2")),
}
local function onActivate()
if isActive == false then
isActive = true
canDamage = true
local slashAnimation = animationList["Animation_"..slashPick]
slashAnimation:Play()
slashPick = math.random(1,2)
wait(cooldown)
canDamage = false
isActive = false
end
end
local function onTouched(hit)
local humanoid = hit.Parent:FindFirstChild("Humanoid")
if humanoid and canDamage then
if humanoid.Health > 0 then
canDamage = false
replicatedStorage.DamageEvent:FireServer(hit, humanoid, slashPick)
end
end
end
tool.Activated:Connect(onActivate)
tool.Hitbox.Touched:Connect(onTouched)
end)
Server script:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ServerStorage = game:GetService("ServerStorage")
local Debris = game:GetService("Debris")
local bloodParticle = ServerStorage.Effects.BloodEffect
local slashSounds = {
slash1 = ServerStorage.Effects.Slash1,
slash2 = ServerStorage.Effects.Slash2,
}
local swordCooldown = .35
local swordRange = 3.5
local swordDamage = 20
local playerCooldowns = {}
local function cooldownChecker(player, tool)
local usedTick = playerCooldowns[player.Name]
if usedTick then
if (usedTick - tick()) < swordCooldown then
usedTick = tick()
return true
else
playerCooldowns[player.Name] = nil
return false
end
else
playerCooldowns[player.Name] = tick()
return true
end
end
local function slashingEffects(hit, slashPick)
local effectClone = bloodParticle:Clone()
effectClone.Parent = hit
local soundClone = slashSounds["slash"..slashPick]:Clone()
soundClone.Parent = hit
soundClone:Play()
Debris:AddItem(effectClone, 1)
Debris:AddItem(soundClone, 1)
wait(.5)
effectClone.Enabled = false
end
local function onDamageEvent(player, hit, humanoid, slashPick)
local tool = player.Character:FindFirstChildWhichIsA("Tool")
if tool and tool.Name == "Sword" then
local spam = cooldownChecker(player, tool)
if spam then
local range = (tool.Hitbox.Position - hit.Position).magnitude
if range < swordRange then
humanoid:TakeDamage(swordDamage)
slashingEffects(hit, slashPick)
end
else
player:Kick()
end
end
end
ReplicatedStorage.DamageEvent.OnServerEvent:Connect(onDamageEvent)