Hello Guys,
i have the problem that when the Player equips the weapon and uses it and after it requips it the cooldown is gone.
Also the Player can spam the attacks but i want that the player can only use the attacks one time per loop because its a combat system ( visible in the code ).
Can someone help me please?
local handle = tool:WaitForChild("Handle")
local hitBox = tool:FindFirstChild("HitBox")
local statusValue = tool:FindFirstChild("Status")
local animationsFolder = tool:WaitForChild("Animations")
local panAttack1 = animationsFolder:WaitForChild("PanAttack1")
local panAttack2 = animationsFolder:WaitForChild("PanAttack2")
local panAttack3 = animationsFolder:WaitForChild("PanAttack3")
local holdingAnimation = animationsFolder:FindFirstChild("HoldAnimation")
local equipAnimation = animationsFolder:FindFirstChild("EquipAnimation")
local fireEffect1 = tool.Union:FindFirstChild("FireBlue")
local soundFolder = tool.ItemSounds
local panSound = tool.AttackSound
local panSwingSound = tool.SwingSound
local timeToMove = 0
local MoveAmount = 0
local canDmg = false
local canAttack = true
local hitTargets = {} -- Table to store targets hit during an attack
local cooldown = 10 -- Time between attacks
local secondAttackCooldown = 0.1 -- Time between the first and the second attack in the combo
local thirdAttackCooldown = 0.3 -- Time between the second and the third attack in the combo
local chainTimeframe = 7 -- Timeframe to chain attacks after the first one
local damageFirstAttack = 80
local damageSecondAttack = 60
local damageThirdAttack = 3000
local lastSwingTime = 0
local currentAnimPlaying = nil
local attackStage = 0
local holdingAnimTrack = nil
local originalWalkSpeed = nil
-- Function to play animation
local function playAnimation(animation)
local humanoid = tool.Parent:FindFirstChildOfClass("Humanoid")
if humanoid then
local animationTrack = humanoid:LoadAnimation(animation)
animationTrack:Play()
return animationTrack
end
return nil
end
-- Function to stop holding animation
local function stopHoldingAnimation()
if holdingAnimTrack then
holdingAnimTrack:Stop()
holdingAnimTrack = nil
end
end
-- Function to start holding animation
local function startHoldingAnimation()
if holdingAnimation and not currentAnimPlaying then
holdingAnimTrack = playAnimation(holdingAnimation)
end
end
-- Callback for when equip animation stops
local function onEquipAnimationStopped()
local humanoid = tool.Parent:FindFirstChildOfClass("Humanoid")
if humanoid and originalWalkSpeed then
humanoid.WalkSpeed = originalWalkSpeed -- Restore movement after equip animation
end
currentAnimPlaying = nil -- Allow holding animation to start
canAttack = true
startHoldingAnimation() -- Start holding animation after equip animation finishes
end
-- Callback for when the tool is equipped
local function onEquipped()
local humanoid = tool.Parent:FindFirstChildOfClass("Humanoid")
if humanoid then
originalWalkSpeed = humanoid.WalkSpeed
humanoid.WalkSpeed = 0 -- Disable movement during equip
end
canAttack = false -- Prevent attacks during equip
currentAnimPlaying = playAnimation(equipAnimation)
if currentAnimPlaying then
currentAnimPlaying.Stopped:Connect(onEquipAnimationStopped)
end
end
-- Callback for when the tool is unequipped
local function onUnequipped()
stopHoldingAnimation()
local humanoid = tool.Parent:FindFirstChildOfClass("Humanoid")
if humanoid and originalWalkSpeed then
humanoid.WalkSpeed = originalWalkSpeed -- Restore movement speed
end
end
-- Function to move player forward
local function movePlayerForward()
local character = tool.Parent
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
local moveDirection = humanoidRootPart.CFrame.lookVector
local targetPosition = humanoidRootPart.Position + (moveDirection * MoveAmount)
timeToMove = 0.4
local startTime = tick()
local endTime = startTime + timeToMove
-- Raycasting parameters
local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {character} -- Ignore the character itself
raycastParams.FilterType = Enum.RaycastFilterType.Blacklist
raycastParams.IgnoreWater = true
-- Cast a ray to check if there's an obstacle
local rayOrigin = humanoidRootPart.Position
local rayDirection = moveDirection * 40 -- Ray length, same as movement distance
local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)
if raycastResult then
-- Obstacle detected, adjust target position
targetPosition = raycastResult.Position - moveDirection * 2 -- Stop 2 units before the obstacle
end
-- Disable movement
local humanoid = character:FindFirstChildOfClass("Humanoid")
if humanoid then
humanoid.WalkSpeed = 0
end
-- Move the player smoothly over time
while tick() < endTime do
local elapsed = tick() - startTime
local alpha = elapsed / timeToMove
humanoidRootPart.CFrame = humanoidRootPart.CFrame:Lerp(CFrame.new(targetPosition), alpha)
wait()
end
-- Restore movement after the move
if humanoid and originalWalkSpeed then
humanoid.WalkSpeed = originalWalkSpeed
end
end
end
-- Function to move player up
local function movePlayerUp()
local character = tool.Parent
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
local originalPosition = humanoidRootPart.Position
local targetPosition = originalPosition + Vector3.new(0, 5, 15) -- Move up 5 studs on the Y-axis
local startTime = tick()
local endTime = startTime + timeToMove
-- Disable movement
local humanoid = character:FindFirstChildOfClass("Humanoid")
local originalWalkSpeed
if humanoid then
originalWalkSpeed = humanoid.WalkSpeed
humanoid.WalkSpeed = 0
end
-- Move the player smoothly over time
while tick() < endTime do
local elapsed = tick() - startTime
local alpha = elapsed / timeToMove
humanoidRootPart.CFrame = humanoidRootPart.CFrame:Lerp(CFrame.new(targetPosition), alpha)
wait()
end
-- Ensure final position is set correctly
humanoidRootPart.CFrame = CFrame.new(targetPosition)
-- Restore movement after the move
if humanoid and originalWalkSpeed then
humanoid.WalkSpeed = originalWalkSpeed
end
end
end
-- Callback for when animation stops
local function onAnimationStopped()
local humanoid = tool.Parent:FindFirstChildOfClass("Humanoid")
if attackStage == 1 and humanoid and originalWalkSpeed then
humanoid.WalkSpeed = originalWalkSpeed
end
if attackStage == 2 and humanoid and originalWalkSpeed then
humanoid.WalkSpeed = originalWalkSpeed
end
if attackStage == 3 and humanoid and originalWalkSpeed then
humanoid.WalkSpeed = originalWalkSpeed
if humanoid.Parent.LowerTorso.WaveClone1 and humanoid.Parent.LowerTorso.WaveClone2 then
humanoid.Parent.LowerTorso.WaveClone1.Enabled = false
humanoid.Parent.LowerTorso.WaveClone2.Enabled = false
wait(1)
humanoid.Parent.LowerTorso.WaveClone1:Destroy()
humanoid.Parent.LowerTorso.WaveClone2:Destroy()
fireEffect1.Enabled = false
end
end
canDmg = false
hitTargets = {} -- Clear the hit targets after each attack
currentAnimPlaying = nil
-- Apply cooldown based on attack stage
local cooldownTime = cooldown
if attackStage == 1 then
cooldownTime = secondAttackCooldown
elseif attackStage == 2 then
cooldownTime = thirdAttackCooldown
end
wait(cooldownTime)
canAttack = true
if attackStage > 0 then
delay(chainTimeframe, function()
if tick() - lastSwingTime >= chainTimeframe then
attackStage = 0
end
end)
end
startHoldingAnimation()
end
-- Function to kill all enemies in range
local function killAllInRange(range)
local character = tool.Parent
local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
if humanoidRootPart then
local characterPosition = humanoidRootPart.Position
local targets = workspace:FindPartsInRegion3(Region3.new(
characterPosition - Vector3.new(range, range, range),
characterPosition + Vector3.new(range, range, range)
), nil, math.huge)
for _, target in ipairs(targets) do
local humanoid = target.Parent:FindFirstChildOfClass("Humanoid")
-- Check if the target is not the player holding the tool
if humanoid and target.Parent ~= character then
humanoid:TakeDamage(humanoid.Health)
panSound:Play()
soundFolder.FireAttack:Play()
end
end
end
end
-- Callback for when the tool is activated
local function onActivated()
if not canAttack then return end
local currentTime = tick()
local timeSinceLastSwing = currentTime - lastSwingTime
if timeSinceLastSwing > chainTimeframe then
attackStage = 1
else
attackStage += 1
end
local humanoid = tool.Parent:FindFirstChildOfClass("Humanoid")
if attackStage == 1 then
if currentAnimPlaying then
currentAnimPlaying:Stop()
end
panSwingSound:Play()
currentAnimPlaying = playAnimation(panAttack1)
-- Disable movement and schedule forward and upward movement
if humanoid then
originalWalkSpeed = humanoid.WalkSpeed
humanoid.WalkSpeed = 0 -- Disable movement during the attack
MoveAmount = 40
timeToMove = 0.4
wait(1)
fireEffect1.Lifetime = NumberRange.new(0.3, 0.5)
fireEffect1.Rate = 300
fireEffect1.Enabled = true
soundFolder.FireActive:Play()
delay(0.821, movePlayerForward)
fireEffect1.Rate = 1000
wait(1)
soundFolder.Fire:Play()
end
elseif attackStage == 2 then
if currentAnimPlaying then
currentAnimPlaying:Stop()
end
currentAnimPlaying = playAnimation(panAttack2)
if humanoid then
originalWalkSpeed = humanoid.WalkSpeed
humanoid.WalkSpeed = 0
delay(0.4, movePlayerUp)
soundFolder.JumpFire:Play()
end
elseif attackStage == 3 then
if currentAnimPlaying then
currentAnimPlaying:Stop()
end
local wave1 = tool.Particle.Wave1
local wave2 = tool.Particle.Wave2
if humanoid then
originalWalkSpeed = humanoid.WalkSpeed
humanoid.WalkSpeed = 0
local waveClone1 = wave1:Clone()
local waveClone2 = wave2:Clone()
waveClone1.Parent = humanoid.Parent.LowerTorso
waveClone2.Parent = humanoid.Parent.LowerTorso
waveClone1.Name = "WaveClone1"
waveClone2.Name = "WaveClone2"
MoveAmount = 70
timeToMove = 0.05
delay(3, movePlayerForward)
soundFolder.Charge:Play()
currentAnimPlaying = playAnimation(panAttack3)
wait(2)
waveClone1.Rate = 300
waveClone2.Rate = 300
end
wait(0.8)
soundFolder.Jump:Play()
soundFolder.JumpFire:Play()
wait(0.4)
killAllInRange(15)
else
attackStage = 0
return
end
if currentAnimPlaying then
currentAnimPlaying.Stopped:Connect(onAnimationStopped)
end
stopHoldingAnimation()
canAttack = false
canDmg = true
lastSwingTime = currentTime
end
-- Callback for when hitbox is touched
local function onHitBoxTouched(hit)
if canDmg then
local humanoid = hit.Parent:FindFirstChild("Humanoid")
if humanoid and not hitTargets[humanoid] then
-- Damage logic based on attack stage
if attackStage == 1 and currentAnimPlaying and currentAnimPlaying.Animation == panAttack1 then
panSound:Play()
soundFolder.FireAttack:Play()
humanoid:TakeDamage(damageFirstAttack)
elseif attackStage == 2 and currentAnimPlaying and currentAnimPlaying.Animation == panAttack2 then
panSound:Play()
soundFolder.FireAttack:Play()
humanoid:TakeDamage(damageSecondAttack)
elseif attackStage == 3 and currentAnimPlaying and currentAnimPlaying.Animation == panAttack3 then
panSound:Play()
soundFolder.FireAttack:Play()
humanoid:TakeDamage(damageThirdAttack)
end
hitTargets[humanoid] = true -- Mark the humanoid as hit during this attack
end
end
end
tool.Activated:Connect(onActivated)
tool.Equipped:Connect(onEquipped)
tool.Unequipped:Connect(onUnequipped)
hitBox.Touched:Connect(onHitBoxTouched)