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-roll")]
29    Roll,
30    #[strum(serialize = "gameinput-moveforward")]
31    MoveForward,
32    #[strum(serialize = "gameinput-moveback")]
33    MoveBack,
34    #[strum(serialize = "gameinput-moveleft")]
35    MoveLeft,
36    #[strum(serialize = "gameinput-moveright")]
37    MoveRight,
38    #[strum(serialize = "gameinput-swimup")]
39    SwimUp,
40    #[strum(serialize = "gameinput-swimdown")]
41    SwimDown,
42    #[strum(serialize = "gameinput-jump")]
43    Jump,
44    #[strum(serialize = "gameinput-walljump")]
45    WallJump,
46    #[strum(serialize = "gameinput-cancelclimb")]
47    CancelClimb,
48    #[strum(serialize = "gameinput-interact")]
49    Interact,
50    #[strum(serialize = "gameinput-trade")]
51    Trade,
52    #[strum(serialize = "gameinput-glide")]
53    Glide,
54    #[strum(serialize = "gameinput-togglelantern")]
55    ToggleLantern,
56    #[strum(serialize = "gameinput-swaploadout")]
57    SwapLoadout,
58    #[strum(serialize = "gameinput-togglewield")]
59    ToggleWield,
60    #[strum(serialize = "gameinput-sneak")]
61    Sneak,
62    #[strum(serialize = "gameinput-sit")]
63    Sit,
64    #[strum(serialize = "gameinput-crawl")]
65    Crawl,
66    #[strum(serialize = "gameinput-dance")]
67    Dance,
68    #[strum(serialize = "gameinput-greet")]
69    Greet,
70    #[strum(serialize = "gameinput-mount")]
71    Mount,
72    #[strum(serialize = "gameinput-stayfollow")]
73    StayFollow,
74    #[strum(serialize = "gameinput-togglewalk")]
75    ToggleWalk,
76    #[strum(serialize = "gameinput-autowalk")]
77    AutoWalk,
78    #[strum(serialize = "gameinput-freelook")]
79    FreeLook,
80    #[strum(serialize = "gameinput-giveup")]
81    GiveUp,
82    #[strum(serialize = "gameinput-respawn")]
83    Respawn,
84    #[strum(serialize = "gameinput-inventory")]
85    Inventory,
86    #[strum(serialize = "gameinput-map")]
87    Map,
88    #[strum(serialize = "gameinput-settings")]
89    Settings,
90    #[strum(serialize = "gameinput-crafting")]
91    Crafting,
92    #[strum(serialize = "gameinput-diary")]
93    Diary,
94    #[strum(serialize = "gameinput-chat")]
95    Chat,
96    #[strum(serialize = "gameinput-social")]
97    Social,
98    #[strum(serialize = "gameinput-escape")]
99    Escape,
100    #[strum(serialize = "gameinput-controls")]
101    Controls,
102    #[strum(serialize = "gameinput-select")]
103    Select,
104    #[strum(serialize = "gameinput-acceptgroupinvite")]
105    AcceptGroupInvite,
106    #[strum(serialize = "gameinput-declinegroupinvite")]
107    DeclineGroupInvite,
108    #[strum(serialize = "gameinput-previousslot")]
109    PreviousSlot,
110    #[strum(serialize = "gameinput-nextslot")]
111    NextSlot,
112    #[strum(serialize = "gameinput-currentslot")]
113    CurrentSlot,
114    #[strum(serialize = "gameinput-slot1")]
115    Slot1,
116    #[strum(serialize = "gameinput-slot2")]
117    Slot2,
118    #[strum(serialize = "gameinput-slot3")]
119    Slot3,
120    #[strum(serialize = "gameinput-slot4")]
121    Slot4,
122    #[strum(serialize = "gameinput-slot5")]
123    Slot5,
124    #[strum(serialize = "gameinput-slot6")]
125    Slot6,
126    #[strum(serialize = "gameinput-slot7")]
127    Slot7,
128    #[strum(serialize = "gameinput-slot8")]
129    Slot8,
130    #[strum(serialize = "gameinput-slot9")]
131    Slot9,
132    #[strum(serialize = "gameinput-slot10")]
133    Slot10,
134    #[strum(serialize = "gameinput-zoomin")]
135    ZoomIn,
136    #[strum(serialize = "gameinput-zoomout")]
137    ZoomOut,
138    #[strum(serialize = "gameinput-togglecursor")]
139    ToggleCursor,
140    #[strum(serialize = "gameinput-zoomlock")]
141    ZoomLock,
142    #[strum(serialize = "gameinput-mapzoomin")]
143    MapZoomIn,
144    #[strum(serialize = "gameinput-mapzoomout")]
145    MapZoomOut,
146    #[strum(serialize = "gameinput-map-locationmarkerbutton")]
147    MapSetMarker,
148    #[strum(serialize = "gameinput-fullscreen")]
149    Fullscreen,
150    #[strum(serialize = "gameinput-screenshot")]
151    Screenshot,
152    #[strum(serialize = "gameinput-command")]
153    Command,
154    #[strum(serialize = "gameinput-fly")]
155    Fly,
156    #[strum(serialize = "gameinput-toggleinterface")]
157    ToggleInterface,
158    #[strum(serialize = "gameinput-toggledebug")]
159    ToggleDebug,
160    #[cfg(feature = "egui-ui")]
161    #[strum(serialize = "gameinput-toggle_egui_debug")]
162    ToggleEguiDebug,
163    #[strum(serialize = "gameinput-togglechat")]
164    ToggleChat,
165    #[strum(serialize = "gameinput-toggleingameui")]
166    ToggleIngameUi,
167    #[strum(serialize = "gameinput-cameraclamp")]
168    CameraClamp,
169    #[strum(serialize = "gameinput-cyclecamera")]
170    CycleCamera,
171    #[strum(serialize = "gameinput-spectatespeedboost")]
172    SpectateSpeedBoost,
173    #[strum(serialize = "gameinput-spectateviewpoint")]
174    SpectateViewpoint,
175    #[strum(serialize = "gameinput-mutemaster")]
176    MuteMaster,
177    #[strum(serialize = "gameinput-muteinactivemaster")]
178    MuteInactiveMaster,
179    #[strum(serialize = "gameinput-mutemusic")]
180    MuteMusic,
181    #[strum(serialize = "gameinput-mutesfx")]
182    MuteSfx,
183    #[strum(serialize = "gameinput-muteambience")]
184    MuteAmbience,
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}