Add a options/pause menu (Closes #4)
This commit is contained in:
parent
2acfa47491
commit
4c590f8184
|
@ -38,6 +38,42 @@ pub struct CVar<T: Sized + Any + 'static> {
|
|||
pub default: &'static Fn() -> T,
|
||||
}
|
||||
|
||||
impl Var for CVar<i64> {
|
||||
fn serialize(&self, val: &Box<Any>) -> String {
|
||||
val.downcast_ref::<i64>().unwrap().to_string()
|
||||
}
|
||||
|
||||
fn deserialize(&self, input: &str) -> Box<Any> {
|
||||
Box::new(input.parse::<i64>().unwrap())
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str {
|
||||
self.description
|
||||
}
|
||||
|
||||
fn can_serialize(&self) -> bool {
|
||||
self.serializable
|
||||
}
|
||||
}
|
||||
|
||||
impl Var for CVar<bool> {
|
||||
fn serialize(&self, val: &Box<Any>) -> String {
|
||||
val.downcast_ref::<bool>().unwrap().to_string()
|
||||
}
|
||||
|
||||
fn deserialize(&self, input: &str) -> Box<Any> {
|
||||
Box::new(input.parse::<bool>().unwrap())
|
||||
}
|
||||
|
||||
fn description(&self) -> &'static str {
|
||||
self.description
|
||||
}
|
||||
|
||||
fn can_serialize(&self) -> bool {
|
||||
self.serializable
|
||||
}
|
||||
}
|
||||
|
||||
impl Var for CVar<String> {
|
||||
fn serialize(&self, val: &Box<Any>) -> String {
|
||||
format!("\"{}\"", val.downcast_ref::<String>().unwrap())
|
||||
|
|
|
@ -20,7 +20,7 @@ use cgmath::{self, Point3, Vector3, Matrix4, Decomposed, Rotation3, Rad, Angle,
|
|||
use std::collections::HashMap;
|
||||
use std::hash::BuildHasherDefault;
|
||||
use types::hash::FNVHash;
|
||||
use sdl2::keyboard::Keycode;
|
||||
use settings::Stevenkey;
|
||||
use shared::Position as BPosition;
|
||||
use format;
|
||||
|
||||
|
@ -441,7 +441,7 @@ impl ecs::System for PlayerRenderer {
|
|||
pub struct PlayerMovement {
|
||||
pub flying: bool,
|
||||
pub did_touch_ground: bool,
|
||||
pub pressed_keys: HashMap<Keycode, bool, BuildHasherDefault<FNVHash>>,
|
||||
pub pressed_keys: HashMap<Stevenkey, bool, BuildHasherDefault<FNVHash>>,
|
||||
}
|
||||
|
||||
impl PlayerMovement {
|
||||
|
@ -457,23 +457,23 @@ impl PlayerMovement {
|
|||
use std::f64::consts::PI;
|
||||
let mut forward = 0.0f64;
|
||||
let mut yaw = player_yaw - (PI/2.0);
|
||||
if self.is_key_pressed(Keycode::W) || self.is_key_pressed(Keycode::S) {
|
||||
if self.is_key_pressed(Stevenkey::Forward) || self.is_key_pressed(Stevenkey::Backward) {
|
||||
forward = 1.0;
|
||||
if self.is_key_pressed(Keycode::S) {
|
||||
if self.is_key_pressed(Stevenkey::Backward) {
|
||||
yaw += PI;
|
||||
}
|
||||
}
|
||||
let mut change = 0.0;
|
||||
if self.is_key_pressed(Keycode::A) {
|
||||
if self.is_key_pressed(Stevenkey::Left) {
|
||||
change = (PI / 2.0) / (forward.abs() + 1.0);
|
||||
}
|
||||
if self.is_key_pressed(Keycode::D) {
|
||||
if self.is_key_pressed(Stevenkey::Right) {
|
||||
change = -(PI / 2.0) / (forward.abs() + 1.0);
|
||||
}
|
||||
if self.is_key_pressed(Keycode::A) || self.is_key_pressed(Keycode::D) {
|
||||
if self.is_key_pressed(Stevenkey::Left) || self.is_key_pressed(Stevenkey::Right) {
|
||||
forward = 1.0;
|
||||
}
|
||||
if self.is_key_pressed(Keycode::S) {
|
||||
if self.is_key_pressed(Stevenkey::Backward) {
|
||||
yaw -= change;
|
||||
} else {
|
||||
yaw += change;
|
||||
|
@ -482,7 +482,7 @@ impl PlayerMovement {
|
|||
(forward, yaw)
|
||||
}
|
||||
|
||||
fn is_key_pressed(&self, key: Keycode) -> bool {
|
||||
fn is_key_pressed(&self, key: Stevenkey) -> bool {
|
||||
self.pressed_keys.get(&key).map_or(false, |v| *v)
|
||||
}
|
||||
}
|
||||
|
@ -554,20 +554,20 @@ impl ecs::System for MovementHandler {
|
|||
if world.is_chunk_loaded((position.position.x as i32) >> 4, (position.position.z as i32) >> 4) {
|
||||
let (forward, yaw) = movement.calculate_movement(rotation.yaw);
|
||||
let mut speed = 0.21585;
|
||||
if movement.is_key_pressed(Keycode::LShift) {
|
||||
if movement.is_key_pressed(Stevenkey::Sprint) {
|
||||
speed = 0.2806;
|
||||
}
|
||||
if movement.flying {
|
||||
speed *= 2.5;
|
||||
|
||||
if movement.is_key_pressed(Keycode::Space) {
|
||||
if movement.is_key_pressed(Stevenkey::Jump) {
|
||||
position.position.y += speed;
|
||||
}
|
||||
if movement.is_key_pressed(Keycode::LCtrl) {
|
||||
if movement.is_key_pressed(Stevenkey::Sneak) {
|
||||
position.position.y -= speed;
|
||||
}
|
||||
} else if gravity.as_ref().map_or(false, |v| v.on_ground) {
|
||||
if movement.is_key_pressed(Keycode::Space) && velocity.velocity.y.abs() < 0.001 {
|
||||
if movement.is_key_pressed(Stevenkey::Jump) && velocity.velocity.y.abs() < 0.001 {
|
||||
velocity.velocity.y = 0.42;
|
||||
}
|
||||
} else {
|
||||
|
|
19
src/main.rs
19
src/main.rs
|
@ -48,6 +48,7 @@ pub mod resources;
|
|||
pub mod render;
|
||||
pub mod ui;
|
||||
pub mod screen;
|
||||
pub mod settings;
|
||||
#[macro_use]
|
||||
pub mod console;
|
||||
pub mod server;
|
||||
|
@ -154,6 +155,7 @@ fn main() {
|
|||
let mut con = con.lock().unwrap();
|
||||
con.register(CL_BRAND);
|
||||
auth::register_vars(&mut con);
|
||||
settings::register_vars(&mut con);
|
||||
con.load_config();
|
||||
con.save_config();
|
||||
}
|
||||
|
@ -297,7 +299,7 @@ fn handle_window_event(window: &sdl2::video::Window,
|
|||
Event::MouseButtonUp{mouse_btn: Mouse::Left, x, y, ..} => {
|
||||
let (width, height) = window.size();
|
||||
|
||||
if game.server.is_connected() && !game.focused {
|
||||
if game.server.is_connected() && !game.focused && !game.screen_sys.is_current_closable() {
|
||||
game.focused = true;
|
||||
if !mouse.relative_mouse_mode() {
|
||||
mouse.set_relative_mouse_mode(true);
|
||||
|
@ -318,6 +320,11 @@ fn handle_window_event(window: &sdl2::video::Window,
|
|||
if game.focused {
|
||||
mouse.set_relative_mouse_mode(false);
|
||||
game.focused = false;
|
||||
game.screen_sys.replace_screen(Box::new(screen::SettingsMenu::new(game.console.clone(), true)));
|
||||
} else if game.screen_sys.is_current_closable() {
|
||||
mouse.set_relative_mouse_mode(true);
|
||||
game.focused = true;
|
||||
game.screen_sys.pop_screen();
|
||||
}
|
||||
}
|
||||
Event::KeyDown{keycode: Some(Keycode::Backquote), ..} => {
|
||||
|
@ -325,14 +332,20 @@ fn handle_window_event(window: &sdl2::video::Window,
|
|||
}
|
||||
Event::KeyDown{keycode: Some(key), ..} => {
|
||||
if game.focused {
|
||||
game.server.key_press(true, key);
|
||||
let console = game.console.lock().unwrap();
|
||||
if let Some(steven_key) = settings::Stevenkey::get_by_keycode(key, &console) {
|
||||
game.server.key_press(true, steven_key);
|
||||
}
|
||||
} else {
|
||||
ui_container.key_press(game, key, true);
|
||||
}
|
||||
}
|
||||
Event::KeyUp{keycode: Some(key), ..} => {
|
||||
if game.focused {
|
||||
game.server.key_press(false, key);
|
||||
let console = game.console.lock().unwrap();
|
||||
if let Some(steven_key) = settings::Stevenkey::get_by_keycode(key, &console) {
|
||||
game.server.key_press(false, steven_key);
|
||||
}
|
||||
} else {
|
||||
ui_container.key_press(game, key, false);
|
||||
}
|
||||
|
|
|
@ -177,4 +177,8 @@ impl super::Screen for EditServerEntry {
|
|||
elements.logo.tick(renderer, ui_container);
|
||||
None
|
||||
}
|
||||
|
||||
fn is_closable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,12 @@
|
|||
mod server_list;
|
||||
pub use self::server_list::*;
|
||||
mod login;
|
||||
pub mod settings_menu;
|
||||
|
||||
pub use self::login::*;
|
||||
pub mod connecting;
|
||||
pub mod edit_server;
|
||||
pub use self::settings_menu::{SettingsMenu, VideoSettingsMenu, AudioSettingsMenu};
|
||||
|
||||
use render;
|
||||
use ui;
|
||||
|
@ -43,6 +46,10 @@ pub trait Screen {
|
|||
// Events
|
||||
fn on_scroll(&mut self, x: f64, y: f64) {
|
||||
}
|
||||
|
||||
fn is_closable(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
struct ScreenInfo {
|
||||
|
@ -83,6 +90,14 @@ impl ScreenSystem {
|
|||
self.add_screen(screen);
|
||||
}
|
||||
|
||||
pub fn is_current_closable(&self) -> bool {
|
||||
if let Some(last) = self.screens.last() {
|
||||
last.screen.is_closable()
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tick(&mut self,
|
||||
delta: f64,
|
||||
renderer: &mut render::Renderer,
|
||||
|
|
|
@ -387,7 +387,9 @@ impl super::Screen for ServerList {
|
|||
cog.set_parent(&re);
|
||||
cog.set_v_attach(ui::VAttach::Middle);
|
||||
cog.set_h_attach(ui::HAttach::Center);
|
||||
super::button_action(ui_container, re.clone(), None, |_, _| {});
|
||||
super::button_action(ui_container, re.clone(), None, | game, _ | {
|
||||
game.screen_sys.add_screen(Box::new(super::SettingsMenu::new(game.console.clone(), false)));
|
||||
});
|
||||
elements.add(re);
|
||||
elements.add(ui_container.add(cog));
|
||||
|
||||
|
|
|
@ -0,0 +1,291 @@
|
|||
use console;
|
||||
use render;
|
||||
use ui;
|
||||
use settings;
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
pub fn new_submenu_button(text: &str, renderer: &mut render::Renderer, ui_container: &mut ui::Container, x: f64, y: f64) -> (ui::ElementRef<ui::Button>, ui::ElementRef<ui::Text>) {
|
||||
let (mut btn, mut txt) = super::new_button_text(renderer, text, x, y, 300.0, 40.0);
|
||||
btn.set_v_attach(ui::VAttach::Middle);
|
||||
btn.set_h_attach(ui::HAttach::Center);
|
||||
let ui_btn = ui_container.add(btn);
|
||||
txt.set_parent(&ui_btn);
|
||||
(ui_btn, ui_container.add(txt))
|
||||
}
|
||||
|
||||
pub fn new_centered_button(text: &str, renderer: &mut render::Renderer, ui_container: &mut ui::Container, y: f64, vertical_attach: ui::VAttach) -> (ui::ElementRef<ui::Button>, ui::ElementRef<ui::Text>) {
|
||||
let (mut btn, mut txt) = super::new_button_text(renderer, text, 0.0, y, 400.0, 40.0);
|
||||
btn.set_v_attach(vertical_attach);
|
||||
btn.set_h_attach(ui::HAttach::Center);
|
||||
let ui_btn = ui_container.add(btn);
|
||||
txt.set_parent(&ui_btn);
|
||||
(ui_btn, ui_container.add(txt))
|
||||
}
|
||||
|
||||
macro_rules! get_bool_str {
|
||||
($fmt:expr, $val:expr, $val_true:expr, $val_false:expr) => (format!($fmt, if $val {
|
||||
$val_true
|
||||
} else {
|
||||
$val_false
|
||||
}).as_ref());
|
||||
($fmt:expr, $val:expr) => (get_bool_string!($fmt, $val, "true", "false"));
|
||||
}
|
||||
|
||||
macro_rules! get_matched_str {
|
||||
($fmt:expr, $val:expr, $($to_match:expr => $result:expr),*) => (
|
||||
format!($fmt, match $val {
|
||||
$($to_match => $result.to_owned(), )*
|
||||
_ => $val.to_string(),
|
||||
}).as_ref()
|
||||
)
|
||||
}
|
||||
|
||||
pub struct UIElement {
|
||||
elements: ui::Collection
|
||||
// TODO: Add background of some sort
|
||||
}
|
||||
|
||||
pub struct SettingsMenu {
|
||||
console: Arc<Mutex<console::Console>>,
|
||||
elements: Option<UIElement>,
|
||||
show_disconnect_button: bool
|
||||
}
|
||||
|
||||
impl SettingsMenu {
|
||||
pub fn new(console: Arc<Mutex<console::Console>>, show_disconnect_button: bool) -> SettingsMenu {
|
||||
SettingsMenu {
|
||||
console: console,
|
||||
elements: None,
|
||||
show_disconnect_button: show_disconnect_button
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl super::Screen for SettingsMenu {
|
||||
fn on_active(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
let mut elements = ui::Collection::new();
|
||||
|
||||
// From top and down
|
||||
let (btn_audio_settings, txt_audio_settings) = new_submenu_button("Audio settings...", renderer, ui_container, -160.0, -50.0);
|
||||
super::button_action(ui_container, btn_audio_settings.clone(), Some(txt_audio_settings.clone()), move | game, _ | {
|
||||
game.screen_sys.add_screen(Box::new(AudioSettingsMenu::new(game.console.clone())));
|
||||
});
|
||||
elements.add(btn_audio_settings);
|
||||
elements.add(txt_audio_settings);
|
||||
|
||||
let (btn_video_settings, txt_video_settings) = new_submenu_button("Video settings...", renderer, ui_container, 160.0, -50.0);
|
||||
super::button_action(ui_container, btn_video_settings.clone(), Some(txt_video_settings.clone()), move | game, _ | {
|
||||
game.screen_sys.add_screen(Box::new(VideoSettingsMenu::new(game.console.clone())));
|
||||
});
|
||||
elements.add(btn_video_settings);
|
||||
elements.add(txt_video_settings);
|
||||
|
||||
let (btn_controls_settings, txt_controls_settings) = new_submenu_button("Controls...", renderer, ui_container, 160.0, 0.0);
|
||||
super::button_action(ui_container, btn_controls_settings.clone(), Some(txt_controls_settings.clone()), move | game, _ | {
|
||||
// TODO: Implement this...
|
||||
});
|
||||
elements.add(btn_controls_settings);
|
||||
elements.add(txt_controls_settings);
|
||||
|
||||
let (btn_locale_settings, txt_locale_settings) = new_submenu_button("Language...", renderer, ui_container, -160.0, 0.0);
|
||||
super::button_action(ui_container, btn_locale_settings.clone(), Some(txt_locale_settings.clone()), move | game, _ | {
|
||||
// TODO: Implement this...
|
||||
});
|
||||
elements.add(btn_locale_settings);
|
||||
elements.add(txt_locale_settings);
|
||||
|
||||
// Center bottom items
|
||||
let (mut btn_back_to_game, mut txt_back_to_game) = new_centered_button("Done", renderer, ui_container, 50.0, ui::VAttach::Bottom);
|
||||
super::button_action(ui_container, btn_back_to_game.clone(), Some(txt_back_to_game.clone()), move | game, _ | {
|
||||
game.screen_sys.pop_screen();
|
||||
game.focused = true;
|
||||
});
|
||||
elements.add(btn_back_to_game);
|
||||
elements.add(txt_back_to_game);
|
||||
|
||||
if self.show_disconnect_button {
|
||||
let (mut btn_exit_game, mut txt_exit_game) = new_centered_button("Disconnect", renderer, ui_container, 100.0, ui::VAttach::Bottom);
|
||||
super::button_action(ui_container, btn_exit_game.clone(), Some(txt_exit_game.clone()), move | game, _ | {
|
||||
game.server.disconnect();
|
||||
game.screen_sys.replace_screen(Box::new(super::ServerList::new(None)));
|
||||
});
|
||||
elements.add(btn_exit_game);
|
||||
elements.add(txt_exit_game);
|
||||
}
|
||||
|
||||
self.elements = Some(UIElement {
|
||||
elements: elements
|
||||
});
|
||||
|
||||
}
|
||||
fn on_deactive(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
{
|
||||
let elements = self.elements.as_mut().unwrap();
|
||||
elements.elements.remove_all(ui_container);
|
||||
}
|
||||
self.elements = None;
|
||||
}
|
||||
|
||||
// Called every frame the screen is active
|
||||
fn tick(&mut self, delta: f64, renderer: &mut render::Renderer, ui_container: &mut ui::Container) -> Option<Box<super::Screen>> {
|
||||
None
|
||||
}
|
||||
|
||||
// Events
|
||||
fn on_scroll(&mut self, x: f64, y: f64) {
|
||||
|
||||
}
|
||||
|
||||
fn is_closable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VideoSettingsMenu {
|
||||
console: Arc<Mutex<console::Console>>,
|
||||
elements: Option<UIElement>,
|
||||
fps_bounds: Vec<i64>
|
||||
}
|
||||
|
||||
impl VideoSettingsMenu {
|
||||
pub fn new(console: Arc<Mutex<console::Console>>) -> VideoSettingsMenu {
|
||||
VideoSettingsMenu {
|
||||
console: console,
|
||||
elements: None,
|
||||
fps_bounds: vec!(60, 120, 144, -1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl super::Screen for VideoSettingsMenu {
|
||||
fn on_active(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
let mut elements = ui::Collection::new();
|
||||
|
||||
// Load defaults
|
||||
let (r_max_fps, r_fov, r_vsync) = {
|
||||
let console = self.console.lock().unwrap();
|
||||
(
|
||||
console.get(settings::R_MAX_FPS).clone(),
|
||||
console.get(settings::R_FOV).clone(),
|
||||
console.get(settings::R_VSYNC).clone()
|
||||
)
|
||||
};
|
||||
|
||||
// Setting buttons
|
||||
// TODO: Slider
|
||||
let (btn_fov, txt_fov) = new_submenu_button(get_matched_str!("FOV: {}", r_fov, 90 => "Normal", 110 => "Quake pro"), renderer, ui_container, -160.0, -50.0);
|
||||
elements.add(btn_fov);
|
||||
elements.add(txt_fov);
|
||||
|
||||
let (btn_vsync, txt_vsync) = new_submenu_button(get_bool_str!("VSync: {}", r_vsync, "Enabled", "Disabled"), renderer, ui_container, -160.0, 0.0);
|
||||
elements.add(txt_vsync.clone());
|
||||
super::button_action(ui_container, btn_vsync.clone(), Some(txt_vsync.clone()), move | game, ui_container | {
|
||||
let mut console = game.console.lock().unwrap();
|
||||
let r_vsync = !console.get(settings::R_VSYNC);
|
||||
let txt_vsync = ui_container.get_mut(&txt_vsync);
|
||||
txt_vsync.set_text(&game.renderer, get_bool_str!("VSync: {}", r_vsync, "Enabled", "Disabled"));
|
||||
console.set(settings::R_VSYNC, r_vsync);
|
||||
});
|
||||
elements.add(btn_vsync);
|
||||
|
||||
// TODO: Slider
|
||||
let (btn_fps_cap, txt_fps_cap) = new_submenu_button(get_matched_str!("FPS cap: {}", r_max_fps, 0 => "Unlimited", 15 => "Potato"), renderer, ui_container, 160.0, 0.0);
|
||||
elements.add(btn_fps_cap);
|
||||
elements.add(txt_fps_cap);
|
||||
|
||||
let (mut btn_done, mut txt_done) = new_centered_button("Done", renderer, ui_container, 50.0, ui::VAttach::Bottom);
|
||||
super::button_action(ui_container, btn_done.clone(), Some(txt_done.clone()), move | game, _ | {
|
||||
game.screen_sys.pop_screen();
|
||||
});
|
||||
elements.add(btn_done);
|
||||
elements.add(txt_done);
|
||||
self.elements = Some(UIElement {
|
||||
elements: elements
|
||||
});
|
||||
|
||||
}
|
||||
fn on_deactive(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
{
|
||||
let elements = self.elements.as_mut().unwrap();
|
||||
elements.elements.remove_all(ui_container);
|
||||
}
|
||||
self.elements = None;
|
||||
}
|
||||
|
||||
// Called every frame the screen is active
|
||||
fn tick(&mut self, delta: f64, renderer: &mut render::Renderer, ui_container: &mut ui::Container) -> Option<Box<super::Screen>> {
|
||||
None
|
||||
}
|
||||
|
||||
// Events
|
||||
fn on_scroll(&mut self, x: f64, y: f64) {
|
||||
|
||||
}
|
||||
|
||||
fn is_closable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AudioSettingsMenu {
|
||||
console: Arc<Mutex<console::Console>>,
|
||||
elements: Option<UIElement>
|
||||
}
|
||||
|
||||
impl AudioSettingsMenu {
|
||||
pub fn new(console: Arc<Mutex<console::Console>>) -> AudioSettingsMenu {
|
||||
AudioSettingsMenu {
|
||||
console: console,
|
||||
elements: None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl super::Screen for AudioSettingsMenu {
|
||||
fn on_active(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
let mut elements = ui::Collection::new();
|
||||
|
||||
let master_volume = {
|
||||
let console = self.console.lock().unwrap();
|
||||
(console.get(settings::CL_MASTER_VOLUME).clone())
|
||||
};
|
||||
|
||||
let (mut btn_master_volume, mut txt_master_volume) = new_centered_button(master_volume.to_string().as_ref(), renderer, ui_container, -150.0, ui::VAttach::Middle);
|
||||
elements.add(btn_master_volume);
|
||||
elements.add(txt_master_volume);
|
||||
|
||||
let (mut btn_done, mut txt_done) = new_centered_button("Done", renderer, ui_container, 50.0, ui::VAttach::Bottom);
|
||||
super::button_action(ui_container, btn_done.clone(), Some(txt_done.clone()), move | game, _ | {
|
||||
game.screen_sys.pop_screen();
|
||||
});
|
||||
elements.add(btn_done);
|
||||
elements.add(txt_done);
|
||||
|
||||
self.elements = Some(UIElement {
|
||||
elements: elements
|
||||
});
|
||||
|
||||
}
|
||||
fn on_deactive(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
{
|
||||
let elements = self.elements.as_mut().unwrap();
|
||||
elements.elements.remove_all(ui_container);
|
||||
}
|
||||
self.elements = None;
|
||||
}
|
||||
|
||||
// Called every frame the screen is active
|
||||
fn tick(&mut self, delta: f64, renderer: &mut render::Renderer, ui_container: &mut ui::Container) -> Option<Box<super::Screen>> {
|
||||
None
|
||||
}
|
||||
|
||||
// Events
|
||||
fn on_scroll(&mut self, x: f64, y: f64) {
|
||||
|
||||
}
|
||||
|
||||
fn is_closable(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ use types::hash::FNVHash;
|
|||
use resources;
|
||||
use console;
|
||||
use render;
|
||||
use settings::Stevenkey;
|
||||
use auth;
|
||||
use ecs;
|
||||
use entity;
|
||||
|
@ -72,7 +73,6 @@ pub struct Server {
|
|||
entity_map: HashMap<i32, ecs::Entity, BuildHasherDefault<FNVHash>>,
|
||||
players: HashMap<protocol::UUID, PlayerInfo, BuildHasherDefault<FNVHash>>,
|
||||
|
||||
pressed_keys: HashMap<Keycode, bool, BuildHasherDefault<FNVHash>>,
|
||||
tick_timer: f64,
|
||||
entity_tick_timer: f64,
|
||||
|
||||
|
@ -285,8 +285,6 @@ impl Server {
|
|||
resources: resources,
|
||||
console: console,
|
||||
|
||||
pressed_keys: HashMap::with_hasher(BuildHasherDefault::default()),
|
||||
|
||||
// Entity accessors
|
||||
game_info: game_info,
|
||||
player_movement: entities.get_key(),
|
||||
|
@ -310,6 +308,14 @@ impl Server {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn disconnect(&mut self) {
|
||||
self.conn = None;
|
||||
self.disconnect_reason = None;
|
||||
if let Some(player) = self.player.take() {
|
||||
self.entities.remove_entity(player);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_connected(&self) -> bool {
|
||||
self.conn.is_some()
|
||||
}
|
||||
|
@ -487,8 +493,7 @@ impl Server {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn key_press(&mut self, down: bool, key: Keycode) {
|
||||
self.pressed_keys.insert(key, down);
|
||||
pub fn key_press(&mut self, down: bool, key: Stevenkey) {
|
||||
if let Some(player) = self.player {
|
||||
if let Some(movement) = self.entities.get_component_mut(player, self.player_movement) {
|
||||
movement.pressed_keys.insert(key, down);
|
||||
|
@ -496,10 +501,6 @@ impl Server {
|
|||
}
|
||||
}
|
||||
|
||||
fn is_key_pressed(&self, key: Keycode) -> bool {
|
||||
self.pressed_keys.get(&key).map_or(false, |v| *v)
|
||||
}
|
||||
|
||||
pub fn write_packet<T: protocol::PacketType>(&mut self, p: T) {
|
||||
let _ = self.conn.as_mut().unwrap().write_packet(p); // TODO handle errors
|
||||
}
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
use console;
|
||||
use std::marker::PhantomData;
|
||||
use sdl2::keyboard::Keycode;
|
||||
// Might just rename this to settings.rs
|
||||
|
||||
pub const R_MAX_FPS: console::CVar<i64> = console::CVar {
|
||||
ty: PhantomData,
|
||||
name: "r_max_fps",
|
||||
description: "fps_max caps the maximum FPS for the rendering engine",
|
||||
mutable: true,
|
||||
serializable: true,
|
||||
default: &|| 60,
|
||||
};
|
||||
|
||||
pub const R_FOV: console::CVar<i64> = console::CVar {
|
||||
ty: PhantomData,
|
||||
name: "r_fov",
|
||||
description: "Setting for controlling the client field of view",
|
||||
mutable: true,
|
||||
serializable: true,
|
||||
default: &|| 90,
|
||||
};
|
||||
|
||||
pub const R_VSYNC: console::CVar<bool> = console::CVar {
|
||||
ty: PhantomData,
|
||||
name: "r_vsync",
|
||||
description: "Toggle to enable/disable vsync",
|
||||
mutable: true,
|
||||
serializable: true,
|
||||
default: &|| true,
|
||||
};
|
||||
|
||||
pub const CL_MASTER_VOLUME: console::CVar<i64> = console::CVar {
|
||||
ty: PhantomData,
|
||||
name: "cl_master_volume",
|
||||
description: "Main volume control",
|
||||
mutable: true,
|
||||
serializable: true,
|
||||
default: &|| 100,
|
||||
};
|
||||
|
||||
macro_rules! create_keybind {
|
||||
($keycode:ident, $name:expr, $description:expr) => (console::CVar {
|
||||
ty: PhantomData,
|
||||
name: $name,
|
||||
description: $description,
|
||||
mutable: true,
|
||||
serializable: true,
|
||||
default: &|| Keycode::$keycode as i64
|
||||
})
|
||||
}
|
||||
|
||||
pub const CL_KEYBIND_FORWARD: console::CVar<i64> = create_keybind!(W, "cl_keybind_forward", "Keybinding for moving forward");
|
||||
pub const CL_KEYBIND_BACKWARD: console::CVar<i64> = create_keybind!(S, "cl_keybind_backward", "Keybinding for moving backward");
|
||||
pub const CL_KEYBIND_LEFT: console::CVar<i64> = create_keybind!(A, "cl_keybind_left", "Keybinding for moving the left");
|
||||
pub const CL_KEYBIND_RIGHT: console::CVar<i64> = create_keybind!(D, "cl_keybind_right", "Keybinding for moving to the right");
|
||||
pub const CL_KEYBIND_OPEN_INV: console::CVar<i64> = create_keybind!(E, "cl_keybind_open_inv", "Keybinding for opening the inventory");
|
||||
pub const CL_KEYBIND_SNEAK: console::CVar<i64> = create_keybind!(LShift, "cl_keybind_sneak", "Keybinding for sneaking");
|
||||
pub const CL_KEYBIND_SPRINT: console::CVar<i64> = create_keybind!(LCtrl, "cl_keybind_sprint", "Keybinding for sprinting");
|
||||
pub const CL_KEYBIND_JUMP: console::CVar<i64> = create_keybind!(Space, "cl_keybind_jump", "Keybinding for jumping");
|
||||
|
||||
pub fn register_vars(console: &mut console::Console) {
|
||||
console.register(R_MAX_FPS);
|
||||
console.register(R_FOV);
|
||||
console.register(R_VSYNC);
|
||||
console.register(CL_MASTER_VOLUME);
|
||||
console.register(CL_KEYBIND_FORWARD);
|
||||
console.register(CL_KEYBIND_BACKWARD);
|
||||
console.register(CL_KEYBIND_LEFT);
|
||||
console.register(CL_KEYBIND_RIGHT);
|
||||
console.register(CL_KEYBIND_OPEN_INV);
|
||||
console.register(CL_KEYBIND_SNEAK);
|
||||
console.register(CL_KEYBIND_SPRINT);
|
||||
console.register(CL_KEYBIND_JUMP);
|
||||
}
|
||||
|
||||
#[derive(Hash, PartialEq, Eq)]
|
||||
pub enum Stevenkey {
|
||||
Forward,
|
||||
Backward,
|
||||
Left,
|
||||
Right,
|
||||
OpenInv,
|
||||
Sneak,
|
||||
Sprint,
|
||||
Jump,
|
||||
}
|
||||
|
||||
impl Stevenkey {
|
||||
pub fn values() -> Vec<Stevenkey> {
|
||||
vec!(Stevenkey::Forward, Stevenkey::Backward, Stevenkey::Left,
|
||||
Stevenkey::Right, Stevenkey::OpenInv, Stevenkey::Sneak,
|
||||
Stevenkey::Sprint, Stevenkey::Jump)
|
||||
}
|
||||
|
||||
pub fn get_by_keycode(keycode: Keycode, console: &console::Console) -> Option<Stevenkey> {
|
||||
for steven_key in Stevenkey::values() {
|
||||
if keycode as i64 == *console.get(steven_key.get_cvar()) {
|
||||
return Some(steven_key)
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
pub fn get_cvar(&self) -> console::CVar<i64> {
|
||||
match *self {
|
||||
Stevenkey::Forward => CL_KEYBIND_FORWARD,
|
||||
Stevenkey::Backward => CL_KEYBIND_BACKWARD,
|
||||
Stevenkey::Left => CL_KEYBIND_LEFT,
|
||||
Stevenkey::Right => CL_KEYBIND_RIGHT,
|
||||
Stevenkey::OpenInv => CL_KEYBIND_OPEN_INV,
|
||||
Stevenkey::Sneak => CL_KEYBIND_SNEAK,
|
||||
Stevenkey::Sprint => CL_KEYBIND_SPRINT,
|
||||
Stevenkey::Jump => CL_KEYBIND_JUMP
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue