Crate unification (#88)

* move client/server/config into shared

* move platforms into shared

* move head drops into shared

* move tb_entities to shared

* reduce server to just a call into shared

* get solo play working

* fix server opening window

* fix fmt

* extracted a few more modules from client

* near completely migrated client

* fixed duplicate CharacterInputEnabled definition

* simplify a few things related to builds

* more simplifications

* fix warnings/check

* ci update

* address comments

* try fixing macos steam build

* address comments

* address comments

* CI tweaks with default client feature

---------

Co-authored-by: PROMETHIA-27 <electriccobras@gmail.com>
This commit is contained in:
extrawurst
2025-12-18 18:31:22 +01:00
committed by GitHub
parent c80129dac1
commit 7cfae285ed
100 changed files with 1099 additions and 1791 deletions

View File

@@ -0,0 +1,229 @@
pub mod abilities;
pub mod ai;
pub mod aim;
pub mod animation;
pub mod backpack;
pub mod camera;
pub mod cash;
pub mod cash_heal;
pub mod character;
#[cfg(feature = "client")]
pub mod client;
pub mod config;
pub mod control;
pub mod cutscene;
pub mod gates;
pub mod head;
pub mod head_drop;
pub mod heads;
pub mod heads_database;
pub mod hitpoints;
pub mod keys;
pub mod loading_assets;
pub mod loading_map;
pub mod movables;
pub mod npc;
pub mod physics_layers;
pub mod platforms;
pub mod player;
pub mod protocol;
pub mod server;
pub mod tb_entities;
pub mod tick;
pub mod utils;
pub mod water;
use crate::{
config::NetworkingConfig,
heads_database::{HeadDatabaseAsset, HeadsDatabase},
protocol::{PlayerId, messages::AssignClientPlayer},
tb_entities::SpawnPoint,
};
use avian3d::{PhysicsPlugins, prelude::TransformInterpolation};
#[cfg(not(feature = "client"))]
use bevy::app::ScheduleRunnerPlugin;
use bevy::{core_pipeline::tonemapping::Tonemapping, prelude::*};
use bevy_common_assets::ron::RonAssetPlugin;
use bevy_replicon::{RepliconPlugins, prelude::ClientId};
use bevy_replicon_renet::RepliconRenetPlugins;
use bevy_sprite3d::Sprite3dPlugin;
use bevy_trenchbroom::{
TrenchBroomPlugins, config::TrenchBroomConfig, prelude::TrenchBroomPhysicsPlugin,
};
use bevy_trenchbroom_avian::AvianPhysicsBackend;
use utils::{billboards, squish_animation};
pub const HEDZ_GREEN: Srgba = Srgba::rgb(0.0, 1.0, 0.0);
pub const HEDZ_PURPLE: Srgba = Srgba::rgb(91. / 256., 4. / 256., 138. / 256.);
pub fn launch() {
let mut app = App::new();
app.register_type::<DebugVisuals>()
.register_type::<TransformInterpolation>();
app.insert_resource(DebugVisuals {
unlit: false,
tonemapping: Tonemapping::None,
exposure: 1.,
shadows: true,
cam_follow: true,
});
let default_plugins = DefaultPlugins;
#[cfg(feature = "client")]
let default_plugins = default_plugins.set(WindowPlugin {
primary_window: Some(Window {
title: "HEDZ Reloaded".into(),
..default()
}),
..default()
});
app.add_plugins(default_plugins);
#[cfg(not(feature = "client"))]
app.add_plugins(ScheduleRunnerPlugin::default());
#[cfg(feature = "client")]
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((RepliconPlugins, RepliconRenetPlugins));
app.add_plugins(Sprite3dPlugin);
app.add_plugins(TrenchBroomPlugins(
TrenchBroomConfig::new("hedz").icon(None),
));
app.add_plugins(TrenchBroomPhysicsPlugin::new(AvianPhysicsBackend));
app.add_plugins(RonAssetPlugin::<HeadDatabaseAsset>::new(&["headsdb.ron"]));
app.add_plugins(plugin);
app.init_state::<GameState>();
app.run();
}
pub fn plugin(app: &mut App) {
app.add_plugins(abilities::plugin);
app.add_plugins(ai::plugin);
app.add_plugins(animation::plugin);
app.add_plugins(character::plugin);
app.add_plugins(cash::plugin);
app.add_plugins(cash_heal::plugin);
app.add_plugins(config::plugin);
app.add_plugins(player::plugin);
app.add_plugins(gates::plugin);
app.add_plugins(platforms::plugin);
app.add_plugins(movables::plugin);
app.add_plugins(utils::billboards::plugin);
app.add_plugins(aim::plugin);
app.add_plugins(npc::plugin);
app.add_plugins(keys::plugin);
app.add_plugins(utils::squish_animation::plugin);
app.add_plugins(camera::plugin);
#[cfg(feature = "client")]
app.add_plugins(client::plugin);
app.add_plugins(control::plugin);
app.add_plugins(cutscene::plugin);
app.add_plugins(backpack::plugin);
app.add_plugins(loading_assets::LoadingPlugin);
app.add_plugins(loading_map::plugin);
app.add_plugins(heads::plugin);
app.add_plugins(hitpoints::plugin);
app.add_plugins(head_drop::plugin);
app.add_plugins(protocol::plugin);
app.add_plugins(server::plugin);
app.add_plugins(tb_entities::plugin);
app.add_plugins(tick::plugin);
app.add_plugins(utils::plugin);
app.add_plugins(utils::auto_rotate::plugin);
app.add_plugins(utils::explosions::plugin);
app.add_plugins(utils::sprite_3d_animation::plugin);
app.add_plugins(utils::trail::plugin);
app.add_plugins(water::plugin);
if cfg!(feature = "client") {
app.add_systems(
OnEnter(GameState::Waiting),
start_solo_client
.run_if(|config: Res<NetworkingConfig>| config.server.is_none() && !config.host),
);
app.add_systems(
OnEnter(GameState::Waiting),
start_listen_server
.run_if(|config: Res<NetworkingConfig>| config.server.is_none() && config.host),
);
app.add_systems(
OnEnter(GameState::Waiting),
start_client.run_if(|config: Res<NetworkingConfig>| config.server.is_some()),
);
} else {
app.add_systems(OnEnter(GameState::Waiting), start_dedicated_server);
}
}
#[derive(Resource, Reflect, Debug)]
#[reflect(Resource)]
pub struct DebugVisuals {
pub unlit: bool,
pub tonemapping: Tonemapping,
pub exposure: f32,
pub shadows: bool,
pub cam_follow: bool,
}
#[derive(States, Default, Clone, Copy, Eq, PartialEq, Debug, Hash)]
pub enum GameState {
/// Loading assets from disk
#[default]
AssetLoading,
/// Loading + constructing map
MapLoading,
/// Waiting to host/connect/play
Waiting,
/// Connecting to server
Connecting,
/// Opening server
Hosting,
/// Running the game
Playing,
}
fn start_solo_client(
commands: Commands,
mut next: ResMut<NextState<GameState>>,
query: Query<&Transform, With<SpawnPoint>>,
heads_db: Res<HeadsDatabase>,
mut assign_player_id: MessageWriter<AssignClientPlayer>,
) {
next.set(GameState::Playing);
player::spawn(commands, ClientId::Server, query, heads_db);
assign_player_id.write(AssignClientPlayer(PlayerId { id: 0 }));
}
fn start_listen_server(
commands: Commands,
mut next: ResMut<NextState<GameState>>,
query: Query<&Transform, With<SpawnPoint>>,
heads_db: Res<HeadsDatabase>,
mut assign_player_id: MessageWriter<AssignClientPlayer>,
) {
next.set(GameState::Hosting);
player::spawn(commands, ClientId::Server, query, heads_db);
assign_player_id.write(AssignClientPlayer(PlayerId { id: 0 }));
}
fn start_client(mut next: ResMut<NextState<GameState>>) {
next.set(GameState::Connecting);
}
fn start_dedicated_server(mut next: ResMut<NextState<GameState>>) {
next.set(GameState::Hosting);
}