Input: one device letting go of sneak or sprint leaves the other's hold

Releasing Shift while R3 held sneak in hold mode dropped it for both, and so did
the other way round.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
martipopsandClaude Opus 5.5 committed 2026-11-06 06:59:30 -05:00
1 parent a4ffae3402
commit 84efc873cf
2 files changed
+36

No files matched your search

+19
View File
@@ -8248,6 +8248,21 @@ impl Game<'_> {
}
}
}
/// Whether the other device still holds the sneak or sprint mapping `source` released.
fn toggle_held_elsewhere(&self, slot: usize, key: KeyCode, source: Source) -> bool {
match source {
Source::Keyboard => self
.pad
.holds_action(&self.settings.controller, ["key.sneak", "key.sprint"][slot]),
Source::Pad => self.physical_keys.iter().any(|physical| {
self.settings
.keys
.translate_all(*physical)
.contains(&Ok(key))
}),
Source::Agent => false,
}
}
/// Apply a physical key to every mapping bound to it.
fn mapped_key_event(&mut self, key: KeyCode, pressed: bool, repeat: bool) -> Result<()> {
for mapped in self.settings.keys.translate_all(key) {
@@ -8310,6 +8325,10 @@ impl Game<'_> {
(_, false) => KeyAction::Press,
(_, true) => KeyAction::Repeat,
};
// One device letting go doesn't let go for the other still holding it.
if !pressed && self.toggle_held_elsewhere(slot, key, source) {
return Ok(());
}
let screen_open =
!gameplay_has_keyboard(self.screen, self.title.is_some(), self.dialog_open());
self.toggles.key(slot, action, screen_open, option);
@@ -58,6 +58,23 @@ fn pad_press(game: &mut Game, button: Button, action: &str) {
game.pad_action(action, true).unwrap();
}
#[test]
#[ignore = "needs prepared resources in HORIZON_TEST_RESOURCES"]
fn a_keyboard_release_keeps_the_sneak_the_pad_holds() {
playing(|game| {
// Hold mode: toggling, Shift's press would flip it anyway.
game.settings.controller.toggle_sneak = false;
pad_press(game, Button::RightStick, "key.sneak");
assert!(game.keys.held(Action::Sneak));
let shift = KeyCode::ShiftLeft;
game.mapped_key(shift, true, false, shift, Source::Keyboard)
.unwrap();
game.mapped_key(shift, false, false, shift, Source::Keyboard)
.unwrap();
assert!(game.keys.held(Action::Sneak), "R3 is still down");
});
}
#[test]
#[ignore = "needs prepared resources in HORIZON_TEST_RESOURCES"]
fn keyboard_handoff_keeps_what_the_pad_holds() {