Browse Source

initial ep2,4 maps + offline for all eps.

pbs
Andy Newjack 5 years ago
parent
commit
60cecc8b61
  1. 80
      src/bin/main.rs
  2. 795
      src/ship/map.rs
  3. 116
      src/ship/monster.rs
  4. 1
      src/ship/packet/handler/message.rs
  5. 2
      src/ship/room.rs

80
src/bin/main.rs

@ -65,7 +65,7 @@ fn main() {
entity_gateway.create_character(character).await; entity_gateway.create_character(character).await;
let mut character = NewCharacterEntity::new(fake_user.id); let mut character = NewCharacterEntity::new(fake_user.id);
character.slot = 2; character.slot = 2;
character.name = "no progress".into();
character.name = "ItemRefactor".into();
character.exp = 80000000; character.exp = 80000000;
character.meseta = 999999; character.meseta = 999999;
let character = entity_gateway.create_character(character).await.unwrap(); let character = entity_gateway.create_character(character).await.unwrap();
@ -80,12 +80,88 @@ fn main() {
attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 40}), attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 40}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}), Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}),
None,], None,],
tekked: false,
tekked: true,
} }
), ),
location: ItemLocation::Inventory { location: ItemLocation::Inventory {
character_id: character.id, character_id: character.id,
slot: 0, slot: 0,
equipped: false,
}
}).await;
entity_gateway.create_item(
NewItemEntity {
item: ItemDetail::Weapon(
item::weapon::Weapon {
weapon: item::weapon::WeaponType::Handgun,
grind: 5,
special: Some(item::weapon::WeaponSpecial::Charge),
attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 40}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}),
None,],
tekked: true,
}
),
location: ItemLocation::Inventory {
character_id: character.id,
slot: 1,
equipped: false,
}
}).await;
entity_gateway.create_item(
NewItemEntity {
item: ItemDetail::Weapon(
item::weapon::Weapon {
weapon: item::weapon::WeaponType::Vjaya,
grind: 5,
special: Some(item::weapon::WeaponSpecial::Charge),
attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 40}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
None,],
tekked: true,
}
),
location: ItemLocation::Inventory {
character_id: character.id,
slot: 2,
equipped: true,
}
}).await;
entity_gateway.create_item(
NewItemEntity {
item: ItemDetail::Weapon(
item::weapon::Weapon {
weapon: item::weapon::WeaponType::Vulcan,
grind: 5,
special: Some(item::weapon::WeaponSpecial::Charge),
attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
None,],
tekked: true,
}
),
location: ItemLocation::Inventory {
character_id: character.id,
slot: 3,
equipped: true,
}
}).await;
entity_gateway.create_item(
NewItemEntity {
item: ItemDetail::Weapon(
item::weapon::Weapon {
weapon: item::weapon::WeaponType::DarkFlow,
grind: 5,
special: Some(item::weapon::WeaponSpecial::Charge),
attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 100}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 100}),
Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Native, value: 100}),],
tekked: true,
}
),
location: ItemLocation::Inventory {
character_id: character.id,
slot: 4,
equipped: true, equipped: true,
} }
}).await; }).await;

795
src/ship/map.rs

@ -9,7 +9,7 @@ use rand::Rng;
use thiserror::Error; use thiserror::Error;
use crate::ship::monster::MonsterType; use crate::ship::monster::MonsterType;
use crate::ship::room::Episode;
use crate::ship::room::{Episode, RoomMode};
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
struct RawMapEnemy { struct RawMapEnemy {
@ -85,89 +85,136 @@ pub struct MapEnemy {
impl MapEnemy { impl MapEnemy {
fn from_raw(enemy: RawMapEnemy, episode: &Episode, map_area: &MapArea /*, battleparam */) -> Result<MapEnemy, MapEnemyError> { fn from_raw(enemy: RawMapEnemy, episode: &Episode, map_area: &MapArea /*, battleparam */) -> Result<MapEnemy, MapEnemyError> {
let monster = match (enemy, episode) {
(RawMapEnemy {id: 64, ..}, _) => MonsterType::Hildebear,
(RawMapEnemy {id: 65, ..}, Episode::Four) => MonsterType::SandRappy,
(RawMapEnemy {id: 65, ..}, _) => MonsterType::RagRappy,
(RawMapEnemy {id: 66, ..}, _) => MonsterType::Monest,
(RawMapEnemy {id: 67, field2: 0, ..}, _) => MonsterType::SavageWolf,
(RawMapEnemy {id: 67, ..}, _) => MonsterType::BarbarousWolf,
(RawMapEnemy {id: 68, skin: 0, ..}, _) => MonsterType::Booma,
(RawMapEnemy {id: 68, skin: 1, ..}, _) => MonsterType::Gobooma,
(RawMapEnemy {id: 68, skin: 2, ..}, _) => MonsterType::Gigobooma,
(RawMapEnemy {id: 96, ..}, _) => MonsterType::GrassAssassin,
(RawMapEnemy {id: 97, ..}, Episode::Two) => MonsterType::DelLily,
(RawMapEnemy {id: 97, ..}, _) => MonsterType::PoisonLily,
(RawMapEnemy {id: 98, ..}, _) => MonsterType::NanoDragon,
(RawMapEnemy {id: 99, skin: 0, ..}, _) => MonsterType::EvilShark,
(RawMapEnemy {id: 99, skin: 1, ..}, _) => MonsterType::PalShark,
(RawMapEnemy {id: 99, skin: 2, ..}, _) => MonsterType::GuilShark,
(RawMapEnemy {id: 100, ..}, _) => MonsterType::PofuillySlime,
(RawMapEnemy {id: 101, ..}, _) => MonsterType::PanArms,
(RawMapEnemy {id: 128, skin: 0, ..}, _) => MonsterType::Dubchic,
(RawMapEnemy {id: 128, skin: 1, ..}, _) => MonsterType::Gillchic,
(RawMapEnemy {id: 129, ..}, _) => MonsterType::Garanz,
(RawMapEnemy {id: 130, field2: 0, ..}, _) => MonsterType::SinowBeat,
(RawMapEnemy {id: 130, ..}, _) => MonsterType::SinowGold,
(RawMapEnemy {id: 131, ..}, _) => MonsterType::Canadine,
(RawMapEnemy {id: 132, ..}, _) => MonsterType::Canane,
(RawMapEnemy {id: 133, ..}, _) => MonsterType::Dubwitch,
(RawMapEnemy {id: 160, ..}, _) => MonsterType::Delsaber,
(RawMapEnemy {id: 161, ..}, _) => MonsterType::ChaosSorcerer,
(RawMapEnemy {id: 162, ..}, _) => MonsterType::DarkGunner,
(RawMapEnemy {id: 164, ..}, _) => MonsterType::ChaosBringer,
(RawMapEnemy {id: 165, ..}, _) => MonsterType::DarkBelra,
(RawMapEnemy {id: 166, skin: 0, ..}, _) => MonsterType::Dimenian,
(RawMapEnemy {id: 166, skin: 1, ..}, _) => MonsterType::LaDimenian,
(RawMapEnemy {id: 166, skin: 2, ..}, _) => MonsterType::SoDimenian,
(RawMapEnemy {id: 167, ..}, _) => MonsterType::Bulclaw,
(RawMapEnemy {id: 168, ..}, _) => MonsterType::Claw,
(RawMapEnemy {id: 192, ..}, Episode::One) => MonsterType::Dragon,
(RawMapEnemy {id: 192, ..}, Episode::Two) => MonsterType::GalGryphon,
(RawMapEnemy {id: 193, ..}, _) => MonsterType::DeRolLe,
(RawMapEnemy {id: 194, ..}, _) => MonsterType::VolOptPartA,
(RawMapEnemy {id: 197, ..}, _) => MonsterType::VolOpt,
(RawMapEnemy {id: 200, ..}, _) => MonsterType::DarkFalz,
(RawMapEnemy {id: 202, ..}, _) => MonsterType::OlgaFlow,
(RawMapEnemy {id: 203, ..}, _) => MonsterType::BarbaRay,
(RawMapEnemy {id: 204, ..}, _) => MonsterType::GolDragon,
(RawMapEnemy {id: 212, skin: 0, ..}, _) => MonsterType::SinowBerill,
(RawMapEnemy {id: 212, skin: 1, ..}, _) => MonsterType::SinowSpigell,
(RawMapEnemy {id: 213, skin: 0, ..}, _) => MonsterType::Merillia,
(RawMapEnemy {id: 213, skin: 1, ..}, _) => MonsterType::Meriltas,
(RawMapEnemy {id: 214, skin: 0, ..}, _) => MonsterType::Mericarol,
(RawMapEnemy {id: 214, skin: 1, ..}, _) => MonsterType::Merikle,
(RawMapEnemy {id: 214, skin: 2, ..}, _) => MonsterType::Mericus,
(RawMapEnemy {id: 215, skin: 0, ..}, _) => MonsterType::UlGibbon,
(RawMapEnemy {id: 215, skin: 1, ..}, _) => MonsterType::ZolGibbon,
(RawMapEnemy {id: 216, ..}, _) => MonsterType::Gibbles,
(RawMapEnemy {id: 217, ..}, _) => MonsterType::Gee,
(RawMapEnemy {id: 218, ..}, _) => MonsterType::GiGue,
(RawMapEnemy {id: 219, ..}, _) => MonsterType::Deldepth,
(RawMapEnemy {id: 220, ..}, _) => MonsterType::Delbiter,
(RawMapEnemy {id: 221, skin: 0, ..}, _) => MonsterType::Dolmdarl,
(RawMapEnemy {id: 221, skin: 1, ..}, _) => MonsterType::Dolmolm,
(RawMapEnemy {id: 222, ..}, _) => MonsterType::Morfos,
(RawMapEnemy {id: 223, ..}, _) => MonsterType::Recobox,
(RawMapEnemy {id: 224, skin: 0, ..}, _) => MonsterType::SinowZoa,
(RawMapEnemy {id: 224, skin: 1, ..}, _) => MonsterType::SinowZele,
(RawMapEnemy {id: 224, ..}, _) => MonsterType::Epsilon,
(RawMapEnemy {id: 225, ..}, _) => MonsterType::IllGill,
(RawMapEnemy {id: 272, ..}, _) => MonsterType::Astark,
(RawMapEnemy {id: 273, field2: 0, ..}, _) => MonsterType::SatelliteLizard,
(RawMapEnemy {id: 273, ..}, _) => MonsterType::Yowie,
(RawMapEnemy {id: 274, ..}, _) => MonsterType::MerissaA,
(RawMapEnemy {id: 275, ..}, _) => MonsterType::Girtablulu,
(RawMapEnemy {id: 276, ..}, _) => MonsterType::Zu,
(RawMapEnemy {id: 277, skin: 0, ..}, _) => MonsterType::Boota,
(RawMapEnemy {id: 277, skin: 1, ..}, _) => MonsterType::ZeBoota,
(RawMapEnemy {id: 277, skin: 2, ..}, _) => MonsterType::BaBoota,
(RawMapEnemy {id: 278, ..}, _) => MonsterType::Dorphon,
(RawMapEnemy {id: 279, skin: 0, ..}, _) => MonsterType::Goran,
(RawMapEnemy {id: 279, skin: 1, ..}, _) => MonsterType::PyroGoran,
(RawMapEnemy {id: 279, skin: 2, ..}, _) => MonsterType::GoranDetonator,
(RawMapEnemy {id: 281, skin: 0, ..}, _) => MonsterType::SaintMillion,
(RawMapEnemy {id: 281, skin: 1, ..}, _) => MonsterType::Shambertin,
let monster = match map_area {
MapArea::Forest1 | MapArea::Forest2 | MapArea::Dragon |
MapArea::Caves1 | MapArea::Caves2 | MapArea::Caves3 | MapArea::DeRolLe |
MapArea::Mines1 | MapArea::Mines2 | MapArea::VolOpt |
MapArea::Ruins1 | MapArea::Ruins2 | MapArea::Ruins3 | MapArea::DarkFalz => {
match (enemy, episode) {
(RawMapEnemy {id: 64, ..}, _) => MonsterType::Hildebear,
(RawMapEnemy {id: 65, ..}, _) => MonsterType::RagRappy,
(RawMapEnemy {id: 66, ..}, _) => MonsterType::Monest,
(RawMapEnemy {id: 67, field2: 0, ..}, _) => MonsterType::SavageWolf,
(RawMapEnemy {id: 67, ..}, _) => MonsterType::BarbarousWolf,
(RawMapEnemy {id: 68, skin: 0, ..}, _) => MonsterType::Booma,
(RawMapEnemy {id: 68, skin: 1, ..}, _) => MonsterType::Gobooma,
(RawMapEnemy {id: 68, skin: 2, ..}, _) => MonsterType::Gigobooma,
(RawMapEnemy {id: 96, ..}, _) => MonsterType::GrassAssassin,
(RawMapEnemy {id: 97, ..}, _) => MonsterType::PoisonLily,
(RawMapEnemy {id: 98, ..}, _) => MonsterType::NanoDragon,
(RawMapEnemy {id: 99, skin: 0, ..}, _) => MonsterType::EvilShark,
(RawMapEnemy {id: 99, skin: 1, ..}, _) => MonsterType::PalShark,
(RawMapEnemy {id: 99, skin: 2, ..}, _) => MonsterType::GuilShark,
(RawMapEnemy {id: 100, ..}, _) => MonsterType::PofuillySlime,
(RawMapEnemy {id: 101, ..}, _) => MonsterType::PanArms,
(RawMapEnemy {id: 128, skin: 0, ..}, _) => MonsterType::Dubchic,
(RawMapEnemy {id: 128, skin: 1, ..}, _) => MonsterType::Gillchic,
(RawMapEnemy {id: 129, ..}, _) => MonsterType::Garanz,
(RawMapEnemy {id: 130, field2: 0, ..}, _) => MonsterType::SinowBeat,
(RawMapEnemy {id: 130, ..}, _) => MonsterType::SinowGold,
(RawMapEnemy {id: 131, ..}, _) => MonsterType::Canadine,
(RawMapEnemy {id: 132, ..}, _) => MonsterType::Canane,
(RawMapEnemy {id: 133, ..}, _) => MonsterType::Dubwitch,
(RawMapEnemy {id: 160, ..}, _) => MonsterType::Delsaber,
(RawMapEnemy {id: 161, ..}, _) => MonsterType::ChaosSorcerer,
(RawMapEnemy {id: 162, ..}, _) => MonsterType::DarkGunner,
(RawMapEnemy {id: 164, ..}, _) => MonsterType::ChaosBringer,
(RawMapEnemy {id: 165, ..}, _) => MonsterType::DarkBelra,
(RawMapEnemy {id: 166, skin: 0, ..}, _) => MonsterType::Dimenian,
(RawMapEnemy {id: 166, skin: 1, ..}, _) => MonsterType::LaDimenian,
(RawMapEnemy {id: 166, skin: 2, ..}, _) => MonsterType::SoDimenian,
(RawMapEnemy {id: 167, ..}, _) => MonsterType::Bulclaw,
(RawMapEnemy {id: 168, ..}, _) => MonsterType::Claw,
(RawMapEnemy {id: 192, ..}, Episode::One) => MonsterType::Dragon,
(RawMapEnemy {id: 193, ..}, _) => MonsterType::DeRolLe,
(RawMapEnemy {id: 194, ..}, _) => MonsterType::VolOptPartA,
(RawMapEnemy {id: 197, ..}, _) => MonsterType::VolOpt,
(RawMapEnemy {id: 200, ..}, _) => MonsterType::DarkFalz,
_ => return Err(MapEnemyError::UnknownEnemyId(enemy.id))
}
},
MapArea::VrTempleAlpha | MapArea::VrTempleBeta | MapArea::BarbaRay |
MapArea::VrSpaceshipAlpha | MapArea::VrSpaceshipBeta | MapArea::GolDragon |
MapArea::JungleAreaNorth | MapArea::JungleAreaEast | MapArea::Mountain | MapArea::Seaside | MapArea::Cca | MapArea::GalGryphon |
MapArea::SeabedUpper | MapArea::SeabedLower | MapArea::OlgaFlow => {
match (enemy, episode) {
(RawMapEnemy {id: 64, ..}, _) => MonsterType::Hildebear,
(RawMapEnemy {id: 65, ..}, _) => MonsterType::RagRappy,
(RawMapEnemy {id: 66, ..}, _) => MonsterType::Monest,
(RawMapEnemy {id: 67, field2: 0, ..}, _) => MonsterType::SavageWolf,
(RawMapEnemy {id: 67, ..}, _) => MonsterType::BarbarousWolf,
(RawMapEnemy {id: 96, ..}, _) => MonsterType::GrassAssassin,
(RawMapEnemy {id: 97, ..}, _) => MonsterType::PoisonLily,
(RawMapEnemy {id: 101, ..}, _) => MonsterType::PanArms,
(RawMapEnemy {id: 128, skin: 0, ..}, _) => MonsterType::Dubchic,
(RawMapEnemy {id: 128, skin: 1, ..}, _) => MonsterType::Gillchic,
(RawMapEnemy {id: 129, ..}, _) => MonsterType::Garanz,
(RawMapEnemy {id: 133, ..}, _) => MonsterType::Dubwitch,
(RawMapEnemy {id: 160, ..}, _) => MonsterType::Delsaber,
(RawMapEnemy {id: 161, ..}, _) => MonsterType::ChaosSorcerer,
(RawMapEnemy {id: 165, ..}, _) => MonsterType::DarkBelra,
(RawMapEnemy {id: 166, skin: 0, ..}, _) => MonsterType::Dimenian,
(RawMapEnemy {id: 166, skin: 1, ..}, _) => MonsterType::LaDimenian,
(RawMapEnemy {id: 166, skin: 2, ..}, _) => MonsterType::SoDimenian,
(RawMapEnemy {id: 192, ..}, Episode::Two) => MonsterType::GalGryphon,
(RawMapEnemy {id: 202, ..}, _) => MonsterType::OlgaFlow,
(RawMapEnemy {id: 203, ..}, _) => MonsterType::BarbaRay,
(RawMapEnemy {id: 204, ..}, _) => MonsterType::GolDragon,
(RawMapEnemy {id: 212, skin: 0, ..}, _) => MonsterType::SinowBerill,
(RawMapEnemy {id: 212, skin: 1, ..}, _) => MonsterType::SinowSpigell,
(RawMapEnemy {id: 213, skin: 0, ..}, _) => MonsterType::Merillia,
(RawMapEnemy {id: 213, skin: 1, ..}, _) => MonsterType::Meriltas,
(RawMapEnemy {id: 214, skin: 0, ..}, _) => MonsterType::Mericarol,
(RawMapEnemy {id: 214, skin: 1, ..}, _) => MonsterType::Merikle,
(RawMapEnemy {id: 214, skin: 2, ..}, _) => MonsterType::Mericus,
(RawMapEnemy {id: 215, skin: 0, ..}, _) => MonsterType::UlGibbon,
(RawMapEnemy {id: 215, skin: 1, ..}, _) => MonsterType::ZolGibbon,
(RawMapEnemy {id: 216, ..}, _) => MonsterType::Gibbles,
(RawMapEnemy {id: 217, ..}, _) => MonsterType::Gee,
(RawMapEnemy {id: 218, ..}, _) => MonsterType::GiGue,
(RawMapEnemy {id: 219, ..}, _) => MonsterType::Deldepth,
(RawMapEnemy {id: 220, ..}, _) => MonsterType::Delbiter,
(RawMapEnemy {id: 221, skin: 0, ..}, _) => MonsterType::Dolmolm,
(RawMapEnemy {id: 221, skin: 1, ..}, _) => MonsterType::Dolmdarl,
(RawMapEnemy {id: 222, ..}, _) => MonsterType::Morfos,
(RawMapEnemy {id: 223, ..}, _) => MonsterType::Recobox,
(RawMapEnemy {id: 224, skin: 0, ..}, _) => MonsterType::SinowZoa,
(RawMapEnemy {id: 224, skin: 1, ..}, _) => MonsterType::SinowZele,
(RawMapEnemy {id: 224, ..}, _) => MonsterType::Epsilon,
(RawMapEnemy {id: 225, ..}, _) => MonsterType::IllGill,
_ => return Err(MapEnemyError::UnknownEnemyId(enemy.id))
}
},
MapArea::CraterEast | MapArea::CraterWest | MapArea::CraterSouth | MapArea::CraterNorth | MapArea::CraterInterior => {
match (enemy, episode) {
(RawMapEnemy {id: 65, ..}, Episode::Four) => MonsterType::SandRappyCrater,
(RawMapEnemy {id: 272, ..}, _) => MonsterType::Astark,
(RawMapEnemy {id: 273, field2: 0, ..}, _) => MonsterType::SatelliteLizardCrater,
(RawMapEnemy {id: 273, ..}, _) => MonsterType::YowieCrater,
(RawMapEnemy {id: 276, ..}, _) => MonsterType::ZuCrater,
(RawMapEnemy {id: 277, skin: 0, ..}, _) => MonsterType::Boota,
(RawMapEnemy {id: 277, skin: 1, ..}, _) => MonsterType::ZeBoota,
(RawMapEnemy {id: 277, skin: 2, ..}, _) => MonsterType::BaBoota,
(RawMapEnemy {id: 278, ..}, _) => MonsterType::Dorphon,
_ => return Err(MapEnemyError::UnknownEnemyId(enemy.id))
}
},
MapArea::SubDesert1 | MapArea::SubDesert2 | MapArea::SubDesert3 | MapArea::SaintMillion => {
match (enemy, episode) {
(RawMapEnemy {id: 65, ..}, Episode::Four) => MonsterType::SandRappyDesert,
(RawMapEnemy {id: 273, field2: 0, ..}, _) => MonsterType::SatelliteLizardDesert,
(RawMapEnemy {id: 273, ..}, _) => MonsterType::YowieDesert,
(RawMapEnemy {id: 274, ..}, _) => MonsterType::MerissaA,
(RawMapEnemy {id: 275, ..}, _) => MonsterType::Girtablulu,
(RawMapEnemy {id: 276, ..}, _) => MonsterType::ZuDesert,
(RawMapEnemy {id: 279, skin: 0, ..}, _) => MonsterType::Goran,
(RawMapEnemy {id: 279, skin: 1, ..}, _) => MonsterType::PyroGoran,
(RawMapEnemy {id: 279, skin: 2, ..}, _) => MonsterType::GoranDetonator,
(RawMapEnemy {id: 281, skin: 0, ..}, _) => MonsterType::SaintMillion,
(RawMapEnemy {id: 281, skin: 1, ..}, _) => MonsterType::Shambertin,
_ => return Err(MapEnemyError::UnknownEnemyId(enemy.id))
}
},
_ => return Err(MapEnemyError::UnknownEnemyId(enemy.id)) _ => return Err(MapEnemyError::UnknownEnemyId(enemy.id))
}; };
@ -217,7 +264,7 @@ struct RawMapObject {
impl RawMapObject { impl RawMapObject {
fn from_byte_stream<R: Read>(cursor: &mut R) -> Result<RawMapObject, std::io::Error> { fn from_byte_stream<R: Read>(cursor: &mut R) -> Result<RawMapObject, std::io::Error> {
Ok(RawMapObject {
let r = RawMapObject {
otype: cursor.read_u16::<LittleEndian>()?, otype: cursor.read_u16::<LittleEndian>()?,
unknown1: cursor.read_u16::<LittleEndian>()?, unknown1: cursor.read_u16::<LittleEndian>()?,
unknown2: cursor.read_u32::<LittleEndian>()?, unknown2: cursor.read_u32::<LittleEndian>()?,
@ -238,7 +285,9 @@ impl RawMapObject {
field5: cursor.read_u32::<LittleEndian>()?, field5: cursor.read_u32::<LittleEndian>()?,
field6: cursor.read_u32::<LittleEndian>()?, field6: cursor.read_u32::<LittleEndian>()?,
field7: cursor.read_u32::<LittleEndian>()?, field7: cursor.read_u32::<LittleEndian>()?,
})
};
println!("from_byte_stream object: {:?}", r);
Ok(r)
} }
} }
@ -329,11 +378,13 @@ impl MapObject {
(RawMapObject {otype: 146, ..}, _) => MapObjectType::FixedBox(FixedBoxDropType::from_object(raw.field1, raw.field2, raw.field3, raw.field4)), (RawMapObject {otype: 146, ..}, _) => MapObjectType::FixedBox(FixedBoxDropType::from_object(raw.field1, raw.field2, raw.field3, raw.field4)),
(RawMapObject {otype: 147, ..}, _) => MapObjectType::EnemyFixedBox(FixedBoxDropType::from_object(raw.field1, raw.field2, raw.field3, raw.field4)), (RawMapObject {otype: 147, ..}, _) => MapObjectType::EnemyFixedBox(FixedBoxDropType::from_object(raw.field1, raw.field2, raw.field3, raw.field4)),
(RawMapObject {otype: 149, ..}, _) => MapObjectType::EmptyFixedBox(FixedBoxDropType::from_object(raw.field1, raw.field2, raw.field3, raw.field4)), (RawMapObject {otype: 149, ..}, _) => MapObjectType::EmptyFixedBox(FixedBoxDropType::from_object(raw.field1, raw.field2, raw.field3, raw.field4)),
(RawMapObject {otype: 353, ..}, _) => MapObjectType::RuinsFixedBox(FixedBoxDropType::from_object(raw.field1, raw.field2, raw.field3, raw.field4)),
(RawMapObject {otype: 354, ..}, _) => MapObjectType::RuinsBox,
(RawMapObject {otype: 355, ..}, _) => MapObjectType::RuinsEnemyFixedBox(FixedBoxDropType::from_object(raw.field1, raw.field2, raw.field3, raw.field4)),
(RawMapObject {otype: 356, ..}, _) => MapObjectType::RuinsEnemyBox,
(RawMapObject {otype: 357, ..}, _) => MapObjectType::RuinsEmptyBox,
(RawMapObject {otype: 353, ..}, Episode::One) => MapObjectType::RuinsFixedBox(FixedBoxDropType::from_object(raw.field1, raw.field2, raw.field3, raw.field4)),
(RawMapObject {otype: 354, ..}, Episode::One) => MapObjectType::RuinsBox,
(RawMapObject {otype: 355, ..}, Episode::One) => MapObjectType::RuinsEnemyFixedBox(FixedBoxDropType::from_object(raw.field1, raw.field2, raw.field3, raw.field4)),
(RawMapObject {otype: 356, ..}, Episode::One) => MapObjectType::RuinsEnemyBox,
(RawMapObject {otype: 357, ..}, Episode::One) => MapObjectType::RuinsEmptyBox,
(RawMapObject {otype: 512, ..}, Episode::Two) => MapObjectType::CcaBox,
(RawMapObject {otype: 515, ..}, Episode::Two) => MapObjectType::CcaFixedBox(FixedBoxDropType::from_object(raw.field1, raw.field2, raw.field3, raw.field4)),
_ => return Err(MapObjectError::UnknownObjectType(raw.otype, raw)) _ => return Err(MapObjectError::UnknownObjectType(raw.otype, raw))
}; };
@ -440,8 +491,8 @@ impl MapArea {
(Episode::Two, 13) => Ok(MapArea::OlgaFlow), (Episode::Two, 13) => Ok(MapArea::OlgaFlow),
(Episode::Two, 14) => Ok(MapArea::BarbaRay), (Episode::Two, 14) => Ok(MapArea::BarbaRay),
(Episode::Two, 15) => Ok(MapArea::GolDragon), (Episode::Two, 15) => Ok(MapArea::GolDragon),
// (Episode::Two, 16) => Ok(MapArea::Seaside2), // valid map?
// (Episode::Two, 17) => Ok(MapArea::Tower), // valid map?
// (Episode::Two, 16) => Ok(MapArea::Seaside2),
// (Episode::Two, 17) => Ok(MapArea::Tower),
(Episode::Four, 0) => Ok(MapArea::Pioneer2Ep4), (Episode::Four, 0) => Ok(MapArea::Pioneer2Ep4),
(Episode::Four, 1) => Ok(MapArea::CraterEast), (Episode::Four, 1) => Ok(MapArea::CraterEast),
(Episode::Four, 2) => Ok(MapArea::CraterWest), (Episode::Four, 2) => Ok(MapArea::CraterWest),
@ -452,7 +503,7 @@ impl MapArea {
(Episode::Four, 7) => Ok(MapArea::SubDesert2), (Episode::Four, 7) => Ok(MapArea::SubDesert2),
(Episode::Four, 8) => Ok(MapArea::SubDesert3), (Episode::Four, 8) => Ok(MapArea::SubDesert3),
(Episode::Four, 9) => Ok(MapArea::SaintMillion), (Episode::Four, 9) => Ok(MapArea::SaintMillion),
// (Episode::Four, 10) => Ok(MapArea::TestMapEp4), // invalid map!
// (Episode::Four, 10) => Ok(MapArea::TestMapEp4),
_ => Err(MapAreaError::UnknownMapArea(area)) _ => Err(MapAreaError::UnknownMapArea(area))
} }
} }
@ -473,35 +524,33 @@ impl MapArea {
MapArea::DeRolLe => Some(5), MapArea::DeRolLe => Some(5),
MapArea::VolOpt => Some(7), MapArea::VolOpt => Some(7),
MapArea::DarkFalz => Some(9), MapArea::DarkFalz => Some(9),
MapArea::Pioneer2Ep2 => Some(0),
MapArea::VrTempleAlpha => Some(1),
MapArea::VrTempleBeta => Some(2),
MapArea::VrSpaceshipAlpha => Some(3),
MapArea::VrSpaceshipBeta => Some(4),
MapArea::Cca => Some(5),
MapArea::JungleAreaNorth => Some(6),
MapArea::JungleAreaEast => Some(7),
MapArea::Mountain => Some(8),
MapArea::Seaside => Some(9),
MapArea::SeabedUpper => Some(10),
MapArea::SeabedLower => Some(11),
MapArea::GalGryphon => Some(12),
MapArea::OlgaFlow => Some(13),
MapArea::BarbaRay => Some(14),
MapArea::GolDragon => Some(15),
// MapArea::Seaside2 => Some(16),
// MapArea::Tower => Some(17),
MapArea::Pioneer2Ep4 => Some(0),
MapArea::CraterEast => Some(1),
MapArea::CraterWest => Some(2),
MapArea::CraterSouth => Some(3),
MapArea::CraterNorth => Some(4),
MapArea::CraterInterior => Some(5),
MapArea::SubDesert1 => Some(6),
MapArea::SubDesert2 => Some(7),
MapArea::SubDesert3 => Some(8),
MapArea::VrTempleAlpha => Some(0),
MapArea::VrTempleBeta => Some(1),
MapArea::VrSpaceshipAlpha => Some(2),
MapArea::VrSpaceshipBeta => Some(3),
MapArea::Cca => Some(4),
MapArea::JungleAreaNorth => Some(5),
MapArea::JungleAreaEast => Some(5),
MapArea::Mountain => Some(6),
MapArea::Seaside => Some(7),
MapArea::SeabedUpper => Some(8),
MapArea::SeabedLower => Some(9),
MapArea::GalGryphon => Some(8),
MapArea::OlgaFlow => Some(9),
MapArea::BarbaRay => Some(2),
MapArea::GolDragon => Some(5),
// MapArea::Seaside2 => Some(0),
// MapArea::Tower => Some(0),
MapArea::CraterEast => Some(2),
MapArea::CraterWest => Some(3),
MapArea::CraterSouth => Some(4),
MapArea::CraterNorth => Some(5),
MapArea::CraterInterior => Some(6),
MapArea::SubDesert1 => Some(7),
MapArea::SubDesert2 => Some(8),
MapArea::SubDesert3 => Some(9),
MapArea::SaintMillion => Some(9), MapArea::SaintMillion => Some(9),
// MapArea::TestMapEp4 => Some(10),
// MapArea::TestMapEp4 => Some(0),
_ => None _ => None
} }
} }
@ -567,7 +616,7 @@ struct MapVariant {
impl MapVariant { impl MapVariant {
fn new(map: MapArea, mode: MapVariantMode) -> MapVariant { fn new(map: MapArea, mode: MapVariantMode) -> MapVariant {
// if mode == MapVariantMode::Online {
if mode == MapVariantMode::Online {
let major = match map { let major = match map {
MapArea::Pioneer2Ep1 => 0, MapArea::Pioneer2Ep1 => 0,
MapArea::Forest1 | MapArea::Forest2 => 0, MapArea::Forest1 | MapArea::Forest2 => 0,
@ -575,12 +624,18 @@ impl MapVariant {
MapArea::Mines1 | MapArea::Mines2 => rand::thread_rng().gen_range(0, 3), MapArea::Mines1 | MapArea::Mines2 => rand::thread_rng().gen_range(0, 3),
MapArea::Ruins1 | MapArea::Ruins2 | MapArea::Ruins3 => rand::thread_rng().gen_range(0, 3), MapArea::Ruins1 | MapArea::Ruins2 | MapArea::Ruins3 => rand::thread_rng().gen_range(0, 3),
MapArea::Dragon | MapArea::DeRolLe | MapArea::VolOpt | MapArea::DarkFalz => 0, MapArea::Dragon | MapArea::DeRolLe | MapArea::VolOpt | MapArea::DarkFalz => 0,
MapArea::Pioneer2Ep2 => 0, MapArea::Pioneer2Ep2 => 0,
MapArea::VrTempleAlpha | MapArea::VrTempleBeta | MapArea::VrSpaceshipAlpha | MapArea::VrSpaceshipBeta => rand::thread_rng().gen_range(0, 1),
MapArea::Cca | MapArea::JungleAreaNorth | MapArea::JungleAreaEast | MapArea::Seaside => rand::thread_rng().gen_range(0, 2),
MapArea::Mountain => rand::thread_rng().gen_range(0, 1),
MapArea::SeabedUpper | MapArea::SeabedLower => rand::thread_rng().gen_range(0, 1),
MapArea::VrTempleAlpha | MapArea::VrTempleBeta => rand::thread_rng().gen_range(0, 2),
MapArea::VrSpaceshipAlpha | MapArea::VrSpaceshipBeta => rand::thread_rng().gen_range(0, 2),
MapArea::Cca => 0,
MapArea::JungleAreaNorth => 0,
MapArea::JungleAreaEast => 0,
MapArea::Mountain => rand::thread_rng().gen_range(0, 2),
MapArea::Seaside => 0,
MapArea::SeabedUpper | MapArea::SeabedLower => rand::thread_rng().gen_range(0, 2),
MapArea::BarbaRay | MapArea::GolDragon | MapArea::GalGryphon | MapArea::OlgaFlow => 0, MapArea::BarbaRay | MapArea::GolDragon | MapArea::GalGryphon | MapArea::OlgaFlow => 0,
MapArea::Pioneer2Ep4 => 0, MapArea::Pioneer2Ep4 => 0,
MapArea::CraterEast => 0, MapArea::CraterEast => 0,
MapArea::CraterWest => 1, MapArea::CraterWest => 1,
@ -600,146 +655,303 @@ impl MapVariant {
MapArea::Mines1 | MapArea::Mines2 => rand::thread_rng().gen_range(0, 2), MapArea::Mines1 | MapArea::Mines2 => rand::thread_rng().gen_range(0, 2),
MapArea::Ruins1 | MapArea::Ruins2 | MapArea::Ruins3 => rand::thread_rng().gen_range(0, 2), MapArea::Ruins1 | MapArea::Ruins2 | MapArea::Ruins3 => rand::thread_rng().gen_range(0, 2),
MapArea::Dragon | MapArea::DeRolLe | MapArea::VolOpt | MapArea::DarkFalz => 0, MapArea::Dragon | MapArea::DeRolLe | MapArea::VolOpt | MapArea::DarkFalz => 0,
MapArea::Pioneer2Ep2 => 0,
MapArea::VrTempleAlpha | MapArea::VrTempleBeta => 0,
MapArea::VrSpaceshipAlpha | MapArea::VrSpaceshipBeta => 0,
MapArea::Cca => rand::thread_rng().gen_range(0, 3),
MapArea::JungleAreaNorth => rand::thread_rng().gen_range(0, 3),
MapArea::JungleAreaEast => rand::thread_rng().gen_range(0, 3),
MapArea::Mountain => rand::thread_rng().gen_range(0, 2),
MapArea::Seaside => rand::thread_rng().gen_range(0, 3),
MapArea::SeabedUpper | MapArea::SeabedLower => rand::thread_rng().gen_range(0, 2),
MapArea::GalGryphon => 0,
MapArea::OlgaFlow => 0,
MapArea::BarbaRay => 0,
MapArea::GolDragon => 0,
MapArea::Pioneer2Ep4 => 0,
MapArea::CraterEast => 2, // 0: good map. 1: good. 2: good
MapArea::CraterWest => 2, // 0: bad map. 1: bad. 2: bad
MapArea::CraterSouth => 2, // 0: bad map. 1: bad. 2:
MapArea::CraterNorth => 2, // 0: bad map. 1: bad . 2:
MapArea::CraterInterior => 2,
// MapArea::CraterWest | MapArea::CraterSouth | MapArea::CraterNorth | MapArea::CraterInterior => rand::thread_rng().gen_range(0, 2),
MapArea::SubDesert1 | MapArea::SubDesert3 => 0,
MapArea::SubDesert2 => rand::thread_rng().gen_range(0, 2),
MapArea::SaintMillion => 0,
};
println!("map: {:?}, mode: {:?}, major: {:?}, minor: {:?}", map, mode, major, minor);
MapVariant {
map: map,
mode: mode,
major: major,
minor: minor,
}
}
else {
let major = match map {
MapArea::Pioneer2Ep1 => 0,
MapArea::Forest1 => 0, | MapArea::Forest2 => 0,
MapArea::Caves1 | MapArea::Caves2 | MapArea::Caves3 => rand::thread_rng().gen_range(0, 3),
MapArea::Mines1 | MapArea::Mines2 => rand::thread_rng().gen_range(0, 3), // no offline-specific maps
MapArea::Ruins1 | MapArea::Ruins2 | MapArea::Ruins3 => rand::thread_rng().gen_range(0, 3), // no offline-specific maps
MapArea::Dragon | MapArea::DeRolLe | MapArea::VolOpt | MapArea::DarkFalz => 0,
MapArea::Pioneer2Ep2 => 0,
MapArea::VrTempleAlpha | MapArea::VrTempleBeta | MapArea::VrSpaceshipAlpha | MapArea::VrSpaceshipBeta => rand::thread_rng().gen_range(0, 1),
MapArea::Cca => 0,
MapArea::JungleAreaNorth => 0,
MapArea::JungleAreaEast => 0,
MapArea::Mountain => rand::thread_rng().gen_range(0, 1),
MapArea::Seaside => 0,
MapArea::SeabedUpper | MapArea::SeabedLower => rand::thread_rng().gen_range(0, 1),
MapArea::BarbaRay | MapArea::GolDragon | MapArea::GalGryphon | MapArea::OlgaFlow => 0,
MapArea::Pioneer2Ep4 => 0,
MapArea::CraterEast => 0,
MapArea::CraterWest => 1,
MapArea::CraterSouth => 2,
MapArea::CraterNorth => 3,
MapArea::CraterInterior => 0,
MapArea::SubDesert1 | MapArea::SubDesert3 => rand::thread_rng().gen_range(0, 2),
MapArea::SubDesert2 => 0,
MapArea::SaintMillion => 0,
};
let minor = match map {
MapArea::Pioneer2Ep1 => 0,
MapArea::Forest1 => rand::thread_rng().gen_range(0, 3) * 2,
MapArea::Forest2 => 0, // TODO: check if the other offline map files are corrupted?
// MapArea::Forest2 => {match rand::thread_rng().gen_range(0, 3) {
// 0 => 0,
// 1 => 3,
// 2 => 4,
// _ => unreachable!()}},
MapArea::Caves1 | MapArea::Caves2 | MapArea::Caves3 => 0,
MapArea::Mines1 | MapArea::Mines2 => rand::thread_rng().gen_range(0, 2), // no offline-specific maps
MapArea::Ruins1 | MapArea::Ruins2 | MapArea::Ruins3 => rand::thread_rng().gen_range(0, 2),// no offline-specific maps
MapArea::Dragon | MapArea::DeRolLe | MapArea::VolOpt | MapArea::DarkFalz => 0,
MapArea::Pioneer2Ep2 => 0, MapArea::Pioneer2Ep2 => 0,
MapArea::VrTempleAlpha | MapArea::VrTempleBeta | MapArea::VrSpaceshipAlpha | MapArea::VrSpaceshipBeta => 0, MapArea::VrTempleAlpha | MapArea::VrTempleBeta | MapArea::VrSpaceshipAlpha | MapArea::VrSpaceshipBeta => 0,
MapArea::Cca | MapArea::JungleAreaNorth | MapArea::JungleAreaEast | MapArea::Seaside => rand::thread_rng().gen_range(0, 2),
MapArea::Cca => 0,
MapArea::JungleAreaNorth => 0,
MapArea::JungleAreaEast => 0,
MapArea::Mountain => rand::thread_rng().gen_range(0, 1), MapArea::Mountain => rand::thread_rng().gen_range(0, 1),
MapArea::Seaside => 0,
MapArea::SeabedUpper | MapArea::SeabedLower => rand::thread_rng().gen_range(0, 1), MapArea::SeabedUpper | MapArea::SeabedLower => rand::thread_rng().gen_range(0, 1),
MapArea::GalGryphon => 0, MapArea::GalGryphon => 0,
MapArea::OlgaFlow => 0, MapArea::OlgaFlow => 0,
MapArea::BarbaRay => 0, MapArea::BarbaRay => 0,
MapArea::GolDragon => 0, MapArea::GolDragon => 0,
MapArea::Pioneer2Ep4 => 0, MapArea::Pioneer2Ep4 => 0,
MapArea::CraterEast | MapArea::CraterWest | MapArea::CraterSouth | MapArea::CraterNorth | MapArea::CraterInterior => rand::thread_rng().gen_range(0, 2), MapArea::CraterEast | MapArea::CraterWest | MapArea::CraterSouth | MapArea::CraterNorth | MapArea::CraterInterior => rand::thread_rng().gen_range(0, 2),
MapArea::SubDesert1 | MapArea::SubDesert3 => 0, MapArea::SubDesert1 | MapArea::SubDesert3 => 0,
MapArea::SubDesert2 => rand::thread_rng().gen_range(0, 2), MapArea::SubDesert2 => rand::thread_rng().gen_range(0, 2),
MapArea::SaintMillion => 0, MapArea::SaintMillion => 0,
}; };
println!("map: {:?}, mode: {:?}, major: {:?}, minor: {:?}", map, mode, major, minor);
MapVariant { MapVariant {
map: map, map: map,
mode: mode, mode: mode,
major: major, major: major,
minor: minor, minor: minor,
} }
// }
// else {
// let major = match map {
// MapArea::Pioneer2Ep1 | MapArea::Pioneer2Ep2 | MapArea::Pioneer2Ep4 => 0,
// MapArea::Forest1 | MapArea::Forest2 => 0,
// MapArea::Caves1 | MapArea::Caves2 | MapArea::Caves3 => rand::thread_rng().gen_range(0, 3),
// MapArea::Mines1 | MapArea::Mines2 => rand::thread_rng().gen_range(0, 3),
// MapArea::Ruins1 | MapArea::Ruins2 | MapArea::Ruins3 => rand::thread_rng().gen_range(0, 3),
// MapArea::Dragon | MapArea::DeRolLe | MapArea::VolOpt | MapArea::DarkFalz => 0,
// };
// let minor = match map {
// MapArea::Pioneer2Ep1 | MapArea::Pioneer2Ep2 | MapArea::Pioneer2Ep4 => 0,
// MapArea::Forest1 => rand::thread_rng().gen_range(0, 5),
// MapArea::Forest2 => rand::thread_rng().gen_range(0, 5),
// MapArea::Caves1 | MapArea::Caves2 | MapArea::Caves3 => rand::thread_rng().gen_range(0, 2),
// MapArea::Mines1 | MapArea::Mines2 => rand::thread_rng().gen_range(0, 2),
// MapArea::Ruins1 | MapArea::Ruins2 | MapArea::Ruins3 => rand::thread_rng().gen_range(0, 2),
// MapArea::Dragon | MapArea::DeRolLe | MapArea::VolOpt | MapArea::DarkFalz => 0,
// };
// MapVariant {
// map: map,
// mode: mode,
// major: major,
// minor: minor,
// }
// }
}
} }
// TODO: rename to npc_file // TODO: rename to npc_file
fn dat_file(&self) -> String { fn dat_file(&self) -> String {
match self.map {
MapArea::Pioneer2Ep1 => "data/maps/map_city00_00e.dat".into(),
MapArea::Forest1 => format!("data/maps/map_forest01_0{}e.dat", self.minor),
MapArea::Forest2 => format!("data/maps/map_forest02_0{}e.dat", self.minor),
MapArea::Caves1 => format!("data/maps/map_cave01_0{}_0{}e.dat", self.major, self.minor),
MapArea::Caves2 => format!("data/maps/map_cave02_0{}_0{}e.dat", self.major, self.minor),
MapArea::Caves3 => format!("data/maps/map_cave03_0{}_0{}e.dat", self.major, self.minor),
MapArea::Mines1 => format!("data/maps/map_machine01_0{}_0{}e.dat", self.major, self.minor),
MapArea::Mines2 => format!("data/maps/map_machine02_0{}_0{}e.dat", self.major, self.minor),
MapArea::Ruins1 => format!("data/maps/map_ancient01_0{}_0{}e.dat", self.major, self.minor),
MapArea::Ruins2 => format!("data/maps/map_ancient02_0{}_0{}e.dat", self.major, self.minor),
MapArea::Ruins3 => format!("data/maps/map_ancient03_0{}_0{}e.dat", self.major, self.minor),
MapArea::Dragon => "data/maps/map_boss01e.dat".into(),
MapArea::DeRolLe => "data/maps/map_boss02e.dat".into(),
MapArea::VolOpt => "data/maps/map_boss03e.dat".into(),
MapArea::DarkFalz => "data/maps/map_boss04e.dat".into(),
MapArea::Pioneer2Ep2 => "data/maps/map_labo00_00e.dat".into(),
MapArea::VrTempleAlpha => format!("data/maps/map_ruins01_0{}_0{}e.dat", self.major, self.minor),
MapArea::VrTempleBeta => format!("data/maps/map_ruins02_0{}_0{}e.dat", self.major, self.minor),
MapArea::VrSpaceshipAlpha => format!("data/maps/map_space01_0{}_0{}e.dat", self.major, self.minor),
MapArea::VrSpaceshipBeta => format!("data/maps/map_space02_0{}_0{}e.dat", self.major, self.minor),
MapArea::Cca => format!("data/maps/map_jungle01_0{}e.dat", self.major),
MapArea::JungleAreaNorth => format!("data/maps/map_jungle02_0{}e.dat", self.major),
MapArea::JungleAreaEast => format!("data/maps/map_jungle03_0{}e.dat", self.major),
MapArea::Mountain => format!("data/maps/map_jungle04_0{}_0{}e.dat", self.major, self.minor),
MapArea::Seaside => format!("data/maps/map_jungle05_0{}e.dat", self.major),
MapArea::SeabedUpper => format!("data/maps/map_seabed01_0{}_0{}e.dat", self.major, self.minor),
MapArea::SeabedLower => format!("data/maps/map_seabed02_0{}_0{}e.dat", self.major, self.minor),
MapArea::GalGryphon => "data/maps/map_boss05e.dat".into(),
MapArea::OlgaFlow => "data/maps/map_boss06e.dat".into(),
MapArea::BarbaRay => "data/maps/map_boss07e.dat".into(),
MapArea::GolDragon => "data/maps/map_boss08e.dat".into(),
MapArea::Pioneer2Ep4 => "data/maps/map_city02_00_00e.dat".into(),
MapArea::CraterEast => format!("data/maps/map_wilds01_0{}_0{}e.dat", self.major, self.minor),
MapArea::CraterWest => format!("data/maps/map_wilds01_0{}_0{}e.dat", self.major, self.minor),
MapArea::CraterSouth => format!("data/maps/map_wilds01_0{}_0{}e.dat", self.major, self.minor),
MapArea::CraterNorth => format!("data/maps/map_wilds01_0{}_0{}e.dat", self.major, self.minor),
MapArea::CraterInterior => format!("data/maps/map_crater01_0{}_0{}e.dat", self.major, self.minor),
MapArea::SubDesert1 => format!("data/maps/map_desert01_0{}_0{}e.dat", self.major, self.minor),
MapArea::SubDesert2 => format!("data/maps/map_desert02_0{}_0{}e.dat", self.major, self.minor),
MapArea::SubDesert3 => format!("data/maps/map_desert03_0{}_0{}e.dat", self.major, self.minor),
MapArea::SaintMillion => "data/maps/map_boss09_00_00e.dat".into(),
if self.mode == MapVariantMode::Online {
match self.map {
MapArea::Pioneer2Ep1 => "data/maps/map_city00_00e.dat".into(),
MapArea::Forest1 => format!("data/maps/map_forest01_0{}e.dat", self.minor),
MapArea::Forest2 => format!("data/maps/map_forest02_0{}e.dat", self.minor),
MapArea::Caves1 => format!("data/maps/map_cave01_0{}_0{}e.dat", self.major, self.minor),
MapArea::Caves2 => format!("data/maps/map_cave02_0{}_0{}e.dat", self.major, self.minor),
MapArea::Caves3 => format!("data/maps/map_cave03_0{}_0{}e.dat", self.major, self.minor),
MapArea::Mines1 => format!("data/maps/map_machine01_0{}_0{}e.dat", self.major, self.minor),
MapArea::Mines2 => format!("data/maps/map_machine02_0{}_0{}e.dat", self.major, self.minor),
MapArea::Ruins1 => format!("data/maps/map_ancient01_0{}_0{}e.dat", self.major, self.minor),
MapArea::Ruins2 => format!("data/maps/map_ancient02_0{}_0{}e.dat", self.major, self.minor),
MapArea::Ruins3 => format!("data/maps/map_ancient03_0{}_0{}e.dat", self.major, self.minor),
MapArea::Dragon => "data/maps/map_boss01e.dat".into(),
MapArea::DeRolLe => "data/maps/map_boss02e.dat".into(),
MapArea::VolOpt => "data/maps/map_boss03e.dat".into(),
MapArea::DarkFalz => "data/maps/map_boss04e.dat".into(),
MapArea::Pioneer2Ep2 => "data/maps/map_labo00_00e.dat".into(),
MapArea::VrTempleAlpha => format!("data/maps/map_ruins01_0{}_0{}e.dat", self.major, self.minor),
MapArea::VrTempleBeta => format!("data/maps/map_ruins02_0{}_0{}e.dat", self.major, self.minor),
MapArea::VrSpaceshipAlpha => format!("data/maps/map_space01_0{}_0{}e.dat", self.major, self.minor),
MapArea::VrSpaceshipBeta => format!("data/maps/map_space02_0{}_0{}e.dat", self.major, self.minor),
MapArea::Cca => format!("data/maps/map_jungle01_0{}e.dat", self.minor),
MapArea::JungleAreaNorth => format!("data/maps/map_jungle02_0{}e.dat", self.minor),
MapArea::JungleAreaEast => format!("data/maps/map_jungle03_0{}e.dat", self.minor),
MapArea::Mountain => format!("data/maps/map_jungle04_0{}_0{}e.dat", self.major, self.minor),
MapArea::Seaside => format!("data/maps/map_jungle05_0{}e.dat", self.minor),
MapArea::SeabedUpper => format!("data/maps/map_seabed01_0{}_0{}e.dat", self.major, self.minor),
MapArea::SeabedLower => format!("data/maps/map_seabed02_0{}_0{}e.dat", self.major, self.minor),
MapArea::GalGryphon => "data/maps/map_boss05e.dat".into(),
MapArea::OlgaFlow => "data/maps/map_boss06e.dat".into(),
MapArea::BarbaRay => "data/maps/map_boss07e.dat".into(),
MapArea::GolDragon => "data/maps/map_boss08e.dat".into(),
MapArea::Pioneer2Ep4 => "data/maps/map_city02_00_00e.dat".into(),
MapArea::CraterEast => format!("data/maps/map_wilds01_0{}_0{}e.dat", self.major, self.minor),
MapArea::CraterWest => format!("data/maps/map_wilds01_0{}_0{}e.dat", self.major, self.minor),
MapArea::CraterSouth => format!("data/maps/map_wilds01_0{}_0{}e.dat", self.major, self.minor),
MapArea::CraterNorth => format!("data/maps/map_wilds01_0{}_0{}e.dat", self.major, self.minor),
MapArea::CraterInterior => format!("data/maps/map_crater01_0{}_0{}e.dat", self.major, self.minor),
MapArea::SubDesert1 => format!("data/maps/map_desert01_0{}_0{}e.dat", self.major, self.minor),
MapArea::SubDesert2 => format!("data/maps/map_desert02_0{}_0{}e.dat", self.major, self.minor),
MapArea::SubDesert3 => format!("data/maps/map_desert03_0{}_0{}e.dat", self.major, self.minor),
MapArea::SaintMillion => "data/maps/map_boss09_00_00e.dat".into(),
}
} else { // Offline
match self.map {
MapArea::Pioneer2Ep1 => "data/maps/map_city00_00e_s.dat".into(),
MapArea::Forest1 => format!("data/maps/map_forest01_0{}_offe.dat", self.minor*2),
MapArea::Forest2 => format!("data/maps/map_forest02_0{}_offe.dat", self.minor),
MapArea::Caves1 => format!("data/maps/map_cave01_0{}_0{}_offe.dat", self.major, self.minor),
MapArea::Caves2 => format!("data/maps/map_cave02_0{}_0{}_offe.dat", self.major, self.minor),
MapArea::Caves3 => format!("data/maps/map_cave03_0{}_0{}_offe.dat", self.major, self.minor),
MapArea::Mines1 => format!("data/maps/map_machine01_0{}_0{}e.dat", self.major, self.minor),
MapArea::Mines2 => format!("data/maps/map_machine02_0{}_0{}e.dat", self.major, self.minor),
MapArea::Ruins1 => format!("data/maps/map_ancient01_0{}_0{}e.dat", self.major, self.minor),
MapArea::Ruins2 => format!("data/maps/map_ancient02_0{}_0{}e.dat", self.major, self.minor),
MapArea::Ruins3 => format!("data/maps/map_ancient03_0{}_0{}e.dat", self.major, self.minor),
MapArea::Dragon => "data/maps/map_boss01e.dat".into(),
MapArea::DeRolLe => "data/maps/map_boss02e.dat".into(),
MapArea::VolOpt => "data/maps/map_boss03e.dat".into(),
MapArea::DarkFalz => "data/maps/map_boss04e.dat".into(),
MapArea::Pioneer2Ep2 => "data/maps/map_labo00_00e.dat".into(),
MapArea::VrTempleAlpha => format!("data/maps/map_ruins01_0{}_0{}e.dat", self.major, self.minor),
MapArea::VrTempleBeta => format!("data/maps/map_ruins02_0{}_0{}e.dat", self.major, self.minor),
MapArea::VrSpaceshipAlpha => format!("data/maps/map_space01_0{}_0{}e.dat", self.major, self.minor),
MapArea::VrSpaceshipBeta => format!("data/maps/map_space02_0{}_0{}e.dat", self.major, self.minor),
MapArea::Cca => format!("data/maps/map_jungle01_0{}e.dat", self.minor),
MapArea::JungleAreaNorth => format!("data/maps/map_jungle02_0{}e.dat", self.minor),
MapArea::JungleAreaEast => format!("data/maps/map_jungle03_0{}e.dat", self.minor),
MapArea::Mountain => format!("data/maps/map_jungle04_0{}_0{}e.dat", self.major, self.minor),
MapArea::Seaside => format!("data/maps/map_jungle05_0{}e.dat", self.minor),
MapArea::SeabedUpper => format!("data/maps/map_seabed01_0{}_0{}e.dat", self.major, self.minor),
MapArea::SeabedLower => format!("data/maps/map_seabed02_0{}_0{}e.dat", self.major, self.minor),
MapArea::GalGryphon => "data/maps/map_boss05e.dat".into(),
MapArea::OlgaFlow => "data/maps/map_boss06e.dat".into(),
MapArea::BarbaRay => "data/maps/map_boss07e.dat".into(),
MapArea::GolDragon => "data/maps/map_boss08e.dat".into(),
MapArea::Pioneer2Ep4 => "data/maps/map_city02_00_00e.dat".into(),
MapArea::CraterEast => format!("data/maps/map_wilds01_0{}_0{}e.dat", self.major, self.minor),
MapArea::CraterWest => format!("data/maps/map_wilds01_0{}_0{}e.dat", self.major, self.minor),
MapArea::CraterSouth => format!("data/maps/map_wilds01_0{}_0{}e.dat", self.major, self.minor),
MapArea::CraterNorth => format!("data/maps/map_wilds01_0{}_0{}e.dat", self.major, self.minor),
MapArea::CraterInterior => format!("data/maps/map_crater01_0{}_0{}e.dat", self.major, self.minor),
MapArea::SubDesert1 => format!("data/maps/map_desert01_0{}_0{}e.dat", self.major, self.minor),
MapArea::SubDesert2 => format!("data/maps/map_desert02_0{}_0{}e.dat", self.major, self.minor),
MapArea::SubDesert3 => format!("data/maps/map_desert03_0{}_0{}e.dat", self.major, self.minor),
MapArea::SaintMillion => "data/maps/map_boss09_00_00e.dat".into(),
}
} }
} }
fn obj_file(&self) -> String { fn obj_file(&self) -> String {
match self.map {
MapArea::Pioneer2Ep1 => "data/maps/map_city00_00o.dat".into(),
MapArea::Forest1 => format!("data/maps/map_forest01_0{}o.dat", self.minor),
MapArea::Forest2 => format!("data/maps/map_forest02_0{}o.dat", self.minor),
MapArea::Caves1 => format!("data/maps/map_cave01_0{}_0{}o.dat", self.major, self.minor),
MapArea::Caves2 => format!("data/maps/map_cave02_0{}_0{}o.dat", self.major, self.minor),
MapArea::Caves3 => format!("data/maps/map_cave03_0{}_0{}o.dat", self.major, self.minor),
MapArea::Mines1 => format!("data/maps/map_machine01_0{}_0{}o.dat", self.major, self.minor),
MapArea::Mines2 => format!("data/maps/map_machine02_0{}_0{}o.dat", self.major, self.minor),
MapArea::Ruins1 => format!("data/maps/map_ancient01_0{}_0{}o.dat", self.major, self.minor),
MapArea::Ruins2 => format!("data/maps/map_ancient02_0{}_0{}o.dat", self.major, self.minor),
MapArea::Ruins3 => format!("data/maps/map_ancient03_0{}_0{}o.dat", self.major, self.minor),
MapArea::Dragon => "data/maps/map_boss01o.dat".into(),
MapArea::DeRolLe => "data/maps/map_boss02o.dat".into(),
MapArea::VolOpt => "data/maps/map_boss03o.dat".into(),
MapArea::DarkFalz => "data/maps/map_boss04o.dat".into(),
MapArea::Pioneer2Ep2 => "data/maps/map_labo00_00o.dat".into(),
MapArea::VrTempleAlpha => format!("data/maps/map_ruins01_0{}_0{}o.dat", self.major, self.minor),
MapArea::VrTempleBeta => format!("data/maps/map_ruins02_0{}_0{}o.dat", self.major, self.minor),
MapArea::VrSpaceshipAlpha => format!("data/maps/map_space01_0{}_0{}o.dat", self.major, self.minor),
MapArea::VrSpaceshipBeta => format!("data/maps/map_space02_0{}_0{}o.dat", self.major, self.minor),
MapArea::Cca => format!("data/maps/map_jungle01_0{}o.dat", self.major),
MapArea::JungleAreaNorth => format!("data/maps/map_jungle02_0{}o.dat", self.major),
MapArea::JungleAreaEast => format!("data/maps/map_jungle03_0{}o.dat", self.major),
MapArea::Mountain => format!("data/maps/map_jungle04_0{}_0{}o.dat", self.major, self.minor),
MapArea::Seaside => format!("data/maps/map_jungle05_0{}o.dat", self.major),
MapArea::SeabedUpper => format!("data/maps/map_seabed01_0{}_0{}o.dat", self.major, self.minor),
MapArea::SeabedLower => format!("data/maps/map_seabed02_0{}_0{}o.dat", self.major, self.minor),
MapArea::GalGryphon => "data/maps/map_boss05o.dat".into(),
MapArea::OlgaFlow => "data/maps/map_boss06o.dat".into(),
MapArea::BarbaRay => "data/maps/map_boss07o.dat".into(),
MapArea::GolDragon => "data/maps/map_boss08o.dat".into(),
MapArea::Pioneer2Ep4 => "data/maps/map_city02_00_00o.dat".into(),
MapArea::CraterEast => format!("data/maps/map_wilds01_0{}_0{}o.dat", self.major, self.minor),
MapArea::CraterWest => format!("data/maps/map_wilds01_0{}_0{}o.dat", self.major, self.minor),
MapArea::CraterSouth => format!("data/maps/map_wilds01_0{}_0{}o.dat", self.major, self.minor),
MapArea::CraterNorth => format!("data/maps/map_wilds01_0{}_0{}o.dat", self.major, self.minor),
MapArea::CraterInterior => format!("data/maps/map_crater01_0{}_0{}o.dat", self.major, self.minor),
MapArea::SubDesert1 => format!("data/maps/map_desert01_0{}_0{}o.dat", self.major, self.minor),
MapArea::SubDesert2 => format!("data/maps/map_desert02_0{}_0{}o.dat", self.major, self.minor),
MapArea::SubDesert3 => format!("data/maps/map_desert03_0{}_0{}o.dat", self.major, self.minor),
MapArea::SaintMillion => "data/maps/map_boss09_00_00o.dat".into(),
if self.mode == MapVariantMode::Online {
match self.map {
MapArea::Pioneer2Ep1 => "data/maps/map_city00_00o.dat".into(),
MapArea::Forest1 => format!("data/maps/map_forest01_0{}o.dat", self.minor),
MapArea::Forest2 => format!("data/maps/map_forest02_0{}o.dat", self.minor),
MapArea::Caves1 => format!("data/maps/map_cave01_0{}_0{}o.dat", self.major, self.minor),
MapArea::Caves2 => format!("data/maps/map_cave02_0{}_0{}o.dat", self.major, self.minor),
MapArea::Caves3 => format!("data/maps/map_cave03_0{}_0{}o.dat", self.major, self.minor),
MapArea::Mines1 => format!("data/maps/map_machine01_0{}_0{}o.dat", self.major, self.minor),
MapArea::Mines2 => format!("data/maps/map_machine02_0{}_0{}o.dat", self.major, self.minor),
MapArea::Ruins1 => format!("data/maps/map_ancient01_0{}_0{}o.dat", self.major, self.minor),
MapArea::Ruins2 => format!("data/maps/map_ancient02_0{}_0{}o.dat", self.major, self.minor),
MapArea::Ruins3 => format!("data/maps/map_ancient03_0{}_0{}o.dat", self.major, self.minor),
MapArea::Dragon => "data/maps/map_boss01o.dat".into(),
MapArea::DeRolLe => "data/maps/map_boss02o.dat".into(),
MapArea::VolOpt => "data/maps/map_boss03o.dat".into(),
MapArea::DarkFalz => "data/maps/map_boss04o.dat".into(),
MapArea::Pioneer2Ep2 => "data/maps/map_labo00_00o.dat".into(),
MapArea::VrTempleAlpha => format!("data/maps/map_ruins01_0{}_0{}o.dat", self.major, self.minor),
MapArea::VrTempleBeta => format!("data/maps/map_ruins02_0{}_0{}o.dat", self.major, self.minor),
MapArea::VrSpaceshipAlpha => format!("data/maps/map_space01_0{}_0{}o.dat", self.major, self.minor),
MapArea::VrSpaceshipBeta => format!("data/maps/map_space02_0{}_0{}o.dat", self.major, self.minor),
MapArea::Cca => format!("data/maps/map_jungle01_0{}o.dat", self.major),
MapArea::JungleAreaNorth => format!("data/maps/map_jungle02_0{}o.dat", self.major),
MapArea::JungleAreaEast => format!("data/maps/map_jungle03_0{}o.dat", self.major),
MapArea::Mountain => format!("data/maps/map_jungle04_0{}_0{}o.dat", self.major, self.minor),
MapArea::Seaside => format!("data/maps/map_jungle05_0{}o.dat", self.major),
MapArea::SeabedUpper => format!("data/maps/map_seabed01_0{}_0{}o.dat", self.major, self.minor),
MapArea::SeabedLower => format!("data/maps/map_seabed02_0{}_0{}o.dat", self.major, self.minor),
MapArea::GalGryphon => "data/maps/map_boss05o.dat".into(),
MapArea::OlgaFlow => "data/maps/map_boss06o.dat".into(),
MapArea::BarbaRay => "data/maps/map_boss07o.dat".into(),
MapArea::GolDragon => "data/maps/map_boss08o.dat".into(),
MapArea::Pioneer2Ep4 => "data/maps/map_city02_00_00o.dat".into(),
MapArea::CraterEast => format!("data/maps/map_wilds01_0{}_0{}o.dat", self.major, self.minor),
MapArea::CraterWest => format!("data/maps/map_wilds01_0{}_0{}o.dat", self.major, self.minor),
MapArea::CraterSouth => format!("data/maps/map_wilds01_0{}_0{}o.dat", self.major, self.minor),
MapArea::CraterNorth => format!("data/maps/map_wilds01_0{}_0{}o.dat", self.major, self.minor),
MapArea::CraterInterior => format!("data/maps/map_crater01_0{}_0{}o.dat", self.major, self.minor),
MapArea::SubDesert1 => format!("data/maps/map_desert01_0{}_0{}o.dat", self.major, self.minor),
MapArea::SubDesert2 => format!("data/maps/map_desert02_0{}_0{}o.dat", self.major, self.minor),
MapArea::SubDesert3 => format!("data/maps/map_desert03_0{}_0{}o.dat", self.major, self.minor),
MapArea::SaintMillion => "data/maps/map_boss09_00_00o.dat".into(),
}
} else {
match self.map {
MapArea::Pioneer2Ep1 => "data/maps/map_city00_00o_s.dat".into(),
MapArea::Forest1 => format!("data/maps/map_forest01_0{}o.dat", self.minor),
MapArea::Forest2 => format!("data/maps/map_forest02_0{}o.dat", self.minor),
MapArea::Caves1 => format!("data/maps/map_cave01_0{}_0{}o.dat", self.major, self.minor),
MapArea::Caves2 => format!("data/maps/map_cave02_0{}_0{}o.dat", self.major, self.minor),
MapArea::Caves3 => format!("data/maps/map_cave03_0{}_0{}o.dat", self.major, self.minor),
MapArea::Mines1 => format!("data/maps/map_machine01_0{}_0{}o.dat", self.major, self.minor),
MapArea::Mines2 => format!("data/maps/map_machine02_0{}_0{}o.dat", self.major, self.minor),
MapArea::Ruins1 => format!("data/maps/map_ancient01_0{}_0{}o.dat", self.major, self.minor),
MapArea::Ruins2 => format!("data/maps/map_ancient02_0{}_0{}o.dat", self.major, self.minor),
MapArea::Ruins3 => format!("data/maps/map_ancient03_0{}_0{}o.dat", self.major, self.minor),
MapArea::Dragon => "data/maps/map_boss01o.dat".into(),
MapArea::DeRolLe => "data/maps/map_boss02o.dat".into(),
MapArea::VolOpt => "data/maps/map_boss03o.dat".into(),
MapArea::DarkFalz => "data/maps/map_boss04_offo.dat".into(),
MapArea::Pioneer2Ep2 => "data/maps/map_labo00_00o.dat".into(),
MapArea::VrTempleAlpha => format!("data/maps/map_ruins01_0{}_0{}o.dat", self.major, self.minor),
MapArea::VrTempleBeta => format!("data/maps/map_ruins02_0{}_0{}o.dat", self.major, self.minor),
MapArea::VrSpaceshipAlpha => format!("data/maps/map_space01_0{}_0{}o.dat", self.major, self.minor),
MapArea::VrSpaceshipBeta => format!("data/maps/map_space02_0{}_0{}o.dat", self.major, self.minor),
MapArea::Cca => format!("data/maps/map_jungle01_0{}o.dat", self.major),
MapArea::JungleAreaNorth => format!("data/maps/map_jungle02_0{}o.dat", self.major),
MapArea::JungleAreaEast => format!("data/maps/map_jungle03_0{}o.dat", self.major),
MapArea::Mountain => format!("data/maps/map_jungle04_0{}_0{}o.dat", self.major, self.minor),
MapArea::Seaside => format!("data/maps/map_jungle05_0{}o.dat", self.major),
MapArea::SeabedUpper => format!("data/maps/map_seabed01_0{}_0{}o.dat", self.major, self.minor),
MapArea::SeabedLower => format!("data/maps/map_seabed02_0{}_0{}o.dat", self.major, self.minor),
MapArea::GalGryphon => "data/maps/map_boss05o.dat".into(),
MapArea::OlgaFlow => "data/maps/map_boss06o.dat".into(),
MapArea::BarbaRay => "data/maps/map_boss07o.dat".into(),
MapArea::GolDragon => "data/maps/map_boss08o.dat".into(),
MapArea::Pioneer2Ep4 => "data/maps/map_city02_00_00o.dat".into(),
MapArea::CraterEast => format!("data/maps/map_wilds01_0{}_0{}o.dat", self.major, self.minor),
MapArea::CraterWest => format!("data/maps/map_wilds01_0{}_0{}o.dat", self.major, self.minor),
MapArea::CraterSouth => format!("data/maps/map_wilds01_0{}_0{}o.dat", self.major, self.minor),
MapArea::CraterNorth => format!("data/maps/map_wilds01_0{}_0{}o.dat", self.major, self.minor),
MapArea::CraterInterior => format!("data/maps/map_crater01_0{}_0{}o.dat", self.major, self.minor),
MapArea::SubDesert1 => format!("data/maps/map_desert01_0{}_0{}o.dat", self.major, self.minor),
MapArea::SubDesert2 => format!("data/maps/map_desert02_0{}_0{}o.dat", self.major, self.minor),
MapArea::SubDesert3 => format!("data/maps/map_desert03_0{}_0{}o.dat", self.major, self.minor),
MapArea::SaintMillion => "data/maps/map_boss09_00_00o.dat".into(),
}
} }
} }
@ -760,6 +972,7 @@ pub fn objects_from_stream(cursor: &mut impl Read, episode: &Episode, map_area:
} }
fn objects_from_map_data(path: PathBuf, episode: &Episode, map_area: &MapArea) -> Vec<Option<MapObject>> { fn objects_from_map_data(path: PathBuf, episode: &Episode, map_area: &MapArea) -> Vec<Option<MapObject>> {
println!("objects_from_map_data() path: {:?}, episode: {:?}, map_area: {:?}", path, episode, map_area);
let mut cursor = File::open(path.clone()).unwrap(); let mut cursor = File::open(path.clone()).unwrap();
objects_from_stream(&mut cursor, episode, map_area) objects_from_stream(&mut cursor, episode, map_area)
} }
@ -841,6 +1054,41 @@ fn parse_enemy(episode: &Episode, map_area: &MapArea, raw_enemy: RawMapEnemy) ->
monsters.push(Some(MapEnemy::new(MonsterType::DarkFalz2, monster.map_area))); monsters.push(Some(MapEnemy::new(MonsterType::DarkFalz2, monster.map_area)));
monsters.push(Some(MapEnemy::new(MonsterType::DarkFalz1, monster.map_area))); monsters.push(Some(MapEnemy::new(MonsterType::DarkFalz1, monster.map_area)));
}, },
MonsterType::OlgaFlow => {
for _ in 0..512 {
monsters.push(Some(MapEnemy::new(MonsterType::OlgaFlow, monster.map_area)));
}
},
MonsterType::BarbaRay => {
for _ in 0..47 {
monsters.push(Some(MapEnemy::new(MonsterType::PigRay, monster.map_area)));
}
},
MonsterType::GolDragon => {
for _ in 0..5 {
monsters.push(Some(MapEnemy::new(MonsterType::GolDragon, monster.map_area)));
}
},
MonsterType::SinowBerill => {
for _ in 0..4 {
monsters.push(Some(MapEnemy::new(MonsterType::SinowBerill, monster.map_area))); // unused clones
}
},
MonsterType::SinowSpigell => {
for _ in 0..4 {
monsters.push(Some(MapEnemy::new(MonsterType::SinowSpigell, monster.map_area))); // unused clones
}
},
MonsterType::Recobox => { // + recons
for _ in 0..raw_enemy.children {
monsters.push(Some(MapEnemy::new(MonsterType::Recon, monster.map_area)));
}
},
MonsterType::Epsilon => {
for _ in 0..4 {
monsters.push(Some(MapEnemy::new(MonsterType::Epsiguard, monster.map_area)));
}
},
_ => { _ => {
for _ in 0..raw_enemy.children { for _ in 0..raw_enemy.children {
monsters.push(Some(MapEnemy::new(monster.monster, monster.map_area))); monsters.push(Some(MapEnemy::new(monster.monster, monster.map_area)));
@ -862,6 +1110,7 @@ pub fn enemy_data_from_stream(cursor: &mut impl Read, map_area: &MapArea, episod
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) -> Vec<Option<MapEnemy>> {
let path = map_variant.dat_file(); let path = map_variant.dat_file();
println!("loaded map: {:?}", path);
let mut cursor = File::open(path).unwrap(); 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)
} }
@ -876,16 +1125,16 @@ pub enum MapsError {
#[derive(Debug)] #[derive(Debug)]
pub struct Maps { pub struct Maps {
map_variants: [MapVariant; 15], // Needs to be a vector. There is an unequal number of maps on each episode
map_variants: Vec<MapVariant>,
enemy_data: Vec<Option<MapEnemy>>, enemy_data: Vec<Option<MapEnemy>>,
object_data: Vec<Option<MapObject>>, object_data: Vec<Option<MapObject>>,
} }
impl Maps { impl Maps {
pub fn new(episode: Episode) -> Maps {
let map_variants = match episode {
Episode::One => {
[MapVariant::new(MapArea::Pioneer2Ep1, MapVariantMode::Online),
pub fn new(room_mode: RoomMode) -> Maps {
let map_variants = match (room_mode.episode(), room_mode.single_player()) {
(Episode::One, 0) => {
vec![MapVariant::new(MapArea::Pioneer2Ep1, MapVariantMode::Online),
MapVariant::new(MapArea::Forest1, MapVariantMode::Online), MapVariant::new(MapArea::Forest1, MapVariantMode::Online),
MapVariant::new(MapArea::Forest2, MapVariantMode::Online), MapVariant::new(MapArea::Forest2, MapVariantMode::Online),
MapVariant::new(MapArea::Caves1, MapVariantMode::Online), MapVariant::new(MapArea::Caves1, MapVariantMode::Online),
@ -902,8 +1151,26 @@ impl Maps {
MapVariant::new(MapArea::DarkFalz, MapVariantMode::Online), MapVariant::new(MapArea::DarkFalz, MapVariantMode::Online),
] ]
}, },
Episode::Two => {
[MapVariant::new(MapArea::Pioneer2Ep2, MapVariantMode::Online),
(Episode::One, 1) => {
vec![MapVariant::new(MapArea::Pioneer2Ep1, MapVariantMode::Offline),
MapVariant::new(MapArea::Forest1, MapVariantMode::Offline),
MapVariant::new(MapArea::Forest2, MapVariantMode::Offline),
MapVariant::new(MapArea::Caves1, MapVariantMode::Offline),
MapVariant::new(MapArea::Caves2, MapVariantMode::Offline),
MapVariant::new(MapArea::Caves3, MapVariantMode::Offline),
MapVariant::new(MapArea::Mines1, MapVariantMode::Offline),
MapVariant::new(MapArea::Mines2, MapVariantMode::Offline),
MapVariant::new(MapArea::Ruins1, MapVariantMode::Offline),
MapVariant::new(MapArea::Ruins2, MapVariantMode::Offline),
MapVariant::new(MapArea::Ruins3, MapVariantMode::Offline),
MapVariant::new(MapArea::Dragon, MapVariantMode::Offline),
MapVariant::new(MapArea::DeRolLe, MapVariantMode::Offline),
MapVariant::new(MapArea::VolOpt, MapVariantMode::Offline),
MapVariant::new(MapArea::DarkFalz, MapVariantMode::Offline),
]
},
(Episode::Two, 0) => {
vec![MapVariant::new(MapArea::Pioneer2Ep2, MapVariantMode::Online),
MapVariant::new(MapArea::VrTempleAlpha, MapVariantMode::Online), MapVariant::new(MapArea::VrTempleAlpha, MapVariantMode::Online),
MapVariant::new(MapArea::VrTempleBeta, MapVariantMode::Online), MapVariant::new(MapArea::VrTempleBeta, MapVariantMode::Online),
MapVariant::new(MapArea::VrSpaceshipAlpha, MapVariantMode::Online), MapVariant::new(MapArea::VrSpaceshipAlpha, MapVariantMode::Online),
@ -921,8 +1188,27 @@ impl Maps {
MapVariant::new(MapArea::GolDragon, MapVariantMode::Online), MapVariant::new(MapArea::GolDragon, MapVariantMode::Online),
] ]
}, },
Episode::Four => {
[MapVariant::new(MapArea::Pioneer2Ep4, MapVariantMode::Online),
(Episode::Two, 1) => {
vec![MapVariant::new(MapArea::Pioneer2Ep2, MapVariantMode::Offline),
MapVariant::new(MapArea::VrTempleAlpha, MapVariantMode::Offline),
MapVariant::new(MapArea::VrTempleBeta, MapVariantMode::Offline),
MapVariant::new(MapArea::VrSpaceshipAlpha, MapVariantMode::Offline),
MapVariant::new(MapArea::VrSpaceshipBeta, MapVariantMode::Offline),
MapVariant::new(MapArea::Cca, MapVariantMode::Offline),
MapVariant::new(MapArea::JungleAreaNorth, MapVariantMode::Offline),
MapVariant::new(MapArea::JungleAreaEast, MapVariantMode::Offline),
MapVariant::new(MapArea::Mountain, MapVariantMode::Offline),
MapVariant::new(MapArea::Seaside, MapVariantMode::Offline),
MapVariant::new(MapArea::SeabedUpper, MapVariantMode::Offline),
MapVariant::new(MapArea::SeabedLower, MapVariantMode::Offline),
MapVariant::new(MapArea::GalGryphon, MapVariantMode::Offline),
MapVariant::new(MapArea::OlgaFlow, MapVariantMode::Offline),
MapVariant::new(MapArea::BarbaRay, MapVariantMode::Offline),
MapVariant::new(MapArea::GolDragon, MapVariantMode::Offline),
]
},
(Episode::Four, _) => {
vec![MapVariant::new(MapArea::Pioneer2Ep4, MapVariantMode::Online),
MapVariant::new(MapArea::CraterEast, MapVariantMode::Online), MapVariant::new(MapArea::CraterEast, MapVariantMode::Online),
MapVariant::new(MapArea::CraterWest, MapVariantMode::Online), MapVariant::new(MapArea::CraterWest, MapVariantMode::Online),
MapVariant::new(MapArea::CraterSouth, MapVariantMode::Online), MapVariant::new(MapArea::CraterSouth, MapVariantMode::Online),
@ -934,20 +1220,22 @@ impl Maps {
MapVariant::new(MapArea::SaintMillion, MapVariantMode::Online), MapVariant::new(MapArea::SaintMillion, MapVariantMode::Online),
] ]
}, },
_ => panic!()
_ => unreachable!()
}; };
let maps = Maps { let maps = Maps {
enemy_data: map_variants.iter().fold(Vec::new(), |mut enemy_data, map_variant| { enemy_data: map_variants.iter().fold(Vec::new(), |mut enemy_data, map_variant| {
enemy_data.append(&mut enemy_data_from_map_data(&map_variant, &episode));
// enemy_data.append(&mut enemy_data_from_map_data(&map_variant, &episode));
enemy_data.append(&mut enemy_data_from_map_data(&map_variant, &room_mode.episode()));
enemy_data enemy_data
}), }),
object_data: map_variants.iter().map(|map_variant| { object_data: map_variants.iter().map(|map_variant| {
objects_from_map_data(map_variant.obj_file().into(), &episode, &map_variant.map)
objects_from_map_data(map_variant.obj_file().into(), &room_mode.episode(), &map_variant.map)
}).flatten().collect(), }).flatten().collect(),
map_variants: map_variants, map_variants: map_variants,
}; };
println!("loading maps: {:?}", maps.map_variants);
println!("loading objects: {:?}", maps.object_data);
maps maps
} }
@ -956,6 +1244,7 @@ impl Maps {
} }
pub fn object_by_id(&self, id: usize) -> Result<MapObject, MapsError> { pub fn object_by_id(&self, id: usize) -> Result<MapObject, MapsError> {
println!("{:?}", self.object_data[id]);
self.object_data[id].ok_or(MapsError::InvalidObjectId(id)) self.object_data[id].ok_or(MapsError::InvalidObjectId(id))
} }

116
src/ship/monster.rs

@ -17,22 +17,16 @@ pub enum MonsterParseError {
pub enum MonsterType { pub enum MonsterType {
Hildebear, Hildebear,
Hildeblue, Hildeblue,
SandRappy,
Mothmant,
Monest,
RagRappy, RagRappy,
AlRappy, AlRappy,
EasterRappy,
StRappy,
HalloRappy,
LoveRappy,
Monest,
Mothmant,
SavageWolf, SavageWolf,
BarbarousWolf, BarbarousWolf,
Booma, Booma,
Gobooma, Gobooma,
Gigobooma, Gigobooma,
GrassAssassin, GrassAssassin,
DelLily,
PoisonLily, PoisonLily,
NarLily, NarLily,
NanoDragon, NanoDragon,
@ -45,14 +39,12 @@ pub enum MonsterType {
Hidoom, Hidoom,
Migium, Migium,
Dubchic, Dubchic,
Gillchic,
Garanz, Garanz,
SinowBeat, SinowBeat,
SinowGold, SinowGold,
Canadine, Canadine,
RingCanadine,
Canane, Canane,
Dubwitch,
RingCanadine,
Delsaber, Delsaber,
ChaosSorcerer, ChaosSorcerer,
BeeR, BeeR,
@ -61,14 +53,13 @@ pub enum MonsterType {
DeathGunner, DeathGunner,
ChaosBringer, ChaosBringer,
DarkBelra, DarkBelra,
Claw,
Bulk,
Bulclaw,
Dimenian, Dimenian,
LaDimenian, LaDimenian,
SoDimenian, SoDimenian,
Bulclaw,
Bulk,
Claw,
Dragon, Dragon,
GalGryphon,
DeRolLe, DeRolLe,
DeRolLeBody, DeRolLeBody,
DeRolLeMine, DeRolLeMine,
@ -86,48 +77,74 @@ pub enum MonsterType {
DarkFalz3, DarkFalz3,
Darvant, Darvant,
UltDarvant, UltDarvant,
OlgaFlow,
BarbaRay,
GolDragon,
SinowBerill,
SinowSpigell,
Dubwitch,
Gillchic,
EventRappy,
Merillia, Merillia,
Meriltas, Meriltas,
Gee,
GiGue,
Mericarol, Mericarol,
Merikle, Merikle,
Mericus, Mericus,
UlGibbon, UlGibbon,
ZolGibbon, ZolGibbon,
Gibbles, Gibbles,
Gee,
GiGue,
Deldepth,
Delbiter,
Dolmdarl,
SinowBerill,
SinowSpigell,
Dolmolm, Dolmolm,
Dolmdarl,
Morfos, Morfos,
Recon,
Recobox, Recobox,
Epsilon,
Epsiguard,
Recon,
SinowZoa, SinowZoa,
SinowZele, SinowZele,
Deldepth,
Delbiter,
BarbaRay,
PigRay,
GolDragon,
GalGryphon,
OlgaFlow,
OlgaFlow1,
OlgaFlow2,
Gael,
Giel,
StRappy,
HalloRappy,
EasterRappy,
LoveRappy,
IllGill, IllGill,
Astark,
SatelliteLizard,
Yowie,
MerissaA,
Girtablulu,
Zu,
DelLily,
Epsilon,
Epsiguard,
Boota, Boota,
ZeBoota, ZeBoota,
BaBoota, BaBoota,
SandRappyCrater,
SandRappyDesert,
ZuCrater,
PazuzuCrater,
Astark,
SatelliteLizardCrater,
YowieCrater,
Dorphon, Dorphon,
DorphonEclair,
Goran, Goran,
PyroGoran,
GoranDetonator, GoranDetonator,
PyroGoran,
DelRappyCrater,
DelRappyDesert,
MerissaA,
MerissaAA,
ZuDesert,
PazuzuDesert,
SatelliteLizardDesert,
YowieDesert,
Girtablulu,
SaintMillion, SaintMillion,
Shambertin, Shambertin,
Kondrieu,
} }
@ -154,6 +171,7 @@ fn load_battle_param(filename: &str) -> HashMap<MonsterType, MonsterStats> {
toml::from_str::<HashMap<String, MonsterStats>>(s.as_str()).unwrap() toml::from_str::<HashMap<String, MonsterStats>>(s.as_str()).unwrap()
.into_iter() .into_iter()
.map(|(monster_name, stats)| { .map(|(monster_name, stats)| {
println!("parsing monster_name :{:?}", monster_name);
(monster_name.parse().unwrap(), stats) (monster_name.parse().unwrap(), stats)
}).collect() }).collect()
} }
@ -164,6 +182,34 @@ pub fn load_monster_stats_table(mode: &RoomMode) -> HashMap<MonsterType, Monster
RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::Hard} => load_battle_param("ep1_multi_hard.toml"), RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::Hard} => load_battle_param("ep1_multi_hard.toml"),
RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::VeryHard} => load_battle_param("ep1_multi_veryhard.toml"), RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::VeryHard} => load_battle_param("ep1_multi_veryhard.toml"),
RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::Ultimate} => load_battle_param("ep1_multi_ultimate.toml"), RoomMode::Multi {episode: Episode::One, difficulty: Difficulty::Ultimate} => load_battle_param("ep1_multi_ultimate.toml"),
RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::Normal} => load_battle_param("ep2_multi_normal.toml"),
RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::Hard} => load_battle_param("ep2_multi_hard.toml"),
RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::VeryHard} => load_battle_param("ep2_multi_veryhard.toml"),
RoomMode::Multi {episode: Episode::Two, difficulty: Difficulty::Ultimate} => load_battle_param("ep2_multi_ultimate.toml"),
RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::Normal} => load_battle_param("ep4_multi_normal.toml"),
RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::Hard} => load_battle_param("ep4_multi_hard.toml"),
RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::VeryHard} => load_battle_param("ep4_multi_veryhard.toml"),
RoomMode::Multi {episode: Episode::Four, difficulty: Difficulty::Ultimate} => load_battle_param("ep4_multi_ultimate.toml"),
RoomMode::Single {episode: Episode::One, difficulty: Difficulty::Normal} => load_battle_param("ep1_solo_normal.toml"),
RoomMode::Single {episode: Episode::One, difficulty: Difficulty::Hard} => load_battle_param("ep1_solo_hard.toml"),
RoomMode::Single {episode: Episode::One, difficulty: Difficulty::VeryHard} => load_battle_param("ep1_solo_veryhard.toml"),
RoomMode::Single {episode: Episode::One, difficulty: Difficulty::Ultimate} => load_battle_param("ep1_solo_ultimate.toml"),
RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::Normal} => load_battle_param("ep2_solo_normal.toml"),
RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::Hard} => load_battle_param("ep2_solo_hard.toml"),
RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::VeryHard} => load_battle_param("ep2_solo_veryhard.toml"),
RoomMode::Single {episode: Episode::Two, difficulty: Difficulty::Ultimate} => load_battle_param("ep2_solo_ultimate.toml"),
RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::Normal} => load_battle_param("ep4_solo_normal.toml"),
RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::Hard} => load_battle_param("ep4_solo_hard.toml"),
RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::VeryHard} => load_battle_param("ep4_solo_veryhard.toml"),
RoomMode::Single {episode: Episode::Four, difficulty: Difficulty::Ultimate} => load_battle_param("ep4_solo_ultimate.toml"),
_ => panic!(), _ => panic!(),
} }
} }

1
src/ship/packet/handler/message.rs

@ -26,6 +26,7 @@ pub async fn request_exp<EG: EntityGateway>(id: ClientId,
.ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?; .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?;
let monster = room.maps.enemy_by_id(request_exp.enemy_id as usize)?; let monster = room.maps.enemy_by_id(request_exp.enemy_id as usize)?;
dbg!(monster);
let monster_stats = room.monster_stats.get(&monster.monster).unwrap(); let monster_stats = room.monster_stats.get(&monster.monster).unwrap();
let exp_gain = if request_exp.last_hitter == 1 { let exp_gain = if request_exp.last_hitter == 1 {

2
src/ship/room.rs

@ -234,7 +234,7 @@ impl RoomState {
random_seed: rand::thread_rng().gen(), random_seed: rand::thread_rng().gen(),
name: String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).into(), name: String::from_utf16_lossy(&create_room.name).trim_matches(char::from(0)).into(),
password: create_room.password, password: create_room.password,
maps: Maps::new(room_mode.episode()),
maps: Maps::new(room_mode),
section_id: section_id, section_id: section_id,
drop_table: Box::new(DropTable::new(room_mode.episode(), room_mode.difficulty(), section_id)), drop_table: Box::new(DropTable::new(room_mode.episode(), room_mode.difficulty(), section_id)),
bursting: false, bursting: false,

Loading…
Cancel
Save