veloren_voxygen/
game_input.rs

1use serde::{Deserialize, Serialize};
2use std::convert::AsRef;
3use strum::{AsRefStr, EnumIter, EnumString};
4
5/// Represents a key that the game recognises after input mapping.
6#[derive(
7    Clone,
8    Copy,
9    Debug,
10    PartialEq,
11    Eq,
12    PartialOrd,
13    Ord,
14    Hash,
15    Deserialize,
16    Serialize,
17    AsRefStr,
18    EnumIter,
19    EnumString,
20)]
21pub enum GameInput {
22    #[strum(serialize = "gameinput-primary")]
23    Primary,
24    #[strum(serialize = "gameinput-secondary")]
25    Secondary,
26    #[strum(serialize = "gameinput-block")]
27    Block,
28    #[strum(serialize = "gameinput-slot1")]
29    Slot1,
30    #[strum(serialize = "gameinput-slot2")]
31    Slot2,
32    #[strum(serialize = "gameinput-slot3")]
33    Slot3,
34    #[strum(serialize = "gameinput-slot4")]
35    Slot4,
36    #[strum(serialize = "gameinput-slot5")]
37    Slot5,
38    #[strum(serialize = "gameinput-slot6")]
39    Slot6,
40    #[strum(serialize = "gameinput-slot7")]
41    Slot7,
42    #[strum(serialize = "gameinput-slot8")]
43    Slot8,
44    #[strum(serialize = "gameinput-slot9")]
45    Slot9,
46    #[strum(serialize = "gameinput-slot10")]
47    Slot10,
48    #[strum(serialize = "gameinput-nextslot")]
49    NextSlot,
50    #[strum(serialize = "gameinput-previousslot")]
51    PreviousSlot,
52    #[strum(serialize = "gameinput-currentslot")]
53    CurrentSlot,
54    #[strum(serialize = "gameinput-togglecursor")]
55    ToggleCursor,
56    #[strum(serialize = "gameinput-moveforward")]
57    MoveForward,
58    #[strum(serialize = "gameinput-moveback")]
59    MoveBack,
60    #[strum(serialize = "gameinput-moveleft")]
61    MoveLeft,
62    #[strum(serialize = "gameinput-moveright")]
63    MoveRight,
64    #[strum(serialize = "gameinput-jump")]
65    Jump,
66    #[strum(serialize = "gameinput-walljump")]
67    WallJump,
68    #[strum(serialize = "gameinput-sit")]
69    Sit,
70    #[strum(serialize = "gameinput-crawl")]
71    Crawl,
72    #[strum(serialize = "gameinput-dance")]
73    Dance,
74    #[strum(serialize = "gameinput-greet")]
75    Greet,
76    #[strum(serialize = "gameinput-glide")]
77    Glide,
78    #[strum(serialize = "gameinput-swimup")]
79    SwimUp,
80    #[strum(serialize = "gameinput-swimdown")]
81    SwimDown,
82    #[strum(serialize = "gameinput-fly")]
83    Fly,
84    #[strum(serialize = "gameinput-sneak")]
85    Sneak,
86    #[strum(serialize = "gameinput-cancelclimb")]
87    CancelClimb,
88    #[strum(serialize = "gameinput-togglelantern")]
89    ToggleLantern,
90    #[strum(serialize = "gameinput-mount")]
91    Mount,
92    #[strum(serialize = "gameinput-stayfollow")]
93    StayFollow,
94    #[strum(serialize = "gameinput-chat")]
95    Chat,
96    #[strum(serialize = "gameinput-command")]
97    Command,
98    #[strum(serialize = "gameinput-escape")]
99    Escape,
100    #[strum(serialize = "gameinput-map")]
101    Map,
102    #[strum(serialize = "gameinput-inventory")]
103    Inventory,
104    #[strum(serialize = "gameinput-trade")]
105    Trade,
106    #[strum(serialize = "gameinput-social")]
107    Social,
108    #[strum(serialize = "gameinput-crafting")]
109    Crafting,
110    #[strum(serialize = "gameinput-diary")]
111    Diary,
112    #[strum(serialize = "gameinput-settings")]
113    Settings,
114    #[strum(serialize = "gameinput-controls")]
115    Controls,
116    #[strum(serialize = "gameinput-toggleinterface")]
117    ToggleInterface,
118    #[strum(serialize = "gameinput-toggledebug")]
119    ToggleDebug,
120    #[cfg(feature = "egui-ui")]
121    #[strum(serialize = "gameinput-toggle_egui_debug")]
122    ToggleEguiDebug,
123    #[strum(serialize = "gameinput-togglechat")]
124    ToggleChat,
125    #[strum(serialize = "gameinput-fullscreen")]
126    Fullscreen,
127    #[strum(serialize = "gameinput-screenshot")]
128    Screenshot,
129    #[strum(serialize = "gameinput-toggleingameui")]
130    ToggleIngameUi,
131    #[strum(serialize = "gameinput-roll")]
132    Roll,
133    #[strum(serialize = "gameinput-giveup")]
134    GiveUp,
135    #[strum(serialize = "gameinput-respawn")]
136    Respawn,
137    #[strum(serialize = "gameinput-interact")]
138    Interact,
139    #[strum(serialize = "gameinput-togglewield")]
140    ToggleWield,
141    #[strum(serialize = "gameinput-swaploadout")]
142    SwapLoadout,
143    #[strum(serialize = "gameinput-freelook")]
144    FreeLook,
145    #[strum(serialize = "gameinput-autowalk")]
146    AutoWalk,
147    #[strum(serialize = "gameinput-zoomin")]
148    ZoomIn,
149    #[strum(serialize = "gameinput-zoomout")]
150    ZoomOut,
151    #[strum(serialize = "gameinput-zoomlock")]
152    ZoomLock,
153    #[strum(serialize = "gameinput-cameraclamp")]
154    CameraClamp,
155    #[strum(serialize = "gameinput-cyclecamera")]
156    CycleCamera,
157    #[strum(serialize = "gameinput-select")]
158    Select,
159    #[strum(serialize = "gameinput-acceptgroupinvite")]
160    AcceptGroupInvite,
161    #[strum(serialize = "gameinput-declinegroupinvite")]
162    DeclineGroupInvite,
163    #[strum(serialize = "gameinput-mapzoomin")]
164    MapZoomIn,
165    #[strum(serialize = "gameinput-mapzoomout")]
166    MapZoomOut,
167    #[strum(serialize = "gameinput-map-locationmarkerbutton")]
168    MapSetMarker,
169    #[strum(serialize = "gameinput-spectatespeedboost")]
170    SpectateSpeedBoost,
171    #[strum(serialize = "gameinput-spectateviewpoint")]
172    SpectateViewpoint,
173    #[strum(serialize = "gameinput-mutemaster")]
174    MuteMaster,
175    #[strum(serialize = "gameinput-muteinactivemaster")]
176    MuteInactiveMaster,
177    #[strum(serialize = "gameinput-mutemusic")]
178    MuteMusic,
179    #[strum(serialize = "gameinput-mutesfx")]
180    MuteSfx,
181    #[strum(serialize = "gameinput-muteambience")]
182    MuteAmbience,
183    #[strum(serialize = "gameinput-togglewalk")]
184    ToggleWalk,
185}
186
187impl GameInput {
188    pub fn get_localization_key(&self) -> &str { self.as_ref() }
189
190    /// Return true if `a` and `b` are able to be bound to the same key at the
191    /// same time without conflict. For example, the player can't jump and climb
192    /// at the same time, so these can be bound to the same key.
193    pub fn can_share_bindings(a: GameInput, b: GameInput) -> bool {
194        let bindings_a = a.get_representative_bindings();
195        let bindings_b = b.get_representative_bindings();
196
197        if bindings_a.is_empty() && bindings_b.is_empty() {
198            return a == b;
199        }
200        if bindings_a.is_empty() {
201            return bindings_b.contains(&a);
202        }
203        if bindings_b.is_empty() {
204            return bindings_a.contains(&b);
205        }
206
207        bindings_a.iter().any(|x| bindings_b.contains(x))
208    }
209
210    /// If two GameInputs are able to be bound at the same time, then they will
211    /// return a slice that contains the other GameInput.
212    /// Since a GameInput might be fine to be shared with multiple other
213    /// GameInputs a slice is required instead of just a single GameInput.
214    /// This models the Find operation of a disjoint-set data
215    /// structure.
216    fn get_representative_bindings(self) -> &'static [GameInput] {
217        match self {
218            GameInput::SwimUp | GameInput::Respawn | GameInput::GiveUp => &[GameInput::Jump],
219
220            GameInput::AutoWalk | GameInput::FreeLook => &[GameInput::FreeLook],
221
222            GameInput::SpectateSpeedBoost => &[GameInput::Glide],
223            GameInput::WallJump => &[GameInput::Mount, GameInput::Jump],
224
225            GameInput::SwimDown | GameInput::Sneak | GameInput::CancelClimb => &[GameInput::Roll],
226
227            GameInput::SpectateViewpoint => &[GameInput::MapSetMarker],
228
229            _ => &[],
230        }
231    }
232}