- Add crouch cancelling - Add IASA for aerial attacks - Add scaffolding for autocancel - Add hitbox group system - Add new ergonomic features for attack scripting - Add more information to the hitbox viewer - Improve the looks of debug capsules Reviewed-on: #82 Co-authored-by: Álex Román Núñez <eirexe@eirteam.moe>
214 lines
7.5 KiB
Rust
214 lines
7.5 KiB
Rust
//! game-test: gameplay shared between `cargo run` and the
|
|
//! editor's Play button.
|
|
//!
|
|
//! Scene content (entities, components, positions) lives in
|
|
//! `assets/*.bsn` files authored in the editor. Game behaviour
|
|
//! (systems, observers, resources) lives in [`GamePlugin`].
|
|
//!
|
|
//! # Try it
|
|
//!
|
|
//! 1. Open this project in jackdaw.
|
|
//! 2. Hierarchy: right-click, `Add > Cube`.
|
|
//! 3. Inspector: `Add Component > SpinningCube`. Set `speed` to `1.5`.
|
|
//! 4. `File > Save`, then click Play. The cube spins.
|
|
//! 5. `cargo run` launches the same game without the editor.
|
|
//!
|
|
//! # Adding your own components
|
|
//!
|
|
//! Write a component anywhere in this library (any module, not
|
|
//! `main.rs`), deriving `Component, Reflect, Default` with
|
|
//! `#[reflect(Component, Default)]`, like `SpinningCube` below. After you
|
|
//! save, click Rebuild in jackdaw (or run `jd build`) and it
|
|
//! appears in `Add Component`. No registration code is needed.
|
|
|
|
#![recursion_limit = "512"]
|
|
|
|
use bevy::{
|
|
asset::processor::{AssetProcessor, ProcessorState},
|
|
prelude::*,
|
|
settings::SettingsPlugin,
|
|
tasks::block_on,
|
|
};
|
|
use bevy_asset_loader::prelude::*;
|
|
use clap::Parser;
|
|
use ron_asset_manager::RonAssetPlugin;
|
|
|
|
use crate::{
|
|
camera::MatchCameraPlugin, fighter::manifest::FighterManifest, game_settings::GameSettings,
|
|
match_runtime::MatchRuntimePlugin, materials::ShinesparkMaterialPlugin,
|
|
menus::style::FGUiStyle, schedule::GameplaySchedulePlugin, stage::manifest::StageManifest,
|
|
ui::InGameUIPlugin,
|
|
};
|
|
|
|
mod args;
|
|
pub mod blend_asset;
|
|
pub mod camera;
|
|
pub mod debug_tools;
|
|
pub mod fighter;
|
|
pub mod filled_gizmos;
|
|
pub mod game_settings;
|
|
pub mod input;
|
|
#[cfg(feature = "hitbox-viewer")]
|
|
pub mod hitbox_viewer;
|
|
pub mod match_loading;
|
|
pub mod match_runtime;
|
|
pub mod materials;
|
|
mod math;
|
|
pub mod menus;
|
|
pub mod netcode;
|
|
pub mod player;
|
|
pub mod replay;
|
|
pub mod schedule;
|
|
pub mod scripting;
|
|
pub mod stage;
|
|
pub mod texture_reference;
|
|
pub mod ui;
|
|
pub mod egui_color_convert;
|
|
|
|
#[derive(States, Debug, Clone, Copy, Eq, PartialEq, Hash, Default)]
|
|
pub enum AppState {
|
|
#[default]
|
|
WaitForAssetProcessing,
|
|
LoadCommonAssets,
|
|
LoadFighterManifests,
|
|
PrepareFighterManifests,
|
|
LoadStageManifests,
|
|
PrepareStageManifests,
|
|
CommonAssetLoadFailed,
|
|
PreMainMenu,
|
|
MainMenu,
|
|
CharacterSelect,
|
|
StageSelect,
|
|
LoadingMatch,
|
|
PreparingMatch,
|
|
InMatch,
|
|
MatchResults,
|
|
MatchDisconnected,
|
|
MatchLoadFailed,
|
|
}
|
|
|
|
/// Your game's Bevy plugin. The editor finds it by this name (override
|
|
/// with `plugin = "..."` in jackdaw.toml) and runs it on Play; the
|
|
/// standalone binary adds it in `main.rs`.
|
|
#[derive(Default)]
|
|
pub struct GamePlugin;
|
|
|
|
/// Registers every custom asset loader used by the game and asset processor.
|
|
pub struct GameAssetPlugin;
|
|
|
|
impl Plugin for GameAssetPlugin {
|
|
fn build(&self, app: &mut App) {
|
|
app.add_plugins((
|
|
blend_asset::BlendAssetProcessingPlugin,
|
|
RonAssetPlugin::<FighterManifest>::create("fighter.ron"),
|
|
RonAssetPlugin::<StageManifest>::create("stage.ron"),
|
|
RonAssetPlugin::<GameSettings>::create("ron"),
|
|
RonAssetPlugin::<FGUiStyle>::create("stylesheet.ron"),
|
|
));
|
|
}
|
|
}
|
|
|
|
impl Plugin for GamePlugin {
|
|
fn build(&self, app: &mut App) {
|
|
// Each module owns its own systems, rollback registrations and
|
|
// resources; this plugin only wires them together and supplies the
|
|
// game-level content and configuration.
|
|
app.init_state::<AppState>()
|
|
.add_plugins((
|
|
(
|
|
SettingsPlugin::new("moe.eirteam.shinespark.debug_settings"),
|
|
// Brings up GGRS (and with it `GgrsSchedule`), so it goes first.
|
|
netcode::FighterNetcodePlugin::default(),
|
|
GameplaySchedulePlugin,
|
|
MatchRuntimePlugin,
|
|
input::FighterInputPlugin,
|
|
replay::ReplayPlugin,
|
|
debug_tools::DebugToolsPlugin,
|
|
filled_gizmos::FilledGizmosPlugin,
|
|
fighter::FighterPlugin,
|
|
fighter::baked_animation::BakedAnimationPlugin,
|
|
scripting::importer::FighterScriptImportPlugin,
|
|
stage::StagePlugin,
|
|
MatchCameraPlugin,
|
|
GameAssetPlugin,
|
|
InGameUIPlugin,
|
|
),
|
|
ShinesparkMaterialPlugin,
|
|
))
|
|
.add_plugins(menus::MenuPlugin)
|
|
.add_loading_state(
|
|
LoadingState::new(AppState::LoadingMatch)
|
|
.continue_to_state(AppState::PreparingMatch)
|
|
.on_failure_continue_to_state(AppState::MatchLoadFailed)
|
|
.load_collection::<match_loading::MatchAssets>(),
|
|
)
|
|
.add_loading_state(
|
|
LoadingState::new(AppState::LoadCommonAssets)
|
|
.continue_to_state(AppState::LoadFighterManifests)
|
|
.on_failure_continue_to_state(AppState::CommonAssetLoadFailed)
|
|
.load_collection::<game_settings::CommonAssets>()
|
|
.finally_init_resource::<GameSettings>(),
|
|
)
|
|
.add_loading_state(
|
|
LoadingState::new(AppState::LoadFighterManifests)
|
|
.continue_to_state(AppState::PrepareFighterManifests)
|
|
.on_failure_continue_to_state(AppState::CommonAssetLoadFailed)
|
|
.load_collection::<fighter::manifest::FighterManifestAssets>(),
|
|
)
|
|
.add_loading_state(
|
|
LoadingState::new(AppState::LoadStageManifests)
|
|
.continue_to_state(AppState::PrepareStageManifests)
|
|
.on_failure_continue_to_state(AppState::CommonAssetLoadFailed)
|
|
.load_collection::<stage::manifest::StageManifestAssets>(),
|
|
)
|
|
.add_systems(
|
|
Update,
|
|
wait_for_asset_processor.run_if(in_state(AppState::WaitForAssetProcessing)),
|
|
)
|
|
.add_systems(
|
|
OnEnter(AppState::PrepareFighterManifests),
|
|
fighter::manifest::prepare_fighter_manifests,
|
|
)
|
|
.add_systems(
|
|
OnEnter(AppState::PrepareStageManifests),
|
|
stage::manifest::prepare_stage_manifests,
|
|
)
|
|
.add_systems(
|
|
OnEnter(AppState::PreMainMenu),
|
|
match_loading::initiate_default_match,
|
|
)
|
|
.add_systems(
|
|
OnEnter(AppState::PreparingMatch),
|
|
match_loading::prepare_match,
|
|
)
|
|
.add_systems(OnExit(AppState::InMatch), match_loading::cleanup_match)
|
|
.insert_resource(args::Args::parse());
|
|
}
|
|
}
|
|
|
|
/// Registers the custom asset loaders and processors used by CI and release
|
|
/// builds. The processing binary adds this plugin without starting the game.
|
|
pub struct AssetProcessingPlugin;
|
|
|
|
impl Plugin for AssetProcessingPlugin {
|
|
fn build(&self, app: &mut App) {
|
|
app.add_plugins((
|
|
GameAssetPlugin,
|
|
scripting::importer::FighterScriptImportPlugin,
|
|
fighter::baked_animation::BakedAnimationAssetProcessingPlugin,
|
|
));
|
|
}
|
|
}
|
|
|
|
fn wait_for_asset_processor(
|
|
processor: Option<Res<AssetProcessor>>,
|
|
mut next_state: ResMut<NextState<AppState>>,
|
|
) {
|
|
if !cfg!(feature = "development")
|
|
|| processor
|
|
.is_none_or(|processor| block_on(processor.get_state()) == ProcessorState::Finished)
|
|
{
|
|
next_state.set(AppState::LoadCommonAssets);
|
|
}
|
|
}
|