Browse Source

load map object files

pbs
jake 5 years ago
parent
commit
979636a4c4
  1. 193
      src/ship/map.rs

193
src/ship/map.rs

@ -183,6 +183,156 @@ impl MapEnemy {
}
}
#[derive(Debug, Copy, Clone)]
struct RawMapObject {
otype: u16,
unknown1: u16,
unknown2: u32,
id: u16,
group: u16,
section: u16,
unknown3: u16,
x: f32,
y: f32,
z: f32,
xrot: u32,
yrot: u32,
zrot: u32,
field1: f32,
field2: f32,
field3: f32,
field4: u32,
field5: u32,
field6: u32,
field7: u32,
}
impl RawMapObject {
fn from_byte_stream<R: Read>(cursor: &mut R) -> Result<RawMapObject, std::io::Error> {
Ok(RawMapObject {
otype: cursor.read_u16::<LittleEndian>()?,
unknown1: cursor.read_u16::<LittleEndian>()?,
unknown2: cursor.read_u32::<LittleEndian>()?,
id: cursor.read_u16::<LittleEndian>()?,
group: cursor.read_u16::<LittleEndian>()?,
section: cursor.read_u16::<LittleEndian>()?,
unknown3: cursor.read_u16::<LittleEndian>()?,
x: cursor.read_f32::<LittleEndian>()?,
y: cursor.read_f32::<LittleEndian>()?,
z: cursor.read_f32::<LittleEndian>()?,
xrot: cursor.read_u32::<LittleEndian>()?,
yrot: cursor.read_u32::<LittleEndian>()?,
zrot: cursor.read_u32::<LittleEndian>()?,
field1: cursor.read_f32::<LittleEndian>()?,
field2: cursor.read_f32::<LittleEndian>()?,
field3: cursor.read_f32::<LittleEndian>()?,
field4: cursor.read_u32::<LittleEndian>()?,
field5: cursor.read_u32::<LittleEndian>()?,
field6: cursor.read_u32::<LittleEndian>()?,
field7: cursor.read_u32::<LittleEndian>()?,
})
}
}
#[derive(Debug, Copy, Clone)]
pub enum FixedBoxDropType {
Weapon,
Armor,
Tool,
Meseta,
Random,
Specific(u32), // TODO: ItemDropType
}
impl FixedBoxDropType {
fn from_object(field1: f32, field2: f32, field3: f32, field4: u32) -> FixedBoxDropType {
match (field1.round() as i32, field2.round() as i32, field3.round() as i32, field4) {
(0, 1, 1, 0) => {
FixedBoxDropType::Random
},
(0, 1, _, 0x4000000) => {
FixedBoxDropType::Meseta
},
(0, 1, 1, _) => {
FixedBoxDropType::Specific(field4)
},
(-1, 1, 1, _) => { // ???????
FixedBoxDropType::Specific(field4)
},
(0, 1, 0, 0) => {
FixedBoxDropType::Weapon
},
(0, 1, 0, 0x1000000) => {
FixedBoxDropType::Armor
},
(0, 1, 0, 0x3000000) => {
FixedBoxDropType::Tool
},
(1, _, _, _) => {
FixedBoxDropType::Random
},
_ => {
println!("this box state should not occur? {} {} {} {}", field1.round() as i32, field2.round() as i32, field3.round() as i32, field4);
FixedBoxDropType::Random
}
}
}
}
#[derive(Debug, Copy, Clone)]
pub enum MapObjectType {
Box,
FixedBox(FixedBoxDropType),
EnemyBox,
EnemyFixedBox(FixedBoxDropType),
RuinsBox,
RuinsFixedBox(FixedBoxDropType),
RuinsEnemyBox,
RuinsEnemyFixedBox(FixedBoxDropType),
CcaBox,
CcaFixedBox(FixedBoxDropType),
EmptyBox,
EmptyFixedBox(FixedBoxDropType),
RuinsEmptyBox,
RuinsEmptyFixedBox,
}
#[derive(Debug, Copy, Clone)]
pub struct MapObject {
pub object: MapObjectType,
//id: u32,
}
#[derive(Debug, Copy, Clone)]
enum MapObjectError {
UnknownObjectType(u16, RawMapObject),
}
impl MapObject {
fn from_raw(raw: RawMapObject, episode: Episode) -> Result<MapObject, MapObjectError> {
let object = match (raw, episode) {
(RawMapObject {otype: 136, ..}, _) => MapObjectType::Box,
(RawMapObject {otype: 145, ..}, _) => MapObjectType::EnemyBox,
(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: 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,
_ => return Err(MapObjectError::UnknownObjectType(raw.otype, raw))
};
Ok(MapObject {
object: object,
})
}
}
#[derive(Debug)]
enum MapVariantMode {
@ -269,7 +419,7 @@ impl MapVariant {
minor: minor,
}
}
// TODO: rename to npc_file
fn dat_file(&self) -> String {
match self.map {
MapVariantType::Pioneer2Ep1 => "data/maps/map_city00_00e.dat".into(),
@ -290,12 +440,45 @@ impl MapVariant {
}
}
fn obj_file(&self) -> String {
match self.map {
MapVariantType::Pioneer2Ep1 => "data/maps/map_city00_00e.dat".into(),
MapVariantType::Forest1 => format!("data/maps/map_forest01_0{}o.dat", self.minor),
MapVariantType::Forest2 => format!("data/maps/map_forest02_0{}o.dat", self.minor),
MapVariantType::Caves1 => format!("data/maps/map_cave01_0{}_0{}o.dat", self.major, self.minor),
MapVariantType::Caves2 => format!("data/maps/map_cave02_0{}_0{}o.dat", self.major, self.minor),
MapVariantType::Caves3 => format!("data/maps/map_cave03_0{}_0{}o.dat", self.major, self.minor),
MapVariantType::Mines1 => format!("data/maps/map_machine01_0{}_0{}o.dat", self.major, self.minor),
MapVariantType::Mines2 => format!("data/maps/map_machine02_0{}_0{}o.dat", self.major, self.minor),
MapVariantType::Ruins1 => format!("data/maps/map_ancient01_0{}_0{}o.dat", self.major, self.minor),
MapVariantType::Ruins2 => format!("data/maps/map_ancient02_0{}_0{}o.dat", self.major, self.minor),
MapVariantType::Ruins3 => format!("data/maps/map_ancient03_0{}_0{}o.dat", self.major, self.minor),
MapVariantType::Dragon => "data/maps/map_boss01o.dat".into(),
MapVariantType::DeRolLe => "data/maps/map_boss02o.dat".into(),
MapVariantType::VolOpt => "data/maps/map_boss03o.dat".into(),
MapVariantType::DarkFalz => "data/maps/map_boss04o.dat".into(),
}
}
fn pkt_header(&self) -> [u8; 2] {
[self.major, self.minor]
}
}
fn objects_from_map_data(path: PathBuf, episode: &Episode) -> Vec<Option<MapObject>> {
let mut cursor = File::open(path.clone()).unwrap();
let mut object_data = Vec::new();
while let Ok(raw_object) = RawMapObject::from_byte_stream(&mut cursor) {
let object = MapObject::from_raw(raw_object.clone(), *episode);
object_data.push(object.ok());
}
object_data
}
fn enemy_data_from_map_data(path: PathBuf, episode: &Episode) -> Vec<Option<MapEnemy>> {
let mut cursor = File::open(path).unwrap();
let mut enemy_data = Vec::new();
@ -377,7 +560,6 @@ fn enemy_data_from_map_data(path: PathBuf, episode: &Episode) -> Vec<Option<MapE
monsters.push(Some(MapEnemy::new(MonsterType::DarkFalz1)));
},
_ => {
warn!("children: {}", enemy.children);
for _ in 0..enemy.children {
monsters.push(Some(MapEnemy::new(monster.monster)));
}
@ -393,12 +575,12 @@ fn enemy_data_from_map_data(path: PathBuf, episode: &Episode) -> Vec<Option<MapE
#[derive(Debug)]
pub struct Maps {
map_variants: [MapVariant; 15],
enemy_data: Vec<Option<MapEnemy>>
enemy_data: Vec<Option<MapEnemy>>,
object_data: Vec<Option<MapObject>>,
}
impl Maps {
pub fn new(episode: Episode) -> Maps {
warn!("new maps ep: {:?}", episode);
let map_variants = match episode {
Episode::One => {
[MapVariant::new(MapVariantType::Pioneer2Ep1, MapVariantMode::Online),
@ -426,6 +608,9 @@ impl Maps {
enemy_data.append(&mut enemy_data_from_map_data(map_variant.dat_file().into(), &episode));
enemy_data
}),
object_data: map_variants.iter().map(|map_variant| {
objects_from_map_data(map_variant.obj_file().into(), &episode)
}).flatten().collect(),
map_variants: map_variants,
};

Loading…
Cancel
Save