mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Input handling changes
This commit is contained in:
@ -12,7 +12,21 @@ pub enum ControlEvent {
|
||||
Mount(Uid),
|
||||
Unmount,
|
||||
InventoryManip(InventoryManip),
|
||||
//Respawn,
|
||||
Respawn,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum ControlAction {
|
||||
SwapLoadout,
|
||||
ToggleWield,
|
||||
ToggleSit,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||
enum Freshness {
|
||||
New,
|
||||
TickedOnce,
|
||||
Old,
|
||||
}
|
||||
|
||||
/// Whether a key is pressed or unpressed
|
||||
@ -21,41 +35,50 @@ pub enum ControlEvent {
|
||||
pub struct Input {
|
||||
/// Should not be pub because duration should
|
||||
/// always be reset when state is updated
|
||||
state: bool,
|
||||
pressed: bool,
|
||||
/// Should only be updated by npc agents
|
||||
/// through appropriate fn
|
||||
duration: Duration,
|
||||
/// How many update ticks the button has been in its current state for
|
||||
ticks_held: u32,
|
||||
/// How fresh is the last change to the input state
|
||||
freshness: Freshness,
|
||||
}
|
||||
|
||||
impl Input {
|
||||
fn tick(&mut self, old: Input, dt: Duration) {
|
||||
fn tick(&mut self, dt: Duration) {
|
||||
// Increase how long input has been in current state
|
||||
self.duration = self.duration.checked_add(dt).unwrap_or_default();
|
||||
self.tick_freshness();
|
||||
}
|
||||
|
||||
match (self.is_pressed(), old.is_pressed()) {
|
||||
(false, true) | (true, false) => {
|
||||
println!("{:?}", self);
|
||||
self.duration = Duration::default();
|
||||
self.ticks_held = 1;
|
||||
println!("{:?}", self);
|
||||
},
|
||||
(_, _) => {
|
||||
self.ticks_held += 1;
|
||||
println!("____");
|
||||
},
|
||||
fn tick_freshness(&mut self) {
|
||||
self.freshness = match self.freshness {
|
||||
Freshness::New => Freshness::TickedOnce,
|
||||
Freshness::TickedOnce => Freshness::Old,
|
||||
Freshness::Old => Freshness::Old,
|
||||
};
|
||||
}
|
||||
|
||||
/// Update input with newer version
|
||||
/// Used to update inputs with input recieved from clients
|
||||
pub fn update_with_new(&mut self, new: Self) {
|
||||
if self.pressed != new.pressed {
|
||||
self.freshness = Freshness::New;
|
||||
}
|
||||
|
||||
self.pressed = new.pressed;
|
||||
self.duration = new.duration;
|
||||
}
|
||||
|
||||
/// Whether input is being pressed down
|
||||
pub fn is_pressed(&self) -> bool { self.state == true }
|
||||
pub fn is_pressed(&self) -> bool { self.pressed }
|
||||
|
||||
/// Whether it's the first frame this input has been pressed
|
||||
pub fn is_just_pressed(&self) -> bool { self.is_pressed() && self.ticks_held == 1 }
|
||||
pub fn is_just_pressed(&self) -> bool { self.is_pressed() && self.freshness != Freshness::Old }
|
||||
|
||||
/// Whether it's the first frame this input has been unpressed
|
||||
pub fn is_just_unpressed(&self) -> bool { !self.is_pressed() && self.ticks_held == 1 }
|
||||
pub fn is_just_unpressed(&self) -> bool {
|
||||
!self.is_pressed() && self.freshness != Freshness::Old
|
||||
}
|
||||
|
||||
/// Whether input has been pressed longer than
|
||||
/// `DEFAULT_HOLD_DURATION`
|
||||
@ -74,49 +97,52 @@ impl Input {
|
||||
self.is_pressed() && self.duration >= threshold
|
||||
}
|
||||
|
||||
/// Whether input has been pressed for longer than `count` number of ticks
|
||||
pub fn held_for_ticks(&self, count: u32) -> bool {
|
||||
self.is_pressed() && self.ticks_held >= count
|
||||
/// Handles logic of updating state of Input
|
||||
pub fn set_state(&mut self, pressed: bool) {
|
||||
if self.pressed != pressed {
|
||||
self.pressed = pressed;
|
||||
self.duration = Duration::default();
|
||||
self.freshness = Freshness::New;
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles logic of updating state of Input
|
||||
pub fn set_state(&mut self, new_state: bool) { self.state = new_state; }
|
||||
|
||||
/// Increases `input::duration` by `dur`
|
||||
/// Increases `input.duration` by `dur`
|
||||
pub fn inc_dur(&mut self, dur: Duration) {
|
||||
self.duration = self.duration.checked_add(dur).unwrap_or_default();
|
||||
}
|
||||
|
||||
/// Returns `input::duration`
|
||||
/// Returns `input.duration`
|
||||
pub fn get_dur(&self) -> Duration { self.duration }
|
||||
}
|
||||
|
||||
impl Default for Input {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
state: false,
|
||||
pressed: false,
|
||||
duration: Duration::default(),
|
||||
ticks_held: 0,
|
||||
freshness: Freshness::New,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||
pub enum Climb {
|
||||
Up,
|
||||
Down,
|
||||
Hold,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
||||
pub struct ControllerInputs {
|
||||
pub primary: Input,
|
||||
pub secondary: Input,
|
||||
pub ability3: Input,
|
||||
pub sit: Input,
|
||||
pub jump: Input,
|
||||
pub roll: Input,
|
||||
pub glide: Input,
|
||||
pub climb: Input,
|
||||
pub climb_down: Input,
|
||||
pub wall_leap: Input,
|
||||
pub respawn: Input,
|
||||
pub toggle_wield: Input,
|
||||
pub swap_loadout: Input,
|
||||
pub charge: Input,
|
||||
pub climb: Option<Climb>,
|
||||
pub move_dir: Vec2<f32>,
|
||||
pub look_dir: Vec3<f32>,
|
||||
}
|
||||
@ -126,25 +152,46 @@ pub struct Controller {
|
||||
pub inputs: ControllerInputs,
|
||||
// TODO: consider SmallVec
|
||||
pub events: Vec<ControlEvent>,
|
||||
pub actions: Vec<ControlAction>,
|
||||
}
|
||||
|
||||
impl ControllerInputs {
|
||||
/// Updates all inputs, accounting for delta time
|
||||
pub fn calculate_change(&mut self, old: ControllerInputs, dt: Duration) {
|
||||
self.primary.tick(old.primary, dt);
|
||||
self.secondary.tick(old.secondary, dt);
|
||||
self.ability3.tick(old.ability3, dt);
|
||||
self.sit.tick(old.sit, dt);
|
||||
self.jump.tick(old.jump, dt);
|
||||
self.roll.tick(old.roll, dt);
|
||||
self.glide.tick(old.glide, dt);
|
||||
self.climb.tick(old.climb, dt);
|
||||
self.climb_down.tick(old.climb_down, dt);
|
||||
self.wall_leap.tick(old.wall_leap, dt);
|
||||
self.respawn.tick(old.respawn, dt);
|
||||
self.toggle_wield.tick(old.toggle_wield, dt);
|
||||
self.swap_loadout.tick(old.swap_loadout, dt);
|
||||
self.charge.tick(old.charge, dt);
|
||||
pub fn tick(&mut self, dt: Duration) {
|
||||
self.primary.tick(dt);
|
||||
self.secondary.tick(dt);
|
||||
self.ability3.tick(dt);
|
||||
self.jump.tick(dt);
|
||||
self.roll.tick(dt);
|
||||
self.glide.tick(dt);
|
||||
self.wall_leap.tick(dt);
|
||||
self.charge.tick(dt);
|
||||
}
|
||||
|
||||
pub fn tick_freshness(&mut self) {
|
||||
self.primary.tick_freshness();
|
||||
self.secondary.tick_freshness();
|
||||
self.ability3.tick_freshness();
|
||||
self.jump.tick_freshness();
|
||||
self.roll.tick_freshness();
|
||||
self.glide.tick_freshness();
|
||||
self.wall_leap.tick_freshness();
|
||||
self.charge.tick_freshness();
|
||||
}
|
||||
|
||||
/// Updates Controller inputs with new version received from the client
|
||||
pub fn update_with_new(&mut self, new: Self) {
|
||||
self.primary.update_with_new(new.primary);
|
||||
self.secondary.update_with_new(new.secondary);
|
||||
self.ability3.update_with_new(new.ability3);
|
||||
self.jump.update_with_new(new.jump);
|
||||
self.roll.update_with_new(new.roll);
|
||||
self.glide.update_with_new(new.glide);
|
||||
self.wall_leap.update_with_new(new.wall_leap);
|
||||
self.charge.update_with_new(new.charge);
|
||||
self.climb = new.climb;
|
||||
self.move_dir = new.move_dir;
|
||||
self.look_dir = new.look_dir;
|
||||
}
|
||||
|
||||
pub fn holding_ability_key(&self) -> bool {
|
||||
|
Reference in New Issue
Block a user