Help with scripting a sword

I don’t really know how tables work, and how I could integrate that into my current code. For example, if I have another tool named Longsword, how could I add that?

As long as each of the weapons has a unique name, you can create a dictionary of their names and damages like so.

local weaponsAndDamages = {}
weaponsAndDamages ["Longsword"] = 30
weaponsAndDamages ["Spear"] = 25
weaponsAndDamages ["Dagger"] = 15
weaponsAndDamages ["Great Sword"] = 50

Then in your damaging code;

hit.Parent.Humanoid:TakeDamage(weaponsAndDamages[Weapon.Name])
1 Like

Another problem, how can I change the attack rate? In the serverscript, we made sure the last attack was 0.5 or more seconds ago so it can’t be spammed by exploiters. In the great sword for example, it would be a much slower attack opposed to a dagger.
edit: I’m guessing another table will work, so that is what I will try.

--working code--
local weaponsAndDamages = {}
weaponsAndDamages [“Sword”] = 35
weaponsAndDamages [“Spear”] = 35
weaponsAndDamages [“Dagger”] = 27
weaponsAndDamages [“Longsword”] = 55

local weaponsAndRates = {}
weaponsAndRates ["Sword"] = 0.5
weaponsAndRates ["Spear"] = 0.5
weaponsAndRates ["Dagger"] = 0.3
weaponsAndRates ["Longsword"] = 1

local lastAttack = {}
game.ReplicatedStorage.Damage.OnServerEvent:Connect(function(player, hit)
    local weapon = player.Character:FindFirstChildWhichIsA("Tool") -- obtain the sword of the player attacking
    if hit.Parent:FindFirstChild("Humanoid") ~= nil and player.Character ~= nil then
        if hit.Parent.Humanoid.Health > 0 and player.Character.Humanoid.Health > 0 then -- check if the users are alive, we don't want dead players dealing damage, or players dealing damage to dead players.
            if lastAttack[player.Name] == nil or tick() - lastAttack[player.Name] > weaponsAndRates[weapon.Name] then
                if (hit.Parent.HumanoidRootPart.Position-player.Character.HumanoidRootPart.Position).magnitude < 40 then -- went with 40 just in case of serious latency. You can tweak this if wanted.
                    lastAttack[player.Name] = tick()
                    if weapon ~= nil then -- make sure it's not nil
                  		hit.Parent.Humanoid:TakeDamage(weaponsAndDamages[weapon.Name])
                        weapon.Handle.Hit:Play() -- You want to play the hit noise on the sword of the player who is attacking, not the sword in the StarterPack.
                    end
                end
            end
        end
    end
end)

Good job! You can further simplify this by combing your dictionaries!

local weaponStats = {}
weaponStats ["Sword"] = {["Damage"] = 35, ["Rate"] = 0.5}
weaponStats ["Spear"] = {["Damage"] = 35, ["Rate"] = 0.5}
weaponStats ["Dagger"] = {["Damage"] = 27, ["Rate"] = 0.3}
weaponStats ["Longsword"] = {["Damage"] = 55, ["Rate"] = 0.1}

-- to refer to Rate
weaponStats[Weapon.Name]["Rate"]
-- to refer to Damage
weaponStats[Weapon.Name]["Damage"]

Edit: If you have solved the problem you made this topic for, you should select a post as the solution so other users can see it without reading every post. It also helps people to tell what posts already have answers so they can focus on others!

1 Like

The sound is a bit buggy. It will play the audios occasionally but most of the time it is completely silent. (attacking noise and hit noise don’t play consistently.) Do you know what could be causing this? Below is the local script for reference, and I already pasted the working server script above.

--//Idle Animation\\--
script.Parent.Equipped:Connect(function()
local idle = script.Parent.Parent.Humanoid:LoadAnimation(script.Parent.Animations.Idle)
idle:Play()
script.Parent.Unequipped:Connect(function()
idle:Stop()
end)
end)

--//Attacking Animations\\--
local UserInputService = game:GetService("UserInputService")
local Tool = script.Parent
local CanAttack = true
local Anim_Name = "Attack"
local Audio = script.Parent.Handle.Swing
local Attack_Animations = script.Parent:WaitForChild("Animations")
local Attack_Num = 1
local blade = script.Parent.SwordBlade

blade.Touched:Connect(function(hit)
	if CanAttack == false then
		game.ReplicatedStorage.Damage:FireServer(hit)
	end
end)

UserInputService.InputBegan:Connect(function(InputObject)
	if InputObject.UserInputType == Enum.UserInputType.MouseButton1 then
		local Animation = script.Parent.Parent.Humanoid:LoadAnimation(Attack_Animations[Anim_Name..Attack_Num])
		if CanAttack == true then
            CanAttack = false
			Animation:Play()
			Audio.PlaybackSpeed = math.random(0.9,1.1)
			Audio:Play()
			blade.Trail.Enabled = true
			wait(0.5)
			CanAttack = true
			blade.Trail.Enabled = false
			if Attack_Num == 1 then
				Attack_Num = Attack_Num + 1
				else if Attack_Num == 2 then
					Attack_Num = 1
				end
			end
		end
	end
end)

after further testing, it has something to do with having the playbackspeed and my math.random. I have to use division to get the numbers because they aren’t integers.

1 Like

Hello once again, I have decided that my weapon seems very much so fast-paced and that there isn’t much skill required. Therefore, I would like to add in a blocking system that:

  1. Right click to block, block for a small amount of time so that you have to time your blocks smartly.
  2. If someone attempted to attack and was blocked, they will be “thrown off balance” which basically slows them down so their movement is limited and they cannot attack for a moment.
  3. Possibly add counter-attack skill moves when the enemy is low on health and the player attack while they are off-balance?
    (I don’t even know where to start lol)

I also think a dodging/rolling system could help me achieve a more skill-based system, which would include side stepping and step back triggered by double pressing the corresponding key (example: double press A to dodge to the right) and a forward roll dodge with control.
(I don’t know how to make it so you have to press the corresponding buttons twice and also how to move the player after the animation is played)

I may try to mess around with the camera to get a more realistic shift-lock type of thing going on with camera swaying and shaking when you are hit. I have no idea how to do this, so advice on this would be appreciated.

Thanks for your help so far!

If your original request was solved for this topic, you should mark a solution. For further assistance with new requests and/or additions to your original request; you should create a new topic.

Swords typically don’t need remote events, if you don’t need to use the mouse, then you don’t need to use remotes. Just use Tool.Activated, it will suit you far better.