diff --git a/data/battle_param/ep1_rare_monster.toml b/data/battle_param/ep1_rare_monster.toml index 9de3518..14a1d4a 100644 --- a/data/battle_param/ep1_rare_monster.toml +++ b/data/battle_param/ep1_rare_monster.toml @@ -3,7 +3,7 @@ # 1/256 = 0.00390625 # 1/512 = 0.001953125 -Hildebear = 0.1 -RagRappy = 0.2 -PoisonLily = 0.3 -PofuillySlime = 0.4 \ No newline at end of file +Hildebear = 0.001953125 +RagRappy = 0.001953125 +PoisonLily = 0.001953125 +PofuillySlime = 0.001953125 diff --git a/data/battle_param/ep2_rare_monster.toml b/data/battle_param/ep2_rare_monster.toml index 290f727..b56bee9 100644 --- a/data/battle_param/ep2_rare_monster.toml +++ b/data/battle_param/ep2_rare_monster.toml @@ -3,7 +3,7 @@ # 1/256 = 0.00390625 # 1/512 = 0.001953125 -Hildebear = 0.01 -RagRappy = 0.01 -PoisonLily = 0.01 +Hildebear = 0.001953125 +RagRappy = 0.001953125 +PoisonLily = 0.001953125 diff --git a/data/battle_param/ep4_rare_monster.toml b/data/battle_param/ep4_rare_monster.toml index 0ddddbf..d5b0fb2 100644 --- a/data/battle_param/ep4_rare_monster.toml +++ b/data/battle_param/ep4_rare_monster.toml @@ -3,11 +3,11 @@ # 1/256 = 0.00390625 # 1/512 = 0.001953125 -SandRappyCrater = 0.01 -ZuCrater = 0.01 -Dorphon = 0.01 -SandRappyDesert = 0.01 -ZuDesert = 0.01 -MerissaA = 0.01 +SandRappyCrater = 0.001953125 +ZuCrater = 0.001953125 +Dorphon = 0.001953125 +SandRappyDesert = 0.001953125 +ZuDesert = 0.001953125 +MerissaA = 0.001953125 Shambertin = 0.1 SaintMillion = 0.1 \ No newline at end of file diff --git a/src/ship/drops/mod.rs b/src/ship/drops/mod.rs index 427da74..e5037af 100644 --- a/src/ship/drops/mod.rs +++ b/src/ship/drops/mod.rs @@ -57,9 +57,9 @@ pub fn load_data_file(episode: Episode, difficul // this is just copypaste pub fn load_rare_monster_file(episode: Episode) -> T { + // TODO: where does the rare monster toml file actually live let mut path = PathBuf::from("data/battle_param/"); path.push(episode.to_string().to_lowercase() + "_rare_monster.toml"); - println!("rare monster file path: {:?}", path); let mut f = File::open(path).unwrap(); let mut s = String::new(); diff --git a/src/ship/map/enemy.rs b/src/ship/map/enemy.rs index e66cca4..2555024 100644 --- a/src/ship/map/enemy.rs +++ b/src/ship/map/enemy.rs @@ -75,21 +75,15 @@ pub enum MapEnemyError { MapAreaError(#[from] MapAreaError), } -// TODO: is this even needed/used? -// #[derive(Clone, Debug, Serialize, Deserialize)] -// pub type RareMonsterAppearRate: HashMap, - // making this `pub type` doesn't allow `impl`s to be defined? #[derive(Clone, Debug, Serialize, Deserialize)] pub struct RareMonsterAppearTable { appear_rate: HashMap, - seed: u32 } impl RareMonsterAppearTable { - pub fn new(episode: Episode, room_seed: u32) -> RareMonsterAppearTable { + pub fn new(episode: Episode) -> RareMonsterAppearTable { let cfg: HashMap = load_rare_monster_file(episode); - println!("got cfg: {:?}", cfg); let appear_rates: HashMap = cfg .into_iter() @@ -102,21 +96,14 @@ impl RareMonsterAppearTable { RareMonsterAppearTable { appear_rate: appear_rates, - seed: room_seed, } } pub fn roll_appearance(&self, monster: &MonsterType) -> bool { - println!("rolling appearance for {:?} with seed {:?}", monster, self.seed); - // let mut rng = rand_chacha::ChaChaRng::from_entropy(); if rand_chacha::ChaChaRng::from_entropy().gen::() < *self.appear_rate.get(monster).unwrap_or(&0.0f32) { - println!("its a rare!"); - true - } - else { - println!("lol sucker"); - false + return true } + false } } @@ -135,7 +122,6 @@ pub struct MapEnemy { impl MapEnemy { pub fn from_raw(enemy: RawMapEnemy, episode: &Episode, map_area: &MapArea /*, battleparam */) -> Result { - println!("enemy.rs::from_raw - {:?}", enemy); // TODO: rare enemies ep1-4, tower lilys, event rappies, ult variants? // TODO: check what "skin" actually does. some unexpected enemies have many (panarms, slimes, lilys) let monster = match map_area { @@ -337,7 +323,6 @@ impl MapEnemy { } } - // TODO: does this actually do anything useful? pub fn has_rare_appearance(self) -> bool { match self.monster { MonsterType::RagRappy | MonsterType::Hildebear | @@ -348,22 +333,11 @@ impl MapEnemy { _ => false } } - - // // TODO: does `shiny` need to be set here? - // // TODO: distinguish between a `random` rare monster and a `set/guaranteed` rare monster? (does any acceptable quest even have this?) - // pub fn set_rare_appearance(self) -> MapEnemy { - // match self.monster { - // MonsterType::RagRappy | MonsterType::Hildebear | - // MonsterType::PoisonLily | MonsterType::PofuillySlime | - // MonsterType::SandRappyCrater | MonsterType::ZuCrater | MonsterType::Dorphon | - // MonsterType::SandRappyDesert | MonsterType::ZuDesert | MonsterType::MerissaA | - // MonsterType::SaintMillion | MonsterType::Shambertin => self.set_shiny(), - // _ => self, - // } - // } - // TODO: does `shiny` need to be set here? - // TODO: distinguish between a `random` rare monster and a `set/guaranteed` rare monster? (does any acceptable quest even have this?) + /* + TODO: distinguish between a `random` rare monster and a `set/guaranteed` rare monster? (does any acceptable quest even have this?) + guaranteed rare monsters don't count towards the limit + */ pub fn set_rare_appearance(self) -> MapEnemy { match (self.monster, self.map_area.to_episode()) { (MonsterType::RagRappy, Episode::One) => {MapEnemy {monster: MonsterType::AlRappy, shiny:true, ..self}}, diff --git a/src/ship/map/maps.rs b/src/ship/map/maps.rs index ceebd65..aca75b7 100644 --- a/src/ship/map/maps.rs +++ b/src/ship/map/maps.rs @@ -12,8 +12,6 @@ use crate::ship::room::{Episode, RoomMode}; // TODO: don't use * use crate::ship::map::*; -// use rand::{Rng}; - pub fn objects_from_stream(cursor: &mut impl Read, episode: &Episode, map_area: &MapArea) -> Vec> { let mut object_data = Vec::new(); @@ -31,99 +29,14 @@ fn objects_from_map_data(path: PathBuf, episode: &Episode, map_area: &MapArea) - } fn parse_enemy(episode: &Episode, map_area: &MapArea, raw_enemy: RawMapEnemy) -> Vec> { -// fn parse_enemy(episode: &Episode, map_area: &MapArea, raw_enemy: RawMapEnemy, rare_monster_table: RareMonsterAppearTable) -> Vec> { let enemy = MapEnemy::from_raw(raw_enemy, episode, map_area); - // TODO: load rare monster rates config enemy .map_or(vec![None], |monster| { let mut monsters = Vec::new(); monsters.push(Some(monster)); match monster.monster { - // TODO: make real spawn rates - // TODO: specific ep 2 event rappies - // MonsterType::RagRappy => {if rand::thread_rng().gen_range(0, 100) < 11 { -/* MonsterType::RagRappy => {if rare_monster_table.roll_appearance(&monster.monster) { - monsters.pop(); - match episode { - Episode::One => {monsters.push(Some(MapEnemy::new(MonsterType::AlRappy, monster.map_area).set_shiny()))}, - Episode::Two => {monsters.push(Some(MapEnemy::new(MonsterType::EventRappy, monster.map_area).set_shiny()))}, - _ => {unreachable!()}, - } - - }}, - // MonsterType::Hildebear => {if rand::thread_rng().gen_range(0, 100) < 11 { - MonsterType::Hildebear => {if rare_monster_table.roll_appearance(&monster.monster) { - monsters.pop(); - monsters.push(Some(MapEnemy::new(MonsterType::Hildeblue, monster.map_area).set_shiny())) - }}, - // MonsterType::PoisonLily => {if rand::thread_rng().gen_range(0, 100) < 11 { - MonsterType::PoisonLily => {if rare_monster_table.roll_appearance(&monster.monster) { - monsters.pop(); - monsters.push(Some(MapEnemy::new(MonsterType::NarLily, monster.map_area).set_shiny())) - }}, - // TODO: client increments by 5 for slimes instead of 4 segawhyyyyy????? - MonsterType::PofuillySlime => { - monsters.pop(); - for _ in 0..5 { - // if rand::thread_rng().gen_range(0, 100) < 11 { - if rare_monster_table.roll_appearance(&monster.monster) { - monsters.push(Some(MapEnemy::new(MonsterType::PouillySlime, monster.map_area).set_shiny())) - } else { - monsters.push(Some(MapEnemy::new(MonsterType::PofuillySlime, monster.map_area))) - } - } - }, - MonsterType::PouillySlime => { - // guaranteed rare slime already pushed - // roll for the other 3 (4?) copies - for _ in 0..4 { - // if rand::thread_rng().gen_range(0, 100) < 11 { - if rare_monster_table.roll_appearance(&monster.monster) { - monsters.push(Some(MapEnemy::new(MonsterType::PouillySlime, monster.map_area).set_shiny())) - } else { - monsters.push(Some(MapEnemy::new(MonsterType::PofuillySlime, monster.map_area))) - } - } - }, - // MonsterType::SandRappyCrater => {if rand::thread_rng().gen_range(0, 100) < 11 { - MonsterType::SandRappyCrater => {if rare_monster_table.roll_appearance(&monster.monster) { - monsters.pop(); - monsters.push(Some(MapEnemy::new(MonsterType::DelRappyCrater, monster.map_area).set_shiny())) - }}, - // MonsterType::ZuCrater => {if rand::thread_rng().gen_range(0, 100) < 11 { - MonsterType::ZuCrater => {if rare_monster_table.roll_appearance(&monster.monster) { - monsters.pop(); - monsters.push(Some(MapEnemy::new(MonsterType::PazuzuCrater, monster.map_area).set_shiny())) - }}, - // MonsterType::Dorphon => {if rand::thread_rng().gen_range(0, 100) < 11 { - MonsterType::Dorphon => {if rare_monster_table.roll_appearance(&monster.monster) { - monsters.pop(); - monsters.push(Some(MapEnemy::new(MonsterType::DorphonEclair, monster.map_area).set_shiny())) - }}, - // MonsterType::SandRappyDesert => {if rand::thread_rng().gen_range(0, 100) < 11 { - MonsterType::SandRappyDesert => {if rare_monster_table.roll_appearance(&monster.monster) { - monsters.pop(); - monsters.push(Some(MapEnemy::new(MonsterType::DelRappyDesert, monster.map_area).set_shiny())) - }}, - // MonsterType::ZuDesert => {if rand::thread_rng().gen_range(0, 100) < 11 { - MonsterType::ZuDesert => {if rare_monster_table.roll_appearance(&monster.monster) { - monsters.pop(); - monsters.push(Some(MapEnemy::new(MonsterType::PazuzuDesert, monster.map_area).set_shiny())) - }}, - // MonsterType::MerissaA => {if rand::thread_rng().gen_range(0, 100) < 11 { - MonsterType::MerissaA => {if rare_monster_table.roll_appearance(&monster.monster) { - monsters.pop(); - monsters.push(Some(MapEnemy::new(MonsterType::MerissaAA, monster.map_area).set_shiny())) - }}, - // MonsterType::SaintMillion | MonsterType::Shambertin => { if rand::thread_rng().gen_range(0, 100) < 11 { - MonsterType::SaintMillion | MonsterType::Shambertin => { if rare_monster_table.roll_appearance(&monster.monster) { - monsters.pop(); - monsters.push(Some(MapEnemy::new(MonsterType::Kondrieu, monster.map_area).set_shiny())) - }}, -*/ - MonsterType::Monest => { for _ in 0..30 { monsters.push(Some(MapEnemy::new(MonsterType::Mothmant, monster.map_area))); @@ -235,21 +148,17 @@ fn parse_enemy(episode: &Episode, map_area: &MapArea, raw_enemy: RawMapEnemy) -> pub fn enemy_data_from_stream(cursor: &mut impl Read, map_area: &MapArea, episode: &Episode) -> Vec> { -// pub fn enemy_data_from_stream(cursor: &mut impl Read, map_area: &MapArea, episode: &Episode, rare_monster_table: enemy::RareMonsterAppearTable) -> Vec> { let mut enemy_data = Vec::new(); while let Ok(enemy) = RawMapEnemy::from_byte_stream(cursor) { enemy_data.append(&mut parse_enemy(episode, map_area, enemy)); - // enemy_data.append(&mut parse_enemy(episode, map_area, enemy, rare_monster_table)); } enemy_data } fn enemy_data_from_map_data(map_variant: &MapVariant, episode: &Episode) -> Vec> { -// fn enemy_data_from_map_data(map_variant: &MapVariant, episode: &Episode, rare_monster_table: enemy::RareMonsterAppearTable) -> Vec> { let path = map_variant.dat_file(); let mut cursor = File::open(path).unwrap(); enemy_data_from_stream(&mut cursor, &map_variant.map, episode) - // enemy_data_from_stream(&mut cursor, &map_variant.map, episode, rare_monster_table) } @@ -268,7 +177,6 @@ pub struct Maps { } impl Maps { - // pub fn new(room_mode: RoomMode) -> Maps { pub fn new(room_mode: RoomMode, rare_monster_table: &enemy::RareMonsterAppearTable) -> Maps { let map_variants = match (room_mode.episode(), room_mode.single_player()) { (Episode::One, 0) => { @@ -365,7 +273,6 @@ impl Maps { enemy_data: map_variants.iter() .fold(Vec::new(), |mut enemy_data, map_variant| { enemy_data.append(&mut enemy_data_from_map_data(map_variant, &room_mode.episode())); - // enemy_data.append(&mut enemy_data_from_map_data(map_variant, &room_mode.episode(), rare_monster_table)); enemy_data }), object_data: map_variants.iter() @@ -398,20 +305,9 @@ impl Maps { }) } - // pub fn set_quest_data(&mut self, enemies: Vec>, objects: Vec>) { pub fn set_quest_data(&mut self, enemies: Vec>, objects: Vec>, rare_monster_appear_table: &RareMonsterAppearTable) { self.enemy_data = enemies; self.roll_monster_appearance(rare_monster_appear_table); - - // self.enemy_data = enemies - // .iter() - // .map(|&x| if x.is_some() { - // Some(x.unwrap().roll_appearance_for_quest(rare_monster_table)) - // } else { - // x - // }) - // .collect(); - self.object_data = objects; } diff --git a/src/ship/packet/handler/quest.rs b/src/ship/packet/handler/quest.rs index c993579..3c4e7b4 100644 --- a/src/ship/packet/handler/quest.rs +++ b/src/ship/packet/handler/quest.rs @@ -83,7 +83,6 @@ pub fn player_chose_quest(id: ClientId, questmenuselect: &QuestMenuSelect, quest let room = rooms.get_mut(room_id.0) .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?.as_mut() .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?; - // room.maps.set_quest_data(quest.enemies.clone(), quest.objects.clone()); room.maps.set_quest_data(quest.enemies.clone(), quest.objects.clone(), &room.rare_monster_table); room.map_areas = quest.map_areas.clone(); diff --git a/src/ship/room.rs b/src/ship/room.rs index 3f0918a..cfee400 100644 --- a/src/ship/room.rs +++ b/src/ship/room.rs @@ -233,19 +233,16 @@ impl RoomState { } }; - let random_seed = rand::thread_rng().gen(); - let rare_monster_table = RareMonsterAppearTable::new(room_mode.episode(), random_seed); + let rare_monster_table = RareMonsterAppearTable::new(room_mode.episode()); Ok(RoomState { monster_stats: Box::new(load_monster_stats_table(&room_mode).map_err(|_| RoomCreationError::CouldNotLoadMonsterStats(room_mode))?), mode: room_mode, - // random_seed: rand::thread_rng().gen(), - random_seed: random_seed, + random_seed: rand::thread_rng().gen(), rare_monster_table: Box::new(rare_monster_table.clone()), name: String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).into(), password: create_room.password, - // maps: Maps::new(room_mode), - maps: Maps::new(room_mode, &rare_monster_table), + maps: Maps::new(room_mode, &rare_monster_table), // TODO: rare_monster_table here feels janky. is there some way to call the the RoomState.rare_monster_table we already created? section_id, drop_table: Box::new(DropTable::new(room_mode.episode(), room_mode.difficulty(), section_id)), bursting: false,