From 84fc27ceea09a97421155c118213cee1153ab5e8 Mon Sep 17 00:00:00 2001 From: andy Date: Mon, 7 Jun 2021 16:42:55 +0000 Subject: [PATCH] map objects 1 --- Cargo.toml | 3 + data/quests.toml | 18 ++- src/bin/main.rs | 34 ++--- src/ship/map/maps.rs | 6 + src/ship/map/object.rs | 167 +++++++++++++++++++++- src/ship/packet/handler/direct_message.rs | 1 + src/ship/quests.rs | 3 +- 7 files changed, 212 insertions(+), 20 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d9c1bff..c29372b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,6 @@ strum = "0.19.5" strum_macros = "0.19" anyhow = "1.0.33" +[patch."http://git.sharnoth.com/jake/libpso"] +libpso = { path = "../libpso" } + diff --git a/data/quests.toml b/data/quests.toml index a316475..29e4440 100644 --- a/data/quests.toml +++ b/data/quests.toml @@ -32,4 +32,20 @@ dat = "q233-ext-bb.dat" [[Retrieval.quests]] bin = "q236-ext-bb.bin" dat = "q236-ext-bb.dat" -#drop_table = "q102-drops" \ No newline at end of file + +[Shop] +list_order = 3 +description = "buy some shit" + +[[Shop.quests]] +bin = "q219-shp-bb.bin" +dat = "q219-shp-bb.dat" +#drop_table = "q204-drops" + +[TTF] +list_order = 4 +description = "best quest" + +[[TTF.quests]] +bin = "q118-vr-bb.bin" +dat = "q118-vr-bb.dat" diff --git a/src/bin/main.rs b/src/bin/main.rs index f5b7823..63dd791 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -72,9 +72,11 @@ fn main() { character.name = "ItemRefactor".into(); character.exp = 80000000; character.meseta = 999999; + // character.techs.set_tech(elseware::entity::item::tech::Technique::Shifta, elseware::entity::character::TechLevel(3)); + // character.techs.set_tech(elseware::entity::item::tech::Technique::Deband, elseware::entity::character::TechLevel(3)); let character = entity_gateway.create_character(character).await.unwrap(); - for _ in 0..3 { + for _ in 0..3usize { entity_gateway.create_item( item::NewItemEntity { item: item::ItemDetail::Weapon( @@ -93,7 +95,7 @@ fn main() { }).await.unwrap(); } - for _ in 0..8 { + for _ in 0..8usize { entity_gateway.create_item( NewItemEntity { item: ItemDetail::Tool ( @@ -112,13 +114,13 @@ fn main() { NewItemEntity { item: ItemDetail::Weapon( item::weapon::Weapon { - weapon: item::weapon::WeaponType::Raygun, + weapon: item::weapon::WeaponType::Decalog, grind: 5, - special: Some(item::weapon::WeaponSpecial::Hell), - attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 40}), - Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 30}), + special: None, + attrs: [None, + None, None,], - tekked: false, + tekked: true, } ), location: ItemLocation::Inventory { @@ -291,8 +293,8 @@ fn main() { NewItemEntity { item: ItemDetail::Unit( item::unit::Unit { - unit: item::unit::UnitType::PriestMind, - modifier: Some(item::unit::UnitModifier::Minus), + unit: item::unit::UnitType::V101, + modifier: None, } ), location: ItemLocation::Inventory { @@ -304,8 +306,8 @@ fn main() { NewItemEntity { item: ItemDetail::Unit( item::unit::Unit { - unit: item::unit::UnitType::PriestMind, - modifier: Some(item::unit::UnitModifier::Minus), + unit: item::unit::UnitType::HeavenlyPower, + modifier: None, } ), location: ItemLocation::Inventory { @@ -317,8 +319,8 @@ fn main() { NewItemEntity { item: ItemDetail::Unit( item::unit::Unit { - unit: item::unit::UnitType::PriestMind, - modifier: Some(item::unit::UnitModifier::Minus), + unit: item::unit::UnitType::HeavenlyPower, + modifier: None, } ), location: ItemLocation::Inventory { @@ -330,8 +332,8 @@ fn main() { NewItemEntity { item: ItemDetail::Unit( item::unit::Unit { - unit: item::unit::UnitType::PriestMind, - modifier: Some(item::unit::UnitModifier::Minus), + unit: item::unit::UnitType::HeavenlyPower, + modifier: None, } ), location: ItemLocation::Inventory { @@ -351,7 +353,7 @@ fn main() { ).await.unwrap(); let equipped = item::EquippedEntity { - weapon: Some(item2_w.id), + weapon: Some(item4.id), armor: Some(item7_a.id), shield: Some(item8_s.id), unit: [Some(item9_u0.id), Some(item10_u1.id), Some(item11_u2.id), Some(item12_u3.id)], diff --git a/src/ship/map/maps.rs b/src/ship/map/maps.rs index 3f7f515..af41523 100644 --- a/src/ship/map/maps.rs +++ b/src/ship/map/maps.rs @@ -19,7 +19,13 @@ pub fn objects_from_stream(cursor: &mut impl Read, episode: &Episode, map_area: while let Ok(raw_object) = RawMapObject::from_byte_stream(cursor) { let object = MapObject::from_raw(raw_object.clone(), *episode, map_area); object_data.push(object.ok()); + println!("PRINTING RAW OBJECT: {:?}", raw_object); } + // object_data needs to be sorted based on map area ie: p2 map objects should be enumerated first (p2,f,c,m,r,d,drl,v,df)? + println!("ship::map::maps.rs -- objects_from_stream() -- printing out all objects"); + for o in &object_data { + println!("{:?}", o); + }; object_data } diff --git a/src/ship/map/object.rs b/src/ship/map/object.rs index dde1e7e..6571b38 100644 --- a/src/ship/map/object.rs +++ b/src/ship/map/object.rs @@ -124,6 +124,91 @@ pub enum MapObjectType { EmptyFixedBox(FixedBoxDropType), RuinsEmptyBox, RuinsEmptyFixedBox, + + // taken from qedit v1.0 public + // TODO: update names + // TODO: add missing objects + // TODO: sort by otype + MenuActivation, + PlaceHolder, + SpawnPosition, + Teleporter, + PrincipalWarp, + TelepipeLocation, + MedicalCenterDoor, + ShopDoor, + HuntersGuildDoor, + TeleporterDoor, + RicoMessagePod, + BossTeleporter, + MapDetect, + SetEventActivation, + ForestDoor, + RandomTypeBox1, // is this different than "Box"? + ForestConsole, + CavesNormalDoor, + FloorPanel2, // implies floor panel 1? + TouchPlateObject, + EffectObject, + CavesSmashingPillar, + LaserFenceEx, // Ex?? + MinesDoor, + PopupTrapsTechs, + Ruins3Door, + RuinsWarpSiteToSite, + RuinsTeleporter, + RuinsPillarTrap, // falling cage trap + Darkness, + RandomBoxTypeRuins, // is this different than "Box"? + FunctionTouchPlate, + Warp, // found in vol opt map? + RuinsSeal, // totem door. unused in bb? + Poison, // found in vol opt map? poison fog?? + LobbyTeleporter, + MainRagolTeleporter, + Pioneer2InvisibleTouchplate, + LaserFence, + ForestLaserFenceSwitch, + ElementalTrap, + StatusTrap, + HealTrap, + HealRing, + ForestSwitch, + LaserSquareFence, + Probe, + ForestWeatherStation, + LaserBarrierDoor, + ForestRisingBridge, + SwitchNoneDoor, + FloorPanel1, + Caves4ButtonDoor, + CavesSign1, + CavesSign3, + CavesSwitchDoor, + Caves1LargeRedRock, + Caves2SmallRock1, + Caves2LargeRock2, + FloorPanel3, + MinesSwitchDoor, + MinesLargeFlashingCrate, + RuinsSwitch, + FloorPanel4, + Ruins1Door, + Ruins2Door, + Ruins4ButtonDoor, + Ruins2ButtonDoor, + RuinsFenceSwitch, + RuinsLaserFence4x2, + RuinsLaserFence6x2, + RuinsPoisonBlob, + RuinsCrystal, + Monument, + RuinsRock1, + RuinsRock2, + RuinsRock3, + RuinsRock4, + RuinsRock5, + RuinsRock6, } #[derive(Debug, Copy, Clone)] @@ -143,11 +228,88 @@ pub enum MapObjectError { impl MapObject { pub fn from_raw(raw: RawMapObject, episode: Episode, map_area: &MapArea) -> Result { let object = match (raw, episode) { - (RawMapObject {otype: 136, ..}, _) => MapObjectType::Box, + (RawMapObject {otype: 0, ..}, _) => MapObjectType::SpawnPosition, + (RawMapObject {otype: 2, ..}, _) => MapObjectType::Teleporter, + (RawMapObject {otype: 3, ..}, _) => MapObjectType::Warp, + (RawMapObject {otype: 8, ..}, _) => MapObjectType::SetEventActivation, + (RawMapObject {otype: 10, ..}, _) => MapObjectType::ElementalTrap, + (RawMapObject {otype: 11, ..}, _) => MapObjectType::StatusTrap, + (RawMapObject {otype: 12, ..}, _) => MapObjectType::HealTrap, + (RawMapObject {otype: 14, ..}, _) => MapObjectType::MapDetect, + (RawMapObject {otype: 18, ..}, _) => MapObjectType::FunctionTouchPlate, + (RawMapObject {otype: 19, ..}, _) => MapObjectType::HealRing, + (RawMapObject {otype: 24, ..}, _) => MapObjectType::Darkness, + (RawMapObject {otype: 25, ..}, _) => MapObjectType::BossTeleporter, + (RawMapObject {otype: 34, ..}, _) => MapObjectType::TouchPlateObject, + (RawMapObject {otype: 36, ..}, _) => MapObjectType::EffectObject, + (RawMapObject {otype: 64, ..}, _) => MapObjectType::MenuActivation, + (RawMapObject {otype: 65, ..}, _) => MapObjectType::TelepipeLocation, + (RawMapObject {otype: 67, ..}, _) => MapObjectType::MainRagolTeleporter, + (RawMapObject {otype: 68, ..}, _) => MapObjectType::LobbyTeleporter, + (RawMapObject {otype: 69, ..}, _) => MapObjectType::PrincipalWarp, + (RawMapObject {otype: 70, ..}, _) => MapObjectType::ShopDoor, + (RawMapObject {otype: 71, ..}, _) => MapObjectType::HuntersGuildDoor, + (RawMapObject {otype: 72, ..}, _) => MapObjectType::TeleporterDoor, + (RawMapObject {otype: 73, ..}, _) => MapObjectType::MedicalCenterDoor, + (RawMapObject {otype: 87, ..}, _) => MapObjectType::Pioneer2InvisibleTouchplate, + (RawMapObject {otype: 128, ..}, _) => MapObjectType::ForestDoor, + (RawMapObject {otype: 129, ..}, _) => MapObjectType::ForestSwitch, + (RawMapObject {otype: 130, ..}, _) => MapObjectType::LaserFence, + (RawMapObject {otype: 131, ..}, _) => MapObjectType::LaserSquareFence, + (RawMapObject {otype: 132, ..}, _) => MapObjectType::ForestLaserFenceSwitch, + (RawMapObject {otype: 135, ..}, _) => MapObjectType::Probe, + (RawMapObject {otype: 137, ..}, _) => MapObjectType::ForestWeatherStation, + (RawMapObject {otype: 139, ..}, _) => MapObjectType::ForestConsole, + (RawMapObject {otype: 141, ..}, _) => MapObjectType::RicoMessagePod, + (RawMapObject {otype: 142, ..}, _) => MapObjectType::LaserBarrierDoor, + (RawMapObject {otype: 143, ..}, _) => MapObjectType::ForestRisingBridge, + (RawMapObject {otype: 144, ..}, _) => MapObjectType::SwitchNoneDoor, (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: 150, ..}, _) => MapObjectType::LaserFenceEx, + (RawMapObject {otype: 192, ..}, _) => MapObjectType::FloorPanel1, + (RawMapObject {otype: 193, ..}, _) => MapObjectType::Caves4ButtonDoor, + (RawMapObject {otype: 194, ..}, _) => MapObjectType::CavesNormalDoor, + (RawMapObject {otype: 195, ..}, _) => MapObjectType::CavesSmashingPillar, + (RawMapObject {otype: 196, ..}, _) => MapObjectType::CavesSign1, + (RawMapObject {otype: 198, ..}, _) => MapObjectType::CavesSign3, + (RawMapObject {otype: 206, ..}, _) => MapObjectType::CavesSwitchDoor, + (RawMapObject {otype: 211, ..}, _) => MapObjectType::Caves1LargeRedRock, + (RawMapObject {otype: 212, ..}, _) => MapObjectType::Caves2SmallRock1, + (RawMapObject {otype: 217, ..}, _) => MapObjectType::Caves2LargeRock2, + (RawMapObject {otype: 222, ..}, _) => MapObjectType::FloorPanel2, + (RawMapObject {otype: 256, ..}, _) => MapObjectType::MinesDoor, + (RawMapObject {otype: 257, ..}, _) => MapObjectType::FloorPanel3, + (RawMapObject {otype: 258, ..}, _) => MapObjectType::MinesSwitchDoor, + (RawMapObject {otype: 268, ..}, _) => MapObjectType::MinesLargeFlashingCrate, + (RawMapObject {otype: 304, ..}, _) => MapObjectType::RuinsSeal, + (RawMapObject {otype: 320, ..}, _) => MapObjectType::RuinsTeleporter, + (RawMapObject {otype: 321, ..}, _) => MapObjectType::RuinsWarpSiteToSite, + (RawMapObject {otype: 322, ..}, _) => MapObjectType::RuinsSwitch, + (RawMapObject {otype: 323, ..}, _) => MapObjectType::FloorPanel4, + (RawMapObject {otype: 324, ..}, _) => MapObjectType::Ruins1Door, + (RawMapObject {otype: 325, ..}, _) => MapObjectType::Ruins3Door, + (RawMapObject {otype: 326, ..}, _) => MapObjectType::Ruins2Door, + (RawMapObject {otype: 330, ..}, _) => MapObjectType::Ruins4ButtonDoor, + (RawMapObject {otype: 331, ..}, _) => MapObjectType::Ruins2ButtonDoor, + (RawMapObject {otype: 333, ..}, _) => MapObjectType::RuinsFenceSwitch, + (RawMapObject {otype: 334, ..}, _) => MapObjectType::RuinsLaserFence4x2, + (RawMapObject {otype: 335, ..}, _) => MapObjectType::RuinsLaserFence6x2, + (RawMapObject {otype: 338, ..}, _) => MapObjectType::RuinsPoisonBlob, + (RawMapObject {otype: 339, ..}, _) => MapObjectType::RuinsPillarTrap, + (RawMapObject {otype: 341, ..}, _) => MapObjectType::RuinsCrystal, + (RawMapObject {otype: 342, ..}, _) => MapObjectType::Monument, + (RawMapObject {otype: 345, ..}, _) => MapObjectType::RuinsRock1, + (RawMapObject {otype: 346, ..}, _) => MapObjectType::RuinsRock2, + (RawMapObject {otype: 347, ..}, _) => MapObjectType::RuinsRock3, + (RawMapObject {otype: 348, ..}, _) => MapObjectType::RuinsRock4, + (RawMapObject {otype: 349, ..}, _) => MapObjectType::RuinsRock5, + (RawMapObject {otype: 350, ..}, _) => MapObjectType::RuinsRock6, + (RawMapObject {otype: 352, ..}, _) => MapObjectType::Poison, + (RawMapObject {otype: 359, ..}, _) => MapObjectType::PopupTrapsTechs, + (RawMapObject {otype: 136, ..}, _) => MapObjectType::Box, (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)), @@ -155,7 +317,8 @@ impl MapObject { (RawMapObject {otype: 357, ..}, _) => MapObjectType::RuinsEmptyBox, (RawMapObject {otype: 512, ..}, _) => MapObjectType::CcaBox, (RawMapObject {otype: 515, ..}, _) => MapObjectType::CcaFixedBox(FixedBoxDropType::from_object(raw.field1, raw.field2, raw.field3, raw.field4)), - _ => return Err(MapObjectError::UnknownObjectType(raw.otype, raw)) + _ => return {println!("UNKNOWN OBJECT OTYPE --- ship::map::object::from_raw() - otype: {:?}, x: {:?}, y: {:?}, z: {:?}, id: {:?}, section: {:?}, maparea: {:?}, ", raw.otype, raw.x, raw.y, raw.z, raw.id, raw.section, map_area); + Err(MapObjectError::UnknownObjectType(raw.otype, raw))} }; Ok(MapObject { diff --git a/src/ship/packet/handler/direct_message.rs b/src/ship/packet/handler/direct_message.rs index 44a8fbf..371e619 100644 --- a/src/ship/packet/handler/direct_message.rs +++ b/src/ship/packet/handler/direct_message.rs @@ -191,6 +191,7 @@ EG: EntityGateway .as_mut() .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?; + println!("ship::packet::handler::direct_message.rs::request_box_item() - box object id: {:?}", box_drop_request.object_id); let box_object = room.maps.object_by_id(box_drop_request.object_id as usize)?; if box_object.dropped_item { return Err(ShipError::BoxAlreadyDroppedItem(id, box_drop_request.object_id).into()) diff --git a/src/ship/quests.rs b/src/ship/quests.rs index 5853cec..51b56c3 100644 --- a/src/ship/quests.rs +++ b/src/ship/quests.rs @@ -179,10 +179,11 @@ impl Quest { let name = array_to_utf16(&bin[24..88]); let description = array_to_utf16(&bin[88..334]); let full_description = array_to_utf16(&bin[334..920]); - + println!("parsing quest {:?}", name); let episode = quest_episode(&bin).ok_or(ParseDatError::CouldNotDetermineEpisode)?; let map_areas = map_area_mappings(&bin); let (enemies, objects) = parse_dat(&dat, &episode, &map_areas)?; + println!("got objects: {:?}", objects); let mut prs_bin = LegacyPrsEncoder::new(Vec::new()); prs_bin.write(&bin)?;