generated from tipragot/rust
WIP: Add a selection of the spawnpoint for every players #108
|
@ -6,6 +6,7 @@ use border_wars::map::generation::MapGenerationPlugin;
|
|||
use border_wars::map::ownership::OwnershipPlugin;
|
||||
use border_wars::map::renderer::RendererPlugin;
|
||||
use border_wars::map::selected_tile::SelectTilePlugin;
|
||||
use border_wars::map::spawnpoint::SpawnpointPlugin;
|
||||
use border_wars::networking::NetworkingPlugin;
|
||||
use border_wars::scenes::ScenesPlugin;
|
||||
use border_wars::ui::UiPlugin;
|
||||
|
@ -20,6 +21,7 @@ fn main() {
|
|||
.add_plugins(NetworkingPlugin)
|
||||
.add_plugins(MapGenerationPlugin)
|
||||
.add_plugins(UiPlugin)
|
||||
.add_plugins(SpawnpointPlugin)
|
||||
.add_plugins(OwnershipPlugin)
|
||||
.run();
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ pub mod hex;
|
|||
pub mod ownership;
|
||||
pub mod renderer;
|
||||
pub mod selected_tile;
|
||||
pub mod spawnpoint;
|
||||
|
||||
use bevy::prelude::*;
|
||||
|
||||
|
|
72
crates/border-wars/src/map/spawnpoint.rs
Normal file
72
crates/border-wars/src/map/spawnpoint.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
//! All code related to set the spawn point of the players.
|
||||
|
||||
use bevy::prelude::*;
|
||||
|
||||
use super::generation::EndMapGeneration;
|
||||
use super::ownership::Owner;
|
||||
use super::{Tile, TilePosition};
|
||||
use crate::Player;
|
||||
|
||||
/// The plugin that initialize the spawn point at the start of the game.
|
||||
pub struct SpawnpointPlugin;
|
||||
|
||||
impl Plugin for SpawnpointPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Update, init_spawn_point);
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize the spawn point when the map is generated.
|
||||
fn init_spawn_point(
|
||||
mut commands: Commands,
|
||||
mut end_map_event: EventReader<EndMapGeneration>,
|
||||
players: Query<&Player>,
|
||||
mut map: Query<(Entity, &TilePosition, &mut Tile)>,
|
||||
) {
|
||||
for _ in end_map_event.read() {
|
||||
// Calculate the radius of the map.
|
||||
let Some(radius) = map.iter().map(|(_, p, _)| p.0.abs()).max() else {
|
||||
warn!("The map is empty");
|
||||
return;
|
||||
};
|
||||
|
||||
if radius == 0 {
|
||||
warn!("The map is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
let mut sorted_players = players.iter().collect::<Vec<_>>();
|
||||
sorted_players.sort_by(|a: &&Player, b: &&Player| a.uuid.cmp(&b.uuid));
|
||||
|
||||
let mut sorted_players = sorted_players.iter();
|
||||
|
||||
// Calculate the distance between the players. It must be an integer because
|
||||
// this is how the map is generated.
|
||||
let interval = radius as usize * 3 / sorted_players.len();
|
||||
|
||||
for (i, position) in TilePosition::new(0, 0)
|
||||
.ring(radius as usize / 2)
|
||||
.enumerate()
|
||||
{
|
||||
// Check the interval between players.
|
||||
if i % interval != 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Find the target tile.
|
||||
let Some((entity, _, mut tile)) = map.iter_mut().find(|(_, p, _)| **p == position)
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Get the current player.
|
||||
let Some(player) = sorted_players.next() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Set the spawn point.
|
||||
*tile = Tile::Castle;
|
||||
commands.entity(entity).insert(Owner(Player::clone(player)));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue