|
|
|
@ -1,95 +1,70 @@ |
|
|
|
use bevy::prelude::*; |
|
|
|
use bevy::prelude::*; |
|
|
|
use common::prelude::network::*; |
|
|
|
use common::network::*; |
|
|
|
use common::prelude::*; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use bevy::asset::AssetMetaCheck; |
|
|
|
|
|
|
|
use bevy::window::WindowResolution; |
|
|
|
use bevy::window::WindowResolution; |
|
|
|
use lightyear::prelude::server::Started; |
|
|
|
use lightyear::prelude::server::Started; |
|
|
|
|
|
|
|
|
|
|
|
mod args; |
|
|
|
mod args; |
|
|
|
mod block_assets; |
|
|
|
mod block; |
|
|
|
mod camera; |
|
|
|
mod camera; |
|
|
|
mod loading; |
|
|
|
|
|
|
|
mod placement; |
|
|
|
mod placement; |
|
|
|
|
|
|
|
|
|
|
|
use args::*; |
|
|
|
use args::*; |
|
|
|
|
|
|
|
use block::*; |
|
|
|
use camera::*; |
|
|
|
use camera::*; |
|
|
|
use placement::*; |
|
|
|
use placement::*; |
|
|
|
|
|
|
|
|
|
|
|
#[derive(States, Clone, Copy, PartialEq, Eq, Hash, Debug)] |
|
|
|
#[rustfmt::skip] |
|
|
|
pub enum Screen { |
|
|
|
|
|
|
|
Loading, |
|
|
|
|
|
|
|
Gameplay, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fn main() -> Result { |
|
|
|
fn main() -> Result { |
|
|
|
|
|
|
|
let cli = Args::parse(); |
|
|
|
let mut app = App::new(); |
|
|
|
let mut app = App::new(); |
|
|
|
|
|
|
|
|
|
|
|
app.add_plugins( |
|
|
|
app.add_plugins(DefaultPlugins.set(WindowPlugin { |
|
|
|
DefaultPlugins |
|
|
|
primary_window: Some(Window { |
|
|
|
.set(WindowPlugin { |
|
|
|
title: "bevy-bloxel-classic".into(), |
|
|
|
primary_window: Some(Window { |
|
|
|
// Steam Deck: DPI appears pretty high, causing everything to be scaled up.
|
|
|
|
title: "bevy-bloxel-classic".into(), |
|
|
|
// Setting `scale_factor_override` prevents this from happening.
|
|
|
|
// Steam Deck: DPI appears pretty high, causing everything to be scaled up.
|
|
|
|
resolution: WindowResolution::new(1280, 720).with_scale_factor_override(1.0), |
|
|
|
// Setting `scale_factor_override` prevents this from happening.
|
|
|
|
// WEB: Fit canvas to parent element, so `Window` resizes automatically.
|
|
|
|
resolution: WindowResolution::new(1280, 720).with_scale_factor_override(1.0), |
|
|
|
fit_canvas_to_parent: true, |
|
|
|
// WEB: Fit canvas to parent element, so `Window` resizes automatically.
|
|
|
|
// WEB: Don't override default event handling like browser hotkeys while focused.
|
|
|
|
fit_canvas_to_parent: true, |
|
|
|
prevent_default_event_handling: false, |
|
|
|
// WEB: Don't override default event handling like browser hotkeys while focused.
|
|
|
|
..default() |
|
|
|
prevent_default_event_handling: false, |
|
|
|
}), |
|
|
|
..default() |
|
|
|
..default() |
|
|
|
}), |
|
|
|
})); |
|
|
|
..default() |
|
|
|
|
|
|
|
}) |
|
|
|
// Fixes issue on web where the cursor isn't ungrabbed properly.
|
|
|
|
.set(AssetPlugin { |
|
|
|
app.add_plugins(bevy_fix_cursor_unlock_web::FixPointerUnlockPlugin); |
|
|
|
// WEB: Don't check for `.meta` files since we don't use them.
|
|
|
|
|
|
|
|
meta_check: AssetMetaCheck::Never, |
|
|
|
app.add_plugins(common::network::ServerPlugin); |
|
|
|
..default() |
|
|
|
app.add_plugins(common::network::ClientPlugin); |
|
|
|
}), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.add_plugins(( |
|
|
|
|
|
|
|
bevy_fix_cursor_unlock_web::FixPointerUnlockPlugin, |
|
|
|
|
|
|
|
ServerPlugin, |
|
|
|
|
|
|
|
ClientPlugin, |
|
|
|
|
|
|
|
common::asset_loading::plugin, |
|
|
|
|
|
|
|
block_assets::plugin, |
|
|
|
|
|
|
|
loading::plugin, |
|
|
|
|
|
|
|
)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app.insert_resource(Args::parse()); |
|
|
|
app.add_systems(Startup, setup_crosshair); |
|
|
|
app.insert_state(Screen::Loading); |
|
|
|
app.add_systems(Startup, setup_blocks); |
|
|
|
|
|
|
|
app.add_systems(Startup, setup_scene.after(setup_blocks)); |
|
|
|
app.add_systems( |
|
|
|
|
|
|
|
OnEnter(Screen::Gameplay), |
|
|
|
app.add_systems(Update, cursor_grab); |
|
|
|
(setup_crosshair, setup_scene, start_server_or_connect), |
|
|
|
app.add_systems(Update, update_crosshair_visibility.after(cursor_grab)); |
|
|
|
); |
|
|
|
app.add_systems(Update, camera_look.after(cursor_grab).run_if(is_cursor_grabbed)); |
|
|
|
|
|
|
|
app.add_systems(Update, noclip_controller.after(camera_look).run_if(is_cursor_grabbed)); |
|
|
|
// TODO: Create and configure `SystemSet`s for gameplay, input, etc.
|
|
|
|
|
|
|
|
app.add_systems( |
|
|
|
|
|
|
|
Update, |
|
|
|
|
|
|
|
( |
|
|
|
|
|
|
|
cursor_grab, |
|
|
|
|
|
|
|
update_crosshair_visibility.after(cursor_grab), |
|
|
|
|
|
|
|
camera_look.after(cursor_grab).run_if(is_cursor_grabbed), |
|
|
|
|
|
|
|
noclip_controller |
|
|
|
|
|
|
|
.after(camera_look) |
|
|
|
|
|
|
|
.run_if(is_cursor_grabbed), |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
.run_if(in_state(Screen::Gameplay)), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// `place_break_blocks` requires the camera's `GlobalTransform`.
|
|
|
|
// `place_break_blocks` requires the camera's `GlobalTransform`.
|
|
|
|
// For a most up-to-date value, run it after that's been updated.
|
|
|
|
// For a most up-to-date value, run it after that's been updated.
|
|
|
|
app.add_systems( |
|
|
|
app.add_systems(PostUpdate, place_break_blocks.after(TransformSystems::Propagate)); |
|
|
|
PostUpdate, |
|
|
|
|
|
|
|
place_break_blocks |
|
|
|
|
|
|
|
.after(TransformSystems::Propagate) |
|
|
|
|
|
|
|
.run_if(in_state(Screen::Gameplay).and(is_cursor_grabbed)), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: Move this to a more general world generation module.
|
|
|
|
|
|
|
|
app.add_observer(spawn_initial_blocks); |
|
|
|
app.add_observer(spawn_initial_blocks); |
|
|
|
|
|
|
|
app.add_observer(add_block_visuals); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut commands = app.world_mut().commands(); |
|
|
|
|
|
|
|
match cli.mode.unwrap_or_default() { |
|
|
|
|
|
|
|
Mode::Local => commands.queue(StartLocalServerCommand), |
|
|
|
|
|
|
|
#[cfg(not(target_family = "wasm"))] |
|
|
|
|
|
|
|
Mode::Host { port } => commands.queue(StartWebTransportServerCommand::new(port)), |
|
|
|
|
|
|
|
Mode::Connect { address, digest } => commands.queue(ConnectWebTransportCommand::new(&address, digest)?), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// NOTE: When setting up a local server, a host-client is automatically
|
|
|
|
|
|
|
|
// connected to it thanks to the `autoconnect_host_client` observer.
|
|
|
|
|
|
|
|
|
|
|
|
app.run(); |
|
|
|
app.run(); |
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
@ -119,23 +94,3 @@ fn spawn_initial_blocks(_event: On<Add, Started>, mut blocks: Blocks) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
fn start_server_or_connect(args: Res<Args>, mut commands: Commands) -> Result { |
|
|
|
|
|
|
|
let mode = args.mode.as_ref(); |
|
|
|
|
|
|
|
let default = Mode::default(); |
|
|
|
|
|
|
|
match mode.unwrap_or(&default) { |
|
|
|
|
|
|
|
Mode::Local => { |
|
|
|
|
|
|
|
commands.queue(StartLocalServerCommand); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#[cfg(not(target_family = "wasm"))] |
|
|
|
|
|
|
|
Mode::Host { port } => { |
|
|
|
|
|
|
|
commands.queue(StartWebTransportServerCommand::new(*port)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Mode::Connect { address, digest } => { |
|
|
|
|
|
|
|
commands.queue(ConnectWebTransportCommand::new(&address, digest.clone())?); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// NOTE: When setting up a local server, a host-client is automatically
|
|
|
|
|
|
|
|
// connected to it thanks to the `autoconnect_host_client` observer.
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|