Checking if a player owns a value that is within a table

I am trying to a create a shop system where the player has to have one item purchased before being able to purchase the next item. In this case, I have a table.

local StorageDependancy = {
   ["Storage2"] = {Owned = 'Storage1'},
   ["Storage3"] = {Owned = 'Storage2'},
	["Storage4"] = {Owned = 'Storage3'}
}

return StorageDependancy

An example of what I am looking for is that in order to Purchase Storage2, Storage1 must be owned. In my case, when the player purchases this, the value gets stored within the player naming it “Storage1”.
However, I am confused on how I would write the code to check if the player (using the table) owns said value. This is what I tried so far but need I need guidance on the right steps to take to make this work.

local StorageDependency = game:GetService("ReplicatedStorage"):WaitForChild("Modules"):WaitForChild("StorageDependency")
for _,NewStorage in pairs (StorageDependency) do
    if player.BoughtStorage:FindFirstChild(StorageDependency.Owned) ~= nil then
        print('got it')
    end
end

I appreciate any help, thanks!

1 Like

I would suggest you to use alvinblox to understand how it works.

Why won’t you make something like;

ownsPrevious and set it to true or false when the player buys it?

this is what I’d do

local storages = { -- table of all storages
	[1] = {Name = "Storage1"},
	[2] = {Name = "Storage2"},
	[3] = {Name = "Storage3"},
}

local playerOwnedStorages = { -- table of the storages the player owns
	["Storage1"] = true -- Storage1 is default
}

function storageAvailable(storageIndex) -- returns true if the player can own the storage but doesn't own it yet
	
	local previousStorage = storages[storageIndex-1]
	
	if previousStorage and playerOwnedStorages[previousStorage.Name] then -- checks if player owns previous storage
		return true
	end
	
	return false -- this line isn't needed but I like to use it for prints
	
end

print(storageAvailable(1)) -- false
print(storageAvailable(2)) -- true
print(storageAvailable(3)) -- false

to add a storage you could do

function addStorage(storageIndex)
	if storageAvailable(storageIndex) then
		playerOwnedStorages[storages[storageIndex].Name] = true
	end
end

Edit: You shouldn’t loop when it’s not necessary as you only need to check the previous storage the majority of the time

if you for whatever reason you need to do a loop it can be easily done

for i = 1, #storages do
	if storageAvailable(i) then
		print("Storage" .. i .. " is available")
	end
end
2 Likes

Hey! So I assume that StorageDependency is a module. The first problem I see is the variable where you declare StorageDependency in the second block of code.

You have to use require to get the contents of a module. So:

local StorageDependency = require(game:GetService("ReplicatedStorage"):WaitForChild("Modules"):WaitForChild("StorageDependency"))

Side note - assuming this is server-side code you don’t actually need to call WaitForChild on these things since they’ll already be loaded

Second problem is on this line in the loop: if player.BoughtStorage:FindFirstChild(StorageDependency.Owned) ~= nil then

You’re trying to reference StorageDependency.Owned, when I believe you should be referencing NewStorage.Owned since NewStorage refers to the value you’re looping through in the table.

I think that should fix the errors in your code. For future reference, though, it is always helpful to include any errors you caught in the output :slightly_smiling_face:

If I may suggest a differently written solution

I might do something like the following; First, switch to an array if the names of the storage is the only data you need to store. Then, whichever Storage piece the player is trying to purchase, check if the player owns the previous Storage (if it is above 1) by getting the previous Storage piece in the array and then searching their BoughtStorage for it.

local StorageDependency = {
	'Storage1',
	'Storage2',
	'Storage3',	
}

for i = 1, #StorageDependency do
	if i > 1 then
		local previousStorage = StorageDependency[i-1]
		local newStorage = StorageDependency[i]
		print('player must own',previousStorage,'to purchase',newStorage)
	end
end

Output:

player must own Storage1 to purchase Storage2
player must own Storage2 to purchase Storage3

Hopefully this helped you understand the problem better!

Quoteory ninja’d me but my 3 am brain won’t throw away a perfectly good post :joy:

2 Likes

I’d have a BoolValue you can update, and then update whatever you want to do accordingly.

But, I see this line here:

if player.BoughtStorage:FindFirstChild(StorageDependency.Owned) ~= nil then

If you’re trying to get the “Owned” variable, you’l want to switch it to

if player.BoughtStorage:FindFirstChild(NewStorage.Owned) ~= nil then

If you need any help, or I got something wrong let me know, i’ll be happy to make you a baseplate file with whatever you need for reference.

1 Like

For the playerOwnedStorages, (the table of storages the player already owns), I have the list of storages they own, within the player itself inside a folder named BoughtStorage. How would I turn the contents of this BoughtStorage folder into a table to place those contents into the playerOwnedStorages table. This is the part that confuses me.

you can use folders instead of a table if that’s what you prefer

local storages = { -- table of all storages
	[1] = {Name = "Storage1"},
	[2] = {Name = "Storage2"},
	[3] = {Name = "Storage3"},
}

function storageAvailable(boughtFolder, storageIndex) -- returns true if the player can own the storage but doesn't own it yet
	
	local previousStorage = storages[storageIndex-1]

	if previousStorage then -- checks if player owns previous storage
		local boughtChild = boughtFolder:FindFirstChild(previousStorage.Name)
		if boughtChild then
			return true
		end
	end
	
	return false
	
end

@bl0wemup sorry there was a issue in my code, fixed now

1 Like

I am trying this method and am getting this error. attempt to perform arithmetic on local 'storageIndex' (a nil value). This is on the local previousStorage = storages[storageIndex-1] line. I’m not quite sure how to fix this issue.

Sorry, I must not be understanding something. I am still getting the same error. Here is the full code, I feel like something must be wrong on my end (I’m not sure though.)


function storageAvailable(BoughtStorage, storageIndex) -- returns true if the player can own the storage but doesn't own it yet
	
	local previousStorage = StorageDependency[storageIndex-1]

	if previousStorage then -- checks if player owns previous storage
		local boughtChild = BoughtStorage:FindFirstChild(previousStorage.Name)
		if boughtChild then
			return true
		end
	end
	
	return false
	
end

function addStorage(storageIndex,BoughtStorage)
	if storageAvailable(storageIndex) then
		BoughtStorage[StorageDependency[storageIndex].Name] = true
	end
end

--]]

BuyStorage.OnServerInvoke = function(player,StorageName)
	local cost = StorageInfo[(StorageName)].Price
	local IncreaseStat = StorageInfo[tostring(StorageName)].Storage

				if player.Coins.Value >= cost and player.BoughtStorage:FindFirstChild(StorageName) == nil then 
				print('successsfuly bought')
				--bought new storage and now equipping
				local NewlyBoughtStorage = Instance.new("StringValue")
				NewlyBoughtStorage.Parent = player.BoughtStorage
				NewlyBoughtStorage.Name = StorageName
		
				player.Storage.Value = IncreaseStat
				player.Coins.Value = player.Coins.Value - cost
				--Destroying a Previously Equipped Storage
				if player.CurrentEquipped:FindFirstChild("Storage") then
					player.CurrentEquipped.Storage:Remove()
				end
				--Equipping Storage
				local NewEquipped = Instance.new("StringValue")
				NewEquipped.Parent = player.CurrentEquipped
				NewEquipped.Name = "Storage"
				NewEquipped.Value = StorageName
				
				-- add system to unlock next tier

				addStorage()
				
				return true

And this is the code inside the StorageDependency Module

local StorageDependancy = {
	[1] = {Name = "Storage1"},
	[2] = {Name = "Storage2"},
	[3] = {Name = "Storage3"},	
}

return StorageDependancy
1 Like

ok hmm did you ever try adding the player to a table and check if the player is in table and give them access to purchase

I am doing this through a remotefunction. I am trying to check if the player has the previous storage requirements before being able to purchase the next option. The remote function is triggered when they try to make a purchase. In this case, I will be giving them access to purchase if they meet all requirements, such as having the correct coin amount and the previous storage amounts purchased.

function addStorage(storageIndex,BoughtStorage)
	if storageAvailable(BoughtStorage, storageIndex) then -- you forgot to pass the BoughtStorage here
		BoughtStorage[StorageDependency[storageIndex].Name] = true
	end
end

The error ServerEvents:75: attempt to perform arithmetic on local 'storageIndex' (a nil value) is preventing anything from happening (from what I can tell). It is on this line local previousStorage = StorageDependency[storageIndex-1] Am I supposed to define storageIndex as something? I have no idea.

you have to pass the index of what storage you want to check from the storage dependency with this function

function storageAvailable(BoughtStorage, storageIndex)

if it says storageIndex is nil that means you’re not passing it

this issue is here

you’re calling the addStorage function but not passing any parameters

I’m trying to pass the following parameters when calling the function. addStorage(StorageName, StorageDependency)

StorageName is the Name of the Storage that the player is trying to buy.
I don’t know what other parameters I would pass because even these parameters aren’t working since I’m getting the same error :pensive:

for the first parameter it’s the Storage index e.g(1, 2, 3) not the name and the second parameter should be the Owned Storages folder inside of the Player

What do I define Storage index as? I am calling the addStorage function inside of a different event so I don’t have Storage Index as a parameter nor is it defined in this event. I have no idea what to do from here