fix: harden resource and world state correctness
This commit is contained in:
@@ -417,15 +417,8 @@ pub fn resolve_material(
|
||||
{
|
||||
return Ok(resolved);
|
||||
}
|
||||
if let Some(first) = table.entries.first() {
|
||||
if let Some(resolved) = load_material_entry(
|
||||
repository,
|
||||
archive,
|
||||
&first.material,
|
||||
MaterialFallback::FirstEntry,
|
||||
)? {
|
||||
return Ok(resolved);
|
||||
}
|
||||
if let Some(resolved) = load_first_material_entry(repository, archive)? {
|
||||
return Ok(resolved);
|
||||
}
|
||||
Err(MaterialError::MissingMaterial(
|
||||
String::from_utf8_lossy(&entry.material.0).into_owned(),
|
||||
@@ -610,6 +603,26 @@ fn load_material_entry(
|
||||
}))
|
||||
}
|
||||
|
||||
fn load_first_material_entry(
|
||||
repository: &dyn ResourceRepository,
|
||||
archive: fparkan_resource::ArchiveId,
|
||||
) -> Result<Option<ResolvedMaterial>, MaterialError> {
|
||||
let Some(handle) = repository.first_entry(archive)? else {
|
||||
return Ok(None);
|
||||
};
|
||||
let info = repository.entry_info(handle)?;
|
||||
if info.key.type_id != Some(MAT0_KIND) {
|
||||
return Ok(None);
|
||||
}
|
||||
let bytes = repository.read(handle)?.into_owned();
|
||||
let document = decode_mat0(&bytes, info.attr2)?;
|
||||
Ok(Some(ResolvedMaterial {
|
||||
name: info.key.name,
|
||||
fallback: MaterialFallback::FirstEntry,
|
||||
document,
|
||||
}))
|
||||
}
|
||||
|
||||
fn parse_lightmaps(lines: &[&str]) -> Result<Vec<LightmapEntry>, MaterialError> {
|
||||
if lines.is_empty() || lines.iter().all(|line| line.trim().is_empty()) {
|
||||
return Ok(Vec::new());
|
||||
@@ -926,6 +939,24 @@ mod tests {
|
||||
assert_eq!(resolved.fallback, MaterialFallback::FirstEntry);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_material_first_entry_uses_material_archive_not_wear_row_zero() {
|
||||
let repo = material_repo(&[
|
||||
material_entry(b"MAT_ARCHIVE_FIRST", &mat0_with_texture(b"TEX_ARCHIVE")),
|
||||
material_entry(b"MAT_WEAR_FIRST", &mat0_with_texture(b"TEX_WEAR")),
|
||||
]);
|
||||
let table = decode_wear(b"2\n0 MAT_WEAR_FIRST\n1 MISSING\n").expect("wear");
|
||||
|
||||
let resolved = resolve_material(&repo, &table, 1).expect("resolved");
|
||||
|
||||
assert_eq!(resolved.name.0, b"MAT_ARCHIVE_FIRST");
|
||||
assert_eq!(resolved.fallback, MaterialFallback::FirstEntry);
|
||||
assert_eq!(
|
||||
resolved.document.primary_texture().expect("texture").0,
|
||||
b"TEX_ARCHIVE"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_material_empty_texture_means_untextured() {
|
||||
let repo = material_repo(&[material_entry(b"MAT_EMPTY", &mat0_with_texture(b""))]);
|
||||
|
||||
Reference in New Issue
Block a user