So I have this touched event which needs to only beable to be fired once for each player.
dictionary = {}
local wallName = wall.Name
local stageName = wall.Parent.Name
if not dictionary[player.Name][stageName][wallName] then -- this is in a touched event
dictionary[player.Name] = stageName
dictionary[player.Name][stageName] = wallName
elseif dictionary[player.Name][stageName][wallName] then return end
I’m trying to make the player unable to touch the same part twice
if not dictionary[player.Name] then
dictionary[player.Name] = stageName
dictionary[player.Name][stageName] = wallName
elseif dictionary[player.Name] and not dictionary[player.Name][stageName] then
dictionary[player.Name] = stageName
dictionary[player.Name][stageName] = wallName -- it errors at this line with: attempt to index string with 'Stage1'
elseif dictionary[player.Name][stageName] and not dictionary[player.Name][stageName][wallName] then
dictionary[player.Name][stageName] = wallName
elseif dictionary[player.Name][stageName][wallName] then return end
dictionary = {}
local wallName = wall.Name
local stageName = wall.Parent.Name
--dictionary[player.Name] can store both stageName and wallName keys, so you should do that instead of storing dictionaries inside a dictionary inside a dictionary, would optimize more memory that way.
if not dictionary[player.Name][wallName] then -- this is in a touched event
dictionary[player.Name].stageName = stageName
dictionary[player.Name].wallName = wallName
elseif dictionary[player.Name][wallName] then return end
I believe this would also work, without the use of 3D Tables (a.k.a table inside table inside table). If this doesn’t work otherwise, could you send the full script for more context?
What I’m trying to do is if the player is not in the dictironary add the player and the stage and the wall. Else if the player is but the stage isn’t then add the stage and the wall. else if only the wall is left, then add the wall, but if everything is there break the touched event.
local luckWalls = workspace:WaitForChild("Map"):WaitForChild("LuckWalls")
local stageSpawns = workspace:WaitForChild("Map"):WaitForChild("StageSpawns")
local luckWallRemote = game:GetService("ReplicatedStorage"):WaitForChild("LuckWallRemote")
local dictionary = {}
for i,v in pairs(luckWalls:GetDescendants()) do
if v.ClassName == "Part" and v.Name ~= "EndPart" and v.Name ~= "EntryPart" or v.ClassName == "BasePart" and v.Name ~= "EndPart" and v.Name ~= "EntryPart" then
local wall = v
local digits = {}
wall.SurfaceGui.TextLabel.Text = wall.Name
for occurrence in (wall.Name):gmatch("%d+") do
table.insert(digits, tonumber(occurrence))
end
wall.Touched:Connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
local wallName = wall.Name
local stageName = wall.Parent.Name
print(dictionary)
if not dictionary[player.Name][wallName] then -- this is in a touched event
dictionary[player.Name].stageName = stageName
dictionary[player.Name].wallName = wallName
elseif dictionary[player.Name][wallName] then return end
print(dictionary)
if math.floor(digits[2] / player.leaderstats.Luck.Value) <= 1 then
if player.leaderstats.Luck.Value - digits[2] <= 0 then
player.leaderstats.Luck.Value -= digits[2]
else
player.leaderstats.Luck.Value = 0
end
-- send message to client
luckWallRemote:FireClient(player,wall)
else
if player.leaderstats.Luck.Value - digits[2] <= 0 then
player.leaderstats.Luck.Value -= digits[2]
else
player.leaderstats.Luck.Value = 0
end
local randomNumber = math.random(digits[1],math.floor(digits[2] / player.leaderstats.Luck.Value))
if randomNumber == digits[1] then
-- teleport back
player.Character.HumanoidRootPart.CFrame = stageSpawns:FindFirstChild(wall.Parent.Name.."Spawn")
end
end
end
end)
elseif v.Name == "EndPart" then
local endPart = v
if endPart.Parent.Name == "Stage1" then -- this is the current stage
endPart.Touched:Connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
player.leaderstats.Wins.Value += 1 -- change this to amount of wins at the current stage
for i,v in pairs(dictionary[player.Name][endPart.Parent.Name]) do
v = nil
end
end
end)
end
elseif v.Name == "EntryPart" then
v.Touched:Connect(function(hit)
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
if player then
luckWallRemote:FireClient(player,nil,nil,v.Parent.Name)
end
end)
end
end
I see that dictionary[player.Name] is not defined beforehand. Which would cause an Attempt to index nil with key error. I believe the solution is to define the player’s dictionary before the if statements. Here’s what the script should look like:
dictionary = {}
local wallName = wall.Name
local stageName = wall.Parent.Name
if dictionary[player.Name] == nil then
dictionary[player.Name] = {}
end
if not dictionary[player.Name][stageName][wallName] then -- this is in a touched event
dictionary[player.Name][stageName] = stageName
dictionary[player.Name][stageName][wallName] = wallName
elseif dictionary[player.Name][stageName][wallName] then return end
Please tell me whether this solution works or not.
I would do physical folders in the player’s folder in Players for simplicity’s sake. A folder for stages, with folders for each stage, with the parts for each stage.
if dictionary[player.Name] == nil then
dictionary[player.Name] = {}
end
if dictionary[player.Name][stageName] == nil then -- this is in a touched event
dictionary[player.Name][stageName] = stageName
dictionary[player.Name][stageName][wallName] = wallName
elseif dictionary[player.Name][stageName] and dictionary[player.Name][stageName][wallName] == nil then
dictionary[player.Name][stageName][wallName] = wallName
elseif dictionary[player.Name][stageName][wallName] then return end
but there still the error: attempt to index string with ‘myWallName’