use rand::rngs::ThreadRng;
use rand::Rng;
#[derive(Debug, Serialize, Deserialize, Copy, Clone, PartialEq, Eq, Hash)]
pub enum Item {
None,
Book,
IronBoots,
Potion,
SplashPotion,
IronNugget,
Quartz,
GlowstoneDust,
MagmaCream,
EnderPearl,
String,
FireCharge,
Gravel,
Leather,
MetherBrick,
Obsidian,
CryingObsidian,
SoulSand,
BlazeRod,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct DropConfig {
pub item: Item,
pub weight: u32,
pub min_count: u32,
pub max_count: u32,
}
impl DropConfig {
pub fn new(item: Item, weight: u32, min_count: u32, max_count: u32) -> Self {
Self {
item,
weight,
min_count,
max_count,
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Drop {
pub roll: u32,
pub item: Item,
pub count: u32,
}
#[derive(Debug)]
pub struct DropSim {
rng: ThreadRng,
drop_list: Vec<DropConfig>,
max_roll: u32,
}
impl DropSim {
pub fn new(drop_list: Vec<DropConfig>) -> Self {
let max_roll = drop_list.iter().fold(0, |sum, drop| sum + drop.weight);
Self {
rng: rand::thread_rng(),
drop_list,
max_roll,
}
}
pub fn get_drop(&mut self) -> Drop {
let roll: u32 = self.rng.gen_range(0..self.max_roll);
let mut weight_remaining: i32 = roll as i32;
let (_, item, count) = self
.drop_list
.iter()
.find(|drop| {
weight_remaining -= drop.weight as i32;
weight_remaining <= 0
})
.map(|drop| {
(
weight_remaining,
drop.item,
drop.min_count..(drop.max_count + 1),
)
})
.unwrap();
Drop {
roll,
item,
count: self.rng.gen_range(count),
}
}
}