Sword script not working. Would anyone kindly help?

Hey there,

I’m working on a weapon script that features blocking, disarming, and even a system where, if you have the correct manual in your ‘inventory’, you get better animations.

However, I’ve been scripting on it for a few days now, and I’ve noticed either one of three problems occur:

  • Either the weapon does damage even when the CanAttack debounce doesn’t allow it to do so.
  • Either the weapon does no damage at all.
  • Either the weapon does way too much damage in a single swing or touch.

Currently the script gives the second problem, I’ve tried toying around with values and debounce alot, but to no avail. Ideally, the weapon should do a single chunk damage only when it’s animation plays. Any help would be greatly appreciated. Here’s the scripts:

  1. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

After that, you should include more details if you have any. Try to make your topic as descriptive as possible, so that it’s easier for people to help you!

LOCAL SCRIPT:

local AttackEvent = tool:WaitForChild("Attack")
local holdEvent = tool:WaitForChild("Equip")
local UnequipEvent = tool:WaitForChild("Unequip")
local equipped = false

local ready = true
local blockReady = true
local disarmReady = true

local function unEquipFalse()

if game.Players.LocalPlayer.PlayerGui:FindFirstChild("Menu") then
game.Players.LocalPlayer.PlayerGui.Menu.Enabled = false	
end
end

local function unEquipTrue()

if game.Players.LocalPlayer.PlayerGui:FindFirstChild("Menu") then
game.Players.LocalPlayer.PlayerGui.Menu.Enabled = true
end
end



tool.Equipped:Connect(function()
if equipped == false then
equipped = true
holdEvent:FireServer()
	end
end)

tool.Unequipped:Connect(function()
UnequipEvent:FireServer()
equipped = false
end)

tool.Activated:Connect(function()
if ready == true then
ready = false
AttackEvent:FireServer()
wait (1.2)
ready = true
end
end)

-- blocking starts here

function onKeyPress(inputObject, gameProcessedEvent)
if equipped == true then
	if inputObject.KeyCode == Enum.KeyCode.R then
		
		unEquipFalse()
		
		if blockReady == true then
		blockReady = false
		tool.Block:FireServer()
		wait(1.35)
		blockReady = true
		
		unEquipTrue()
				
	end
		end
			end

-- disarming starts here

	if equipped == true then
	if inputObject.KeyCode == Enum.KeyCode.F then
		if disarmReady == true then
			if blockReady == true then
		disarmReady = false
		tool.DisarmOpponent:FireServer()
		wait(2)
		disarmReady = true
end
	end
	end
end
	end
game:GetService("UserInputService").InputBegan:Connect(onKeyPress)

SERVER SCRIPT:

math.randomseed(tick())

local players = game:GetService("Players")

local tool = script.Parent
local AttackEvent = tool.Attack
local animations = {2767602406,2768855848,2768933359}
local clumsyAnim = {3568954918,3568954918}
local holdEvent = tool.Equip
local unEquipEvent = tool.Unequip
--local touched = false
local blockEvent = tool.Block
local disarmEvent = tool.DisarmOpponent
local canAttack = true
local disarmOpponentAnimation = script.Parent.Anims.DisarmOpponent
local manualRequired = script.Parent.ManualRequired

local function onHoldFired(plr)
	plr.Character.Humanoid["IsDisarmable"].Value = false
	local animHold = script.Parent.Anims.Hold
	local animHoldLoop = plr.Character.Humanoid:LoadAnimation(animHold)
	animHoldLoop:Play()
end

local function onUnequipFired(plr)
local humanoid = plr.Character.Humanoid

local ActiveTracks = humanoid:GetPlayingAnimationTracks()
for _,v in pairs(ActiveTracks) do
    v:Stop()
	end
end

local function onAttackFired(plr)
	local canAttack = true

	if canAttack == true then
	canAttack = false

	local char = plr.Character
	local humanoid = char.Humanoid
	local animation = Instance.new("Animation")
	local picked = math.random(1, #animations)
	if plr.Manuals:FindFirstChild(manualRequired.Value) then
	animation.AnimationId = "http://roblox.com/asset/?id="..animations[picked]
	local animTrack = humanoid:LoadAnimation(animation)
	
	animTrack:Play()
	script.Parent.Handle.SwingSound:Play()
	plr.Character.Humanoid["IsDisarmable"].Value = true
	wait(script.Parent.DisarmingTimeWindow.Value) 
	plr.Character.Humanoid["IsDisarmable"].Value = false
		
	elseif not plr.Manuals:FindFirstChild(manualRequired.Value) then
	animation.AnimationId = "http://roblox.com/asset/?id=".. clumsyAnim[picked]
	local animTrack = humanoid:LoadAnimation(animation)
	
	animTrack:Play()
	script.Parent.Handle.SwingSound:Play()
	plr.Character.Humanoid["IsDisarmable"].Value = true
	wait(script.Parent.DisarmingTimeWindow.Value) 
	plr.Character.Humanoid["IsDisarmable"].Value = false
	
end
end
tool.Blade.Touched:Connect(function(part)
if part.Parent:FindFirstChild("Humanoid") and part.Parent.Humanoid:FindFirstChild("CanEngageInPVP")then
if part.Parent.Humanoid["CanEngageInPVP"].Value  == true then
	if touched == false then
	
	-- if opponent is blocking
	if part.Parent.Humanoid:FindFirstChild("IsBlocking") and part.Parent.Humanoid:FindFirstChild("IsBlocking").Value == true then
	--part.Parent.Humanoid:TakeDamage(2) -- (this could serve as defense penentration)
			tool.Handle.BlockSound:Play()
			tool.Blade.Sparkles.Enabled = true
			wait(0.1)
			tool.Blade.Sparkles.Enabled = false
			wait(0.9)
			canAttack = true
			touched = false
-- if opponent is not blocking
elseif part.Parent.Humanoid:FindFirstChild("IsBlocking") and part.Parent.Humanoid:FindFirstChild("IsBlocking").Value == false then
	if plr.Manuals:FindFirstChild(manualRequired.Value) then
	part.Parent:FindFirstChild("Humanoid"):TakeDamage(script.Parent.Damage.Value - part.Parent["Humanoid"].ArmourLevel.Value/script.Parent.AntiArmourCapacity.Value)-- the higher the number, the better it penentrates armour
								
	elseif not plr.Manuals:FindFirstChild(manualRequired.Value)	then
	part.Parent:FindFirstChild("Humanoid"):TakeDamage(script.Parent.Damage.Value - part.Parent["Humanoid"].ArmourLevel.Value/script.Parent.AntiArmourCapacity.Value/100*80)-- the higher the number, the better it penentrates armour
end
	part.Parent["Humanoid"]["WhoKilled"].Value = plr.Name -- for the exp system
		tool.Handle.HitSound:Play()
		wait(1)
		canAttack = true
	
	else
		wait(1)
		canAttack = true		
								end
							end
				end
			end
		end)
	end
local function disarmTouch()
	local disarmTouched = false
	tool.Blade.Touched:Connect(function(part)

		if part.Parent:FindFirstChild("Humanoid") then
			if part.Parent["Humanoid"].CanEngageInPVP == true then
					if disarmTouched == false then
					disarmTouched = true
				if part.Parent.Humanoid["IsDisarmable"].Value == true then
					
					local opponent = players:GetPlayerFromCharacter(part.Parent)

	if opponent.Character:FindFirstChildOfClass("Tool") then	

						local opponentItem = opponent.Character:FindFirstChildOfClass("Tool")
						local itemName = opponentItem.Name
							opponent.Character["Humanoid"]:UnequipTools()
									opponentItem:Destroy()
									opponent.Storage:FindFirstChild(itemName):Destroy()
								local item = game.ReplicatedStorage.Objects:FindFirstChild(itemName):Clone()
								item.Position = part.Parent.LeftHand.Position
							local OpponentDisarmPlay = opponent.Character["Humanoid"]:LoadAnimation(disarmOpponentAnimation)
							OpponentDisarmPlay:Play()
								item.Parent = game.Workspace
					tool.Blade.Sparkles.Enabled  = true
					tool.Handle.Disarm:Play()
					wait(0.2)
					tool.Blade.Sparkles.Enabled = false

wait(OpponentDisarmPlay.Length + 0.5)
local ActiveTracks = opponent.Character.Humanoid:GetPlayingAnimationTracks()
for _,v in pairs(ActiveTracks) do
    v:Stop()
	end
end
			end
	end
end
end
end)
				wait(0.1)
			tool.Blade.Sparkles.Enabled = false
						touched = false
						disarmTouched = false
end

--blocking
local function onBlockFired(plr)
	plr.Character.Humanoid.IsBlocking.Value = true
	plr.Character.Humanoid.WalkSpeed = 7.3
	local animBlock = script.Parent.Anims.Block
	local animBlockPlay = plr.Character.Humanoid:LoadAnimation(animBlock)
	animBlockPlay:Play()
	wait(animBlockPlay.Length)
	plr.Character.Humanoid.WalkSpeed = plr.Character.Humanoid.MovementSpeed.Value
	plr.Character.Humanoid.IsBlocking.Value = false
	
	end
--disarming
local function onDisarmFired(plr)
	plr.Character.Humanoid.WalkSpeed = 0
	local animDisarm = script.Parent.Anims.Disarm
	local animDisarmPlay = plr.Character.Humanoid:LoadAnimation(animDisarm)
	animDisarmPlay:Play()
	disarmTouch()
	wait(animDisarmPlay.Length)
	plr.Character.Humanoid.WalkSpeed = plr.Character.Humanoid.MovementSpeed.Value

	end

holdEvent.OnServerEvent:Connect(onHoldFired)
unEquipEvent.OnServerEvent:Connect(onUnequipFired)
AttackEvent.OnServerEvent:Connect(onAttackFired)
blockEvent.OnServerEvent:Connect(onBlockFired)
disarmEvent.OnServerEvent:Connect(onDisarmFired)

Really, I’ve run out of ideas and options, I’d really appreciate some help. If you’ve got any questions about the script or I’m not being clear - feel free to ask in the comments.
Thank you!

  • Souflee
1 Like

There’s a lot here, so this sort of turned into more of a code review :slight_smile:

There may be more issues than this, but here’s what I’ve found:

General Comments

  1. As a suggestion, I would move much of the animation playing to the client. Animations played on the client are replicated to the server anyways, but this way it’s more responsive. It also cleans up your server code and makes it easier to reason about. Some will need to stay on the server, to play on the other client.

  2. Use the same wait variables in your server code as your client code. You’re using NumberValues on the server-side, but hardcoded ones on the client side.

  3. Your formatting is a little wack. There are online auto-formatters that will fix it for you. Might be worth it to edit your post with well-formatted code.

  4. You need some sort of rate-limiting on the server side. This is a security problem – assume that the client can call any RemoteEvent whenever they want to (for example, 50 times a second), because exploiters can do exactly that. Are you confident that your server code will properly prevent players from doing that?

Your problem

  1. The client side looks pretty much fine (except for the hardcoded wait values)

  2. The touched variable on the server side seems incorrect. It’s commented out at the top of your script, yet it is checked in the first tool.Blade.Touched connection. I’m not sure what you intended it to do, but the way I’m reading the script means that this line:

                    if touched == false then
    

    will always fail, and so that touched event will never do anything.

  3. … Except, you do set a global touched variable at the bottom of disarmTouch:

    touched = false
    disarmTouched = false
    

    So actually, I guess if you disarmed first, and then attacked, the (global) variable would actually be false, and the if touched == false then check would pass. That’s almost definitely not what you intended, so you should clean that up.

  4. The Biggest Problem: You are creating a new Touched connection every time the player attacks or disarms. That’s bad for a lot of reasons – mostly, it’s a memory leak, and it will cause the event to fire multiple times the more times you attack. BAD!

    The Solution: You can call Disconnect on connections. Use this to kill connections after they’re used once:

    local connection; -- create local variable so we can access it inside the function
    
    connection = tool.Blade.Touched:Connect(function(part)
        -- immediately disconnect the event so it only runs once.
        connection:Disconnect()
    
        -- hurt the players, etc.
    end)
    

    If you wanted to hurt groups of people with one strike, you’d need more complex logic – keeping track of who you’ve hit with this swing, etc.

1 Like

Hello, nicemike40

First off I’d like to say a big thank you for giving such a detailed, well thought out response. I’ve been scripting for a while now, but there’s always more to learn as it seems :slight_smile: Really, I appreciate it.

All I’m wondering now is how I should call the onTouched event? Where should I put it and how do I make sure I don’t call it every time the player attacks as you said?

I’m thinking you have this sort of flow:

  1. Client clicks button, fires remoteevent
  2. Server checks everything is OK
  3. Server connects touched event to sword, plays animations
  4. As soon as the first touch occurs (so inside the touched event handler), disconnect the touched connection to prevent further touches.
  5. Process hit as normal
1 Like

Hey, thanks for the reply again.

I think I’m really close to finishing the script thanks to you! However, the following code still doen’t do damage. I also ‘beautified’ it a bit with the formatter you sent.

math.randomseed(tick())

local players = game:GetService("Players")

local tool = script.Parent
local AttackEvent = tool.Attack
local animations = {2767602406,2768855848,2768933359}
local clumsyAnim = {3568954918,3568954918}
local holdEvent = tool.Equip
local unEquipEvent = tool.Unequip
local touched = false
local blockEvent = tool.Block
local disarmEvent = tool.DisarmOpponent
local disarmOpponentAnimation = script.Parent.Anims.DisarmOpponent
local manualRequired = script.Parent.ManualRequired
local canAttack = true

local connection;

local function onHoldFired(plr)
	plr.Character.Humanoid["IsDisarmable"].Value = false
	local animHold = script.Parent.Anims.Hold
	local animHoldLoop = plr.Character.Humanoid:LoadAnimation(animHold)
	animHoldLoop:Play()
end

local function onUnequipFired(plr)
local humanoid = plr.Character.Humanoid

local ActiveTracks = humanoid:GetPlayingAnimationTracks()
for _,v in pairs(ActiveTracks) do
    v:Stop()
	end
end

local function onAttackFired(plr)	
		if touched == false then
	
	local char = plr.Character
	local humanoid = char.Humanoid
	local animation = Instance.new("Animation")
	local picked = math.random(1, #animations)
		
	if plr.Manuals:FindFirstChild(manualRequired.Value) then
	animation.AnimationId = "http://roblox.com/asset/?id="..animations[picked]
	local animTrack = humanoid:LoadAnimation(animation)
	
	animTrack:Play()
	script.Parent.Handle.SwingSound:Play()
	plr.Character.Humanoid["IsDisarmable"].Value = true
	wait(script.Parent.DisarmingTimeWindow.Value) 
	plr.Character.Humanoid["IsDisarmable"].Value = false
		
	elseif not plr.Manuals:FindFirstChild(manualRequired.Value) then
	animation.AnimationId = "http://roblox.com/asset/?id=".. clumsyAnim[picked]
	local animTrack = humanoid:LoadAnimation(animation)
	
	animTrack:Play()
	script.Parent.Handle.SwingSound:Play()
	plr.Character.Humanoid["IsDisarmable"].Value = true
	wait(script.Parent.DisarmingTimeWindow.Value) 
	plr.Character.Humanoid["IsDisarmable"].Value = false
	
	end

end
end

connection = tool.Blade.Touched:Connect(function(part)
	connection:Disconnect()
	local plr = players:GetPlayerFromCharacter(tool.Parent)
	
if part.Parent:FindFirstChild("Humanoid") and part.Parent.Humanoid:FindFirstChild("CanEngageInPVP")then
if part.Parent.Humanoid["CanEngageInPVP"].Value  == true then
		if touched == false then

	-- if opponent is blocking
	if part.Parent.Humanoid:FindFirstChild("IsBlocking") and part.Parent.Humanoid:FindFirstChild("IsBlocking").Value == true then
	--part.Parent.Humanoid:TakeDamage(2) -- (this could serve as defense penentration)
			tool.Handle.BlockSound:Play()
			tool.Blade.Sparkles.Enabled = true
			wait(0.1)
			tool.Blade.Sparkles.Enabled = false
			wait(0.9)
				touched = false
				canAttack = true

-- if opponent is not blocking
elseif part.Parent.Humanoid:FindFirstChild("IsBlocking") and part.Parent.Humanoid:FindFirstChild("IsBlocking").Value == false then
	if plr.Manuals:FindFirstChild(manualRequired.Value) then
	part.Parent:FindFirstChild("Humanoid"):TakeDamage(script.Parent.Damage.Value - part.Parent["Humanoid"].ArmourLevel.Value/script.Parent.AntiArmourCapacity.Value)-- the higher the number, the better it penentrates armour
								
	elseif not plr.Manuals:FindFirstChild(manualRequired.Value)	then
	part.Parent:FindFirstChild("Humanoid"):TakeDamage(script.Parent.Damage.Value - part.Parent["Humanoid"].ArmourLevel.Value/script.Parent.AntiArmourCapacity.Value/100*80)-- the higher the number, the better it penentrates armour
					
	part.Parent["Humanoid"]["WhoKilled"].Value = plr.Name -- for the exp system
		tool.Handle.HitSound:Play()
		wait(1)
		touched = false
		canAttack = true

	else
		wait(1)
		touched = false
		canAttack = true
		
					end
					wait(1)
					touched = false
			end
		end
		end
	end
end)


local function disarmTouch()
	local disarmTouched = false
	tool.Blade.Touched:Connect(function(part)

		if part.Parent:FindFirstChild("Humanoid") then
			if part.Parent["Humanoid"].CanEngageInPVP == true then
					if disarmTouched == false then
					disarmTouched = true
				if part.Parent.Humanoid["IsDisarmable"].Value == true then
					
					local opponent = players:GetPlayerFromCharacter(part.Parent)

	if opponent.Character:FindFirstChildOfClass("Tool") then	

						local opponentItem = opponent.Character:FindFirstChildOfClass("Tool")
						local itemName = opponentItem.Name
							opponent.Character["Humanoid"]:UnequipTools()
									opponentItem:Destroy()
									opponent.Storage:FindFirstChild(itemName):Destroy()
								local item = game.ReplicatedStorage.Objects:FindFirstChild(itemName):Clone()
								item.Position = part.Parent.LeftHand.Position
							local OpponentDisarmPlay = opponent.Character["Humanoid"]:LoadAnimation(disarmOpponentAnimation)
							OpponentDisarmPlay:Play()
								item.Parent = game.Workspace
					tool.Blade.Sparkles.Enabled  = true
					tool.Handle.Disarm:Play()
					wait(0.2)
					tool.Blade.Sparkles.Enabled = false

wait(OpponentDisarmPlay.Length + 0.5)
local ActiveTracks = opponent.Character.Humanoid:GetPlayingAnimationTracks()
for _,v in pairs(ActiveTracks) do
    v:Stop()
	end
end
			end
	end
end
end
end)
				wait(0.1)
			tool.Blade.Sparkles.Enabled = false
						touched = false
						disarmTouched = false
end

--blocking
local function onBlockFired(plr)
	plr.Character.Humanoid.IsBlocking.Value = true
	plr.Character.Humanoid.WalkSpeed = 7.3
	local animBlock = script.Parent.Anims.Block
	local animBlockPlay = plr.Character.Humanoid:LoadAnimation(animBlock)
	animBlockPlay:Play()
	wait(animBlockPlay.Length)
	plr.Character.Humanoid.WalkSpeed = plr.Character.Humanoid.MovementSpeed.Value
	plr.Character.Humanoid.IsBlocking.Value = false
	
	end
--disarming
local function onDisarmFired(plr)
	plr.Character.Humanoid.WalkSpeed = 0
	local animDisarm = script.Parent.Anims.Disarm
	local animDisarmPlay = plr.Character.Humanoid:LoadAnimation(animDisarm)
	animDisarmPlay:Play()
	disarmTouch()
	wait(animDisarmPlay.Length)
	plr.Character.Humanoid.WalkSpeed = plr.Character.Humanoid.MovementSpeed.Value

	end

holdEvent.OnServerEvent:Connect(onHoldFired)
unEquipEvent.OnServerEvent:Connect(onUnequipFired)
AttackEvent.OnServerEvent:Connect(onAttackFired)
blockEvent.OnServerEvent:Connect(onBlockFired)
disarmEvent.OnServerEvent:Connect(onDisarmFired)

I’m really not sure what I’m doing wrong.

That’s close to what I was imagining! Think about what that code does, though.

  1. You’re connecting a Touched event when the tool is first created
  2. You disconnect that event on the first touch
  3. You never reconnect it after that

I think you’re adding so many variables and things that you’re confusing yourself.

There are two different ways to do what you want:

  1. Do the “connect an event, disconnect immediately inside the handler” thing, but run connect a new Touched event every time the player swings their sword, or

  2. Do what you did – just connect the event once, when the tool is created – but don’t disconnect it. Instead, you would need some logic inside that touched event to figure out if the player is currently attacking/blocking (some of this you have).

I was suggesting option 1, although option 2 might be useful depending on your needs.

Here’s the sort of idea about option 1. It’s just a guide, not complete code, but should nudge you enough in the right direction:

local canAttack = true

local function onAttackFired(plr)
    if (canAttack) then
        canAttack = false

        -- start animation
        
        -- set up a connection *for this swing only*
        local connection
        connection = tool.Blade.Touched:Connect(function(part))
            local plr = players:GetPlayerFromCharacter(tool.Parent)
            local them = players:GetPlayerFromCharacter(part.Parent)
            
            if plr and them then
                local theirHuman = them.Character:FindFirstChild("Humanoid")
                
                if theirHuman then
                    -- we definitely hit a person, disconnect the event so that
                    -- we don't do it again!
                    connection:Disconnect()
                    if --[[ more checks for blocking, pvp, etc. ]] then
                        -- play sounds, etc.
                        theirHuman:TakeDamage(20)
                    end
                end
            end
        end)
        
        wait(1)
        
        -- If we didn't hit anything after one second, the event still needs to
        -- be disconnected!
        if connection.Connected then
            connection:Disconnect()
        end
        
        canAttack = true
    end
end

AttackEvent.OnServerEvent:Connect(onAttackFired)

The other handlers for disarming, etc. would be similar.

Any more questions feel free to ask.

P.S. clumsyAnim[picked] will eventually error on you, since picked is based on the length of animations, which is a longer list.
2 Likes

Holy smokes that worked just fine! Thanks so much!! I followed your steps and it finally works! Hurrah!

I really appreciate the time and effort you put into helping me, you made a young man in Belgium really happy! :slight_smile:
If I happen to finish the larger project this script is meant for, I’ll be sure to credit you when it’s done!

Thanks alot again. This is the finished script: (although I didn’t fix the disarming just yet, I’ll save that for later)

math.randomseed(tick())

local players = game:GetService("Players")

local tool = script.Parent
local AttackEvent = tool.Attack
local animations = {2767602406,2768855848,2768933359}
local clumsyAnim = {3568954918,3568954918}
local holdEvent = tool.Equip
local unEquipEvent = tool.Unequip
--local touched = false
local blockEvent = tool.Block
local disarmEvent = tool.DisarmOpponent
local disarmOpponentAnimation = script.Parent.Anims.DisarmOpponent
local manualRequired = script.Parent.ManualRequired
local canAttack = true
local attackDelay = script.Parent.AttackDelay

local function onHoldFired(plr)
	plr.Character.Humanoid["IsDisarmable"].Value = false
	local animHold = script.Parent.Anims.Hold
	local animHoldLoop = plr.Character.Humanoid:LoadAnimation(animHold)
	animHoldLoop:Play()
end

local function onUnequipFired(plr)
local humanoid = plr.Character.Humanoid

local ActiveTracks = humanoid:GetPlayingAnimationTracks()
for _,v in pairs(ActiveTracks) do
    v:Stop()
	end
end

local function onAttackFired(plr)	
    if canAttack == true then
		canAttack = false
		
	local char = plr.Character
	local humanoid = char.Humanoid
	local animation = Instance.new("Animation")
	local picked = math.random(1, #animations)
		
	if plr.Manuals:FindFirstChild(manualRequired.Value) then
	animation.AnimationId = "http://roblox.com/asset/?id="..animations[picked]
	local animTrack = humanoid:LoadAnimation(animation)
	
	animTrack:Play()
	script.Parent.Handle.SwingSound:Play()
	plr.Character.Humanoid["IsDisarmable"].Value = true
	wait(script.Parent.DisarmingTimeWindow.Value) 
	plr.Character.Humanoid["IsDisarmable"].Value = false
		
	elseif not plr.Manuals:FindFirstChild(manualRequired.Value) then
	animation.AnimationId = "http://roblox.com/asset/?id=".. clumsyAnim[picked]
	local animTrack = humanoid:LoadAnimation(animation)
	
	animTrack:Play()
	script.Parent.Handle.SwingSound:Play()
	plr.Character.Humanoid["IsDisarmable"].Value = true
	wait(script.Parent.DisarmingTimeWindow.Value) 
	plr.Character.Humanoid["IsDisarmable"].Value = false
			
end
		
local connection	
connection = tool.Blade.Touched:Connect(function(part)
	local plr = players:GetPlayerFromCharacter(tool.Parent)
	
if part.Parent:FindFirstChild("Humanoid") and part.Parent.Humanoid:FindFirstChild("CanEngageInPVP")then
if part.Parent.Humanoid["CanEngageInPVP"].Value  == true then

	-- if opponent is blocking
	if part.Parent.Humanoid:FindFirstChild("IsBlocking") and part.Parent.Humanoid:FindFirstChild("IsBlocking").Value == true then
	--part.Parent.Humanoid:TakeDamage(2) -- (this could serve as defense penentration)
			tool.Handle.BlockSound:Play()
			tool.Blade.Sparkles.Enabled = true
			connection:Disconnect()
			wait(0.1)
			tool.Blade.Sparkles.Enabled = false
			wait(attackDelay.Value-.1)
			canAttack = true

-- if opponent is not blocking
elseif part.Parent.Humanoid:FindFirstChild("IsBlocking") and part.Parent.Humanoid:FindFirstChild("IsBlocking").Value == false then
	if plr.Manuals:FindFirstChild(manualRequired.Value) then
	part.Parent:FindFirstChild("Humanoid"):TakeDamage(script.Parent.Damage.Value - part.Parent["Humanoid"].ArmourLevel.Value/script.Parent.AntiArmourCapacity.Value)-- the higher the number, the better it penentrates armour
	tool.Handle.HitSound:Play()
							
end		
	elseif not plr.Manuals:FindFirstChild(manualRequired.Value)	then
		part.Parent:FindFirstChild("Humanoid"):TakeDamage(script.Parent.Damage.Value - part.Parent["Humanoid"].ArmourLevel.Value/script.Parent.AntiArmourCapacity.Value/100*80)-- the higher the number, the better it penentrates armour
		tool.Handle.HitSound:Play()
end			
end
	part.Parent["Humanoid"]["WhoKilled"].Value = plr.Name -- for the exp system
		connection:Disconnect()

			end
		end)
			wait(attackDelay.Value)
	        if connection.Connected then
            connection:Disconnect()
	end
	canAttack = true
end
end


----- disarming
local function disarmTouch()
	local disarmTouched = false
	tool.Blade.Touched:Connect(function(part)

		if part.Parent:FindFirstChild("Humanoid") then
			if part.Parent["Humanoid"].CanEngageInPVP == true then
					if disarmTouched == false then
					disarmTouched = true
				if part.Parent.Humanoid["IsDisarmable"].Value == true then
					
					local opponent = players:GetPlayerFromCharacter(part.Parent)

	if opponent.Character:FindFirstChildOfClass("Tool") then	

						local opponentItem = opponent.Character:FindFirstChildOfClass("Tool")
						local itemName = opponentItem.Name
							opponent.Character["Humanoid"]:UnequipTools()
									opponentItem:Destroy()
									opponent.Storage:FindFirstChild(itemName):Destroy()
								local item = game.ReplicatedStorage.Objects:FindFirstChild(itemName):Clone()
								item.Position = part.Parent.LeftHand.Position
							local OpponentDisarmPlay = opponent.Character["Humanoid"]:LoadAnimation(disarmOpponentAnimation)
							OpponentDisarmPlay:Play()
								item.Parent = game.Workspace
					tool.Blade.Sparkles.Enabled  = true
					tool.Handle.Disarm:Play()
					wait(0.2)
					tool.Blade.Sparkles.Enabled = false

wait(OpponentDisarmPlay.Length + 0.5)
local ActiveTracks = opponent.Character.Humanoid:GetPlayingAnimationTracks()
for _,v in pairs(ActiveTracks) do
    v:Stop()
	end
end
			end
	end
end
end
end)
				wait(0.1)
			tool.Blade.Sparkles.Enabled = false
						disarmTouched = false
end

--blocking
local function onBlockFired(plr)
	plr.Character.Humanoid.IsBlocking.Value = true
	plr.Character.Humanoid.WalkSpeed = 7.3
	local animBlock = script.Parent.Anims.Block
	local animBlockPlay = plr.Character.Humanoid:LoadAnimation(animBlock)
	animBlockPlay:Play()
	wait(animBlockPlay.Length)
	plr.Character.Humanoid.WalkSpeed = plr.Character.Humanoid.MovementSpeed.Value
	plr.Character.Humanoid.IsBlocking.Value = false
	
	end
--disarming
local function onDisarmFired(plr)
	plr.Character.Humanoid.WalkSpeed = 0
	local animDisarm = script.Parent.Anims.Disarm
	local animDisarmPlay = plr.Character.Humanoid:LoadAnimation(animDisarm)
	animDisarmPlay:Play()
	disarmTouch()
	wait(animDisarmPlay.Length)
	plr.Character.Humanoid.WalkSpeed = plr.Character.Humanoid.MovementSpeed.Value

	end

holdEvent.OnServerEvent:Connect(onHoldFired)
unEquipEvent.OnServerEvent:Connect(onUnequipFired)
AttackEvent.OnServerEvent:Connect(onAttackFired)
blockEvent.OnServerEvent:Connect(onBlockFired)
disarmEvent.OnServerEvent:Connect(onDisarmFired)

1 Like

N’oubliez pas de formater votre code correctement :slight_smile:

1 Like

Can do! Definitely gonna use that online auto formatter :slight_smile: