load map object files
This commit is contained in:
parent
2f2e9e5c5c
commit
979636a4c4
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…
x
Reference in New Issue
Block a user