use log::warn; use std::io::Cursor; use std::convert::Into; use std::path::PathBuf; use std::io::{Read}; use std::fs::File; use byteorder::{LittleEndian, ReadBytesExt}; use crate::ship::monster::MonsterType; use crate::ship::room::Episode; #[derive(Debug, Copy, Clone)] struct RawMapEnemy { id: u32, _unknown1: u16, children: u16, _unknown3: u16, _unknown4: u16, section: u16, wave_idd: u16, wave_id: u32, x: f32, y: f32, z: f32, xrot: u32, yrot: u32, zrot: u32, _field1: u32, field2: u32, _field3: u32, _field4: u32, _field5: u32, skin: u32, _field6: u32 } impl RawMapEnemy { fn from_byte_stream(cursor: &mut R) -> Result { Ok(RawMapEnemy { id: cursor.read_u32::()?, _unknown1: cursor.read_u16::()?, children: cursor.read_u16::()?, _unknown3: cursor.read_u16::()?, _unknown4: cursor.read_u16::()?, section: cursor.read_u16::()?, wave_idd: cursor.read_u16::()?, wave_id: cursor.read_u32::()?, x: cursor.read_f32::()?, y: cursor.read_f32::()?, z: cursor.read_f32::()?, xrot: cursor.read_u32::()?, yrot: cursor.read_u32::()?, zrot: cursor.read_u32::()?, _field1: cursor.read_u32::()?, field2: cursor.read_u32::()?, _field3: cursor.read_u32::()?, _field4: cursor.read_u32::()?, _field5: cursor.read_u32::()?, skin: cursor.read_u32::()?, _field6: cursor.read_u32::()?, }) } } struct MapObjects { } struct MapEnemies { } impl MapEnemies { fn new(path: PathBuf) -> MapEnemies { MapEnemies { } } fn read_next_enemy(&mut self) -> Option { None } } #[derive(Debug)] enum MapEnemyError { UnknownEnemyId(u32), } #[derive(Debug, Copy, Clone)] pub struct MapEnemy { pub monster: MonsterType, hp: u32, // other stats from bp.n dead: bool, } impl MapEnemy { fn from_raw(enemy: RawMapEnemy, episode: &Episode /*, battleparam */) -> Result { 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::DubchicSwitch, (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::Olga, (RawMapEnemy {id: 203, ..}, _) => MonsterType::BarbaRay, (RawMapEnemy {id: 204, ..}, _) => MonsterType::GolDragon, (RawMapEnemy {id: 212, skin: 0, ..}, _) => MonsterType::SinowBeril, (RawMapEnemy {id: 212, skin: 1, ..}, _) => MonsterType::SinowSpigell, (RawMapEnemy {id: 213, skin: 0, ..}, _) => MonsterType::Merillias, (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::ReconBox, (RawMapEnemy {id: 224, ..}, _) => MonsterType::Epsilon, (RawMapEnemy {id: 224, skin: 0, ..}, _) => MonsterType::SinowZoa, (RawMapEnemy {id: 224, skin: 1, ..}, _) => MonsterType::SinowZele, (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, _ => return Err(MapEnemyError::UnknownEnemyId(enemy.id)) //_ => panic!("trying to load unknown monster: {:?}", enemy) }; Ok(MapEnemy { monster: monster, hp: 0, dead: false, }) } fn new(monster: MonsterType) -> MapEnemy { MapEnemy { monster: monster, hp: 0, dead: false, } } } //impl From for MapEnemy #[derive(Debug)] pub struct Maps { //map_indexes: enemy_data: Vec } impl Maps { pub fn new() -> Maps { let mut maps = Maps { enemy_data: Vec::new(), }; maps.add_map("data/maps/map_city00_00e.dat".into()); maps.add_map("data/maps/map_forest01_00e.dat".into()); maps.add_map("data/maps/map_cave01_00_00e.dat".into()); warn!("len {}", maps.enemy_data.len()); maps } fn add_map(&mut self, path: PathBuf) { let mut cursor = File::open(path).unwrap(); while let Ok(enemy) = RawMapEnemy::from_byte_stream(&mut cursor) { let new_enemy = MapEnemy::from_raw(enemy); match new_enemy.monster { MonsterType::Monest => { self.enemy_data.push(new_enemy); for _ in 0..30 { self.enemy_data.push(MapEnemy::new(MonsterType::Mothmant)); } }, _ => self.enemy_data.push(new_enemy) } } } pub fn enemy_by_id(&self, id: usize) -> MapEnemy { self.enemy_data[id] } }