mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Carbonhell/keybindings
This commit is contained in:
parent
611359e52f
commit
198c875559
@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Added daily Mac builds
|
||||
- Allow spawning individual pet species, not just generic body kinds.
|
||||
- Configurable fonts
|
||||
- Configurable keybindings from the Controls menu
|
||||
- Tanslation status tracking
|
||||
- Added gamma setting
|
||||
- Added new orc hairstyles
|
||||
|
@ -250,90 +250,7 @@ Enjoy your stay in the World of Veloren."#,
|
||||
"hud.settings.sound_effect_volume": "Sound Effects Volume",
|
||||
"hud.settings.audio_device": "Audio Device",
|
||||
|
||||
// Control list
|
||||
"hud.settings.control_names": r#"Free Cursor
|
||||
Toggle Help Window
|
||||
Toggle Interface
|
||||
Toggle FPS and Debug Info
|
||||
Take Screenshot
|
||||
Toggle Nametags
|
||||
Toggle Fullscreen
|
||||
|
||||
|
||||
Move Forward
|
||||
Move Left
|
||||
Move Right
|
||||
Move Backwards
|
||||
|
||||
Jump
|
||||
|
||||
Glider
|
||||
|
||||
Dodge
|
||||
|
||||
Roll
|
||||
|
||||
Climb
|
||||
|
||||
Climb down
|
||||
|
||||
Auto Walk
|
||||
|
||||
Sheathe/Draw Weapons
|
||||
|
||||
Put on/Remove Helmet
|
||||
|
||||
Sit
|
||||
|
||||
Mount
|
||||
|
||||
Interact
|
||||
|
||||
|
||||
Basic Attack
|
||||
Secondary Attack/Block/Aim
|
||||
|
||||
|
||||
Skillbar Slot 1
|
||||
Skillbar Slot 2
|
||||
Skillbar Slot 3
|
||||
Skillbar Slot 4
|
||||
Skillbar Slot 5
|
||||
Skillbar Slot 6
|
||||
Skillbar Slot 7
|
||||
Skillbar Slot 8
|
||||
Skillbar Slot 9
|
||||
Skillbar Slot 10
|
||||
|
||||
|
||||
Pause Menu
|
||||
Settings
|
||||
Social
|
||||
Map
|
||||
Spellbook
|
||||
Character
|
||||
Questlog
|
||||
Bag
|
||||
|
||||
|
||||
|
||||
Send Chat Message
|
||||
Scroll Chat
|
||||
|
||||
|
||||
Free look
|
||||
|
||||
|
||||
Chat commands:
|
||||
|
||||
/alias [Name] - Change your Chat Name
|
||||
/tp [Name] - Teleports you to another player
|
||||
/jump <dx> <dy> <dz> - Offset your position
|
||||
/goto <x> <y> <z> - Teleport to a position
|
||||
/kill - Kill yourself
|
||||
/pig - Spawn pig NPC
|
||||
/wolf - Spawn wolf NPC
|
||||
/help - Display chat commands"#,
|
||||
"hud.settings.awaitingkey": "Press a key...",
|
||||
|
||||
"hud.social": "Social",
|
||||
"hud.social.online": "Online",
|
||||
@ -348,6 +265,48 @@ Chat commands:
|
||||
/// End HUD section
|
||||
|
||||
|
||||
/// Start GameInput section
|
||||
|
||||
"gameinput.primary": "Basic Attack",
|
||||
"gameinput.secondary": "Secondary Attack/Block/Aim",
|
||||
"gameinput.ability3": "Hotbar Slot 1",
|
||||
"gameinput.swaploadout": "Swap Loadout",
|
||||
"gameinput.togglecursor": "Free Cursor",
|
||||
"gameinput.help": "Toggle Help Window",
|
||||
"gameinput.toggleinterface": "Toggle Interface",
|
||||
"gameinput.toggledebug": "Toggle FPS and Debug Info",
|
||||
"gameinput.screenshot": "Take Screenshot",
|
||||
"gameinput.toggleingameui": "Toggle Nametags",
|
||||
"gameinput.fullscreen": "Toggle Fullscreen",
|
||||
"gameinput.moveforward": "Move Forward",
|
||||
"gameinput.moveleft": "Move Left",
|
||||
"gameinput.moveright": "Move Right",
|
||||
"gameinput.moveback": "Move Backwards",
|
||||
"gameinput.jump": "Jump",
|
||||
"gameinput.glide": "Glider",
|
||||
"gameinput.roll": "Roll",
|
||||
"gameinput.climb": "Climb",
|
||||
"gameinput.climbdown": "Climb Down",
|
||||
"gameinput.wallleap": "Wall Leap",
|
||||
"gameinput.mount": "Mount",
|
||||
"gameinput.enter": "Enter",
|
||||
"gameinput.command": "Command",
|
||||
"gameinput.escape": "Escape",
|
||||
"gameinput.map": "Map",
|
||||
"gameinput.bag": "Bag",
|
||||
"gameinput.social": "Social",
|
||||
"gameinput.sit": "Sit",
|
||||
"gameinput.spellbook": "Spell Book",
|
||||
"gameinput.settings": "Settings",
|
||||
"gameinput.respawn": "Respawn",
|
||||
"gameinput.charge": "Charge",
|
||||
"gameinput.togglewield": "Toggle Wield",
|
||||
"gameinput.interact": "Interact",
|
||||
"gameinput.freelook": "Free look behavior",
|
||||
|
||||
/// End GameInput section
|
||||
|
||||
|
||||
/// Start chracter selection section
|
||||
"char_selection.delete_permanently": "Permanently delete this Character?",
|
||||
"char_selection.change_server": "Change Server",
|
||||
|
@ -237,6 +237,7 @@ pub enum Event {
|
||||
Logout,
|
||||
Quit,
|
||||
ChangeLanguage(LanguageMetadata),
|
||||
ChangeBinding(GameInput),
|
||||
ChangeFreeLookBehavior(PressBehavior),
|
||||
}
|
||||
|
||||
@ -1494,66 +1495,70 @@ impl Hud {
|
||||
.set(self.ids.num_figures, ui_widgets);
|
||||
|
||||
// Help Window
|
||||
Text::new(
|
||||
&self
|
||||
.voxygen_i18n
|
||||
.get("hud.press_key_to_toggle_keybindings_fmt")
|
||||
.replace(
|
||||
"{key}",
|
||||
&format!("{:?}", global_state.settings.controls.help),
|
||||
),
|
||||
)
|
||||
.color(TEXT_COLOR)
|
||||
.down_from(self.ids.num_figures, 5.0)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.set(self.ids.help_info, ui_widgets);
|
||||
if let Some(help_key) = global_state.settings.controls.get_binding(GameInput::Help) {
|
||||
Text::new(
|
||||
&self
|
||||
.voxygen_i18n
|
||||
.get("hud.press_key_to_toggle_keybindings_fmt")
|
||||
.replace("{key}", help_key.to_string().as_str()),
|
||||
)
|
||||
.color(TEXT_COLOR)
|
||||
.down_from(self.ids.num_figures, 5.0)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.set(self.ids.help_info, ui_widgets);
|
||||
}
|
||||
// Info about Debug Shortcut
|
||||
Text::new(
|
||||
&self
|
||||
.voxygen_i18n
|
||||
.get("hud.press_key_to_toggle_debug_info_fmt")
|
||||
.replace(
|
||||
"{key}",
|
||||
&format!("{:?}", global_state.settings.controls.toggle_debug),
|
||||
),
|
||||
)
|
||||
.color(TEXT_COLOR)
|
||||
.down_from(self.ids.help_info, 5.0)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.set(self.ids.debug_info, ui_widgets);
|
||||
if let Some(toggle_debug_key) = global_state
|
||||
.settings
|
||||
.controls
|
||||
.get_binding(GameInput::ToggleDebug)
|
||||
{
|
||||
Text::new(
|
||||
&self
|
||||
.voxygen_i18n
|
||||
.get("hud.press_key_to_toggle_debug_info_fmt")
|
||||
.replace("{key}", toggle_debug_key.to_string().as_str()),
|
||||
)
|
||||
.color(TEXT_COLOR)
|
||||
.down_from(self.ids.help_info, 5.0)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(14))
|
||||
.set(self.ids.debug_info, ui_widgets);
|
||||
}
|
||||
} else {
|
||||
// Help Window
|
||||
Text::new(
|
||||
&self
|
||||
.voxygen_i18n
|
||||
.get("hud.press_key_to_show_keybindings_fmt")
|
||||
.replace(
|
||||
"{key}",
|
||||
&format!("{:?}", global_state.settings.controls.help),
|
||||
),
|
||||
)
|
||||
.color(TEXT_COLOR)
|
||||
.top_left_with_margins_on(ui_widgets.window, 5.0, 5.0)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(16))
|
||||
.set(self.ids.help_info, ui_widgets);
|
||||
if let Some(help_key) = global_state.settings.controls.get_binding(GameInput::Help) {
|
||||
Text::new(
|
||||
&self
|
||||
.voxygen_i18n
|
||||
.get("hud.press_key_to_show_keybindings_fmt")
|
||||
.replace("{key}", help_key.to_string().as_str()),
|
||||
)
|
||||
.color(TEXT_COLOR)
|
||||
.top_left_with_margins_on(ui_widgets.window, 5.0, 5.0)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(16))
|
||||
.set(self.ids.help_info, ui_widgets);
|
||||
}
|
||||
// Info about Debug Shortcut
|
||||
Text::new(
|
||||
&self
|
||||
.voxygen_i18n
|
||||
.get("hud.press_key_to_show_debug_info_fmt")
|
||||
.replace(
|
||||
"{key}",
|
||||
&format!("{:?}", global_state.settings.controls.toggle_debug),
|
||||
),
|
||||
)
|
||||
.color(TEXT_COLOR)
|
||||
.down_from(self.ids.help_info, 5.0)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(12))
|
||||
.set(self.ids.debug_info, ui_widgets);
|
||||
if let Some(toggle_debug_key) = global_state
|
||||
.settings
|
||||
.controls
|
||||
.get_binding(GameInput::ToggleDebug)
|
||||
{
|
||||
Text::new(
|
||||
&self
|
||||
.voxygen_i18n
|
||||
.get("hud.press_key_to_show_debug_info_fmt")
|
||||
.replace("{key}", toggle_debug_key.to_string().as_str()),
|
||||
)
|
||||
.color(TEXT_COLOR)
|
||||
.down_from(self.ids.help_info, 5.0)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(12))
|
||||
.set(self.ids.debug_info, ui_widgets);
|
||||
}
|
||||
}
|
||||
|
||||
// Help Text
|
||||
@ -1822,6 +1827,9 @@ impl Hud {
|
||||
settings_window::Event::AdjustWindowSize(new_size) => {
|
||||
events.push(Event::AdjustWindowSize(new_size));
|
||||
},
|
||||
settings_window::Event::ChangeBinding(game_input) => {
|
||||
events.push(Event::ChangeBinding(game_input));
|
||||
},
|
||||
settings_window::Event::ChangeFreeLookBehavior(behavior) => {
|
||||
events.push(Event::ChangeFreeLookBehavior(behavior));
|
||||
},
|
||||
|
@ -6,12 +6,15 @@ use crate::{
|
||||
i18n::{list_localizations, LanguageMetadata, VoxygenLocalization},
|
||||
render::{AaMode, CloudMode, FluidMode},
|
||||
ui::{fonts::ConrodVoxygenFonts, ImageSlider, ScaleMode, ToggleButton},
|
||||
window::GameInput,
|
||||
GlobalState,
|
||||
};
|
||||
use conrod_core::{
|
||||
color,
|
||||
position::Relative,
|
||||
widget::{self, Button, DropDownList, Image, Rectangle, Scrollbar, Text},
|
||||
widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon,
|
||||
widget_ids, Borderable, Color, Colorable, Labelable, Positionable, Sizeable, Widget,
|
||||
WidgetCommon,
|
||||
};
|
||||
|
||||
const FPS_CHOICES: [u32; 11] = [15, 30, 40, 50, 60, 90, 120, 144, 240, 300, 500];
|
||||
@ -27,8 +30,9 @@ widget_ids! {
|
||||
settings_r,
|
||||
settings_l,
|
||||
settings_scrollbar,
|
||||
controls_text,
|
||||
controls_controls,
|
||||
controls_texts[],
|
||||
controls_buttons[],
|
||||
controls_alignment_rectangle,
|
||||
button_help,
|
||||
button_help2,
|
||||
show_help_label,
|
||||
@ -221,6 +225,7 @@ pub enum Event {
|
||||
SctPlayerBatch(bool),
|
||||
SctDamageBatch(bool),
|
||||
ChangeLanguage(LanguageMetadata),
|
||||
ChangeBinding(GameInput),
|
||||
ChangeFreeLookBehavior(PressBehavior),
|
||||
}
|
||||
|
||||
@ -1328,142 +1333,86 @@ impl<'a> Widget for SettingsWindow<'a> {
|
||||
// Contents
|
||||
if let SettingsTab::Controls = self.show.settings_tab {
|
||||
let controls = &self.global_state.settings.controls;
|
||||
Text::new(&self.localized_strings.get("hud.settings.control_names"))
|
||||
.color(TEXT_COLOR)
|
||||
.top_left_with_margins_on(state.ids.settings_content, 5.0, 5.0)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(18))
|
||||
.set(state.ids.controls_text, ui);
|
||||
// TODO: Replace with buttons that show actual keybinds and allow the user to
|
||||
// change them.
|
||||
#[rustfmt::skip]
|
||||
Text::new(&format!(
|
||||
"{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
\n\
|
||||
\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
\n\
|
||||
{}\n\
|
||||
\n\
|
||||
{}\n\
|
||||
\n\
|
||||
{}\n\
|
||||
\n\
|
||||
{}\n\
|
||||
\n\
|
||||
{}\n\
|
||||
\n\
|
||||
{}\n\
|
||||
\n\
|
||||
{}\n\
|
||||
\n\
|
||||
{}\n\
|
||||
\n\
|
||||
{}\n\
|
||||
\n\
|
||||
{}\n\
|
||||
\n\
|
||||
{}\n\
|
||||
\n\
|
||||
{}\n\
|
||||
\n\
|
||||
\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
\n\
|
||||
\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
\n\
|
||||
\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
{}\n\
|
||||
{}\n\
|
||||
\n\
|
||||
\n\
|
||||
{}\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
\n\
|
||||
",
|
||||
controls.toggle_cursor,
|
||||
controls.help,
|
||||
controls.toggle_interface,
|
||||
controls.toggle_debug,
|
||||
controls.screenshot,
|
||||
controls.toggle_ingame_ui,
|
||||
controls.fullscreen,
|
||||
controls.move_forward,
|
||||
controls.move_left,
|
||||
controls.move_back,
|
||||
controls.move_right,
|
||||
controls.jump,
|
||||
controls.glide,
|
||||
"??", // Dodge
|
||||
controls.roll,
|
||||
controls.climb,
|
||||
controls.climb_down,
|
||||
"??", // Auto Walk
|
||||
controls.toggle_wield,
|
||||
"??", // Put on/Remove Helmet
|
||||
controls.sit,
|
||||
controls.mount,
|
||||
controls.interact,
|
||||
controls.primary,
|
||||
controls.secondary,
|
||||
"1", // Skillbar Slot 1
|
||||
"2", // Skillbar Slot 2
|
||||
"3", // Skillbar Slot 3
|
||||
"4", // Skillbar Slot 4
|
||||
"5", // Skillbar Slot 5
|
||||
"6", // Skillbar Slot 6
|
||||
"7", // Skillbar Slot 7
|
||||
"8", // Skillbar Slot 8
|
||||
"9", // Skillbar Slot 9
|
||||
"0", // Skillbar Slot 10
|
||||
controls.escape,
|
||||
controls.settings,
|
||||
controls.social,
|
||||
controls.map,
|
||||
controls.spellbook,
|
||||
//controls.character_window,
|
||||
//controls.quest_log,
|
||||
controls.bag,
|
||||
controls.enter,
|
||||
"Mouse Wheel", // Scroll chat
|
||||
controls.free_look
|
||||
))
|
||||
.color(TEXT_COLOR)
|
||||
.right_from(state.ids.controls_text, 0.0)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(18))
|
||||
.set(state.ids.controls_controls, ui);
|
||||
if controls.keybindings.len() > state.ids.controls_texts.len()
|
||||
|| controls.keybindings.len() > state.ids.controls_buttons.len()
|
||||
{
|
||||
state.update(|s| {
|
||||
s.ids
|
||||
.controls_texts
|
||||
.resize(controls.keybindings.len(), &mut ui.widget_id_generator());
|
||||
s.ids
|
||||
.controls_buttons
|
||||
.resize(controls.keybindings.len(), &mut ui.widget_id_generator());
|
||||
});
|
||||
}
|
||||
// Used for sequential placement in a flow-down pattern
|
||||
let mut previous_text_id = None;
|
||||
let mut keybindings_vec: Vec<&GameInput> = controls.keybindings.keys().collect();
|
||||
keybindings_vec.sort();
|
||||
// Loop all existing keybindings and the ids for text and button widgets
|
||||
for (game_input, (&text_id, &button_id)) in keybindings_vec.into_iter().zip(
|
||||
state
|
||||
.ids
|
||||
.controls_texts
|
||||
.iter()
|
||||
.zip(state.ids.controls_buttons.iter()),
|
||||
) {
|
||||
if let Some(key) = controls.get_binding(*game_input) {
|
||||
let loc_key = self
|
||||
.localized_strings
|
||||
.get(game_input.get_localization_key());
|
||||
let key_string = match self.global_state.window.remapping_keybindings {
|
||||
Some(game_input_binding) => {
|
||||
if *game_input == game_input_binding {
|
||||
String::from(self.localized_strings.get("hud.settings.awaitingkey"))
|
||||
} else {
|
||||
key.to_string()
|
||||
}
|
||||
},
|
||||
None => key.to_string(),
|
||||
};
|
||||
|
||||
let text_widget = Text::new(loc_key)
|
||||
.color(TEXT_COLOR)
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.font_size(self.fonts.cyri.scale(18));
|
||||
let button_widget = Button::new()
|
||||
.label(&key_string)
|
||||
.label_color(TEXT_COLOR)
|
||||
.label_font_id(self.fonts.cyri.conrod_id)
|
||||
.label_font_size(self.fonts.cyri.scale(15))
|
||||
.w(150.0)
|
||||
.rgba(0.0, 0.0, 0.0, 0.0)
|
||||
.border_rgba(0.0, 0.0, 0.0, 255.0)
|
||||
.label_y(Relative::Scalar(3.0));
|
||||
// Place top-left if it's the first text, else under the previous one
|
||||
let text_widget = match previous_text_id {
|
||||
None => text_widget.top_left_with_margins_on(
|
||||
state.ids.settings_content,
|
||||
10.0,
|
||||
5.0,
|
||||
),
|
||||
Some(prev_id) => text_widget.down_from(prev_id, 10.0),
|
||||
};
|
||||
let text_width = text_widget.get_w(ui).unwrap_or(0.0);
|
||||
text_widget.set(text_id, ui);
|
||||
if button_widget
|
||||
.right_from(text_id, 350.0 - text_width)
|
||||
.set(button_id, ui)
|
||||
.was_clicked()
|
||||
{
|
||||
events.push(Event::ChangeBinding(*game_input));
|
||||
}
|
||||
// Set the previous id to the current one for the next cycle
|
||||
previous_text_id = Some(text_id);
|
||||
}
|
||||
}
|
||||
// Add an empty text widget to simulate some bottom margin, because conrod sucks
|
||||
if let Some(prev_id) = previous_text_id {
|
||||
Rectangle::fill_with([1.0, 1.0], color::TRANSPARENT)
|
||||
.down_from(prev_id, 10.0)
|
||||
.set(state.ids.controls_alignment_rectangle, ui);
|
||||
}
|
||||
}
|
||||
|
||||
// 4) Video Tab -----------------------------------
|
||||
|
@ -5,6 +5,7 @@ use super::{
|
||||
use crate::{
|
||||
i18n::{i18n_asset_key, VoxygenLocalization},
|
||||
ui::fonts::ConrodVoxygenFonts,
|
||||
window::GameInput,
|
||||
GlobalState,
|
||||
};
|
||||
use common::{
|
||||
@ -300,36 +301,45 @@ impl<'a> Widget for Skillbar<'a> {
|
||||
.set(state.ids.level_down, ui);
|
||||
// Death message
|
||||
if self.stats.is_dead {
|
||||
Text::new(&localized_strings.get("hud.you_died"))
|
||||
.middle_of(ui.window)
|
||||
.font_size(self.fonts.cyri.scale(50))
|
||||
if let Some(key) = self
|
||||
.global_state
|
||||
.settings
|
||||
.controls
|
||||
.get_binding(GameInput::Respawn)
|
||||
{
|
||||
Text::new(&localized_strings.get("hud.you_died"))
|
||||
.middle_of(ui.window)
|
||||
.font_size(self.fonts.cyri.scale(50))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(0.0, 0.0, 0.0, 1.0))
|
||||
.set(state.ids.death_message_1_bg, ui);
|
||||
Text::new(
|
||||
&localized_strings
|
||||
.get("hud.press_key_to_respawn")
|
||||
.replace("{key}", key.to_string().as_str()),
|
||||
)
|
||||
.mid_bottom_with_margin_on(state.ids.death_message_1_bg, -120.0)
|
||||
.font_size(self.fonts.cyri.scale(30))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(0.0, 0.0, 0.0, 1.0))
|
||||
.set(state.ids.death_message_1_bg, ui);
|
||||
Text::new(&localized_strings.get("hud.press_key_to_respawn").replace(
|
||||
"{key}",
|
||||
&format!("{:?}", self.global_state.settings.controls.respawn),
|
||||
))
|
||||
.mid_bottom_with_margin_on(state.ids.death_message_1_bg, -120.0)
|
||||
.font_size(self.fonts.cyri.scale(30))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(Color::Rgba(0.0, 0.0, 0.0, 1.0))
|
||||
.set(state.ids.death_message_2_bg, ui);
|
||||
Text::new(&localized_strings.get("hud.you_died"))
|
||||
.bottom_left_with_margins_on(state.ids.death_message_1_bg, 2.0, 2.0)
|
||||
.font_size(self.fonts.cyri.scale(50))
|
||||
.set(state.ids.death_message_2_bg, ui);
|
||||
Text::new(&localized_strings.get("hud.you_died"))
|
||||
.bottom_left_with_margins_on(state.ids.death_message_1_bg, 2.0, 2.0)
|
||||
.font_size(self.fonts.cyri.scale(50))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(CRITICAL_HP_COLOR)
|
||||
.set(state.ids.death_message_1, ui);
|
||||
Text::new(
|
||||
&localized_strings
|
||||
.get("hud.press_key_to_respawn")
|
||||
.replace("{key}", key.to_string().as_str()),
|
||||
)
|
||||
.bottom_left_with_margins_on(state.ids.death_message_2_bg, 2.0, 2.0)
|
||||
.font_size(self.fonts.cyri.scale(30))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(CRITICAL_HP_COLOR)
|
||||
.set(state.ids.death_message_1, ui);
|
||||
Text::new(&localized_strings.get("hud.press_key_to_respawn").replace(
|
||||
"{key}",
|
||||
&format!("{:?}", self.global_state.settings.controls.respawn),
|
||||
))
|
||||
.bottom_left_with_margins_on(state.ids.death_message_2_bg, 2.0, 2.0)
|
||||
.font_size(self.fonts.cyri.scale(30))
|
||||
.font_id(self.fonts.cyri.conrod_id)
|
||||
.color(CRITICAL_HP_COLOR)
|
||||
.set(state.ids.death_message_2, ui);
|
||||
.set(state.ids.death_message_2, ui);
|
||||
}
|
||||
}
|
||||
// Experience-Bar
|
||||
match self.global_state.settings.gameplay.xp_bar {
|
||||
|
@ -713,6 +713,9 @@ impl PlayState for SessionState {
|
||||
global_state.settings.graphics.window_size = new_size;
|
||||
global_state.settings.save_to_file_warn();
|
||||
},
|
||||
HudEvent::ChangeBinding(game_input) => {
|
||||
global_state.window.set_keybinding_mode(game_input);
|
||||
},
|
||||
HudEvent::ChangeFreeLookBehavior(behavior) => {
|
||||
global_state.settings.gameplay.free_look_behavior = behavior;
|
||||
},
|
||||
|
@ -3,7 +3,7 @@ use crate::{
|
||||
i18n,
|
||||
render::{AaMode, CloudMode, FluidMode},
|
||||
ui::ScaleMode,
|
||||
window::KeyMouse,
|
||||
window::{GameInput, KeyMouse},
|
||||
};
|
||||
use directories::{ProjectDirs, UserDirs};
|
||||
use glutin::{MouseButton, VirtualKeyCode};
|
||||
@ -12,46 +12,47 @@ use log::warn;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::{fs, io::prelude::*, path::PathBuf};
|
||||
|
||||
// ControlSetting-like struct used by Serde, to handle not serializing/building
|
||||
// post-deserializing the inverse_keybindings hashmap
|
||||
#[derive(Serialize, Deserialize)]
|
||||
struct ControlSettingsSerde {
|
||||
keybindings: HashMap<GameInput, KeyMouse>,
|
||||
}
|
||||
|
||||
impl From<ControlSettings> for ControlSettingsSerde {
|
||||
fn from(control_settings: ControlSettings) -> Self {
|
||||
let mut user_bindings: HashMap<GameInput, KeyMouse> = HashMap::new();
|
||||
// Do a delta between default() ControlSettings and the argument, and let
|
||||
// keybindings be only the custom keybindings chosen by the user.
|
||||
for (k, v) in control_settings.keybindings {
|
||||
if ControlSettings::default_binding(k) != v {
|
||||
// Keybinding chosen by the user
|
||||
user_bindings.insert(k, v);
|
||||
}
|
||||
}
|
||||
ControlSettingsSerde {
|
||||
keybindings: user_bindings,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// `ControlSettings` contains keybindings.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[serde(default)]
|
||||
#[serde(from = "ControlSettingsSerde", into = "ControlSettingsSerde")]
|
||||
pub struct ControlSettings {
|
||||
pub primary: KeyMouse,
|
||||
pub secondary: KeyMouse,
|
||||
pub ability3: KeyMouse,
|
||||
pub toggle_cursor: KeyMouse,
|
||||
pub escape: KeyMouse,
|
||||
pub enter: KeyMouse,
|
||||
pub command: KeyMouse,
|
||||
pub move_forward: KeyMouse,
|
||||
pub move_left: KeyMouse,
|
||||
pub move_back: KeyMouse,
|
||||
pub move_right: KeyMouse,
|
||||
pub jump: KeyMouse,
|
||||
pub sit: KeyMouse,
|
||||
pub glide: KeyMouse,
|
||||
pub climb: KeyMouse,
|
||||
pub climb_down: KeyMouse,
|
||||
pub wall_leap: KeyMouse,
|
||||
pub mount: KeyMouse,
|
||||
pub map: KeyMouse,
|
||||
pub bag: KeyMouse,
|
||||
pub social: KeyMouse,
|
||||
pub spellbook: KeyMouse,
|
||||
pub settings: KeyMouse,
|
||||
pub help: KeyMouse,
|
||||
pub toggle_interface: KeyMouse,
|
||||
pub toggle_debug: KeyMouse,
|
||||
pub fullscreen: KeyMouse,
|
||||
pub screenshot: KeyMouse,
|
||||
pub toggle_ingame_ui: KeyMouse,
|
||||
pub roll: KeyMouse,
|
||||
pub respawn: KeyMouse,
|
||||
pub interact: KeyMouse,
|
||||
pub toggle_wield: KeyMouse,
|
||||
pub swap_loadout: KeyMouse,
|
||||
pub charge: KeyMouse,
|
||||
pub free_look: KeyMouse,
|
||||
pub keybindings: HashMap<GameInput, KeyMouse>,
|
||||
pub inverse_keybindings: HashMap<KeyMouse, HashSet<GameInput>>, // used in event loop
|
||||
}
|
||||
|
||||
impl From<ControlSettingsSerde> for ControlSettings {
|
||||
fn from(control_serde: ControlSettingsSerde) -> Self {
|
||||
let user_keybindings = control_serde.keybindings;
|
||||
let mut control_settings = ControlSettings::default();
|
||||
for (k, v) in user_keybindings {
|
||||
control_settings.modify_binding(k, v);
|
||||
}
|
||||
control_settings
|
||||
}
|
||||
}
|
||||
|
||||
/// Since Macbook trackpads lack middle click, on OS X we default to LShift
|
||||
@ -64,46 +65,135 @@ const MIDDLE_CLICK_KEY: KeyMouse = KeyMouse::Key(VirtualKeyCode::LShift);
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
const MIDDLE_CLICK_KEY: KeyMouse = KeyMouse::Mouse(MouseButton::Middle);
|
||||
|
||||
impl ControlSettings {
|
||||
pub fn get_binding(&self, game_input: GameInput) -> Option<KeyMouse> {
|
||||
self.keybindings.get(&game_input).copied()
|
||||
}
|
||||
|
||||
pub fn get_associated_game_inputs(&self, key_mouse: &KeyMouse) -> Option<&HashSet<GameInput>> {
|
||||
self.inverse_keybindings.get(key_mouse)
|
||||
}
|
||||
|
||||
pub fn insert_binding(&mut self, game_input: GameInput, key_mouse: KeyMouse) {
|
||||
self.keybindings.insert(game_input, key_mouse);
|
||||
self.inverse_keybindings
|
||||
.entry(key_mouse)
|
||||
.or_default()
|
||||
.insert(game_input);
|
||||
}
|
||||
|
||||
pub fn modify_binding(&mut self, game_input: GameInput, key_mouse: KeyMouse) {
|
||||
// For the KeyMouse->GameInput hashmap, we first need to remove the GameInput
|
||||
// from the old binding
|
||||
if let Some(old_binding) = self.get_binding(game_input) {
|
||||
self.inverse_keybindings
|
||||
.entry(old_binding)
|
||||
.or_default()
|
||||
.remove(&game_input);
|
||||
}
|
||||
// then we add the GameInput to the proper key
|
||||
self.inverse_keybindings
|
||||
.entry(key_mouse)
|
||||
.or_default()
|
||||
.insert(game_input);
|
||||
// For the GameInput->KeyMouse hashmap, just overwrite the value
|
||||
self.keybindings.insert(game_input, key_mouse);
|
||||
}
|
||||
|
||||
pub fn default_binding(game_input: GameInput) -> KeyMouse {
|
||||
// If a new GameInput is added, be sure to update ControlSettings::default()
|
||||
// too!
|
||||
match game_input {
|
||||
GameInput::Primary => KeyMouse::Mouse(MouseButton::Left),
|
||||
GameInput::Secondary => KeyMouse::Mouse(MouseButton::Right),
|
||||
GameInput::ToggleCursor => KeyMouse::Key(VirtualKeyCode::Tab),
|
||||
GameInput::Escape => KeyMouse::Key(VirtualKeyCode::Escape),
|
||||
GameInput::Enter => KeyMouse::Key(VirtualKeyCode::Return),
|
||||
GameInput::Command => KeyMouse::Key(VirtualKeyCode::Slash),
|
||||
GameInput::MoveForward => KeyMouse::Key(VirtualKeyCode::W),
|
||||
GameInput::MoveLeft => KeyMouse::Key(VirtualKeyCode::A),
|
||||
GameInput::MoveBack => KeyMouse::Key(VirtualKeyCode::S),
|
||||
GameInput::MoveRight => KeyMouse::Key(VirtualKeyCode::D),
|
||||
GameInput::Jump => KeyMouse::Key(VirtualKeyCode::Space),
|
||||
GameInput::Sit => KeyMouse::Key(VirtualKeyCode::K),
|
||||
GameInput::Glide => KeyMouse::Key(VirtualKeyCode::LShift),
|
||||
GameInput::Climb => KeyMouse::Key(VirtualKeyCode::Space),
|
||||
GameInput::ClimbDown => KeyMouse::Key(VirtualKeyCode::LControl),
|
||||
GameInput::WallLeap => MIDDLE_CLICK_KEY,
|
||||
GameInput::Mount => KeyMouse::Key(VirtualKeyCode::F),
|
||||
GameInput::Map => KeyMouse::Key(VirtualKeyCode::M),
|
||||
GameInput::Bag => KeyMouse::Key(VirtualKeyCode::B),
|
||||
GameInput::Social => KeyMouse::Key(VirtualKeyCode::O),
|
||||
GameInput::Spellbook => KeyMouse::Key(VirtualKeyCode::P),
|
||||
GameInput::Settings => KeyMouse::Key(VirtualKeyCode::N),
|
||||
GameInput::Help => KeyMouse::Key(VirtualKeyCode::F1),
|
||||
GameInput::ToggleInterface => KeyMouse::Key(VirtualKeyCode::F2),
|
||||
GameInput::ToggleDebug => KeyMouse::Key(VirtualKeyCode::F3),
|
||||
GameInput::Fullscreen => KeyMouse::Key(VirtualKeyCode::F11),
|
||||
GameInput::Screenshot => KeyMouse::Key(VirtualKeyCode::F4),
|
||||
GameInput::ToggleIngameUi => KeyMouse::Key(VirtualKeyCode::F6),
|
||||
GameInput::Roll => MIDDLE_CLICK_KEY,
|
||||
GameInput::Respawn => KeyMouse::Key(VirtualKeyCode::Space),
|
||||
GameInput::Interact => KeyMouse::Mouse(MouseButton::Right),
|
||||
GameInput::ToggleWield => KeyMouse::Key(VirtualKeyCode::T),
|
||||
GameInput::Charge => KeyMouse::Key(VirtualKeyCode::Key1),
|
||||
GameInput::FreeLook => KeyMouse::Key(VirtualKeyCode::L),
|
||||
GameInput::Ability3 => KeyMouse::Key(VirtualKeyCode::Key1),
|
||||
GameInput::SwapLoadout => KeyMouse::Key(VirtualKeyCode::LAlt),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Default for ControlSettings {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
primary: KeyMouse::Mouse(MouseButton::Left),
|
||||
secondary: KeyMouse::Mouse(MouseButton::Right),
|
||||
ability3: KeyMouse::Key(VirtualKeyCode::Key1),
|
||||
toggle_cursor: KeyMouse::Key(VirtualKeyCode::Tab),
|
||||
escape: KeyMouse::Key(VirtualKeyCode::Escape),
|
||||
enter: KeyMouse::Key(VirtualKeyCode::Return),
|
||||
command: KeyMouse::Key(VirtualKeyCode::Slash),
|
||||
move_forward: KeyMouse::Key(VirtualKeyCode::W),
|
||||
move_left: KeyMouse::Key(VirtualKeyCode::A),
|
||||
move_back: KeyMouse::Key(VirtualKeyCode::S),
|
||||
move_right: KeyMouse::Key(VirtualKeyCode::D),
|
||||
jump: KeyMouse::Key(VirtualKeyCode::Space),
|
||||
sit: KeyMouse::Key(VirtualKeyCode::K),
|
||||
glide: KeyMouse::Key(VirtualKeyCode::LShift),
|
||||
climb: KeyMouse::Key(VirtualKeyCode::Space),
|
||||
climb_down: KeyMouse::Key(VirtualKeyCode::LControl),
|
||||
wall_leap: MIDDLE_CLICK_KEY,
|
||||
mount: KeyMouse::Key(VirtualKeyCode::F),
|
||||
map: KeyMouse::Key(VirtualKeyCode::M),
|
||||
bag: KeyMouse::Key(VirtualKeyCode::B),
|
||||
social: KeyMouse::Key(VirtualKeyCode::O),
|
||||
spellbook: KeyMouse::Key(VirtualKeyCode::P),
|
||||
settings: KeyMouse::Key(VirtualKeyCode::N),
|
||||
help: KeyMouse::Key(VirtualKeyCode::F1),
|
||||
toggle_interface: KeyMouse::Key(VirtualKeyCode::F2),
|
||||
toggle_debug: KeyMouse::Key(VirtualKeyCode::F3),
|
||||
fullscreen: KeyMouse::Key(VirtualKeyCode::F11),
|
||||
screenshot: KeyMouse::Key(VirtualKeyCode::F4),
|
||||
toggle_ingame_ui: KeyMouse::Key(VirtualKeyCode::F6),
|
||||
roll: MIDDLE_CLICK_KEY,
|
||||
respawn: KeyMouse::Key(VirtualKeyCode::Space),
|
||||
interact: KeyMouse::Mouse(MouseButton::Right),
|
||||
toggle_wield: KeyMouse::Key(VirtualKeyCode::T),
|
||||
swap_loadout: KeyMouse::Key(VirtualKeyCode::Q),
|
||||
charge: KeyMouse::Key(VirtualKeyCode::Key1),
|
||||
free_look: KeyMouse::Key(VirtualKeyCode::L),
|
||||
let mut new_settings = Self {
|
||||
keybindings: HashMap::new(),
|
||||
inverse_keybindings: HashMap::new(),
|
||||
};
|
||||
// Sets the initial keybindings for those GameInputs. If a new one is created in
|
||||
// future, you'll have to update default_binding, and you should update this vec
|
||||
// too.
|
||||
let game_inputs = vec![
|
||||
GameInput::Primary,
|
||||
GameInput::Secondary,
|
||||
GameInput::ToggleCursor,
|
||||
GameInput::MoveForward,
|
||||
GameInput::MoveBack,
|
||||
GameInput::MoveLeft,
|
||||
GameInput::MoveRight,
|
||||
GameInput::Jump,
|
||||
GameInput::Sit,
|
||||
GameInput::Glide,
|
||||
GameInput::Climb,
|
||||
GameInput::ClimbDown,
|
||||
GameInput::WallLeap,
|
||||
GameInput::Mount,
|
||||
GameInput::Enter,
|
||||
GameInput::Command,
|
||||
GameInput::Escape,
|
||||
GameInput::Map,
|
||||
GameInput::Bag,
|
||||
GameInput::Social,
|
||||
GameInput::Spellbook,
|
||||
GameInput::Settings,
|
||||
GameInput::ToggleInterface,
|
||||
GameInput::Help,
|
||||
GameInput::ToggleDebug,
|
||||
GameInput::Fullscreen,
|
||||
GameInput::Screenshot,
|
||||
GameInput::ToggleIngameUi,
|
||||
GameInput::Roll,
|
||||
GameInput::Respawn,
|
||||
GameInput::Interact,
|
||||
GameInput::ToggleWield,
|
||||
GameInput::Charge,
|
||||
GameInput::FreeLook,
|
||||
GameInput::Ability3,
|
||||
GameInput::SwapLoadout,
|
||||
];
|
||||
for game_input in game_inputs {
|
||||
new_settings.insert_binding(game_input, ControlSettings::default_binding(game_input));
|
||||
}
|
||||
new_settings
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
controller::*,
|
||||
render::{Renderer, WinColorFmt, WinDepthFmt},
|
||||
settings::Settings,
|
||||
settings::{ControlSettings, Settings},
|
||||
ui, Error,
|
||||
};
|
||||
use gilrs::{EventType, Gilrs};
|
||||
@ -12,7 +12,7 @@ use std::fmt;
|
||||
use vek::*;
|
||||
|
||||
/// Represents a key that the game recognises after input mapping.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
|
||||
pub enum GameInput {
|
||||
Primary,
|
||||
Secondary,
|
||||
@ -34,8 +34,6 @@ pub enum GameInput {
|
||||
Escape,
|
||||
Map,
|
||||
Bag,
|
||||
QuestLog,
|
||||
CharacterWindow,
|
||||
Social,
|
||||
Spellbook,
|
||||
Settings,
|
||||
@ -54,6 +52,49 @@ pub enum GameInput {
|
||||
FreeLook,
|
||||
}
|
||||
|
||||
impl GameInput {
|
||||
pub fn get_localization_key(&self) -> &str {
|
||||
match *self {
|
||||
GameInput::Primary => "gameinput.primary",
|
||||
GameInput::Secondary => "gameinput.secondary",
|
||||
GameInput::ToggleCursor => "gameinput.togglecursor",
|
||||
GameInput::MoveForward => "gameinput.moveforward",
|
||||
GameInput::MoveLeft => "gameinput.moveleft",
|
||||
GameInput::MoveRight => "gameinput.moveright",
|
||||
GameInput::MoveBack => "gameinput.moveback",
|
||||
GameInput::Jump => "gameinput.jump",
|
||||
GameInput::Sit => "gameinput.sit",
|
||||
GameInput::Glide => "gameinput.glide",
|
||||
GameInput::Climb => "gameinput.climb",
|
||||
GameInput::ClimbDown => "gameinput.climbdown",
|
||||
GameInput::WallLeap => "gameinput.wallleap",
|
||||
GameInput::Mount => "gameinput.mount",
|
||||
GameInput::Enter => "gameinput.enter",
|
||||
GameInput::Command => "gameinput.command",
|
||||
GameInput::Escape => "gameinput.escape",
|
||||
GameInput::Map => "gameinput.map",
|
||||
GameInput::Bag => "gameinput.bag",
|
||||
GameInput::Social => "gameinput.social",
|
||||
GameInput::Spellbook => "gameinput.spellbook",
|
||||
GameInput::Settings => "gameinput.settings",
|
||||
GameInput::ToggleInterface => "gameinput.toggleinterface",
|
||||
GameInput::Help => "gameinput.help",
|
||||
GameInput::ToggleDebug => "gameinput.toggledebug",
|
||||
GameInput::Fullscreen => "gameinput.fullscreen",
|
||||
GameInput::Screenshot => "gameinput.screenshot",
|
||||
GameInput::ToggleIngameUi => "gameinput.toggleingameui",
|
||||
GameInput::Roll => "gameinput.roll",
|
||||
GameInput::Respawn => "gameinput.respawn",
|
||||
GameInput::Interact => "gameinput.interact",
|
||||
GameInput::ToggleWield => "gameinput.togglewield",
|
||||
GameInput::Charge => "gameinput.charge",
|
||||
GameInput::FreeLook => "gameinput.freelook",
|
||||
GameInput::Ability3 => "gameinput.ability3",
|
||||
GameInput::SwapLoadout => "gameinput.swaploadout",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a key that the game menus recognise after input mapping
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize, Serialize)]
|
||||
pub enum MenuInput {
|
||||
@ -319,8 +360,8 @@ pub struct Window {
|
||||
pub mouse_y_inversion: bool,
|
||||
fullscreen: bool,
|
||||
needs_refresh_resize: bool,
|
||||
key_map: HashMap<KeyMouse, Vec<GameInput>>,
|
||||
keypress_map: HashMap<GameInput, glutin::ElementState>,
|
||||
pub remapping_keybindings: Option<GameInput>,
|
||||
supplement_events: Vec<Event>,
|
||||
focused: bool,
|
||||
gilrs: Option<Gilrs>,
|
||||
@ -355,116 +396,6 @@ impl Window {
|
||||
)
|
||||
.map_err(|err| Error::BackendError(Box::new(err)))?;
|
||||
|
||||
let mut map: HashMap<_, Vec<_>> = HashMap::new();
|
||||
map.entry(settings.controls.primary)
|
||||
.or_default()
|
||||
.push(GameInput::Primary);
|
||||
map.entry(settings.controls.secondary)
|
||||
.or_default()
|
||||
.push(GameInput::Secondary);
|
||||
map.entry(settings.controls.ability3)
|
||||
.or_default()
|
||||
.push(GameInput::Ability3);
|
||||
map.entry(settings.controls.toggle_cursor)
|
||||
.or_default()
|
||||
.push(GameInput::ToggleCursor);
|
||||
map.entry(settings.controls.escape)
|
||||
.or_default()
|
||||
.push(GameInput::Escape);
|
||||
map.entry(settings.controls.enter)
|
||||
.or_default()
|
||||
.push(GameInput::Enter);
|
||||
map.entry(settings.controls.command)
|
||||
.or_default()
|
||||
.push(GameInput::Command);
|
||||
map.entry(settings.controls.move_forward)
|
||||
.or_default()
|
||||
.push(GameInput::MoveForward);
|
||||
map.entry(settings.controls.move_left)
|
||||
.or_default()
|
||||
.push(GameInput::MoveLeft);
|
||||
map.entry(settings.controls.move_back)
|
||||
.or_default()
|
||||
.push(GameInput::MoveBack);
|
||||
map.entry(settings.controls.move_right)
|
||||
.or_default()
|
||||
.push(GameInput::MoveRight);
|
||||
map.entry(settings.controls.jump)
|
||||
.or_default()
|
||||
.push(GameInput::Jump);
|
||||
map.entry(settings.controls.sit)
|
||||
.or_default()
|
||||
.push(GameInput::Sit);
|
||||
map.entry(settings.controls.glide)
|
||||
.or_default()
|
||||
.push(GameInput::Glide);
|
||||
map.entry(settings.controls.climb)
|
||||
.or_default()
|
||||
.push(GameInput::Climb);
|
||||
map.entry(settings.controls.climb_down)
|
||||
.or_default()
|
||||
.push(GameInput::ClimbDown);
|
||||
map.entry(settings.controls.wall_leap)
|
||||
.or_default()
|
||||
.push(GameInput::WallLeap);
|
||||
map.entry(settings.controls.mount)
|
||||
.or_default()
|
||||
.push(GameInput::Mount);
|
||||
map.entry(settings.controls.map)
|
||||
.or_default()
|
||||
.push(GameInput::Map);
|
||||
map.entry(settings.controls.bag)
|
||||
.or_default()
|
||||
.push(GameInput::Bag);
|
||||
map.entry(settings.controls.social)
|
||||
.or_default()
|
||||
.push(GameInput::Social);
|
||||
map.entry(settings.controls.spellbook)
|
||||
.or_default()
|
||||
.push(GameInput::Spellbook);
|
||||
map.entry(settings.controls.settings)
|
||||
.or_default()
|
||||
.push(GameInput::Settings);
|
||||
map.entry(settings.controls.help)
|
||||
.or_default()
|
||||
.push(GameInput::Help);
|
||||
map.entry(settings.controls.toggle_interface)
|
||||
.or_default()
|
||||
.push(GameInput::ToggleInterface);
|
||||
map.entry(settings.controls.toggle_debug)
|
||||
.or_default()
|
||||
.push(GameInput::ToggleDebug);
|
||||
map.entry(settings.controls.fullscreen)
|
||||
.or_default()
|
||||
.push(GameInput::Fullscreen);
|
||||
map.entry(settings.controls.screenshot)
|
||||
.or_default()
|
||||
.push(GameInput::Screenshot);
|
||||
map.entry(settings.controls.toggle_ingame_ui)
|
||||
.or_default()
|
||||
.push(GameInput::ToggleIngameUi);
|
||||
map.entry(settings.controls.roll)
|
||||
.or_default()
|
||||
.push(GameInput::Roll);
|
||||
map.entry(settings.controls.respawn)
|
||||
.or_default()
|
||||
.push(GameInput::Respawn);
|
||||
map.entry(settings.controls.interact)
|
||||
.or_default()
|
||||
.push(GameInput::Interact);
|
||||
map.entry(settings.controls.toggle_wield)
|
||||
.or_default()
|
||||
.push(GameInput::ToggleWield);
|
||||
map.entry(settings.controls.swap_loadout)
|
||||
.or_default()
|
||||
.push(GameInput::SwapLoadout);
|
||||
map.entry(settings.controls.charge)
|
||||
.or_default()
|
||||
.push(GameInput::Charge);
|
||||
map.entry(settings.controls.free_look)
|
||||
.or_default()
|
||||
.push(GameInput::FreeLook);
|
||||
|
||||
let keypress_map = HashMap::new();
|
||||
|
||||
let gilrs = match Gilrs::new() {
|
||||
@ -510,8 +441,8 @@ impl Window {
|
||||
mouse_y_inversion: settings.gameplay.mouse_y_inversion,
|
||||
fullscreen: false,
|
||||
needs_refresh_resize: false,
|
||||
key_map: map,
|
||||
keypress_map,
|
||||
remapping_keybindings: None,
|
||||
supplement_events: vec![],
|
||||
focused: true,
|
||||
gilrs,
|
||||
@ -543,8 +474,9 @@ impl Window {
|
||||
let cursor_grabbed = self.cursor_grabbed;
|
||||
let renderer = &mut self.renderer;
|
||||
let window = &mut self.window;
|
||||
let remapping_keybindings = &mut self.remapping_keybindings;
|
||||
let focused = &mut self.focused;
|
||||
let key_map = &self.key_map;
|
||||
let controls = &mut settings.controls;
|
||||
let keypress_map = &mut self.keypress_map;
|
||||
let pan_sensitivity = self.pan_sensitivity;
|
||||
let zoom_sensitivity = self.zoom_sensitivity;
|
||||
@ -577,23 +509,27 @@ impl Window {
|
||||
},
|
||||
glutin::WindowEvent::ReceivedCharacter(c) => events.push(Event::Char(c)),
|
||||
glutin::WindowEvent::MouseInput { button, state, .. } => {
|
||||
if let (true, Some(game_inputs)) =
|
||||
(cursor_grabbed, key_map.get(&KeyMouse::Mouse(button)))
|
||||
{
|
||||
if let Some(game_inputs) = Window::map_input(
|
||||
KeyMouse::Mouse(button),
|
||||
controls,
|
||||
remapping_keybindings,
|
||||
) {
|
||||
for game_input in game_inputs {
|
||||
events.push(Event::InputUpdate(
|
||||
*game_input,
|
||||
state == glutin::ElementState::Pressed,
|
||||
));
|
||||
}
|
||||
events.push(Event::MouseButton(button, state));
|
||||
}
|
||||
events.push(Event::MouseButton(button, state));
|
||||
},
|
||||
glutin::WindowEvent::KeyboardInput { input, .. } => match input.virtual_keycode
|
||||
{
|
||||
Some(key) => {
|
||||
let game_inputs = key_map.get(&KeyMouse::Key(key));
|
||||
if let Some(game_inputs) = game_inputs {
|
||||
glutin::WindowEvent::KeyboardInput { input, .. } => {
|
||||
if let Some(key) = input.virtual_keycode {
|
||||
if let Some(game_inputs) = Window::map_input(
|
||||
KeyMouse::Key(key),
|
||||
controls,
|
||||
remapping_keybindings,
|
||||
) {
|
||||
for game_input in game_inputs {
|
||||
match game_input {
|
||||
GameInput::Fullscreen => {
|
||||
@ -631,9 +567,9 @@ impl Window {
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
},
|
||||
|
||||
glutin::WindowEvent::Focused(state) => {
|
||||
*focused = state;
|
||||
events.push(Event::Focused(state));
|
||||
@ -1000,4 +936,33 @@ impl Window {
|
||||
) {
|
||||
map.insert(input, state);
|
||||
}
|
||||
|
||||
// Function used to handle Mouse and Key events. It first checks if we're in
|
||||
// remapping mode for a specific GameInput. If we are, we modify the binding
|
||||
// of that GameInput with the KeyMouse passed. Else, we return an iterator of
|
||||
// the GameInputs for that KeyMouse.
|
||||
fn map_input<'a>(
|
||||
key_mouse: KeyMouse,
|
||||
controls: &'a mut ControlSettings,
|
||||
remapping: &mut Option<GameInput>,
|
||||
) -> Option<impl Iterator<Item = &'a GameInput>> {
|
||||
match *remapping {
|
||||
Some(game_input) => {
|
||||
controls.modify_binding(game_input, key_mouse);
|
||||
*remapping = None;
|
||||
None
|
||||
},
|
||||
None => {
|
||||
if let Some(game_inputs) = controls.get_associated_game_inputs(&key_mouse) {
|
||||
Some(game_inputs.iter())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_keybinding_mode(&mut self, game_input: GameInput) {
|
||||
self.remapping_keybindings = Some(game_input);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user