1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-07-10 07:57:46 +00:00

Make loading zone LGBs more accurate

The game actually has a list of LGBs for the territory/zone in a
LVB file, so we don't have to hardcode a list of names.
This commit is contained in:
Joshua Goins 2025-07-04 11:33:01 -04:00
parent 37f0e07116
commit c65e413900
2 changed files with 39 additions and 45 deletions

23
Cargo.lock generated
View file

@ -213,9 +213,9 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.2.27" version = "1.2.28"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" checksum = "4ad45f4f74e4e20eaa392913b7b33a7091c87e59628f4dd27888205ad888843c"
dependencies = [ dependencies = [
"jobserver", "jobserver",
"libc", "libc",
@ -689,6 +689,17 @@ dependencies = [
"hashbrown", "hashbrown",
] ]
[[package]]
name = "io-uring"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
dependencies = [
"bitflags",
"cfg-if",
"libc",
]
[[package]] [[package]]
name = "ipnet" name = "ipnet"
version = "2.11.0" version = "2.11.0"
@ -1048,7 +1059,7 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]] [[package]]
name = "physis" name = "physis"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/redstrate/physis#5a5896a1261c13732ec856fbb9badbdd5da196d6" source = "git+https://github.com/redstrate/physis#b74a5c3a9615001ff5604f783d4929d917596924"
dependencies = [ dependencies = [
"binrw", "binrw",
"bitflags", "bitflags",
@ -1438,15 +1449,17 @@ dependencies = [
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.45.1" version = "1.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" checksum = "1140bb80481756a8cbe10541f37433b459c5aa1e727b4c020fbfebdc25bf3ec4"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"bytes", "bytes",
"io-uring",
"libc", "libc",
"mio", "mio",
"pin-project-lite", "pin-project-lite",
"slab",
"socket2", "socket2",
"tokio-macros", "tokio-macros",
"windows-sys 0.52.0", "windows-sys 0.52.0",

View file

@ -4,6 +4,7 @@ use physis::{
layer::{ layer::{
ExitRangeInstanceObject, InstanceObject, LayerEntryData, LayerGroup, PopRangeInstanceObject, ExitRangeInstanceObject, InstanceObject, LayerEntryData, LayerGroup, PopRangeInstanceObject,
}, },
lvb::Lvb,
}; };
use crate::common::{GameData, TerritoryNameKind}; use crate::common::{GameData, TerritoryNameKind};
@ -16,13 +17,7 @@ pub struct Zone {
pub region_name: String, pub region_name: String,
pub place_name: String, pub place_name: String,
pub intended_use: u8, pub intended_use: u8,
planevent: Option<LayerGroup>, pub layer_groups: Vec<LayerGroup>,
vfx: Option<LayerGroup>,
planmap: Option<LayerGroup>,
planner: Option<LayerGroup>,
bg: Option<LayerGroup>,
sound: Option<LayerGroup>,
planlive: Option<LayerGroup>,
} }
impl Zone { impl Zone {
@ -44,12 +39,11 @@ impl Zone {
// e.g. ffxiv/fst_f1/fld/f1f3/level/f1f3 // e.g. ffxiv/fst_f1/fld/f1f3/level/f1f3
let bg_path = row.Bg().into_string().unwrap(); let bg_path = row.Bg().into_string().unwrap();
let Some(level_index) = bg_path.find("/level/") else { let path = format!("bg/{}.lvb", &bg_path);
return zone; let lgb_file = game_data.game_data.extract(&path).unwrap();
}; let lgb = Lvb::from_existing(&lgb_file).unwrap();
let mut load_lgb = |name: &str| -> Option<LayerGroup> { let mut load_lgb = |path: &str| -> Option<LayerGroup> {
let path = format!("bg/{}/level/{}.lgb", &bg_path[..level_index], name);
let lgb_file = game_data.game_data.extract(&path)?; let lgb_file = game_data.game_data.extract(&path)?;
tracing::info!("Loading {path}"); tracing::info!("Loading {path}");
let lgb = LayerGroup::from_existing(&lgb_file); let lgb = LayerGroup::from_existing(&lgb_file);
@ -61,13 +55,11 @@ impl Zone {
lgb lgb
}; };
zone.planevent = load_lgb("planevent"); for path in &lgb.scns[0].header.path_layer_group_resources {
zone.vfx = load_lgb("vfx"); if let Some(lgb) = load_lgb(&path) {
zone.planmap = load_lgb("planmap"); zone.layer_groups.push(lgb);
zone.planner = load_lgb("planner"); }
zone.bg = load_lgb("bg"); }
zone.sound = load_lgb("sound");
zone.planlive = load_lgb("planlive");
// load names // load names
let fallback = "<Unable to load name!>"; let fallback = "<Unable to load name!>";
@ -90,11 +82,13 @@ impl Zone {
instance_id: u32, instance_id: u32,
) -> Option<(&InstanceObject, &ExitRangeInstanceObject)> { ) -> Option<(&InstanceObject, &ExitRangeInstanceObject)> {
// TODO: also check position! // TODO: also check position!
for group in &self.planmap.as_ref().unwrap().chunks[0].layers { for layer_group in &self.layer_groups {
for object in &group.objects { for layer in &layer_group.chunks[0].layers {
if let LayerEntryData::ExitRange(exit_range) = &object.data { for object in &layer.objects {
if object.instance_id == instance_id { if let LayerEntryData::ExitRange(exit_range) = &object.data {
return Some((object, exit_range)); if object.instance_id == instance_id {
return Some((object, exit_range));
}
} }
} }
} }
@ -108,22 +102,9 @@ impl Zone {
instance_id: u32, instance_id: u32,
) -> Option<(&InstanceObject, &PopRangeInstanceObject)> { ) -> Option<(&InstanceObject, &PopRangeInstanceObject)> {
// TODO: also check position! // TODO: also check position!
if let Some(planmap) = self.planmap.as_ref() { for layer_group in &self.layer_groups {
for group in &planmap.chunks[0].layers { for layer in &layer_group.chunks[0].layers {
for object in &group.objects { for object in &layer.objects {
if let LayerEntryData::PopRange(pop_range) = &object.data {
if object.instance_id == instance_id {
return Some((object, pop_range));
}
}
}
}
}
if let Some(planevent) = self.planevent.as_ref() {
// For certain PopRanges (e.g. the starting position in the opening zones)
for group in &planevent.chunks[0].layers {
for object in &group.objects {
if let LayerEntryData::PopRange(pop_range) = &object.data { if let LayerEntryData::PopRange(pop_range) = &object.data {
if object.instance_id == instance_id { if object.instance_id == instance_id {
return Some((object, pop_range)); return Some((object, pop_range));