- 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.
74 lines
1.7 KiB
Rust
74 lines
1.7 KiB
Rust
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<DropEntry>);
|
|
|
|
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)
|
|
}
|