diff --git a/main.lua b/main.lua index 309ce57..cb122c4 100644 --- a/main.lua +++ b/main.lua @@ -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 diff --git a/room.lua b/room.lua index 3f4b5b4..351650c 100644 --- a/room.lua +++ b/room.lua @@ -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} - for _, color in ipairs(self.colorsPlayerHas or {}) do visibleColors[color] = true end + 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 diff --git a/tests/test_wire.lua b/tests/test_wire.lua index 6211662..3777ef5 100644 --- a/tests/test_wire.lua +++ b/tests/test_wire.lua @@ -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) diff --git a/world.lua b/world.lua index 518be54..aaefd31 100644 --- a/world.lua +++ b/world.lua @@ -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()