new to scripting and was wondering how you can make it so that upon damaging an npc you get money depending on how much damage you deal to it
ive tried looking in the toolbox and on youtube and on devforums but most of them only give you money when you kill the npc, not damage it
i would like to have it so that it would give the player money when damaging it to avoid other players stealing kills and getting more money than the other player
i am also using ACS 2.0.1 for my gun system
please read my whole post!!
i would prefer if it gave cash according to how much you damage the npc and not getting money upon killing it
I think that when the humanoid is damaged (I think that there is an event for this?) you would get the damage, convert it to money and then change the leaderboard stat with this number?
I believe the event is HealthChanged I may be wrong
So I guess you would set the health before it was changed, and when it is changed (Using HealthChanged Humanoid.HealthChanged) get the value of that change (so that you can preform and operation on this value, such as adding it to the leaderboard), and then send that value to the leaderboard.
This is sudo code, and not actual code.
You can add a multiplier based on the dmg to your cash. I’ll assume you know how to add money. Here’s an example to the equation.
local dmg = 50 --how much dmg the player did I believe you can check the amount of dmg via HealthChanged on the humanoid of the npc you're attacking.
local multiplier = 1.5 --The multiplier. You would do dmg * multiplier to get the amount of cash you get.
cash += dmg * multiplier --adding to the current cash leaderstat
You would put this probably as a local scripts in player starter scripts or something- don’t really know much about leaderstats.
Yeah he/her could do it that way most likely
Next time, try to provide some code of what you’ve already done to make it easier for others to add or fix upon what you’ve made (it makes for a better learning experience too!).
For example, in this code, I have no idea HOW you want a certain player to be rewarded. I don’t know if you’ve tagged the player instance or set up object values pointing to the player who did the last hit.
Anyways, I’ll just set up the basics of what this thread has come up with for you so you can build upon it or ask about it later…
local players = game:GetService("Players")
-- your values here. these won't work until you hook them up appropriately for your game.
local humanoid
local humanoidRootPart
local cashPerHit = 10
local cash
local function findNearestPlayer()
-- put characters in a table array so we can sort through it later...
local characters = {}
-- loop through each player in the server and check if their characters exist...
for i, playerInstance in ipairs(players:GetChildren()) do
local thisPlayerCharacter = playerInstance.Character
if thisPlayerCharacter then
-- put this character in the table
table.insert(characters, thisPlayerCharacter)
end
end
-- check to see if the table has at least one character inside the array..
-- if there is one, sort the list
if #characters > 0 then
if #characters > 1 then
-- only sort if there is more than one target otherwise you're sorting for no reason...
table.sort(characters, function(a, b)
local function distance(givenChar)
-- in this case, Magnitude is the distance in units between two points
return (humanoidRootPart.Position - givenChar.Position).Magnitude
end
-- sort from smallest to greatest
return distance(a) < distance(b)
end)
end
-- closest char should be at the first
return characters[1]
else
-- return nothing since table is empty
return nil
end
end
-- HealthChanged event suggested by ProgrammersRightHand
humanoid.HealthChanged:Connect(function()
local closestChar = findNearestPlayer()
-- if player character was found...
if closestChar ~= nil then
--convert the character back into a player instance to change cash value prolly
local targetPlayer = players:GetPlayerFromCharacter(closestChar)
-- change the cash value
targetPlayer.Cash += cashPerHit
end
end)
But for real, please put any code that you have done that you think can help us help you.
sorry for not providing any code
heres the script for the cash when killing an npc:
function PwntX_X()
local tag = Humanoid:findFirstChild("creator")
if tag ~= nil then
if tag.Value ~= nil then
local Leaderstats = tag.Value:findFirstChild("leaderstats")
if Leaderstats ~= nil then
Leaderstats.Cash.Value = Leaderstats.Cash.Value + script.Parent.addedMoney.Value
wait(0.1)
script:remove()
end
end
end
end
Humanoid.Died:connect(PwntX_X)
and heres the cash:
local folder = Instance.new("Folder", plr)
folder.Name = "leaderstats"
local cash = Instance.new("IntValue", folder)
cash.Name = "Cash"
cash.Value = 0
end)
game:GetService('Players').PlayerAdded:Connect(function(player)
player.CharacterAdded:Connect(function(character)
character:WaitForChild("Humanoid").Died:Connect(function()
if player.leaderstats.Cash.Value > 0 then
wait(1)
player.leaderstats.Cash.Value = 0
player.PlayerGui.Death.Message.Visible = false
player.PlayerGui.Death.Message.Text = ''
wait(1)
player.PlayerGui.Death.Message.Visible = false
end
end)
end)
end)
im new to scripting, please try to provide clear instructions on how to set it up if you have a solution
Thank you for sharing your code.
Since you’ve tagged them with an object value (I think), we just have to copy your PwntX_X() function and change it up a bit so it doesn’t destroy the script as soon as it gets damaged.
I made it so you can slap this code into the script that has PwntX_X() in it
local function onDamage()
local tag = Humanoid:findFirstChild("creator")
if tag ~= nil and tag.Value ~= nil then
local Leaderstats = tag.Value:findFirstChild("leaderstats")
if Leaderstats ~= nil then
Leaderstats.Cash.Value = Leaderstats.Cash.Value + script.Parent.addedMoney.Value
end
end
end
-- add HealthChanged event
Humanoid.HealthChanged:Connect(onDamage)
Note that these events might overlap each other because the Died and HealthChanged event will both fire at the same time when the humanoid dies, so you’ll probably want to add a check to make sure the humanoid is alive before running the code in onDamage().
is there any way to make it so that the amount of money given to the player be the amount of the damage the player deals to the npc?
Yes there is.
https://developer.roblox.com/en-us/api-reference/event/Humanoid/HealthChanged
What you should do is to create a dictionary and add any new NPCs to it along with their current health.
Then when the healthchanged event fires, you get the previous current health stored in the table, as well as the value that the event returns (the new health). Subtract the difference and you have the change in health which you can convert to cash amount.
Then update the dictionary for the NPC with the new health.
can you show me an example of how to do this with my current code? thanks
Would be difficult to do as youve not provided the code around how your NPCs are created. But broadly:
Create a blank array in the server script which creates your npcs:
Local npcHealth = {}
At the point your server script creates an Npc, get the NPC humanoid and:
npcHealth[humanoid] = humanoid.Health
Then in your event:
humanoid.HealthChanged:Connect(function(newhealth)
local currentHealth = npcHealth[humanoid]
local change = math.abs(currentHealth - newhealth)
-- Insert your code to calculate money based on the change in health
npcHealth[humanoid] = newhealth
end)
Bear in mind im writing this on a mobile so the syntax and formatting might not accurate. Nut this should be enough for you to adaprt for your code.
Going off of what @ArcherThesu suggested, I would recommend adding money inside the server code of your guns. As it deals damage, add money to the player based on how much damage has been dealt. I can’t provide an exact solution since no code was provided, but here is an example:
local MoneyMultiplier = 2 -- (this can obviously be changed)
--Damage
NPC_humanoid:TakeDamage(damageToDeal) -- lets say damageToDeal is 50 in this case
Player.Money.Value += (damageToDeal * MoneyMultiplier) -- 50x2=100 cash would be added
This example assumes you use an IntValue inside the player, but adjust it accordingly.
Hope this helps a bit
the npc is actually an AI free model, i changed mine a little but that shouldnt affect anything
Marine AI IV - Roblox (ignore the vehicle i dont use it)
as stated in the original post im using ACS 2.0.1 which is a free model gun engine
unfortunately the entire system is complex and the guns themselves only have the values for how much damage a gun does but the code which makes it so that these values are how much damage the gun does is in a separate script which is not in the gun itself
If the gun’s damage is controlled by a separate script, edit that one, otherwise if the actual damage is controlled by each gun individually, you’ll have to add it to every gun, which would be tedious (but possible). It may be worth switching gun systems or learning how to make one yourself, which could take time but would eventually pay off.
Unfortunately, free models have their limitations and can be harder to edit than if you made it yourself.
In the same script as the PwntX_X(), add a variable that stores the past health of the humanoid.
We’re gonna use it to calculate the damage percentage that the last player hit just did, though it may not be performant or accurate if you’re using a bunch of guns with high firerates.
-- I'm assuming this is the total amount of gold you want reward...
local totalCashReward = script.Parent.addedMoney.Value
-- this is to calculate the damage percentage in onDamage()
local pastHp = Humanoid.Health
local function onDamage()
local currentHp = Humanoid.Health
local damagePercentage = currentHp / pastHp
-- if the damagePercentage is over 100%, that means the humanoid has healed instead of taking damage
-- we return because we're only rewarding players for damaging npcs, not healing them
if damagePercentage > 1 then return end
-- update the pastHp for the next onDamage() call
pastHp = currentHp
local tag = Humanoid:findFirstChild("creator")
if tag ~= nil and tag.Value ~= nil then
local Leaderstats = tag.Value:findFirstChild("leaderstats")
if Leaderstats ~= nil then
-- scale reward amount with the damage percentage...
local thisReward = totalCashReward * damagePercentage
Leaderstats.Cash.Value = Leaderstats.Cash.Value + thisReward
end
end
end
-- add HealthChanged event
Humanoid.HealthChanged:Connect(onDamage)
I haven’t stressed tested this to see how well it would do against multiple machine guns but this should be a good starting point.
You can also do what @fireustuk and @pjhinthehouse said. Their methods take a lot more work, but it is better in the long run when making a big game.