clean up and set rare monster appear rate to 1/512
This commit is contained in:
		
							parent
							
								
									5c49ded823
								
							
						
					
					
						commit
						309b97cbc2
					
				| @ -3,7 +3,7 @@ | ||||
| # 1/256 = 0.00390625 | ||||
| # 1/512 = 0.001953125 | ||||
| 
 | ||||
| Hildebear = 0.1 | ||||
| RagRappy = 0.2 | ||||
| PoisonLily = 0.3 | ||||
| PofuillySlime = 0.4 | ||||
| Hildebear = 0.001953125 | ||||
| RagRappy = 0.001953125 | ||||
| PoisonLily = 0.001953125 | ||||
| PofuillySlime = 0.001953125 | ||||
|  | ||||
| @ -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 | ||||
| 
 | ||||
|  | ||||
| @ -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 | ||||
| @ -57,9 +57,9 @@ pub fn load_data_file<T: serde::de::DeserializeOwned>(episode: Episode, difficul | ||||
| 
 | ||||
| // this is just copypaste
 | ||||
| pub fn load_rare_monster_file<T: serde::de::DeserializeOwned>(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(); | ||||
|  | ||||
| @ -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<MonsterType, f32>,
 | ||||
| 
 | ||||
| // making this `pub type` doesn't allow `impl`s to be defined?
 | ||||
| #[derive(Clone, Debug, Serialize, Deserialize)] | ||||
| pub struct RareMonsterAppearTable { | ||||
|     appear_rate: HashMap<MonsterType, f32>, | ||||
|     seed: u32 | ||||
| } | ||||
| 
 | ||||
| impl RareMonsterAppearTable { | ||||
|     pub fn new(episode: Episode, room_seed: u32) -> RareMonsterAppearTable { | ||||
|     pub fn new(episode: Episode) -> RareMonsterAppearTable { | ||||
|         let cfg: HashMap<String, f32> = load_rare_monster_file(episode); | ||||
|         println!("got cfg: {:?}", cfg); | ||||
| 
 | ||||
|         let appear_rates: HashMap<MonsterType, f32> = cfg | ||||
|             .into_iter() | ||||
| @ -102,22 +96,15 @@ 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::<f32>() < *self.appear_rate.get(monster).unwrap_or(&0.0f32) { | ||||
|             println!("its a rare!"); | ||||
|             true | ||||
|             return true | ||||
|         } | ||||
|         else { | ||||
|             println!("lol sucker"); | ||||
|         false | ||||
|     } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @ -135,7 +122,6 @@ pub struct MapEnemy { | ||||
| 
 | ||||
| impl MapEnemy { | ||||
|     pub fn from_raw(enemy: RawMapEnemy, episode: &Episode, map_area: &MapArea /*, battleparam */) -> Result<MapEnemy, MapEnemyError> { | ||||
|         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 | | ||||
| @ -349,21 +334,10 @@ impl MapEnemy { | ||||
|         } | ||||
|     } | ||||
|     
 | ||||
|     // // 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}}, | ||||
|  | ||||
| @ -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<Option<MapObject>> { | ||||
|     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<Option<MapEnemy>> { | ||||
| // fn parse_enemy(episode: &Episode, map_area: &MapArea, raw_enemy: RawMapEnemy, rare_monster_table: RareMonsterAppearTable) -> Vec<Option<MapEnemy>> {
 | ||||
|     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<Option<MapEnemy>> { | ||||
| // pub fn enemy_data_from_stream(cursor: &mut impl Read, map_area: &MapArea, episode: &Episode, rare_monster_table: enemy::RareMonsterAppearTable) -> Vec<Option<MapEnemy>> {
 | ||||
|     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<Option<MapEnemy>> { | ||||
| // fn enemy_data_from_map_data(map_variant: &MapVariant, episode: &Episode, rare_monster_table: enemy::RareMonsterAppearTable) -> Vec<Option<MapEnemy>> {
 | ||||
|     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<Option<MapEnemy>>, objects: Vec<Option<MapObject>>) {
 | ||||
|     pub fn set_quest_data(&mut self, enemies: Vec<Option<MapEnemy>>, objects: Vec<Option<MapObject>>, 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; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -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(); | ||||
| 
 | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user