2020-10-16 06:08:45 +00:00
|
|
|
use crate::{
|
2021-02-08 17:31:17 +00:00
|
|
|
comp::{
|
2021-02-08 18:55:50 +00:00
|
|
|
inventory::slot::{EquipSlot, InvSlotId, Slot},
|
2021-02-13 23:32:55 +00:00
|
|
|
invite::{InviteKind, InviteResponse},
|
2021-03-21 17:45:01 +00:00
|
|
|
BuffKind,
|
2021-02-08 17:31:17 +00:00
|
|
|
},
|
2021-02-13 23:32:55 +00:00
|
|
|
trade::{TradeAction, TradeId},
|
2020-12-13 17:11:55 +00:00
|
|
|
uid::Uid,
|
2020-10-16 06:08:45 +00:00
|
|
|
util::Dir,
|
|
|
|
};
|
2020-07-06 14:23:08 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
2021-01-07 20:25:12 +00:00
|
|
|
use specs::{Component, DerefFlaggedStorage};
|
2020-07-06 05:56:02 +00:00
|
|
|
use specs_idvs::IdvStorage;
|
2021-03-21 16:09:16 +00:00
|
|
|
use std::collections::BTreeMap;
|
2019-07-29 19:54:58 +00:00
|
|
|
use vek::*;
|
2019-06-09 14:20:20 +00:00
|
|
|
|
2020-04-04 17:51:41 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
2021-03-01 22:40:42 +00:00
|
|
|
pub enum InventoryEvent {
|
2020-04-04 17:51:41 +00:00
|
|
|
Pickup(Uid),
|
|
|
|
Collect(Vec3<i32>),
|
2021-02-08 18:55:50 +00:00
|
|
|
Swap(InvSlotId, InvSlotId),
|
2021-03-02 00:08:46 +00:00
|
|
|
SplitSwap(InvSlotId, InvSlotId),
|
2021-02-08 18:55:50 +00:00
|
|
|
Drop(InvSlotId),
|
2021-04-19 15:56:16 +00:00
|
|
|
SplitDrop(InvSlotId),
|
2021-04-17 16:24:33 +00:00
|
|
|
Sort,
|
2021-04-17 14:58:43 +00:00
|
|
|
CraftRecipe {
|
|
|
|
recipe: String,
|
|
|
|
craft_sprite: Option<Vec3<i32>>,
|
|
|
|
},
|
2020-04-04 17:51:41 +00:00
|
|
|
}
|
|
|
|
|
2021-02-07 16:57:41 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
2021-03-01 22:40:42 +00:00
|
|
|
pub enum InventoryAction {
|
2021-02-08 17:31:17 +00:00
|
|
|
Swap(EquipSlot, Slot),
|
|
|
|
Drop(EquipSlot),
|
2021-03-01 22:40:42 +00:00
|
|
|
Use(Slot),
|
2021-04-17 16:24:33 +00:00
|
|
|
Sort,
|
2021-02-07 16:57:41 +00:00
|
|
|
}
|
|
|
|
|
2021-02-08 18:55:50 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
2021-03-01 22:40:42 +00:00
|
|
|
pub enum InventoryManip {
|
2021-02-08 18:55:50 +00:00
|
|
|
Pickup(Uid),
|
|
|
|
Collect(Vec3<i32>),
|
|
|
|
Use(Slot),
|
|
|
|
Swap(Slot, Slot),
|
2021-03-02 00:08:46 +00:00
|
|
|
SplitSwap(Slot, Slot),
|
2021-02-08 18:55:50 +00:00
|
|
|
Drop(Slot),
|
2021-04-19 15:56:16 +00:00
|
|
|
SplitDrop(Slot),
|
2021-04-17 16:24:33 +00:00
|
|
|
Sort,
|
2021-04-17 14:58:43 +00:00
|
|
|
CraftRecipe {
|
|
|
|
recipe: String,
|
|
|
|
craft_sprite: Option<Vec3<i32>>,
|
|
|
|
},
|
2021-02-08 18:55:50 +00:00
|
|
|
}
|
|
|
|
|
2021-03-01 22:40:42 +00:00
|
|
|
impl From<InventoryAction> for InventoryManip {
|
|
|
|
fn from(inv_action: InventoryAction) -> Self {
|
|
|
|
match inv_action {
|
|
|
|
InventoryAction::Use(slot) => Self::Use(slot),
|
|
|
|
InventoryAction::Swap(equip, slot) => Self::Swap(Slot::Equip(equip), slot),
|
|
|
|
InventoryAction::Drop(equip) => Self::Drop(Slot::Equip(equip)),
|
2021-04-17 16:24:33 +00:00
|
|
|
InventoryAction::Sort => Self::Sort,
|
2021-02-07 16:57:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-01 22:40:42 +00:00
|
|
|
impl From<InventoryEvent> for InventoryManip {
|
|
|
|
fn from(inv_event: InventoryEvent) -> Self {
|
|
|
|
match inv_event {
|
|
|
|
InventoryEvent::Pickup(pickup) => Self::Pickup(pickup),
|
|
|
|
InventoryEvent::Collect(collect) => Self::Collect(collect),
|
|
|
|
InventoryEvent::Swap(inv1, inv2) => {
|
2021-02-08 18:55:50 +00:00
|
|
|
Self::Swap(Slot::Inventory(inv1), Slot::Inventory(inv2))
|
|
|
|
},
|
2021-03-01 22:40:42 +00:00
|
|
|
InventoryEvent::SplitSwap(inv1, inv2) => {
|
2021-03-02 00:08:46 +00:00
|
|
|
Self::SplitSwap(Slot::Inventory(inv1), Slot::Inventory(inv2))
|
|
|
|
},
|
2021-03-01 22:40:42 +00:00
|
|
|
InventoryEvent::Drop(inv) => Self::Drop(Slot::Inventory(inv)),
|
2021-04-17 18:35:48 +00:00
|
|
|
InventoryEvent::SplitDrop(inv) => Self::SplitDrop(Slot::Inventory(inv)),
|
2021-04-17 16:24:33 +00:00
|
|
|
InventoryEvent::Sort => Self::Sort,
|
2021-04-17 18:35:48 +00:00
|
|
|
InventoryEvent::CraftRecipe {
|
|
|
|
recipe,
|
|
|
|
craft_sprite,
|
|
|
|
} => Self::CraftRecipe {
|
|
|
|
recipe,
|
|
|
|
craft_sprite,
|
|
|
|
},
|
2021-02-08 18:55:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-26 17:03:19 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub enum GroupManip {
|
|
|
|
Leave,
|
|
|
|
Kick(Uid),
|
|
|
|
AssignLeader(Uid),
|
|
|
|
}
|
|
|
|
|
2021-06-15 16:15:58 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
|
|
pub enum UtteranceKind {
|
|
|
|
Calm,
|
|
|
|
Angry,
|
|
|
|
Surprised,
|
2021-06-15 22:01:16 +00:00
|
|
|
Hurt,
|
2021-06-16 12:49:43 +00:00
|
|
|
Greeting,
|
2021-06-18 06:24:57 +00:00
|
|
|
/* Death,
|
|
|
|
* TODO: Wait for more post-death features (i.e. animiations) before implementing death
|
|
|
|
* sounds */
|
2021-06-15 16:15:58 +00:00
|
|
|
}
|
|
|
|
|
2019-09-09 19:11:40 +00:00
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub enum ControlEvent {
|
2020-10-07 02:23:20 +00:00
|
|
|
//ToggleLantern,
|
|
|
|
EnableLantern,
|
|
|
|
DisableLantern,
|
2021-01-31 20:29:50 +00:00
|
|
|
Interact(Uid),
|
2021-02-13 23:32:55 +00:00
|
|
|
InitiateInvite(Uid, InviteKind),
|
|
|
|
InviteResponse(InviteResponse),
|
|
|
|
PerformTradeAction(TradeId, TradeAction),
|
2019-09-09 19:11:40 +00:00
|
|
|
Mount(Uid),
|
|
|
|
Unmount,
|
2021-03-01 22:40:42 +00:00
|
|
|
InventoryEvent(InventoryEvent),
|
2020-04-26 17:03:19 +00:00
|
|
|
GroupManip(GroupManip),
|
2020-10-19 03:00:35 +00:00
|
|
|
RemoveBuff(BuffKind),
|
2020-03-24 07:38:16 +00:00
|
|
|
Respawn,
|
2021-06-15 16:15:58 +00:00
|
|
|
Utterance(UtteranceKind),
|
2020-03-24 07:38:16 +00:00
|
|
|
}
|
|
|
|
|
2021-02-07 16:57:41 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
2020-03-24 07:38:16 +00:00
|
|
|
pub enum ControlAction {
|
2021-02-08 17:31:17 +00:00
|
|
|
SwapEquippedWeapons,
|
2021-03-01 22:40:42 +00:00
|
|
|
InventoryAction(InventoryAction),
|
2020-03-26 15:05:17 +00:00
|
|
|
Wield,
|
2020-06-16 21:32:39 +00:00
|
|
|
GlideWield,
|
2020-03-26 15:05:17 +00:00
|
|
|
Unwield,
|
|
|
|
Sit,
|
2020-05-27 06:41:55 +00:00
|
|
|
Dance,
|
2020-08-02 05:09:11 +00:00
|
|
|
Sneak,
|
2020-03-26 15:05:17 +00:00
|
|
|
Stand,
|
2021-01-31 20:29:50 +00:00
|
|
|
Talk,
|
2021-03-05 06:09:56 +00:00
|
|
|
StartInput {
|
2021-03-12 21:01:30 +00:00
|
|
|
input: InputKind,
|
2021-03-21 03:28:13 +00:00
|
|
|
target_entity: Option<Uid>,
|
2021-03-21 16:09:16 +00:00
|
|
|
// Some inputs need a selected position, such as mining
|
|
|
|
select_pos: Option<Vec3<f32>>,
|
2021-03-05 06:09:56 +00:00
|
|
|
},
|
2021-03-12 04:53:25 +00:00
|
|
|
CancelInput(InputKind),
|
2021-03-05 06:09:56 +00:00
|
|
|
}
|
|
|
|
|
2021-03-21 16:09:16 +00:00
|
|
|
impl ControlAction {
|
2021-03-21 17:45:01 +00:00
|
|
|
pub fn basic_input(input: InputKind) -> Self {
|
2021-03-21 16:09:16 +00:00
|
|
|
ControlAction::StartInput {
|
|
|
|
input,
|
2021-03-21 03:28:13 +00:00
|
|
|
target_entity: None,
|
2021-03-21 16:09:16 +00:00
|
|
|
select_pos: None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-05 06:09:56 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize, Eq, Ord, PartialOrd)]
|
|
|
|
#[repr(u32)]
|
|
|
|
pub enum InputKind {
|
|
|
|
Primary = 0,
|
2021-03-13 00:38:20 +00:00
|
|
|
Secondary = 1,
|
2021-04-10 03:40:20 +00:00
|
|
|
Block = 2,
|
|
|
|
Ability(usize) = 3,
|
|
|
|
Roll = 4,
|
|
|
|
Jump = 5,
|
|
|
|
Fly = 6,
|
2021-03-14 20:35:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl InputKind {
|
|
|
|
pub fn is_ability(self) -> bool {
|
2021-04-19 05:35:46 +00:00
|
|
|
matches!(
|
|
|
|
self,
|
|
|
|
Self::Primary | Self::Secondary | Self::Ability(_) | Self::Block
|
|
|
|
)
|
2021-03-14 20:35:28 +00:00
|
|
|
}
|
2019-11-29 15:20:35 +00:00
|
|
|
}
|
|
|
|
|
2021-03-21 03:28:13 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
2021-03-21 17:45:01 +00:00
|
|
|
pub struct InputAttr {
|
|
|
|
pub select_pos: Option<Vec3<f32>>,
|
2021-03-21 03:28:13 +00:00
|
|
|
pub target_entity: Option<Uid>,
|
2021-03-21 17:45:01 +00:00
|
|
|
}
|
|
|
|
|
2020-03-24 07:38:16 +00:00
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub enum Climb {
|
|
|
|
Up,
|
|
|
|
Down,
|
|
|
|
Hold,
|
|
|
|
}
|
|
|
|
|
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 {
|
2020-03-24 07:38:16 +00:00
|
|
|
pub climb: Option<Climb>,
|
2019-10-15 04:06:14 +00:00
|
|
|
pub move_dir: Vec2<f32>,
|
2020-11-03 22:46:07 +00:00
|
|
|
pub move_z: f32, /* z axis (not combined with move_dir because they may have independent
|
|
|
|
* limits) */
|
2020-03-28 01:31:22 +00:00
|
|
|
pub look_dir: Dir,
|
2021-03-21 20:09:59 +00:00
|
|
|
pub select_pos: Option<Vec3<f32>>,
|
2021-06-21 12:27:19 +00:00
|
|
|
/// Attempt to enable strafing.
|
|
|
|
/// Currently, setting this to false will *not* disable strafing during a
|
|
|
|
/// wielding character state.
|
|
|
|
pub strafing: bool,
|
2019-10-15 04:06:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub struct Controller {
|
|
|
|
pub inputs: ControllerInputs,
|
2021-03-21 16:09:16 +00:00
|
|
|
pub queued_inputs: BTreeMap<InputKind, InputAttr>,
|
2019-10-21 00:59:53 +00:00
|
|
|
// TODO: consider SmallVec
|
2019-09-09 19:11:40 +00:00
|
|
|
pub events: Vec<ControlEvent>,
|
2020-03-24 07:38:16 +00:00
|
|
|
pub actions: Vec<ControlAction>,
|
2019-09-09 19:11:40 +00:00
|
|
|
}
|
|
|
|
|
2019-11-29 15:20:35 +00:00
|
|
|
impl ControllerInputs {
|
2021-06-21 20:13:49 +00:00
|
|
|
/// Sanitize inputs to avoid clients sending bad data.
|
|
|
|
pub fn sanitize(&mut self) {
|
|
|
|
self.move_dir = if self.move_dir.map(|e| e.is_finite()).reduce_and() {
|
|
|
|
self.move_dir / self.move_dir.magnitude().max(1.0)
|
|
|
|
} else {
|
|
|
|
Vec2::zero()
|
|
|
|
};
|
|
|
|
self.move_z = if self.move_z.is_finite() {
|
|
|
|
self.move_z.clamped(-1.0, 1.0)
|
|
|
|
} else {
|
|
|
|
0.0
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-03-24 07:38:16 +00:00
|
|
|
/// Updates Controller inputs with new version received from the client
|
|
|
|
pub fn update_with_new(&mut self, new: Self) {
|
|
|
|
self.climb = new.climb;
|
|
|
|
self.move_dir = new.move_dir;
|
2020-11-03 22:46:07 +00:00
|
|
|
self.move_z = new.move_z;
|
2020-03-24 07:38:16 +00:00
|
|
|
self.look_dir = new.look_dir;
|
2021-03-21 20:09:59 +00:00
|
|
|
self.select_pos = new.select_pos;
|
2019-12-03 06:30:08 +00:00
|
|
|
}
|
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 {
|
2020-11-25 22:47:16 +00:00
|
|
|
type Storage = 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 {
|
2021-01-07 20:25:12 +00:00
|
|
|
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
|
2019-09-09 19:11:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
|
|
pub struct Mounting(pub Uid);
|
|
|
|
|
|
|
|
impl Component for Mounting {
|
2021-01-07 20:25:12 +00:00
|
|
|
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
|
2019-09-09 19:11:40 +00:00
|
|
|
}
|