Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7271d02e29 | ||
|
|
866a9c7500 |
@@ -109,7 +109,6 @@ impl FighterDebugRowKind {
|
|||||||
enum DebugFlag {
|
enum DebugFlag {
|
||||||
Network,
|
Network,
|
||||||
Ecb,
|
Ecb,
|
||||||
BlastZones,
|
|
||||||
StageCollision,
|
StageCollision,
|
||||||
AnimationBones,
|
AnimationBones,
|
||||||
AttackHitboxes,
|
AttackHitboxes,
|
||||||
@@ -151,10 +150,6 @@ const FIGHTER_MENU: &[DebugMenuEntry] = &[
|
|||||||
label: "ECB",
|
label: "ECB",
|
||||||
flag: DebugFlag::Ecb,
|
flag: DebugFlag::Ecb,
|
||||||
},
|
},
|
||||||
DebugMenuEntry::Toggle {
|
|
||||||
label: "Blast Zones",
|
|
||||||
flag: DebugFlag::BlastZones,
|
|
||||||
},
|
|
||||||
DebugMenuEntry::Toggle {
|
DebugMenuEntry::Toggle {
|
||||||
label: "Animation bones",
|
label: "Animation bones",
|
||||||
flag: DebugFlag::AnimationBones,
|
flag: DebugFlag::AnimationBones,
|
||||||
@@ -248,7 +243,6 @@ pub struct DebugSettings {
|
|||||||
pub frame_stepping: bool,
|
pub frame_stepping: bool,
|
||||||
pub network: bool,
|
pub network: bool,
|
||||||
pub ecb: bool,
|
pub ecb: bool,
|
||||||
pub blast_zones: bool,
|
|
||||||
pub stage_collision: bool,
|
pub stage_collision: bool,
|
||||||
pub animation_bones: bool,
|
pub animation_bones: bool,
|
||||||
pub attack_hitboxes: bool,
|
pub attack_hitboxes: bool,
|
||||||
@@ -270,7 +264,6 @@ impl Default for DebugSettings {
|
|||||||
frame_stepping: false,
|
frame_stepping: false,
|
||||||
network: false,
|
network: false,
|
||||||
ecb: false,
|
ecb: false,
|
||||||
blast_zones: false,
|
|
||||||
stage_collision: false,
|
stage_collision: false,
|
||||||
animation_bones: false,
|
animation_bones: false,
|
||||||
attack_hitboxes: false,
|
attack_hitboxes: false,
|
||||||
@@ -335,7 +328,6 @@ impl DebugSettings {
|
|||||||
match flag {
|
match flag {
|
||||||
DebugFlag::Network => self.network,
|
DebugFlag::Network => self.network,
|
||||||
DebugFlag::Ecb => self.ecb,
|
DebugFlag::Ecb => self.ecb,
|
||||||
DebugFlag::BlastZones => self.blast_zones,
|
|
||||||
DebugFlag::StageCollision => self.stage_collision,
|
DebugFlag::StageCollision => self.stage_collision,
|
||||||
DebugFlag::AnimationBones => self.animation_bones,
|
DebugFlag::AnimationBones => self.animation_bones,
|
||||||
DebugFlag::AttackHitboxes => self.attack_hitboxes,
|
DebugFlag::AttackHitboxes => self.attack_hitboxes,
|
||||||
@@ -350,7 +342,6 @@ impl DebugSettings {
|
|||||||
match flag {
|
match flag {
|
||||||
DebugFlag::Network => self.network = !self.network,
|
DebugFlag::Network => self.network = !self.network,
|
||||||
DebugFlag::Ecb => self.ecb = !self.ecb,
|
DebugFlag::Ecb => self.ecb = !self.ecb,
|
||||||
DebugFlag::BlastZones => self.blast_zones = !self.blast_zones,
|
|
||||||
DebugFlag::StageCollision => self.stage_collision = !self.stage_collision,
|
DebugFlag::StageCollision => self.stage_collision = !self.stage_collision,
|
||||||
DebugFlag::AnimationBones => self.animation_bones = !self.animation_bones,
|
DebugFlag::AnimationBones => self.animation_bones = !self.animation_bones,
|
||||||
DebugFlag::AttackHitboxes => self.attack_hitboxes = !self.attack_hitboxes,
|
DebugFlag::AttackHitboxes => self.attack_hitboxes = !self.attack_hitboxes,
|
||||||
@@ -893,10 +884,6 @@ pub fn stage_collision_enabled(settings: Res<DebugSettings>) -> bool {
|
|||||||
settings.stage_collision
|
settings.stage_collision
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn blast_zones_enabled(settings: Res<DebugSettings>) -> bool {
|
|
||||||
settings.blast_zones
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn animation_bones_enabled(settings: Res<DebugSettings>) -> bool {
|
pub fn animation_bones_enabled(settings: Res<DebugSettings>) -> bool {
|
||||||
settings.animation_bones
|
settings.animation_bones
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-53
@@ -21,6 +21,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
input::{LocalInputAssignments, LocalInputSource},
|
input::{LocalInputAssignments, LocalInputSource},
|
||||||
match_runtime::MatchState,
|
match_runtime::MatchState,
|
||||||
|
math::{int::FGi32, vec::FGVec2},
|
||||||
netcode::{
|
netcode::{
|
||||||
GGRSCfg,
|
GGRSCfg,
|
||||||
session::{ConnectionStatus, SessionConfig, create_session},
|
session::{ConnectionStatus, SessionConfig, create_session},
|
||||||
@@ -276,7 +277,7 @@ pub fn prepare_match(
|
|||||||
if !valid_player_handles(&config.players) {
|
if !valid_player_handles(&config.players) {
|
||||||
fail_match(
|
fail_match(
|
||||||
&mut next_state,
|
&mut next_state,
|
||||||
"player handles must be unique and non-empty",
|
"player handles must be unique and cover 0..player_count",
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -286,20 +287,6 @@ pub fn prepare_match(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let stage_handle = stage_registry
|
|
||||||
.get(config.stage)
|
|
||||||
.expect("Initialization check should ensure all stages exist");
|
|
||||||
let stage_manifest = stage_manifests
|
|
||||||
.get(&stage_handle)
|
|
||||||
.expect("Initialization check should ensure stage manifests are kept alive");
|
|
||||||
let spawn_positions = match stage_manifest.neutral_spawn_positions(config.players.len()) {
|
|
||||||
Ok(positions) => positions,
|
|
||||||
Err(error) => {
|
|
||||||
fail_match(&mut next_state, &error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if assets.fighters.len() != config.players.len() {
|
if assets.fighters.len() != config.players.len() {
|
||||||
fail_match(
|
fail_match(
|
||||||
&mut next_state,
|
&mut next_state,
|
||||||
@@ -462,8 +449,7 @@ pub fn prepare_match(
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let session_player_count = player_count_for_handles(&config.players);
|
let session_config = match SessionConfig::from_args(&args, config.players.len()) {
|
||||||
let session_config = match SessionConfig::from_args(&args, session_player_count) {
|
|
||||||
Ok(config) => config,
|
Ok(config) => config,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
fail_match(
|
fail_match(
|
||||||
@@ -473,7 +459,7 @@ pub fn prepare_match(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let session = match create_session(&args, session_player_count) {
|
let session = match create_session(&args, config.players.len()) {
|
||||||
Ok(session) => session,
|
Ok(session) => session,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
fail_match(
|
fail_match(
|
||||||
@@ -486,6 +472,12 @@ pub fn prepare_match(
|
|||||||
|
|
||||||
let root = commands.spawn((Name::new("Match"), MatchRoot)).id();
|
let root = commands.spawn((Name::new("Match"), MatchRoot)).id();
|
||||||
|
|
||||||
|
let stage_handle = stage_registry
|
||||||
|
.get(config.stage)
|
||||||
|
.expect("Initialization check should ensure all stages exist");
|
||||||
|
let stage_manifest = stage_manifests
|
||||||
|
.get(&stage_handle)
|
||||||
|
.expect("Initialization check should ensure stage manifests are kept alive");
|
||||||
stage::spawn_stage(
|
stage::spawn_stage(
|
||||||
&mut commands,
|
&mut commands,
|
||||||
root,
|
root,
|
||||||
@@ -495,15 +487,14 @@ pub fn prepare_match(
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut fighter_roster = Vec::with_capacity(config.players.len());
|
let mut fighter_roster = Vec::with_capacity(config.players.len());
|
||||||
|
for (index, (player, (scene, animations, attack_scripts, manifest_handle, model_scale, ecb_bone_indices))) in
|
||||||
for (spawn_index, (player, (scene, animations, attack_scripts, manifest_handle, model_scale, ecb_bone_indices))) in
|
|
||||||
config.players.iter().zip(prepared).enumerate()
|
config.players.iter().zip(prepared).enumerate()
|
||||||
{
|
{
|
||||||
let spawn_point = spawn_positions[spawn_index];
|
let spawn_x = (index as i32 * 2 + 1 - config.players.len() as i32) * 5;
|
||||||
fighter_roster.push(spawn_fighter(
|
fighter_roster.push(spawn_fighter(
|
||||||
&mut commands,
|
&mut commands,
|
||||||
player.handle,
|
player.handle,
|
||||||
spawn_point,
|
FGVec2::new(FGi32::from_num(spawn_x), FGi32::lit("12.5")),
|
||||||
manifest_handle.clone(),
|
manifest_handle.clone(),
|
||||||
model_scale,
|
model_scale,
|
||||||
animations,
|
animations,
|
||||||
@@ -527,22 +518,12 @@ fn fail_match(next_state: &mut NextState<AppState>, message: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn valid_player_handles(players: &[MatchPlayer]) -> bool {
|
fn valid_player_handles(players: &[MatchPlayer]) -> bool {
|
||||||
if players.is_empty() {
|
let mut handles = players
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut handles = players.iter().map(|player| player.handle).collect::<Vec<_>>();
|
|
||||||
handles.sort_unstable();
|
|
||||||
handles.windows(2).all(|handles| handles[0] != handles[1])
|
|
||||||
&& handles.last().is_none_or(|handle| *handle != usize::MAX)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn player_count_for_handles(players: &[MatchPlayer]) -> usize {
|
|
||||||
players
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|player| player.handle)
|
.map(|player| player.handle)
|
||||||
.max()
|
.collect::<Vec<_>>();
|
||||||
.map_or(0, |handle| handle + 1)
|
handles.sort_unstable();
|
||||||
|
handles == (0..players.len()).collect::<Vec<_>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cleanup_match(
|
pub fn cleanup_match(
|
||||||
@@ -609,23 +590,6 @@ mod tests {
|
|||||||
assert!(!valid_player_handles(&players));
|
assert!(!valid_player_handles(&players));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn player_handles_may_have_gaps() {
|
|
||||||
let players = [
|
|
||||||
MatchPlayer {
|
|
||||||
handle: 0,
|
|
||||||
fighter: FighterId::TestFighter,
|
|
||||||
},
|
|
||||||
MatchPlayer {
|
|
||||||
handle: 2,
|
|
||||||
fighter: FighterId::TestFighter,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
assert!(valid_player_handles(&players));
|
|
||||||
assert_eq!(player_count_for_handles(&players), 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn match_rules_reject_zero_limits() {
|
fn match_rules_reject_zero_limits() {
|
||||||
assert!(
|
assert!(
|
||||||
|
|||||||
@@ -40,12 +40,7 @@ impl MatchState {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
elapsed_frames: 0,
|
elapsed_frames: 0,
|
||||||
players: (0..config
|
players: (0..config.players.len())
|
||||||
.players
|
|
||||||
.iter()
|
|
||||||
.map(|player| player.handle)
|
|
||||||
.max()
|
|
||||||
.map_or(0, |handle| handle + 1))
|
|
||||||
.map(|_| PlayerMatchState {
|
.map(|_| PlayerMatchState {
|
||||||
stocks_remaining,
|
stocks_remaining,
|
||||||
score: 0,
|
score: 0,
|
||||||
|
|||||||
+3
-14
@@ -140,7 +140,7 @@ fn validate(replay: &Replay) -> Result<(), String> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
if replay.players_are_invalid() {
|
if replay.players_are_invalid() {
|
||||||
return Err("replay player handles must be unique".into());
|
return Err("replay player handles must cover 0..player_count".into());
|
||||||
}
|
}
|
||||||
if replay.frames.is_empty() {
|
if replay.frames.is_empty() {
|
||||||
return Err("replay must contain at least one frame".into());
|
return Err("replay must contain at least one frame".into());
|
||||||
@@ -169,16 +169,7 @@ fn validate(replay: &Replay) -> Result<(), String> {
|
|||||||
if replay
|
if replay
|
||||||
.frames
|
.frames
|
||||||
.iter()
|
.iter()
|
||||||
.any(|frame| {
|
.any(|frame| frame.inputs.len() != replay.match_config.players.len())
|
||||||
frame.inputs.len()
|
|
||||||
!= replay
|
|
||||||
.match_config
|
|
||||||
.players
|
|
||||||
.iter()
|
|
||||||
.map(|player| player.handle)
|
|
||||||
.max()
|
|
||||||
.map_or(0, |handle| handle + 1)
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
return Err("replay frame input count does not match player count".into());
|
return Err("replay frame input count does not match player count".into());
|
||||||
}
|
}
|
||||||
@@ -194,9 +185,7 @@ impl Replay {
|
|||||||
.map(|player| player.handle)
|
.map(|player| player.handle)
|
||||||
.collect();
|
.collect();
|
||||||
handles.sort_unstable();
|
handles.sort_unstable();
|
||||||
handles.is_empty()
|
handles != (0..handles.len()).collect::<Vec<_>>()
|
||||||
|| handles.windows(2).any(|handles| handles[0] == handles[1])
|
|
||||||
|| handles.last() == Some(&usize::MAX)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn frame(&self, frame: i32) -> Option<&ReplayFrame> {
|
fn frame(&self, frame: i32) -> Option<&ReplayFrame> {
|
||||||
|
|||||||
+1
-29
@@ -1,12 +1,6 @@
|
|||||||
use bevy::{color::palettes::css::RED, prelude::*};
|
use bevy::{color::palettes::css::RED, prelude::*};
|
||||||
|
|
||||||
use crate::{
|
use crate::stage::line::StageCollision;
|
||||||
match_loading::MatchConfig,
|
|
||||||
stage::{
|
|
||||||
line::StageCollision,
|
|
||||||
manifest::{StageManifest, StageManifestRegistry},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn debug_draw_scene(mut gizmos: Gizmos, stage_collision: Res<StageCollision>) {
|
pub fn debug_draw_scene(mut gizmos: Gizmos, stage_collision: Res<StageCollision>) {
|
||||||
for poly in stage_collision.stage_polys.iter() {
|
for poly in stage_collision.stage_polys.iter() {
|
||||||
@@ -22,25 +16,3 @@ pub fn debug_draw_scene(mut gizmos: Gizmos, stage_collision: Res<StageCollision>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn debug_draw_blast_zones(
|
|
||||||
mut gizmos: Gizmos,
|
|
||||||
stage_registry: Res<StageManifestRegistry>,
|
|
||||||
stage_manifests: Res<Assets<StageManifest>>,
|
|
||||||
match_config: Res<MatchConfig>,
|
|
||||||
) {
|
|
||||||
let Some(stage_manifest_handle) = stage_registry.get(match_config.stage) else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(stage_manifest) = stage_manifests.get(&stage_manifest_handle) else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let top_left = stage_manifest.blast_zone_top_left.to_vec2();
|
|
||||||
let bottom_right = stage_manifest.blast_zone_bottom_right.to_vec2();
|
|
||||||
let center = (top_left + bottom_right) / 2.0;
|
|
||||||
let size = (bottom_right - top_left).abs();
|
|
||||||
|
|
||||||
gizmos.rect(Vec3::new(center.x, center.y, 0.0), size, bevy::color::palettes::css::BLUE);
|
|
||||||
}
|
|
||||||
|
|||||||
+7
-82
@@ -1,4 +1,4 @@
|
|||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use bevy_asset_loader::asset_collection::AssetCollection;
|
use bevy_asset_loader::asset_collection::AssetCollection;
|
||||||
use ron_asset_manager::prelude::RonAsset;
|
use ron_asset_manager::prelude::RonAsset;
|
||||||
@@ -7,10 +7,14 @@ use strum::IntoEnumIterator;
|
|||||||
use strum_macros::EnumIter;
|
use strum_macros::EnumIter;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState, game_settings::GameSettings, math::{vec::FGVec2}, stage::{
|
AppState,
|
||||||
|
game_settings::GameSettings,
|
||||||
|
math::vec::FGVec2,
|
||||||
|
stage::{
|
||||||
StagePoly,
|
StagePoly,
|
||||||
line::{StageCollision, StagePolyLineSegmentType, StagePolyType},
|
line::{StageCollision, StagePolyLineSegmentType, StagePolyType},
|
||||||
}, texture_reference::TextureReference,
|
},
|
||||||
|
texture_reference::TextureReference,
|
||||||
};
|
};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
@@ -83,15 +87,6 @@ pub struct StageManifest {
|
|||||||
pub icon: TextureReference,
|
pub icon: TextureReference,
|
||||||
pub camera: StageCameraProfile,
|
pub camera: StageCameraProfile,
|
||||||
pub polygons: Vec<StagePolyDefinition>,
|
pub polygons: Vec<StagePolyDefinition>,
|
||||||
|
|
||||||
#[reflect(ignore)]
|
|
||||||
pub blast_zone_top_left: FGVec2,
|
|
||||||
#[reflect(ignore)]
|
|
||||||
pub blast_zone_bottom_right: FGVec2,
|
|
||||||
|
|
||||||
#[reflect(ignore)]
|
|
||||||
pub spawn_points: Vec<FGVec2>,
|
|
||||||
pub neutral_spawn_point_sets: Vec<Vec<usize>>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
@@ -167,13 +162,6 @@ pub fn prepare_stage_manifests(
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Err(error) = manifest.validate_spawn_points() {
|
|
||||||
fail(
|
|
||||||
&mut next_state,
|
|
||||||
&format!("{:?} has invalid spawn points: {error}", manifest.id),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if registry.insert(manifest.id, handle.clone()).is_some() {
|
if registry.insert(manifest.id, handle.clone()).is_some() {
|
||||||
fail(
|
fail(
|
||||||
&mut next_state,
|
&mut next_state,
|
||||||
@@ -198,69 +186,6 @@ pub fn prepare_stage_manifests(
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl StageManifest {
|
impl StageManifest {
|
||||||
pub fn neutral_spawn_positions(&self, player_count: usize) -> Result<Vec<FGVec2>, String> {
|
|
||||||
if player_count == 0 {
|
|
||||||
return Err("a match must contain at least one player".to_owned());
|
|
||||||
}
|
|
||||||
|
|
||||||
let layout = self
|
|
||||||
.neutral_spawn_point_sets
|
|
||||||
.get(player_count - 1)
|
|
||||||
.ok_or_else(|| format!("no spawn layout for {player_count} players"))?;
|
|
||||||
|
|
||||||
if layout.len() != player_count {
|
|
||||||
return Err(format!(
|
|
||||||
"the {player_count}-player layout contains {} positions",
|
|
||||||
layout.len()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
layout
|
|
||||||
.iter()
|
|
||||||
.map(|&index| {
|
|
||||||
self.spawn_points.get(index).copied().ok_or_else(|| {
|
|
||||||
format!("the {player_count}-player layout references spawn point {index}")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn validate_spawn_points(&self) -> Result<(), String> {
|
|
||||||
if self.spawn_points.is_empty() {
|
|
||||||
return Err("no spawn points are configured".to_owned());
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.neutral_spawn_point_sets.is_empty() {
|
|
||||||
return Err("no neutral spawn layouts are configured".to_owned());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (layout_index, layout) in self.neutral_spawn_point_sets.iter().enumerate() {
|
|
||||||
let player_count = layout_index + 1;
|
|
||||||
if layout.len() != player_count {
|
|
||||||
return Err(format!(
|
|
||||||
"the {player_count}-player layout contains {} positions",
|
|
||||||
layout.len()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut unique_indices = HashSet::with_capacity(layout.len());
|
|
||||||
for &spawn_point_index in layout {
|
|
||||||
if spawn_point_index >= self.spawn_points.len() {
|
|
||||||
return Err(format!(
|
|
||||||
"the {player_count}-player layout references spawn point {spawn_point_index}"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
if !unique_indices.insert(spawn_point_index) {
|
|
||||||
return Err(format!(
|
|
||||||
"the {player_count}-player layout uses spawn point {spawn_point_index} more than once"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_collision(&self) -> StageCollision {
|
pub fn to_collision(&self) -> StageCollision {
|
||||||
let stage_polys: Vec<StagePoly> = self
|
let stage_polys: Vec<StagePoly> = self
|
||||||
.polygons
|
.polygons
|
||||||
|
|||||||
+4
-9
@@ -10,7 +10,7 @@ pub mod scene;
|
|||||||
|
|
||||||
pub use line::{StagePlaneIntersectResult, StagePoly};
|
pub use line::{StagePlaneIntersectResult, StagePoly};
|
||||||
|
|
||||||
use crate::{match_loading::MatchConfig, stage::{line::StageCollision, manifest::StageCameraProfile}};
|
use crate::stage::{line::StageCollision, manifest::StageCameraProfile};
|
||||||
|
|
||||||
/// Owns the stage geometry: which scene gets spawned and how it is drawn.
|
/// Owns the stage geometry: which scene gets spawned and how it is drawn.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@@ -20,14 +20,9 @@ impl Plugin for StagePlugin {
|
|||||||
fn build(&self, app: &mut App) {
|
fn build(&self, app: &mut App) {
|
||||||
app.add_systems(
|
app.add_systems(
|
||||||
Update,
|
Update,
|
||||||
(
|
debug::debug_draw_scene
|
||||||
(debug::debug_draw_scene
|
.run_if(resource_exists::<line::StageCollision>)
|
||||||
.run_if(resource_exists::<line::StageCollision>)
|
.run_if(crate::debug_tools::stage_collision_enabled),
|
||||||
.run_if(crate::debug_tools::stage_collision_enabled)),
|
|
||||||
(debug::debug_draw_blast_zones
|
|
||||||
.run_if(resource_exists::<MatchConfig>)
|
|
||||||
.run_if(crate::debug_tools::blast_zones_enabled),),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user