2019-11-24 20:12:03 +00:00
|
|
|
use crate::sync::Uid;
|
2019-07-29 19:54:48 +00:00
|
|
|
use specs::{Component, FlaggedStorage};
|
|
|
|
use specs_idvs::IDVStorage;
|
2019-11-29 15:20:35 +00:00
|
|
|
use std::time::Duration;
|
2019-07-29 19:54:58 +00:00
|
|
|
use vek::*;
|
2019-06-09 14:20:20 +00:00
|
|
|
|
2019-12-03 06:30:08 +00:00
|
|
|
/// Default duration before an input is considered 'held'.
|
|
|
|
pub const DEFAULT_HOLD_DURATION: Duration = Duration::from_millis(200);
|
2019-11-29 15:20:35 +00:00
|
|
|
|
2019-09-09 19:11:40 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub enum ControlEvent {
|
|
|
|
Mount(Uid),
|
|
|
|
Unmount,
|
2019-10-15 04:06:14 +00:00
|
|
|
InventoryManip(InventoryManip),
|
|
|
|
//Respawn,
|
2019-09-09 19:11:40 +00:00
|
|
|
}
|
|
|
|
|
2019-11-29 15:20:35 +00:00
|
|
|
/// Whether a key is pressed or unpressed
|
|
|
|
/// and how long it has been in that state
|
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub struct Input {
|
2019-12-03 06:30:08 +00:00
|
|
|
/// Should not be pub because duration should
|
|
|
|
/// always be reset when state is updated
|
2020-03-23 17:13:44 +00:00
|
|
|
state: bool,
|
2019-12-03 06:30:08 +00:00
|
|
|
/// Should only be updated by npc agents
|
|
|
|
/// through appropriate fn
|
2019-11-29 15:20:35 +00:00
|
|
|
duration: Duration,
|
2020-03-23 17:13:44 +00:00
|
|
|
/// How many update ticks the button has been in its current state for
|
|
|
|
ticks_held: u32,
|
2019-11-29 15:20:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Input {
|
2020-03-23 17:13:44 +00:00
|
|
|
fn tick(&mut self, old: Input, dt: Duration) {
|
2019-12-03 06:30:08 +00:00
|
|
|
// Increase how long input has been in current state
|
|
|
|
self.duration = self.duration.checked_add(dt).unwrap_or_default();
|
2020-03-23 17:13:44 +00:00
|
|
|
|
|
|
|
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!("____");
|
|
|
|
},
|
|
|
|
};
|
2019-12-03 06:30:08 +00:00
|
|
|
}
|
|
|
|
|
2020-03-23 17:13:44 +00:00
|
|
|
/// Whether input is being pressed down
|
|
|
|
pub fn is_pressed(&self) -> bool { self.state == true }
|
2019-12-03 06:30:08 +00:00
|
|
|
|
2020-03-23 17:13:44 +00:00
|
|
|
/// 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 }
|
2019-12-03 06:30:08 +00:00
|
|
|
|
2020-03-23 17:13:44 +00:00
|
|
|
/// 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 }
|
|
|
|
|
|
|
|
/// Whether input has been pressed longer than
|
2019-11-29 15:20:35 +00:00
|
|
|
/// `DEFAULT_HOLD_DURATION`
|
|
|
|
pub fn is_held_down(&self) -> bool {
|
2020-02-09 21:15:10 +00:00
|
|
|
self.is_pressed() && self.duration >= DEFAULT_HOLD_DURATION
|
2019-11-29 15:20:35 +00:00
|
|
|
}
|
|
|
|
|
2020-03-23 17:13:44 +00:00
|
|
|
/// Whether input has been unpressed longer than
|
|
|
|
/// `DEFAULT_HOLD_DURATION`
|
|
|
|
pub fn is_held_up(&self) -> bool {
|
|
|
|
!self.is_pressed() && self.duration >= DEFAULT_HOLD_DURATION
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Whether input has been pressed for longer than `threshold` duration
|
|
|
|
pub fn held_for_dur(&self, threshold: Duration) -> bool {
|
2020-03-07 21:03:10 +00:00
|
|
|
self.is_pressed() && self.duration >= threshold
|
2020-01-08 13:17:36 +00:00
|
|
|
}
|
|
|
|
|
2020-03-23 17:13:44 +00:00
|
|
|
/// 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
|
2019-11-29 15:20:35 +00:00
|
|
|
}
|
|
|
|
|
2020-03-23 17:13:44 +00:00
|
|
|
/// Handles logic of updating state of Input
|
|
|
|
pub fn set_state(&mut self, new_state: bool) { self.state = new_state; }
|
|
|
|
|
2019-12-03 06:30:08 +00:00
|
|
|
/// Increases `input::duration` by `dur`
|
2019-11-29 15:20:35 +00:00
|
|
|
pub fn inc_dur(&mut self, dur: Duration) {
|
2019-12-03 06:30:08 +00:00
|
|
|
self.duration = self.duration.checked_add(dur).unwrap_or_default();
|
2019-11-29 15:20:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Returns `input::duration`
|
2020-02-01 20:39:39 +00:00
|
|
|
pub fn get_dur(&self) -> Duration { self.duration }
|
2019-11-29 15:20:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for Input {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self {
|
2020-03-23 17:13:44 +00:00
|
|
|
state: false,
|
2019-11-29 15:20:35 +00:00
|
|
|
duration: Duration::default(),
|
2020-03-23 17:13:44 +00:00
|
|
|
ticks_held: 0,
|
2019-11-29 15:20:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-09 14:20:20 +00:00
|
|
|
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
2019-10-15 04:06:14 +00:00
|
|
|
pub struct ControllerInputs {
|
2019-11-29 15:20:35 +00:00
|
|
|
pub primary: Input,
|
|
|
|
pub secondary: Input,
|
2020-03-24 12:59:53 +00:00
|
|
|
pub ability3: Input,
|
2019-11-29 15:20:35 +00:00
|
|
|
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,
|
2020-03-21 17:26:38 +00:00
|
|
|
pub swap_loadout: Input,
|
2019-12-03 06:30:08 +00:00
|
|
|
pub charge: Input,
|
2019-10-15 04:06:14 +00:00
|
|
|
pub move_dir: Vec2<f32>,
|
|
|
|
pub look_dir: Vec3<f32>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub struct Controller {
|
|
|
|
pub inputs: ControllerInputs,
|
2019-10-21 00:59:53 +00:00
|
|
|
// TODO: consider SmallVec
|
2019-09-09 19:11:40 +00:00
|
|
|
pub events: Vec<ControlEvent>,
|
|
|
|
}
|
|
|
|
|
2019-11-29 15:20:35 +00:00
|
|
|
impl ControllerInputs {
|
|
|
|
/// Updates all inputs, accounting for delta time
|
2020-03-23 17:13:44 +00:00
|
|
|
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);
|
2019-12-03 06:30:08 +00:00
|
|
|
}
|
2020-03-24 12:59:53 +00:00
|
|
|
|
|
|
|
pub fn holding_ability_key(&self) -> bool {
|
|
|
|
self.primary.is_pressed() || self.secondary.is_pressed() || self.ability3.is_pressed()
|
|
|
|
}
|
2019-11-29 15:20:35 +00:00
|
|
|
}
|
|
|
|
|
2019-09-09 19:11:40 +00:00
|
|
|
impl Controller {
|
2019-11-29 15:20:35 +00:00
|
|
|
/// Sets all inputs to default
|
2020-02-01 20:39:39 +00:00
|
|
|
pub fn reset(&mut self) { *self = Self::default(); }
|
2019-09-09 19:11:40 +00:00
|
|
|
|
2020-02-01 20:39:39 +00:00
|
|
|
pub fn clear_events(&mut self) { self.events.clear(); }
|
2019-09-09 19:11:40 +00:00
|
|
|
|
2020-02-01 20:39:39 +00:00
|
|
|
pub fn push_event(&mut self, event: ControlEvent) { self.events.push(event); }
|
2019-06-09 14:20:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Component for Controller {
|
2019-07-29 19:54:48 +00:00
|
|
|
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
|
2019-06-09 14:20:20 +00:00
|
|
|
}
|
2019-09-09 19:11:40 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub enum MountState {
|
|
|
|
Unmounted,
|
|
|
|
MountedBy(Uid),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Component for MountState {
|
|
|
|
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub struct Mounting(pub Uid);
|
|
|
|
|
|
|
|
impl Component for Mounting {
|
|
|
|
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
|
|
|
|
}
|
2019-10-15 04:06:14 +00:00
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub enum InventoryManip {
|
|
|
|
Pickup(Uid),
|
|
|
|
Collect(Vec3<i32>),
|
|
|
|
Use(usize),
|
|
|
|
Swap(usize, usize),
|
|
|
|
Drop(usize),
|
|
|
|
}
|