Amount Counter Script

It seems pretty simple but im not sure if it is. I just want to make a counter to track how many times a Clickdetector has been clicked by an individual player. it will be used inside an NPC that will be destroyed and cloned, so it just needs to keep track of clicks per player temporarily

Im not exactly sure what code is needed to collect this data

i believe to do this i would have to have an intValue made within the NPC every time a player first clicks it, and then store each click somehow in that intValue, then when the mob reaches 0HP it will evaluate if the amount of clicks per player is 20% or greater.
Someone please let me know if that sounds about right or if there is a better way to do this.
Thank you so much!

I believe this is what you would need to accomplish that.
Here is the wiki you could also look at for help: ClickDetector

clickdetector.MouseClick:Connect(function (player)
    -- Track counts
end)

I have gotten this far, but i need to know how to keep track of every click made by multiple players. Here is a scenario:

an NPC has 100 clicks till it dies
i want to check if a player has clicked it at least 20 times
if one player clicks 90 times and a 2nd player clicks 10 times, i need a way to track both of these clicks and refer to them in a seperate script

this is the primary outcome i am looking for, i am just not sure how i would accomplish that

Well you can only send I think it’s 20 remoteEvents in a second per player(Correct me if I’m wrong).

Just make so that the clicks between the RemoteEvents firing is stored locally, and then send through all the clicks the player has done, since last RemoteEvent was fired.

Now on the server, just make a variable that is the sum of the total amount of clicks, and it updates each wave.

--Server
TotalClicks += IncomingClicks -- Current TotalClicks value + the amount each IncomingClicks has.

(Remotes could be fired each 1 second or so?)

This will ofc delay the NPC’s death with minimum 1 second, but you could always decrease the time between the remotes firing to 0.5s or so.

hmm i havnt used remote events much, im kinda aware of what they are, but im still very new to lua and roblox scripting. I will see how this works to the best of my ability

I’ve got a pretty simple solution here.

local counterList = {}

local clickDetector = --yourclickdetectorhere

clickDetector.MouseClick:Connect(function(player)
	if counterList[player] == nil then
		counterList[player] = {["Clicks"] = 0}
	end

	local playerIndex = counterList[player]

	if playerIndex ~= nil then
		playerIndex["Clicks"] += 1
	end

end)

Keep in mind that this is in a serverScript. Use remotes if it’s a local script

1 Like

here’s a quick one! :smiley:

--ClientScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ClicksRemote = ReplicatedStorage:WaitForChild("ClicksRemote")
local ClickSumInterval = ReplicatedStorage:WaitForChild("ClickSumInterval")
local Players = game:GetService("Players")
local Gui = script.Parent
local Button = Gui:WaitForChild("Button")
local Clicks = 0

Button.Activated:Connect(function()
	Clicks += Clicks
end)

ClicksRemote.OnClientEvent:Connect(function()
	Clicks = 0 --We reset clicks here, because server told us to! :C
end)

while task.wait(ClickSumInterval.Value) do
	if Clicks > 0 then
		ClicksRemote:FireServer(Clicks)
	end
end

Now for the server!

--ServerScript
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local ClicksRemote = ReplicatedStorage:WaitForChild("ClicksRemote")
local ClickSumInterval = ReplicatedStorage:WaitForChild("ClickSumInterval")
local TotalClicks = ReplicatedStorage:WaitForChild("TotalClicks")

local ClicksSentDebounce = {}

ClicksRemote.OnServerEvent:Connect(function(Player, Clicks)
	if not ClicksSentDebounce[Player] then -- Checks if player is in our debounce table! :D
		ClicksSentDebounce[Player] = true -- Sets player into our debounce table!
		TotalClicks.Value += Clicks
		ClicksRemote:FireClient(Player) -- Now remove players current clicks!
		task.wait(ClickSumInterval)
		ClicksSentDebounce[Player] = nil -- Removes player from debounce table :D
	end
end

Someone please correct me if anything is wrong! :smiley:

1 Like

This seems to do exactly what I want, but if you dont mind explaining/showing, how would i call this number in another script?

Sorry! didn’t have focus enough to see you wanted it to be through a clickdetector. If you by any means want it through a GUI button, then you have my method in stock! :smiley:

thank you for your input still! i will make sure to look back on that if it ever comes up.

I assume you have some sort of spawn system for these npcs? Well if need be, create a bindableFunction (server to server version of a remoteFunction).

When you need the information, invoke the script with the info, and have that script then send back the data

1 Like

so i actually think it will work by putting this directly into my NPC script, im working on that now and will update this message with what happens

Update:
So this is the script i am currently working with now after adding the table you suggested

local HP = script.parent.HP.Value
local mob = script.Parent.Torso

local StartPos = script.Parent.StartPos
local clickDetector = script.Parent.ClickDetector
local healthNumber = mob.healthbargui.barbackground.healthamount
local healthBar = mob.healthbargui.barbackground.bar
local healthValue = Instance.new("IntValue")
healthValue.Value = HP --Monster HP

healthNumber.Text = HP

print("--SPAWNED--")

healthValue:GetPropertyChangedSignal("Value"):Connect(function()
	healthNumber.Text = healthValue.Value
	print(healthNumber.Text, healthValue.Value)
end)




local counterList = {}

local clickDetector = script.Parent.ClickDetector --yourclickdetectorhere

clickDetector.MouseClick:Connect(function(player)
	if counterList[player] == nil then
		counterList[player] = {["Clicks"] = 0}
	end

	local playerIndex = counterList[player]

	if playerIndex ~= nil then
		playerIndex["Clicks"] += 1
	end

end)


function onMouseClick(player)
	-- Subtract healthValue by Damage Amount and Change the healhBar Size
	local damage = player.damage.Value
	local actualDamage = counterList * damage --This is where the error is
	healthValue.Value -= damage
	healthBar.Size -= UDim2.new(damage/HP, 0, 0, 0) --damage/whatever the monster HP is
	if healthValue.Value <= 0 then
		clickDetector.MaxActivationDistance = UDim2.new(0)
		healthNumber.Text = "0"
		if actualDamage >= HP * 0.2 then
			player.leaderstats.Coins.Value += math.random(script.Parent.CoinLow.Value,script.Parent.CoinHigh.Value)
		end
		script.Parent.Humanoid.Health = 0
	end
end

clickDetector.MouseClick:Connect(onMouseClick)

I am getting the error “Attempt to preform arithmetic (mul) on table and number”
is there a way i can pass through the last number, per player, to calculate the overall damage?

1 Like

i have put the code in as shown in my post above. I just dont know how to call the player and the numbers seperatly

like specifically how would i call a player and their highest number in the counterList this is what i need to know

very well. Give me a few minutes and I’ll see what I can come up with.

1 Like
local HP = script.parent.HP.Value
local mob = script.Parent.Torso

local StartPos = script.Parent.StartPos
local clickDetector = script.Parent.ClickDetector
local healthNumber = mob.healthbargui.barbackground.healthamount
local healthBar = mob.healthbargui.barbackground.bar
local healthValue = Instance.new("IntValue")
healthValue.Value = HP --Monster HP

healthNumber.Text = HP

print("--SPAWNED--")

healthValue:GetPropertyChangedSignal("Value"):Connect(function()
	healthNumber.Text = healthValue.Value
	print(healthNumber.Text, healthValue.Value)
end)


local counterList = {}

local clickDetector = script.Parent.ClickDetector --yourclickdetectorhere

local function increment(player)
	if counterList[player] == nil then
		counterList[player] = {["Clicks"] = 0}
	end

	local playerIndex = counterList[player]

	if playerIndex ~= nil then
		playerIndex["Clicks"] += 1
	end
	
	return playerIndex["Clicks"]
end

local function getValue(player)
	local valToReturn = 0
	
	if counterList[player] ~= nil then
		valToReturn = counterList[player]["Clicks"]
	end
	
	return valToReturn
end

function onMouseClick(player)
	increment(player)
	local myClicks = getValue(player)
	
	local damage = player.damage.Value
	local actualDamage = myClicks * damage --This is where the error is
	healthValue.Value -= damage
	healthBar.Size -= UDim2.new(damage/HP, 0, 0, 0) --damage/whatever the monster HP is
	
	if healthValue.Value <= 0 then
		clickDetector.MaxActivationDistance = UDim2.new(0)
		healthNumber.Text = "0"
		if actualDamage >= HP * 0.2 then
			player.leaderstats.Coins.Value += math.random(script.Parent.CoinLow.Value,script.Parent.CoinHigh.Value)
		end
		script.Parent.Humanoid.Health = 0
	end
	
end

clickDetector.MouseClick:Connect(onMouseClick)

Have a go of this. Is this what you meant? @concon98765

1 Like

Double checking right now, it seems to work mostly, but if 2 players were to do 50% damage each, it is still only ending up with the one who gets the final killing click getting the coin reward

I think it is coming down to this block of code here

if actualDamage >= HP * 0.2 then
			player.leaderstats.Coins.Value += math.random(script.Parent.CoinLow.Value,script.Parent.CoinHigh.Value)
		end

somehow everyone with over 20% damage needs to be able to get the coin reward

how would you phrase:
if actualDamage of player >= HP * 0.2 then

oooohh ok. Give me another 5 minutes. Easy solution

1 Like

Ok, so I’ve linked the died event to the humanoid. This will loop through every player, and check if they have done enough damage. I’ve moved a few things around, too.

--Services{
local playerService = game:GetService("Players")
--}

--LocalVars{
local HP = script.Parent.HP.Value
local mob = script.Parent.Torso

local StartPos = script.Parent.StartPos
local clickDetector = script.Parent:FindFirstChildOfClass("ClickDetector")
local healthNumber = mob.healthbargui.barbackground.healthamount
local healthBar = mob.healthbargui.barbackground.bar
local healthValue = Instance.new("IntValue")
healthValue.Value = HP --Monster HP
healthNumber.Text = HP
--}

--Tables{
local counterList = {}
--}

print("--SPAWNED--")



healthValue:GetPropertyChangedSignal("Value"):Connect(function()
	healthNumber.Text = healthValue.Value
	if healthValue.Value == 0 then
		script.Parent.Humanoid.Health = 0
	end
end)

local function increment(player)
	if counterList[player] == nil then
		counterList[player] = {["Clicks"] = 0}
	end

	local playerIndex = counterList[player]

	if playerIndex ~= nil then
		playerIndex["Clicks"] += 1
	end
	
	return playerIndex["Clicks"]
end

local function getValue(player)
	local valToReturn = 0
	
	if counterList[player] ~= nil then
		valToReturn = counterList[player]["Clicks"]
	end
	
	return valToReturn
end

script.Parent.Humanoid.Died:Connect(function()
	clickDetector.MaxActivationDistance = 0
	healthNumber.Text = "0"

	for _, player in pairs(playerService:GetPlayers()) do
		local damage = player.damage.Value
		local myClicks = getValue(player)
		
		if myClicks <= 0 then continue end
		
		local actualDamage = myClicks * damage
		
		if actualDamage >= HP * 0.2 then
			player.leaderstats.Coins.Value += math.random(script.Parent.CoinLow.Value,script.Parent.CoinHigh.Value)
		end
	end
end)

function onMouseClick(player)
	increment(player)
	local myClicks = getValue(player)
	
	local damage = player.damage.Value
	local actualDamage = myClicks * damage --This is where the error is
	healthValue.Value -= damage
	healthBar.Size -= UDim2.new(damage/HP, 0, 0, 0) --damage/whatever the monster HP is
end

clickDetector.MouseClick:Connect(onMouseClick)
1 Like

it works absolutly flawlessly, If you can i would love a bit of an explination on what you changed to make it work. I do understand a good chunk here, and will definetly be looking at how your changes work. But overall thank you so so soo much this will make the game so much more balanced!