cameraYawSmoothSpeed follows at the stored rate, not the slider's 90-270 (#1712)
`cameraYawSmoothSpeed` was clamped to 90-270 when applied, the Auto-Follow Speed slider's range, so `/console cameraYawSmoothSpeed 360` followed at 270. In 1.12.1 its validator `0x50c000` refuses only outside [0.1, 360] (`0x50b330`, `Value out of range` at `0x50b36c`) and the follow reader takes the stored rate as is (`[0xbe1070]` at `0x512d75`). The camera now uses the stored value; the registry's existing check, which already matched `0x50b330` and also runs on the config load, does the refusing. `FOLLOW_SPEED_RANGE` is gone. Test: 270, 360, 0.2 and 30 are stored and applied as given; 360.5, 400, 9000, 0, 0.05 and -30 are vetoed and keep 30. It fails with the clamp put back. Fixes #323 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 9e1b3e9ae9c7fd488ea0addd3f11460678cd61fc) # Conflicts: # crates/benilla-app/src/cvars/mod.rs # crates/benilla-app/src/cvars/table.rs Absorbed into the octo fork. Ported by hand: our cvars registry is one file, not upstream's cvars/ split, and it has no .checked() validators or SetOutcome::Vetoed, so the clamp cannot simply be removed — without a veto channel that would turn a clamp into an unvalidated accept. FOLLOW_SPEED_RANGE is widened from the slider's 90..=270 to the reference validator's 0.1..=360 instead, so /console cameraYawSmoothSpeed 360 now follows at 360; refusing (rather than clamping) outside that window is recorded as a deviation on the constant. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
This commit is contained in:
co-authored by
Claude Opus 5
parent
694ef5832d
commit
132776c197
@@ -436,7 +436,9 @@ pub(crate) const REGISTERED: &[Registered] = &[
|
||||
same("cameraSmoothTrackingStyle", "1"),
|
||||
// AUTO_FOLLOW_SPEED (`UIOptionsFrame.lua:88`), deg/s, registered "180.0" (`[0xbe1070]`): it
|
||||
// sets the transition's duration (`|dyaw| / rate * factor`), an average rate, not a slew. The
|
||||
// knob clamps it to `FOLLOW_SPEED_RANGE`. The stock Save also writes `cameraPitchSmoothSpeed`
|
||||
// validator `0x50c000` refuses outside [0.1, 360] and the follow reader (`0x512d75`) uses the
|
||||
// stored value as is; 90 to 270 is only the stock slider's range, and clamping to it made
|
||||
// `/console cameraYawSmoothSpeed 360` follow at 270. The stock Save also writes `cameraPitchSmoothSpeed`
|
||||
// at a quarter (`:353`), unregistered here: `FollowRig` has one rate.
|
||||
same("cameraYawSmoothSpeed", "180"),
|
||||
// `cameraPivot` `[0xbe10a4]` "1" (`0x50bda3`), smart pivot: gate `0x510690`, routing
|
||||
@@ -4171,8 +4173,13 @@ mod tests {
|
||||
FollowStyle::Smart,
|
||||
"and only that one"
|
||||
);
|
||||
apply(&mut app, "cameraYawSmoothSpeed", "270");
|
||||
assert_eq!(res::<FollowConfig>(&app).yaw_speed, 270.0);
|
||||
// The validator's [0.1, 360] (`0x50c000`) is the range, not the stock slider's 90 to 270:
|
||||
// a value inside it is stored and used as is (`0x512d75`). 360 is the case that was wrong.
|
||||
for (text, want) in [("270", 270.0), ("360", 360.0), ("0.2", 0.2), ("30", 30.0)] {
|
||||
apply(&mut app, "cameraYawSmoothSpeed", text);
|
||||
assert_eq!(res::<FollowConfig>(&app).yaw_speed, want, "{text}");
|
||||
}
|
||||
// Outside it the reference refuses the set; we clamp to the edge (see FOLLOW_SPEED_RANGE).
|
||||
apply(&mut app, "cameraYawSmoothSpeed", "9000");
|
||||
assert_eq!(
|
||||
res::<FollowConfig>(&app).yaw_speed,
|
||||
|
||||
@@ -142,6 +142,8 @@ pub(crate) fn on_cvar(
|
||||
// The stock dropdown writes 1 Smart, 2 Always, 0 Never (`UIOptionsFrame.lua:518`).
|
||||
"camerasmoothstyle" => follow.style = FollowStyle::from_cvar(v),
|
||||
"camerasmoothtrackingstyle" => follow.tracking_style = FollowStyle::from_cvar(v),
|
||||
// The follow reader takes the stored rate as is (`0x512d75`); 90 to 270 is only the stock
|
||||
// slider's range, so a `/console` value inside the validator's own stands.
|
||||
"camerayawsmoothspeed" => {
|
||||
follow.yaw_speed = v.clamp(*FOLLOW_SPEED_RANGE.start(), *FOLLOW_SPEED_RANGE.end());
|
||||
}
|
||||
@@ -202,8 +204,17 @@ impl LookConfig {
|
||||
/// `cameraYawSmoothSpeed`, default 180°/s (`[0xbe1070]`, read at `0x512d75`): a duration divisor,
|
||||
/// as a return lasts `|Δyaw| / rate × factor`. The AUTO_FOLLOW_SPEED slider, greyed under Never.
|
||||
pub(crate) const FOLLOW_SPEED_DEFAULT: f32 = 180.0;
|
||||
/// The 1.12 slider's own range for [`FollowConfig::yaw_speed`].
|
||||
pub(crate) const FOLLOW_SPEED_RANGE: std::ops::RangeInclusive<f32> = 90.0..=270.0;
|
||||
/// What the reference's validator `0x50c000` accepts for [`FollowConfig::yaw_speed`]: outside
|
||||
/// [0.1, 360] it refuses the set outright (`0x50b330`, `Value out of range` at `0x50b36c`), and
|
||||
/// the follow reader then uses the stored rate as is (`0x512d75`). 90 to 270 is the AUTO_FOLLOW_
|
||||
/// SPEED slider's range alone, and clamping to it made `/console cameraYawSmoothSpeed 360` follow
|
||||
/// at 270.
|
||||
///
|
||||
/// Deviation: the reference *refuses* an out-of-range set and keeps the old rate; we clamp to the
|
||||
/// edge, because this registry has no veto channel — upstream's `Registered::checked` validators
|
||||
/// and `SetOutcome::Vetoed` are not in this fork, so there is nowhere to report the refusal. The
|
||||
/// accepted window is now the reference's; only what happens outside it still differs.
|
||||
pub(crate) const FOLLOW_SPEED_RANGE: std::ops::RangeInclusive<f32> = 0.1..=360.0;
|
||||
/// `cameraSmoothTimeMin`/`Max`: 0.1 s and 2.0 s (`[0xbe105c]`/`[0xbe1038]`, clamped at `0x510f4d`).
|
||||
const FOLLOW_TIME_MIN: f32 = 0.1;
|
||||
const FOLLOW_TIME_MAX: f32 = 2.0;
|
||||
|
||||
Reference in New Issue
Block a user