Widen save-world finance neighborhood window

This commit is contained in:
Jan Petykiewicz 2026-04-17 21:01:45 -07:00
commit a73a789bac
4 changed files with 42 additions and 15 deletions

View file

@ -109,6 +109,8 @@ const RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_CANDIDATE_FIELDS: [(&str, usize)
("issue_neighbor_candidate_1", 0x31),
("issue_neighbor_candidate_2", 0x35),
];
const RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_ROOT_RELATIVE_OFFSET: usize = 0x11;
const RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_WINDOW_LEN_DWORDS: usize = 16;
const RT3_SAVE_WORLD_BLOCK_CHAIRMAN_SLOT_SELECTOR_RELATIVE_OFFSET: usize = 0x83;
const RT3_SAVE_WORLD_BLOCK_CAMPAIGN_OVERRIDE_FLAG_RELATIVE_OFFSET: usize = 0xc1;
const RT3_SAVE_WORLD_BLOCK_CHAIRMAN_ROLE_GATE_RELATIVE_OFFSET: usize = 0x0bbf;
@ -8705,12 +8707,8 @@ fn parse_save_world_finance_neighborhood_probe(
continue;
}
let dword_candidates = RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_CANDIDATE_FIELDS
.iter()
.map(|(label, relative_offset)| {
build_save_dword_candidate(bytes, payload_offset, label, *relative_offset)
})
.collect::<Option<Vec<_>>>()?;
let dword_candidates =
build_save_world_finance_neighborhood_candidates(bytes, payload_offset)?;
return Some(SmpSaveWorldFinanceNeighborhoodProbe {
profile_family: profile.profile_family.clone(),
@ -8736,6 +8734,24 @@ fn parse_save_world_finance_neighborhood_probe(
None
}
fn build_save_world_finance_neighborhood_candidates(
bytes: &[u8],
payload_offset: usize,
) -> Option<Vec<SmpSaveDwordCandidate>> {
(0..RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_WINDOW_LEN_DWORDS)
.map(|index| {
let relative_offset =
RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_ROOT_RELATIVE_OFFSET + index * 4;
let label = RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_CANDIDATE_FIELDS
.iter()
.find(|(_, named_offset)| *named_offset == relative_offset)
.map(|(name, _)| (*name).to_string())
.unwrap_or_else(|| format!("finance_neighborhood_word_{:02}", index + 1));
build_save_dword_candidate(bytes, payload_offset, &label, relative_offset)
})
.collect()
}
fn parse_save_world_economic_tuning_probe(
bytes: &[u8],
file_extension_hint: Option<&str>,
@ -15431,12 +15447,10 @@ mod tests {
let payload_offset = chunk_tag_offset + 4;
bytes[chunk_tag_offset..chunk_tag_offset + 4]
.copy_from_slice(&RT3_SAVE_WORLD_BLOCK_CHUNK_TAG.to_le_bytes());
for (index, (_, relative_offset)) in
RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_CANDIDATE_FIELDS
.iter()
.enumerate()
{
bytes[payload_offset + *relative_offset..payload_offset + *relative_offset + 4]
for index in 0..RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_WINDOW_LEN_DWORDS {
let relative_offset =
RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_ROOT_RELATIVE_OFFSET + index * 4;
bytes[payload_offset + relative_offset..payload_offset + relative_offset + 4]
.copy_from_slice(&((index as u32) + 1).to_le_bytes());
}
let next_chunk_offset = payload_offset + RT3_SAVE_WORLD_BLOCK_LEN;
@ -15458,7 +15472,7 @@ mod tests {
assert_eq!(probe.payload_offset, payload_offset);
assert_eq!(
probe.dword_candidates.len(),
RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_CANDIDATE_FIELDS.len()
RT3_SAVE_WORLD_BLOCK_FINANCE_NEIGHBORHOOD_WINDOW_LEN_DWORDS
);
assert_eq!(
probe.dword_candidates[0].label,
@ -15474,6 +15488,12 @@ mod tests {
);
assert_eq!(probe.dword_candidates[9].relative_offset_hex, "0x35");
assert_eq!(probe.dword_candidates[9].value_i32, 10);
assert_eq!(probe.dword_candidates[10].label, "finance_neighborhood_word_11");
assert_eq!(probe.dword_candidates[10].relative_offset_hex, "0x39");
assert_eq!(probe.dword_candidates[10].value_i32, 11);
assert_eq!(probe.dword_candidates[15].label, "finance_neighborhood_word_16");
assert_eq!(probe.dword_candidates[15].relative_offset_hex, "0x4d");
assert_eq!(probe.dword_candidates[15].value_i32, 16);
}
#[test]