Browse Source

cleanup rare enemy generation

pull/122/head
jake 2 years ago
parent
commit
ed9f951bca
  1. 24
      src/ship/map/enemy.rs
  2. 67
      src/ship/map/maps.rs

24
src/ship/map/enemy.rs

@ -87,10 +87,9 @@ impl RareMonsterAppearTable {
let appear_rates: HashMap<MonsterType, f32> = cfg
.into_iter()
.map(|(monster, rate)| {
let monster: MonsterType = monster.parse().unwrap(); // TODO: don't unwrap!
let appear_rate = rate;
(monster, appear_rate)
.filter_map(|(monster, rate)| {
let monster: MonsterType = monster.parse().ok()?;
Some((monster, rate))
})
.collect();
@ -99,7 +98,7 @@ impl RareMonsterAppearTable {
}
}
pub fn roll_appearance(&self, monster: &MonsterType) -> bool {
pub fn roll_is_rare(&self, monster: &MonsterType) -> bool {
if rand_chacha::ChaChaRng::from_entropy().gen::<f32>() < *self.appear_rate.get(monster).unwrap_or(&0.0f32) {
return true
}
@ -324,7 +323,7 @@ impl MapEnemy {
}
}
pub fn has_rare_appearance(self) -> bool {
pub fn can_be_rare(&self) -> bool {
matches!(self.monster,
MonsterType::RagRappy | MonsterType::Hildebear |
MonsterType::PoisonLily | MonsterType::PofuillySlime |
@ -339,10 +338,10 @@ impl MapEnemy {
guaranteed rare monsters don't count towards the limit
*/
#[must_use]
pub fn set_rare_appearance(self) -> MapEnemy {
pub fn into_rare(self) -> MapEnemy {
match (self.monster, self.map_area.to_episode()) {
(MonsterType::RagRappy, Episode::One) => {MapEnemy {monster: MonsterType::AlRappy, shiny:true, ..self}},
(MonsterType::RagRappy, Episode::Two) => {MapEnemy {monster: MonsterType::EventRappy, shiny:true, ..self}},
(MonsterType::RagRappy, Episode::Two) => {MapEnemy {monster: MonsterType::LoveRappy, shiny:true, ..self}},
(MonsterType::Hildebear, _) => {MapEnemy {monster: MonsterType::Hildeblue, shiny:true, ..self}},
(MonsterType::PoisonLily, _) => {MapEnemy {monster: MonsterType::NarLily, shiny:true, ..self}},
(MonsterType::PofuillySlime, _) => {MapEnemy {monster: MonsterType::PouillySlime, shiny:true, ..self}},
@ -357,14 +356,5 @@ impl MapEnemy {
_ => {self},
}
}
// in theory this should only be called on monsters we know can have rare types
#[must_use]
pub fn roll_appearance_for_mission(self, rare_monster_table: &RareMonsterAppearTable) -> MapEnemy {
if rare_monster_table.roll_appearance(&self.monster) {
return self.set_rare_appearance()
}
self
}
}

67
src/ship/map/maps.rs

@ -278,20 +278,20 @@ impl Maps {
_ => unreachable!()
};
let mut maps = Maps {
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
}),
.map(|map_variant| {
enemy_data_from_map_data(map_variant, &room_mode.episode())
})
.flatten()
.map(|enemy| apply_rare_enemy(enemy, rare_monster_table))
.collect(),
object_data: map_variants.iter()
.flat_map(|map_variant| {
objects_from_map_data(map_variant.obj_file().into(), &room_mode.episode(), &map_variant.map)
}).collect(),
map_variants,
};
maps.roll_monster_appearance(rare_monster_table);
maps
.flat_map(|map_variant| {
objects_from_map_data(map_variant.obj_file().into(), &room_mode.episode(), &map_variant.map)
}).collect(),
map_variants,
}
}
pub fn enemy_by_id(&self, id: usize) -> Result<MapEnemy, MapsError> {
@ -314,9 +314,11 @@ impl Maps {
})
}
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);
pub fn set_quest_data(&mut self, enemies: Vec<Option<MapEnemy>>, objects: Vec<Option<MapObject>>, rare_monster_table: &RareMonsterAppearTable) {
self.enemy_data = enemies
.into_iter()
.map(|enemy| apply_rare_enemy(enemy, rare_monster_table))
.collect();
self.object_data = objects;
}
@ -325,10 +327,11 @@ impl Maps {
let shiny: Vec<(usize, &Option<MapEnemy>)> = self.enemy_data.iter()
.enumerate()
.filter(|(_,m)| {
if m.is_some() {
m.unwrap().shiny
} else {
false
match m {
Some(m) => {
m.shiny
},
None => false,
}
})
.collect();
@ -341,21 +344,15 @@ impl Maps {
}
rare_monsters
}
}
pub fn roll_monster_appearance(&mut self, rare_monster_table: &RareMonsterAppearTable) {
self.enemy_data = self.enemy_data
.iter()
.map(|&x|
if let Some(monster) = x {
if monster.has_rare_appearance() {
Some(monster.roll_appearance_for_mission(rare_monster_table))
} else {
Some(monster)
}
} else {
x
}
)
.collect();
}
fn apply_rare_enemy(enemy: Option<MapEnemy>, rare_enemy_table: &RareMonsterAppearTable) -> Option<MapEnemy> {
enemy.map(|enemy| {
if enemy.can_be_rare() && rare_enemy_table.roll_is_rare(&enemy.monster) {
enemy.into_rare()
}
else {
enemy
}
})
}
Loading…
Cancel
Save