@ -1,25 +1,33 @@
use bevy ::prelude ::* ;
use bevy ::prelude ::* ;
use common ::network ::* ;
use common ::prelude ::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 ;
mod block_assets ;
mod camera ;
mod camera ;
mod loading ;
mod placement ;
mod placement ;
use args ::* ;
use args ::* ;
use block ::* ;
use camera ::* ;
use camera ::* ;
use placement ::* ;
use placement ::* ;
#[ rustfmt::skip ]
#[ derive(States, Clone, Copy, PartialEq, Eq, Hash, Debug) ]
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 ( DefaultPlugins . set ( WindowPlugin {
app . add_plugins (
DefaultPlugins
. set ( WindowPlugin {
primary_window : Some ( Window {
primary_window : Some ( Window {
title : "bevy-bloxel-classic" . into ( ) ,
title : "bevy-bloxel-classic" . into ( ) ,
// Steam Deck: DPI appears pretty high, causing everything to be scaled up.
// Steam Deck: DPI appears pretty high, causing everything to be scaled up.
@ -32,39 +40,56 @@ fn main() -> Result {
.. default ( )
.. default ( )
} ) ,
} ) ,
.. default ( )
.. default ( )
} ) ) ;
} )
. set ( AssetPlugin {
// Fixes issue on web where the cursor isn't ungrabbed properly.
// WEB: Don't check for `.meta` files since we don't use them.
app . add_plugins ( bevy_fix_cursor_unlock_web ::FixPointerUnlockPlugin ) ;
meta_check : AssetMetaCheck ::Never ,
.. default ( )
app . add_plugins ( common ::network ::ServerPlugin ) ;
} ) ,
app . add_plugins ( common ::network ::ClientPlugin ) ;
) ;
app . add_systems ( Startup , setup_crosshair ) ;
app . add_plugins ( (
app . add_systems ( Startup , setup_blocks ) ;
bevy_fix_cursor_unlock_web ::FixPointerUnlockPlugin ,
app . add_systems ( Startup , setup_scene . after ( setup_blocks ) ) ;
ServerPlugin ,
ClientPlugin ,
common ::asset_loading ::plugin ,
block_assets ::plugin ,
loading ::plugin ,
) ) ;
app . add_systems ( Update , cursor_grab ) ;
app . insert_resource ( Args ::parse ( ) ) ;
app . add_systems ( Update , update_crosshair_visibility . after ( cursor_grab ) ) ;
app . insert_state ( Screen ::Loading ) ;
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 ) ) ;
app . add_systems (
OnEnter ( Screen ::Gameplay ) ,
( setup_crosshair , setup_scene , start_server_or_connect ) ,
) ;
// 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 ( PostUpdate , place_break_blocks . after ( TransformSystems ::Propagate ) ) ;
app . add_systems (
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 ( ( ) )
@ -94,3 +119,23 @@ 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 ( ( ) )
}