the raid tab lands, and sounds take the reference's voice buses

- the social window's fourth tab, Raid: the eight-subgroup grid over the roster, drag a member between subgroups, Convert To Raid, promote / demote assistant, uninvite, Ready Check with its popup, and the Raid Info flyout on the new `CMSG_REQUEST_RAID_INFO` / `SMSG_RAID_INSTANCE_INFO` wire (byte-golden against vmangos, an empty answer decoding as an empty list); `raid1`..`raid40` unit tokens, and `/partytest raid` stages a roster for a solo look
- an imbue pressed with an empty weapon hand says "Your weapon hand is empty" instead of raising a cursor — the attribute bit has two readers in the reference and the second is the error (corrects the day's first cut)
- sounds route onto the reference's own voice buses with its per-bus caps (the 0x87ce60 table, pinned as bytes): weapon impacts and clangs share four voices, footsteps six, the attacker's grunt one, the victim's injury two — so a pack swinging together makes about a dozen voices where it made dozens

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Sam
2026-08-25 18:22:17 +07:00
co-authored by Claude Fable 5
parent 915ebc0119
commit eeb607e5e6
41 changed files with 3808 additions and 144 deletions
@@ -115,6 +115,28 @@ pub(super) fn assert_geometry_matches(
reference: &Path,
expected: &[&str],
min_compared: usize,
) {
assert_geometry_matches_text(
ours,
&std::fs::read_to_string(reference).unwrap(),
expected,
min_compared,
);
}
/// [`assert_geometry_matches`] against reference TEXT rather than a file on disk.
///
/// The split exists because not every reference file is *on* disk: `_extracted_framexml/` holds
/// FrameXML only, and a window whose specification is partly a `Blizzard_*` **addon** — the raid
/// grid is the first, decision 1549 — has to read its half straight out of the patch chain
/// (`benilla_formats::open_chain`, the same door `mpqx` uses). Reading it rather than requiring
/// someone to have extracted it first is what keeps that half of the diff ARMED instead of
/// skipped, and it writes nothing into the install.
pub(super) fn assert_geometry_matches_text(
ours: &str,
reference_text: &str,
expected: &[&str],
min_compared: usize,
) {
let ours_text = std::fs::read_to_string(
Path::new(env!("CARGO_MANIFEST_DIR"))
@@ -122,10 +144,7 @@ pub(super) fn assert_geometry_matches(
.join(ours),
)
.unwrap();
let theirs: HashMap<String, Vec<(f32, f32)>> =
scrape(&std::fs::read_to_string(reference).unwrap())
.into_iter()
.collect();
let theirs: HashMap<String, Vec<(f32, f32)>> = scrape(reference_text).into_iter().collect();
let mut compared = 0;
let mut drifted = Vec::new();