diff --git a/src/dev_tools/ui/maze_controls.rs b/src/dev_tools/ui/maze_controls.rs index 114b7e0..66e4668 100644 --- a/src/dev_tools/ui/maze_controls.rs +++ b/src/dev_tools/ui/maze_controls.rs @@ -34,11 +34,10 @@ pub(crate) fn maze_controls_ui(world: &mut World) { let mut maze_config = maze_config.clone(); let floor_value = floor.0; - let global_config = world.get_resource::().cloned(); let mut changed = false; egui::Window::new("Maze Controls").show(egui_context.get_mut(), |ui| { - if let Some(mut global_config) = global_config.clone() { + if let Some(mut global_config) = world.get_resource_mut::() { ui.heading("Maze Configuration"); changed |= add_seed_control(ui, &mut maze_config.seed); diff --git a/src/maze/systems/common.rs b/src/maze/systems/common.rs new file mode 100644 index 0000000..2ca0add --- /dev/null +++ b/src/maze/systems/common.rs @@ -0,0 +1,14 @@ +use crate::maze::{ + components::MazeConfig, + errors::{MazeError, MazeResult}, +}; +use hexlab::{GeneratorType, HexMaze, MazeBuilder}; + +pub(super) fn generate_maze(config: &MazeConfig) -> MazeResult { + Ok(MazeBuilder::new() + .with_radius(config.radius) + .with_seed(config.seed) + .with_generator(GeneratorType::RecursiveBacktracking) + .build() + .map_err(|_| MazeError::generation_failed(config.radius, config.seed))?) +} diff --git a/src/maze/systems/event_handler.rs b/src/maze/systems/event_handler.rs index b32a987..65f0430 100644 --- a/src/maze/systems/event_handler.rs +++ b/src/maze/systems/event_handler.rs @@ -10,13 +10,13 @@ pub(crate) fn handle_maze_events( mut meshes: ResMut>, mut materials: ResMut>, mut event_reader: EventReader, - mut maze_query: Query<(Entity, &Floor, &Children, &mut Maze)>, + mut maze_query: Query<(Entity, &Floor, &mut Maze)>, global_config: Res, ) { for event in event_reader.read() { match event { MazeEvent::Create { floor, config } => { - if maze_query.iter().any(|(_, f, _, _)| f.0 == *floor) { + if maze_query.iter().any(|(_, f, _)| f.0 == *floor) { warn!("Floor {} already exists, skipping creation", floor); continue; } @@ -44,8 +44,8 @@ pub(crate) fn handle_maze_events( } } MazeEvent::Remove { floor } => { - match maze_query.iter().find(|(_, f, _, _)| f.0 == *floor) { - Some((entity, _, _, _)) => commands.entity(entity).despawn_recursive(), + match maze_query.iter().find(|(_, f, _)| f.0 == *floor) { + Some((entity, _, _)) => commands.entity(entity).despawn_recursive(), _ => warn!("Floor {} not found for removal", floor), } } diff --git a/src/maze/systems/mod.rs b/src/maze/systems/mod.rs index a739a0b..a67e90a 100644 --- a/src/maze/systems/mod.rs +++ b/src/maze/systems/mod.rs @@ -1,3 +1,4 @@ +pub mod common; pub mod event_handler; pub mod setup; pub mod spawn; diff --git a/src/maze/systems/spawn.rs b/src/maze/systems/spawn.rs index ee1be3b..33956d2 100644 --- a/src/maze/systems/spawn.rs +++ b/src/maze/systems/spawn.rs @@ -11,6 +11,8 @@ use hexlab::prelude::*; use hexx::HexOrientation; use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_6}; +use super::common::generate_maze; + pub(super) fn spawn_floor( commands: &mut Commands, meshes: &mut ResMut>, @@ -19,15 +21,9 @@ pub(super) fn spawn_floor( maze_config: &MazeConfig, global_config: &GlobalMazeConfig, ) { - let maze = MazeBuilder::new() - .with_radius(maze_config.radius) - .with_seed(maze_config.seed) - .with_generator(GeneratorType::RecursiveBacktracking) - .build() - .expect("Something went wrong while creating maze"); + let maze = generate_maze(maze_config).expect("Failed to generate maze during spawn"); - let assets = MazeAssets::new(meshes, materials, &global_config); - commands + let entity = commands .spawn(( Name::new(format!("Floor {}", floor)), Maze(maze.clone()), @@ -37,11 +33,25 @@ pub(super) fn spawn_floor( Transform::from_translation(Vec3::ZERO), Visibility::Visible, )) - .with_children(|parent| { - for tile in maze.values() { - spawn_single_hex_tile(parent, &assets, tile, &maze_config, &global_config) - } - }); + .id(); + + let assets = MazeAssets::new(meshes, materials, global_config); + spawn_maze_tiles(commands, entity, &maze, &assets, maze_config, global_config); +} + +pub(super) fn spawn_maze_tiles( + commands: &mut Commands, + parent_entity: Entity, + maze: &HexMaze, + assets: &MazeAssets, + maze_config: &MazeConfig, + global_config: &GlobalMazeConfig, +) { + commands.entity(parent_entity).with_children(|parent| { + for tile in maze.values() { + spawn_single_hex_tile(parent, &assets, tile, maze_config, global_config); + } + }); } pub(super) fn spawn_single_hex_tile( diff --git a/src/maze/systems/update.rs b/src/maze/systems/update.rs index 88b98ae..10c67eb 100644 --- a/src/maze/systems/update.rs +++ b/src/maze/systems/update.rs @@ -1,3 +1,7 @@ +use super::{ + common::generate_maze, + spawn::{spawn_maze_tiles, spawn_single_hex_tile}, +}; use crate::{ floor::components::Floor, maze::{ @@ -8,45 +12,35 @@ use crate::{ }, }; use bevy::prelude::*; -use hexlab::{GeneratorType, MazeBuilder}; - -use super::spawn::spawn_single_hex_tile; pub(super) fn update_floor( commands: &mut Commands, meshes: &mut ResMut>, materials: &mut ResMut>, - maze_query: &mut Query<(Entity, &Floor, &Children, &mut Maze)>, + maze_query: &mut Query<(Entity, &Floor, &mut Maze)>, floor: u8, maze_config: &MazeConfig, global_config: &GlobalMazeConfig, ) -> MazeResult<()> { - let (entity, _, children, mut maze) = maze_query + let (entity, _, mut maze) = maze_query .iter_mut() - .find(|(_, f, _, _)| f.0 == floor) + .find(|(_, f, _)| f.0 == floor) .ok_or(MazeError::FloorNotFound(floor))?; - let new_maze = MazeBuilder::new() - .with_radius(maze_config.radius) - .with_seed(maze_config.seed) - .with_generator(GeneratorType::RecursiveBacktracking) - .build() - .map_err(|_| MazeError::generation_failed(maze_config.radius, maze_config.seed))?; + maze.0 = generate_maze(maze_config)?; - let new_maze = Maze(new_maze); - - commands.entity(entity).clear_children(); - for &child in children.iter() { - commands.entity(child).despawn_recursive(); - } + commands.entity(entity).despawn_descendants(); let assets = MazeAssets::new(meshes, materials, global_config); - commands.entity(entity).with_children(|parent| { - for tile in new_maze.0.values() { - spawn_single_hex_tile(parent, &assets, tile, maze_config, global_config); - } - }); + spawn_maze_tiles( + commands, + entity, + &maze.0, + &assets, + maze_config, + global_config, + ); - *maze = new_maze; commands.entity(entity).insert(maze_config.clone()); + Ok(()) } diff --git a/src/player/systems/input.rs b/src/player/systems/input.rs index 62a5602..a2ceac6 100644 --- a/src/player/systems/input.rs +++ b/src/player/systems/input.rs @@ -1,5 +1,5 @@ use crate::{ - floor::components::{CurrentFloor, Floor}, + floor::components::CurrentFloor, maze::components::{Maze, MazeConfig}, player::components::{CurrentPosition, MovementTarget, Player}, };