note blocks and sticky test

This commit is contained in:
Your Name 2026-08-13 12:45:41 -04:00
parent 1bc1cdb11f
commit d829b4972f
11 changed files with 3389 additions and 118 deletions

View file

@ -17,6 +17,7 @@ require "generic_skewer"
require "generic_spiky"
require "generic_unmoveable"
require "generic_player_blocker"
require "note"
local Movement = require "movement"
local Wire = require "wire"
@ -31,6 +32,7 @@ function Room:initialize(t)
self.collideables = { red = {}, green = {}, blue = {} }
self.playerBlockers = { red = {}, green = {}, blue = {} }
self.npcs = {}
self.notes = {}
self.activeColors = {red = false, green = false, blue = false}
self.colorsPlayerHas = {}
@ -172,6 +174,16 @@ function Room:draw(drawChannels)
for _, switch in ipairs(self.wiredSwitches) do switch:draw(channel) end
for _, npc in ipairs(self.npcs) do npc:draw(channel) end
end
-- Notes are an editor-only overlay: shown only while the editor build is
-- running (DEBUG) and the NOTES_VISIBLE toggle is on. Drawn once (not per
-- channel) in alpha so the faint icon reads as itself instead of screen-adding.
if DEBUG and NOTES_VISIBLE and #self.notes > 0 then
local mode, alphaMode = love.graphics.getBlendMode()
love.graphics.setBlendMode("alpha")
for _, note in ipairs(self.notes) do note:draw() end
love.graphics.setBlendMode(mode, alphaMode)
end
end
function Room:wireTracksAt(cell, create)
@ -739,6 +751,11 @@ function Room:createEntity(class, color, x, y, data)
self:registerNpc(entity)
return entity
end
if class == "note" then
local entity = Note:new(x, y, data.text)
self:registerNote(entity)
return entity
end
local props = globalAssetProperties and globalAssetProperties[class]
local behavior = props and props.class or "immoveable"
@ -857,6 +874,22 @@ function Room:registerNpc(entity)
table.insert(self.npcs, entity)
end
function Room:registerNote(entity)
-- Notes are like switches: a passable object kept in their own registry, so
-- serialize's note loop round-trips them and movement never sees them (their
-- "none" collision means canPassOver, so they are not stamped into a matrix).
table.insert(self.notes, entity)
end
-- The note (if any) under a given grid cell — used by the editor's hover/click.
function Room:noteAtCell(cell)
if not cell then return nil end
for _, note in ipairs(self.notes) do
if note:occupiesCell(cell) then return note end
end
return nil
end
function Room:getCellFromMousePos(mouseX, mouseY)
if gameWorld and gameWorld.levels and gameWorld.levels[self.name] == self and
not gameWorld.drawingRoomNeighborhood then
@ -933,6 +966,11 @@ function Room:attemptDeleteAtCell(cell, color)
for index = #self.npcs, 1, -1 do
if self.npcs[index]:occupiesCell(cell) then table.remove(self.npcs, index) end
end
-- Notes are non-collidable and colourless, so a right-click removes them
-- regardless of the currently selected editor colour.
for index = #self.notes, 1, -1 do
if self.notes[index]:occupiesCell(cell) then table.remove(self.notes, index) end
end
self:tick()
end
@ -940,7 +978,19 @@ function Room:attemptDelete(mouseX, mouseY, color)
return self:attemptDeleteAtCell(self:getCellFromMousePos(mouseX, mouseY), color)
end
function Room:attemptPlaceAtCell(name, props, cell, color)
function Room:attemptPlaceAtCell(name, props, cell, color, text)
-- Notes are colourless, single-instance annotations (no per-channel sprites),
-- so they place once carrying their text rather than one copy per colour. One
-- note per cell: drop any note already here before adding the new one.
if name == "note" then
if not cell then return end
for index = #self.notes, 1, -1 do
if self.notes[index]:occupiesCell(cell) then table.remove(self.notes, index) end
end
self:createEntity("note", nil, cell.x, cell.y, { text = text })
self:tick()
return
end
if not props or not props.sprites then return end
if not cell then return end
-- Jorge is one dialogable NPC with three display channels, not three
@ -1101,6 +1151,10 @@ function Room:serialize(includePlayers)
table.insert(objects, { class = npc.saveClass or "npc", x = npc.x, y = npc.y })
end
for _, note in ipairs(self.notes) do
table.insert(objects, { class = "note", x = note.x, y = note.y, text = note.text })
end
return { objects = objects, wires = self:serializeWires() }
end