/* * This file is part of laurelin_client * Copyright (C) 2023 Jonni Liljamo * * Licensed under GPL-3.0-only. * See LICENSE for licensing information. */ #![allow(clippy::too_many_arguments)] #![allow(clippy::derivable_impls)] #![allow(clippy::type_complexity)] use api::user::User; use bevy::{ input::mouse::{MouseScrollUnit, MouseWheel}, prelude::*, }; use bevy_assets_bundler::*; use bevy_editor_pls::EditorPlugin; use bevy_egui::EguiPlugin; use bevy_mod_picking::prelude::*; use bevy_rapier3d::prelude::*; use bevy_text_mesh::prelude::*; mod api; mod macros; mod util; mod plugins; mod game_status; use game_status::Card; #[macro_export] macro_rules! seed_gen { () => { fastrand::u64(u64::MIN..=u64::MAX) }; } #[derive(Debug, Clone, PartialEq, Eq, Hash, Default, States)] enum AppState { #[default] Menu, InGame, } fn main() { let key = [ 25, 221, 123, 82, 182, 95, 251, 128, 83, 192, 172, 139, 92, 102, 34, 248, ]; let mut asset_bundling_options = AssetBundlingOptions::default(); asset_bundling_options.set_encryption_key(key); asset_bundling_options.encode_file_names = true; asset_bundling_options.enabled_on_debug_build = true; let mut app = App::new(); app.add_plugins( DefaultPlugins .set(WindowPlugin { primary_window: Some(Window { title: String::from("Laurelin Client"), ..Default::default() }), ..Default::default() }) .build() .add_before::(BundledAssetIoPlugin::from(asset_bundling_options)), ); app.add_plugin(RapierPhysicsPlugin::::default()); app.add_plugin(TextMeshPlugin); app.add_plugins(DefaultPickingPlugins); app.insert_resource(AmbientLight { color: Color::ANTIQUE_WHITE, brightness: 0.4, }); info!("laurelin client initializing"); // dev app.add_plugin(RapierDebugRenderPlugin::default()); app.add_plugin(EditorPlugin::new()); app.insert_resource(editor_controls()); // the egui plugin is also added by the editor plugin if !app.is_plugin_added::() { app.add_plugin(EguiPlugin); } // clear color app.insert_resource(ClearColor(Color::rgb(0.53, 0.53, 0.7))); // yaml assets app.add_asset::() .init_asset_loader::(); // add the top level app state app.add_state::(); // holds networking options and a request agent app.register_type::() .init_resource::(); app.register_type::() .register_type::() .init_resource::(); // has handlers for all async tasks app.add_plugin(plugins::AsyncTasksPlugin); app.add_plugin(plugins::MenuPlugin); app.add_plugin(plugins::GamePlugin); app.add_event::() .add_system(load_card_manifest.run_if(on_event::())); app.add_startup_system(setup).add_system(move_camera); app.run(); info!("goodbye"); } #[derive(Component)] struct PlayerCamera; fn setup( mut commands: Commands, asset_server: Res, mut lcm_ev_w: EventWriter, ) { commands.insert_resource(CardManifestHandle { handle: asset_server.load("card_manifest.yaml") }); lcm_ev_w.send(LoadCardManifestEvent); commands .spawn(( Camera3dBundle { transform: Transform { translation: Vec3::new(0., 5.5, 5.8), rotation: Quat::from_rotation_x(-1.2), ..Default::default() }, ..Default::default() }, RapierPickCamera::default(), )) .insert(PlayerCamera); } struct LoadCardManifestEvent; fn load_card_manifest( mut commands: Commands, yaml_assets: Res>, card_manifest_handle: Res, ) { let card_manifest_yaml: String = yaml_assets.get(&card_manifest_handle.handle).unwrap().0.clone(); let card_manifest: CardManifest = serde_yaml::from_str(&card_manifest_yaml).unwrap(); commands.insert_resource(card_manifest); } fn move_camera( time: Res