diff --git a/data/battle_param/ep1_rare_monster.toml b/data/battle_param/ep1_rare_monster.toml index b7e62c4..b806f9a 100644 --- a/data/battle_param/ep1_rare_monster.toml +++ b/data/battle_param/ep1_rare_monster.toml @@ -3,13 +3,13 @@ # 1/512 = 0.001953125 [[Hildebear]] -rate = 0.01 +appear_rate = 0.01 [[RagRappy]] -rate = 0.01 +appear_rate = 0.01 [[PoisonLily]] -rate = 0.01 +appear_rate = 0.01 [[PofuillySlime]] -rate = 0.01 \ No newline at end of file +appear_rate = 0.01 \ No newline at end of file diff --git a/data/battle_param/ep2_rare_monster.toml b/data/battle_param/ep2_rare_monster.toml index 2b6f916..948b189 100644 --- a/data/battle_param/ep2_rare_monster.toml +++ b/data/battle_param/ep2_rare_monster.toml @@ -3,11 +3,11 @@ # 1/512 = 0.001953125 [[Hildebear]] -rate = 0.01 +appear_rate = 0.01 [[RagRappy]] -rate = 0.01 +appear_rate = 0.01 [[PoisonLily]] -rate = 0.01 +appear_rate = 0.01 diff --git a/data/battle_param/ep4_rare_monster.toml b/data/battle_param/ep4_rare_monster.toml index 9a4b244..9f807c2 100644 --- a/data/battle_param/ep4_rare_monster.toml +++ b/data/battle_param/ep4_rare_monster.toml @@ -3,25 +3,25 @@ # 1/512 = 0.001953125 [[SandRappyCrater]] -rate = 0.01 +appear_rate = 0.01 [[ZuCrater]] -rate = 0.01 +appear_rate = 0.01 [[Dorphon]] -rate = 0.01 +appear_rate = 0.01 [[SandRappyDesert]] -rate = 0.01 +appear_rate = 0.01 [[ZuDesert]] -rate = 0.01 +appear_rate = 0.01 [[MerissaA]] -rate = 0.01 +appear_rate = 0.01 [[Shambertin]] -rate = 0.1 +appear_rate = 0.1 [[SaintMillion]] -rate = 0.1 \ No newline at end of file +appear_rate = 0.1 \ No newline at end of file diff --git a/src/ship/drops/mod.rs b/src/ship/drops/mod.rs index 8de0408..4ada11e 100644 --- a/src/ship/drops/mod.rs +++ b/src/ship/drops/mod.rs @@ -55,6 +55,17 @@ pub fn load_data_file(episode: Episode, difficul toml::from_str::(s.as_str()).unwrap() } +// this is just copypaste +pub fn load_rare_monster_file(episode: Episode) -> T { + let mut path = PathBuf::from("data/battle_param/"); + path.push(episode.to_string().to_lowercase()); + path.push("_rare_monster.toml"); + + let mut f = File::open(path).unwrap(); + let mut s = String::new(); + f.read_to_string(&mut s); + toml::from_str::(s.as_str()).unwrap() +} #[derive(Debug, Serialize, Deserialize, Copy, Clone)] pub enum MonsterDropType { diff --git a/src/ship/map/enemy.rs b/src/ship/map/enemy.rs index 5f9a60e..62c2155 100644 --- a/src/ship/map/enemy.rs +++ b/src/ship/map/enemy.rs @@ -1,5 +1,6 @@ // TOOD: `pub(super) for most of these?` use std::io::{Read}; +use std::collections::HashMap; use byteorder::{LittleEndian, ReadBytesExt}; use thiserror::Error; @@ -9,6 +10,10 @@ use crate::ship::room::Episode; use crate::ship::map::*; +use rand::{Rng, SeedableRng}; +use serde::{Serialize, Deserialize}; +use crate::ship::drops::{load_rare_monster_file}; + #[derive(Debug, Copy, Clone)] pub struct RawMapEnemy { id: u32, @@ -70,6 +75,46 @@ pub enum MapEnemyError { MapAreaError(#[from] MapAreaError), } +#[derive(Debug, Serialize, Deserialize)] +pub struct RareMonsterAppearRate(pub f32); + +// making this `pub type` doesn't allow `impl`s to be defined? +#[derive(Debug, Serialize, Deserialize)] +pub struct RareMonsterAppearTable { + appear_rate: HashMap, + seed: u32, +} + +impl RareMonsterAppearTable { + pub fn new(episode: Episode, room_seed: u32) -> RareMonsterAppearTable { + let cfg: HashMap = load_rare_monster_file(episode); + + let appear_rates: HashMap = cfg + .into_iter() + .map(|(monster, appear_rate)| { + let monster: MonsterType = monster.parse().unwrap(); + let appear_rate = RareMonsterAppearRate(appear_rate); + (monster, appear_rate) + }) + .collect(); + + RareMonsterAppearTable { + appear_rate: appear_rates, + seed: room_seed, + } + } + + pub fn roll_appearance(&self, monster: &MonsterType) -> bool { + let mut rng = rand_chacha::ChaChaRng::seed_from_u64(self.seed as u64); + if rng.gen::() < self.appear_rate.get(monster).unwrap_or(&RareMonsterAppearRate(0.0f32)).0 { + true + } + else { + false + } + } +} + #[derive(Debug, Copy, Clone)] pub struct MapEnemy {