Players receiving more instead of the usual

Hello again robloxians!
Well, so i’m making a game where you can use swords to defeat enemys and gain more gold, i’m having a problem with my rewarding script, when the players kills an enemy, it not stops rewarding the player until the enemy respawns.

Here is my script fellas!

local PlayerService = game:GetService("Players")

local Tool = script.Parent.Parent
local Handle = Tool:WaitForChild("Handle")

local SwordStatus = script.Parent:WaitForChild("SwordStatus")
local StatusModule = require(SwordStatus)

Handle.Touched:Connect(function(Hit)
	
	local Humanoid = Hit.Parent:WaitForChild(StatusModule.HumanoidToDamage)
	local Player = PlayerService:GetPlayerFromCharacter(Tool.Parent)
	
		Humanoid.Died:Connect(function()
			Player.GoldCurrency.Value = Player.GoldCurrency.Value + 100
		end)
end)

AQ

1. Why you don’t use a tag system?

  • Well, i prefer already use a reward system into my sword, it looks more practical than using a tag system.

2. Did you tried using the reward system in the enemy?

  • Actually, the unique way i thinked for that was using a tag system. So the first question answers the second question.

3. Did you looked into youtube or in devforum?

  • I didn’t saw someone with the same problem as me in the devforum. While in youtube, major of the videos uses the tag system, or uses a reward system inside the own currency script, some don’t even explain the vídeo and just put a toolbox kill 4 cash in the video. So YouTube ins’t a option.
5 Likes

I think that if the player dies, and the sword touching the humanoid after it dies, they get gold because if the player dies, it will always check if the player died or not, but its recommended to use a tag system to prevent multiple or duplicated gold currency.

1 Like

So when the enemy dies, you get more gold than usual? That’s probably because you are creating more Humanoid.Died connections every single time you hit the enemy. Why don’t you just use an if statement checking if the enemy is dead after they get hit?

Here’s what I mean by that:

local PlayerService = game:GetService("Players")

local Tool = script.Parent.Parent
local Handle = Tool:WaitForChild("Handle")

local SwordStatus = script.Parent:WaitForChild("SwordStatus")
local StatusModule = require(SwordStatus)

Handle.Touched:Connect(function(Hit)
	if(Humanoid.Health <= 0) then --Don't run the script if the enemy is already dead
		return
	end

	local Humanoid = Hit.Parent:WaitForChild(StatusModule.HumanoidToDamage)
	local Player = PlayerService:GetPlayerFromCharacter(Tool.Parent)
	
	if(Humanoid.Health <= 0) then
		Player.GoldCurrency.Value = Player.GoldCurrency.Value + 100
	end
end)
1 Like

Actually, the script is for killing an NPC/Enemy, and Humanoid.Died don’t works only once? if not, then could i create a bool value inside the enemy and use a if Humanoid.Health <= 0 then do deactivate that bool value?

1 Like

Yes, it was to reward only 10 (sorry to put in the script 100, but it was just a test) gold, but when the enemy dies, it rewards 10k, it just don’t rewards more cause i used math.clamp to prevent negative values in the currency.

I already tried a if statment to:

	if(Humanoid.Health <= 0) then
		Player.GoldCurrency.Value = Player.GoldCurrency.Value + 100
	end

but didn’t tried:

if(Humanoid.Health <= 0) then --Don't run the script if the enemy is already dead
		return
	end

Disconnect the nested function

Add a debounce variable that starts as false. If the debounce is false when the enemy dies, set the debounce to true, run the rest of the script, and only set it to false when the enemy respawns (using the CharacterAdded function)

local PlayerService = game:GetService("Players")

local Tool = script.Parent.Parent
local Handle = Tool:WaitForChild("Handle")

local SwordStatus = script.Parent:WaitForChild("SwordStatus")
local StatusModule = require(SwordStatus)

local debounce = false
Handle.Touched:Connect(function(Hit)

	local Humanoid = Hit.Parent:WaitForChild(StatusModule.HumanoidToDamage)
	local Player = PlayerService:GetPlayerFromCharacter(Tool.Parent)

	Humanoid.Died:Connect(function()
		if debounce then
			return
		else
			debounce = true
			Player.GoldCurrency.Value = Player.GoldCurrency.Value + 100
		end
		
		PlayerService:GetPlayerFromCharacter(Humanoid.Parent).CharacterAdded:Connect(function()
			debounce = false
		end)
	end)
end)
1 Like

Now the player gets rewarded even if the enemy didn’t died.

1 Like

Or you could, yknow, use Humanoid.Died:Once()

1 Like

Reminding you that Part.Touched fires for every part it touches, including the arm, the torso, the head, the accessories, etc. While I wouldn’t recommend allowing the sword to manage the rewards (since it’s only meant to damage enemies), I’ll still provide my answer.

Keep a reference of the humanoid it finds from the part it touches, and if the sword detects a humanoid, check if it is already referenced:

local PlayerService = game:GetService("Players")

local Tool = script.Parent.Parent
local Handle = Tool:WaitForChild("Handle")

local SwordStatus = script.Parent:WaitForChild("SwordStatus")
local StatusModule = require(SwordStatus)

local EnemyHumanoids = {}

Handle.Touched:Connect(function(Hit)
	local Humanoid = Hit.Parent:WaitForChild(StatusModule.HumanoidToDamage)
	
	if (EnemyHumanoids[Humanoid] == true) then
		-- If it finds a humanoid inside this table, ignore it.
		return
	elseif Humanoid:GetState(Enum.HumanoidStateType.Dead) then
		-- Don't do anything to a dead humanoid.
		return
	end
	
	EnemyHumanoids[Humanoid] = true -- Reference the humanoid.
	
	local Player = PlayerService:GetPlayerFromCharacter(Tool.Parent)
	
	-- Use Once instead of Connect to only listen to the event just once.
	Humanoid.Died:Once(function()
		Player.GoldCurrency.Value = Player.GoldCurrency.Value + 100
		
		EnemyHumanoids[Humanoid] = false -- Deference the humanoid since it is dead.
	end)
end)
2 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.