- Add TileOccupancy resource and rebuild_tile_occupancy system to track per-tile entity counts for soft collision avoidance - Add collision_delay to Ambulatory; entities try relative-left step on occupied tiles, wait 1 tick, then push through - Fix leaf canopy standability: leaves are now can_stand_in=true, can_stand_on=false (walkable, not standable-on) - Delete FloorTilePrefab / FixtureTilePrefab / FloorTile / FixtureTile / TileState (all fully dead — TileMap + ChunkData are sole truth) - Delete tile_spawns from TerrainBlob (populated but never consumed) - Delete leaf ghost entity spawn in forestry (orphaned invisible ECS entity) - Replace log prefab spawn with inline commands.spawn(Transform, Visibility) - Add TileMap::remove_fixture for future digging/explosion use - Skip collision avoidance when current tile has >2 entities (handles spawn cluster deadlock)
34 lines
943 B
Rust
34 lines
943 B
Rust
use crate::constants::ITILE_SIZE;
|
|
use crate::entities::shared_components::Ambulatory;
|
|
use bevy::prelude::*;
|
|
use rustc_hash::FxHashMap;
|
|
|
|
#[derive(Resource, Default)]
|
|
pub struct TileOccupancy {
|
|
pub counts: FxHashMap<(i32, i32), u8>,
|
|
}
|
|
|
|
impl TileOccupancy {
|
|
#[inline]
|
|
pub fn count_at(&self, world_pos: Vec3) -> u8 {
|
|
let tx = (world_pos.x as i32) / ITILE_SIZE;
|
|
let ty = (world_pos.y as i32) / ITILE_SIZE;
|
|
*self.counts.get(&(tx, ty)).unwrap_or(&0)
|
|
}
|
|
}
|
|
|
|
pub fn rebuild_tile_occupancy(
|
|
mut occupancy: ResMut<TileOccupancy>,
|
|
query: Query<&Transform, With<Ambulatory>>,
|
|
) {
|
|
occupancy.counts.clear();
|
|
for transform in query.iter() {
|
|
let tx = (transform.translation.x as i32) / ITILE_SIZE;
|
|
let ty = (transform.translation.y as i32) / ITILE_SIZE;
|
|
let count = occupancy.counts.entry((tx, ty)).or_insert(0);
|
|
if *count < 255 {
|
|
*count += 1;
|
|
}
|
|
}
|
|
}
|