Reward on Damage Dealt to Enemy Humanoid

Hey, so I am wanting to make a Reward System so when a Player does X amount of damage, they get rewarded when the Enemy dies. Thing is, I have a script where I get the Damage Dealt, but the problem is, the Damage isn’t separate between the Players. It is all added up between them into one Variable. Also, I’d like for it to add up per EnemyHumanoid. What I mean by that is, let’s say they are attacking Two Enemies, I would like for each Humanoid to have separate ‘DamageDealt’ variables. Here is what I have so far for DamageDealt being found.

local curHP = enemyHumanoid.Health
							
enemyHumanoid.HealthChanged:Connect(function(newHP)
     if curHP < newHP then return end
     local difference = math.abs(curHP-newHP)
					
     curHP = newHP
								
     damageDealt = math.abs(damageDealt + difference)
     print(damageDealt)
end)

This is in a ServerScript within a RemoteEvent. I will post the full code below. What this does is when a Players health is Changed, it adds to the Damage Dealt. This actually adds up really weirdly… It can start from going up by 1s to going up by 100s in a matter of a few Sword Swings… This is obviously not the best way to do this, so how would I go about it?

Full Code:

local replicatedStorage = game:GetService("ReplicatedStorage")
local katanaEquip = replicatedStorage:WaitForChild("AbilityEvents"):WaitForChild("KatanaEquip")
local katanaAttack = replicatedStorage:WaitForChild("AbilityEvents"):WaitForChild("KatanaAttack")
local tweenService = game:GetService("TweenService")


local debris = game:GetService("Debris")

local animations = script:WaitForChild("Animations")
local enemyAnims = script:WaitForChild("EnemyAnimations")
local meshes = script:WaitForChild("Meshes")
local particles = script:WaitForChild("Particles")

local animsTable = 
	{
		animations:WaitForChild("RightSlash"),
		animations:WaitForChild("LeftSlash"),
		animations:WaitForChild("RightSlash"),
		animations:WaitForChild("LeftSlash"),
	}

local enemyAnimsTable =
	{
		enemyAnims:WaitForChild("Stunned"),
		enemyAnims:WaitForChild("Stunned"),
		enemyAnims:WaitForChild("Stunned"),
		enemyAnims:WaitForChild("Fling"),
		enemyAnims:WaitForChild("BlockBreak"),
	}

local damageDealt = 0

coroutine.wrap(function()
	while true do
		wait(1)
		damage = math.random(1, 15)
	end
end)()

katanaAttack.OnServerEvent:Connect(function(player, isActive, count, comboDebounce)
	local character = player.Character
	local humanoid = character:WaitForChild("Humanoid")
	local humRootPart = character:WaitForChild("HumanoidRootPart")
	
	
	local folder = character:WaitForChild(player.Name.."'s Katana")
	local katanaMesh = folder:WaitForChild("Katana")
	
	if isActive == true and comboDebounce == false then
		
		local lightAttack = humanoid:LoadAnimation(animsTable[count])
		lightAttack:Play()
		
		local swingSFX = Instance.new("Sound")
		swingSFX.SoundId = "rbxassetid://7171591581"
		swingSFX.PlayOnRemove = true
		swingSFX.Parent = folder
		swingSFX:Destroy()

		
		local hitbox = meshes:WaitForChild("Hitbox"):Clone()
		local hitboxWeld = meshes:WaitForChild("HitboxWeld"):Clone()
		hitbox.Position = hitboxWeld.Position
		hitboxWeld.Position = katanaMesh.Position
		hitbox.Parent = folder
		hitboxWeld.Parent = katanaMesh
		debris:AddItem(hitbox, 0.375)

		local motor2 = Instance.new('Motor6D')
		motor2.Part0 = katanaMesh -- What you want to Connect to
		motor2.Part1 = hitboxWeld -- What you are wanting to Connect
		--motor2.C0 = 
		motor2.Parent = katanaMesh

		local motor3 = Instance.new('Motor6D')
		motor3.Part0 = hitboxWeld -- What you want to Connect to
		motor3.Part1 = hitbox -- What you are wanting to Connect
		motor2.C0 = CFrame.Angles(0, 0, math.rad(90))
		motor3.Parent = hitboxWeld

		hitbox.Touched:Connect(function(hit)
			if hit:IsA("BasePart") then
				if not hit:IsDescendantOf(character) then
					local enemyHumanoid = hit.Parent:FindFirstChild("Humanoid")
					local enemyHumRootPart = hit.Parent:FindFirstChild("HumanoidRootPart")
					if enemyHumanoid and enemyHumRootPart then
						local blockAction = enemyHumanoid:FindFirstChild("BlockAction")
						if blockAction then
							--//Counts towards breaking

							local hitSFX = Instance.new("Sound")
							hitSFX.SoundId = "rbxassetid://7171761940"
							hitSFX.PlayOnRemove = true
							hitSFX.Parent = hitbox
							hitSFX:Destroy()

							hitbox:Destroy()

							if blockAction.Value > 0 then
								blockAction.Value = blockAction.Value - 1
								if blockAction.Value == 0 then

									local blockBreak = enemyHumanoid:LoadAnimation(enemyAnimsTable[5])
									blockBreak:Play()

									blockAction:Destroy()

									spawn(function()


										local enemy = game:GetService("Players"):GetPlayerFromCharacter(enemyHumanoid.Parent)
										if enemy then
											local backpack = enemy:FindFirstChild("Backpack")
											if backpack then
												local CombatSystem = backpack:FindFirstChild("CombatSystem")
												if CombatSystem then
													local isBroken = CombatSystem:FindFirstChild("isBroken")
													if isBroken then
														isBroken.Value = true
														--/Stun
														wait(3)
														isBroken.Value = false
													end
												end
											end

										end
									end)

									local effects = Instance.new("Folder", workspace)
									effects.Name = player.Name.." Effects"
									debris:AddItem(effects,0.75)

									local breakParticle = meshes:WaitForChild("BlockBreakParticle"):Clone()
									breakParticle.CFrame = enemyHumRootPart.CFrame + Vector3.new(0,0.75,-1)
									breakParticle.Orientation = breakParticle.Orientation + Vector3.new(90,0,0)
									breakParticle.Parent = effects

									breakParticle.Attachment.Spark:Emit(1)
									breakParticle.Attachment.InnerRing:Emit(1)
									breakParticle.Attachment.OuterRing:Emit(1)

								end
							end
						else
							--/Do damage since they aren't blocking
							local hitSFX = Instance.new("Sound")
							hitSFX.SoundId = "rbxassetid://7171761940"
							hitSFX.PlayOnRemove = true
							hitSFX.Parent = hitbox
							hitSFX:Destroy()

							hitbox:Destroy()

							local critChance = math.round(100/20)

							if math.random(critChance) == 1 then
								enemyHumanoid:TakeDamage(damage*2)
							else
								enemyHumanoid:TakeDamage(damage)
							end

							local curHP = enemyHumanoid.Health
							
							enemyHumanoid.HealthChanged:Connect(function(newHP)
								if curHP < newHP then return end
								local difference = math.abs(curHP-newHP)
					
								curHP = newHP
								
								damageDealt = math.abs(damageDealt + difference)
								print(damageDealt)
							end)
							
							local react = enemyHumanoid:LoadAnimation(enemyAnimsTable[1])
							react:Play()


							if count == 4 then						
								local goal = {}
								goal.CFrame = CFrame.new((humRootPart.CFrame * Vector3.new(0,5,-15)), humRootPart.CFrame.p)
								local info = TweenInfo.new(0.5, Enum.EasingStyle.Linear, Enum.EasingDirection.Out)
								local tween = tweenService:Create(enemyHumRootPart,info,goal)
								tween:Play()
							end


						end
					end
				end
			end
		end)
	end

	katanaAttack:FireClient(player)
end)

Thanks for your help in the long run!

Alright, so, listen closely!

You require:

  • A creator string value

So, whenever you hit that player with the melee weapon or whatever it is, you do a check wether the opponent’s health is over 0. If it is not then you will have to set the creator string value’s value to the LocalPlayer’s name.

Now, in that LocalScript, whenever the creator string value changes you basically invoke it.

local Player = game.Players.LocalPlayer
local Value = Instance.new("StringValue")

Value.Changed:Connect(function(NewVal)
   if game.Players:FindFirstChild(NewVal) then
        print(Player.Name.." has killed "..NewValue.."!")
   end
end)

What do you mean by ‘Creator String Value’? Also, the current Script I have is a Server Script. Should I be putting the Value.Changed func into the Local Script where the Remote Event is firing from?

Yes, the Value.Changed function should be put into the LocalScript. By creator string values I mean StringValues which have their values set as the enemy’s name. Once that value changes, it will fire the Value.Changed function and in that function you can do whatever you want. Wether it’s clientsided or serversided, you can fire a RemoteEvent for example with the LocalPlayer’s name and the CreatorValue.Value.

Oh ok… So basically ‘NewVal’ is the name of a Player and it’s trying to find said Player. Thing is, my game is PVE based. If a player kills and Enemy AI, I’d like for it to reward them if they did a certain amount of damage. So, I would do the same thing but instead of game.Players:FindFirstChild(NewVal), I would FindFirstChild in the Folder containing the AI, correct?

Also, am I supposed to put a line of code that Changes said Value when the player attacks?