I have a melee weapon that swings and attacks other players with a remote event and a 1 in 5 chance to do a critical hit, but I don’t know how to make the critical hit deal more damage in the server script. I was thinking adding a value and changing it with local script but it wont be server sided and I read about remote events in the developer hub but there was not anything that could fix the issue. How can I do this?
Local script
local tool = script.Parent
local hit = script:WaitForChild("Hit")
local critical = script:WaitForChild('Critical')
local player = game.Players.LocalPlayer
local char = player.Character
local humanoid = char:WaitForChild("Humanoid")
local mouse = player:GetMouse()
local hittrack = humanoid:LoadAnimation(hit)
local criticaltrack = humanoid:LoadAnimation(critical)
local meleeEvent = script.Parent:WaitForChild("MeleeEvent")
local meleeing = false
local canMelee = true
local equipped = false
tool.Equipped:Connect(function()
equipped = true
end)
tool.Unequipped:Connect(function()
equipped = false
end)
mouse.Button1Down:Connect(function()
meleeing = true
while equipped and canMelee and meleeing do
local randomChance = math.random(1, 5)
canMelee = false
meleeEvent:FireServer()
if randomChance == 5 then
criticaltrack:Play()
criticaltrack.Stopped:Wait()
canMelee = true
else
hittrack:Play()
hittrack.Stopped:Wait()
canMelee = true
end
mouse.Button1Up:Connect(function()
meleeing = false
end)
end
end)
Server script
local tool = script.Parent
local handle = tool:WaitForChild('Handle')
local swingSound = handle:WaitForChild('SwingSound')
local hitSound = handle:WaitForChild('HitSound')
local meleeEvent = tool:WaitForChild("MeleeEvent")
local damageamount = 20
local critamount = 40
local canHit = true
local function onTouch(otherPart)
local humanoid = otherPart.Parent:FindFirstChildOfClass("Humanoid")
if humanoid and canHit and humanoid.Health > 0 then
canHit = false
hitSound:Play()
humanoid:TakeDamage(damageamount)
swingSound.Ended:Wait()
canHit = true
end
end
meleeEvent.OnServerEvent:Connect(function()
script.Parent.ShovelHandle.Trail.Enabled = true
swingSound:Play()
handle.Touched:Connect(onTouch)
swingSound.Ended:Wait()
script.Parent.ShovelHandle.Trail.Enabled = false
end)
Do the math.random chance on the server instead of on the client, you cannot trust the client. Also make sure to disconnect your touch event as your code currently has a memory leak in it - alternatively connect the touch event and when the event is fired change CanHits value.
Animations can be played on the server as well as the client. OnServerEvent gives you the player that fired the event as it’s first parameter. OnServerEvent:Connect(function(playerWhoFiredEvent)
In your use case I recommend disconnecting your touch event when the event is fired and when a valid target is hit.
local c = nil -- this is where we will store your connection
local function swingSword(otherPart)
-- your hit detection code here
if c then
c:Disconnect() -- disconnect the event, it will not be fired after this until reconnected
c = nil
end
end
event.OnServerEvent:Connect(function(plr)
if c then c:Disconnect() c = nil end -- if for some reason the last swing failed to disconnect or did not disconnect in time
c = sword.Touched:Connect(swingSword)
end)
you can generate a random number between 1 & 10, if the num is between 1-5 its a normal and if 6-10 its a crit. whenever, the player clicks the mouse you can generate it and store it in a variable, then you can send that variable to the server in the FireServer(–arguments)
Remote events take in anything you want to send, but there are some exceptions but you really dont wanna focus on those.
client script:
local randomInt = math.random(1, 10)
Remote:FireServer(randomInt)
server script:
Remote.OnServerEvent:Connect(function(player, all of the stuff here you sent from the client.)
--player who fired the event will always be the first param in the remote event,
If you are playing the animation inside the swordSwing function you will need to pass the player instance into that function.
local function swordSwing(plr, otherPart)
end
-- inside remote event code
c = Sword.Touched:Connect(function(hit)
swordSwing(plr, hit)
end)
You should never ever trust the client with information such as player data or damage as exploiters can make these values whatever they want (ie: they can make your sword do a critical hit every time)
Local scripts cannot be edited, however exploiters can fire events from their client and they can change what is passed to the server. Exploiters usually disable your client code and replace it with their own.
eg:
Your code:
UpdateCash:FireServer(50) -- your client code wants to give your player 50 cash
Exploiter code:
UpdateCash:FireServer(999999) -- exploiter code wants to give them 999999 cash
You should never ever trust the client when it comes to giving cash, dealing damage, or anything similar as it can be manipulated and usually will be.