mirror of
https://github.com/kristoferssolo/maze-ascension.git
synced 2025-12-30 21:31:37 +00:00
Merge pull request #20 from kristoferssolo/fix/floor-transitions
This commit is contained in:
commit
e096216806
13
justfile
13
justfile
@ -8,7 +8,7 @@ native-dev:
|
|||||||
|
|
||||||
# Run native release
|
# Run native release
|
||||||
native-release:
|
native-release:
|
||||||
cargo run --release --no-default-features
|
RUSTC_WRAPPER=sccache cargo run --release --no-default-features
|
||||||
|
|
||||||
# Run web dev
|
# Run web dev
|
||||||
web-dev:
|
web-dev:
|
||||||
@ -16,8 +16,17 @@ web-dev:
|
|||||||
|
|
||||||
# Run web release
|
# Run web release
|
||||||
web-release:
|
web-release:
|
||||||
trunk serve --release --no-default-features
|
RUSTC_WRAPPER=sccache trunk serve --release --no-default-features
|
||||||
|
|
||||||
# Run tests
|
# Run tests
|
||||||
test:
|
test:
|
||||||
RUSTC_WRAPPER=sccache RUST_BACKTRACE=full cargo nextest run --no-default-features --all-targets
|
RUSTC_WRAPPER=sccache RUST_BACKTRACE=full cargo nextest run --no-default-features --all-targets
|
||||||
|
|
||||||
|
# Run CI localy
|
||||||
|
ci:
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
cargo fmt --all -- --check
|
||||||
|
cargo clippy --workspace --all-targets --all-features -- --deny warnings
|
||||||
|
cargo doc --workspace --all-features --document-private-items --no-deps
|
||||||
|
cargo test --workspace --no-default-features
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
pub const MOVEMENT_THRESHOLD: f32 = 0.01;
|
pub const MOVEMENT_THRESHOLD: f32 = 0.01;
|
||||||
pub const WALL_OVERLAP_MODIFIER: f32 = 1.25;
|
pub const WALL_OVERLAP_MODIFIER: f32 = 1.25;
|
||||||
pub const FLOOR_Y_OFFSET: u8 = 100;
|
pub const FLOOR_Y_OFFSET: u8 = 200;
|
||||||
pub const MOVEMENT_COOLDOWN: f32 = 1.0; // one second cooldown
|
pub const MOVEMENT_COOLDOWN: f32 = 1.0; // one second cooldown
|
||||||
|
|||||||
@ -6,10 +6,12 @@ pub struct Floor(pub u8);
|
|||||||
|
|
||||||
#[derive(Debug, Reflect, Component)]
|
#[derive(Debug, Reflect, Component)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
|
#[require(Floor)]
|
||||||
pub struct CurrentFloor;
|
pub struct CurrentFloor;
|
||||||
|
|
||||||
#[derive(Debug, Reflect, Component, Deref, DerefMut)]
|
#[derive(Debug, Reflect, Component, Deref, DerefMut)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
|
#[require(Floor)]
|
||||||
pub struct FloorYTarget(pub f32);
|
pub struct FloorYTarget(pub f32);
|
||||||
|
|
||||||
impl Default for Floor {
|
impl Default for Floor {
|
||||||
|
|||||||
@ -15,8 +15,9 @@ pub(super) fn plugin(app: &mut App) {
|
|||||||
spawn_floor,
|
spawn_floor,
|
||||||
despawn_floor,
|
despawn_floor,
|
||||||
handle_floor_transition_events,
|
handle_floor_transition_events,
|
||||||
move_floors.after(handle_floor_transition_events),
|
move_floors,
|
||||||
)
|
)
|
||||||
|
.chain()
|
||||||
.run_if(resource_exists::<MazePluginLoaded>),
|
.run_if(resource_exists::<MazePluginLoaded>),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,10 +12,7 @@ use bevy::prelude::*;
|
|||||||
|
|
||||||
pub fn move_floors(
|
pub fn move_floors(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut maze_query: Query<
|
mut maze_query: Query<(Entity, &mut Transform, &FloorYTarget), With<FloorYTarget>>,
|
||||||
(Entity, &mut Transform, &FloorYTarget),
|
|
||||||
(With<HexMaze>, With<FloorYTarget>),
|
|
||||||
>,
|
|
||||||
player_query: Query<&MovementSpeed, With<Player>>,
|
player_query: Query<&MovementSpeed, With<Player>>,
|
||||||
time: Res<Time>,
|
time: Res<Time>,
|
||||||
) {
|
) {
|
||||||
@ -48,7 +45,6 @@ pub fn handle_floor_transition_events(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for event in event_reader.read() {
|
for event in event_reader.read() {
|
||||||
dbg!(&event);
|
|
||||||
let Some((current_entity, current_floor)) = current_query.get_single().ok() else {
|
let Some((current_entity, current_floor)) = current_query.get_single().ok() else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
@ -68,7 +64,6 @@ pub fn handle_floor_transition_events(
|
|||||||
|
|
||||||
for (entity, transforms, _, movement_state) in maze_query.iter_mut() {
|
for (entity, transforms, _, movement_state) in maze_query.iter_mut() {
|
||||||
let target_y = (FLOOR_Y_OFFSET as f32).mul_add(direction, transforms.translation.y);
|
let target_y = (FLOOR_Y_OFFSET as f32).mul_add(direction, transforms.translation.y);
|
||||||
dbg!(movement_state, target_y);
|
|
||||||
if movement_state.is_none() {
|
if movement_state.is_none() {
|
||||||
commands.entity(entity).insert(FloorYTarget(target_y));
|
commands.entity(entity).insert(FloorYTarget(target_y));
|
||||||
}
|
}
|
||||||
@ -77,7 +72,6 @@ pub fn handle_floor_transition_events(
|
|||||||
update_current_next_floor(&mut commands, current_entity, target_entity);
|
update_current_next_floor(&mut commands, current_entity, target_entity);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
event_reader.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_current_next_floor(commands: &mut Commands, current: Entity, target: Entity) {
|
fn update_current_next_floor(commands: &mut Commands, current: Entity, target: Entity) {
|
||||||
|
|||||||
@ -4,17 +4,17 @@ use crate::{
|
|||||||
events::TransitionFloor,
|
events::TransitionFloor,
|
||||||
resources::HighestFloor,
|
resources::HighestFloor,
|
||||||
},
|
},
|
||||||
maze::events::SpawnMaze,
|
maze::{components::MazeConfig, events::SpawnMaze},
|
||||||
};
|
};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
pub(super) fn spawn_floor(
|
pub(super) fn spawn_floor(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
query: Query<&mut Floor, (With<CurrentFloor>, Without<FloorYTarget>)>,
|
query: Query<(&mut Floor, &MazeConfig), (With<CurrentFloor>, Without<FloorYTarget>)>,
|
||||||
mut event_reader: EventReader<TransitionFloor>,
|
mut event_reader: EventReader<TransitionFloor>,
|
||||||
mut highest_floor: ResMut<HighestFloor>,
|
mut highest_floor: ResMut<HighestFloor>,
|
||||||
) {
|
) {
|
||||||
let Ok(current_floor) = query.get_single() else {
|
let Ok((current_floor, config)) = query.get_single() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -24,14 +24,17 @@ pub(super) fn spawn_floor(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let next_floor = event.next_floor_num(current_floor);
|
let target_floor = event.next_floor_num(current_floor);
|
||||||
highest_floor.0 = highest_floor.0.max(next_floor);
|
highest_floor.0 = highest_floor.0.max(target_floor);
|
||||||
|
|
||||||
info!("Creating level for floor {}", next_floor);
|
info!("Creating level for floor {}", target_floor);
|
||||||
|
|
||||||
commands.trigger(SpawnMaze {
|
commands.trigger(SpawnMaze {
|
||||||
floor: next_floor,
|
floor: target_floor,
|
||||||
|
config: MazeConfig {
|
||||||
|
start_pos: config.end_pos,
|
||||||
..default()
|
..default()
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
11
src/lib.rs
11
src/lib.rs
@ -14,6 +14,7 @@ use bevy::{
|
|||||||
audio::{AudioPlugin, Volume},
|
audio::{AudioPlugin, Volume},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
use theme::{palette::rose_pine, prelude::ColorScheme};
|
||||||
|
|
||||||
pub struct AppPlugin;
|
pub struct AppPlugin;
|
||||||
|
|
||||||
@ -26,7 +27,7 @@ impl Plugin for AppPlugin {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Spawn the main camera.
|
// Spawn the main camera.
|
||||||
app.add_systems(Startup, spawn_camera);
|
app.add_systems(Startup, (spawn_camera, load_background));
|
||||||
|
|
||||||
// Add Bevy plugins.
|
// Add Bevy plugins.
|
||||||
app.add_plugins(
|
app.add_plugins(
|
||||||
@ -100,3 +101,11 @@ fn spawn_camera(mut commands: Commands) {
|
|||||||
IsDefaultUiCamera,
|
IsDefaultUiCamera,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn load_background(mut commands: Commands) {
|
||||||
|
#[cfg(feature = "dev")]
|
||||||
|
let colorcheme = rose_pine::RosePine::Base;
|
||||||
|
#[cfg(not(feature = "dev"))]
|
||||||
|
let colorcheme = rose_pine::RosePineDawn::Base;
|
||||||
|
commands.insert_resource(ClearColor(colorcheme.to_color()));
|
||||||
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use super::resources::GlobalMazeConfig;
|
use super::resources::GlobalMazeConfig;
|
||||||
use crate::{
|
use crate::{
|
||||||
constants::WALL_OVERLAP_MODIFIER,
|
constants::WALL_OVERLAP_MODIFIER,
|
||||||
theme::{palette::rose_pine::RosePine, prelude::ColorScheme},
|
theme::{palette::rose_pine::RosePineDawn, prelude::ColorScheme},
|
||||||
};
|
};
|
||||||
use bevy::{prelude::*, utils::HashMap};
|
use bevy::{prelude::*, utils::HashMap};
|
||||||
use std::f32::consts::FRAC_PI_2;
|
use std::f32::consts::FRAC_PI_2;
|
||||||
@ -15,7 +15,7 @@ pub struct MazeAssets {
|
|||||||
pub wall_mesh: Handle<Mesh>,
|
pub wall_mesh: Handle<Mesh>,
|
||||||
pub hex_material: Handle<StandardMaterial>,
|
pub hex_material: Handle<StandardMaterial>,
|
||||||
pub wall_material: Handle<StandardMaterial>,
|
pub wall_material: Handle<StandardMaterial>,
|
||||||
pub custom_materials: HashMap<RosePine, Handle<StandardMaterial>>,
|
pub custom_materials: HashMap<RosePineDawn, Handle<StandardMaterial>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MazeAssets {
|
impl MazeAssets {
|
||||||
@ -24,7 +24,7 @@ impl MazeAssets {
|
|||||||
materials: &mut ResMut<Assets<StandardMaterial>>,
|
materials: &mut ResMut<Assets<StandardMaterial>>,
|
||||||
global_config: &GlobalMazeConfig,
|
global_config: &GlobalMazeConfig,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let custom_materials = RosePine::iter()
|
let custom_materials = RosePineDawn::iter()
|
||||||
.map(|color| (color, materials.add(color.to_standart_material())))
|
.map(|color| (color, materials.add(color.to_standart_material())))
|
||||||
.collect();
|
.collect();
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
@ -35,18 +35,17 @@ impl MazeConfig {
|
|||||||
orientation: HexOrientation,
|
orientation: HexOrientation,
|
||||||
seed: Option<u64>,
|
seed: Option<u64>,
|
||||||
global_conig: &GlobalMazeConfig,
|
global_conig: &GlobalMazeConfig,
|
||||||
|
start_pos: Option<Hex>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let seed = seed.unwrap_or_else(|| thread_rng().gen());
|
let seed = seed.unwrap_or_else(|| thread_rng().gen());
|
||||||
let mut rng = StdRng::seed_from_u64(seed);
|
let mut rng = StdRng::seed_from_u64(seed);
|
||||||
|
|
||||||
// Generate start and end positions ensuring they're different
|
let start_pos = start_pos.unwrap_or_else(|| generate_pos(radius, &mut rng));
|
||||||
let mut start_pos;
|
|
||||||
|
// Generate end position ensuring start and end are different
|
||||||
let mut end_pos;
|
let mut end_pos;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
start_pos = generate_pos(radius, &mut rng);
|
|
||||||
end_pos = generate_pos(radius, &mut rng);
|
end_pos = generate_pos(radius, &mut rng);
|
||||||
|
|
||||||
if start_pos != end_pos {
|
if start_pos != end_pos {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -79,7 +78,13 @@ impl MazeConfig {
|
|||||||
|
|
||||||
impl Default for MazeConfig {
|
impl Default for MazeConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new(8, HexOrientation::Flat, None, &GlobalMazeConfig::default())
|
Self::new(
|
||||||
|
8,
|
||||||
|
HexOrientation::Flat,
|
||||||
|
None,
|
||||||
|
&GlobalMazeConfig::default(),
|
||||||
|
None,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,7 +131,7 @@ mod tests {
|
|||||||
let seed = Some(12345);
|
let seed = Some(12345);
|
||||||
let global_config = GlobalMazeConfig::default();
|
let global_config = GlobalMazeConfig::default();
|
||||||
|
|
||||||
let config = MazeConfig::new(radius, orientation, seed, &global_config);
|
let config = MazeConfig::new(radius, orientation, seed, &global_config, None);
|
||||||
|
|
||||||
assert_eq!(config.radius, radius);
|
assert_eq!(config.radius, radius);
|
||||||
assert_eq!(config.seed, 12345);
|
assert_eq!(config.seed, 12345);
|
||||||
@ -173,8 +178,13 @@ mod tests {
|
|||||||
];
|
];
|
||||||
|
|
||||||
for seed in test_seeds {
|
for seed in test_seeds {
|
||||||
let config =
|
let config = MazeConfig::new(
|
||||||
MazeConfig::new(8, HexOrientation::Flat, seed, &GlobalMazeConfig::default());
|
8,
|
||||||
|
HexOrientation::Flat,
|
||||||
|
seed,
|
||||||
|
&GlobalMazeConfig::default(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(config.radius, 8);
|
assert_eq!(config.radius, 8);
|
||||||
assert_eq!(config.layout.orientation, HexOrientation::Flat);
|
assert_eq!(config.layout.orientation, HexOrientation::Flat);
|
||||||
@ -226,12 +236,14 @@ mod tests {
|
|||||||
HexOrientation::Flat,
|
HexOrientation::Flat,
|
||||||
Some(1),
|
Some(1),
|
||||||
&GlobalMazeConfig::default(),
|
&GlobalMazeConfig::default(),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
let config2 = MazeConfig::new(
|
let config2 = MazeConfig::new(
|
||||||
8,
|
8,
|
||||||
HexOrientation::Flat,
|
HexOrientation::Flat,
|
||||||
Some(2),
|
Some(2),
|
||||||
&GlobalMazeConfig::default(),
|
&GlobalMazeConfig::default(),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_ne!(config1.start_pos, config2.start_pos);
|
assert_ne!(config1.start_pos, config2.start_pos);
|
||||||
@ -241,8 +253,20 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn same_seed_same_positions() {
|
fn same_seed_same_positions() {
|
||||||
let seed = Some(12345);
|
let seed = Some(12345);
|
||||||
let config1 = MazeConfig::new(8, HexOrientation::Flat, seed, &GlobalMazeConfig::default());
|
let config1 = MazeConfig::new(
|
||||||
let config2 = MazeConfig::new(8, HexOrientation::Flat, seed, &GlobalMazeConfig::default());
|
8,
|
||||||
|
HexOrientation::Flat,
|
||||||
|
seed,
|
||||||
|
&GlobalMazeConfig::default(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
let config2 = MazeConfig::new(
|
||||||
|
8,
|
||||||
|
HexOrientation::Flat,
|
||||||
|
seed,
|
||||||
|
&GlobalMazeConfig::default(),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(config1.start_pos, config2.start_pos);
|
assert_eq!(config1.start_pos, config2.start_pos);
|
||||||
assert_eq!(config1.end_pos, config2.end_pos);
|
assert_eq!(config1.end_pos, config2.end_pos);
|
||||||
@ -255,6 +279,7 @@ mod tests {
|
|||||||
HexOrientation::Pointy,
|
HexOrientation::Pointy,
|
||||||
None,
|
None,
|
||||||
&GlobalMazeConfig::default(),
|
&GlobalMazeConfig::default(),
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
assert_eq!(config.layout.orientation, HexOrientation::Pointy);
|
assert_eq!(config.layout.orientation, HexOrientation::Pointy);
|
||||||
}
|
}
|
||||||
@ -269,6 +294,7 @@ mod tests {
|
|||||||
hex_size: 0.0,
|
hex_size: 0.0,
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
assert_eq!(config.layout.hex_size.x, 0.0);
|
assert_eq!(config.layout.hex_size.x, 0.0);
|
||||||
assert_eq!(config.layout.hex_size.y, 0.0);
|
assert_eq!(config.layout.hex_size.y, 0.0);
|
||||||
|
|||||||
@ -8,8 +8,9 @@ use crate::{
|
|||||||
events::SpawnMaze,
|
events::SpawnMaze,
|
||||||
resources::GlobalMazeConfig,
|
resources::GlobalMazeConfig,
|
||||||
},
|
},
|
||||||
theme::palette::rose_pine::RosePine,
|
theme::palette::rose_pine::RosePineDawn,
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use hexlab::prelude::{Tile as HexTile, *};
|
use hexlab::prelude::{Tile as HexTile, *};
|
||||||
use hexx::HexOrientation;
|
use hexx::HexOrientation;
|
||||||
@ -43,8 +44,6 @@ pub(super) fn spawn_maze(
|
|||||||
_ => FLOOR_Y_OFFSET,
|
_ => FLOOR_Y_OFFSET,
|
||||||
} as f32;
|
} as f32;
|
||||||
|
|
||||||
// (floor - 1) * FLOOR_Y_OFFSET
|
|
||||||
|
|
||||||
let entity = commands
|
let entity = commands
|
||||||
.spawn((
|
.spawn((
|
||||||
Name::new(format!("Floor {}", floor)),
|
Name::new(format!("Floor {}", floor)),
|
||||||
@ -100,12 +99,12 @@ pub(super) fn spawn_single_hex_tile(
|
|||||||
let material = match tile.pos() {
|
let material = match tile.pos() {
|
||||||
pos if pos == maze_config.start_pos => assets
|
pos if pos == maze_config.start_pos => assets
|
||||||
.custom_materials
|
.custom_materials
|
||||||
.get(&RosePine::Pine)
|
.get(&RosePineDawn::Pine)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
pos if pos == maze_config.end_pos => assets
|
pos if pos == maze_config.end_pos => assets
|
||||||
.custom_materials
|
.custom_materials
|
||||||
.get(&RosePine::Love)
|
.get(&RosePineDawn::Love)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
_ => assets.hex_material.clone(),
|
_ => assets.hex_material.clone(),
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
|
|
||||||
use crate::theme::{palette::rose_pine::RosePine, prelude::ColorScheme};
|
use crate::theme::{palette::rose_pine::RosePineDawn, prelude::ColorScheme};
|
||||||
|
|
||||||
pub(super) fn generate_pill_mesh(radius: f32, half_length: f32) -> Mesh {
|
pub(super) fn generate_pill_mesh(radius: f32, half_length: f32) -> Mesh {
|
||||||
Mesh::from(Capsule3d {
|
Mesh::from(Capsule3d {
|
||||||
@ -10,7 +10,7 @@ pub(super) fn generate_pill_mesh(radius: f32, half_length: f32) -> Mesh {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn blue_material() -> StandardMaterial {
|
pub(super) fn blue_material() -> StandardMaterial {
|
||||||
let color = RosePine::Pine;
|
let color = RosePineDawn::Pine;
|
||||||
StandardMaterial {
|
StandardMaterial {
|
||||||
base_color: color.to_color(),
|
base_color: color.to_color(),
|
||||||
emissive: color.to_linear_rgba() * 3.,
|
emissive: color.to_linear_rgba() * 3.,
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use hexx::Hex;
|
|||||||
|
|
||||||
#[derive(Debug, Reflect, Component)]
|
#[derive(Debug, Reflect, Component)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
#[require(CurrentPosition, MovementSpeed, MovementTarget)]
|
#[require(CurrentPosition, MovementSpeed, MovementTarget, TranstitionState)]
|
||||||
pub struct Player;
|
pub struct Player;
|
||||||
|
|
||||||
#[derive(Debug, Reflect, Component, Deref, DerefMut, Default)]
|
#[derive(Debug, Reflect, Component, Deref, DerefMut, Default)]
|
||||||
@ -14,6 +14,13 @@ pub struct CurrentPosition(pub Hex);
|
|||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct MovementSpeed(pub f32);
|
pub struct MovementSpeed(pub f32);
|
||||||
|
|
||||||
|
#[derive(Debug, Reflect, Component, Default)]
|
||||||
|
#[reflect(Component)]
|
||||||
|
pub struct TranstitionState {
|
||||||
|
pub just_transitioned: bool,
|
||||||
|
pub last_position: Hex,
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for MovementSpeed {
|
impl Default for MovementSpeed {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self(100.)
|
Self(100.)
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
floor::components::CurrentFloor,
|
floor::components::{CurrentFloor, FloorYTarget},
|
||||||
maze::components::MazeConfig,
|
maze::components::MazeConfig,
|
||||||
player::components::{CurrentPosition, MovementTarget, Player},
|
player::components::{CurrentPosition, MovementTarget, Player},
|
||||||
};
|
};
|
||||||
@ -10,12 +10,16 @@ use hexx::{EdgeDirection, HexOrientation};
|
|||||||
pub(super) fn player_input(
|
pub(super) fn player_input(
|
||||||
input: Res<ButtonInput<KeyCode>>,
|
input: Res<ButtonInput<KeyCode>>,
|
||||||
mut player_query: Query<(&mut MovementTarget, &CurrentPosition), With<Player>>,
|
mut player_query: Query<(&mut MovementTarget, &CurrentPosition), With<Player>>,
|
||||||
maze_query: Query<(&Maze, &MazeConfig), With<CurrentFloor>>,
|
maze_query: Query<(&Maze, &MazeConfig, Has<FloorYTarget>), With<CurrentFloor>>,
|
||||||
) {
|
) {
|
||||||
let Ok((maze, maze_config)) = maze_query.get_single() else {
|
let Ok((maze, maze_config, has_y_target)) = maze_query.get_single() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if has_y_target {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (mut target_pos, current_pos) in player_query.iter_mut() {
|
for (mut target_pos, current_pos) in player_query.iter_mut() {
|
||||||
if target_pos.is_some() {
|
if target_pos.is_some() {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@ -6,11 +6,11 @@ use crate::{
|
|||||||
events::TransitionFloor,
|
events::TransitionFloor,
|
||||||
},
|
},
|
||||||
maze::components::MazeConfig,
|
maze::components::MazeConfig,
|
||||||
player::components::{CurrentPosition, Player},
|
player::components::{CurrentPosition, Player, TranstitionState},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn handle_floor_transition(
|
pub fn handle_floor_transition(
|
||||||
player_query: Query<&CurrentPosition, With<Player>>,
|
mut player_query: Query<(&CurrentPosition, &mut TranstitionState), With<Player>>,
|
||||||
maze_query: Query<(&MazeConfig, &Floor), With<CurrentFloor>>,
|
maze_query: Query<(&MazeConfig, &Floor), With<CurrentFloor>>,
|
||||||
mut event_writer: EventWriter<TransitionFloor>,
|
mut event_writer: EventWriter<TransitionFloor>,
|
||||||
) {
|
) {
|
||||||
@ -19,17 +19,30 @@ pub fn handle_floor_transition(
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
for current_hex in player_query.iter() {
|
for (current_hex, mut transition_state) in player_query.iter_mut() {
|
||||||
|
// Reset transition state if moved to a new position
|
||||||
|
if current_hex.0 != transition_state.last_position {
|
||||||
|
transition_state.just_transitioned = false;
|
||||||
|
}
|
||||||
|
transition_state.last_position = current_hex.0;
|
||||||
|
|
||||||
|
// Skip if transition just happened
|
||||||
|
if transition_state.just_transitioned {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Check for ascending
|
// Check for ascending
|
||||||
if current_hex.0 == config.end_pos {
|
if current_hex.0 == config.end_pos {
|
||||||
info!("Ascending");
|
info!("Ascending");
|
||||||
event_writer.send(TransitionFloor::Ascend);
|
event_writer.send(TransitionFloor::Ascend);
|
||||||
|
transition_state.just_transitioned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for descending
|
// Check for descending
|
||||||
if current_hex.0 == config.start_pos && floor.0 != 1 {
|
if current_hex.0 == config.start_pos && floor.0 != 1 {
|
||||||
info!("Descending");
|
info!("Descending");
|
||||||
event_writer.send(TransitionFloor::Descend);
|
event_writer.send(TransitionFloor::Descend);
|
||||||
|
transition_state.just_transitioned = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,92 @@
|
|||||||
use super::rgb_u8;
|
use crate::{
|
||||||
use crate::theme::prelude::ColorScheme;
|
create_color_scheme,
|
||||||
|
theme::{colorscheme::ColorScheme, palette::rgb_u8},
|
||||||
|
};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use strum::EnumIter;
|
use strum::EnumIter;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter)]
|
create_color_scheme!(
|
||||||
pub enum RosePine {
|
pub RosePine, {
|
||||||
|
Base: "#191724",
|
||||||
|
Surface: "#1f1d2e",
|
||||||
|
Overlay: "#26233a",
|
||||||
|
Muted: "#6e6a86",
|
||||||
|
Subtle: "#908caa",
|
||||||
|
Text: "#e0def4",
|
||||||
|
Love: "#eb6f92",
|
||||||
|
Gold: "#f6c177",
|
||||||
|
Rose: "#ebbcba",
|
||||||
|
Pine: "#31748f",
|
||||||
|
Foam: "#9ccfd8",
|
||||||
|
Iris: "#c4a7e7",
|
||||||
|
HighlightLow: "#21202e",
|
||||||
|
HighlightMed: "#403d52",
|
||||||
|
HighlightHigh: "#524f67"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
create_color_scheme!(
|
||||||
|
pub RosePineMoon, {
|
||||||
|
Base: "#232136",
|
||||||
|
Surface: "#2a273f",
|
||||||
|
Overlay: "#393552",
|
||||||
|
Muted: "#6e6a86",
|
||||||
|
Subtle: "#908caa",
|
||||||
|
Text: "#e0def4",
|
||||||
|
Love: "#eb6f92",
|
||||||
|
Gold: "#f6c177",
|
||||||
|
Rose: "#ea9a97",
|
||||||
|
Pine: "#3e8fb0",
|
||||||
|
Foam: "#9ccfd8",
|
||||||
|
Iris: "#c4a7e7",
|
||||||
|
HighlightLow: "#2a283e",
|
||||||
|
HighlightMed: "#44415a",
|
||||||
|
HighlightHigh: "#56526e"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
create_color_scheme!(
|
||||||
|
pub RosePineDawn, {
|
||||||
|
Base: "#faf4ed",
|
||||||
|
Surface: "#fffaf3",
|
||||||
|
Overlay: "#f2e9e1",
|
||||||
|
Muted: "#9893a5",
|
||||||
|
Subtle: "#797593",
|
||||||
|
Text: "#575279",
|
||||||
|
Love: "#b4637a",
|
||||||
|
Gold: "#ea9d34",
|
||||||
|
Rose: "#d7827e",
|
||||||
|
Pine: "#286983",
|
||||||
|
Foam: "#56949f",
|
||||||
|
Iris: "#907aa9",
|
||||||
|
HighlightLow: "#f4ede8",
|
||||||
|
HighlightMed: "#dfdad9",
|
||||||
|
HighlightHigh: "#cecacd"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! create_color_scheme {
|
||||||
|
($(#[$meta:meta])* $vis:vis $name:ident, {
|
||||||
|
Base: $base:expr,
|
||||||
|
Surface: $surface:expr,
|
||||||
|
Overlay: $overlay:expr,
|
||||||
|
Muted: $muted:expr,
|
||||||
|
Subtle: $subtle:expr,
|
||||||
|
Text: $text:expr,
|
||||||
|
Love: $love:expr,
|
||||||
|
Gold: $gold:expr,
|
||||||
|
Rose: $rose:expr,
|
||||||
|
Pine: $pine:expr,
|
||||||
|
Foam: $foam:expr,
|
||||||
|
Iris: $iris:expr,
|
||||||
|
HighlightLow: $hl_low:expr,
|
||||||
|
HighlightMed: $hl_med:expr,
|
||||||
|
HighlightHigh: $hl_high:expr
|
||||||
|
}) => {
|
||||||
|
$(#[$meta])*
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, EnumIter)]
|
||||||
|
$vis enum $name {
|
||||||
Base,
|
Base,
|
||||||
Surface,
|
Surface,
|
||||||
Overlay,
|
Overlay,
|
||||||
@ -20,26 +102,83 @@ pub enum RosePine {
|
|||||||
HighlightLow,
|
HighlightLow,
|
||||||
HighlightMed,
|
HighlightMed,
|
||||||
HighlightHigh,
|
HighlightHigh,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorScheme for RosePine {
|
impl $name {
|
||||||
|
fn hex_to_rgb(hex: &str) -> (u8, u8, u8) {
|
||||||
|
let hex = hex.strip_prefix('#').unwrap_or(hex);
|
||||||
|
let r = u8::from_str_radix(&hex[0..2], 16).unwrap_or(0);
|
||||||
|
let g = u8::from_str_radix(&hex[2..4], 16).unwrap_or(0);
|
||||||
|
let b = u8::from_str_radix(&hex[4..6], 16).unwrap_or(0);
|
||||||
|
(r, g, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ColorScheme for $name {
|
||||||
fn to_color(&self) -> Color {
|
fn to_color(&self) -> Color {
|
||||||
match self {
|
match self {
|
||||||
Self::Base => rgb_u8(25, 23, 36),
|
Self::Base => {
|
||||||
Self::Surface => rgb_u8(31, 29, 46),
|
let (r, g, b) = Self::hex_to_rgb($base);
|
||||||
Self::Overlay => rgb_u8(38, 35, 58),
|
rgb_u8(r, g, b)
|
||||||
Self::Muted => rgb_u8(110, 106, 134),
|
},
|
||||||
Self::Subtle => rgb_u8(144, 140, 170),
|
Self::Surface => {
|
||||||
Self::Text => rgb_u8(224, 222, 244),
|
let (r, g, b) = Self::hex_to_rgb($surface);
|
||||||
Self::Love => rgb_u8(235, 111, 146),
|
rgb_u8(r, g, b)
|
||||||
Self::Gold => rgb_u8(246, 193, 119),
|
},
|
||||||
Self::Rose => rgb_u8(235, 188, 186),
|
Self::Overlay => {
|
||||||
Self::Pine => rgb_u8(49, 116, 143),
|
let (r, g, b) = Self::hex_to_rgb($overlay);
|
||||||
Self::Foam => rgb_u8(156, 207, 216),
|
rgb_u8(r, g, b)
|
||||||
Self::Iris => rgb_u8(196, 167, 231),
|
},
|
||||||
Self::HighlightLow => rgb_u8(33, 32, 46),
|
Self::Muted => {
|
||||||
Self::HighlightMed => rgb_u8(64, 61, 82),
|
let (r, g, b) = Self::hex_to_rgb($muted);
|
||||||
Self::HighlightHigh => rgb_u8(82, 79, 103),
|
rgb_u8(r, g, b)
|
||||||
|
},
|
||||||
|
Self::Subtle => {
|
||||||
|
let (r, g, b) = Self::hex_to_rgb($subtle);
|
||||||
|
rgb_u8(r, g, b)
|
||||||
|
},
|
||||||
|
Self::Text => {
|
||||||
|
let (r, g, b) = Self::hex_to_rgb($text);
|
||||||
|
rgb_u8(r, g, b)
|
||||||
|
},
|
||||||
|
Self::Love => {
|
||||||
|
let (r, g, b) = Self::hex_to_rgb($love);
|
||||||
|
rgb_u8(r, g, b)
|
||||||
|
},
|
||||||
|
Self::Gold => {
|
||||||
|
let (r, g, b) = Self::hex_to_rgb($gold);
|
||||||
|
rgb_u8(r, g, b)
|
||||||
|
},
|
||||||
|
Self::Rose => {
|
||||||
|
let (r, g, b) = Self::hex_to_rgb($rose);
|
||||||
|
rgb_u8(r, g, b)
|
||||||
|
},
|
||||||
|
Self::Pine => {
|
||||||
|
let (r, g, b) = Self::hex_to_rgb($pine);
|
||||||
|
rgb_u8(r, g, b)
|
||||||
|
},
|
||||||
|
Self::Foam => {
|
||||||
|
let (r, g, b) = Self::hex_to_rgb($foam);
|
||||||
|
rgb_u8(r, g, b)
|
||||||
|
},
|
||||||
|
Self::Iris => {
|
||||||
|
let (r, g, b) = Self::hex_to_rgb($iris);
|
||||||
|
rgb_u8(r, g, b)
|
||||||
|
},
|
||||||
|
Self::HighlightLow => {
|
||||||
|
let (r, g, b) = Self::hex_to_rgb($hl_low);
|
||||||
|
rgb_u8(r, g, b)
|
||||||
|
},
|
||||||
|
Self::HighlightMed => {
|
||||||
|
let (r, g, b) = Self::hex_to_rgb($hl_med);
|
||||||
|
rgb_u8(r, g, b)
|
||||||
|
},
|
||||||
|
Self::HighlightHigh => {
|
||||||
|
let (r, g, b) = Self::hex_to_rgb($hl_high);
|
||||||
|
rgb_u8(r, g, b)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user