CleverRaven/Cataclysm-DDA — pull request #7283 by BevapDin (2014-04-18 13:45:54+00:00)
Title: Unify input system, remove keymap [CR]

Lets get rid of the keymap.

- Read the keymap file one last time and add the keybindings to `input_manager`, storing the keybindings in `data/raw/keybindings.json`. It then *deletes* the keymap! - to prevent loading it again and again.

- There is a `input_context` that you get by calling `get_default_mode_input_context`. It contains the actions that the main screen has (everything that is mapped to an `action_id`).

- The idents of action of the context from `get_default_mode_input_context` are the results of `action_ident`, with the exceptions of direction keys. They have the idents `UP`, `LEFT`, `LEFTUP`, ... `LEVEL_UP` and `LEVEL_DOWN`, because their mapping already exist in the keybindings.json file.

- The main help window ('?' -> '1') uses the `input_context` to display the keybindings and bindings can be changed there. The window is the same as for example when changing the keybindings in the bionics window.

- Moving the cursor in various screens should now use the same keys as the character movement. In fact they should map to the same action in the `input_context` ("LEFT", "RIGHT", "UP", "LEFTUP", ...).

- Fixes #235, mostly. Normal movement and movement on the overmap use the same key (because they use the same direction actions). The bindings will still conflict with other bindings, this is unavoidable. If the user binds 'q' to "move NE" and 'q' to quit, they will conflict. The input_context uses the first action that matches the input (direction actions are usually registers before other actions so 'q' will usually trigger the movement). Anyway the user can rebind the keys, including the "exit screen" key and thereby avoiding the problem. The problem can't really be avoid otherwise.

- Fixes #166, but some keys will turn up as "unknown key xxx". This is because the name for key xxx is not declared. This is a minor display bug, but it does not affect the game mechanics. Rebinding a key works by waiting for an input (key press) by the user and than storing that input (typically a `long`). It is later compared to the current input and if it's the same, the game assumes the same key has been pressed. If the OS/the terminal maps the input (for example Ctrl-D is often mapped to EOF in terminals), only the mapped value arrives at the program. Similar if the terminal has its own handler for Ctrl-Shift-t (in konsole it's mapped to "open a new tab") or if the ncurses interface generally does not support a key combination, nothing can be done.

- Fixes #234, the functions `choose_direction`, `choose_adjacent` and `choose_adjacent_highlight` use the `input_context` with the usually keybindings. Questing aside: is there a reason that `choose_adjacent_highlight` contained a lot of code that already exists in `choose_adjacent`? I compressed that by calling `choose_adjacent` from `choose_adjacent_highlight` after setting up the highlight.

- It also fixes #4324 finally.

----

Some issues with the `input_manger`:

The keybindings file contains the names of the action as they are displayed to the user. They are translated upon loading, but saving the keybindings file saves the translated names. Loading the game in a different language will still display the names that have been in use when the keybindings were saved.

This is actually easy to fix, but I think the names of the actions should not go into the json file at all, and instead remain in the game code. After all changing the names in json doesn't make much sense as the actions still keep their original meaning.

Some suggesting: on conflicts ask the user if they want to ignore the conflict and apply the keybinding anyway. Because of the way keybindings are reused in other screens it might be useful.