mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'fix-singleplayer' into 'master'
Implement StartSingleplayerState See merge request veloren/veloren!81 Former-commit-id: 64bf5ff7e4db2640dedfccdcff5c0e1e34a2f6b3
This commit is contained in:
@ -25,7 +25,6 @@ use crate::{
|
|||||||
menu::main::MainMenuState,
|
menu::main::MainMenuState,
|
||||||
window::Window,
|
window::Window,
|
||||||
settings::Settings,
|
settings::Settings,
|
||||||
singleplayer::Singleplayer,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// The URL of the default public server that Voxygen will connect to
|
/// 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 {
|
pub struct GlobalState {
|
||||||
settings: Settings,
|
settings: Settings,
|
||||||
window: Window,
|
window: Window,
|
||||||
singleplayer: Option<Singleplayer>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlobalState {
|
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,
|
// 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
|
// or switch to a totally different state
|
||||||
pub enum PlayStateResult {
|
pub enum PlayStateResult {
|
||||||
@ -65,7 +68,7 @@ pub enum PlayStateResult {
|
|||||||
pub trait PlayState {
|
pub trait PlayState {
|
||||||
/// Play the state until some change of state is required (i.e: a menu is opened or the game
|
/// Play the state until some change of state is required (i.e: a menu is opened or the game
|
||||||
/// is closed).
|
/// 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
|
/// Get a descriptive name for this state type
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> &'static str;
|
||||||
@ -123,7 +126,6 @@ The information below is intended for developers and testers.
|
|||||||
let mut global_state = GlobalState {
|
let mut global_state = GlobalState {
|
||||||
settings,
|
settings,
|
||||||
window,
|
window,
|
||||||
singleplayer: None,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Set up the initial play state
|
// 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.
|
// 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
|
// 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.
|
// 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
|
// Implement state transfer logic
|
||||||
match state_result {
|
match state_result {
|
||||||
PlayStateResult::Shutdown => {
|
PlayStateResult::Shutdown => {
|
||||||
|
direction = Direction::Backwards;
|
||||||
log::info!("Shutting down all states...");
|
log::info!("Shutting down all states...");
|
||||||
while states.last().is_some() {
|
while states.last().is_some() {
|
||||||
states.pop().map(|old_state| {
|
states.pop().map(|old_state| {
|
||||||
@ -154,17 +158,20 @@ The information below is intended for developers and testers.
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
PlayStateResult::Pop => {
|
PlayStateResult::Pop => {
|
||||||
|
direction = Direction::Backwards;
|
||||||
states.pop().map(|old_state| {
|
states.pop().map(|old_state| {
|
||||||
log::info!("Popped state '{}'", old_state.name());
|
log::info!("Popped state '{}'", old_state.name());
|
||||||
global_state.on_play_state_changed();
|
global_state.on_play_state_changed();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
PlayStateResult::Push(new_state) => {
|
PlayStateResult::Push(new_state) => {
|
||||||
|
direction = Direction::Forwards;
|
||||||
log::info!("Pushed state '{}'", new_state.name());
|
log::info!("Pushed state '{}'", new_state.name());
|
||||||
states.push(new_state);
|
states.push(new_state);
|
||||||
global_state.on_play_state_changed();
|
global_state.on_play_state_changed();
|
||||||
},
|
},
|
||||||
PlayStateResult::Switch(mut new_state) => {
|
PlayStateResult::Switch(mut new_state) => {
|
||||||
|
direction = Direction::Forwards;
|
||||||
states.last_mut().map(|old_state| {
|
states.last_mut().map(|old_state| {
|
||||||
log::info!("Switching to state '{}' from state '{}'", new_state.name(), old_state.name());
|
log::info!("Switching to state '{}' from state '{}'", new_state.name(), old_state.name());
|
||||||
mem::swap(old_state, &mut new_state);
|
mem::swap(old_state, &mut new_state);
|
||||||
|
@ -3,7 +3,7 @@ mod ui;
|
|||||||
use crate::{
|
use crate::{
|
||||||
window::{Event, Window},
|
window::{Event, Window},
|
||||||
session::SessionState,
|
session::SessionState,
|
||||||
GlobalState, PlayState, PlayStateResult,
|
Direction, GlobalState, PlayState, PlayStateResult,
|
||||||
};
|
};
|
||||||
use client::{self, Client};
|
use client::{self, Client};
|
||||||
use common::{
|
use common::{
|
||||||
@ -40,7 +40,7 @@ const BG_COLOR: Rgba<f32> = Rgba {
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl PlayState for CharSelectionState {
|
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
|
// Set up an fps clock
|
||||||
let mut clock = Clock::new();
|
let mut clock = Clock::new();
|
||||||
|
|
||||||
@ -49,7 +49,6 @@ impl PlayState for CharSelectionState {
|
|||||||
for event in global_state.window.fetch_events() {
|
for event in global_state.window.fetch_events() {
|
||||||
match event {
|
match event {
|
||||||
Event::Close => {
|
Event::Close => {
|
||||||
global_state.singleplayer = None;
|
|
||||||
return PlayStateResult::Shutdown;
|
return PlayStateResult::Shutdown;
|
||||||
},
|
},
|
||||||
// Pass events to ui
|
// 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()) {
|
for event in self.char_selection_ui.maintain(global_state.window.renderer_mut()) {
|
||||||
match event {
|
match event {
|
||||||
ui::Event::Logout => {
|
ui::Event::Logout => {
|
||||||
global_state.singleplayer = None;
|
|
||||||
return PlayStateResult::Pop;
|
return PlayStateResult::Pop;
|
||||||
},
|
},
|
||||||
ui::Event::Play => {
|
ui::Event::Play => {
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
mod client_init;
|
mod client_init;
|
||||||
|
mod start_singleplayer;
|
||||||
mod ui;
|
mod ui;
|
||||||
|
|
||||||
|
use start_singleplayer::StartSingleplayerState;
|
||||||
use super::char_selection::CharSelectionState;
|
use super::char_selection::CharSelectionState;
|
||||||
use crate::{
|
use crate::{
|
||||||
window::{Event, Window},
|
window::{Event, Window},
|
||||||
GlobalState, PlayState, PlayStateResult,
|
Direction, GlobalState, PlayState, PlayStateResult,
|
||||||
singleplayer::Singleplayer,
|
|
||||||
};
|
};
|
||||||
use client_init::{ClientInit, Error as InitError};
|
use client_init::{ClientInit, Error as InitError};
|
||||||
use common::{clock::Clock, comp};
|
use common::{clock::Clock, comp};
|
||||||
@ -28,6 +29,8 @@ impl MainMenuState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_PORT: u16 = 59003;
|
||||||
|
|
||||||
// Background colour
|
// Background colour
|
||||||
const BG_COLOR: Rgba<f32> = Rgba {
|
const BG_COLOR: Rgba<f32> = Rgba {
|
||||||
r: 0.0,
|
r: 0.0,
|
||||||
@ -37,7 +40,7 @@ const BG_COLOR: Rgba<f32> = Rgba {
|
|||||||
};
|
};
|
||||||
|
|
||||||
impl PlayState for MainMenuState {
|
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
|
// Set up an fps clock
|
||||||
let mut clock = Clock::new();
|
let mut clock = Clock::new();
|
||||||
|
|
||||||
@ -98,7 +101,6 @@ impl PlayState for MainMenuState {
|
|||||||
net_settings.servers.push(server_address.clone());
|
net_settings.servers.push(server_address.clone());
|
||||||
}
|
}
|
||||||
global_state.settings.save_to_file();
|
global_state.settings.save_to_file();
|
||||||
const DEFAULT_PORT: u16 = 59003;
|
|
||||||
// Don't try to connect if there is already a connection in progress
|
// Don't try to connect if there is already a connection in progress
|
||||||
client_init = client_init.or(Some(ClientInit::new(
|
client_init = client_init.or(Some(ClientInit::new(
|
||||||
(server_address, DEFAULT_PORT, false),
|
(server_address, DEFAULT_PORT, false),
|
||||||
@ -109,7 +111,7 @@ impl PlayState for MainMenuState {
|
|||||||
)));
|
)));
|
||||||
},
|
},
|
||||||
MainMenuEvent::StartSingleplayer => {
|
MainMenuEvent::StartSingleplayer => {
|
||||||
global_state.singleplayer = Some(Singleplayer::new());
|
return PlayStateResult::Push(Box::new(StartSingleplayerState::new()));
|
||||||
},
|
},
|
||||||
MainMenuEvent::Quit => return PlayStateResult::Shutdown,
|
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"
|
||||||
|
}
|
||||||
|
}
|
@ -180,6 +180,7 @@ impl MainMenuUi {
|
|||||||
.font_size(14)
|
.font_size(14)
|
||||||
.color(TEXT_COLOR)
|
.color(TEXT_COLOR)
|
||||||
.set(self.ids.version, ui_widgets);
|
.set(self.ids.version, ui_widgets);
|
||||||
|
|
||||||
// Input fields
|
// Input fields
|
||||||
// Used when the login button is pressed, or enter is pressed within input field
|
// Used when the login button is pressed, or enter is pressed within input field
|
||||||
macro_rules! login {
|
macro_rules! login {
|
||||||
|
@ -6,6 +6,7 @@ use client::{
|
|||||||
Client,
|
Client,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
Direction,
|
||||||
Error,
|
Error,
|
||||||
PlayState,
|
PlayState,
|
||||||
PlayStateResult,
|
PlayStateResult,
|
||||||
@ -100,7 +101,7 @@ impl SessionState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PlayState for 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
|
// Trap the cursor
|
||||||
global_state.window.grab_cursor(true);
|
global_state.window.grab_cursor(true);
|
||||||
|
|
||||||
@ -129,7 +130,6 @@ impl PlayState for SessionState {
|
|||||||
}
|
}
|
||||||
let _handled = match event {
|
let _handled = match event {
|
||||||
Event::Close => {
|
Event::Close => {
|
||||||
global_state.singleplayer = None;
|
|
||||||
return PlayStateResult::Shutdown;
|
return PlayStateResult::Shutdown;
|
||||||
},
|
},
|
||||||
// Toggle cursor grabbing
|
// Toggle cursor grabbing
|
||||||
@ -171,7 +171,6 @@ impl PlayState for SessionState {
|
|||||||
},
|
},
|
||||||
HudEvent::Logout => return PlayStateResult::Pop,
|
HudEvent::Logout => return PlayStateResult::Pop,
|
||||||
HudEvent::Quit => {
|
HudEvent::Quit => {
|
||||||
global_state.singleplayer = None;
|
|
||||||
return PlayStateResult::Shutdown;
|
return PlayStateResult::Shutdown;
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user