Attempt to index number with number

What are you trying to access with v.Amount[1]?

Is it ‘SpawnChance’, ‘xp’, or ‘Loot’?

i’m trying to access v.Amount[1] in Loot, where it says amount

Try to click the 3 dots button at the top right corner of the output, and disable “Log Mode”, so you can see the content of the tables in the output.

Then, how the rock.Loot table looks like?

I made a quick test with a fake table, adding the amount, and used that code that is causing the error, with this fake table works normally:

local FakeTable = {}

FakeTable[1] = {}
FakeTable[1]["Amount"] = {3,7}

FakeTable[2] = {}
FakeTable[2]["Amount"] = {2,5}

FakeTable[3] = {}
FakeTable[3]["Amount"] = {4,8}

local lootgained = {}

for i, v in pairs(FakeTable) do
    warn(i, v)
    table.insert(lootgained, i, v)
    lootgained[i].Amount = math.random(v.Amount[1], v.Amount[2])
end

print(lootgained)

The output:
image

In my opinion, the potential problem is probably a typo, which can either be:

["Stone"] = { --Rock Name
		SpawnChance = 50, --The Chance of the rock spawning
		xp = {3,7}, --Amount of Xp it can drop
		Loot = {
        --Forgetting to enclose Loot details in a table.
			Name = "Stone", Weight = 100, Amount = {2,5}, --Loot Table
		},
	},

Or:

["Stone"] = { --Rock Name
		SpawnChance = 50, --The Chance of the rock spawning
		xp = {3,7}, --Amount of Xp it can drop
		Loot = {
        --Amount isn't a table.
			{Name = "Stone", Weight = 100, Amount = 2} --Loot Table
		},
	},

I printed the table without log mode on and it showed this.
image
However this doesn’t necessarily explain why the table only works once and never again.

I’ve checked the tables and I haven’t seen any misspellings. Is there anything else you think it can be?

What table is that? the one you printed and showing the output

Sorry, I dont know the structure of your rock.Loot table, and how your Rocks module looks like…
I dont know how your player’s loot table looks like either

Just an example on how I would do it, works fine:

-- Player's Loot, created from mining or any action you are using
local PlayerLoot = {"Stone","Copper","Gold","Copper","Stone","Stone","Copper"}

-- Table of Rocks Data probably in a Module
local AllRocks = {}
AllRocks["Stone"] = {
	SpawnChance = 50,
	xp = {3,7},
	Weight = 100,
	Amount = {2,5}
}
AllRocks["Copper"] = {
	SpawnChance = 40,
	xp = {5,9},
	Weight = 100,
	Amount = {2,5}
}
AllRocks["Gold"] = {
	SpawnChance = 30,
	xp = {9,13},
	Weight = 100,
	Amount = {2,5}
}

local function ReadPlayerLoot(LootGot, player)
	local lootgained = {}
	local xpGained = 0
	
	-- Setting random amount and random xp, storing entry into lootgained table
	for _, v in pairs(LootGot) do
		local xpPerRock = math.random(AllRocks[v]["xp"][1], AllRocks[v]["xp"][2])
		table.insert(lootgained, {Name = v, Amount = math.random(AllRocks[v]["Amount"][1], AllRocks[v]["Amount"][2]), RockXP = xpPerRock})
		xpGained += xpPerRock
	end

	warn("Final XP gained from entire loot:", xpGained)
	
	-- Checking created table
	for _, v in pairs(lootgained) do
		warn("Rock Name:", v["Name"])
		print("Amount:", v["Amount"])
		print("XP got:", v["RockXP"])
		--player.PlayerInfo.Levels.Exp.Value += v["RockXP"]
		--DropItem(target, v.Name, v.Amount)
	end
	
	-- Print whole table for debugging
	warn("whole lootgained table:")
	print(lootgained)	
end

-- Call Loot Reader
ReadPlayerLoot(PlayerLoot)

Output:
image
image

The table is a module script in replicated storage, and the table looks this

Local module = {}

module.Rocks = {
	["Stone"] = { --Rock Name
		SpawnChance = 50, --The Chance of the rock spawning
		xp = {3,7}, --Amount of Xp it can drop
		{Name = "Stone", Weight = 100, Amount = {2,5}}, --Loot Table
	},

	["Coal Ore"] = { --Rock Name
		SpawnChance = 50, --The Chance of the rock spawning
		xp = {3,7}, --Amount of Xp it can drop
		Loot = {
			{Name = "Copper", Weight = 100, Amount = {1,5}}, --Loot Table
		},
	},

	["Geode"] = { --Rock Name
		SpawnChance = 50, --The Chance of the rock spawning
		xp = {10,20}, --Amount of Xp it can drop
		Loot = {--Loot Table
			{Name = "Amethyst", Weight = 12.5, Amount = {1,4}}, 
			{Name = "Topaz", Weight = 12.5, Amount = {1,4}}, 
			{Name = "Sapphire", Weight = 12.5, Amount = {1,3}}, 
			{Name = "Amber", Weight = 12.5, Amount = {1,3}}, 
			{Name = "Ruby", Weight = 12.5, Amount = {1,3}}, 
			{Name = "Diamond", Weight = 12.5, Amount = {1,3}}, 
			{Name = "Emerald", Weight = 12.5, Amount = {1,3}}, 
			{Name = "Onyx", Weight = 12.5, Amount = {1,2}}, 
		},
	},
},

I think I see the problem. lootgained[i] is the same table as rock.Loot[i]. So when you change lootgained[i].Amount to a number, rock.Loot[i].Amount also becomes a number.

Add this function to the top of your script:

local deepcopy function deepcopy(t)
	local out = {}
	for k, v in t do
		if type(v) == "table" then
			out[k] = deepcopy(v)
		else
			out[k] = v
		end
	end
	return out
end

And then change your code down here to this.

for i,v in pairs(rock.Loot) do
    lootgained[i] = deepcopy(v)
    lootgained[i].Amount = math.random(v.Amount[1], v.Amount[2])
end
1 Like

You are setting lootgained[i].Amount to a number, but also using it as a table when you assign that value: v.Amount[1] and v.Amount[2]. Eventually when running the function a lot, there will be the error.

Try this in your code:

local function trypick(player, target)
	
	local rock = RockMod.Rocks[target.Name]
	
	if target == nil then
		player:SendMessage("This Rock doesn't exist!", 5)
		return
	end
	
	if isinrange(player, target, rock.Reach) then
		
		if math.random(1, 100) <= rock.dropchance then
			
			local rock = RockMod.Rocks[target.Name]
			local p = player.Character.HumanoidRootPart.CFrame
			local dir = (p - target.CFrame).lookVector
			local range = rock.Reach*2
			local ray = Ray.new(target.CFrame.p, dir * range)
			local part, pos = workspace:FindPartOnRay(ray, player.Character)
			local dist = (p.p - pos).magnitude
			
			if dist > rock.Reach then
				player:SendMessage("You must get closer!", 5)
			else
				givereward(player, target)
				
				spawnrock(player, target)
			end
			
		else
			local rand = math.random(1, 100)
			
			if rand <= rock.dropchance/2 then
				player:SendMessage("You failed to mine the Rock.", 5)
			elseif rand >= rock.dropchance then
				player:SendMessage("You have no tool to mine the Rock.", 5)
			end
		end
	else
		player:SendMessage("You must get closer!", 5)
	end
end

local function onClicked(mouse)
	
	local player = mouse.Player
	local target = mouse.Target
	
	trypick(player, target)
	
end


local function onTouch(touchedpart)
	
	local player = touchedpart.Parent
	local target = touchedpart.Parent.Parent
	
	trypick(player, target)
	
	
end

local function onCharacterAdded(char)
	
	local plr = game.Players:GetPlayerFromCharacter(char)
	
	
	if plr ~= nil then
		
		local equipped = plr.Backpack:FindFirstChild("Pickaxe")
		
		if equipped ~= nil then
			
			equipped.Parent = plr.Character
			equipped.AttachmentPos = Vector3.new(0,0.35, 1.3)
			equipped.AttachmentPoint = Enum.AttachmentPoint.RightHand
			equipped.Rotation = Vector3.new(-90,0,0)
			equipped.Size = Vector3.new(1,1,1)
			
		end
		
	end
	
end

local function onPlayerAdded(plr)
	
	if plr.Character ~= nil then
		onCharacterAdded(plr.Character)
	end
	
	
	plr.CharacterAdded:connect(onCharacterAdded)
	
end

local function onPlayerRemoving(plr)
	
	
	
end

game.Players.PlayerAdded:connect(onPlayerAdded)
game.Players.PlayerRemoving:connect(onPlayerRemoving)

workspace.ChildAdded:connect(function(child)
	if child:IsA("Tool") then
		if child.Name == "Pickaxe" then
			if child.Parent ~= nil then
				child.ClickDetector.MouseClick:connect(onClicked)
				child.ClickDetector.Touched:connect(onTouch)
			end
		end
	end
	if child:IsA("Model") then
		for i,v in pairs(child:GetChildren()) do
			if v:IsA("Part") then
				v.ClickDetector.MouseClick:connect(onClicked)
				v.ClickDetector.Touched:connect(onTouch)
			end
		end
	end
end)


workspace.ChildRemoved:connect(function(child)
	if child:IsA("Tool") then
		if child.Name == "Pickaxe" then
			child.ClickDetector.MouseClick:disconnect()
			child.ClickDetector.Touched:disconnect()
		end
	end
end)

Have you checked out this post before posting this:

Yes but unfortunately it didn’t help much.

so i tried this function but instead of returning a number it returned as a table again.

Unsure what you mean, since deepcopy(t) is supposed to return a table. Could you perhaps be referring to something else? Did his solution not work, and, if so, what is the current problem?

When I used this part of the code it gave me an error that said a table was returned instead of a number

But I removed the code and put it back to its original. I’ve put the code back into the script to see if it would give me the same error but now it’s saying Argument 1 missing or nil on my he part of the script that drops the amount of loot

I fixed a mistake I made and edited my post accordingly. Want to give it another try?

1 Like

It worked!!! thank you so much for your help!!! I really appreciate it!

1 Like

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