Join co-located player colors

This commit is contained in:
Your Name 2026-08-12 00:30:13 -04:00
parent e200ddcaad
commit cb1b5006b9
3 changed files with 71 additions and 4 deletions

View file

@ -440,8 +440,24 @@ function Room:switchPlayerColorLocal(color)
local targetPlayer = self.player[color] local targetPlayer = self.player[color]
if not targetPlayer then return false end if not targetPlayer then return false end
local canSwitch = not self:onlyColorIsActive(color) local activeColors = self:getActiveColors()
if canSwitch then local canJoin = not self:colorIsActive(color) and #activeColors > 0
if canJoin then
local target = targetPlayer:getGridPos()
for _, activeColor in ipairs(activeColors) do
local activePlayer = self.player[activeColor]
local activePos = activePlayer and activePlayer:getGridPos()
if not activePos or activePos.x ~= target.x or activePos.y ~= target.y then
canJoin = false
break
end
end
end
local canSwitch = canJoin or not self:onlyColorIsActive(color)
if canJoin then
self:setActiveColor(color, true)
elseif canSwitch then
for _, c in ipairs(self:getPossibleColors()) do for _, c in ipairs(self:getPossibleColors()) do
self:setActiveColor(c, c == color) self:setActiveColor(c, c == color)
end end

View file

@ -291,6 +291,42 @@ test("selecting a parked colour changes to its room", function()
currentRoom, setEditorRoomName = oldCurrentRoom, oldSetEditorRoomName currentRoom, setEditorRoomName = oldCurrentRoom, oldSetEditorRoomName
end) end)
test("co-located colours join the active player selection", function()
local function player(x, y)
local entity = {x = x, y = y, switched = false}
function entity:getGridPos() return {x = self.x, y = self.y} end
function entity:playSwitchSound(success) self.switched = success end
return entity
end
local room = {
name = "a",
player = {red = player(3, 4), green = player(3, 4), blue = player(6, 4)},
activeColors = {red = true, green = false, blue = false},
colorsPlayerHas = {"red", "green", "blue"},
}
function room:getPossibleColors() return self.colorsPlayerHas end
function room:getActiveColors()
local colors = {}
for _, color in ipairs(self.colorsPlayerHas) do
if self.activeColors[color] then table.insert(colors, color) end
end
return colors
end
function room:colorIsActive(color) return self.activeColors[color] end
function room:setActiveColor(color, value) self.activeColors[color] = value end
local world = setmetatable({
levels = {a = room}, roomByName = {a = {name = "a", x = 1, y = 1}},
}, {__index = World})
world.flushRuntime = function() end
assertTrue(world:switchPlayerColor(room, "green"))
assertTrue(room.activeColors.red and room.activeColors.green,
"co-located red and green did not become active together")
assertTrue(world:switchPlayerColor(room, "blue"))
assertTrue(room.activeColors.blue and not room.activeColors.red and not room.activeColors.green,
"separated blue player should still select by itself")
end)
test("one run cannot terminate at two different switches", function() test("one run cannot terminate at two different switches", function()
local second = switch("red", 1, 2) local second = switch("red", 1, 2)
local world, _, roomB = makeWorld(second) local world, _, roomB = makeWorld(second)

View file

@ -731,8 +731,23 @@ function World:switchPlayerColor(room, color)
return true return true
end end
local activeColors = room:getActiveColors() local activeColors = room:getActiveColors()
local canSwitch = #activeColors ~= 1 or activeColors[1] ~= color local canJoin = not room:colorIsActive(color) and #activeColors > 0
if canSwitch then if canJoin then
local target = player:getGridPos()
for _, activeColor in ipairs(activeColors) do
local activePlayer = room.player[activeColor]
local activePos = activePlayer and activePlayer:getGridPos()
if not activePos or activePos.x ~= target.x or activePos.y ~= target.y then
canJoin = false
break
end
end
end
local canSwitch = canJoin or #activeColors ~= 1 or activeColors[1] ~= color
if canJoin then
room:setActiveColor(color, true)
elseif canSwitch then
for _, possibleColor in ipairs(room:getPossibleColors()) do for _, possibleColor in ipairs(room:getPossibleColors()) do
room:setActiveColor(possibleColor, possibleColor == color) room:setActiveColor(possibleColor, possibleColor == color)
end end