Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Help With Ipairs Script?

I have this script which works find except for one thing that I don't know how to fix. At one part of the script, it generates a number, either 1 or 2, and that number is the one that decides which map is loaded, the only problem is that with multiple people the value seems to have multiple numbers somehow and it calls for more than one map. How can I fix this? I'm using intvalue as the value for the map number, if that's what's causing the problem.

gm = game.Workspace.GMstat.Intermission

while true do
ToMapOne = CFrame.new(-2, 20.5, -50)
ToMapTwo = CFrame.new(-27, 69.5, 18)
ToSpawn = CFrame.new(277.5, 1.5, -206.5)
mapc = game.Workspace.MapNum.Value
wait(29)
gm.Name = "Game In Progress"
for i, player in ipairs(game.Players:GetChildren()) do
   if player.Character and player.Character:FindFirstChild("Torso") then
    mapc.Value = (math.random(2))
    wait(1)
    if mapc.Value == 1 then
      print(mapc.Value)
      player.Character.Torso.CFrame = ToMapOne + Vector3.new(0, i * 5, 0)
      player.TeamColor = game.Teams["Playing"].TeamColor
        for i, m1 in ipairs(game.Workspace.MapOne:GetChildren()) do
    m1.Transparency = 0
    m1.CanCollide = true
end
        end 
    if mapc.Value == 2 then
        print(mapc.Value)
        player.Character.Torso.CFrame = ToMapTwo + Vector3.new(0, i * 5, 0)
        player.TeamColor = game.Teams["Playing"].TeamColor
        for i, m2 in ipairs(game.Workspace.MapTwo:GetChildren()) do
    m2.Transparency = 0
    m2.CanCollide = true
end
    end 
    end  
end
wait(60)
gm.Name = "Intermission"
for i, m1 in ipairs(game.Workspace.MapOne:GetChildren()) do
    m1.Transparency = 1 
    m1.CanCollide = false
end
for i, m2 in ipairs(game.Workspace.MapTwo:GetChildren()) do
    m2.Transparency = 1 
    m2.CanCollide = false
end
for i, player in ipairs(game.Players:GetChildren()) do
      if player.Character and player.Character:FindFirstChild("Torso") then
           player.TeamColor = game.Teams["Lobby"].TeamColor
           player.Character.Torso.CFrame = ToSpawn + Vector3.new(0, i * 5, 0)
end
     end
end

1 answer

Tab your code correctly.

Currently, your code reads like this:

  • For each player
    • ... select a random map, and build it
    • teleport that player

Obviously, the second step is in the wrong place.

Notice how mapc and related is inside the loop, but doesn't use player or i at all? That's a hint that's in the wrong place.

First, though, some cleanup.

  • Use elseif mapc.Value == 2 instead of end if mapc.Value == 2. This is cleaner, briefer, and better shows that the two cases are mutually exclusive.

  • Now, you can see that most of the code is the same between the two then blocks. Don't repeat yourself. Pull it out if it's the same.

Looks something like this:

			local teleport, map
			print(mapc.Value)
			if mapc.Value == 1 then
				teleport = ToMapOne
				map = workspace.MapOne
			elseif mapc.Value == 2 then
				teleport = ToMapTwo
				map = workspace.MapTwo
			end
			for _, part in pairs(map:GetChildren()) do
				part.Transparency = 0
				part.CanCollide = true
			end
			player.TeamColor = game.Teams["Playing"].TeamColor
			player.Character.Torso.CFrame = teleport + Vector3.new(0, i * 5, 0)

You don't need to use ipairs if the order doesn't matter -- just use pairs -- it indicates that meaning better. Also, you should be careful that all of the children of the map are actually parts, and aren't, for instance, grouped.


The above code still needs to have the map-selection-code pulled out. It's a lot easier now, though, since just the last two lines use player:

	mapc.Value = math.random(2)
	wait(1)
	print(mapc.Value)
	local teleport, map
	if mapc.Value == 1 then
		teleport = ToMapOne
		map = workspace.MapOne
	elseif mapc.Value == 2 then
		teleport = ToMapTwo
		map = workspace.MapTwo
	end
	for _, part in pairs(map:GetChildren()) do
		part.Transparency = 0
		part.CanCollide = true
	end
	for i, player in pairs(game.Players:GetChildren()) do
		if player.Character and player.Character:FindFirstChild("Torso") then
			player.TeamColor = game.Teams["Playing"].TeamColor
			player.Character.Torso.CFrame = teleport + Vector3.new(0, i * 5, 0)
		end
	end
	wait(60)

The cleanup code repeats itself, too. You only need to hide the map that just played:

	wait(60)
	gm.Name = "Intermission"
	for _, part in pairs(map:GetChildren()) do
		part.Transparency = 1 
		part.CanCollide = false
	end

Your code would look even better if you use functions to break it up.

Other Suggestions

I'm guessing you don't want to set the Name of gm. It probably makes more sense to be setting Text or Value, depending on what it is.

mapc doesn't really need to be an IntValue. You could just have a variable for the index.

Instead of using elseifs on the mapc, you could use a dictionary of map & teleport location, or make the teleport location a part of the map (e.g., have a part named "SpawnLocation" in it that you look for)

I imagine a final cleanup looking something like this:

gm = game.Workspace.GMstat.Intermission

function hideMap(map)
	for _, part in pairs(map:GetChildren()) do
		part.Transparency = 1
		part.CanCollide = false
	end
end

function showMap(map)
	for _, part in pairs(map:GetChidren()) do
		part.Transparency = 0
		part.CanCollide = true
	end
end

-- Returns the list of players with torso
function alivePlayers()
	local t = {}
	for _, player in pairs(game.Players:GetPlayers()) do
		if player.Character and player.Character:FindFirstChild("Torso") then
			table.insert(t, player)
		end
	end
	return t
end

-- Teleports all living players to CFrame to
-- Sets the teamcolor of all living players to `teamcolor`
function teleportPlayers(to, teamcolor)
	for i, player in pairs(alivePlayers()) do
		player.TeamColor = teamcolor
		player.Character.Torso.CFrame = to + Vector3.new(0, i * 5, 0)
	end
end

ToSpawn = CFrame.new(277.5, 1.5, -206.5)
MapSpawns = {
	[1] = CFrame.new(-2, 20.5, -50),
	[2] = CFrame.new(-27, 69.5, 18),
}
Maps = {
	[1] = workspace.MapOne,
	[2] = workspace.MapTwo,
}

while true do
	wait(29)
	gm.Name = "Game In Progress"
	wait(1)
	local mapc = math.random(2)
	local teleport = MapSpawns[mapc]
	local map = Maps[mapc]
	showMap(map)
	teleportPlayers(teleport, game.Teams.Playing.TeamColor)
	wait(60)
	gm.Name = "Intermission"
	hideMap(map)
	teleportPlayers(ToSpawn, game.Teams.Lobby.TeamColor)
end

Though I think you have a mistake in thinking that you can just reset the teamcolor of alive players back to Lobby. I think you want to reset all players.

2 comments

0

Still doesn't work. Some error at line 52

0

I had a typo. Just read the code, it shouldn't be hard to figure out. Not to mention only the final, total rewrite had the mistake. Read the answer, while you're at it.

This discussion is preserved as it was. New answers, comments, and votes are closed.