Browse Source

add some vars to MapEnemy, error types to misc map functions, and MapArea -> u8

pbs
jake 4 years ago
parent
commit
0e3b305f95
  1. 103
      src/ship/map.rs

103
src/ship/map.rs

@ -7,6 +7,7 @@ use std::fs::File;
use byteorder::{LittleEndian, ReadBytesExt}; use byteorder::{LittleEndian, ReadBytesExt};
use rand::Rng; use rand::Rng;
use thiserror::Error;
use crate::ship::monster::MonsterType; use crate::ship::monster::MonsterType;
use crate::ship::room::Episode; use crate::ship::room::Episode;
@ -65,18 +66,22 @@ impl RawMapEnemy {
} }
#[derive(Debug)]
#[derive(Error, Debug)]
#[error("")]
enum MapEnemyError { enum MapEnemyError {
UnknownEnemyId(u32), UnknownEnemyId(u32),
MapAreaError(#[from] MapAreaError),
} }
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MapEnemy { pub struct MapEnemy {
pub monster: MonsterType, pub monster: MonsterType,
pub map_area: MapArea,
hp: u32, hp: u32,
// other stats from bp.n
dead: bool,
// TODO: other stats from battleparam
pub dropped_item: bool,
pub gave_exp: bool,
} }
impl MapEnemy { impl MapEnemy {
@ -169,16 +174,20 @@ impl MapEnemy {
Ok(MapEnemy { Ok(MapEnemy {
monster: monster, monster: monster,
map_area: MapArea::from_value(&episode, enemy.map_area as u32)?,
hp: 0, hp: 0,
dead: false,
dropped_item: false,
gave_exp: false,
}) })
} }
fn new(monster: MonsterType) -> MapEnemy {
fn new(monster: MonsterType, map_area: MapArea) -> MapEnemy {
MapEnemy { MapEnemy {
monster: monster, monster: monster,
map_area: map_area,
hp: 0, hp: 0,
dead: false,
dropped_item: false,
gave_exp: false,
} }
} }
} }
@ -340,7 +349,7 @@ enum MapVariantMode {
Offline, Offline,
} }
#[derive(Debug)]
#[derive(Debug, Copy, Clone)]
pub enum MapArea { pub enum MapArea {
Pioneer2Ep1, Pioneer2Ep1,
Forest1, Forest1,
@ -359,12 +368,14 @@ pub enum MapArea {
DarkFalz, DarkFalz,
} }
#[derive(Error, Debug)]
#[error("")]
pub enum MapAreaError { pub enum MapAreaError {
UnknownMapArea(u32), UnknownMapArea(u32),
} }
impl MapArea { impl MapArea {
pub fn from_value(episode: Episode, area: u32) -> Result<MapArea, MapAreaError> {
pub fn from_value(episode: &Episode, area: u32) -> Result<MapArea, MapAreaError> {
match (episode, area) { match (episode, area) {
(Episode::One, 0) => Ok(MapArea::Pioneer2Ep1), (Episode::One, 0) => Ok(MapArea::Pioneer2Ep1),
(Episode::One, 1) => Ok(MapArea::Forest1), (Episode::One, 1) => Ok(MapArea::Forest1),
@ -404,6 +415,26 @@ impl MapArea {
_ => None _ => None
} }
} }
pub fn area_value(&self) -> u8 {
match self {
MapArea::Pioneer2Ep1 => 0,
MapArea::Forest1 => 1,
MapArea::Forest2 => 2,
MapArea::Caves1 => 3,
MapArea::Caves2 => 4,
MapArea::Caves3 => 5,
MapArea::Mines1 => 6,
MapArea::Mines2 => 7,
MapArea::Ruins1 => 8,
MapArea::Ruins2 => 9,
MapArea::Ruins3 => 10,
MapArea::Dragon => 11,
MapArea::DeRolLe => 12,
MapArea::VolOpt => 13,
MapArea::DarkFalz => 14,
}
}
} }
@ -516,76 +547,76 @@ fn enemy_data_from_map_data(path: PathBuf, episode: &Episode) -> Vec<Option<MapE
match monster.monster { match monster.monster {
MonsterType::Monest => { MonsterType::Monest => {
for _ in 0..30 { for _ in 0..30 {
monsters.push(Some(MapEnemy::new(MonsterType::Mothmant)));
monsters.push(Some(MapEnemy::new(MonsterType::Mothmant, monster.map_area)));
} }
}, },
MonsterType::PofuillySlime => { MonsterType::PofuillySlime => {
for _ in 0..4 { for _ in 0..4 {
monsters.push(Some(MapEnemy::new(MonsterType::PofuillySlime)));
monsters.push(Some(MapEnemy::new(MonsterType::PofuillySlime, monster.map_area)));
} }
}, },
MonsterType::PanArms => { MonsterType::PanArms => {
monsters.push(Some(MapEnemy::new(MonsterType::Hidoom)));
monsters.push(Some(MapEnemy::new(MonsterType::Migium)));
monsters.push(Some(MapEnemy::new(MonsterType::Hidoom, monster.map_area)));
monsters.push(Some(MapEnemy::new(MonsterType::Migium, monster.map_area)));
}, },
MonsterType::SinowBeat => { MonsterType::SinowBeat => {
for _ in 0..4 { for _ in 0..4 {
monsters.push(Some(MapEnemy::new(MonsterType::SinowBeat)));
monsters.push(Some(MapEnemy::new(MonsterType::SinowBeat, monster.map_area)));
} }
}, },
MonsterType::SinowGold => { MonsterType::SinowGold => {
for _ in 0..4 { for _ in 0..4 {
monsters.push(Some(MapEnemy::new(MonsterType::SinowGold)));
monsters.push(Some(MapEnemy::new(MonsterType::SinowGold, monster.map_area)));
} }
}, },
MonsterType::Canane => { MonsterType::Canane => {
for _ in 0..8 { for _ in 0..8 {
monsters.push(Some(MapEnemy::new(MonsterType::RingCanadine)));
monsters.push(Some(MapEnemy::new(MonsterType::RingCanadine, monster.map_area)));
} }
}, },
MonsterType::ChaosSorcerer => { MonsterType::ChaosSorcerer => {
monsters.push(Some(MapEnemy::new(MonsterType::BeeR)));
monsters.push(Some(MapEnemy::new(MonsterType::BeeL)));
monsters.push(Some(MapEnemy::new(MonsterType::BeeR, monster.map_area)));
monsters.push(Some(MapEnemy::new(MonsterType::BeeL, monster.map_area)));
}, },
MonsterType::Bulclaw => { MonsterType::Bulclaw => {
for _ in 0..4 { for _ in 0..4 {
monsters.push(Some(MapEnemy::new(MonsterType::Claw)));
monsters.push(Some(MapEnemy::new(MonsterType::Claw, monster.map_area)));
} }
}, },
MonsterType::DeRolLe => { MonsterType::DeRolLe => {
for _ in 0..10 { for _ in 0..10 {
monsters.push(Some(MapEnemy::new(MonsterType::DeRolLeBody)));
monsters.push(Some(MapEnemy::new(MonsterType::DeRolLeBody, monster.map_area)));
} }
for _ in 0..9 { for _ in 0..9 {
monsters.push(Some(MapEnemy::new(MonsterType::DeRolLeMine)));
monsters.push(Some(MapEnemy::new(MonsterType::DeRolLeMine, monster.map_area)));
} }
}, },
MonsterType::VolOptPartA => { MonsterType::VolOptPartA => {
for _ in 0..6 { for _ in 0..6 {
monsters.push(Some(MapEnemy::new(MonsterType::VolOptPillar)));
monsters.push(Some(MapEnemy::new(MonsterType::VolOptPillar, monster.map_area)));
} }
for _ in 0..24 { for _ in 0..24 {
monsters.push(Some(MapEnemy::new(MonsterType::VolOptMonitor)));
monsters.push(Some(MapEnemy::new(MonsterType::VolOptMonitor, monster.map_area)));
} }
for _ in 0..2 { for _ in 0..2 {
monsters.push(Some(MapEnemy::new(MonsterType::VolOptUnused)));
monsters.push(Some(MapEnemy::new(MonsterType::VolOptUnused, monster.map_area)));
} }
monsters.push(Some(MapEnemy::new(MonsterType::VolOptAmp)));
monsters.push(Some(MapEnemy::new(MonsterType::VolOptCore)));
monsters.push(Some(MapEnemy::new(MonsterType::VolOptUnused)));
monsters.push(Some(MapEnemy::new(MonsterType::VolOptAmp, monster.map_area)));
monsters.push(Some(MapEnemy::new(MonsterType::VolOptCore, monster.map_area)));
monsters.push(Some(MapEnemy::new(MonsterType::VolOptUnused, monster.map_area)));
}, },
// TOOD: this cares about difficulty (theres an ult-specific darvant?) // TOOD: this cares about difficulty (theres an ult-specific darvant?)
MonsterType::DarkFalz => { MonsterType::DarkFalz => {
for _ in 0..509 { for _ in 0..509 {
monsters.push(Some(MapEnemy::new(MonsterType::Darvant)));
monsters.push(Some(MapEnemy::new(MonsterType::Darvant, monster.map_area)));
} }
monsters.push(Some(MapEnemy::new(MonsterType::DarkFalz3)));
monsters.push(Some(MapEnemy::new(MonsterType::DarkFalz2)));
monsters.push(Some(MapEnemy::new(MonsterType::DarkFalz1)));
monsters.push(Some(MapEnemy::new(MonsterType::DarkFalz3, monster.map_area)));
monsters.push(Some(MapEnemy::new(MonsterType::DarkFalz2, monster.map_area)));
monsters.push(Some(MapEnemy::new(MonsterType::DarkFalz1, monster.map_area)));
}, },
_ => { _ => {
for _ in 0..enemy.children { for _ in 0..enemy.children {
monsters.push(Some(MapEnemy::new(monster.monster)));
monsters.push(Some(MapEnemy::new(monster.monster, monster.map_area)));
} }
} }
} }
@ -596,6 +627,12 @@ fn enemy_data_from_map_data(path: PathBuf, episode: &Episode) -> Vec<Option<MapE
} }
#[derive(Error, Debug)]
#[error("")]
pub enum MapsError {
InvalidMonsterId(usize),
}
#[derive(Debug)] #[derive(Debug)]
pub struct Maps { pub struct Maps {
map_variants: [MapVariant; 15], map_variants: [MapVariant; 15],
@ -641,8 +678,8 @@ impl Maps {
maps maps
} }
pub fn enemy_by_id(&self, id: usize) -> MapEnemy {
self.enemy_data[id].unwrap()
pub fn enemy_by_id(&self, id: usize) -> Result<MapEnemy, MapsError> {
self.enemy_data[id].ok_or(MapsError::InvalidMonsterId(id))
} }
pub fn map_headers(&self) -> [u32; 0x20] { pub fn map_headers(&self) -> [u32; 0x20] {

Loading…
Cancel
Save