1.0.4: flower/bush/statue/trash-can billboards, in-place mesh refresh

Flowers stand as 1px animated cutouts on their own pulled mesh (own-cell
flowers hide behind the walker, the cell south still overdraws feet).
Cuttable bushes, gym statues (single-block plinth) and Lt. Surge's trash
cans stand as 5-voxel prop cutouts; prop_ground names the tile painted
beneath. Block edits refresh meshes in place instead of blinking to 2D.
This commit is contained in:
DramaticShape
2026-07-27 00:11:06 -04:00
parent fdcd5f1fce
commit dcf078c2e0
9 changed files with 334 additions and 30 deletions
+10 -3
View File
@@ -535,8 +535,10 @@ local ChunkMesher = run.loader.exports.DRAMATIC_SHAPE.lib.require("ChunkMesher")
local Runtime = require("src.mods.Runtime")
local realInvalidate = ChunkMesher.invalidate
local dropped = {}
local realRefresh = ChunkMesher.refresh
local dropped, refreshed = {}, {}
ChunkMesher.invalidate = function(id) dropped[#dropped + 1] = id or "<every map>" end
ChunkMesher.refresh = function(id) refreshed[#refreshed + 1] = id or "<every map>" end
Runtime.emit("map.reloaded", { mapId = "PALLET_TOWN", reason = "colors" })
T.eq(#dropped, 0,
@@ -551,11 +553,16 @@ T.eq(dropped[1], "PALLET_TOWN", "and drops exactly the map that reloaded")
Runtime.emit("map.reloaded", { mapId = "VIRIDIAN_CITY" })
T.eq(#dropped, 2, "a reload with no stated reason is treated as a real one")
-- and the edits that genuinely change geometry are untouched by any of this
-- a block edit (Cut, a door stamp, the tree regrowing on re-entry) is a
-- REFRESH, not a drop: the stale mesh keeps drawing while the rebuild
-- cooks, so the scene never blinks down to the flat 2D path
Runtime.emit("world.block_replaced", { mapId = "PALLET_TOWN" })
T.eq(#dropped, 3, "a replaced block still drops the mesh it changed")
T.eq(#dropped, 2, "a replaced block does not drop the mesh outright")
T.eq(#refreshed, 1, "it refreshes the mesh in place instead")
T.eq(refreshed[1], "PALLET_TOWN", "and refreshes exactly the edited map")
ChunkMesher.invalidate = realInvalidate
ChunkMesher.refresh = realRefresh
-- ------- the non-colour palette modes must not come through as SGB
--
+3
View File
@@ -94,6 +94,8 @@ return function(game)
if S then
local def = ow.map.def
for _, spec in ipairs(specs) do
if not spec.tile then goto continue end -- "toggle" specs claim
-- tile LISTS, not one slot
local flat, prop, run, first = 0, 0, 0, nil
for ty = 0, def.height * 4 - 1 do
for tx = 0, def.width * 4 - 1 do
@@ -112,6 +114,7 @@ return function(game)
.. " %d inside a prop%s"):format(spec.tile, flat, run, prop,
first and (" -- first at cell " .. math.floor(first[1] / 2)
.. "," .. math.floor(first[2] / 2)) or ""))
::continue::
end
end
end