feat: soft entity collision, dead code removal, leaf standability fix
- 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)
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
use bevy::prelude::*;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
|
||||
use crate::entities::shared_components::Ambulatory;
|
||||
|
||||
pub fn dump_entity_positions(
|
||||
keys: Res<ButtonInput<KeyCode>>,
|
||||
time: Res<Time>,
|
||||
query: Query<(Entity, &Transform, Option<&Ambulatory>), With<Ambulatory>>,
|
||||
) {
|
||||
if !keys.just_pressed(KeyCode::Space) {
|
||||
return;
|
||||
}
|
||||
|
||||
let timestamp = time.elapsed_secs();
|
||||
let filename = format!("entity_dump_{:.2}.csv", timestamp);
|
||||
|
||||
let mut file = match OpenOptions::new()
|
||||
.create(true)
|
||||
.write(true)
|
||||
.truncate(true)
|
||||
.open(&filename)
|
||||
{
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
eprintln!("Failed to create dump file: {}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
writeln!(
|
||||
file,
|
||||
"timestamp,entity_id,x,y,z,has_path,path_index,path_len,target_x,target_y,target_z"
|
||||
)
|
||||
.ok();
|
||||
|
||||
let mut count = 0;
|
||||
for (entity, transform, ambulatory) in query.iter() {
|
||||
let pos = transform.translation;
|
||||
let (has_path, path_index, path_len, tx, ty, tz) = match ambulatory {
|
||||
Some(a) => {
|
||||
let path_len = a.current_path.as_ref().map(|p| p.len()).unwrap_or(0);
|
||||
let has_path = path_len > 0;
|
||||
let (tx, ty, tz) = match a.target {
|
||||
Some(t) => (t.x, t.y, t.z),
|
||||
None => (0.0, 0.0, 0.0),
|
||||
};
|
||||
(has_path, a.path_index, path_len, tx, ty, tz)
|
||||
}
|
||||
None => (false, 0, 0, 0.0, 0.0, 0.0),
|
||||
};
|
||||
|
||||
writeln!(
|
||||
file,
|
||||
"{:.3},{},{:.1},{:.1},{:.1},{},{},{},{:.1},{:.1},{:.1}",
|
||||
timestamp,
|
||||
entity.index(),
|
||||
pos.x,
|
||||
pos.y,
|
||||
pos.z,
|
||||
has_path,
|
||||
path_index,
|
||||
path_len,
|
||||
tx,
|
||||
ty,
|
||||
tz,
|
||||
)
|
||||
.ok();
|
||||
count += 1;
|
||||
}
|
||||
|
||||
println!("[DUMP] {} entities written to {}", count, filename);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod entity_dump;
|
||||
Reference in New Issue
Block a user