diff --git a/Cargo.lock b/Cargo.lock index 6174fc6..cbd3b59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2589,12 +2589,13 @@ checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" [[package]] name = "hexlab" -version = "0.2.1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b912e78d292803bc279aec3a4e2a0cdd0e0ac1540bcdc5d0f32cbfe9e4d234dc" dependencies = [ "bevy", "hexx", "rand", - "rand_chacha", "thiserror 2.0.6", ] @@ -3076,7 +3077,7 @@ dependencies = [ [[package]] name = "maze-ascension" -version = "0.1.0" +version = "0.2.0" dependencies = [ "bevy", "bevy-inspector-egui", diff --git a/Cargo.toml b/Cargo.toml index ac7d4b5..5059061 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "maze-ascension" authors = ["Kristofers Solo "] -version = "0.1.0" +version = "0.2.0" edition = "2021" [dependencies] @@ -18,7 +18,7 @@ tracing = { version = "0.1", features = [ "release_max_level_warn", ] } hexx = { version = "0.19", features = ["bevy_reflect", "grid"] } -hexlab = { path = "../hexlab", features = ["bevy"] } +hexlab = { version = "0.3", features = ["bevy"] } bevy-inspector-egui = { version = "0.28", optional = true } bevy_egui = { version = "0.31", optional = true } thiserror = "2.0" diff --git a/src/dev_tools/ui/maze_controls.rs b/src/dev_tools/ui/maze_controls.rs index 387fbdc..f611a2c 100644 --- a/src/dev_tools/ui/maze_controls.rs +++ b/src/dev_tools/ui/maze_controls.rs @@ -1,14 +1,15 @@ -use std::ops::RangeInclusive; - +use crate::{ + maze::{events::RecreateMazeEvent, MazeConfig, MazePluginLoaded}, + player::events::RespawnPlayer, +}; use bevy::{prelude::*, window::PrimaryWindow}; -use hexx::{Hex, HexOrientation}; -use rand::{thread_rng, Rng}; - -use crate::maze::{events::RecreateMazeEvent, MazeConfig, MazePluginLoaded}; use bevy_egui::{ egui::{self, emath::Numeric, DragValue, TextEdit, Ui}, EguiContext, }; +use hexx::{Hex, HexOrientation}; +use rand::{thread_rng, Rng}; +use std::ops::RangeInclusive; pub(crate) fn maze_controls_ui(world: &mut World) { if world.get_resource::().is_none() { @@ -55,6 +56,9 @@ pub(crate) fn maze_controls_ui(world: &mut World) { { event_writer.send(RecreateMazeEvent { floor: 1 }); } + if let Some(mut event_writer) = world.get_resource_mut::>() { + event_writer.send(RespawnPlayer); + } } } }); @@ -82,9 +86,9 @@ fn add_position_control(ui: &mut Ui, label: &str, pos: &mut Hex) -> bool { ui.horizontal(|ui| { ui.label(label); - let response_x = ui.add(DragValue::new(&mut pos.x).speed(1).prefix("x: ")); - let response_y = ui.add(DragValue::new(&mut pos.y).speed(1).prefix("y: ")); - changed = response_x.changed() || response_y.changed(); + let response_q = ui.add(DragValue::new(&mut pos.x).speed(1).prefix("q: ")); + let response_r = ui.add(DragValue::new(&mut pos.y).speed(1).prefix("r: ")); + changed = response_r.changed() || response_q.changed(); }); changed } diff --git a/src/maze/mod.rs b/src/maze/mod.rs index 34d31a3..db58ab1 100644 --- a/src/maze/mod.rs +++ b/src/maze/mod.rs @@ -7,12 +7,11 @@ mod resources; mod systems; pub use resources::{MazeConfig, MazePluginLoaded}; -use systems::recreation::handle_maze_recreation_event; pub(super) fn plugin(app: &mut App) { app.init_resource::() .add_event::() - .add_systems(Update, handle_maze_recreation_event); + .add_plugins(systems::plugin); } pub fn spawn_level_command(world: &mut World) { diff --git a/src/maze/plugin.rs b/src/maze/plugin.rs deleted file mode 100644 index aa87236..0000000 --- a/src/maze/plugin.rs +++ /dev/null @@ -1,28 +0,0 @@ -use bevy::{ - ecs::{system::RunSystemOnce, world::Command}, - prelude::*, -}; - -use super::{ - events::RecreateMazeEvent, - systems::{self, recreation::handle_maze_recreation_event}, - MazeConfig, MazePluginLoaded, -}; - -#[derive(Default)] -pub(crate) struct MazePlugin; - -impl Plugin for MazePlugin { - fn build(&self, app: &mut App) { - app.init_resource::() - .add_event::() - .add_systems(Update, handle_maze_recreation_event); - } -} - -impl Command for MazePlugin { - fn apply(self, world: &mut World) { - world.insert_resource(MazePluginLoaded); - let _ = world.run_system_once(systems::setup::setup); - } -} diff --git a/src/maze/resources.rs b/src/maze/resources.rs index dee34ff..0f24456 100644 --- a/src/maze/resources.rs +++ b/src/maze/resources.rs @@ -40,8 +40,8 @@ impl MazeConfig { let start_pos = generate_pos(radius, &mut rng)?; let end_pos = generate_pos(radius, &mut rng)?; - debug!("Start pos: ({},{})", start_pos.x, start_pos.y); - debug!("End pos: ({},{})", end_pos.x, end_pos.y); + info!("Start pos: (q={}, r={})", start_pos.x, start_pos.y); + info!("End pos: (q={}, r={})", end_pos.x, end_pos.y); let layout = HexLayout { orientation, diff --git a/src/maze/systems/despawn.rs b/src/maze/systems/despawn.rs index ad25077..16385f1 100644 --- a/src/maze/systems/despawn.rs +++ b/src/maze/systems/despawn.rs @@ -1,3 +1,14 @@ +use crate::maze::components::Floor; use bevy::prelude::*; -use crate::maze::components::MazeFloor; +pub(crate) fn despawn_floor( + commands: &mut Commands, + query: &Query<(Entity, &Floor)>, + floor_num: u8, +) { + for (entity, floor) in query.iter() { + if floor.0 == floor_num { + commands.entity(entity).despawn_recursive(); + } + } +} diff --git a/src/maze/systems/mod.rs b/src/maze/systems/mod.rs index 6fe5160..8965842 100644 --- a/src/maze/systems/mod.rs +++ b/src/maze/systems/mod.rs @@ -1,3 +1,11 @@ +pub mod despawn; pub mod recreation; pub mod setup; -mod spawn; +pub mod spawn; + +use bevy::prelude::*; +use recreation::recreate_maze; + +pub(super) fn plugin(app: &mut App) { + app.add_systems(Update, recreate_maze); +} diff --git a/src/maze/systems/recreation.rs b/src/maze/systems/recreation.rs index 11b37f2..358e458 100644 --- a/src/maze/systems/recreation.rs +++ b/src/maze/systems/recreation.rs @@ -2,9 +2,9 @@ use bevy::prelude::*; use crate::maze::{components::Floor, events::RecreateMazeEvent, MazeConfig}; -use super::setup::setup_maze; +use super::{despawn::despawn_floor, spawn::spawn_floor}; -pub(crate) fn handle_maze_recreation_event( +pub(crate) fn recreate_maze( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, @@ -14,14 +14,6 @@ pub(crate) fn handle_maze_recreation_event( ) { for event in event_reader.read() { despawn_floor(&mut commands, &query, event.floor); - setup_maze(&mut commands, &mut meshes, &mut materials, &config); - } -} - -fn despawn_floor(commands: &mut Commands, query: &Query<(Entity, &Floor)>, floor_num: u8) { - for (entity, floor) in query.iter() { - if floor.0 == floor_num { - commands.entity(entity).despawn_recursive(); - } + spawn_floor(&mut commands, &mut meshes, &mut materials, &config); } } diff --git a/src/maze/systems/setup.rs b/src/maze/systems/setup.rs index b44f9e8..113cf89 100644 --- a/src/maze/systems/setup.rs +++ b/src/maze/systems/setup.rs @@ -1,13 +1,6 @@ +use super::spawn::spawn_floor; +use crate::maze::MazeConfig; use bevy::prelude::*; -use hexlab::{GeneratorType, MazeBuilder}; - -use crate::maze::{ - assets::MazeAssets, - components::{Floor, Maze}, - MazeConfig, -}; - -use super::spawn::spawn_single_hex_tile; pub(crate) fn setup( mut commands: Commands, @@ -15,34 +8,5 @@ pub(crate) fn setup( mut materials: ResMut>, config: Res, ) { - setup_maze(&mut commands, &mut meshes, &mut materials, &config); -} - -pub(super) fn setup_maze( - commands: &mut Commands, - meshes: &mut ResMut>, - materials: &mut ResMut>, - config: &MazeConfig, -) { - let maze = MazeBuilder::new() - .with_radius(config.radius) - .with_seed(config.seed) - .with_generator(GeneratorType::RecursiveBacktracking) - .build() - .expect("Something went wrong while creating maze"); - - let assets = MazeAssets::new(meshes, materials, config); - commands - .spawn(( - Name::new("Floor"), - Maze(maze.clone()), - Floor(1), - Transform::from_translation(Vec3::ZERO), - Visibility::Visible, - )) - .with_children(|parent| { - for tile in maze.values() { - spawn_single_hex_tile(parent, &assets, tile, config) - } - }); + spawn_floor(&mut commands, &mut meshes, &mut materials, &config); } diff --git a/src/maze/systems/spawn.rs b/src/maze/systems/spawn.rs index be9a9d7..8cb229c 100644 --- a/src/maze/systems/spawn.rs +++ b/src/maze/systems/spawn.rs @@ -1,14 +1,41 @@ -use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_6}; - +use crate::maze::{ + assets::MazeAssets, + components::{Floor, Maze, Tile, Wall}, + MazeConfig, +}; use bevy::prelude::*; use hexlab::prelude::*; use hexx::HexOrientation; +use std::f32::consts::{FRAC_PI_2, FRAC_PI_3, FRAC_PI_6}; -use crate::maze::{ - assets::MazeAssets, - components::{Tile, Wall}, - MazeConfig, -}; +pub(super) fn spawn_floor( + commands: &mut Commands, + meshes: &mut ResMut>, + materials: &mut ResMut>, + config: &MazeConfig, +) { + let maze = MazeBuilder::new() + .with_radius(config.radius) + .with_seed(config.seed) + .with_generator(GeneratorType::RecursiveBacktracking) + .build() + .expect("Something went wrong while creating maze"); + + let assets = MazeAssets::new(meshes, materials, config); + commands + .spawn(( + Name::new("Floor"), + Maze(maze.clone()), + Floor(1), + Transform::from_translation(Vec3::ZERO), + Visibility::Visible, + )) + .with_children(|parent| { + for tile in maze.values() { + spawn_single_hex_tile(parent, &assets, tile, config) + } + }); +} pub(super) fn spawn_single_hex_tile( parent: &mut ChildBuilder, diff --git a/src/player/components.rs b/src/player/components.rs index 87f7d18..26f8a8b 100644 --- a/src/player/components.rs +++ b/src/player/components.rs @@ -16,7 +16,7 @@ pub struct MovementSpeed(pub f32); impl Default for MovementSpeed { fn default() -> Self { - Self(50.) + Self(100.) } } diff --git a/src/player/events.rs b/src/player/events.rs new file mode 100644 index 0000000..edd056e --- /dev/null +++ b/src/player/events.rs @@ -0,0 +1,4 @@ +use bevy::prelude::*; + +#[derive(Debug, Event)] +pub(crate) struct RespawnPlayer; diff --git a/src/player/mod.rs b/src/player/mod.rs index 7d067d4..5db0cf0 100644 --- a/src/player/mod.rs +++ b/src/player/mod.rs @@ -1,14 +1,18 @@ mod assets; pub mod components; +pub mod events; mod systems; use bevy::{ecs::system::RunSystemOnce, prelude::*}; use components::Player; +use events::RespawnPlayer; pub(super) fn plugin(app: &mut App) { - app.register_type::().add_plugins(systems::plugin); + app.register_type::() + .add_event::() + .add_plugins(systems::plugin); } pub fn spawn_player_command(world: &mut World) { - let _ = world.run_system_once(systems::spawn::spawn_player); + let _ = world.run_system_once(systems::setup::setup); } diff --git a/src/player/systems/despawn.rs b/src/player/systems/despawn.rs new file mode 100644 index 0000000..24dc9f4 --- /dev/null +++ b/src/player/systems/despawn.rs @@ -0,0 +1,9 @@ +use bevy::prelude::*; + +use crate::player::components::Player; + +pub(crate) fn despawn_players(commands: &mut Commands, query: &Query>) { + for entity in query.iter() { + commands.entity(entity).despawn_recursive(); + } +} diff --git a/src/player/systems/mod.rs b/src/player/systems/mod.rs index b43f2f4..ea066cd 100644 --- a/src/player/systems/mod.rs +++ b/src/player/systems/mod.rs @@ -1,11 +1,22 @@ +pub mod despawn; mod input; mod movement; +pub mod respawn; +pub mod setup; pub mod spawn; use bevy::prelude::*; use input::player_input; use movement::player_movement; +use respawn::respawn_player; pub(super) fn plugin(app: &mut App) { - app.add_systems(Update, (player_input, player_movement.after(player_input))); + app.add_systems( + Update, + ( + player_input, + player_movement.after(player_input), + respawn_player, + ), + ); } diff --git a/src/player/systems/respawn.rs b/src/player/systems/respawn.rs new file mode 100644 index 0000000..af2446a --- /dev/null +++ b/src/player/systems/respawn.rs @@ -0,0 +1,21 @@ +use crate::{ + maze::MazeConfig, + player::{components::Player, events::RespawnPlayer}, +}; +use bevy::prelude::*; + +use super::{despawn::despawn_players, spawn::spawn_player}; + +pub(crate) fn respawn_player( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, + config: Res, + query: Query>, + mut event_reader: EventReader, +) { + for _ in event_reader.read() { + despawn_players(&mut commands, &query); + spawn_player(&mut commands, &mut meshes, &mut materials, &config); + } +} diff --git a/src/player/systems/setup.rs b/src/player/systems/setup.rs new file mode 100644 index 0000000..4092d52 --- /dev/null +++ b/src/player/systems/setup.rs @@ -0,0 +1,14 @@ +use bevy::prelude::*; + +use crate::maze::MazeConfig; + +use super::spawn::spawn_player; + +pub(crate) fn setup( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, + config: Res, +) { + spawn_player(&mut commands, &mut meshes, &mut materials, &config); +} diff --git a/src/player/systems/spawn.rs b/src/player/systems/spawn.rs index 08a35f5..19a5a85 100644 --- a/src/player/systems/spawn.rs +++ b/src/player/systems/spawn.rs @@ -6,26 +6,26 @@ use crate::{ }, }; use bevy::prelude::*; -use hexx::Hex; -pub fn spawn_player( - mut commands: Commands, - mut meshes: ResMut>, - mut materials: ResMut>, - maze_config: Res, +pub(super) fn spawn_player( + commands: &mut Commands, + meshes: &mut ResMut>, + materials: &mut ResMut>, + config: &MazeConfig, ) { - let player_height = maze_config.height * 0.5; - let player_radius = maze_config.hex_size * 0.5; + let player_radius = config.hex_size * 0.5; + let player_height = player_radius * 3.5; - let start_hex = Hex::new(1, 1); - let start_pos = maze_config.layout.hex_to_world_pos(start_hex); + let y_offset = config.height / 2. + player_height / 1.3; + + let start_pos = config.layout.hex_to_world_pos(config.start_pos); commands.spawn(( Name::new("Player"), Player, - CurrentPosition(start_hex), + CurrentPosition(config.start_pos), Mesh3d(meshes.add(generate_pill_mesh(player_radius, player_height / 2.))), MeshMaterial3d(materials.add(blue_material())), - Transform::from_xyz(start_pos.x, player_height * 2., start_pos.y), + Transform::from_xyz(start_pos.x, y_offset, start_pos.y), )); }