mod backpack; mod client; mod config; mod control; mod debug; mod enemy; mod heal_effect; mod player; mod sounds; mod steam; mod ui; use avian3d::prelude::*; use bevy::{ audio::{PlaybackMode, Volume}, core_pipeline::tonemapping::Tonemapping, prelude::*, render::view::ColorGrading, }; use bevy_common_assets::ron::RonAssetPlugin; use bevy_sprite3d::Sprite3dPlugin; use bevy_trenchbroom::prelude::*; use bevy_trenchbroom_avian::AvianPhysicsBackend; use camera::MainCamera; use heads_database::HeadDatabaseAsset; use loading_assets::AudioAssets; use shared::*; fn main() { let mut app = App::new(); app.register_type::() .register_type::(); app.insert_resource(DebugVisuals { unlit: false, tonemapping: Tonemapping::None, exposure: 1., shadows: true, cam_follow: true, }); app.add_plugins( DefaultPlugins .set(WindowPlugin { primary_window: Some(Window { title: "HEDZ Reloaded".into(), // resolution: (1024., 768.).into(), ..default() }), ..default() }) .set(bevy::log::LogPlugin { filter: "info,lightyear_replication=off,bevy_ecs::hierarchy=off".into(), level: bevy::log::Level::INFO, // provide custom log layer to receive logging events custom_layer: bevy_debug_log::log_capture_layer, ..default() }), ); app.add_plugins(steam::plugin); app.add_plugins( bevy_debug_log::LogViewerPlugin::default() .auto_open_threshold(bevy::log::tracing::level_filters::LevelFilter::OFF), ); app.add_plugins(PhysicsPlugins::default()); app.add_plugins(Sprite3dPlugin); app.add_plugins(TrenchBroomPlugins( TrenchBroomConfig::new("hedz") .icon(None) .default_solid_spawn_hooks(|| SpawnHooks::new().convex_collider()), )); app.add_plugins(TrenchBroomPhysicsPlugin::new(AvianPhysicsBackend)); app.add_plugins(RonAssetPlugin::::new(&["headsdb.ron"])); #[cfg(feature = "dbg")] { app.add_plugins(bevy_inspector_egui::bevy_egui::EguiPlugin::default()); app.add_plugins(bevy_inspector_egui::quick::WorldInspectorPlugin::new()); app.add_plugins(PhysicsDebugPlugin::default()); // app.add_plugins(bevy::pbr::wireframe::WireframePlugin) // .insert_resource(bevy::pbr::wireframe::WireframeConfig { // global: true, // default_color: bevy::color::palettes::css::WHITE.into(), // }); } app.add_plugins(shared::ai::plugin); app.add_plugins(shared::animation::plugin); app.add_plugins(shared::character::plugin); app.add_plugins(shared::cash::plugin); app.add_plugins(shared::player::plugin); app.add_plugins(shared::gates::plugin); app.add_plugins(shared::platforms::plugin); app.add_plugins(shared::movables::plugin); app.add_plugins(shared::utils::billboards::plugin); app.add_plugins(shared::aim::plugin); app.add_plugins(shared::npc::plugin); app.add_plugins(shared::keys::plugin); app.add_plugins(shared::utils::squish_animation::plugin); app.add_plugins(shared::cutscene::plugin); app.add_plugins(shared::control::plugin); app.add_plugins(shared::camera::plugin); app.add_plugins(shared::backpack::plugin); app.add_plugins(shared::loading_assets::LoadingPlugin); app.add_plugins(shared::loading_map::plugin); app.add_plugins(shared::utils::sprite_3d_animation::plugin); app.add_plugins(shared::abilities::plugin); app.add_plugins(shared::heads::plugin); app.add_plugins(shared::hitpoints::plugin); app.add_plugins(shared::cash_heal::plugin); app.add_plugins(shared::utils::plugin); app.add_plugins(shared::water::plugin); app.add_plugins(shared::head_drop::plugin); app.add_plugins(shared::utils::trail::plugin); app.add_plugins(shared::utils::auto_rotate::plugin); app.add_plugins(shared::tb_entities::plugin); app.add_plugins(shared::tick::plugin); app.add_plugins(shared::utils::explosions::plugin); // Networking // The client/server plugin must go before the protocol, or else `ProtocolHasher` will not be available. app.add_plugins(client::plugin); app.add_plugins(shared::protocol::plugin); app.add_plugins(backpack::plugin); app.add_plugins(config::plugin); app.add_plugins(control::plugin); app.add_plugins(debug::plugin); app.add_plugins(enemy::plugin); app.add_plugins(heal_effect::plugin); app.add_plugins(player::plugin); app.add_plugins(sounds::plugin); app.add_plugins(ui::plugin); app.init_state::(); app.insert_resource(AmbientLight { color: Color::WHITE, brightness: 400., ..Default::default() }); app.insert_resource(ClearColor(Color::BLACK)); //TODO: let user control this app.insert_resource(GlobalVolume::new(Volume::Linear(0.4))); app.add_systems(Startup, write_trenchbroom_config); app.add_systems(OnEnter(GameState::Playing), music); app.add_systems(Update, (set_materials_unlit, set_tonemapping, set_shadows)); app.run(); } fn music(assets: Res, mut commands: Commands) { commands.spawn(( Name::new("sfx-music"), AudioPlayer::new(assets.music.clone()), PlaybackSettings { mode: PlaybackMode::Loop, volume: Volume::Linear(0.5), ..default() }, )); commands.spawn(( Name::new("sfx-ambient"), AudioPlayer::new(assets.ambient.clone()), PlaybackSettings { mode: PlaybackMode::Loop, volume: Volume::Linear(0.8), ..default() }, )); } fn write_trenchbroom_config(server: Res, type_registry: Res) { if let Err(e) = server .config .write_game_config("trenchbroom/hedz", &type_registry.read()) { warn!("Failed to write trenchbroom config: {}", e); } } fn set_tonemapping( mut cams: Query<(&mut Tonemapping, &mut ColorGrading), With>, visuals: Res, ) { for (mut tm, mut color) in cams.iter_mut() { *tm = visuals.tonemapping; color.global.exposure = visuals.exposure; } } fn set_materials_unlit( mut materials: ResMut>, visuals: Res, ) { if !materials.is_changed() { return; } for (_, material) in materials.iter_mut() { material.unlit = visuals.unlit; } } fn set_shadows(mut lights: Query<&mut DirectionalLight>, visuals: Res) { for mut l in lights.iter_mut() { l.shadows_enabled = visuals.shadows; } }