mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Implement StartSingleplayerState
Former-commit-id: 982246096fe20c33631c1df3ce172c60b4f49bfe
This commit is contained in:
parent
b72c6b7185
commit
a4d7d0d488
@ -25,7 +25,6 @@ use crate::{
|
||||
menu::main::MainMenuState,
|
||||
window::Window,
|
||||
settings::Settings,
|
||||
singleplayer::Singleplayer,
|
||||
};
|
||||
|
||||
/// The URL of the default public server that Voxygen will connect to
|
||||
@ -35,7 +34,6 @@ const DEFAULT_PUBLIC_SERVER: &'static str = "server.veloren.net";
|
||||
pub struct GlobalState {
|
||||
settings: Settings,
|
||||
window: Window,
|
||||
singleplayer: Option<Singleplayer>,
|
||||
}
|
||||
|
||||
impl GlobalState {
|
||||
@ -47,6 +45,11 @@ impl GlobalState {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Direction {
|
||||
Forwards,
|
||||
Backwards,
|
||||
}
|
||||
|
||||
// States can either close (and revert to a previous state), push a new state on top of themselves,
|
||||
// or switch to a totally different state
|
||||
pub enum PlayStateResult {
|
||||
@ -65,7 +68,7 @@ pub enum PlayStateResult {
|
||||
pub trait PlayState {
|
||||
/// Play the state until some change of state is required (i.e: a menu is opened or the game
|
||||
/// is closed).
|
||||
fn play(&mut self, global_state: &mut GlobalState) -> PlayStateResult;
|
||||
fn play(&mut self, direction: Direction, global_state: &mut GlobalState) -> PlayStateResult;
|
||||
|
||||
/// Get a descriptive name for this state type
|
||||
fn name(&self) -> &'static str;
|
||||
@ -123,7 +126,6 @@ The information below is intended for developers and testers.
|
||||
let mut global_state = GlobalState {
|
||||
settings,
|
||||
window,
|
||||
singleplayer: None,
|
||||
};
|
||||
|
||||
// Set up the initial play state
|
||||
@ -141,10 +143,12 @@ The information below is intended for developers and testers.
|
||||
// which can in turn push a "settings" state or a "game session" state on top of it.
|
||||
// The code below manages the state transfer logic automatically so that we don't have to
|
||||
// re-engineer it for each menu we decide to add to the game.
|
||||
while let Some(state_result) = states.last_mut().map(|last| last.play(&mut global_state)){
|
||||
let mut direction = Direction::Forwards;
|
||||
while let Some(state_result) = states.last_mut().map(|last| last.play(direction, &mut global_state)){
|
||||
// Implement state transfer logic
|
||||
match state_result {
|
||||
PlayStateResult::Shutdown => {
|
||||
direction = Direction::Backwards;
|
||||
log::info!("Shutting down all states...");
|
||||
while states.last().is_some() {
|
||||
states.pop().map(|old_state| {
|
||||
@ -154,17 +158,20 @@ The information below is intended for developers and testers.
|
||||
}
|
||||
},
|
||||
PlayStateResult::Pop => {
|
||||
direction = Direction::Backwards;
|
||||
states.pop().map(|old_state| {
|
||||
log::info!("Popped state '{}'", old_state.name());
|
||||
global_state.on_play_state_changed();
|
||||
});
|
||||
},
|
||||
PlayStateResult::Push(new_state) => {
|
||||
direction = Direction::Forwards;
|
||||
log::info!("Pushed state '{}'", new_state.name());
|
||||
states.push(new_state);
|
||||
global_state.on_play_state_changed();
|
||||
},
|
||||
PlayStateResult::Switch(mut new_state) => {
|
||||
direction = Direction::Forwards;
|
||||
states.last_mut().map(|old_state| {
|
||||
log::info!("Switching to state '{}' from state '{}'", new_state.name(), old_state.name());
|
||||
mem::swap(old_state, &mut new_state);
|
||||
|
@ -3,7 +3,7 @@ mod ui;
|
||||
use crate::{
|
||||
window::{Event, Window},
|
||||
session::SessionState,
|
||||
GlobalState, PlayState, PlayStateResult,
|
||||
Direction, GlobalState, PlayState, PlayStateResult,
|
||||
};
|
||||
use client::{self, Client};
|
||||
use common::{
|
||||
@ -40,7 +40,7 @@ const BG_COLOR: Rgba<f32> = Rgba {
|
||||
};
|
||||
|
||||
impl PlayState for CharSelectionState {
|
||||
fn play(&mut self, global_state: &mut GlobalState) -> PlayStateResult {
|
||||
fn play(&mut self, _: Direction, global_state: &mut GlobalState) -> PlayStateResult {
|
||||
// Set up an fps clock
|
||||
let mut clock = Clock::new();
|
||||
|
||||
@ -49,7 +49,6 @@ impl PlayState for CharSelectionState {
|
||||
for event in global_state.window.fetch_events() {
|
||||
match event {
|
||||
Event::Close => {
|
||||
global_state.singleplayer = None;
|
||||
return PlayStateResult::Shutdown;
|
||||
},
|
||||
// Pass events to ui
|
||||
@ -67,7 +66,6 @@ impl PlayState for CharSelectionState {
|
||||
for event in self.char_selection_ui.maintain(global_state.window.renderer_mut()) {
|
||||
match event {
|
||||
ui::Event::Logout => {
|
||||
global_state.singleplayer = None;
|
||||
return PlayStateResult::Pop;
|
||||
},
|
||||
ui::Event::Play => {
|
||||
|
@ -1,11 +1,12 @@
|
||||
mod client_init;
|
||||
mod start_singleplayer;
|
||||
mod ui;
|
||||
|
||||
use start_singleplayer::StartSingleplayerState;
|
||||
use super::char_selection::CharSelectionState;
|
||||
use crate::{
|
||||
window::{Event, Window},
|
||||
GlobalState, PlayState, PlayStateResult,
|
||||
singleplayer::Singleplayer,
|
||||
Direction, GlobalState, PlayState, PlayStateResult,
|
||||
};
|
||||
use client_init::{ClientInit, Error as InitError};
|
||||
use common::{clock::Clock, comp};
|
||||
@ -28,6 +29,8 @@ impl MainMenuState {
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_PORT: u16 = 59003;
|
||||
|
||||
// Background colour
|
||||
const BG_COLOR: Rgba<f32> = Rgba {
|
||||
r: 0.0,
|
||||
@ -37,7 +40,7 @@ const BG_COLOR: Rgba<f32> = Rgba {
|
||||
};
|
||||
|
||||
impl PlayState for MainMenuState {
|
||||
fn play(&mut self, global_state: &mut GlobalState) -> PlayStateResult {
|
||||
fn play(&mut self, _: Direction, global_state: &mut GlobalState) -> PlayStateResult {
|
||||
// Set up an fps clock
|
||||
let mut clock = Clock::new();
|
||||
|
||||
@ -98,7 +101,6 @@ impl PlayState for MainMenuState {
|
||||
net_settings.servers.push(server_address.clone());
|
||||
}
|
||||
global_state.settings.save_to_file();
|
||||
const DEFAULT_PORT: u16 = 59003;
|
||||
// Don't try to connect if there is already a connection in progress
|
||||
client_init = client_init.or(Some(ClientInit::new(
|
||||
(server_address, DEFAULT_PORT, false),
|
||||
@ -109,7 +111,7 @@ impl PlayState for MainMenuState {
|
||||
)));
|
||||
},
|
||||
MainMenuEvent::StartSingleplayer => {
|
||||
global_state.singleplayer = Some(Singleplayer::new());
|
||||
return PlayStateResult::Push(Box::new(StartSingleplayerState::new()));
|
||||
},
|
||||
MainMenuEvent::Quit => return PlayStateResult::Shutdown,
|
||||
}
|
||||
|
66
voxygen/src/menu/main/start_singleplayer.rs
Normal file
66
voxygen/src/menu/main/start_singleplayer.rs
Normal file
@ -0,0 +1,66 @@
|
||||
use common::comp;
|
||||
use super::{DEFAULT_PORT, client_init::ClientInit};
|
||||
use crate::{
|
||||
menu::char_selection::CharSelectionState,
|
||||
singleplayer::Singleplayer,
|
||||
Direction, GlobalState, PlayState, PlayStateResult,
|
||||
};
|
||||
|
||||
pub struct StartSingleplayerState {
|
||||
singleplayer: Singleplayer,
|
||||
}
|
||||
|
||||
impl StartSingleplayerState {
|
||||
/// Create a new `MainMenuState`
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
singleplayer: Singleplayer::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PlayState for StartSingleplayerState {
|
||||
fn play(&mut self, direction: Direction, global_state: &mut GlobalState) -> PlayStateResult {
|
||||
match direction {
|
||||
Direction::Forwards => {
|
||||
let username = "singleplayer".to_owned();
|
||||
let server_address = "localhost".to_owned();
|
||||
|
||||
let client_init = ClientInit::new(
|
||||
(server_address.clone(), DEFAULT_PORT, false),
|
||||
(
|
||||
comp::Player::new(username.clone()),
|
||||
300,
|
||||
),
|
||||
);
|
||||
|
||||
// Client creation
|
||||
let client = loop {
|
||||
match client_init.poll() {
|
||||
Some(Ok(client)) => break client,
|
||||
// Should always work
|
||||
Some(Err(err)) => unreachable!(),
|
||||
_ => {},
|
||||
}
|
||||
};
|
||||
|
||||
let mut net_settings = &mut global_state.settings.networking;
|
||||
net_settings.username = username.clone();
|
||||
if !net_settings.servers.contains(&server_address) {
|
||||
net_settings.servers.push(server_address.clone());
|
||||
}
|
||||
global_state.settings.save_to_file();
|
||||
|
||||
PlayStateResult::Push(Box::new(CharSelectionState::new(
|
||||
&mut global_state.window,
|
||||
std::rc::Rc::new(std::cell::RefCell::new(client)),
|
||||
)))
|
||||
},
|
||||
Direction::Backwards => PlayStateResult::Pop,
|
||||
}
|
||||
}
|
||||
|
||||
fn name(&self) -> &'static str {
|
||||
"Starting Singleplayer"
|
||||
}
|
||||
}
|
@ -176,10 +176,11 @@ impl MainMenuUi {
|
||||
.top_left_with_margins(30.0, 30.0)
|
||||
.set(self.ids.v_logo, ui_widgets);
|
||||
Text::new(version)
|
||||
.top_left_with_margins_on(ui_widgets.window, 5.0, 5.0)
|
||||
.font_size(14)
|
||||
.color(TEXT_COLOR)
|
||||
.set(self.ids.version, ui_widgets);
|
||||
.top_left_with_margins_on(ui_widgets.window, 5.0, 5.0)
|
||||
.font_size(14)
|
||||
.color(TEXT_COLOR)
|
||||
.set(self.ids.version, ui_widgets);
|
||||
|
||||
// Input fields
|
||||
// Used when the login button is pressed, or enter is pressed within input field
|
||||
macro_rules! login {
|
||||
@ -390,7 +391,7 @@ impl MainMenuUi {
|
||||
};
|
||||
|
||||
// Singleplayer button
|
||||
if Button::image(self.imgs.button)
|
||||
if Button::image(self.imgs.button)
|
||||
.hover_image(self.imgs.button_hover)
|
||||
.press_image(self.imgs.button_press)
|
||||
.w_h(258.0, 68.0)
|
||||
|
@ -6,6 +6,7 @@ use client::{
|
||||
Client,
|
||||
};
|
||||
use crate::{
|
||||
Direction,
|
||||
Error,
|
||||
PlayState,
|
||||
PlayStateResult,
|
||||
@ -100,7 +101,7 @@ impl SessionState {
|
||||
}
|
||||
|
||||
impl PlayState for SessionState {
|
||||
fn play(&mut self, global_state: &mut GlobalState) -> PlayStateResult {
|
||||
fn play(&mut self, _: Direction, global_state: &mut GlobalState) -> PlayStateResult {
|
||||
// Trap the cursor
|
||||
global_state.window.grab_cursor(true);
|
||||
|
||||
@ -129,7 +130,6 @@ impl PlayState for SessionState {
|
||||
}
|
||||
let _handled = match event {
|
||||
Event::Close => {
|
||||
global_state.singleplayer = None;
|
||||
return PlayStateResult::Shutdown;
|
||||
},
|
||||
// Toggle cursor grabbing
|
||||
@ -171,7 +171,6 @@ impl PlayState for SessionState {
|
||||
},
|
||||
HudEvent::Logout => return PlayStateResult::Pop,
|
||||
HudEvent::Quit => {
|
||||
global_state.singleplayer = None;
|
||||
return PlayStateResult::Shutdown;
|
||||
},
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user