Compare commits
No commits in common. "798dcbc1bda2922706342718cbcb783b4c1d97a6" and "69e609e501f8de7a3d8b4b41a14ae1e2b6c48e78" have entirely different histories.
798dcbc1bd
...
69e609e501
77
Cargo.lock
generated
77
Cargo.lock
generated
@ -41,12 +41,6 @@ version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "gdextension-api"
|
||||
version = "0.5.1"
|
||||
@ -144,28 +138,12 @@ dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.186"
|
||||
@ -203,7 +181,6 @@ dependencies = [
|
||||
"godot",
|
||||
"serde",
|
||||
"teanet",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -245,15 +222,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.119"
|
||||
@ -294,45 +262,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "1.1.3+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53c96ecdfa941c8fc4fcaed14f99ada8ebed502eef533015095a07e3301d4c3c"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde_core",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_parser",
|
||||
"toml_writer",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "1.1.1+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
version = "1.1.2+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526"
|
||||
dependencies = [
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_writer"
|
||||
version = "1.1.2+spec-1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
@ -349,12 +278,6 @@ dependencies = [
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.54"
|
||||
|
||||
@ -83,11 +83,6 @@ shoot={
|
||||
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
|
||||
]
|
||||
}
|
||||
pause={
|
||||
"deadzone": 0.2,
|
||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||
]
|
||||
}
|
||||
|
||||
[physics]
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
[gd_scene format=3 uid="uid://lahirbqfppvw"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bbmc2gmy7g8ag" path="res://scenes/misc/menu_player.tscn" id="1_o5qli"]
|
||||
[ext_resource type="PackedScene" uid="uid://n3u0jr4wiib1" path="res://scenes/ui/settings.tscn" id="2_0wfyh"]
|
||||
|
||||
[node name="menu" type="MainMenu" unique_id=2036763876 node_paths=PackedStringArray("camera", "main_position", "host_position", "main_panel", "host_panel", "join_panel", "host_port", "join_addr", "popup_panel", "popup_title", "popup_text", "popup_button")]
|
||||
camera = NodePath("camera_3d")
|
||||
@ -166,7 +165,6 @@ horizontal_alignment = 1
|
||||
[node name="address_text" type="TextEdit" parent="join_panel/v_box_container" unique_id=584304528]
|
||||
custom_minimum_size = Vector2(150, 30)
|
||||
layout_mode = 2
|
||||
text = "127.0.0.1:8080"
|
||||
|
||||
[node name="join" type="Button" parent="join_panel/v_box_container" unique_id=1953386108]
|
||||
layout_mode = 2
|
||||
@ -176,9 +174,6 @@ text = "Join"
|
||||
layout_mode = 2
|
||||
text = "Back"
|
||||
|
||||
[node name="settings" parent="." unique_id=999912383 instance=ExtResource("2_0wfyh")]
|
||||
visible = false
|
||||
|
||||
[node name="main_pos" type="Node3D" parent="." unique_id=98241074]
|
||||
transform = Transform3D(0.98629165, -0.031186387, 0.16203767, -1.4054484e-08, 0.981978, 0.1889952, -0.16501155, -0.18640435, 0.9685167, 1.0974054, 1.7166122, 1.4909104)
|
||||
|
||||
@ -236,7 +231,6 @@ text = "Ok"
|
||||
|
||||
[connection signal="pressed" from="main_panel/v_box_container/host" to="." method="go_to_host_game"]
|
||||
[connection signal="pressed" from="main_panel/v_box_container/join" to="." method="go_to_join_game"]
|
||||
[connection signal="pressed" from="main_panel/v_box_container/settings" to="settings" method="open"]
|
||||
[connection signal="pressed" from="main_panel/v_box_container/quit" to="." method="quit_game"]
|
||||
[connection signal="pressed" from="host_panel/v_box_container/host" to="." method="host_game"]
|
||||
[connection signal="pressed" from="host_panel/v_box_container/back" to="." method="go_to_main_menu"]
|
||||
|
||||
@ -8,7 +8,7 @@ glow_enabled = true
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_oh8vq"]
|
||||
|
||||
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh", "collider", "splorch", "dead_cam_target", "respawn_label", "ball_origin", "weapon_node", "pause_panel", "exit_to_lobby")]
|
||||
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh", "collider", "splorch", "dead_cam_target", "respawn_label", "ball_origin", "weapon_node")]
|
||||
look_sensitivity = 1.5
|
||||
camera = NodePath("camera_3d")
|
||||
move_speed = 5.0
|
||||
@ -19,8 +19,6 @@ dead_cam_target = NodePath("dead_camera_target")
|
||||
respawn_label = NodePath("respawn_label")
|
||||
ball_origin = NodePath("camera_3d")
|
||||
weapon_node = NodePath("camera_3d/weapon_node")
|
||||
pause_panel = NodePath("pause_menu")
|
||||
exit_to_lobby = NodePath("pause_menu/v_box_container/exit_to_lobby")
|
||||
health = 100
|
||||
collision_mask = 4
|
||||
|
||||
@ -70,43 +68,3 @@ offset_right = 20.0
|
||||
offset_bottom = 58.0
|
||||
grow_horizontal = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="pause_menu" type="Panel" parent="." unique_id=1542204162]
|
||||
visible = false
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -67.75
|
||||
offset_top = -101.25
|
||||
offset_right = 67.75
|
||||
offset_bottom = 101.25
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="v_box_container" type="VBoxContainer" parent="pause_menu" unique_id=839758321]
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -20.0
|
||||
offset_top = -20.0
|
||||
offset_right = 20.0
|
||||
offset_bottom = 20.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="exit_to_lobby" type="Button" parent="pause_menu/v_box_container" unique_id=1816170399]
|
||||
layout_mode = 2
|
||||
text = "Exit to Lobby"
|
||||
|
||||
[node name="exit" type="Button" parent="pause_menu/v_box_container" unique_id=641638697]
|
||||
layout_mode = 2
|
||||
text = "Exit"
|
||||
|
||||
[connection signal="pressed" from="pause_menu/v_box_container/exit_to_lobby" to="." method="exit_to_lobby"]
|
||||
[connection signal="pressed" from="pause_menu/v_box_container/exit" to="." method="exit"]
|
||||
|
||||
@ -1,54 +0,0 @@
|
||||
[gd_scene format=3 uid="uid://n3u0jr4wiib1"]
|
||||
|
||||
[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("settings_grid")]
|
||||
settings_grid = NodePath("grid")
|
||||
slider_scene = ExtResource("1_8wfqe")
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -207.0
|
||||
offset_top = -112.0
|
||||
offset_right = 207.0
|
||||
offset_bottom = 112.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="label" type="Label" parent="." unique_id=2036746921]
|
||||
layout_mode = 0
|
||||
offset_left = 57.0
|
||||
offset_right = 357.0
|
||||
offset_bottom = 23.0
|
||||
text = "Settings"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="grid" type="GridContainer" parent="." unique_id=833231169]
|
||||
custom_minimum_size = Vector2(400, 0)
|
||||
custom_maximum_size = Vector2(400, -1)
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -145.0
|
||||
offset_top = -74.0
|
||||
offset_right = 155.0
|
||||
offset_bottom = 67.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
columns = 2
|
||||
|
||||
[node name="button" type="Button" parent="." unique_id=1301469030]
|
||||
layout_mode = 0
|
||||
offset_left = 182.0
|
||||
offset_top = 192.0
|
||||
offset_right = 232.0
|
||||
offset_bottom = 223.0
|
||||
size_flags_horizontal = 4
|
||||
text = "Close"
|
||||
|
||||
[connection signal="pressed" from="button" to="." method="close"]
|
||||
@ -1,19 +0,0 @@
|
||||
[gd_scene format=3 uid="uid://cqiwdajl71ujv"]
|
||||
|
||||
[node name="slider" type="SliderContainer" unique_id=2000698366 node_paths=PackedStringArray("label", "slider")]
|
||||
label = NodePath("label")
|
||||
slider = NodePath("h_slider")
|
||||
value = 50.0
|
||||
max = 100.0
|
||||
offset_right = 214.0
|
||||
offset_bottom = 23.0
|
||||
|
||||
[node name="label" type="Label" parent="." unique_id=2059967949]
|
||||
layout_mode = 2
|
||||
text = "50"
|
||||
|
||||
[node name="h_slider" type="HSlider" parent="." unique_id=1564648919]
|
||||
custom_minimum_size = Vector2(200, 0)
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
value = 50.0
|
||||
@ -10,4 +10,3 @@ crate-type = ["cdylib"] # Compile this crate to a dynamic C library.
|
||||
godot = "0.5.4"
|
||||
serde = "1.0.228"
|
||||
teanet = { path = "../teanet-rust" }
|
||||
toml = "1.1.3"
|
||||
|
||||
@ -96,13 +96,11 @@ impl GameManager {
|
||||
|
||||
pub fn exit_game(&mut self) {
|
||||
self.exiting = true;
|
||||
self.run_deferred(|s| {
|
||||
if let Some(mut game) = s.game.take() {
|
||||
game.bind_mut().finish_game();
|
||||
game.queue_free();
|
||||
s.go_to_main_menu();
|
||||
}
|
||||
});
|
||||
if let Some(mut game) = self.game.take() {
|
||||
game.bind_mut().finish_game();
|
||||
game.queue_free();
|
||||
self.go_to_main_menu();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn go_to_finish_screen(&self) {
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
use godot::{
|
||||
classes::{FileAccess, file_access::ModeFlags},
|
||||
prelude::*,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct GameSettings {
|
||||
pub fov: f64,
|
||||
}
|
||||
|
||||
impl Default for GameSettings {
|
||||
fn default() -> Self {
|
||||
Self { fov: 90. }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(GodotClass)]
|
||||
#[class(base=Node, singleton)]
|
||||
pub struct GameSettingsManager {
|
||||
pub settings: GameSettings,
|
||||
base: Base<Node>,
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl INode for GameSettingsManager {
|
||||
fn init(base: Base<Node>) -> GameSettingsManager {
|
||||
let mut settings = GameSettings::default();
|
||||
if let Some(file) = FileAccess::open("user://config.toml", ModeFlags::READ) {
|
||||
if let Ok(deserialized) = toml::from_str(&file.get_as_text().to_string()) {
|
||||
settings = deserialized;
|
||||
}
|
||||
}
|
||||
GameSettingsManager { settings, base }
|
||||
}
|
||||
}
|
||||
|
||||
impl GameSettingsManager {
|
||||
pub fn update_settings(&mut self, settings: GameSettings) {
|
||||
self.settings = settings;
|
||||
if let Some(mut file) = FileAccess::open("user://config.toml", ModeFlags::WRITE) {
|
||||
if let Ok(serialized) = toml::to_string(&self.settings) {
|
||||
file.store_string(&serialized);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,6 @@ use godot::prelude::*;
|
||||
pub mod ball;
|
||||
pub mod cli_parser;
|
||||
pub mod game_manager;
|
||||
pub mod game_settings;
|
||||
pub mod goal;
|
||||
pub mod killbox;
|
||||
pub mod map;
|
||||
|
||||
@ -2,8 +2,8 @@ use std::{f32::consts::PI, ops::Neg};
|
||||
|
||||
use godot::{
|
||||
classes::{
|
||||
Button, Camera3D, CharacterBody3D, CollisionShape3D, GpuParticles3D, ICharacterBody3D,
|
||||
Input, InputEvent, InputEventMouseMotion, Label, Label3D, Panel, input::MouseMode,
|
||||
Camera3D, CharacterBody3D, CollisionShape3D, GpuParticles3D, ICharacterBody3D, Input,
|
||||
InputEvent, InputEventMouseMotion, Label, Label3D, input::MouseMode,
|
||||
},
|
||||
obj::WithBaseField,
|
||||
prelude::*,
|
||||
@ -11,7 +11,7 @@ use godot::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
game_manager::{Game, GameManager, GameOption},
|
||||
game_manager::{Game, GameOption},
|
||||
net::{
|
||||
network_manager::{
|
||||
NetworkManager,
|
||||
@ -191,10 +191,6 @@ pub struct LocalPlayer {
|
||||
#[export]
|
||||
weapon_node: Option<Gd<Node3D>>,
|
||||
#[export]
|
||||
pause_panel: Option<Gd<Panel>>,
|
||||
#[export]
|
||||
exit_to_lobby: Option<Gd<Button>>,
|
||||
#[export]
|
||||
health: i32,
|
||||
|
||||
pub player_id: Option<u16>,
|
||||
@ -382,12 +378,12 @@ impl ICharacterBody3D for LocalPlayer {
|
||||
CommandLinePanel::singleton()
|
||||
.signals()
|
||||
.on_open()
|
||||
.connect_other(self, |s| s.update_lock());
|
||||
.connect_other(self, |s| s.set_lock(false));
|
||||
CommandLinePanel::singleton()
|
||||
.signals()
|
||||
.on_close()
|
||||
.connect_other(self, |s| {
|
||||
s.update_lock();
|
||||
s.set_lock(true);
|
||||
});
|
||||
|
||||
self.swap_weapon(WeaponType::Raygun);
|
||||
@ -401,12 +397,6 @@ impl ICharacterBody3D for LocalPlayer {
|
||||
{
|
||||
remover.bind_mut().active = true;
|
||||
}
|
||||
|
||||
self.run_deferred(|s| {
|
||||
if let Some(exit_to_lobby) = &mut s.exit_to_lobby {
|
||||
exit_to_lobby.set_visible(NetworkManager::singleton().bind().is_host());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn process(&mut self, delta: f64) {
|
||||
@ -482,14 +472,6 @@ impl ICharacterBody3D for LocalPlayer {
|
||||
}
|
||||
|
||||
fn input(&mut self, event: Gd<InputEvent>) {
|
||||
if event.is_action_pressed("pause") {
|
||||
if let Some(pause_panel) = &mut self.pause_panel {
|
||||
let is_visible = pause_panel.is_visible();
|
||||
pause_panel.set_visible(!is_visible);
|
||||
self.update_lock();
|
||||
}
|
||||
}
|
||||
|
||||
if self.locked {
|
||||
if event.is_action_pressed("shoot") {
|
||||
let pos = if let Some(camera) = &self.camera {
|
||||
@ -569,17 +551,6 @@ impl LocalPlayer {
|
||||
#[signal]
|
||||
pub fn on_take_damage(source: DamageSourceSignal, source_player: u16, damage: i32);
|
||||
|
||||
fn update_lock(&mut self) {
|
||||
self.run_deferred(|s| {
|
||||
let paused = if let Some(panel) = &s.pause_panel {
|
||||
panel.is_visible()
|
||||
} else {
|
||||
false
|
||||
};
|
||||
s.set_lock(!CommandLinePanel::singleton().bind().opened && !paused);
|
||||
});
|
||||
}
|
||||
|
||||
fn set_lock(&mut self, locked: bool) {
|
||||
self.locked = locked;
|
||||
if self.locked {
|
||||
@ -598,19 +569,6 @@ impl LocalPlayer {
|
||||
self.weapon = Some(weapon);
|
||||
}
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn exit_to_lobby(&mut self) {
|
||||
if let Some(game) = &mut Game::singleton() {
|
||||
game.bind_mut().finish_game();
|
||||
}
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn exit(&mut self) {
|
||||
GameManager::singleton().bind_mut().exit_game();
|
||||
NetworkManager::singleton().bind_mut().disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(GodotClass)]
|
||||
|
||||
@ -6,6 +6,4 @@ pub mod main_menu;
|
||||
pub mod menu_player;
|
||||
pub mod net_stats;
|
||||
pub mod player_listing;
|
||||
pub mod settings;
|
||||
pub mod simple_score_view;
|
||||
pub mod slider;
|
||||
|
||||
@ -1,137 +0,0 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use godot::{
|
||||
classes::{Control, GridContainer, IPanel, Label, Panel, control::SizeFlags},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
game_settings::{GameSettings, GameSettingsManager},
|
||||
ui::slider::SliderContainer,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Eq, Hash)]
|
||||
pub enum Setting {
|
||||
FoV,
|
||||
}
|
||||
|
||||
impl ToString for Setting {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
Setting::FoV => "Field of View",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum SettingValue {
|
||||
SliderNumber(SliderValue),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct SliderValue {
|
||||
min: f64,
|
||||
max: f64,
|
||||
value: f64,
|
||||
}
|
||||
|
||||
#[derive(GodotClass)]
|
||||
#[class(base=Panel, init)]
|
||||
pub struct SettingsPanel {
|
||||
#[export]
|
||||
settings_grid: Option<Gd<GridContainer>>,
|
||||
#[export]
|
||||
slider_scene: Option<Gd<PackedScene>>,
|
||||
|
||||
settings: HashMap<Setting, SettingValue>,
|
||||
|
||||
base: Base<Panel>,
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl IPanel for SettingsPanel {
|
||||
fn ready(&mut self) {
|
||||
let singleton = GameSettingsManager::singleton();
|
||||
let settings = &singleton.bind().settings;
|
||||
self.settings.insert(
|
||||
Setting::FoV,
|
||||
SettingValue::SliderNumber(SliderValue {
|
||||
min: 60.,
|
||||
max: 120.,
|
||||
value: settings.fov,
|
||||
}),
|
||||
);
|
||||
|
||||
if let Some(mut grid) = self.settings_grid.clone() {
|
||||
for (setting, value) in &self.settings {
|
||||
let mut label = Label::new_alloc();
|
||||
label.set_text(&setting.to_string());
|
||||
label.set_h_size_flags(SizeFlags::EXPAND | SizeFlags::SHRINK_BEGIN);
|
||||
grid.add_child(&label);
|
||||
|
||||
if let Some(scene) = self.slider_scene.clone() {
|
||||
let node = match value {
|
||||
SettingValue::SliderNumber(slider_value) => {
|
||||
let mut slider = scene.instantiate_as::<SliderContainer>();
|
||||
|
||||
slider.bind_mut().min = slider_value.min;
|
||||
slider.bind_mut().max = slider_value.max;
|
||||
slider.bind_mut().value = slider_value.value;
|
||||
|
||||
let setting_clone = setting.clone();
|
||||
let value_clone = slider_value.clone();
|
||||
slider.bind_mut().signals().on_change().connect_other(
|
||||
self,
|
||||
move |s, new_value| {
|
||||
s.run_deferred(move |s| {
|
||||
s.on_change(
|
||||
setting_clone,
|
||||
SettingValue::SliderNumber(SliderValue {
|
||||
value: new_value,
|
||||
..value_clone
|
||||
}),
|
||||
)
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
slider.upcast::<Control>()
|
||||
}
|
||||
};
|
||||
|
||||
grid.add_child(&node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl SettingsPanel {
|
||||
pub fn on_change(&mut self, setting: Setting, new_value: SettingValue) {
|
||||
self.settings.insert(setting, new_value);
|
||||
|
||||
let mut new_settings = GameSettingsManager::singleton().bind().settings.clone();
|
||||
for (setting, value) in &self.settings {
|
||||
match (setting, value) {
|
||||
(Setting::FoV, SettingValue::SliderNumber(value)) => {
|
||||
new_settings.fov = value.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
GameSettingsManager::singleton()
|
||||
.bind_mut()
|
||||
.update_settings(new_settings);
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn open(&mut self) {
|
||||
self.base_mut().set_visible(true);
|
||||
}
|
||||
|
||||
#[func]
|
||||
pub fn close(&mut self) {
|
||||
self.base_mut().set_visible(false);
|
||||
}
|
||||
}
|
||||
@ -1,56 +0,0 @@
|
||||
use godot::{
|
||||
classes::{HBoxContainer, IHBoxContainer, Label, Slider},
|
||||
prelude::*,
|
||||
};
|
||||
|
||||
#[derive(GodotClass)]
|
||||
#[class(base=HBoxContainer, init, tool)]
|
||||
pub struct SliderContainer {
|
||||
#[export]
|
||||
label: Option<Gd<Label>>,
|
||||
#[export]
|
||||
slider: Option<Gd<Slider>>,
|
||||
#[export]
|
||||
pub value: f64,
|
||||
#[export]
|
||||
pub min: f64,
|
||||
#[export]
|
||||
pub max: f64,
|
||||
|
||||
last_value: f64,
|
||||
|
||||
base: Base<HBoxContainer>,
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl IHBoxContainer for SliderContainer {
|
||||
fn ready(&mut self) {}
|
||||
|
||||
fn process(&mut self, _delta: f64) {
|
||||
if let Some(slider) = &mut self.slider {
|
||||
slider.set_min(self.min);
|
||||
slider.set_max(self.max);
|
||||
if self.last_value != self.value {
|
||||
slider.set_value(self.value);
|
||||
}
|
||||
self.value = slider.get_value();
|
||||
if self.last_value != self.value {
|
||||
let value = self.value;
|
||||
self.signals().on_change().emit(value);
|
||||
}
|
||||
self.last_value = self.value;
|
||||
}
|
||||
|
||||
if let Some(label) = &mut self.label
|
||||
&& let Some(slider) = &self.slider
|
||||
{
|
||||
label.set_text(&format!("{}", slider.get_value()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl SliderContainer {
|
||||
#[signal]
|
||||
pub fn on_change(value: f64);
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user