Files
HEDZReloaded/crates/hedz_reloaded/src/lib.rs
2025-12-20 13:19:13 -05:00

250 lines
7.0 KiB
Rust

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::NetConfig,
heads_database::{HeadDatabaseAsset, HeadsDatabase},
protocol::{PlayerIdCounter, 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_steamworks::SteamworksEvent;
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<NetConfig>| config.is_singleplayer()),
);
app.add_systems(
OnEnter(GameState::Waiting),
start_listen_server.run_if(|config: Res<NetConfig>| config.is_host()),
);
app.add_systems(
OnEnter(GameState::Waiting),
start_client.run_if(|config: Res<NetConfig>| config.is_client()),
);
} else {
app.add_systems(OnEnter(GameState::Waiting), start_dedicated_server);
}
app.add_systems(Update, log_steam_events);
}
#[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 log_steam_events(events: Option<MessageReader<SteamworksEvent>>) {
let Some(mut events) = events else {
return;
};
for event in events.read() {
let SteamworksEvent::CallbackResult(result) = event;
info!("steam: {:?}", result);
}
}
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>,
mut ids: ResMut<PlayerIdCounter>,
) {
next.set(GameState::Playing);
ids.reset();
let id = ids.alloc();
player::spawn(commands, ClientId::Server, id, query, heads_db);
assign_player_id.write(AssignClientPlayer(id));
}
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>,
mut ids: ResMut<PlayerIdCounter>,
) {
next.set(GameState::Hosting);
ids.reset();
let id = ids.alloc();
player::spawn(commands, ClientId::Server, id, query, heads_db);
assign_player_id.write(AssignClientPlayer(id));
}
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);
}