Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

Weapon Isn't Dealing Damage?

Asked by 7 years ago
Edited 7 years ago

Hi, I wrote a question about the use of my RemoteEvents because of the error I was having. I now have no errors, but the script still does not deal damage to the player that is being attacked. The tool has one local script, a RemoteEvent in a folder in ReplicatedStorage, and a script in ServerScriptService to activate when the RemoteEvent is fired.

The local script is this:

local player = game.Players.LocalPlayer
local char = player.Character
local hum = char:WaitForChild("Humanoid")

repeat wait() until char

repeat wait() until hum

local attackanim = script:WaitForChild("SlashAnim2")
attackanim.Parent = char

local animtrack = hum:LoadAnimation(attackanim)

local tool = script.Parent

local damage = 30

local debounce = false
local attacking = false
local attackingtouch = false

local rs = game:GetService("RunService")
local debris = game:GetService("Debris")

function onEquip()
    enabled = true
    animtrack:Stop()
end

function onActivate()
    if debounce == false then
        debounce = true
        attacking = true
        attackingtouch = true

        animtrack:Play()

        wait(1)

        attackingtouch = false
        debounce = false
        attacking = false
    end
end

function onTouch(part)
    if attackingtouch == true and debounce == true then
        if part.Parent.Name ~= player.Name then
            local vhum = part.Parent:findFirstChild("Humanoid")
            if vhum and vhum.Health > 0 then
                game.ReplicatedStorage.RemoteEvents.TakeHealthFromWeapon:FireServer(vhum, damage)
                attackingtouch = false
            end
        end
    end
end


function onUnequip()
    enabled = false
    animtrack:Stop()
end

tool.Equipped:connect(onEquip)
tool.Activated:connect(onActivate)
tool.Handle.Touched:connect(onTouch)
tool.Unequipped:connect(onUnequip)

The script in ServerScriptService looks like this:

function onTHFW(Player, vhum, damage)
    vhum.Health = vhum.Health - damage
end

game.ReplicatedStorage.RemoteEvents.TakeHealthFromWeapon.OnServerEvent:connect(onTHFW)

As I said before, I get no errors. What am I doing wrong? Thanks. :} ~Loughdough

1 answer

Log in to vote
1
Answered by
movsb 242 Moderation Voter
7 years ago
Edited 7 years ago

Ok; here I go:

The first thing you need to understand is that tools like swords, and guns are not very functional in a filtering enabled environment, unless they are replicated over both the server, and the cleint(s). To achieve this, you should usually store tools inside ReplicatedStorage, and clone the tool in replicated storage into a certain player's backpack down the road instead, however do not store your remote event inside of the tool; instead make sure your remote event is stored directly in ReplicatedStorage (i.e. so you could say game.ReplicatedStorage.my_remote_event)

From this point on, I will refer to your sword tool as 'Tool', and a standard remote event as 'r'

Typically to start a game, you would want to get the recent player that joined, and you typically do that with game.Players.PlayerAdded, however with filtering enabled, getting the player that joined is a bit different.

Insert a local script into game.StarterPlayer.StarterPlayerScripts; It's code should be something along the lines of:

local r = game.ReplicatedStorage.remote_event;
r:FireServer("Join");

this script is the script that fires to the server whenever its client joins the game. (this works because all local scripts are replicated to each client when they join a server)

Insert a server script (a script) into game.ServerScriptService that can manage cloning and giving out the Tool to every player when they join, or are re-spawned; its code should be something along the lines of:

local r = game.ReplicatedStorage.remote_event;
local my_tool = game.ReplicatedStorage.Tool;
r.OnServerEvent:connect(function(plr, info)
    if info == "Join" then
--just to be on the safe side i am adding a waitforchild incase the player's backpack does not exist yet, since they just joined the server.
        plr:WaitForChild("Backpack");
        my_tool:Clone().Parent = plr.Backpack;
    end
--when the player's character is changed is essentially when the player is respawned, because ROBLOX has to create a new character for the player.
    plr.Changed:connect(function(prop)
        if prop == "Character" then
            my_tool:Clone().Parent = plr.Backpack;
        end
    end)
end)

I will be referring to this script as 'main' from this point on.

So now that the basics of Filtering enabled are all out of the way, lets get down to analyzing the code inside of the local script of your Tool; change its code to:

local player = game.Players.LocalPlayer
local r = game.ReplicatedStorage.remote_event;

local attackanim = script:WaitForChild("SlashAnim2")

local tool = script.Parent
local damage = 30

local current_track;

local debounce = false;
local attacking = false
local attack_debounce = false;

--by the time a player activates a tool, their character, and humanoid will already be loaded in.
tool.Activated:connect(function()
    if not debounce then
        debounce = true;
        local hmd = player.Character:FindFirstChild("Humanoid");
        current_track = hmd:LoadAnimation(attackanim);
        attacking = true;
        current_track:Play();
        local event;
        event = current_track.Stopped:connect(function()
            attacking = false;
            wait(0.2);
            debounce = false;
            event:disconnect();
        end);
    end
end)

tool.Handle.Touched:connect(function(part)
    if not attack_debounce then
        attack_debounce = true;
        if attacking then
            local plr_hmd = part.Parent:FindFirstChild("Humanoid") or part.Parent.Parent:FindFirstChild("Humanoid"); --always take into account whether the tool hit an accessorie's Handle on the other player as well (i.e. part.Parent.Parent)
            if plr_hmd ~= nil then
                local plr_name = plr_hmd.Parent.Name;
                if player.Name ~= plr_name then
                    r:FireServer("Hit", plr_hmd.Parent, damage);
                end
            end
        end
        attack_debounce = false;
    end
end)

tool.Unequipped:connect(function()
    if current_track ~= nil then
        current_track:Stop();
        current_track:Destroy();
        current_track = nil;
    end
    attack_debounce = false;
    attacking = false;
    debounce = false;
end)

We are using the same remote event for Tool, as we did for our join script. So now we can go back and edit main's code to something more like this so that it can also handle whenever a player attacks another player:

local r = game.ReplicatedStorage.remote_event;
local my_tool = game.ReplicatedStorage.Tool;
r.OnServerEvent:connect(function(plr, ...)
    local inf_table = {...};
    if inf_table[1] == "Join" then
--just to be on the safe side i am adding a waitforchild incase the player's backpack does not exist yet, since they just joined the server.
        plr:WaitForChild("Backpack");
        my_tool:Clone().Parent = plr.Backpack;
    elseif inf_table[1] == "Hit" then
        if game.Players:GetPlayerFromCharacter(inf_table[2]) then
            inf_table[2].Humanoid:TakeDamage(inf_table[3]);
        end
    end
--when the player's character is changed is essentially when the player is respawned, because ROBLOX has to create a new character for the player.
    plr.Changed:connect(function(prop)
        if prop == "Character" then
            my_tool:Clone().Parent = plr.Backpack;
        end
    end)
end)

I am too tired to explain any more, if you are still having problems with it, send me details and I will see what I can do to help.

I hope this helps you.

0
Sorry it took me a while to answer, but this answer is a pretty long one. movsb 242 — 7y
0
@laczka You really seem to know what you're doing. Thanks! ~Loughdough Loughdough 291 — 7y
0
I am always glad to help. :) movsb 242 — 7y
Ad

Answer this question