Add spawn points (#71)
Reviewed-on: #71 Co-authored-by: Álex Román Núñez <eirexe@eirteam.moe>
This commit was merged in pull request #71.
This commit is contained in:
+75
-1
@@ -1,4 +1,4 @@
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use bevy_asset_loader::asset_collection::AssetCollection;
|
||||
use ron_asset_manager::prelude::RonAsset;
|
||||
@@ -88,6 +88,10 @@ pub struct StageManifest {
|
||||
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)]
|
||||
@@ -163,6 +167,13 @@ pub fn prepare_stage_manifests(
|
||||
);
|
||||
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() {
|
||||
fail(
|
||||
&mut next_state,
|
||||
@@ -187,6 +198,69 @@ pub fn prepare_stage_manifests(
|
||||
}
|
||||
|
||||
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 {
|
||||
let stage_polys: Vec<StagePoly> = self
|
||||
.polygons
|
||||
|
||||
Reference in New Issue
Block a user