From e065ab83deab6d6b8360ab629dc6b23603b7a5a4 Mon Sep 17 00:00:00 2001 From: Your Name Date: Fri, 7 Aug 2026 01:57:48 -0400 Subject: [PATCH] we're back baby --- door.lua | 48 +-- room.lua | 54 +-- rooms/2.sav | 1050 ++++++++++++++++++++++++++------------------------- 3 files changed, 575 insertions(+), 577 deletions(-) diff --git a/door.lua b/door.lua index 978e5d4..20a15df 100644 --- a/door.lua +++ b/door.lua @@ -2,53 +2,33 @@ require "entity" Door = class("Door", Entity) -function Door:initialize(x, y) +function Door:initialize(x, y, color) + self.doorColor = color Entity.initialize(self, { x = x, y = y, - color = "white", + color = color, collision = "unmoveable", - sprites = { - red = loadSprite("art/game/door_r.png"), - green = loadSprite("art/game/door_g.png"), - blue = loadSprite("art/game/door_b.png"), - }, + sprite = loadSprite("art/game/door_" .. color:sub(1, 1) .. ".png"), }) self.locked = true - - self.colors = {} - for _, color in pairs({"red", "green", "blue"}) do - self.colors[color] = true --these are currently loc_ed - end self:refreshSprites() end --- keep the per-channel sprite map in sync with lock state so the shared --- Entity:draw(channel) renders the door with no door-specific draw code +-- A door is one normal, colour-layered entity. The editor can therefore place, +-- delete, and serialize its red/green/blue instances independently. function Door:refreshSprites() - self.sprites = {} - for _, c in ipairs({"red", "green", "blue"}) do - if self.locked then - if self.colors[c] then self.sprites[c] = loadSprite("art/game/door_" .. c:sub(1, 1) .. ".png") end - else - self.sprites[c] = loadSprite("art/game/door_unlocked.png") - end + local sprite + if self.locked then + sprite = loadSprite("art/game/door_" .. self.doorColor:sub(1, 1) .. ".png") + else + sprite = loadSprite("art/game/door_unlocked.png") end + self.sprites = { [self.doorColor] = sprite } end function Door:setColors(colors) - local offColors = {} - - for color, off in pairs(colors) do - if off then - if self.colors[color] then self.colors[color] = false end - table.insert(offColors, color) - else - if not self.colors[color] then self.colors[color] = true end - end - end - - if #offColors == 3 then + if colors[self.doorColor] then if self.locked then self:unlock() end else if not self.locked then self:lock() end @@ -65,4 +45,4 @@ end function Door:lock() self.locked = true self.collision = "unmoveable" -end \ No newline at end of file +end diff --git a/room.lua b/room.lua index 0d44721..3d3f733 100644 --- a/room.lua +++ b/room.lua @@ -23,7 +23,7 @@ function Room:initialize(t) if t.name then print("loaded!!") - self:load(t.name) -- registers objects (and any saved players) from the .sav + self:load(t.name, t.runtime) -- registers objects (and any saved players) from the .sav print(t.name) if t.player then @@ -423,10 +423,6 @@ function Room:tick() for _, door in pairs(self.doors) do door:setColors(setDoorColors) end - -- Door:setColors can change collision from unmoveable to none. Rebuild once - -- more after that state change so an open-looking door is passable on the - -- very next input, rather than leaving the previous tick's solid cell here. - self:createCollideablesMatrix() self:nextRoomCheck() end @@ -541,8 +537,16 @@ function Room:createEntity(class, color, x, y) local entity if behavior == "door" then - entity = Door:new(x, y) - self:registerDoor(entity) + -- Old migrated rooms stored a colourless shared door. Expand that legacy + -- record into ordinary colour-layer door objects on load. + if not color then + for _, doorColor in ipairs({"red", "green", "blue"}) do + if props.sprites[doorColor] then self:createEntity(class, doorColor, x, y) end + end + return + end + entity = Door:new(x, y, color) + self:registerDoor(entity, color) elseif behavior == "switch" then entity = Switch:new(x, y, color) self:registerSwitch(entity, color) @@ -571,9 +575,9 @@ function Room:registerCollidable(entityPointer, colorArray) end end -function Room:registerDoor(entityPointer) +function Room:registerDoor(entityPointer, color) table.insert(self.doors, entityPointer) - self:registerCollidable(entityPointer, {"red", "green", "blue"}) + self:registerCollidable(entityPointer, color) end function Room:registerSwitch(entityPointer, color) @@ -607,6 +611,7 @@ function Room:attemptDelete(mouseX, mouseY, color) colors = {color} end + local removedEntities = {} for _, c in ipairs(colors) do -- player if self.player[c] and self.player[c]:occupiesCell(cell) then @@ -620,6 +625,7 @@ function Room:attemptDelete(mouseX, mouseY, color) local entityArray = self.collideables[c] for index = #entityArray, 1, -1 do if entityArray[index]:occupiesCell(cell) then + removedEntities[entityArray[index]] = true table.remove(entityArray, index) end end @@ -631,6 +637,11 @@ function Room:attemptDelete(mouseX, mouseY, color) end end end + -- Behaviour registries hold references to the same objects as the colour + -- layers. Clean references by identity; no class gets bespoke delete rules. + for index = #self.doors, 1, -1 do + if removedEntities[self.doors[index]] then table.remove(self.doors, index) end + end self:tick() end @@ -656,11 +667,13 @@ function Room:attemptPlace(name, props, mouseX, mouseY, color) self:tick() end -function Room:load(name) - -- Runtime rooms are game state: let LÖVE resolve them from its save - -- directory, where Room:save writes autosaves. Source files remain the - -- shipped/editor versions until the editor explicitly saves one. - local room = love.filesystem.read("rooms/" .. name .. ".sav") +function Room:load(name, preferRuntime) + -- Editor/startup loads must use the project source level. Runtime saves are + -- only consulted for an in-progress room-to-room game transition, otherwise + -- an old runtime autosave can hide an editor Save after restart. + local room + if preferRuntime then room = love.filesystem.read("rooms/" .. name .. ".sav") end + if not room then room = readFromSource("rooms/" .. name .. ".sav") end if not room then -- no save yet: start with a blank room to build in the editor print("no save for '" .. name .. "', starting blank") @@ -704,19 +717,9 @@ function Room:serialize() emit("player", color, player) end - -- collideables hold walls/static_walls/generics on one color each, plus - -- doors registered across all three colors -> dedupe doors, emit once - local seenDoor = {} for color, collideableArray in pairs(self.collideables) do for _, collideable in pairs(collideableArray) do - if collideable:isInstanceOf(Door) then - if not seenDoor[collideable] then - seenDoor[collideable] = true - emit("door", nil, collideable) - end - else - emit(collideable.saveClass or "unmoveable", color, collideable) - end + emit(collideable.saveClass or "unmoveable", color, collideable) end end @@ -758,6 +761,7 @@ function nextRoom(pos) -- A placed neighbour gets the same carried player state at its opposite edge. currentRoom = Room:new{ name = nextName or currentName, + runtime = true, player = { x = newPos.x, y = newPos.y, activeColors = currentRoom:getActiveColors() } diff --git a/rooms/2.sav b/rooms/2.sav index dc5990c..4049725 100644 --- a/rooms/2.sav +++ b/rooms/2.sav @@ -1,872 +1,886 @@ { objects={ { - x=1, - class="player", - color="red", - y=1 - }, - { - x=11, class="door", - y=6 + color="blue", + y=6, + x=11 }, { - x=6, class="door", - y=11 + color="blue", + y=11, + x=6 }, { - x=1, - class="static_wall", - color="green", - y=1 - }, - { - x=2, - class="static_wall", - color="green", - y=1 - }, - { - x=3, - class="static_wall", - color="green", - y=1 - }, - { - x=4, - class="static_wall", - color="green", - y=1 - }, - { - x=5, - class="static_wall", - color="green", - y=1 - }, - { - x=6, - class="static_wall", - color="green", - y=1 - }, - { - x=7, - class="static_wall", - color="green", - y=1 - }, - { - x=8, - class="static_wall", - color="green", - y=1 - }, - { - x=9, - class="static_wall", - color="green", - y=1 - }, - { - x=10, - class="static_wall", - color="green", - y=1 - }, - { - x=11, - class="static_wall", - color="green", - y=1 - }, - { - x=1, - class="static_wall", - color="green", - y=2 - }, - { - x=11, - class="static_wall", - color="green", - y=2 - }, - { - x=1, - class="static_wall", - color="green", - y=3 - }, - { - x=11, - class="static_wall", - color="green", - y=3 - }, - { - x=1, - class="static_wall", - color="green", - y=4 - }, - { - x=3, - class="static_wall", - color="green", - y=4 - }, - { - x=9, - class="static_wall", - color="green", - y=4 - }, - { - x=11, - class="static_wall", - color="green", - y=4 - }, - { - x=1, - class="static_wall", - color="green", - y=5 - }, - { - x=4, - class="static_wall", - color="green", - y=5 - }, - { - x=5, - class="static_wall", - color="green", - y=5 - }, - { - x=7, - class="static_wall", - color="green", - y=5 - }, - { - x=8, - class="static_wall", - color="green", - y=5 - }, - { - x=11, - class="static_wall", - color="green", - y=5 - }, - { - x=1, - class="static_wall", - color="green", - y=6 - }, - { - x=1, - class="static_wall", - color="green", - y=7 - }, - { - x=4, - class="static_wall", - color="green", - y=7 - }, - { - x=5, - class="static_wall", - color="green", - y=7 - }, - { - x=7, - class="static_wall", - color="green", - y=7 - }, - { - x=8, - class="static_wall", - color="green", - y=7 - }, - { - x=11, - class="static_wall", - color="green", - y=7 - }, - { - x=1, - class="static_wall", - color="green", - y=8 - }, - { - x=3, - class="static_wall", - color="green", - y=8 - }, - { - x=9, - class="static_wall", - color="green", - y=8 - }, - { - x=11, - class="static_wall", - color="green", - y=8 - }, - { - x=1, - class="static_wall", - color="green", - y=9 - }, - { - x=11, - class="static_wall", - color="green", - y=9 - }, - { - x=1, - class="static_wall", - color="green", - y=10 - }, - { - x=11, - class="static_wall", - color="green", - y=10 - }, - { - x=1, - class="static_wall", - color="green", - y=11 - }, - { - x=2, - class="static_wall", - color="green", - y=11 - }, - { - x=3, - class="static_wall", - color="green", - y=11 - }, - { - x=4, - class="static_wall", - color="green", - y=11 - }, - { - x=5, - class="static_wall", - color="green", - y=11 - }, - { - x=7, - class="static_wall", - color="green", - y=11 - }, - { - x=8, - class="static_wall", - color="green", - y=11 - }, - { - x=9, - class="static_wall", - color="green", - y=11 - }, - { - x=10, - class="static_wall", - color="green", - y=11 - }, - { - x=11, - class="static_wall", - color="green", - y=11 - }, - { - x=6, - class="box", - color="green", - y=5 - }, - { - x=9, - class="box", - color="green", - y=5 - }, - { - x=3, - class="box", - color="green", - y=7 - }, - { - x=6, - class="box", - color="green", - y=7 - }, - { - x=1, class="static_wall", color="blue", - y=1 + y=1, + x=1 }, { - x=2, class="static_wall", color="blue", - y=1 + y=1, + x=2 }, { - x=3, class="static_wall", color="blue", - y=1 + y=1, + x=3 }, { - x=4, class="static_wall", color="blue", - y=1 + y=1, + x=4 }, { - x=5, class="static_wall", color="blue", - y=1 + y=1, + x=5 }, { - x=6, class="static_wall", color="blue", - y=1 + y=1, + x=6 }, { - x=7, class="static_wall", color="blue", - y=1 + y=1, + x=7 }, { - x=8, class="static_wall", color="blue", - y=1 + y=1, + x=8 }, { - x=9, class="static_wall", color="blue", - y=1 + y=1, + x=9 }, { - x=10, class="static_wall", color="blue", - y=1 + y=1, + x=10 }, { - x=11, class="static_wall", color="blue", - y=1 + y=1, + x=11 }, { - x=1, class="static_wall", color="blue", - y=2 + y=2, + x=1 }, { - x=11, class="static_wall", color="blue", - y=2 + y=2, + x=11 }, { - x=1, class="static_wall", color="blue", - y=3 + y=3, + x=1 }, { - x=11, class="static_wall", color="blue", - y=3 + y=3, + x=11 }, { - x=1, class="static_wall", color="blue", - y=4 + y=4, + x=1 }, { - x=11, class="static_wall", color="blue", - y=4 + y=4, + x=11 }, { - x=1, class="static_wall", color="blue", - y=5 + y=5, + x=1 }, { - x=11, class="static_wall", color="blue", - y=5 + y=5, + x=11 }, { - x=1, class="static_wall", color="blue", - y=6 + y=6, + x=1 }, { - x=1, class="static_wall", color="blue", - y=7 + y=7, + x=1 }, { - x=11, class="static_wall", color="blue", - y=7 + y=7, + x=11 }, { - x=1, class="static_wall", color="blue", - y=8 + y=8, + x=1 }, { - x=11, class="static_wall", color="blue", - y=8 + y=8, + x=11 }, { - x=1, class="static_wall", color="blue", - y=9 + y=9, + x=1 }, { - x=11, class="static_wall", color="blue", - y=9 + y=9, + x=11 }, { - x=1, class="static_wall", color="blue", - y=10 + y=10, + x=1 }, { - x=11, class="static_wall", color="blue", - y=10 + y=10, + x=11 }, { - x=1, class="static_wall", color="blue", - y=11 + y=11, + x=1 }, { - x=2, class="static_wall", color="blue", - y=11 + y=11, + x=2 }, { - x=3, class="static_wall", color="blue", - y=11 + y=11, + x=3 }, { - x=4, class="static_wall", color="blue", - y=11 + y=11, + x=4 }, { - x=5, class="static_wall", color="blue", - y=11 + y=11, + x=5 }, { - x=7, class="static_wall", color="blue", - y=11 + y=11, + x=7 }, { - x=8, class="static_wall", color="blue", - y=11 + y=11, + x=8 }, { - x=9, class="static_wall", color="blue", - y=11 + y=11, + x=9 }, { - x=10, class="static_wall", color="blue", - y=11 + y=11, + x=10 }, { - x=11, class="static_wall", color="blue", - y=11 + y=11, + x=11 + }, + { + class="door", + color="red", + y=6, + x=11 }, { - x=1, class="static_wall", color="red", - y=1 + y=1, + x=1 }, { - x=2, class="static_wall", color="red", - y=1 + y=1, + x=2 }, { - x=3, class="static_wall", color="red", - y=1 + y=1, + x=3 }, { - x=4, class="static_wall", color="red", - y=1 + y=1, + x=4 }, { - x=5, class="static_wall", color="red", - y=1 + y=1, + x=5 }, { - x=6, class="static_wall", color="red", - y=1 + y=1, + x=6 }, { - x=7, class="static_wall", color="red", - y=1 + y=1, + x=7 }, { - x=8, class="static_wall", color="red", - y=1 + y=1, + x=8 }, { - x=9, class="static_wall", color="red", - y=1 + y=1, + x=9 }, { - x=10, class="static_wall", color="red", - y=1 + y=1, + x=10 }, { - x=11, class="static_wall", color="red", - y=1 + y=1, + x=11 }, { - x=1, class="static_wall", color="red", - y=2 + y=2, + x=1 }, { - x=5, class="static_wall", color="red", - y=2 + y=2, + x=5 }, { - x=7, class="static_wall", color="red", - y=2 + y=2, + x=7 }, { - x=11, class="static_wall", color="red", - y=2 + y=2, + x=11 }, { - x=1, class="static_wall", color="red", - y=3 + y=3, + x=1 }, { - x=5, class="static_wall", color="red", - y=3 + y=3, + x=5 }, { - x=7, class="static_wall", color="red", - y=3 + y=3, + x=7 }, { - x=11, class="static_wall", color="red", - y=3 + y=3, + x=11 }, { - x=1, class="static_wall", color="red", - y=4 + y=4, + x=1 }, { - x=11, class="static_wall", color="red", - y=4 + y=4, + x=11 }, { - x=1, class="static_wall", color="red", - y=5 + y=5, + x=1 }, { - x=11, class="static_wall", color="red", - y=5 + y=5, + x=11 }, { - x=1, class="static_wall", color="red", - y=6 + y=6, + x=1 }, { - x=1, class="static_wall", color="red", - y=7 + y=7, + x=1 }, { - x=11, class="static_wall", color="red", - y=7 + y=7, + x=11 }, { - x=1, class="static_wall", color="red", - y=8 + y=8, + x=1 }, { - x=11, class="static_wall", color="red", - y=8 + y=8, + x=11 }, { - x=1, class="static_wall", color="red", - y=9 + y=9, + x=1 }, { - x=11, class="static_wall", color="red", - y=9 + y=9, + x=11 }, { - x=1, class="static_wall", color="red", - y=10 + y=10, + x=1 }, { - x=11, class="static_wall", color="red", - y=10 + y=10, + x=11 }, { - x=1, class="static_wall", color="red", - y=11 + y=11, + x=1 }, { - x=2, class="static_wall", color="red", - y=11 + y=11, + x=2 }, { - x=3, class="static_wall", color="red", - y=11 + y=11, + x=3 }, { - x=4, class="static_wall", color="red", - y=11 + y=11, + x=4 }, { - x=5, class="static_wall", color="red", - y=11 + y=11, + x=5 }, { - x=7, class="static_wall", color="red", - y=11 + y=11, + x=8 }, { - x=8, class="static_wall", color="red", - y=11 + y=11, + x=9 }, { - x=9, class="static_wall", color="red", - y=11 + y=11, + x=10 }, { - x=10, class="static_wall", color="red", - y=11 + y=11, + x=11 }, { - x=11, - class="static_wall", - color="red", - y=11 - }, - { - x=3, class="box", color="red", - y=3 + y=3, + x=3 }, { - x=9, class="box", color="red", - y=3 + y=3, + x=9 }, { - x=4, - class="switch", + class="static_wall", + color="red", + y=11, + x=7 + }, + { + class="door", color="green", - y=6 + y=6, + x=11 }, { - x=5, - class="switch", + class="door", color="green", - y=6 + y=11, + x=6 }, { - x=7, - class="switch", + class="static_wall", color="green", - y=6 + y=1, + x=1 }, { - x=8, - class="switch", + class="static_wall", color="green", - y=6 + y=1, + x=2 + }, + { + class="static_wall", + color="green", + y=1, + x=3 + }, + { + class="static_wall", + color="green", + y=1, + x=4 + }, + { + class="static_wall", + color="green", + y=1, + x=5 + }, + { + class="static_wall", + color="green", + y=1, + x=6 + }, + { + class="static_wall", + color="green", + y=1, + x=7 + }, + { + class="static_wall", + color="green", + y=1, + x=8 + }, + { + class="static_wall", + color="green", + y=1, + x=9 + }, + { + class="static_wall", + color="green", + y=1, + x=10 + }, + { + class="static_wall", + color="green", + y=1, + x=11 + }, + { + class="static_wall", + color="green", + y=2, + x=1 + }, + { + class="static_wall", + color="green", + y=2, + x=11 + }, + { + class="static_wall", + color="green", + y=3, + x=1 + }, + { + class="static_wall", + color="green", + y=3, + x=11 + }, + { + class="static_wall", + color="green", + y=4, + x=1 + }, + { + class="static_wall", + color="green", + y=4, + x=3 + }, + { + class="static_wall", + color="green", + y=4, + x=9 + }, + { + class="static_wall", + color="green", + y=4, + x=11 + }, + { + class="static_wall", + color="green", + y=5, + x=1 + }, + { + class="static_wall", + color="green", + y=5, + x=4 + }, + { + class="static_wall", + color="green", + y=5, + x=5 + }, + { + class="static_wall", + color="green", + y=5, + x=7 + }, + { + class="static_wall", + color="green", + y=5, + x=8 + }, + { + class="static_wall", + color="green", + y=5, + x=11 + }, + { + class="static_wall", + color="green", + y=6, + x=1 + }, + { + class="static_wall", + color="green", + y=7, + x=1 + }, + { + class="static_wall", + color="green", + y=7, + x=4 + }, + { + class="static_wall", + color="green", + y=7, + x=5 + }, + { + class="static_wall", + color="green", + y=7, + x=7 + }, + { + class="static_wall", + color="green", + y=7, + x=8 + }, + { + class="static_wall", + color="green", + y=7, + x=11 + }, + { + class="static_wall", + color="green", + y=8, + x=1 + }, + { + class="static_wall", + color="green", + y=8, + x=3 + }, + { + class="static_wall", + color="green", + y=8, + x=9 + }, + { + class="static_wall", + color="green", + y=8, + x=11 + }, + { + class="static_wall", + color="green", + y=9, + x=1 + }, + { + class="static_wall", + color="green", + y=9, + x=11 + }, + { + class="static_wall", + color="green", + y=10, + x=1 + }, + { + class="static_wall", + color="green", + y=10, + x=11 + }, + { + class="static_wall", + color="green", + y=11, + x=1 + }, + { + class="static_wall", + color="green", + y=11, + x=2 + }, + { + class="static_wall", + color="green", + y=11, + x=3 + }, + { + class="static_wall", + color="green", + y=11, + x=4 + }, + { + class="static_wall", + color="green", + y=11, + x=5 + }, + { + class="static_wall", + color="green", + y=11, + x=7 + }, + { + class="static_wall", + color="green", + y=11, + x=8 + }, + { + class="static_wall", + color="green", + y=11, + x=9 + }, + { + class="static_wall", + color="green", + y=11, + x=10 + }, + { + class="static_wall", + color="green", + y=11, + x=11 + }, + { + class="box", + color="green", + y=5, + x=6 + }, + { + class="box", + color="green", + y=5, + x=9 + }, + { + class="box", + color="green", + y=7, + x=3 + }, + { + class="box", + color="green", + y=7, + x=6 }, { - x=6, class="switch", color="red", - y=2 + y=2, + x=6 }, { - x=6, class="switch", color="red", - y=6 + y=6, + x=6 + }, + { + class="switch", + color="green", + y=6, + x=4 + }, + { + class="switch", + color="green", + y=6, + x=5 + }, + { + class="switch", + color="green", + y=6, + x=7 + }, + { + class="switch", + color="green", + y=6, + x=8 } } } \ No newline at end of file