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
Tab your code correctly.
Currently, your code reads like this:
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.
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 elseif
s 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.