From 97cc8b1712759d75bc26e2e7b513e9fb62b295ca Mon Sep 17 00:00:00 2001 From: Sofia Date: Sun, 26 Jul 2026 02:03:10 +0300 Subject: [PATCH] Start adding keybinds --- godot/scenes/ui/settings.tscn | 11 ++++- rust/src/game_settings.rs | 71 +++++++++++++++++++++++++++++- rust/src/ui/settings.rs | 82 +++++++++++++++++++++++++++++++++-- 3 files changed, 159 insertions(+), 5 deletions(-) diff --git a/godot/scenes/ui/settings.tscn b/godot/scenes/ui/settings.tscn index ade7db2..280dd02 100644 --- a/godot/scenes/ui/settings.tscn +++ b/godot/scenes/ui/settings.tscn @@ -2,9 +2,10 @@ [ext_resource type="PackedScene" uid="uid://cqiwdajl71ujv" path="res://scenes/ui/slider.tscn" id="1_8wfqe"] -[node name="settings" type="SettingsPanel" unique_id=999912383 node_paths=PackedStringArray("general_grid", "volume_grid")] +[node name="settings" type="SettingsPanel" unique_id=999912383 node_paths=PackedStringArray("general_grid", "volume_grid", "keybinds_grid")] general_grid = NodePath("v_box_container/tab_container/general") volume_grid = NodePath("v_box_container/tab_container/volume") +keybinds_grid = NodePath("v_box_container/tab_container/keybinds") slider_scene = ExtResource("1_8wfqe") anchors_preset = 8 anchor_left = 0.5 @@ -46,6 +47,14 @@ layout_mode = 2 columns = 2 metadata/_tab_index = 1 +[node name="keybinds" type="GridContainer" parent="v_box_container/tab_container" unique_id=852698711] +visible = false +custom_minimum_size = Vector2(400, 0) +custom_maximum_size = Vector2(400, -1) +layout_mode = 2 +columns = 2 +metadata/_tab_index = 2 + [node name="button" type="Button" parent="v_box_container" unique_id=1301469030] layout_mode = 2 size_flags_horizontal = 4 diff --git a/rust/src/game_settings.rs b/rust/src/game_settings.rs index e347a2f..47188a4 100644 --- a/rust/src/game_settings.rs +++ b/rust/src/game_settings.rs @@ -4,7 +4,11 @@ use std::{ }; use godot::{ - classes::{AudioServer, FileAccess, file_access::ModeFlags}, + classes::{ + AudioServer, FileAccess, InputEvent, InputEventKey, InputEventMouse, InputEventMouseButton, + file_access::ModeFlags, + }, + global::{Key, MouseButton}, prelude::*, tools::get_autoload_by_name, }; @@ -23,6 +27,7 @@ pub struct GameSettings { pub default_name: String, pub recent_servers: Vec, pub volume: VolumeSettings, + pub keybinds: KeybindSettings, } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -33,6 +38,60 @@ pub struct VolumeSettings { pub announcer_volume: f64, } +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct KeybindSettings { + pub move_left: Keybind, + pub move_right: Keybind, + pub move_forward: Keybind, + pub move_backward: Keybind, + pub select_raygun: Keybind, + pub select_shotgun: Keybind, + pub shoot: Keybind, + pub melee: Keybind, +} + +#[derive(Clone, Copy, Debug, Serialize, Deserialize)] +pub enum Keybind { + Key(i32), + MouseButton(i32), +} + +impl ToString for Keybind { + fn to_string(&self) -> String { + match self { + Keybind::Key(value) => format!("{:?}", Key::from_godot(*value)), + Keybind::MouseButton(value) => format!("{:?}", MouseButton::from_godot(*value)), + } + } +} + +impl Keybind { + pub fn from_event(event: Gd) -> Option { + if let Ok(key) = event.clone().try_cast::() { + Some(Keybind::Key(key.get_keycode().to_godot())) + } else if let Ok(mouse) = event.clone().try_cast::() { + Some(Keybind::MouseButton(mouse.get_button_index().to_godot())) + } else { + None + } + } + + pub fn into_event(&self) -> Gd { + match self { + Keybind::Key(key) => { + let mut event = InputEventKey::new_gd(); + event.set_keycode(Key::from_godot(*key)); + event.upcast() + } + Keybind::MouseButton(mb) => { + let mut event = InputEventMouseButton::new_gd(); + event.set_button_index(MouseButton::from_godot(*mb)); + event.upcast() + } + } + } +} + impl VolumeSettings { pub fn master(&self) -> f32 { (self.master_volume / 100.) as f32 @@ -69,6 +128,16 @@ impl Default for GameSettings { music_volume: 100., announcer_volume: 100., }, + keybinds: KeybindSettings { + move_left: Keybind::Key(Key::A.to_godot()), + move_right: Keybind::Key(Key::D.to_godot()), + move_forward: Keybind::Key(Key::W.to_godot()), + move_backward: Keybind::Key(Key::S.to_godot()), + select_raygun: Keybind::Key(Key::KEY_1.to_godot()), + select_shotgun: Keybind::Key(Key::KEY_2.to_godot()), + shoot: Keybind::MouseButton(MouseButton::LEFT.to_godot()), + melee: Keybind::Key(Key::F.to_godot()), + }, } } } diff --git a/rust/src/ui/settings.rs b/rust/src/ui/settings.rs index fbf6723..6b5b69d 100644 --- a/rust/src/ui/settings.rs +++ b/rust/src/ui/settings.rs @@ -2,27 +2,44 @@ use std::collections::HashMap; use godot::{ classes::{ - Control, GridContainer, IPanelContainer, Label, LineEdit, PanelContainer, - control::SizeFlags, + Button, Control, GridContainer, IPanelContainer, InputEvent, InputEventKey, InputMap, + Label, LineEdit, PanelContainer, control::SizeFlags, }, prelude::*, }; -use crate::{game_settings::GameSettingsManager, ui::slider::SliderContainer}; +use crate::{ + game_settings::{GameSettingsManager, Keybind}, + ui::slider::SliderContainer, +}; #[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Ord, Eq, Hash)] pub enum Setting { + // General settings FoV, DefaultName, + + // Volume settings MasterVolume, SfxVolume, MusicVolume, AnnouncerVolume, + + // Keybinds + MoveLeft, + MoveForward, + MoveRight, + MoveBackward, + Shoot, + Melee, + SelectRaygun, + SelectShotgun, } pub enum SettingsTab { General, Volume, + Keybinds, } impl ToString for Setting { @@ -30,10 +47,20 @@ impl ToString for Setting { match self { Setting::FoV => "Field of View", Setting::DefaultName => "Default Name", + Setting::MasterVolume => "Master volume", Setting::SfxVolume => "Sfx Volume", Setting::MusicVolume => "Music Volume", Setting::AnnouncerVolume => "Announcer Volume", + + Setting::MoveLeft => "Move left", + Setting::MoveRight => "Move right", + Setting::MoveForward => "Move forward", + Setting::MoveBackward => "Move backward", + Setting::SelectRaygun => "Select Raygun", + Setting::SelectShotgun => "Select Shotgun", + Setting::Shoot => "Shoot", + Setting::Melee => "Melee", } .to_string() } @@ -44,10 +71,13 @@ impl Setting { match self { Setting::FoV => SettingsTab::General, Setting::DefaultName => SettingsTab::General, + Setting::MasterVolume => SettingsTab::Volume, Setting::SfxVolume => SettingsTab::Volume, Setting::MusicVolume => SettingsTab::Volume, Setting::AnnouncerVolume => SettingsTab::Volume, + + _ => SettingsTab::Keybinds, } } } @@ -56,6 +86,7 @@ impl Setting { pub enum SettingValue { SliderNumber(SliderValue), String(String), + Keybind(Keybind), } #[derive(Clone, Copy)] @@ -73,6 +104,8 @@ pub struct SettingsPanel { #[export] volume_grid: Option>, #[export] + keybinds_grid: Option>, + #[export] slider_scene: Option>, settings: HashMap, @@ -130,6 +163,39 @@ impl IPanelContainer for SettingsPanel { }), ); + self.settings.insert( + Setting::MoveForward, + SettingValue::Keybind(settings.keybinds.move_forward), + ); + self.settings.insert( + Setting::MoveBackward, + SettingValue::Keybind(settings.keybinds.move_backward), + ); + self.settings.insert( + Setting::MoveLeft, + SettingValue::Keybind(settings.keybinds.move_left), + ); + self.settings.insert( + Setting::MoveRight, + SettingValue::Keybind(settings.keybinds.move_right), + ); + self.settings.insert( + Setting::SelectRaygun, + SettingValue::Keybind(settings.keybinds.select_raygun), + ); + self.settings.insert( + Setting::SelectShotgun, + SettingValue::Keybind(settings.keybinds.select_shotgun), + ); + self.settings.insert( + Setting::Shoot, + SettingValue::Keybind(settings.keybinds.shoot), + ); + self.settings.insert( + Setting::Melee, + SettingValue::Keybind(settings.keybinds.melee), + ); + let mut keys = self.settings.keys().collect::>(); keys.sort(); @@ -139,6 +205,7 @@ impl IPanelContainer for SettingsPanel { let grid = match setting.tab() { SettingsTab::General => self.general_grid.clone(), SettingsTab::Volume => self.volume_grid.clone(), + SettingsTab::Keybinds => self.keybinds_grid.clone(), }; if let Some(mut grid) = grid { @@ -191,6 +258,13 @@ impl IPanelContainer for SettingsPanel { line_edit.upcast() } + SettingValue::Keybind(value) => { + let mut toggle_button = Button::new_alloc(); + toggle_button.set_text(&value.to_string()); + toggle_button.set_toggle_mode(true); + + toggle_button.upcast() + } }; grid.add_child(&node); @@ -198,6 +272,8 @@ impl IPanelContainer for SettingsPanel { } } } + + fn input(&mut self, event: Gd) {} } #[godot_api]