Compare commits
3 Commits
0ad90d24dd
...
fac936b97a
| Author | SHA1 | Date | |
|---|---|---|---|
| fac936b97a | |||
| b0a4048360 | |||
| 7752a009fe |
@ -5,8 +5,8 @@ use std::{
|
|||||||
|
|
||||||
use godot::{
|
use godot::{
|
||||||
classes::{
|
classes::{
|
||||||
AudioServer, FileAccess, InputEvent, InputEventKey, InputEventMouseButton, InputMap,
|
AudioServer, DisplayServer, FileAccess, InputEvent, InputEventKey, InputEventMouseButton,
|
||||||
file_access::ModeFlags,
|
InputMap, display_server::WindowMode, file_access::ModeFlags,
|
||||||
},
|
},
|
||||||
global::{Key, MouseButton},
|
global::{Key, MouseButton},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
@ -26,6 +26,8 @@ pub struct GameSettings {
|
|||||||
pub fov: f64,
|
pub fov: f64,
|
||||||
pub default_name: String,
|
pub default_name: String,
|
||||||
pub replay_fps: u8,
|
pub replay_fps: u8,
|
||||||
|
pub window_mode: WindowModeSetting,
|
||||||
|
pub render_scale: f32,
|
||||||
pub recent_servers: Vec<RecentServer>,
|
pub recent_servers: Vec<RecentServer>,
|
||||||
pub volume: VolumeSettings,
|
pub volume: VolumeSettings,
|
||||||
pub keybinds: KeybindSettings,
|
pub keybinds: KeybindSettings,
|
||||||
@ -53,6 +55,26 @@ pub struct KeybindSettings {
|
|||||||
pub telegrenade: Keybind,
|
pub telegrenade: Keybind,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, PartialOrd)]
|
||||||
|
pub enum WindowModeSetting {
|
||||||
|
Fullscreen = 0,
|
||||||
|
BorderlessFullscreen,
|
||||||
|
Windowed,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<usize> for WindowModeSetting {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(value: usize) -> Result<Self, Self::Error> {
|
||||||
|
match value {
|
||||||
|
0 => Ok(WindowModeSetting::Fullscreen),
|
||||||
|
1 => Ok(WindowModeSetting::BorderlessFullscreen),
|
||||||
|
2 => Ok(WindowModeSetting::Windowed),
|
||||||
|
_ => Err(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, PartialOrd)]
|
||||||
pub enum Keybind {
|
pub enum Keybind {
|
||||||
Key(i32),
|
Key(i32),
|
||||||
@ -125,6 +147,8 @@ impl Default for GameSettings {
|
|||||||
fov: 90.,
|
fov: 90.,
|
||||||
default_name: "Default McGee".to_owned(),
|
default_name: "Default McGee".to_owned(),
|
||||||
replay_fps: 60,
|
replay_fps: 60,
|
||||||
|
render_scale: 1.,
|
||||||
|
window_mode: WindowModeSetting::Windowed,
|
||||||
recent_servers: Vec::new(),
|
recent_servers: Vec::new(),
|
||||||
volume: VolumeSettings {
|
volume: VolumeSettings {
|
||||||
master_volume: 100.,
|
master_volume: 100.,
|
||||||
@ -166,6 +190,10 @@ impl INode for GameSettingsManager {
|
|||||||
}
|
}
|
||||||
GameSettingsManager { settings, base }
|
GameSettingsManager { settings, base }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ready(&mut self) {
|
||||||
|
self.update_window_mode(&self.settings.window_mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[godot_api]
|
#[godot_api]
|
||||||
@ -194,6 +222,14 @@ impl GameSettingsManager {
|
|||||||
set_keybind("jump", settings.keybinds.jump);
|
set_keybind("jump", settings.keybinds.jump);
|
||||||
set_keybind("throw_telegrenade", settings.keybinds.telegrenade);
|
set_keybind("throw_telegrenade", settings.keybinds.telegrenade);
|
||||||
|
|
||||||
|
if settings.window_mode != self.settings.window_mode {
|
||||||
|
self.update_window_mode(&settings.window_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(mut viewport) = self.base().get_viewport() {
|
||||||
|
viewport.set_scaling_3d_scale(settings.render_scale);
|
||||||
|
}
|
||||||
|
|
||||||
self.settings = settings;
|
self.settings = settings;
|
||||||
if let Some(mut file) = FileAccess::open("user://config.toml", ModeFlags::WRITE) {
|
if let Some(mut file) = FileAccess::open("user://config.toml", ModeFlags::WRITE) {
|
||||||
if let Ok(serialized) = toml::to_string(&self.settings) {
|
if let Ok(serialized) = toml::to_string(&self.settings) {
|
||||||
@ -237,6 +273,15 @@ impl GameSettingsManager {
|
|||||||
};
|
};
|
||||||
self.update_settings(settings);
|
self.update_settings(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_window_mode(&self, window_mode: &WindowModeSetting) {
|
||||||
|
let window_mode = match *window_mode {
|
||||||
|
WindowModeSetting::Fullscreen => WindowMode::EXCLUSIVE_FULLSCREEN,
|
||||||
|
WindowModeSetting::BorderlessFullscreen => WindowMode::EXCLUSIVE_FULLSCREEN,
|
||||||
|
WindowModeSetting::Windowed => WindowMode::WINDOWED,
|
||||||
|
};
|
||||||
|
DisplayServer::singleton().window_set_mode(window_mode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_bus_volume(bus: &str, volume: f32) {
|
fn set_bus_volume(bus: &str, volume: f32) {
|
||||||
|
|||||||
@ -391,11 +391,13 @@ impl ICharacterBody3D for LocalPlayer {
|
|||||||
.connect_other(self, |s, lock| s.set_lock(lock));
|
.connect_other(self, |s, lock| s.set_lock(lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.telegrenades_allowed = if let Some(game) = Game::singleton() {
|
self.run_deferred(|s| {
|
||||||
|
s.telegrenades_allowed = if let Some(game) = Game::singleton() {
|
||||||
game.bind().opts.is_true(GameOption::TelegrenadesAllowed)
|
game.bind().opts.is_true(GameOption::TelegrenadesAllowed)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(&mut self, delta: f64) {
|
fn process(&mut self, delta: f64) {
|
||||||
|
|||||||
@ -309,11 +309,13 @@ impl ICharacterBody3D for RemotePlayer {
|
|||||||
self.swap_weapon(WeaponType::Raygun, false);
|
self.swap_weapon(WeaponType::Raygun, false);
|
||||||
self.update_health_bar();
|
self.update_health_bar();
|
||||||
|
|
||||||
self.telegrenades_allowed = if let Some(game) = Game::singleton() {
|
self.run_deferred(|s| {
|
||||||
|
s.telegrenades_allowed = if let Some(game) = Game::singleton() {
|
||||||
game.bind().opts.is_true(GameOption::TelegrenadesAllowed)
|
game.bind().opts.is_true(GameOption::TelegrenadesAllowed)
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process(&mut self, delta: f64) {
|
fn process(&mut self, delta: f64) {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use std::collections::HashMap;
|
|||||||
|
|
||||||
use godot::{
|
use godot::{
|
||||||
classes::{
|
classes::{
|
||||||
Button, Control, GridContainer, IPanelContainer, InputEvent, Label, LineEdit,
|
Button, Control, GridContainer, IPanelContainer, InputEvent, Label, LineEdit, OptionButton,
|
||||||
PanelContainer,
|
PanelContainer,
|
||||||
control::{FocusBehaviorRecursive, SizeFlags},
|
control::{FocusBehaviorRecursive, SizeFlags},
|
||||||
},
|
},
|
||||||
@ -10,7 +10,7 @@ use godot::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
game_settings::{GameSettings, GameSettingsManager, Keybind},
|
game_settings::{GameSettings, GameSettingsManager, Keybind, WindowModeSetting},
|
||||||
ui::slider::SliderContainer,
|
ui::slider::SliderContainer,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -20,6 +20,8 @@ pub enum Setting {
|
|||||||
FoV,
|
FoV,
|
||||||
DefaultName,
|
DefaultName,
|
||||||
ReplayFPS,
|
ReplayFPS,
|
||||||
|
WindowMode,
|
||||||
|
RenderScale,
|
||||||
|
|
||||||
// Volume settings
|
// Volume settings
|
||||||
MasterVolume,
|
MasterVolume,
|
||||||
@ -52,6 +54,8 @@ impl ToString for Setting {
|
|||||||
Setting::FoV => "Field of View",
|
Setting::FoV => "Field of View",
|
||||||
Setting::DefaultName => "Default Name",
|
Setting::DefaultName => "Default Name",
|
||||||
Setting::ReplayFPS => "Replay FPS",
|
Setting::ReplayFPS => "Replay FPS",
|
||||||
|
Setting::WindowMode => "Window Mode",
|
||||||
|
Setting::RenderScale => "Render Scale",
|
||||||
|
|
||||||
Setting::MasterVolume => "Master volume",
|
Setting::MasterVolume => "Master volume",
|
||||||
Setting::SfxVolume => "Sfx Volume",
|
Setting::SfxVolume => "Sfx Volume",
|
||||||
@ -79,6 +83,8 @@ impl Setting {
|
|||||||
Setting::FoV => SettingsTab::General,
|
Setting::FoV => SettingsTab::General,
|
||||||
Setting::DefaultName => SettingsTab::General,
|
Setting::DefaultName => SettingsTab::General,
|
||||||
Setting::ReplayFPS => SettingsTab::General,
|
Setting::ReplayFPS => SettingsTab::General,
|
||||||
|
Setting::WindowMode => SettingsTab::General,
|
||||||
|
Setting::RenderScale => SettingsTab::General,
|
||||||
|
|
||||||
Setting::MasterVolume => SettingsTab::Volume,
|
Setting::MasterVolume => SettingsTab::Volume,
|
||||||
Setting::SfxVolume => SettingsTab::Volume,
|
Setting::SfxVolume => SettingsTab::Volume,
|
||||||
@ -95,12 +101,20 @@ pub enum SettingValue {
|
|||||||
SliderNumber(SliderValue),
|
SliderNumber(SliderValue),
|
||||||
String(String),
|
String(String),
|
||||||
Keybind(Keybind),
|
Keybind(Keybind),
|
||||||
|
OptionSetting(usize, Vec<OptionSetting>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, PartialOrd)]
|
||||||
|
pub struct OptionSetting {
|
||||||
|
value: usize,
|
||||||
|
text: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
|
||||||
pub struct SliderValue {
|
pub struct SliderValue {
|
||||||
min: f64,
|
min: f64,
|
||||||
max: f64,
|
max: f64,
|
||||||
|
step: f64,
|
||||||
value: f64,
|
value: f64,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,6 +193,7 @@ impl IPanelContainer for SettingsPanel {
|
|||||||
slider.bind_mut().min = slider_value.min;
|
slider.bind_mut().min = slider_value.min;
|
||||||
slider.bind_mut().max = slider_value.max;
|
slider.bind_mut().max = slider_value.max;
|
||||||
slider.bind_mut().value = slider_value.value;
|
slider.bind_mut().value = slider_value.value;
|
||||||
|
slider.bind_mut().step = slider_value.step;
|
||||||
|
|
||||||
let setting_clone = setting.clone();
|
let setting_clone = setting.clone();
|
||||||
let value_clone = slider_value.clone();
|
let value_clone = slider_value.clone();
|
||||||
@ -237,6 +252,30 @@ impl IPanelContainer for SettingsPanel {
|
|||||||
|
|
||||||
toggle_button.upcast()
|
toggle_button.upcast()
|
||||||
}
|
}
|
||||||
|
SettingValue::OptionSetting(value, items) => {
|
||||||
|
let mut option_button = OptionButton::new_alloc();
|
||||||
|
for item in &items {
|
||||||
|
option_button.add_item(&item.text);
|
||||||
|
}
|
||||||
|
option_button.select(value as i32);
|
||||||
|
|
||||||
|
let setting_clone = setting.clone();
|
||||||
|
let items_clone = items.clone();
|
||||||
|
option_button.signals().item_selected().connect_other(
|
||||||
|
self,
|
||||||
|
move |s, i| {
|
||||||
|
s.on_change(
|
||||||
|
setting_clone,
|
||||||
|
SettingValue::OptionSetting(
|
||||||
|
i as usize,
|
||||||
|
items_clone.clone(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
option_button.upcast()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.values.insert(*setting, node.clone());
|
self.values.insert(*setting, node.clone());
|
||||||
@ -283,6 +322,11 @@ impl SettingsPanel {
|
|||||||
self.on_change(setting, new_value);
|
self.on_change(setting, new_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SettingValue::OptionSetting(selected, _) => {
|
||||||
|
if let Ok(mut button) = control.try_cast::<OptionButton>() {
|
||||||
|
button.select(selected as i32);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,6 +352,16 @@ impl SettingsPanel {
|
|||||||
(Setting::ReplayFPS, SettingValue::SliderNumber(value)) => {
|
(Setting::ReplayFPS, SettingValue::SliderNumber(value)) => {
|
||||||
new_settings.replay_fps = value.value as u8;
|
new_settings.replay_fps = value.value as u8;
|
||||||
}
|
}
|
||||||
|
(Setting::WindowMode, SettingValue::OptionSetting(selected, items)) => {
|
||||||
|
if let Some(item) = items.get(*selected) {
|
||||||
|
if let Ok(setting) = WindowModeSetting::try_from(item.value) {
|
||||||
|
new_settings.window_mode = setting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(Setting::RenderScale, SettingValue::SliderNumber(value)) => {
|
||||||
|
new_settings.render_scale = value.value as f32;
|
||||||
|
}
|
||||||
|
|
||||||
(Setting::MasterVolume, SettingValue::SliderNumber(value)) => {
|
(Setting::MasterVolume, SettingValue::SliderNumber(value)) => {
|
||||||
new_settings.volume.master_volume = value.value;
|
new_settings.volume.master_volume = value.value;
|
||||||
@ -377,6 +431,7 @@ fn settings_from(map: &mut HashMap<Setting, SettingValue>, settings: &GameSettin
|
|||||||
SettingValue::SliderNumber(SliderValue {
|
SettingValue::SliderNumber(SliderValue {
|
||||||
min: 60.,
|
min: 60.,
|
||||||
max: 120.,
|
max: 120.,
|
||||||
|
step: 1.,
|
||||||
value: settings.fov,
|
value: settings.fov,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -389,7 +444,37 @@ fn settings_from(map: &mut HashMap<Setting, SettingValue>, settings: &GameSettin
|
|||||||
SettingValue::SliderNumber(SliderValue {
|
SettingValue::SliderNumber(SliderValue {
|
||||||
min: 1.,
|
min: 1.,
|
||||||
max: 240.,
|
max: 240.,
|
||||||
value: 60.,
|
step: 1.,
|
||||||
|
value: settings.replay_fps as f64,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
map.insert(
|
||||||
|
Setting::WindowMode,
|
||||||
|
SettingValue::OptionSetting(
|
||||||
|
settings.window_mode as usize,
|
||||||
|
vec![
|
||||||
|
OptionSetting {
|
||||||
|
value: WindowModeSetting::Fullscreen as usize,
|
||||||
|
text: "Fullscreen".to_string(),
|
||||||
|
},
|
||||||
|
OptionSetting {
|
||||||
|
value: WindowModeSetting::BorderlessFullscreen as usize,
|
||||||
|
text: "Borderless Fullscreen".to_string(),
|
||||||
|
},
|
||||||
|
OptionSetting {
|
||||||
|
value: WindowModeSetting::Windowed as usize,
|
||||||
|
text: "Windowed".to_string(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
map.insert(
|
||||||
|
Setting::RenderScale,
|
||||||
|
SettingValue::SliderNumber(SliderValue {
|
||||||
|
min: 0.25,
|
||||||
|
max: 2.,
|
||||||
|
step: 0.05,
|
||||||
|
value: settings.render_scale as f64,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
map.insert(
|
map.insert(
|
||||||
@ -397,6 +482,7 @@ fn settings_from(map: &mut HashMap<Setting, SettingValue>, settings: &GameSettin
|
|||||||
SettingValue::SliderNumber(SliderValue {
|
SettingValue::SliderNumber(SliderValue {
|
||||||
min: 0.,
|
min: 0.,
|
||||||
max: 100.,
|
max: 100.,
|
||||||
|
step: 1.,
|
||||||
value: settings.volume.master_volume,
|
value: settings.volume.master_volume,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -405,6 +491,7 @@ fn settings_from(map: &mut HashMap<Setting, SettingValue>, settings: &GameSettin
|
|||||||
SettingValue::SliderNumber(SliderValue {
|
SettingValue::SliderNumber(SliderValue {
|
||||||
min: 0.,
|
min: 0.,
|
||||||
max: 100.,
|
max: 100.,
|
||||||
|
step: 1.,
|
||||||
value: settings.volume.sfx_volume,
|
value: settings.volume.sfx_volume,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -413,6 +500,7 @@ fn settings_from(map: &mut HashMap<Setting, SettingValue>, settings: &GameSettin
|
|||||||
SettingValue::SliderNumber(SliderValue {
|
SettingValue::SliderNumber(SliderValue {
|
||||||
min: 0.,
|
min: 0.,
|
||||||
max: 100.,
|
max: 100.,
|
||||||
|
step: 1.,
|
||||||
value: settings.volume.music_volume,
|
value: settings.volume.music_volume,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
@ -421,6 +509,7 @@ fn settings_from(map: &mut HashMap<Setting, SettingValue>, settings: &GameSettin
|
|||||||
SettingValue::SliderNumber(SliderValue {
|
SettingValue::SliderNumber(SliderValue {
|
||||||
min: 0.,
|
min: 0.,
|
||||||
max: 100.,
|
max: 100.,
|
||||||
|
step: 1.,
|
||||||
value: settings.volume.announcer_volume,
|
value: settings.volume.announcer_volume,
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -16,6 +16,8 @@ pub struct SliderContainer {
|
|||||||
pub min: f64,
|
pub min: f64,
|
||||||
#[export]
|
#[export]
|
||||||
pub max: f64,
|
pub max: f64,
|
||||||
|
#[export]
|
||||||
|
pub step: f64,
|
||||||
|
|
||||||
last_value: f64,
|
last_value: f64,
|
||||||
|
|
||||||
@ -30,6 +32,7 @@ impl IHBoxContainer for SliderContainer {
|
|||||||
if let Some(slider) = &mut self.slider {
|
if let Some(slider) = &mut self.slider {
|
||||||
slider.set_min(self.min);
|
slider.set_min(self.min);
|
||||||
slider.set_max(self.max);
|
slider.set_max(self.max);
|
||||||
|
slider.set_step(self.step);
|
||||||
if self.last_value != self.value {
|
if self.last_value != self.value {
|
||||||
slider.set_value(self.value);
|
slider.set_value(self.value);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user