|
@ -1,4 +1,5 @@ |
|
|
// TOOD: `pub(super) for most of these?`
|
|
|
// TOOD: `pub(super) for most of these?`
|
|
|
|
|
|
use std::collections::HashMap;
|
|
|
use thiserror::Error;
|
|
|
use thiserror::Error;
|
|
|
use crate::ship::room::Episode;
|
|
|
use crate::ship::room::Episode;
|
|
|
|
|
|
|
|
@ -57,53 +58,55 @@ pub enum MapAreaError { |
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
impl MapArea {
|
|
|
impl MapArea {
|
|
|
pub fn from_value(episode: &Episode, area: u16) -> Result<MapArea, MapAreaError> {
|
|
|
|
|
|
match (episode, area) {
|
|
|
|
|
|
(Episode::One, 0) => Ok(MapArea::Pioneer2Ep1),
|
|
|
|
|
|
(Episode::One, 1) => Ok(MapArea::Forest1),
|
|
|
|
|
|
(Episode::One, 2) => Ok(MapArea::Forest2),
|
|
|
|
|
|
(Episode::One, 3) => Ok(MapArea::Caves1),
|
|
|
|
|
|
(Episode::One, 4) => Ok(MapArea::Caves2),
|
|
|
|
|
|
(Episode::One, 5) => Ok(MapArea::Caves3),
|
|
|
|
|
|
(Episode::One, 6) => Ok(MapArea::Mines1),
|
|
|
|
|
|
(Episode::One, 7) => Ok(MapArea::Mines2),
|
|
|
|
|
|
(Episode::One, 8) => Ok(MapArea::Ruins1),
|
|
|
|
|
|
(Episode::One, 9) => Ok(MapArea::Ruins2),
|
|
|
|
|
|
(Episode::One, 10) => Ok(MapArea::Ruins3),
|
|
|
|
|
|
(Episode::One, 11) => Ok(MapArea::Dragon),
|
|
|
|
|
|
(Episode::One, 12) => Ok(MapArea::DeRolLe),
|
|
|
|
|
|
(Episode::One, 13) => Ok(MapArea::VolOpt),
|
|
|
|
|
|
(Episode::One, 14) => Ok(MapArea::DarkFalz),
|
|
|
|
|
|
(Episode::Two, 0) => Ok(MapArea::Pioneer2Ep2),
|
|
|
|
|
|
(Episode::Two, 1) => Ok(MapArea::VrTempleAlpha),
|
|
|
|
|
|
(Episode::Two, 2) => Ok(MapArea::VrTempleBeta),
|
|
|
|
|
|
(Episode::Two, 3) => Ok(MapArea::VrSpaceshipAlpha),
|
|
|
|
|
|
(Episode::Two, 4) => Ok(MapArea::VrSpaceshipBeta),
|
|
|
|
|
|
(Episode::Two, 5) => Ok(MapArea::Cca),
|
|
|
|
|
|
(Episode::Two, 6) => Ok(MapArea::JungleAreaNorth),
|
|
|
|
|
|
(Episode::Two, 7) => Ok(MapArea::JungleAreaEast),
|
|
|
|
|
|
(Episode::Two, 8) => Ok(MapArea::Mountain),
|
|
|
|
|
|
(Episode::Two, 9) => Ok(MapArea::Seaside),
|
|
|
|
|
|
(Episode::Two, 10) => Ok(MapArea::SeabedUpper),
|
|
|
|
|
|
(Episode::Two, 11) => Ok(MapArea::SeabedLower),
|
|
|
|
|
|
(Episode::Two, 12) => Ok(MapArea::GalGryphon),
|
|
|
|
|
|
(Episode::Two, 13) => Ok(MapArea::OlgaFlow),
|
|
|
|
|
|
(Episode::Two, 14) => Ok(MapArea::BarbaRay),
|
|
|
|
|
|
(Episode::Two, 15) => Ok(MapArea::GolDragon),
|
|
|
|
|
|
(Episode::Two, 16) => Ok(MapArea::SeasideNight),
|
|
|
|
|
|
(Episode::Two, 17) => Ok(MapArea::Tower),
|
|
|
|
|
|
(Episode::Four, 0) => Ok(MapArea::Pioneer2Ep4),
|
|
|
|
|
|
(Episode::Four, 1) => Ok(MapArea::CraterEast),
|
|
|
|
|
|
(Episode::Four, 2) => Ok(MapArea::CraterWest),
|
|
|
|
|
|
(Episode::Four, 3) => Ok(MapArea::CraterSouth),
|
|
|
|
|
|
(Episode::Four, 4) => Ok(MapArea::CraterNorth),
|
|
|
|
|
|
(Episode::Four, 5) => Ok(MapArea::CraterInterior),
|
|
|
|
|
|
(Episode::Four, 6) => Ok(MapArea::SubDesert1),
|
|
|
|
|
|
(Episode::Four, 7) => Ok(MapArea::SubDesert2),
|
|
|
|
|
|
(Episode::Four, 8) => Ok(MapArea::SubDesert3),
|
|
|
|
|
|
(Episode::Four, 9) => Ok(MapArea::SaintMillion),
|
|
|
|
|
|
// (Episode::Four, 10) => Ok(MapArea::TestMapEp4),
|
|
|
|
|
|
_ => Err(MapAreaError::UnknownMapArea(area))
|
|
|
|
|
|
|
|
|
pub fn from_bb_map_designate(map_number: u8) -> Option<MapArea> {
|
|
|
|
|
|
match map_number {
|
|
|
|
|
|
0 => Some(MapArea::Pioneer2Ep1),
|
|
|
|
|
|
1 => Some(MapArea::Forest1),
|
|
|
|
|
|
2 => Some(MapArea::Forest2),
|
|
|
|
|
|
3 => Some(MapArea::Caves1),
|
|
|
|
|
|
4 => Some(MapArea::Caves2),
|
|
|
|
|
|
5 => Some(MapArea::Caves3),
|
|
|
|
|
|
6 => Some(MapArea::Mines1),
|
|
|
|
|
|
7 => Some(MapArea::Mines2),
|
|
|
|
|
|
8 => Some(MapArea::Ruins1),
|
|
|
|
|
|
9 => Some(MapArea::Ruins2),
|
|
|
|
|
|
10 => Some(MapArea::Ruins3),
|
|
|
|
|
|
11 => Some(MapArea::Dragon),
|
|
|
|
|
|
12 => Some(MapArea::DeRolLe),
|
|
|
|
|
|
13 => Some(MapArea::VolOpt),
|
|
|
|
|
|
14 => Some(MapArea::DarkFalz),
|
|
|
|
|
|
|
|
|
|
|
|
18 => Some(MapArea::Pioneer2Ep2),
|
|
|
|
|
|
19 => Some(MapArea::VrTempleAlpha),
|
|
|
|
|
|
20 => Some(MapArea::VrTempleBeta),
|
|
|
|
|
|
21 => Some(MapArea::VrSpaceshipAlpha),
|
|
|
|
|
|
22 => Some(MapArea::VrSpaceshipBeta),
|
|
|
|
|
|
23 => Some(MapArea::Cca),
|
|
|
|
|
|
24 => Some(MapArea::JungleAreaNorth),
|
|
|
|
|
|
25 => Some(MapArea::JungleAreaEast),
|
|
|
|
|
|
26 => Some(MapArea::Mountain),
|
|
|
|
|
|
27 => Some(MapArea::Seaside),
|
|
|
|
|
|
28 => Some(MapArea::SeabedUpper),
|
|
|
|
|
|
29 => Some(MapArea::SeabedLower),
|
|
|
|
|
|
30 => Some(MapArea::GalGryphon),
|
|
|
|
|
|
31 => Some(MapArea::OlgaFlow),
|
|
|
|
|
|
32 => Some(MapArea::BarbaRay),
|
|
|
|
|
|
33 => Some(MapArea::GolDragon),
|
|
|
|
|
|
34 => Some(MapArea::SeasideNight),
|
|
|
|
|
|
35 => Some(MapArea::Tower),
|
|
|
|
|
|
|
|
|
|
|
|
45 => Some(MapArea::Pioneer2Ep4),
|
|
|
|
|
|
36 => Some(MapArea::CraterEast),
|
|
|
|
|
|
37 => Some(MapArea::CraterWest),
|
|
|
|
|
|
38 => Some(MapArea::CraterSouth),
|
|
|
|
|
|
39 => Some(MapArea::CraterNorth),
|
|
|
|
|
|
40 => Some(MapArea::CraterInterior),
|
|
|
|
|
|
41 => Some(MapArea::SubDesert1),
|
|
|
|
|
|
42 => Some(MapArea::SubDesert2),
|
|
|
|
|
|
43 => Some(MapArea::SubDesert3),
|
|
|
|
|
|
44 => Some(MapArea::SaintMillion),
|
|
|
|
|
|
|
|
|
|
|
|
_=> None
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
@ -139,7 +142,7 @@ impl MapArea { |
|
|
MapArea::OlgaFlow => Some(9),
|
|
|
MapArea::OlgaFlow => Some(9),
|
|
|
MapArea::BarbaRay => Some(2),
|
|
|
MapArea::BarbaRay => Some(2),
|
|
|
MapArea::GolDragon => Some(5),
|
|
|
MapArea::GolDragon => Some(5),
|
|
|
MapArea::SeasideNight => Some(7),
|
|
|
|
|
|
|
|
|
MapArea::SeasideNight => Some(7), // TODO: this could also be 9? needs research
|
|
|
MapArea::Tower => Some(9),
|
|
|
MapArea::Tower => Some(9),
|
|
|
|
|
|
|
|
|
MapArea::CraterEast => Some(2),
|
|
|
MapArea::CraterEast => Some(2),
|
|
@ -205,3 +208,101 @@ impl MapArea { |
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
|
pub struct MapAreaLookup(HashMap<u16, MapArea>);
|
|
|
|
|
|
|
|
|
|
|
|
impl MapAreaLookup {
|
|
|
|
|
|
pub fn get_area_map(&self, map_area: u16) -> Result<&MapArea, MapAreaError> {
|
|
|
|
|
|
self.0.get(&map_area).ok_or(MapAreaError::UnknownMapArea(map_area))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn default_ep1_maps() -> MapAreaLookup {
|
|
|
|
|
|
let mut ep1 = HashMap::new();
|
|
|
|
|
|
ep1.insert(0, MapArea::Pioneer2Ep1);
|
|
|
|
|
|
ep1.insert(1, MapArea::Forest1);
|
|
|
|
|
|
ep1.insert(2, MapArea::Forest2);
|
|
|
|
|
|
ep1.insert(3, MapArea::Caves1);
|
|
|
|
|
|
ep1.insert(4, MapArea::Caves2);
|
|
|
|
|
|
ep1.insert(5, MapArea::Caves3);
|
|
|
|
|
|
ep1.insert(6, MapArea::Mines1);
|
|
|
|
|
|
ep1.insert(7, MapArea::Mines2);
|
|
|
|
|
|
ep1.insert(8, MapArea::Ruins1);
|
|
|
|
|
|
ep1.insert(9, MapArea::Ruins2);
|
|
|
|
|
|
ep1.insert(10, MapArea::Ruins3);
|
|
|
|
|
|
ep1.insert(11, MapArea::Dragon);
|
|
|
|
|
|
ep1.insert(12, MapArea::DeRolLe);
|
|
|
|
|
|
ep1.insert(13, MapArea::VolOpt);
|
|
|
|
|
|
ep1.insert(14, MapArea::DarkFalz);
|
|
|
|
|
|
MapAreaLookup(ep1)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn default_ep2_maps() -> MapAreaLookup {
|
|
|
|
|
|
let mut ep2 = HashMap::new();
|
|
|
|
|
|
ep2.insert(0, MapArea::Pioneer2Ep2);
|
|
|
|
|
|
ep2.insert(1, MapArea::VrTempleAlpha);
|
|
|
|
|
|
ep2.insert(2, MapArea::VrTempleBeta);
|
|
|
|
|
|
ep2.insert(3, MapArea::VrSpaceshipAlpha);
|
|
|
|
|
|
ep2.insert(4, MapArea::VrSpaceshipBeta);
|
|
|
|
|
|
ep2.insert(5, MapArea::Cca);
|
|
|
|
|
|
ep2.insert(6, MapArea::JungleAreaNorth);
|
|
|
|
|
|
ep2.insert(7, MapArea::JungleAreaEast);
|
|
|
|
|
|
ep2.insert(8, MapArea::Mountain);
|
|
|
|
|
|
ep2.insert(9, MapArea::Seaside);
|
|
|
|
|
|
ep2.insert(10, MapArea::SeabedUpper);
|
|
|
|
|
|
ep2.insert(11, MapArea::SeabedLower);
|
|
|
|
|
|
ep2.insert(12, MapArea::GalGryphon);
|
|
|
|
|
|
ep2.insert(13, MapArea::OlgaFlow);
|
|
|
|
|
|
ep2.insert(14, MapArea::BarbaRay);
|
|
|
|
|
|
ep2.insert(15, MapArea::GolDragon);
|
|
|
|
|
|
ep2.insert(16, MapArea::SeasideNight);
|
|
|
|
|
|
ep2.insert(17, MapArea::Tower);
|
|
|
|
|
|
MapAreaLookup(ep2)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn default_ep4_maps() -> MapAreaLookup {
|
|
|
|
|
|
let mut ep4 = HashMap::new();
|
|
|
|
|
|
ep4.insert(0, MapArea::Pioneer2Ep4);
|
|
|
|
|
|
ep4.insert(1, MapArea::CraterEast);
|
|
|
|
|
|
ep4.insert(2, MapArea::CraterWest);
|
|
|
|
|
|
ep4.insert(3, MapArea::CraterSouth);
|
|
|
|
|
|
ep4.insert(4, MapArea::CraterNorth);
|
|
|
|
|
|
ep4.insert(5, MapArea::CraterInterior);
|
|
|
|
|
|
ep4.insert(6, MapArea::SubDesert1);
|
|
|
|
|
|
ep4.insert(7, MapArea::SubDesert2);
|
|
|
|
|
|
ep4.insert(8, MapArea::SubDesert3);
|
|
|
|
|
|
ep4.insert(9, MapArea::SaintMillion);
|
|
|
|
|
|
MapAreaLookup(ep4)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn new(episode: &Episode) -> MapAreaLookup {
|
|
|
|
|
|
match episode {
|
|
|
|
|
|
Episode::One => MapAreaLookup::default_ep1_maps(),
|
|
|
|
|
|
Episode::Two => MapAreaLookup::default_ep2_maps(),
|
|
|
|
|
|
Episode::Four => MapAreaLookup::default_ep4_maps(),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub struct MapAreaLookupBuilder {
|
|
|
|
|
|
map_areas: HashMap<u16, MapArea>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl MapAreaLookupBuilder {
|
|
|
|
|
|
pub fn new() -> MapAreaLookupBuilder {
|
|
|
|
|
|
MapAreaLookupBuilder {
|
|
|
|
|
|
map_areas: HashMap::new()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn add(mut self, value: u16, map_area: MapArea) -> MapAreaLookupBuilder {
|
|
|
|
|
|
self.map_areas.insert(value, map_area);
|
|
|
|
|
|
self
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn build(self) -> MapAreaLookup {
|
|
|
|
|
|
MapAreaLookup(self.map_areas)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|