If multiple NumberValues found in GetDescendants(), Value is returning 0

Hi there, I am trying to make a sell button where it detects all the items inside of a certain model. Problem is, if it detects more than 1 “chest” then it returns the chest’s value as 0. It functions correctly if there is only 1 chest inside of the model. I would like it to give the player the amount of money that each chest is worth when it detects several of them inside of the model.

The chests are located inside of the WeldedPart brick in the models (They are welded and parented to WeldedPart when a player interacts with a ProximityPrompt):
image

button.Triggered:Connect(function(player)
	print("Triggered button")
	local plrStats = PlayerMoney:FindFirstChild(player.Name)
	local boat = workspace:FindFirstChild(player.Name.."'s Boat")
	
	if boat then
		local distance = player:DistanceFromCharacter(boat.PrimaryPart.CFrame.Position)
		print("Boat exists")
		print(distance)
		
		if distance <= 30 then
			local findChests = boat:GetDescendants()
			for _, chest in pairs(findChests) do
				if chest.Name == "Price" then -- Price is a NumberValue inside of the chest model. The chest model is parented to a brick inside of the boat and I couldn't figure out how to make GetChildren() work with the given path
					button.Enabled = true
					plrStats.Value += math.floor(chest.Value * tempMultiplier)
					print("$"..math.floor(chest.Value * tempMultiplier))
					chest.Parent:Destroy()
				end
			end
		else
			button.Enabled = false
		end
	end
end)

I would also be open to critique about my coding; I am quite new to it :slight_smile:

1 Like

I’m confused… where are the chests located?

Hey! The photo I used in the OP was just a screenshot of the explorer without the game running - here is what the path would look like if the player put a chest on their boat:
image
where “Wooden Lockbox” is the chest model and “WeldedPart” is the brick where a chest would be located, assuming the player has put a chest on the boat. There are several different chest types.
image

What is the value of tempMultiplier as well as chest.Value for the ones returning a value of 0?

tempMultiplier is a random value being anywhere from 0.6 to 2 - this changes every 10 minutes
chest.Value is also a random value depending on the type of chest being sold, however the value ranges from 250 - 8000. I am defining chest.Value in another script when the chest spawns:

local t1Chest = ReplicatedStorage:FindFirstChild("Rickety Chest")
local chest = t1Chest:Clone()
chest.Price.Value = math.random(250, 500)

I have confirmed this works as the value of the NumberValue located inside of each chest model is correct when the item spawns and if the player only has 1 chest on their boat (as opposed to several), the script posted in OP works as intended.

Just cleaned up your code a bit.

button.Triggered:Connect(function(player)
	print("Triggered button")
	local plrStats = PlayerMoney:FindFirstChild(player.Name)
	local boat = workspace:FindFirstChild(player.Name.."'s Boat")
	
	if not PlrStats or not boat then return end

	local distance = player:DistanceFromCharacter(boat.PrimaryPart.CFrame.Position)
	print(distance)

	if distance > 30 then return end

	for _, chest in boat:GetDescendants() do
		if chest.Name ~= "Price" then continue end -- Price is a NumberValue inside of the chest model. The chest model is parented to a brick inside of the boat and I couldn't figure out how to make GetChildren() work with the given path
		if not chest:IsA("IntValue") and not chest:IsA("NumberValue") then return end -- Didn't know which one you use
		if chest.Value <= 0 then warn("Chest value is invalid",chest.value) return end
	--button.Enabled = true -- ?
		plrStats.Value += math.floor(chest.Value * tempMultiplier)
		print("$"..math.floor(chest.Value * tempMultiplier))
		chest.Parent:Destroy()
	end
	--else
		--button.Enabled = false -- ?
	--end
end)

 -- My Note: Why do you change Button.Enabled by distance? If you use Roblox's inbuilt Prompt, then you can set the settings to when it should be visible, within that prompt. You then check on the server, if they're able to "sell" or whatever you do with the loot.

Let me know the result, it might not have fixed anything as of yet.

I appreciate that!

I’ve messed around a bunch and for some reason print("$"..math.floor(chest.Value * tempMultiplier)) this line is making the value 0?
If I comment out the print line the script works exactly as intended… Weird

local tempMultiplier = game.Workspace["Island 1"].Multiplier.Value

I assume it’s because you try to do math.random(0.6,2) this cannot work, since math.random only takes whole numbers, instead you should define the random tempMultiplier as:

math.random(60,200)/100

I am one step ahead of you there! I have the multiplier being set like this: island1.Multiplier.Value = math.random(6,20)/10
I didn’t need the extra decimal so I only opted for dividing by 10, would that be causing the issue anyway?

Not at all, it juse gives the end number more possible numbers to be within.

But if your script works as intended when commenting out the print line, just calculate the value before doing anything else.

		local calculatedValue = math.floor(chest.Value * tempMultiplier)
		plrStats.Value += calculatedValue 
		print("$"..calculatedValue))

I’ve made your changes and now it’s not working at all again! (I reverted the changes too and it stopped working anyway, so it’s being very random)
image
It is printing the value of the chest correctly before doing any of the calculations, but then the calculatedValue is $0…

for _, chest in boat:GetDescendants() do
		if chest.Name ~= "Price" then continue end
		if not chest:IsA("NumberValue") then return end
		if chest.Value <= 0 then warn("Chest value is invalid",chest.value) return end
		print(chest.Value)
		local calculatedValue = math.floor(chest.Value * tempMultiplier)
		plrStats.Value += calculatedValue
		print("$"..calculatedValue)
		chest.Parent:Destroy()
	end

edit: I think it’s got something to do with the tempMultiplier… will do some further testing

I would suggest that you print what chest.Value is, tempMultiplier is, and what chest.Value*tempMultiplier is before using math.floor on them.

Edit: also at the not chest:IsA(“NumberValue”), use continue instead of return, same with the line below that :slight_smile:

What continue does, is that in a loop it continues to the next index in the loop. (meaning the next object within your boat.Descendants in this case)

1 Like

So it stops looking through boat.Descendants once it finds the NumberValue? Makes a lot of sense. I will keep that in mind!

I also figured out the issue. The script was not updating the value of tempMultiplier - it defaults to 0 in Workspace and I have it updating through a script in ServerScriptService.

I just made it update tempMultiplier whenever you’re in range now.

local tempMultiplier = 0

if distance > 30 then return end
	tempMultiplier = game.Workspace["Island 1"].Multiplier.Value
	for _, chest in boat:GetDescendants() do
		if chest.Name ~= "Price" then continue end
		if not chest:IsA("NumberValue") then continue end
		if chest.Value <= 0 then warn("Chest value is invalid",chest.value) continue end
		print("Chest value is:"..chest.Value)
		print("Multiplier value is:"..tempMultiplier)
		print("Total value is:"..chest.Value * tempMultiplier)
		local calculatedValue = math.floor(chest.Value)
		plrStats.Value += calculatedValue
		print("$"..calculatedValue)
		chest.Parent:Destroy()
	end

Thank you kindly for your help! :slight_smile:

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