From 269686323ff77edbde182306733471172f31ef37 Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Wed, 18 Dec 2024 17:01:21 +0200 Subject: [PATCH] feat(player): add ascension/descension --- src/floor/components.rs | 14 ++++++++++++-- src/floor/mod.rs | 4 +++- src/floor/systems/mod.rs | 2 ++ src/maze/assets.rs | 28 +++++++++++++++++++++++++--- src/maze/triggers/spawn.rs | 18 +++++++++++++++++- src/player/events.rs | 10 ++++++++++ src/player/mod.rs | 4 +++- src/player/systems/ascend.rs | 30 ++++++++++++++++++++++++++++++ src/player/systems/descend.rs | 30 ++++++++++++++++++++++++++++++ src/player/systems/mod.rs | 9 ++++++--- 10 files changed, 138 insertions(+), 11 deletions(-) create mode 100644 src/player/systems/ascend.rs create mode 100644 src/player/systems/descend.rs diff --git a/src/floor/components.rs b/src/floor/components.rs index de73815..7f421d4 100644 --- a/src/floor/components.rs +++ b/src/floor/components.rs @@ -1,10 +1,10 @@ use bevy::prelude::*; -#[derive(Debug, Reflect, Component)] +#[derive(Debug, Reflect, Component, Deref, DerefMut)] #[reflect(Component)] pub struct Floor(pub u8); -#[derive(Debug, Reflect, Component)] +#[derive(Debug, Reflect, Component, Deref, DerefMut)] #[reflect(Component)] pub struct TargetFloor(pub u8); @@ -17,3 +17,13 @@ impl Default for Floor { Self(1) } } + +impl Floor { + pub fn increase(&self) -> Self { + Self(self.0.saturating_add(1)) + } + + pub fn decrease(&self) -> Self { + Self(self.0.saturating_sub(1).max(1)) + } +} diff --git a/src/floor/mod.rs b/src/floor/mod.rs index b071bcf..b0e8bc0 100644 --- a/src/floor/mod.rs +++ b/src/floor/mod.rs @@ -4,4 +4,6 @@ mod systems; use bevy::prelude::*; -pub(super) fn plugin(_app: &mut App) {} +pub(super) fn plugin(app: &mut App) { + app.add_plugins(systems::plugin); +} diff --git a/src/floor/systems/mod.rs b/src/floor/systems/mod.rs index 8b13789..5b1303d 100644 --- a/src/floor/systems/mod.rs +++ b/src/floor/systems/mod.rs @@ -1 +1,3 @@ +use bevy::prelude::*; +pub(super) fn plugin(_app: &mut App) {} diff --git a/src/maze/assets.rs b/src/maze/assets.rs index 011d406..12d9872 100644 --- a/src/maze/assets.rs +++ b/src/maze/assets.rs @@ -1,5 +1,7 @@ +use crate::theme::palette::rose_pine::{LOVE, PINE}; + use super::resources::GlobalMazeConfig; -use bevy::prelude::*; +use bevy::{prelude::*, utils::HashMap}; use std::f32::consts::FRAC_PI_2; const WALL_OVERLAP_MODIFIER: f32 = 1.25; @@ -11,6 +13,7 @@ pub(crate) struct MazeAssets { pub(crate) wall_mesh: Handle, pub(crate) hex_material: Handle, pub(crate) wall_material: Handle, + pub(crate) custom_materials: HashMap>, } impl MazeAssets { @@ -19,6 +22,11 @@ impl MazeAssets { materials: &mut ResMut>, global_config: &GlobalMazeConfig, ) -> MazeAssets { + let mut custom_materials = HashMap::new(); + custom_materials.extend(vec![ + ("LOVE".to_string(), materials.add(red_material())), + ("PINE".to_string(), materials.add(blue_material())), + ]); MazeAssets { hex_mesh: meshes.add(generate_hex_mesh( global_config.hex_size, @@ -30,6 +38,7 @@ impl MazeAssets { )), hex_material: materials.add(white_material()), wall_material: materials.add(Color::BLACK), + custom_materials, } } } @@ -53,9 +62,8 @@ fn generate_square_mesh(depth: f32, wall_size: f32) -> Mesh { Mesh::from(rectangular_prism).rotated_by(rotation) } -fn white_material() -> StandardMaterial { +pub(crate) fn white_material() -> StandardMaterial { StandardMaterial { - base_color: Color::WHITE, emissive: LinearRgba::new( WHITE_EMISSION_INTENSITY, WHITE_EMISSION_INTENSITY, @@ -65,3 +73,17 @@ fn white_material() -> StandardMaterial { ..default() } } + +pub(crate) fn red_material() -> StandardMaterial { + StandardMaterial { + emissive: LOVE.to_linear(), + ..default() + } +} + +pub(crate) fn blue_material() -> StandardMaterial { + StandardMaterial { + emissive: PINE.to_linear(), + ..default() + } +} diff --git a/src/maze/triggers/spawn.rs b/src/maze/triggers/spawn.rs index af25d4a..e7ed398 100644 --- a/src/maze/triggers/spawn.rs +++ b/src/maze/triggers/spawn.rs @@ -81,12 +81,28 @@ pub(super) fn spawn_single_hex_tile( HexOrientation::Flat => Quat::from_rotation_y(FRAC_PI_6), // 30 degrees rotation }; + let material = match tile.pos() { + pos if pos == maze_config.start_pos => assets + .custom_materials + .get("PINE") + .cloned() + .to_owned() + .unwrap(), + pos if pos == maze_config.end_pos => assets + .custom_materials + .get("LOVE") + .cloned() + .to_owned() + .unwrap(), + _ => assets.hex_material.clone(), + }; + parent .spawn(( Name::new(format!("Hex {}", tile)), Tile, Mesh3d(assets.hex_mesh.clone()), - MeshMaterial3d(assets.hex_material.clone()), + MeshMaterial3d(material), Transform::from_translation(world_pos).with_rotation(rotation), )) .with_children(|parent| spawn_walls(parent, assets, tile.walls(), global_config)); diff --git a/src/player/events.rs b/src/player/events.rs index 953c8c9..04ed340 100644 --- a/src/player/events.rs +++ b/src/player/events.rs @@ -8,3 +8,13 @@ pub struct RespawnPlayer; #[derive(Debug, Event)] pub struct DespawnPlayer; + +#[derive(Debug, Event)] +pub struct AscendPlayer { + pub floor: u8, +} + +#[derive(Debug, Event)] +pub struct DescendPlayer { + pub floor: u8, +} diff --git a/src/player/mod.rs b/src/player/mod.rs index 480168d..624c110 100644 --- a/src/player/mod.rs +++ b/src/player/mod.rs @@ -6,13 +6,15 @@ mod triggers; use bevy::{ecs::system::RunSystemOnce, prelude::*}; use components::Player; -use events::{DespawnPlayer, RespawnPlayer, SpawnPlayer}; +use events::{AscendPlayer, DescendPlayer, DespawnPlayer, RespawnPlayer, SpawnPlayer}; pub(super) fn plugin(app: &mut App) { app.register_type::() .add_event::() .add_event::() .add_event::() + .add_event::() + .add_event::() .add_plugins((triggers::plugin, systems::plugin)); } diff --git a/src/player/systems/ascend.rs b/src/player/systems/ascend.rs new file mode 100644 index 0000000..c20f01a --- /dev/null +++ b/src/player/systems/ascend.rs @@ -0,0 +1,30 @@ +use bevy::prelude::*; + +use crate::{ + floor::components::{CurrentFloor, Floor}, + maze::components::MazeConfig, + player::{ + components::{CurrentPosition, Player}, + events::AscendPlayer, + }, +}; + +pub(super) fn ascend_player( + query: Query<&CurrentPosition, With>, + maze_config_query: Query<(&MazeConfig, &Floor), With>, + mut event_writer: EventWriter, +) { + let Ok((config, floor)) = maze_config_query.get_single() else { + warn!("No current floor configuration found"); + return; + }; + + for current_hex in query.iter() { + if current_hex.0 == config.end_pos { + event_writer.send(AscendPlayer { + floor: *floor.increase(), + }); + return; + } + } +} diff --git a/src/player/systems/descend.rs b/src/player/systems/descend.rs new file mode 100644 index 0000000..d03b67e --- /dev/null +++ b/src/player/systems/descend.rs @@ -0,0 +1,30 @@ +use bevy::prelude::*; + +use crate::{ + floor::components::{CurrentFloor, Floor}, + maze::components::MazeConfig, + player::{ + components::{CurrentPosition, Player}, + events::DescendPlayer, + }, +}; + +pub(super) fn descend_player( + query: Query<&CurrentPosition, With>, + maze_config_query: Query<(&MazeConfig, &Floor), With>, + mut event_writer: EventWriter, +) { + let Ok((config, floor)) = maze_config_query.get_single() else { + warn!("No current floor configuration found"); + return; + }; + + for current_hex in query.iter() { + if current_hex.0 == config.start_pos { + event_writer.send(DescendPlayer { + floor: *floor.decrease(), + }); + return; + } + } +} diff --git a/src/player/systems/mod.rs b/src/player/systems/mod.rs index 7d69b84..df081cd 100644 --- a/src/player/systems/mod.rs +++ b/src/player/systems/mod.rs @@ -1,17 +1,20 @@ +mod ascend; +mod descend; mod input; mod movement; pub mod setup; +use crate::maze::MazePluginLoaded; +use ascend::ascend_player; use bevy::prelude::*; +use descend::descend_player; use input::player_input; use movement::player_movement; -use crate::maze::MazePluginLoaded; - pub(super) fn plugin(app: &mut App) { app.add_systems( Update, - (player_input, player_movement) + (player_input, player_movement, ascend_player, descend_player) .chain() .run_if(resource_exists::), );