diff --git a/src/floor/systems/movement.rs b/src/floor/systems/movement.rs index bb98dd7..526d2f8 100644 --- a/src/floor/systems/movement.rs +++ b/src/floor/systems/movement.rs @@ -10,6 +10,12 @@ use crate::{ use bevy::prelude::*; +/// Move floor entities to their target Y positions based on movement speed +/// +/// # Behavior +/// - Calculates movement distance based on player speed and delta time +/// - Moves floors towards their target Y position +/// - Removes FloorYTarget component when floor reaches destination pub fn move_floors( mut commands: Commands, mut maze_query: Query<(Entity, &mut Transform, &FloorYTarget), With>, @@ -30,6 +36,13 @@ pub fn move_floors( } } +/// Handle floor transition events by setting up floor movement targets +/// +/// # Behavior +/// - Checks if any floors are currently moving +/// - Processes floor transition events +/// - Sets target Y positions for all maze entities +/// - Updates current and next floor designations pub fn handle_floor_transition_events( mut commands: Commands, mut maze_query: Query<(Entity, &Transform, &Floor, Option<&FloorYTarget>), With>, diff --git a/src/maze/assets.rs b/src/maze/assets.rs index 7b9f108..15350eb 100644 --- a/src/maze/assets.rs +++ b/src/maze/assets.rs @@ -1,8 +1,14 @@ +//! Maze asset management and generation. +//! +//! Module handles the creation and management of meshes and materials +//! used in the maze visualization, including hexagonal tiles and walls. + use super::resources::GlobalMazeConfig; use crate::{ constants::WALL_OVERLAP_MODIFIER, theme::{palette::rose_pine::RosePineDawn, prelude::ColorScheme}, }; + use bevy::{prelude::*, utils::HashMap}; use std::f32::consts::FRAC_PI_2; use strum::IntoEnumIterator; @@ -10,15 +16,26 @@ use strum::IntoEnumIterator; const HEX_SIDES: u32 = 6; const WHITE_EMISSION_INTENSITY: f32 = 10.; +/// Collection of mesh and material assets used in maze rendering. +/// +/// This struct contains all the necessary assets for rendering maze components, +/// including hexagonal tiles, walls, and custom colored materials. +#[derive(Debug)] pub struct MazeAssets { + /// Mesh for hexagonal floor tiles pub hex_mesh: Handle, + /// Mesh for wall segments pub wall_mesh: Handle, + /// Default material for hexagonal tiles pub hex_material: Handle, + /// Default material for walls pub wall_material: Handle, + /// Custom materials mapped to specific colors from the RosePineDawn palette pub custom_materials: HashMap>, } impl MazeAssets { + /// Creates a new instance of MazeAssets with all necessary meshes and materials. pub fn new( meshes: &mut ResMut>, materials: &mut ResMut>, @@ -43,6 +60,7 @@ impl MazeAssets { } } +/// Generates a hexagonal mesh for floor tiles. fn generate_hex_mesh(radius: f32, depth: f32) -> Mesh { let hexagon = RegularPolygon { sides: HEX_SIDES, @@ -54,6 +72,7 @@ fn generate_hex_mesh(radius: f32, depth: f32) -> Mesh { Mesh::from(prism_shape).rotated_by(rotation) } +/// Generates a square mesh for wall segments. fn generate_square_mesh(depth: f32, wall_size: f32) -> Mesh { let square = Rectangle::new(wall_size, wall_size); let rectangular_prism = Extrusion::new(square, depth); @@ -62,6 +81,7 @@ fn generate_square_mesh(depth: f32, wall_size: f32) -> Mesh { Mesh::from(rectangular_prism).rotated_by(rotation) } +/// Creates a glowing white material for default tile appearance. pub fn white_material() -> StandardMaterial { StandardMaterial { emissive: LinearRgba::new( diff --git a/src/maze/components.rs b/src/maze/components.rs index 0e3d2d2..537394e 100644 --- a/src/maze/components.rs +++ b/src/maze/components.rs @@ -1,6 +1,11 @@ +//! Maze components and configuration. +//! +//! Module defines the core components and configuration structures used +//! for maze generation and rendering, including hexagonal maze layouts, +//! tiles, walls, and maze configuration. +use super::GlobalMazeConfig; use crate::floor::components::Floor; -use super::GlobalMazeConfig; use bevy::prelude::*; use hexlab::Maze; use hexx::{Hex, HexLayout, HexOrientation}; @@ -19,17 +24,27 @@ pub struct Tile; #[reflect(Component)] pub struct Wall; +/// Configuration for a single maze instance. +/// +/// Contains all necessary parameters to generate and position a maze, +/// including its size, start/end positions, random seed, and layout. #[derive(Debug, Reflect, Component, Clone)] #[reflect(Component)] pub struct MazeConfig { + /// Radius of the hexagonal maze pub radius: u16, + /// Starting position in hex coordinates pub start_pos: Hex, + /// Ending position in hex coordinates pub end_pos: Hex, + /// Random seed for maze generation pub seed: u64, + /// Layout configuration for hex-to-world space conversion pub layout: HexLayout, } impl MazeConfig { + /// Creates a new maze configuration with the specified parameters. fn new( radius: u16, orientation: HexOrientation, @@ -71,6 +86,7 @@ impl MazeConfig { } } + /// Updates the maze configuration with new global settings. pub fn update(&mut self, global_conig: &GlobalMazeConfig) { self.layout.hex_size = Vec2::splat(global_conig.hex_size); } @@ -88,6 +104,10 @@ impl Default for MazeConfig { } } +/// Generates a random position within a hexagonal radius. +/// +/// # Returns +/// A valid Hex coordinate within the specified radius fn generate_pos(radius: u16, rng: &mut R) -> Hex { let radius = radius as i32; loop { diff --git a/src/maze/triggers/common.rs b/src/maze/triggers/common.rs index 378d6c8..2ee978e 100644 --- a/src/maze/triggers/common.rs +++ b/src/maze/triggers/common.rs @@ -1,10 +1,23 @@ -use crate::maze::{ - components::MazeConfig, - errors::{MazeError, MazeResult}, -}; +//! Common maze generation utilities. +use crate::maze::{components::MazeConfig, errors::MazeError}; use hexlab::prelude::*; -pub fn generate_maze(config: &MazeConfig) -> MazeResult { +/// Generates a new maze based on the provided configuration. +/// +/// This function uses a recursive backtracking algorithm to generate +/// a hexagonal maze with the specified parameters. +/// +/// # Arguments +/// - `config` - Configuration parameters for maze generation including radius and seed. +/// +/// # Returns +/// `Result` - The generated maze or an error if generation fails. +/// +/// # Errors +/// Returns `MazeError::GenerationFailed` if: +/// - The maze builder fails to create a valid maze +/// - The provided radius or seed results in an invalid configuration +pub fn generate_maze(config: &MazeConfig) -> Result { MazeBuilder::new() .with_radius(config.radius) .with_seed(config.seed) diff --git a/src/maze/triggers/despawn.rs b/src/maze/triggers/despawn.rs index e478c19..15f8700 100644 --- a/src/maze/triggers/despawn.rs +++ b/src/maze/triggers/despawn.rs @@ -1,7 +1,13 @@ +//! Maze despawning functionality. +//! +//! Module handles the cleanup of maze entities when they need to be removed, +//! ensuring proper cleanup of both the maze and all its child entities. use crate::{floor::components::Floor, maze::events::DespawnMaze}; + use bevy::prelude::*; -pub(super) fn despawn_maze( +/// Despawns a maze and all its associated entities for a given floor. +pub fn despawn_maze( trigger: Trigger, mut commands: Commands, query: Query<(Entity, &Floor)>, diff --git a/src/maze/triggers/respawn.rs b/src/maze/triggers/respawn.rs index fd8f957..ac9bc47 100644 --- a/src/maze/triggers/respawn.rs +++ b/src/maze/triggers/respawn.rs @@ -1,3 +1,8 @@ +//! Maze respawning functionality. +//! +//! Module provides the ability to regenerate mazes for existing floors, +//! maintaining the same floor entity but replacing its internal maze structure. + use super::{common::generate_maze, spawn::spawn_maze_tiles}; use crate::{ floor::components::Floor, @@ -6,7 +11,15 @@ use crate::{ use bevy::prelude::*; use hexlab::Maze; -pub(super) fn respawn_maze( +/// Respawns a maze for an existing floor with a new configuration. +/// +/// # Behavior: +/// - Finds the target floor +/// - Generates a new maze configuration +/// - Cleans up existing maze tiles +/// - Spawns new maze tiles +/// - Updates the floor's configuration +pub fn respawn_maze( trigger: Trigger, mut commands: Commands, mut meshes: ResMut>, diff --git a/src/maze/triggers/spawn.rs b/src/maze/triggers/spawn.rs index daa9c58..63e1c68 100644 --- a/src/maze/triggers/spawn.rs +++ b/src/maze/triggers/spawn.rs @@ -1,3 +1,7 @@ +//! Maze spawning and rendering functionality. +//! +//! Module handles the creation and visualization of hexagonal mazes. + use super::common::generate_maze; use crate::{ constants::FLOOR_Y_OFFSET, @@ -20,6 +24,7 @@ use hexlab::prelude::{Tile as HexTile, *}; use hexx::HexOrientation; use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_6}; +/// Spawns a new maze for the specified floor on [`SpawnMaze`] event. pub fn spawn_maze( trigger: Trigger, mut commands: Commands, @@ -44,9 +49,10 @@ pub fn spawn_maze( } }; + // Calculate vertical offset based on floor number let y_offset = match *floor { - 1 => 0, - _ => FLOOR_Y_OFFSET, + 1 => 0, // Ground/Initial floor (floor 1) is at y=0 + _ => FLOOR_Y_OFFSET, // Other floors are offset vertically } as f32; let entity = commands @@ -60,7 +66,7 @@ pub fn spawn_maze( Visibility::Visible, StateScoped(Screen::Gameplay), )) - .insert_if(CurrentFloor, || *floor == 1) + .insert_if(CurrentFloor, || *floor == 1) // Only floor 1 gets CurrentFloor .id(); let assets = MazeAssets::new(&mut meshes, &mut materials, &global_config); @@ -79,6 +85,7 @@ pub fn spawn_maze( } } +/// Spawns all tiles for a maze as children of the parent maze entity pub fn spawn_maze_tiles( commands: &mut Commands, parent_entity: Entity, @@ -94,6 +101,7 @@ pub fn spawn_maze_tiles( }); } +/// Spawns a single hexagonal tile with appropriate transforms and materials pub(super) fn spawn_single_hex_tile( parent: &mut ChildBuilder, assets: &MazeAssets, @@ -107,6 +115,7 @@ pub(super) fn spawn_single_hex_tile( HexOrientation::Flat => Quat::from_rotation_y(FRAC_PI_6), // 30 degrees rotation }; + // Select material based on tile position: start, end, or default let material = match tile.pos() { pos if pos == maze_config.start_pos => assets .custom_materials @@ -132,12 +141,14 @@ pub(super) fn spawn_single_hex_tile( .with_children(|parent| spawn_walls(parent, assets, tile.walls(), global_config)); } +/// Spawns walls around a hexagonal tile based on the walls configuration fn spawn_walls( parent: &mut ChildBuilder, assets: &MazeAssets, walls: &Walls, global_config: &GlobalMazeConfig, ) { + // Base rotation for wall alignment (90 degrees counter-clockwise) let z_rotation = Quat::from_rotation_z(-FRAC_PI_2); let y_offset = global_config.height / 2.; @@ -146,12 +157,25 @@ fn spawn_walls( continue; } + // Calculate the angle for this wall + // FRAC_PI_3 = 60 deg + // Negative because going clockwise + // i * 60 produces: 0, 60, 120, 180, 240, 300 let wall_angle = -FRAC_PI_3 * i as f32; + // cos(angle) gives x coordinate on unit circle + // sin(angle) gives z coordinate on unit circle + // Multiply by wall_offset to get actual distance from center let x_offset = global_config.wall_offset() * f32::cos(wall_angle); let z_offset = global_config.wall_offset() * f32::sin(wall_angle); + + // x: distance along x-axis from center + // y: vertical offset from center + // z: distance along z-axis from center let pos = Vec3::new(x_offset, y_offset, z_offset); + // 1. Rotate around x-axis to align wall with angle + // 2. Add FRAC_PI_2 (90) to make wall perpendicular to angle let x_rotation = Quat::from_rotation_x(wall_angle + FRAC_PI_2); let final_rotation = z_rotation * x_rotation; @@ -159,6 +183,7 @@ fn spawn_walls( } } +/// Spawns a single wall segment with the specified rotation and position fn spawn_single_wall(parent: &mut ChildBuilder, assets: &MazeAssets, rotation: Quat, offset: Vec3) { parent.spawn(( Name::new("Wall"), diff --git a/src/player/systems/movement.rs b/src/player/systems/movement.rs index d47b8dd..d69d55f 100644 --- a/src/player/systems/movement.rs +++ b/src/player/systems/movement.rs @@ -1,13 +1,22 @@ +//! Player movement system and related utilities. +//! +//! This module handles smooth player movement between hexagonal tiles, +//! including position interpolation and movement completion detection. use crate::{ constants::MOVEMENT_THRESHOLD, floor::components::CurrentFloor, maze::components::MazeConfig, player::components::{CurrentPosition, MovementSpeed, MovementTarget, Player}, }; + use bevy::prelude::*; use hexx::Hex; -pub(super) fn player_movement( +/// System handles player movement between hexagonal tiles. +/// +/// Smoothly interpolates player position between hexagonal tiles, +/// handling movement target acquisition, position updates, and movement completion. +pub fn player_movement( time: Res