From d0a46ed82b665c4fb8b63426525ec83388644229 Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 29 Oct 2022 23:32:52 -0400 Subject: [PATCH] Inputs now remain queued even when the input is released, until the input is used. --- client/src/lib.rs | 1 + common/src/comp/character_state.rs | 2 ++ common/src/comp/controller.rs | 2 ++ common/src/states/utils.rs | 13 ++++++------- common/systems/src/character_behavior.rs | 14 +++++++++----- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index b92f7036dd..9988a6f717 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -1723,6 +1723,7 @@ impl Client { entry .or_insert_with(|| Controller { inputs: inputs.clone(), + held_inputs: BTreeMap::new(), queued_inputs: BTreeMap::new(), events: Vec::new(), actions: Vec::new(), diff --git a/common/src/comp/character_state.rs b/common/src/comp/character_state.rs index 16a9c4735e..6928570902 100644 --- a/common/src/comp/character_state.rs +++ b/common/src/comp/character_state.rs @@ -27,6 +27,7 @@ pub struct StateUpdate { pub swap_equipped_weapons: bool, pub should_strafe: bool, pub queued_inputs: BTreeMap, + pub used_inputs: Vec, pub removed_inputs: Vec, } @@ -57,6 +58,7 @@ impl From<&JoinData<'_>> for StateUpdate { should_strafe: data.inputs.strafing, character: data.character.clone(), queued_inputs: BTreeMap::new(), + used_inputs: Vec::new(), removed_inputs: Vec::new(), } } diff --git a/common/src/comp/controller.rs b/common/src/comp/controller.rs index 9c049ac97f..8c85138312 100644 --- a/common/src/comp/controller.rs +++ b/common/src/comp/controller.rs @@ -246,6 +246,7 @@ pub struct ControllerInputs { #[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] pub struct Controller { pub inputs: ControllerInputs, + pub held_inputs: BTreeMap, pub queued_inputs: BTreeMap, // TODO: consider SmallVec pub events: Vec, @@ -282,6 +283,7 @@ impl Controller { pub fn reset(&mut self) { self.inputs = Default::default(); self.queued_inputs = Default::default(); + self.held_inputs = Default::default(); } pub fn clear_events(&mut self) { self.events.clear(); } diff --git a/common/src/states/utils.rs b/common/src/states/utils.rs index 4df839538b..6936557361 100644 --- a/common/src/states/utils.rs +++ b/common/src/states/utils.rs @@ -1017,8 +1017,7 @@ pub fn attempt_glide_wield( pub fn handle_jump( data: &JoinData<'_>, output_events: &mut OutputEvents, - // TODO: remove? - _update: &mut StateUpdate, + update: &mut StateUpdate, strength: f32, ) -> bool { (input_is_pressed(data, InputKind::Jump) && data.physics.on_ground.is_some()) @@ -1029,6 +1028,7 @@ pub fn handle_jump( data.entity, strength * impulse / data.mass.0 * data.stats.move_speed_modifier, )); + update.used_inputs.push(InputKind::Jump); }) .is_some() } @@ -1054,6 +1054,7 @@ fn handle_ability(data: &JoinData<'_>, update: &mut StateUpdate, input: InputKin AbilityInfo::from_input(data, from_offhand, input, ability.ability_meta()), data, )); + update.used_inputs.push(input); return true; } } @@ -1109,6 +1110,7 @@ pub fn handle_block_input(data: &JoinData<'_>, update: &mut StateUpdate) -> bool AbilityInfo::from_input(data, false, InputKind::Block, Default::default()), data, )); + update.used_inputs.push(InputKind::Block); true } else { false @@ -1129,6 +1131,7 @@ pub fn handle_dodge_input(data: &JoinData<'_>, update: &mut StateUpdate) -> bool AbilityInfo::from_input(data, false, InputKind::Roll, Default::default()), data, )); + update.used_inputs.push(InputKind::Roll); if let CharacterState::Roll(roll) = &mut update.character { if let CharacterState::ComboMelee(c) = data.character { roll.was_combo = c @@ -1276,11 +1279,7 @@ pub fn get_buff_strength(data: &JoinData<'_>, ai: AbilityInfo) -> f32 { } pub fn input_is_pressed(data: &JoinData<'_>, input: InputKind) -> bool { - data.controller.queued_inputs.contains_key(&input) -} - -pub fn input_just_pressed(update: &StateUpdate, input: InputKind) -> bool { - update.queued_inputs.contains_key(&input) + data.controller.queued_inputs.contains_key(&input) || data.controller.held_inputs.contains_key(&input) } /// Checked `Duration` addition. Computes `timer` + `dt`, applying relevant stat diff --git a/common/systems/src/character_behavior.rs b/common/systems/src/character_behavior.rs index 0b0bd3e4fc..71dd8afff8 100644 --- a/common/systems/src/character_behavior.rs +++ b/common/systems/src/character_behavior.rs @@ -244,7 +244,7 @@ impl<'a> System<'a> for Sys { impl Sys { fn publish_state_update( join: &mut JoinStruct, - mut state_update: StateUpdate, + state_update: StateUpdate, output_events: &mut OutputEvents, ) { // Here we check for equality with the previous value of these components before @@ -269,12 +269,16 @@ impl Sys { *join.vel = state_update.vel; *join.ori = state_update.ori; - join.controller - .queued_inputs - .append(&mut state_update.queued_inputs); - for input in state_update.removed_inputs { + for (input, attr) in state_update.queued_inputs { + join.controller.queued_inputs.insert(input, attr); + join.controller.held_inputs.insert(input, attr); + } + for input in state_update.used_inputs { join.controller.queued_inputs.remove(&input); } + for input in state_update.removed_inputs { + join.controller.held_inputs.remove(&input); + } if state_update.swap_equipped_weapons { output_events.emit_server(ServerEvent::InventoryManip( join.entity,