Files
benilla-octo/crates/benilla-formats/tests/light_zero_key_band.rs
T
Sam SungandClaude Opus 5.5 8da634afa9 Comments in benilla-formats: one line of fact each, no history, no record numbers (#130)
Part of #41: the comments of `benilla-formats` (the library, its extract tools, examples and tests) are rewritten to the rule in `docs/METHOD.md`, which is what the code does and the reference fact behind it, in a line. 19,654 comment lines become 7,264.

Fixes #105: the WMO collision comments now name walking's box-query leaf `0x6bca50` and the camera and line-of-sight segment-query leaf `0x6bc700`, in `models/collision.rs`, `examples/wmo_bsp.rs` and `tests/chain.rs`.

- **The mechanical strip.** The citations that were only a private record number go first, and each edit is shown to be a pure removal.
- **Wrong facts corrected.** The rewrite corrects the comments that stated wrong facts. Among them:
  - A placed doodad's material alpha reads file slot 0 on its spawn clock, while the reference reads bone 0's armed sequence, re-rolled every play window. The old text said doodads are armed once at load.
  - The fog end is stored ×36 and scaled once at load (`0x6d6090`). It is not raw.
  - The MCSH bit picks a map doodad's sun scale, 1.0 lit or 0.5 shadowed. 2.5 belongs to an entity's light node.
  - `SpellRec` is the row as stored, column × 4, not a translated copy.
  - A global sequence's clock is anchored at the instance's attach time (`0x714352`).
  - Particle twinkle is a gated size multiplier (`0x7b2adc`).
  - The blob shadow sizes from the Stand box.
  - Data claims are checked against the install: the weapon-trail kits' parameters and alphas, the beam rows' noise, and the maps' `field_16`.
  - Dozens more turned up on the way: renamed or deleted items, docs sitting on the wrong item, stale counts and links.
- **Deviation labels.** "Deviation:" now marks only a choice with a reason. An unbuilt behaviour says so plainly.
- **Verification.** Every file strips to identical code, and `cargo fmt --check` is clean. Four second readers compared every file old against new, restored the facts the rewrite had dropped, and checked each new citation against the reference, the code and the shipped data.

String literals are untouched; they are #92.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-09-24 19:38:53 +07:00

111 lines
4.0 KiB
Rust

//! A band row with no keyframes commits the reference's constant, black or `+0.0`: the colour
//! evaluator `0x6d62e0` stores `0xff000000` (guard `0x6d62ef`, store `0x6d62f6`), the scalar one
//! `+0.0f` (`0x6d6489`, `fld [0x7ffd74]`), and both copy on unconditionally. 973 of 7668
//! `LightIntBand` rows and 132 of 2556 `LightFloatBand` rows are keyless.
use benilla_formats::{Chain, LightCatalog, ZERO_KEY_COLOR, ZERO_KEY_SCALAR};
/// Half-minutes; 1440 = noon.
const NOON: u32 = 1440;
/// Blasted Lands' clear `LightParams`; its cloud gradient base, `LightIntBand` 643, has no keys.
const PARAMS_BLASTED_LANDS: u32 = 36;
/// The Azeroth global's clear `LightParams`; its cloud gradient base is keyed, and black.
const PARAMS_ELWYNN: u32 = 12;
fn params(id: u32) -> Option<benilla_formats::Atmosphere> {
let data = benilla_formats::wow_data_or_skip!(None);
let mut chain = Chain::open(&data).expect("open vanilla patch chain");
let cat = LightCatalog::load(&mut chain).expect("load Light/LightParams/*Band");
Some(
cat.sample_params_id(id, NOON)
.expect("shipped LightParams id"),
)
}
#[test]
fn the_blasted_lands_cloud_base_is_black_not_a_pale_invention() {
let Some(atmo) = params(PARAMS_BLASTED_LANDS) else {
return;
};
assert_eq!(
atmo.cloud_colors[2], ZERO_KEY_COLOR,
"sub-12 is keyless for LightParams 36 — the cloud gradient base must be black"
);
// Its authored neighbours: the row is read, not the palette blanked.
let rgb = |c: [f32; 3]| c.map(|v| (v * 255.0).round() as i32);
assert_eq!(
rgb(atmo.cloud_colors[0]),
[133, 47, 0],
"sub-10 sun glow tint"
);
assert_eq!(
rgb(atmo.cloud_colors[1]),
[0, 34, 88],
"sub-11 gradient slope"
);
assert!(
(atmo.cloud_density - 0.85).abs() < 1e-6,
"Blasted Lands authors C = 0.85 (Elwynn's is 0.50): near-total overcast"
);
}
#[test]
fn an_authored_black_and_a_keyless_row_agree_which_is_why_the_data_reads_as_it_does() {
let Some(elwynn) = params(PARAMS_ELWYNN) else {
return;
};
// 209 of the 308 keyed cloud-base rows are (0,0,0), and 288 have every channel under 64.
assert_eq!(
elwynn.cloud_colors[2], ZERO_KEY_COLOR,
"LightParams 12 authors its cloud base as black"
);
let rgb = |c: [f32; 3]| c.map(|v| (v * 255.0).round() as i32);
assert_eq!(
rgb(elwynn.cloud_colors[1]),
[43, 105, 132],
"sub-11 slope, authored"
);
assert_eq!(rgb(elwynn.sky[0]), [0, 31, 73], "SkyColor0, authored");
assert_eq!(
rgb(elwynn.fog_color),
[77, 120, 143],
"fog row is authored, unchanged"
);
}
#[test]
fn a_keyless_scalar_row_is_zero_not_a_thousand_yards() {
// LightParams 95, a clear-underwater slot on map 269, has keyless fog-end and fog-start rows.
let Some(atmo) = params(95) else { return };
assert_eq!(
atmo.fog_end, ZERO_KEY_SCALAR,
"keyless fog-end commits +0.0"
);
assert_eq!(atmo.fog_start_frac, ZERO_KEY_SCALAR);
assert_eq!(atmo.fog_color, ZERO_KEY_COLOR, "its fog row is keyless too");
}
#[test]
fn a_params_id_above_the_id_gaps_still_reads_its_own_bands() {
// `LightParams` ids run 1..499 over 426 records, and a band-row id derives from the params id,
// `(p-1)*18 + b + 1`, not its row position. 499 is the last id.
let Some(atmo) = params(499) else { return };
let rgb = |c: [f32; 3]| c.map(|v| (v * 255.0).round() as i32);
assert_eq!(rgb(atmo.ambient), [75, 97, 124], "sub-1");
assert_eq!(rgb(atmo.sun_diffuse), [255, 148, 0], "sub-0");
assert_eq!(rgb(atmo.fog_color), [107, 114, 136], "sub-7");
assert_eq!(rgb(atmo.sky[0]), [54, 56, 73], "sub-2");
assert_eq!(rgb(atmo.sky[4]), [117, 124, 149], "sub-6");
assert_eq!(atmo.cloud_colors[2], ZERO_KEY_COLOR, "sub-12 keyless");
assert!(
(atmo.fog_end - 14000.0 / 36.0).abs() < 1e-3,
"fsub-0 authored"
);
assert!(
(atmo.fog_start_frac + 0.2).abs() < 1e-6,
"fsub-1 authored, negative"
);
}