first pass at tree interaction
This commit is contained in:
@@ -131,12 +131,16 @@ impl FloorTileData {
|
||||
}
|
||||
|
||||
/// Packed fixture tile data. ~18 bytes vs 48 bytes tuple.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
/// NOTE: Clone+Debug only — adding DropTable removes Copy.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct FixtureTileData {
|
||||
pub id: u8,
|
||||
/// bit0=can_stand_in, bit1=can_stand_on
|
||||
pub flags: u8,
|
||||
pub visible_range: [u32; 8],
|
||||
/// Items dropped when this fixture is removed. Empty = nothing drops.
|
||||
/// Trunk tiles will yield wood logs here once log items exist.
|
||||
pub drop_table: DropTable,
|
||||
}
|
||||
|
||||
impl Default for FixtureTileData {
|
||||
@@ -145,12 +149,19 @@ impl Default for FixtureTileData {
|
||||
id: 0,
|
||||
flags: 0,
|
||||
visible_range: [0; 8],
|
||||
drop_table: DropTable::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FixtureTileData {
|
||||
pub fn new(id: u8, can_stand_in: bool, can_stand_on: bool, visible_range: [u32; 8]) -> Self {
|
||||
pub fn new(
|
||||
id: u8,
|
||||
can_stand_in: bool,
|
||||
can_stand_on: bool,
|
||||
visible_range: [u32; 8],
|
||||
drop_table: DropTable,
|
||||
) -> Self {
|
||||
let mut flags = 0u8;
|
||||
if can_stand_in {
|
||||
flags |= 0b001;
|
||||
@@ -162,6 +173,7 @@ impl FixtureTileData {
|
||||
id,
|
||||
flags,
|
||||
visible_range,
|
||||
drop_table,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,10 +312,23 @@ impl TileMap {
|
||||
.unwrap_or(ASTAR_DEFAULT_WEIGHT)
|
||||
}
|
||||
|
||||
/// Remove a fixture tile, clearing both the HashMap entry and ChunkData bitsets.
|
||||
/// BOTH must be cleared — leaving ChunkData stale causes is_standable bugs.
|
||||
/// Remove a fixture tile, clearing the HashMap entry, ChunkData bitsets, and tile_ids.
|
||||
/// All three must be cleared — leaving ChunkData stale causes is_standable bugs,
|
||||
/// and leaving tile_ids non-zero causes the renderer to keep drawing the fixture.
|
||||
///
|
||||
/// Also restores the floor tile's stand_in bit, which insert_fixture clears for
|
||||
/// blocking fixtures (can_stand_in=false) to prevent air floor tiles from overriding
|
||||
/// the block via the OR check in is_standable.
|
||||
pub fn remove_fixture(&mut self, pos: &IVec3) -> Option<FixtureTileData> {
|
||||
let removed = self.fixture_tiles.remove(pos);
|
||||
|
||||
// Read floor standability before taking mutable borrow on chunks.
|
||||
let floor_can_stand_in = self
|
||||
.floor_tiles
|
||||
.get(pos)
|
||||
.map(|f| f.can_stand_in())
|
||||
.unwrap_or(false);
|
||||
|
||||
let chunk_pos = world_to_chunk(*pos);
|
||||
if let Some(chunk) = self.chunks.get_mut(&chunk_pos) {
|
||||
let (lx, ly, z) = ChunkData::world_to_local(*pos);
|
||||
@@ -326,9 +351,14 @@ impl TileMap {
|
||||
);
|
||||
let idx = ChunkData::pos_to_index(lx, ly, z);
|
||||
let word = idx / 32;
|
||||
let clear_mask = !(1u32 << (idx % 32));
|
||||
chunk.stand_in_fixture[word] &= clear_mask;
|
||||
chunk.stand_on_fixture[word] &= clear_mask;
|
||||
let bit = 1u32 << (idx % 32);
|
||||
chunk.stand_in_fixture[word] &= !bit;
|
||||
chunk.stand_on_fixture[word] &= !bit;
|
||||
chunk.tile_ids[idx] = 0;
|
||||
// Restore floor stand_in bit cleared by insert_fixture for blocking fixtures.
|
||||
if floor_can_stand_in {
|
||||
chunk.stand_in_floor[word] |= bit;
|
||||
}
|
||||
}
|
||||
removed
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user