Replace box variants with a moveable adhesion property
Collapse the spiky/sticky/skewer box-variant assets into a single per-
instance `adhesion` property on any moveable block, chosen in the editor
via a dropdown next to the colour picker and stored in the .sav alongside
the class.
- spiky -> sticky: soft grab on every true edge (goopy shader)
- skewer -> gluey: rigid weld on every true edge (spiked outline)
- old trailing-face sticky is removed; its saves fold into new sticky
Move the spike geometry + drawGlueySprite into shaders.lua, fold drawing
and the adhesion flag into GenericMoveable, and delete the three
Generic{Sticky,Spiky,Skewer} classes and box_variants.lua. Room:createEntity
normalises legacy spiky_/skewer_/sticky_ class prefixes so old saves load,
and serialization emits `adhesion`. World/map previews and the movement
proxy follow the rename.
Backfill rooms/*.sav to the new format via tools/backfill_adhesion.lua
(41 objects across 8 files). Update tests to the two-mode model; the two
tests asserting the removed lateral-shear limitation are dropped and a
legacy-load migration test added. 27/27 pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
c348b81a93
commit
7d84f595e4
25 changed files with 4010 additions and 3797 deletions
27
room.lua
27
room.lua
|
|
@ -12,9 +12,6 @@ require "wired_switch"
|
|||
require "wired_door"
|
||||
require "dialogue_manager"
|
||||
require "generic_moveable"
|
||||
require "generic_sticky"
|
||||
require "generic_skewer"
|
||||
require "generic_spiky"
|
||||
require "generic_unmoveable"
|
||||
require "generic_player_blocker"
|
||||
require "note"
|
||||
|
|
@ -772,6 +769,17 @@ function Room:createEntity(class, color, x, y, data)
|
|||
return entity
|
||||
end
|
||||
|
||||
-- Legacy: adhesion used to be baked into separate asset classes
|
||||
-- (spiky_/skewer_/sticky_<box>). Collapse them to the base asset carrying an
|
||||
-- adhesion string so old .sav files still load. spiky/old-sticky both become
|
||||
-- the new soft "sticky"; skewer becomes the rigid "gluey".
|
||||
local adhesion = data.adhesion
|
||||
local legacyAdhesion = { spiky = "sticky", skewer = "gluey", sticky = "sticky" }
|
||||
for prefix, mapped in pairs(legacyAdhesion) do
|
||||
local base = class:match("^" .. prefix .. "_(.+)")
|
||||
if base then class = base; adhesion = adhesion or mapped; break end
|
||||
end
|
||||
|
||||
local props = globalAssetProperties and globalAssetProperties[class]
|
||||
local behavior = props and props.class or "immoveable"
|
||||
local entity
|
||||
|
|
@ -829,13 +837,7 @@ function Room:createEntity(class, color, x, y, data)
|
|||
entity = GenericPlayerBlocker:new(x, y, color, sprite, cellShape)
|
||||
self:registerPlayerBlocker(entity, color)
|
||||
elseif behavior == "moveable" then
|
||||
entity = GenericMoveable:new(x, y, color, sprite, class, cellShape)
|
||||
elseif behavior == "sticky" then
|
||||
entity = GenericSticky:new(x, y, color, sprite, class, cellShape)
|
||||
elseif behavior == "skewer" then
|
||||
entity = GenericSkewer:new(x, y, color, sprite, class, cellShape)
|
||||
elseif behavior == "spiky" then
|
||||
entity = GenericSpiky:new(x, y, color, sprite, class, cellShape)
|
||||
entity = GenericMoveable:new(x, y, color, sprite, class, cellShape, adhesion)
|
||||
else
|
||||
entity = GenericUnmoveable:new(x, y, color, sprite, cellShape)
|
||||
end
|
||||
|
|
@ -1038,7 +1040,7 @@ function Room:attemptDelete(mouseX, mouseY, color)
|
|||
return self:attemptDeleteAtCell(self:getCellFromMousePos(mouseX, mouseY), color)
|
||||
end
|
||||
|
||||
function Room:attemptPlaceAtCell(name, props, cell, color, text)
|
||||
function Room:attemptPlaceAtCell(name, props, cell, color, text, adhesion)
|
||||
-- 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.
|
||||
|
|
@ -1084,7 +1086,7 @@ function Room:attemptPlaceAtCell(name, props, cell, color, text)
|
|||
-- additive blend combines the channels into full color
|
||||
for _, c in ipairs(colors) do
|
||||
if props.sprites[c] then
|
||||
self:createEntity(name, c, cell.x, cell.y)
|
||||
self:createEntity(name, c, cell.x, cell.y, { adhesion = adhesion })
|
||||
end
|
||||
end
|
||||
self:tick()
|
||||
|
|
@ -1181,6 +1183,7 @@ function Room:serialize(includePlayers)
|
|||
local pos = entity:getGridPos()
|
||||
local object = { class = class, color = color, x = pos.x, y = pos.y }
|
||||
if entity.circuitId then object.circuit = entity.circuitId end
|
||||
if entity.adhesion then object.adhesion = entity.adhesion end
|
||||
table.insert(objects, object)
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue