From ce3746366ca65d48aa39ad4fd0de169c6742c2fa Mon Sep 17 00:00:00 2001 From: popertots Date: Sat, 21 Mar 2026 15:40:34 +0000 Subject: [PATCH] refactor: extract generic digging system, drop tables, remove debug code - New src/entities/item/drop_table.rs: DropEntry (chance, min/max count, pseudo-RNG roll) + DropTable wrapper. grass=5% coin 1-2, rock=10% coin 1, dirt/air=none. - New src/entities/shared_systems/digging.rs: Digger component + dig_system. Any entity with Digger digs the tile below on its interval. Replaces rabbit_dig_system/rabbit_fall_debug_system/RabbitDigTimer/RabbitFallDebug. - New TileMap::dig_floor: remove_floor + insert air. Used by dig_system. - FloorTileData: added drop_table field. Lost Copy derive (Vec field). Updated all 6 terrain.rs call sites with per-tile drop tables. - Pig: removed PigDropTimer + pig_drop_system. Drops were debug placeholder. TODO added for future loot-on-death/butcher system. - Rabbit: removed all debug components/systems. Now uses Digger::new(5.0). - main.rs: removed rabbit_dig_system/rabbit_fall_debug_system/pig_drop_system, added shared_systems::digging::dig_system. --- src/entities/item/drop_table.rs | 73 ++++++++ src/entities/item/mod.rs | 2 + src/entities/livestock/pig.rs | 44 ----- src/entities/livestock/rabbit.rs | 239 +------------------------ src/entities/shared_systems/digging.rs | 93 ++++++++++ src/entities/shared_systems/mod.rs | 1 + src/main.rs | 10 +- src/world/generation/terrain.rs | 50 ++++-- src/world/tiles/tilemap.rs | 27 ++- 9 files changed, 238 insertions(+), 301 deletions(-) create mode 100644 src/entities/item/drop_table.rs create mode 100644 src/entities/shared_systems/digging.rs diff --git a/src/entities/item/drop_table.rs b/src/entities/item/drop_table.rs new file mode 100644 index 0000000..a73d518 --- /dev/null +++ b/src/entities/item/drop_table.rs @@ -0,0 +1,73 @@ +use crate::entities::item::prefabs::misc::misc_prefabs::MiscPrefab; +use bevy::prelude::*; + +#[derive(Clone, Debug)] +pub struct DropEntry { + pub prefab: MiscPrefab, + pub chance: f32, + pub min_count: u32, + pub max_count: u32, +} + +impl DropEntry { + pub fn always(prefab: MiscPrefab) -> Self { + Self { + prefab, + chance: 1.0, + min_count: 1, + max_count: 1, + } + } + + pub fn chance(prefab: MiscPrefab, chance: f32, min_count: u32, max_count: u32) -> Self { + Self { + prefab, + chance, + min_count, + max_count, + } + } + + pub fn roll(&self, pos: IVec3) -> u32 { + if self.chance < 1.0 { + let r = pseudo_rand_f32(pos); + if r >= self.chance { + return 0; + } + } + pseudo_rand_u32(pos) % (self.max_count - self.min_count + 1) + self.min_count + } +} + +#[derive(Clone, Debug, Default)] +pub struct DropTable(pub Vec); + +impl DropTable { + pub fn is_empty(&self) -> bool { + self.0.is_empty() + } +} + +fn hash3(pos: IVec3) -> u32 { + let mut h: u32 = 0; + h = h.wrapping_mul(374761393).wrapping_add(pos.x as u32); + h = h.wrapping_mul(374761393).wrapping_add(pos.y as u32); + h = h.wrapping_mul(374761393).wrapping_add(pos.z as u32); + h ^= h >> 13; + h = h.wrapping_mul(1274126177); + h ^= h >> 16; + h +} + +fn pseudo_rand_u32(pos: IVec3) -> u32 { + let timestamp = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_nanos() as u32; + hash3(pos) ^ timestamp +} + +fn pseudo_rand_f32(pos: IVec3) -> f32 { + let val = pseudo_rand_u32(pos); + (val as f32) / (u32::MAX as f32) +} diff --git a/src/entities/item/mod.rs b/src/entities/item/mod.rs index 867bbe5..4d2ae5f 100644 --- a/src/entities/item/mod.rs +++ b/src/entities/item/mod.rs @@ -1,6 +1,7 @@ pub mod container; pub mod core; pub mod decorations; +pub mod drop_table; pub mod material; pub mod perishable; pub mod prefabs; @@ -11,6 +12,7 @@ pub mod types; pub use container::*; pub use core::*; pub use decorations::*; +pub use drop_table::*; pub use material::*; pub use perishable::*; pub use prefabs::*; diff --git a/src/entities/livestock/pig.rs b/src/entities/livestock/pig.rs index dadeb2a..548c7d2 100644 --- a/src/entities/livestock/pig.rs +++ b/src/entities/livestock/pig.rs @@ -1,10 +1,8 @@ use crate::config::GameConfig; use crate::constants::TILE_SIZE; use crate::constants::*; -use crate::entities::item::{spawn_prefab, MiscPrefab}; use crate::entities::shared_components::Ambulatory; use crate::game::SpawnDelay; -use crate::world::tiles::tilemap; use crate::world::VisibleGameEntity; use bevy::prelude::*; use bevy_rand::prelude::*; @@ -16,7 +14,6 @@ pub struct Pig { sprite: Sprite, transform: Transform, visibility: Visibility, - drop_timer: PigDropTimer, } impl Pig { @@ -39,14 +36,10 @@ impl Pig { }, transform: Transform::from_translation(position).with_scale(Vec3::splat(PIXEL_RATIO)), visibility: Visibility::Hidden, - drop_timer: PigDropTimer(Timer::from_seconds(5.0, TimerMode::Repeating)), } } } -#[derive(Component, Deref, DerefMut)] -pub struct PigDropTimer(pub Timer); - pub fn spawn_pigs( mut commands: Commands, asset_server: Res, @@ -81,40 +74,3 @@ pub fn spawn_pigs( } } } - -pub fn pig_drop_system( - mut commands: Commands, - asset_server: Res, - time: Res