/* * This file is part of laurelin/client * Copyright (C) 2023 Jonni Liljamo * * Licensed under GPL-3.0-only. * See LICENSE for licensing information. */ use bevy::{ app::AppExit, prelude::*, window::{ CompositeAlphaMode, Cursor, CursorGrabMode, PresentMode, WindowLevel, WindowMode, WindowResizeConstraints, WindowResolution, }, }; #[cfg(feature = "dev")] use bevy_editor_pls::EditorPlugin; use naia_bevy_client::{Client, ClientConfig as NaiaClientConfig, Plugin as NaiaClientPlugin}; use laurelin_shared::server::protocol::protocol; mod cfg; mod constants; mod plugins; mod runtime; mod util; // NOTE: lua things, currently not in use //use bevy_mod_scripting::prelude::*; //mod lua; /// Used to control the state of the game #[derive(Debug, Clone, Eq, PartialEq, Hash, Default, States)] pub enum GameState { #[default] Splash, Loading, MainMenu, Game, } struct MainLoop; fn main() { let mut app = App::new(); app.add_plugins(DefaultPlugins.set(WindowPlugin { primary_window: Some(Window { cursor: Cursor { icon: CursorIcon::Default, visible: true, grab_mode: CursorGrabMode::None, hit_test: true, ..Default::default() }, present_mode: PresentMode::Fifo, mode: WindowMode::Windowed, position: WindowPosition::Centered(MonitorSelection::Primary), resolution: WindowResolution::new(1280., 720.), title: "Laurelin".to_string(), composite_alpha_mode: CompositeAlphaMode::Auto, resize_constraints: WindowResizeConstraints { min_width: 1280., min_height: 720., max_width: 3840., max_height: 2160., }, resizable: false, decorations: true, transparent: false, focused: true, window_level: WindowLevel::Normal, canvas: None, fit_canvas_to_parent: false, prevent_default_event_handling: false, ime_enabled: false, ..Default::default() }), ..Default::default() })); #[cfg(feature = "dev")] app.add_plugin(EditorPlugin); //app.add_plugin(ScriptingPlugin).add_plugin(lua::LuaPlugin); app.insert_resource(cfg::CfgDirs( directories::ProjectDirs::from("com", "liljamo", "deckbuilder") .expect("failed to get project directories"), )); app.insert_resource(cfg::CfgSettings::default()) .insert_resource(cfg::CfgUser::default()) .insert_resource(cfg::CfgDev::default()); app.add_startup_system(setup).add_state::(); app.add_plugin(plugins::config::ConfigPlugin) .add_plugin(plugins::phases::splash::SplashPlugin) .add_plugin(plugins::phases::loading::LoadingPlugin) .add_plugin(plugins::menu::MenuPlugin); // Lastly, add in runtime data structs //app.insert_resource(runtime::menu::RTDMenu::default()) // .insert_resource(runtime::game::RTDGame::default()); // Networking app.add_plugin(NaiaClientPlugin::new( NaiaClientConfig::default(), protocol(), )) .add_plugin(plugins::networking::NetworkingPlugin); // Graceful exit app.add_event::() .add_system(handle_graceful_exit); app.run(); } fn setup(mut commands: Commands) { // Spawn a camera commands.spawn(Camera3dBundle::default()); } /// Utility function do despawn an entity and all its children pub fn despawn_screen(to_despawn: Query>, mut commands: Commands) { for entity in &to_despawn { commands.entity(entity).despawn_recursive(); } } pub struct GracefulExit; /// Graceful exit, disconnects client cleanly before closing pub fn handle_graceful_exit( mut ev: EventReader, mut app_exit_events: EventWriter, mut client: Client, ) { for _ in ev.iter() { if client.is_connected() { client.disconnect(); } app_exit_events.send(AppExit); } }