diff --git a/assets/config/health_bar.ron b/assets/config/health_bar.ron index c8be9fc..a579817 100644 --- a/assets/config/health_bar.ron +++ b/assets/config/health_bar.ron @@ -1,8 +1,8 @@ ( color_ramp: [ - Oklcha(Oklcha(lightness: 0.500, chroma: 0.300, hue: 030, alpha: 1.000)), - Oklcha(Oklcha(lightness: 0.500, chroma: 0.300, hue: 030, alpha: 1.000)), - Oklcha(Oklcha(lightness: 0.800, chroma: 0.300, hue: 090, alpha: 1.000)), - Oklcha(Oklcha(lightness: 0.700, chroma: 0.300, hue: 150, alpha: 1.000)), + Oklcha(Oklcha(lightness: 0.500, chroma: 0.300, hue: 030, alpha: 0.600)), + Oklcha(Oklcha(lightness: 0.500, chroma: 0.300, hue: 030, alpha: 0.600)), + Oklcha(Oklcha(lightness: 0.800, chroma: 0.300, hue: 090, alpha: 0.600)), + Oklcha(Oklcha(lightness: 0.700, chroma: 0.300, hue: 150, alpha: 0.600)), ], ) diff --git a/assets/config/theme.ron b/assets/config/theme.ron index c7b488a..f6d6b6e 100644 --- a/assets/config/theme.ron +++ b/assets/config/theme.ron @@ -23,5 +23,7 @@ // Popup Srgba(Srgba(red: 0.106, green: 0.118, blue: 0.122, alpha: 0.850)), + // FacingIndicator + Srgba(Srgba(red: 0.400, green: 0.800, blue: 1.000, alpha: 1.000)), )), ) diff --git a/src/core/theme.rs b/src/core/theme.rs index c996494..e54f928 100644 --- a/src/core/theme.rs +++ b/src/core/theme.rs @@ -69,10 +69,11 @@ pub enum ThemeColor { // Misc UI colors Popup, + FacingIndicator, } impl ThemeColor { - pub const fn set(self) -> ThemeColorFor { + pub const fn target(self) -> ThemeColorFor { ThemeColorFor(self, PhantomData) } } diff --git a/src/game/actor.rs b/src/game/actor.rs index 11496f0..7edbe53 100644 --- a/src/game/actor.rs +++ b/src/game/actor.rs @@ -9,6 +9,7 @@ use bevy::math::vec2; use bevy::math::vec3; use bevy::prelude::*; use bevy::utils::HashMap; +use facing::FacingIndicator; use serde::Deserialize; use serde::Serialize; @@ -110,6 +111,12 @@ fn actor_helper(mut entity: EntityWorldMut, key: Option) -> EntityWorldM size: vec2(8.0, 1.0), }) .insert(Transform::from_translation(vec3(0.0, -4.5, 1.0))); + + children + .spawn_with(FacingIndicator { + radius: vec2(5.5, 4.5), + }) + .insert(Transform::from_translation(vec3(0.0, -0.5, 2.0))); }); entity diff --git a/src/game/actor/facing.rs b/src/game/actor/facing.rs index 3010aa6..4ea7cb5 100644 --- a/src/game/actor/facing.rs +++ b/src/game/actor/facing.rs @@ -1,13 +1,17 @@ +use bevy::ecs::system::EntityCommand; use bevy::prelude::*; +use crate::animation::backup::Backup; use crate::core::camera::CameraRoot; +use crate::core::theme::ThemeColor; use crate::core::window::WindowRoot; +use crate::core::PostTransformSet; use crate::core::UpdateSet; use crate::game::actor::player::IsPlayer; use crate::util::prelude::*; pub(super) fn plugin(app: &mut App) { - app.configure::<(Facing, FacePlayer, FaceCursor)>(); + app.configure::<(Facing, FacePlayer, FaceCursor, FacingIndicator)>(); } #[derive(Component, Reflect)] @@ -78,3 +82,43 @@ fn face_cursor( facing.0 = c!(Dir2::new(target_pos - pos)); } } + +/// Reads from the `Facing` component on its parent entity. +#[derive(Component, Reflect)] +#[reflect(Component)] +pub struct FacingIndicator { + pub radius: Vec2, +} + +impl Configure for FacingIndicator { + fn configure(app: &mut App) { + app.register_type::(); + app.add_systems( + PostUpdate, + update_facing_indicator.in_set(PostTransformSet::Blend), + ); + } +} + +fn update_facing_indicator( + facing_query: Query<&Facing>, + mut facing_indicator_query: Query<(&Parent, &FacingIndicator, &mut Transform)>, +) { + for (parent, facing_indicator, mut transform) in &mut facing_indicator_query { + let facing = c!(facing_query.get(parent.get())); + transform.translation += (facing_indicator.radius * facing.0.as_vec2()).extend(0.0); + transform.rotate(Quat::from_rotation_z(facing.0.to_angle())); + } +} + +impl EntityCommand for FacingIndicator { + fn apply(self, id: Entity, world: &mut World) { + world.entity_mut(id).insert(( + Name::new("FacingIndicator"), + SpriteBundle::default(), + ThemeColor::FacingIndicator.target::(), + Backup::::default(), + self, + )); + } +} diff --git a/src/screen.rs b/src/screen.rs index 09a9eb6..5b36874 100644 --- a/src/screen.rs +++ b/src/screen.rs @@ -49,7 +49,7 @@ const FADE_IN_SECS: f32 = 0.5; fn fade_in(mut entity: EntityWorldMut) { entity.add(widget::overlay).insert(( Name::new("ScreenFadeIn"), - ThemeColor::Body.set::(), + ThemeColor::Body.target::(), FadeIn::new(FADE_IN_SECS), )); } @@ -60,7 +60,7 @@ fn fade_out(to_screen: Screen) -> impl EntityCommand { move |mut entity: EntityWorldMut| { entity.add(widget::blocking_overlay).insert(( Name::new("ScreenFadeOut"), - ThemeColor::Body.set::(), + ThemeColor::Body.target::(), FadeOut::new(FADE_OUT_SECS, to_screen), )); } diff --git a/src/screen/loading.rs b/src/screen/loading.rs index 59a680b..d190713 100644 --- a/src/screen/loading.rs +++ b/src/screen/loading.rs @@ -94,7 +94,7 @@ fn loading_bar(mut entity: EntityWorldMut) { }, ..default() }, - ThemeColor::BodyText.set::(), + ThemeColor::BodyText.target::(), )) .with_children(|children| { children.spawn_with(loading_bar_fill); @@ -112,7 +112,7 @@ fn loading_bar_fill(mut entity: EntityWorldMut) { }, ..default() }, - ThemeColor::Primary.set::(), + ThemeColor::Primary.target::(), IsLoadingBarFill, )); } diff --git a/src/screen/splash.rs b/src/screen/splash.rs index 3292649..dd96944 100644 --- a/src/screen/splash.rs +++ b/src/screen/splash.rs @@ -76,7 +76,7 @@ fn splash_image(mut entity: EntityWorldMut) { )), ..default() }, - ThemeColor::BodyText.set::(), + ThemeColor::BodyText.target::(), )); } diff --git a/src/ui/tooltip.rs b/src/ui/tooltip.rs index 7a00e90..f126012 100644 --- a/src/ui/tooltip.rs +++ b/src/ui/tooltip.rs @@ -39,7 +39,7 @@ impl FromWorld for TooltipRoot { z_index: ZIndex::Global(999), ..default() }, - ThemeColor::Popup.set::(), + ThemeColor::Popup.target::(), )) .id(); diff --git a/src/ui/widget.rs b/src/ui/widget.rs index a56c976..4119985 100644 --- a/src/ui/widget.rs +++ b/src/ui/widget.rs @@ -152,12 +152,12 @@ pub fn menu_button(text: impl Into) -> impl EntityCommand { border_radius: BorderRadius::MAX, ..default() }, - ThemeColor::default().set::(), + ThemeColor::default().target::(), InteractionTable { - normal: ThemeColor::Primary.set::(), - hovered: ThemeColor::PrimaryHovered.set::(), - pressed: ThemeColor::PrimaryPressed.set::(), - disabled: ThemeColor::PrimaryDisabled.set::(), + normal: ThemeColor::Primary.target::(), + hovered: ThemeColor::PrimaryHovered.target::(), + pressed: ThemeColor::PrimaryPressed.target::(), + disabled: ThemeColor::PrimaryDisabled.target::(), }, Offset::default(), Backup::::default(),