@@ -72,7 +72,6 @@ pub fn try_move_player(delta_x: i32, delta_y: i32, gs: &mut State) -> RunState {
72
72
}
73
73
74
74
macro_attr ! {
75
-
76
75
#[ derive( PartialEq , Eq , Clone , Copy , Debug , Hash , EnumDisplay !) ]
77
76
pub enum PlayerAction {
78
77
ShowInventory ,
@@ -92,6 +91,31 @@ macro_attr! {
92
91
}
93
92
}
94
93
94
+ macro_attr ! {
95
+ #[ derive( PartialEq , Eq , Clone , Copy , Debug , Hash , EnumDisplay !) ]
96
+ pub enum ContextKeys {
97
+ Shift
98
+ }
99
+
100
+ }
101
+
102
+ impl ContextKeys {
103
+ pub fn display_vec ( keys : & Vec < ContextKeys > ) -> String {
104
+ if keys. is_empty ( ) {
105
+ "" . to_string ( )
106
+ } else {
107
+ " + " . to_owned ( ) + & keys. iter ( ) . map ( |k| k. to_string ( ) ) . join ( " + " )
108
+ }
109
+ }
110
+ }
111
+
112
+ type Keys = ( VirtualKeyCode , Vec < ContextKeys > ) ;
113
+
114
+ pub fn display_key_combo ( keys : & Keys ) -> String {
115
+ let ( key, context_keys) = keys;
116
+ format ! ( "{:?}{}" , key, ContextKeys :: display_vec( context_keys) )
117
+ }
118
+
95
119
pub trait PlayerActionFnT : Fn ( & mut State ) -> RunState + Send + Sync + ' static { }
96
120
97
121
impl < F > PlayerActionFnT for F where F : Fn ( & mut State ) -> RunState + Send + Sync + ' static { }
@@ -106,7 +130,7 @@ impl std::fmt::Debug for dyn PlayerActionFnT {
106
130
107
131
#[ derive( Clone , Debug ) ]
108
132
pub struct ActionAndKeys {
109
- pub key_codes : Vec < VirtualKeyCode > ,
133
+ pub key_codes : Vec < Keys > ,
110
134
pub action : PlayerActionFn ,
111
135
}
112
136
@@ -119,7 +143,7 @@ pub struct ActionAndId {
119
143
#[ derive( Debug ) ]
120
144
pub struct KeyBindings {
121
145
pub action_by_id : IndexMap < PlayerAction , ActionAndKeys > ,
122
- pub action_by_key : IndexMap < VirtualKeyCode , ActionAndId > ,
146
+ pub action_by_key : IndexMap < Keys , ActionAndId > ,
123
147
}
124
148
125
149
pub static DEFAULT_KEY_BINDINGS : OnceCell < KeyBindings > = OnceCell :: new ( ) ;
@@ -136,21 +160,21 @@ impl KeyBindings {
136
160
(
137
161
PlayerAction :: ShowInventory ,
138
162
ActionAndKeys {
139
- key_codes : vec ! [ VirtualKeyCode :: I ] ,
163
+ key_codes : vec ! [ ( VirtualKeyCode :: I , vec! [ ] ) ] ,
140
164
action : Arc :: new ( |_| RunState :: ShowInventory ) ,
141
165
} ,
142
166
) ,
143
167
(
144
168
PlayerAction :: ShowDropItem ,
145
169
ActionAndKeys {
146
- key_codes : vec ! [ VirtualKeyCode :: D ] ,
170
+ key_codes : vec ! [ ( VirtualKeyCode :: D , vec! [ ContextKeys :: Shift ] ) ] ,
147
171
action : Arc :: new ( |_| RunState :: ShowDropItem ) ,
148
172
} ,
149
173
) ,
150
174
(
151
175
PlayerAction :: Escape ,
152
176
ActionAndKeys {
153
- key_codes : vec ! [ VirtualKeyCode :: Escape ] ,
177
+ key_codes : vec ! [ ( VirtualKeyCode :: Escape , vec! [ ] ) ] ,
154
178
action : Arc :: new ( |_| RunState :: MainMenu {
155
179
menu_selection : SaveGame ,
156
180
} ) ,
@@ -159,17 +183,17 @@ impl KeyBindings {
159
183
(
160
184
PlayerAction :: ShowRemoveItem ,
161
185
ActionAndKeys {
162
- key_codes : vec ! [ VirtualKeyCode :: R ] ,
186
+ key_codes : vec ! [ ( VirtualKeyCode :: R , vec! [ ] ) ] ,
163
187
action : Arc :: new ( |_| RunState :: ShowRemoveItem ) ,
164
188
} ,
165
189
) ,
166
190
(
167
191
PlayerAction :: Left ,
168
192
ActionAndKeys {
169
193
key_codes : vec ! [
170
- VirtualKeyCode :: Left ,
171
- VirtualKeyCode :: A ,
172
- VirtualKeyCode :: Numpad4 ,
194
+ ( VirtualKeyCode :: Left , vec! [ ] ) ,
195
+ ( VirtualKeyCode :: A , vec! [ ] ) ,
196
+ ( VirtualKeyCode :: Numpad4 , vec! [ ] ) ,
173
197
] ,
174
198
action : Arc :: new ( |gs| try_move_player ( -1 , 0 , gs) ) ,
175
199
} ,
@@ -178,9 +202,9 @@ impl KeyBindings {
178
202
PlayerAction :: Right ,
179
203
ActionAndKeys {
180
204
key_codes : vec ! [
181
- VirtualKeyCode :: Right ,
182
- VirtualKeyCode :: D ,
183
- VirtualKeyCode :: Numpad6 ,
205
+ ( VirtualKeyCode :: Right , vec! [ ] ) ,
206
+ ( VirtualKeyCode :: D , vec! [ ] ) ,
207
+ ( VirtualKeyCode :: Numpad6 , vec! [ ] ) ,
184
208
] ,
185
209
action : Arc :: new ( |gs| try_move_player ( 1 , 0 , gs) ) ,
186
210
} ,
@@ -189,9 +213,9 @@ impl KeyBindings {
189
213
PlayerAction :: Up ,
190
214
ActionAndKeys {
191
215
key_codes : vec ! [
192
- VirtualKeyCode :: Up ,
193
- VirtualKeyCode :: W ,
194
- VirtualKeyCode :: Numpad8 ,
216
+ ( VirtualKeyCode :: Up , vec! [ ] ) ,
217
+ ( VirtualKeyCode :: W , vec! [ ] ) ,
218
+ ( VirtualKeyCode :: Numpad8 , vec! [ ] ) ,
195
219
] ,
196
220
action : Arc :: new ( |gs| try_move_player ( 0 , -1 , gs) ) ,
197
221
} ,
@@ -200,52 +224,55 @@ impl KeyBindings {
200
224
PlayerAction :: Down ,
201
225
ActionAndKeys {
202
226
key_codes : vec ! [
203
- VirtualKeyCode :: Down ,
204
- VirtualKeyCode :: S ,
205
- VirtualKeyCode :: Numpad2 ,
227
+ ( VirtualKeyCode :: Down , vec! [ ] ) ,
228
+ ( VirtualKeyCode :: S , vec! [ ] ) ,
229
+ ( VirtualKeyCode :: Numpad2 , vec! [ ] ) ,
206
230
] ,
207
231
action : Arc :: new ( |gs| try_move_player ( 0 , 1 , gs) ) ,
208
232
} ,
209
233
) ,
210
234
(
211
235
PlayerAction :: UpLeft ,
212
236
ActionAndKeys {
213
- key_codes : vec ! [ VirtualKeyCode :: Numpad7 ] ,
237
+ key_codes : vec ! [ ( VirtualKeyCode :: Numpad7 , vec! [ ] ) ] ,
214
238
action : Arc :: new ( |gs| try_move_player ( -1 , -1 , gs) ) ,
215
239
} ,
216
240
) ,
217
241
(
218
242
PlayerAction :: UpRight ,
219
243
ActionAndKeys {
220
- key_codes : vec ! [ VirtualKeyCode :: Numpad9 ] ,
244
+ key_codes : vec ! [ ( VirtualKeyCode :: Numpad9 , vec! [ ] ) ] ,
221
245
action : Arc :: new ( |gs| try_move_player ( 1 , -1 , gs) ) ,
222
246
} ,
223
247
) ,
224
248
(
225
249
PlayerAction :: DownLeft ,
226
250
ActionAndKeys {
227
- key_codes : vec ! [ VirtualKeyCode :: Numpad1 ] ,
251
+ key_codes : vec ! [ ( VirtualKeyCode :: Numpad1 , vec! [ ] ) ] ,
228
252
action : Arc :: new ( |gs| try_move_player ( -1 , 1 , gs) ) ,
229
253
} ,
230
254
) ,
231
255
(
232
256
PlayerAction :: DownRight ,
233
257
ActionAndKeys {
234
- key_codes : vec ! [ VirtualKeyCode :: Numpad3 ] ,
258
+ key_codes : vec ! [ ( VirtualKeyCode :: Numpad3 , vec! [ ] ) ] ,
235
259
action : Arc :: new ( |gs| try_move_player ( 1 , 1 , gs) ) ,
236
260
} ,
237
261
) ,
238
262
(
239
263
PlayerAction :: Rest ,
240
264
ActionAndKeys {
241
- key_codes : vec ! [ VirtualKeyCode :: Numpad5 , VirtualKeyCode :: Space ] ,
265
+ key_codes : vec ! [
266
+ ( VirtualKeyCode :: Numpad5 , vec![ ] ) ,
267
+ ( VirtualKeyCode :: Space , vec![ ] ) ,
268
+ ] ,
242
269
action : Arc :: new ( |gs| skip_turn ( & mut gs. ecs ) ) ,
243
270
} ,
244
271
) ,
245
272
(
246
273
PlayerAction :: Grab ,
247
274
ActionAndKeys {
248
- key_codes : vec ! [ VirtualKeyCode :: G ] ,
275
+ key_codes : vec ! [ ( VirtualKeyCode :: G , vec! [ ] ) ] ,
249
276
action : Arc :: new ( |gs| interact ( & mut gs. ecs ) ) ,
250
277
} ,
251
278
) ,
@@ -254,12 +281,12 @@ impl KeyBindings {
254
281
. cloned ( )
255
282
. collect ( ) ;
256
283
257
- let action_by_key: IndexMap < VirtualKeyCode , ActionAndId > = action_by_id
284
+ let action_by_key: IndexMap < Keys , ActionAndId > = action_by_id
258
285
. iter ( )
259
286
. flat_map ( |( id, action_and_keys) | {
260
287
action_and_keys. key_codes . iter ( ) . map ( |key_code| {
261
288
(
262
- * key_code,
289
+ key_code. clone ( ) ,
263
290
ActionAndId {
264
291
id : * id,
265
292
action : action_and_keys. action . clone ( ) ,
@@ -278,9 +305,15 @@ impl KeyBindings {
278
305
279
306
pub fn player_input ( gs : & mut State , ctx : & mut BTerm ) -> RunState {
280
307
let key_map = & KeyBindings :: default ( ) . action_by_key ;
281
- match ctx. key {
308
+
309
+ let mut ctxt_keys = vec ! [ ] ;
310
+ if ctx. shift {
311
+ ctxt_keys. push ( ContextKeys :: Shift ) ;
312
+ }
313
+ let keys_opt = ctx. key . map ( |key| ( key, ctxt_keys) ) ;
314
+ match keys_opt {
282
315
None => RunState :: AwaitingInput ,
283
- Some ( key ) => match key_map. get ( & key ) {
316
+ Some ( keys ) => match key_map. get ( & keys ) {
284
317
None => RunState :: AwaitingInput ,
285
318
Some ( action_and_id) => ( action_and_id. action ) ( gs) ,
286
319
} ,
0 commit comments