|
|
@ -98,7 +98,7 @@ impl ItemDropType { |
|
|
|
.or_else(|_| mag::MagType::parse_type([data[0],data[1],data[2]]).map(ItemType::Mag))
|
|
|
|
.or_else(|_| tool::ToolType::parse_type([data[0],data[1],data[2]]).map(ItemType::Tool))
|
|
|
|
.or_else(|_| esweapon::ESWeaponType::parse_type([data[0],data[1],data[2]]).map(ItemType::ESWeapon)).ok()?;
|
|
|
|
|
|
|
|
|
|
|
|
match item_type {
|
|
|
|
ItemType::Weapon(_w) => Some(ItemDropType::Weapon(weapon::Weapon::from_bytes(data).ok()?)),
|
|
|
|
ItemType::Armor(_a) => Some(ItemDropType::Armor(armor::Armor::from_bytes(data).ok()?)),
|
|
|
@ -121,7 +121,12 @@ pub struct ItemDrop { |
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub struct DropTable {
|
|
|
|
pub trait DropTable {
|
|
|
|
fn get_drop(&mut self, map_area: &MapArea, monster: &MonsterType) -> Option<ItemDropType>;
|
|
|
|
fn get_box_drop(&mut self, map_area: &MapArea, object: &MapObject) -> Option<ItemDropType>;
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct StandardDropTable {
|
|
|
|
monster_stats: HashMap<MonsterType, MonsterDropStats>,
|
|
|
|
rare_table: RareDropTable,
|
|
|
|
weapon_table: GenericWeaponTable,
|
|
|
@ -133,11 +138,11 @@ pub struct DropTable { |
|
|
|
rng: rand_chacha::ChaCha20Rng,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl DropTable {
|
|
|
|
pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> DropTable {
|
|
|
|
impl StandardDropTable {
|
|
|
|
pub fn new(episode: Episode, difficulty: Difficulty, section_id: SectionID) -> Box<dyn DropTable + Send + Sync> {
|
|
|
|
let monster_stats: HashMap<String, MonsterDropStats> = load_data_file(episode, difficulty, section_id, "monster_dar.toml");
|
|
|
|
|
|
|
|
DropTable {
|
|
|
|
|
|
|
|
Box::new(StandardDropTable {
|
|
|
|
monster_stats: monster_stats.into_iter().map(|(m, s)| (m.parse().unwrap(), s)).collect(),
|
|
|
|
rare_table: RareDropTable::new(episode, difficulty, section_id),
|
|
|
|
weapon_table: GenericWeaponTable::new(episode, difficulty, section_id),
|
|
|
@ -147,7 +152,7 @@ impl DropTable { |
|
|
|
tool_table: ToolTable::new(episode, difficulty, section_id),
|
|
|
|
box_table: BoxDropTable::new(episode, difficulty, section_id),
|
|
|
|
rng: rand_chacha::ChaCha20Rng::from_entropy(),
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn builder() -> DropTableBuilder {
|
|
|
@ -177,8 +182,10 @@ impl DropTable { |
|
|
|
MonsterDropType::None => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_drop(&mut self, map_area: &MapArea, monster: &MonsterType) -> Option<ItemDropType> {
|
|
|
|
impl DropTable for StandardDropTable {
|
|
|
|
fn get_drop(&mut self, map_area: &MapArea, monster: &MonsterType) -> Option<ItemDropType> {
|
|
|
|
let monster_stat = *self.monster_stats.get(monster)?;
|
|
|
|
|
|
|
|
let drop_anything = self.rng.gen_range(0, 100);
|
|
|
@ -191,7 +198,7 @@ impl DropTable { |
|
|
|
}
|
|
|
|
|
|
|
|
let drop_type = self.rng.gen_range(0, 3);
|
|
|
|
|
|
|
|
|
|
|
|
match drop_type {
|
|
|
|
0 => {
|
|
|
|
self.generate_meseta(&monster_stat)
|
|
|
@ -206,7 +213,7 @@ impl DropTable { |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_box_drop(&mut self, map_area: &MapArea, object: &MapObject) -> Option<ItemDropType> {
|
|
|
|
fn get_box_drop(&mut self, map_area: &MapArea, object: &MapObject) -> Option<ItemDropType> {
|
|
|
|
self.box_table.get_drop(map_area, object, &mut self.rng)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -253,8 +260,8 @@ impl DropTableBuilder { |
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn build(self, episode: Episode, difficulty: Difficulty, section_id: SectionID) -> DropTable {
|
|
|
|
DropTable {
|
|
|
|
pub fn build(self, episode: Episode, difficulty: Difficulty, section_id: SectionID) -> Box<dyn DropTable + Send + Sync> {
|
|
|
|
Box::new(StandardDropTable {
|
|
|
|
monster_stats: self.monster_stats.unwrap_or_else(|| {
|
|
|
|
let monster_stats: HashMap<String, MonsterDropStats> = load_data_file(episode, difficulty, section_id, "monster_dar.toml");
|
|
|
|
monster_stats.into_iter().map(|(m, s)| (m.parse().unwrap(), s)).collect()
|
|
|
@ -267,10 +274,24 @@ impl DropTableBuilder { |
|
|
|
tool_table: self.tool_table.unwrap_or_else(|| ToolTable::new(episode, difficulty, section_id)),
|
|
|
|
box_table: self.box_table.unwrap_or_else(|| BoxDropTable::new(episode, difficulty, section_id)),
|
|
|
|
rng: self.rng.unwrap_or_else(rand_chacha::ChaCha20Rng::from_entropy),
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct NullDropTable;
|
|
|
|
|
|
|
|
impl DropTable for NullDropTable {
|
|
|
|
fn get_drop(&mut self, _map_area: &MapArea, _monster: &MonsterType) -> Option<ItemDropType> {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
fn get_box_drop(&mut self, _map_area: &MapArea, _object: &MapObject) -> Option<ItemDropType> {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn null_drop_table(_episode: Episode, _difficult: Difficulty, _section_id: SectionID) -> Box<dyn DropTable + Send + Sync> {
|
|
|
|
Box::new(NullDropTable)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
|
|
|