Add white room browsing mode

This commit is contained in:
Your Name 2026-08-12 02:55:29 -04:00
parent 794b4dc162
commit 3c5e6daf06
4 changed files with 45 additions and 3 deletions

View file

@ -194,6 +194,8 @@ function love.keypressed(key)
elseif editorView ~= "world" and editorView ~= "wire" and Input.isPlayerSwitch(key) then
local c = Input.playerColor(key)
gameWorld:switchPlayerColor(currentRoom, c)
elseif editorView ~= "world" and editorView ~= "wire" and gameWorld:browseRoom(currentRoom, key) then
return
end
-- if key == "w" then

View file

@ -140,7 +140,8 @@ function Room:draw()
-- draw only the channels the player has. Each object just exposes sprites per
-- channel via Entity:draw(channel); a door registered on all three channels
-- naturally draws its red sprite on the red pass, etc. No per-object logic.
for _, channel in ipairs(self.colorsPlayerHas) do
local drawChannels = gameWorld and gameWorld.roomBrowseMode and {"red", "green", "blue"} or self.colorsPlayerHas
for _, channel in ipairs(drawChannels) do
if self.player[channel] then self.player[channel]:draw(channel) end
for _, entity in pairs(self.collideables[channel]) do entity:draw(channel) end
-- The zoomed-out neighbourhood already draws every room directly. Calling
@ -201,8 +202,11 @@ function Room:drawWiresAt(originX, originY, cellSize, selectedCircuit, editorCol
table.sort(ordered)
love.graphics.setBlendMode("alpha")
local visibleColors = {red = false, green = false, blue = false}
local showAllChannels = gameWorld and gameWorld.roomBrowseMode
local visibleColors = {red = showAllChannels, green = showAllChannels, blue = showAllChannels}
if not showAllChannels then
for _, color in ipairs(self.colorsPlayerHas or {}) do visibleColors[color] = true end
end
local editorIsOn = editorView ~= nil and editorView ~= "off"
for _, circuitId in ipairs(ordered) do
local selected = not selectedCircuit or selectedCircuit == circuitId

View file

@ -370,6 +370,27 @@ test("co-located colours join the active player selection", function()
"separated blue player should still select by itself")
end)
test("WASD room browsing changes view without moving players", function()
local player = {x = 3, y = 4}
local roomA = {name = "a", player = {red = player}}
local roomB = {name = "b", player = {green = {x = 7, y = 8}}}
local world = setmetatable({
levels = {a = roomA, b = roomB},
roomByName = {a = {name = "a", x = 1, y = 1}, b = {name = "b", x = 2, y = 1}},
rooms = {{name = "a", x = 1, y = 1}, {name = "b", x = 2, y = 1}},
}, {__index = World})
local oldCurrentRoom, oldSetEditorRoomName = currentRoom, setEditorRoomName
currentRoom = roomA
setEditorRoomName = function() end
assertTrue(world:browseRoom(roomA, "d"))
assertTrue(currentRoom == roomB)
assertTrue(world.roomBrowseMode)
assertTrue(player.x == 3 and player.y == 4, "browsing moved the player")
currentRoom, setEditorRoomName = oldCurrentRoom, oldSetEditorRoomName
end)
test("one run cannot terminate at two different switches", function()
local second = switch("red", 1, 2)
local world, _, roomB = makeWorld(second)

View file

@ -663,6 +663,7 @@ function World:playerJoinCheck(room, previousPositions, newPositions)
end
function World:movePlayer(room, key)
self.roomBrowseMode = false
local directions = {
up = {x = 0, y = -1, axis = "y"}, down = {x = 0, y = 1, axis = "y"},
left = {x = -1, y = 0, axis = "x"}, right = {x = 1, y = 0, axis = "x"},
@ -714,6 +715,7 @@ function World:movePlayer(room, key)
end
function World:switchPlayerColor(room, color)
self.roomBrowseMode = false
local player = room.player[color]
if not player then
-- A colour copy can be parked in another world room. Number keys are a
@ -771,6 +773,19 @@ function World:switchPlayerColor(room, color)
return canSwitch
end
-- Developer room browser. It changes only the displayed room; players,
-- collision, and runtime save state remain untouched.
function World:browseRoom(room, key)
local exits = {a = "left", d = "right", w = "top", s = "bottom"}
local destinationName = exits[key] and self:getNeighbor(room.name, exits[key])
local destination = destinationName and self.levels[destinationName]
if not destination then return false end
currentRoom = destination
self.roomBrowseMode = true
if setEditorRoomName then setEditorRoomName(destination.name) end
return true
end
function World:tick(room)
room:tickLocal()
self:rebuildCollision()