From 8659623edada9d8e0d35870e2b7d0aa730f50d3b Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sun, 23 Mar 2025 16:31:30 -0400 Subject: [PATCH] Allow loading territories without a planmap --- src/world/zone.rs | 50 +++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/world/zone.rs b/src/world/zone.rs index 4819061..c3fffd1 100644 --- a/src/world/zone.rs +++ b/src/world/zone.rs @@ -11,35 +11,51 @@ use crate::config::get_config; /// Represents a loaded zone pub struct Zone { pub id: u16, - layer_group: LayerGroup, + layer_group: Option, } impl Zone { pub fn load(id: u16) -> Self { let config = get_config(); - let mut game_data = - GameData::from_existing(Platform::Win32, &config.game_location).unwrap(); + let mut zone = Self { + id, + layer_group: None, + }; - let exh = game_data.read_excel_sheet_header("TerritoryType").unwrap(); - let exd = game_data - .read_excel_sheet("TerritoryType", &exh, Language::None, 0) - .unwrap(); + let Some(mut game_data) = GameData::from_existing(Platform::Win32, &config.game_location) + else { + return zone; + }; - let territory_type_row = &exd.read_row(&exh, id as u32).unwrap()[0]; + let Some(exh) = game_data.read_excel_sheet_header("TerritoryType") else { + return zone; + }; + let Some(exd) = game_data.read_excel_sheet("TerritoryType", &exh, Language::None, 0) else { + return zone; + }; + + let Some(territory_type_row) = &exd.read_row(&exh, id as u32) else { + return zone; + }; + let territory_type_row = &territory_type_row[0]; // e.g. ffxiv/fst_f1/fld/f1f3/level/f1f3 let physis::exd::ColumnData::String(bg_path) = &territory_type_row.data[1] else { panic!("Unexpected type!"); }; - let path = format!( - "bg/{}/level/planmap.lgb", - &bg_path[..bg_path.find("/level/").unwrap()] - ); - let lgb = game_data.extract(&path).unwrap(); - let layer_group = LayerGroup::from_existing(&lgb).unwrap(); - Self { id, layer_group } + let Some(level_index) = bg_path.find("/level/") else { + return zone; + }; + + let path = format!("bg/{}/level/planmap.lgb", &bg_path[..level_index]); + let Some(lgb) = game_data.extract(&path) else { + return zone; + }; + zone.layer_group = LayerGroup::from_existing(&lgb); + + zone } /// Search for an exit box matching an id. @@ -48,7 +64,7 @@ impl Zone { instance_id: u32, ) -> Option<(&InstanceObject, &ExitRangeInstanceObject)> { // TODO: also check position! - for group in &self.layer_group.layers { + for group in &self.layer_group.as_ref().unwrap().layers { for object in &group.objects { if let LayerEntryData::ExitRange(exit_range) = &object.data { if object.instance_id == instance_id { @@ -66,7 +82,7 @@ impl Zone { instance_id: u32, ) -> Option<(&InstanceObject, &PopRangeInstanceObject)> { // TODO: also check position! - for group in &self.layer_group.layers { + for group in &self.layer_group.as_ref().unwrap().layers { for object in &group.objects { if let LayerEntryData::PopRange(pop_range) = &object.data { if object.instance_id == instance_id {