mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-20 07:26:19 +00:00
fix: show furniture-occupied tiles in the floor plan editor
The editor never requested occupied tiles, so tiles holding furniture were indistinguishable from empty floor and could be edited/voided. - request GetOccupiedTilesMessageComposer when the editor opens - handle RoomOccupiedTilesMessageEvent -> SET_OCCUPIED_TILES - new Tile.occupied flag (kept separate from `blocked`/void): occupied tiles render with a distinct marker and are protected from PAINT/ ERASE/ADJUST and brush-to-selection edits - occupied is purely informational and never changes the saved tilemap (no accidental voiding of floor under furni) Tests: reducer cases for SET_OCCUPIED_TILES + edit protection; container test asserts the occupied event is non-destructive on save; route the canvas pointer test through elementFromPoint (jsdom has no getScreenCTM).
This commit is contained in:
@@ -52,6 +52,7 @@ export const reducer = (state: FloorplanState, action: FloorplanAction): Floorpl
|
||||
{
|
||||
const row = clamp64(action.row);
|
||||
const col = clamp64(action.col);
|
||||
if(state.tiles[row]?.[col]?.occupied) return state;
|
||||
const tiles = ensureRect(state.tiles, row + 1, col + 1);
|
||||
const target = { h: clampHeight(action.h), blocked: false };
|
||||
const next = setTile(tiles, row, col, target);
|
||||
@@ -64,6 +65,7 @@ export const reducer = (state: FloorplanState, action: FloorplanAction): Floorpl
|
||||
const col = action.col | 0;
|
||||
if(row < 0 || col < 0 || row >= state.tiles.length || col >= (state.tiles[0]?.length ?? 0)) return state;
|
||||
const current = state.tiles[row][col];
|
||||
if(current.occupied) return state;
|
||||
const target = { h: current.h, blocked: true };
|
||||
const next = setTile(state.tiles, row, col, target);
|
||||
if(next === state.tiles) return state;
|
||||
@@ -75,7 +77,7 @@ export const reducer = (state: FloorplanState, action: FloorplanAction): Floorpl
|
||||
const col = action.col | 0;
|
||||
if(row < 0 || col < 0 || row >= state.tiles.length || col >= (state.tiles[0]?.length ?? 0)) return state;
|
||||
const current = state.tiles[row][col];
|
||||
if(current.blocked) return state;
|
||||
if(current.blocked || current.occupied) return state;
|
||||
const newH = clampHeight(current.h + action.delta);
|
||||
if(newH === current.h) return state;
|
||||
const next = setTile(state.tiles, row, col, { h: newH, blocked: false });
|
||||
@@ -106,6 +108,22 @@ export const reducer = (state: FloorplanState, action: FloorplanAction): Floorpl
|
||||
if(value === state.wallHeight) return state;
|
||||
return { ...state, wallHeight: value };
|
||||
}
|
||||
case 'SET_OCCUPIED_TILES':
|
||||
{
|
||||
// Mark tiles that currently hold furniture (server-reported). Leaves
|
||||
// height + blocked untouched so it never alters the saved tilemap.
|
||||
const map = action.map ?? [];
|
||||
let changed = false;
|
||||
const tiles = state.tiles.map((r, ri) => r.map((tile, ci) =>
|
||||
{
|
||||
const occ = !!map[ri]?.[ci];
|
||||
if((tile.occupied ?? false) === occ) return tile;
|
||||
changed = true;
|
||||
return { ...tile, occupied: occ };
|
||||
}));
|
||||
if(!changed) return state;
|
||||
return { ...state, tiles };
|
||||
}
|
||||
case 'BRUSH_SET':
|
||||
{
|
||||
const h = action.h ?? state.brush.h;
|
||||
@@ -174,6 +192,7 @@ export const reducer = (state: FloorplanState, action: FloorplanAction): Floorpl
|
||||
const col = parseInt(cStr, 10);
|
||||
const current = tiles[row]?.[col];
|
||||
if(!current) continue;
|
||||
if(current.occupied) continue;
|
||||
|
||||
switch(state.brush.action)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user