This commit is contained in:
2026-03-22 16:05:38 +00:00
parent bceec18a7a
commit e7a43457a3
3 changed files with 50 additions and 24 deletions
+28 -7
View File
@@ -15,10 +15,26 @@ use crate::entities::cargo::{Cargo, Haulable};
use crate::entities::item::constants::ITEM_Z_FIGHTING_OFFSET;
use crate::entities::item::inventory::constants::SIZE_LARGE;
use crate::world::tiles::TileMap;
use crate::world::VisibleGameEntity;
/// Weight of a single log in kg. Enough to encumber a dorf carrying one.
pub const LOG_WEIGHT_KG: u32 = 15;
/// Find the standable surface tile at world XY. Returns the tile one above
/// the highest floor tile where an entity can stand, or None if not found.
fn find_surface_at(world_x: i32, world_y: i32, tilemap: &TileMap) -> Option<IVec3> {
for z in -3i32..=4i32 {
let floor_pos = IVec3::new(world_x, world_y, z * ITILE_SIZE);
if tilemap.floor_tiles.contains_key(&floor_pos) {
let above = IVec3::new(world_x, world_y, floor_pos.z + ITILE_SIZE);
if tilemap.is_standable(above) {
return Some(above);
}
}
}
None
}
/// Spawn a Cargo log entity with a directional fall bias.
///
/// `tile_pos` — world position of the trunk tile this log came from.
@@ -50,14 +66,18 @@ pub fn spawn_log_cargo(
let jitter_tiles = rng.random_range(0u32..=2) as f32 - 1.0; // -1, 0, or +1
let offset = fall_direction * fall_tiles + perp * jitter_tiles;
let biased_pos = IVec3::new(
tile_pos.x + (offset.x * ITILE_SIZE as f32).round() as i32,
tile_pos.y + (offset.y * ITILE_SIZE as f32).round() as i32,
tile_pos.z,
);
let biased_xy_x = tile_pos.x + (offset.x * ITILE_SIZE as f32).round() as i32;
let biased_xy_y = tile_pos.y + (offset.y * ITILE_SIZE as f32).round() as i32;
// Find nearest free tile from biased position
let drop_pos = tilemap.find_nearest_free_cargo_tile(biased_pos, 4, &[])?;
// Find the actual standable surface at this XY — logs land on the floor
let biased_pos = find_surface_at(biased_xy_x, biased_xy_y, tilemap).unwrap_or(IVec3::new(
biased_xy_x,
biased_xy_y,
tile_pos.z,
));
// Find nearest free tile from biased position (increased radius for scattered logs)
let drop_pos = tilemap.find_nearest_free_cargo_tile(biased_pos, 8, &[])?;
// TODO: OuchEvent — if a living entity occupies drop_pos, they take impact damage.
// Check tilemap occupancy here when the combat/injury system exists.
@@ -87,6 +107,7 @@ pub fn spawn_log_cargo(
))
.with_scale(Vec3::splat(PIXEL_RATIO)),
Visibility::Visible,
VisibleGameEntity,
))
.id();