diff --git a/src/game/actor.rs b/src/game/actor.rs index cc8fa3b..c6d1eaa 100644 --- a/src/game/actor.rs +++ b/src/game/actor.rs @@ -6,6 +6,7 @@ pub mod health; pub mod level; pub mod movement; pub mod player; +mod shield; use avian2d::prelude::*; use bevy::ecs::system::EntityCommand; @@ -17,6 +18,7 @@ use bevy::utils::HashMap; use iyes_progress::prelude::*; use serde::Deserialize; use serde::Serialize; +use shield::IsShield; use crate::game::actor::attack::Attack; use crate::game::actor::attack::AttackController; @@ -33,6 +35,7 @@ use crate::game::audio::music::Beat; use crate::game::card::deck::Deck; use crate::game::combat::hit::Hurtbox; use crate::game::sprite::SpriteAnimation; +use crate::screen::playing::PlayingAssets; use crate::util::prelude::*; pub(super) fn plugin(app: &mut App) { @@ -47,6 +50,7 @@ pub(super) fn plugin(app: &mut App) { level::plugin, movement::plugin, player::plugin, + shield::plugin, )); } @@ -130,6 +134,7 @@ fn one() -> f64 { impl EntityCommand for Actor { fn apply(mut self, id: Entity, world: &mut World) { self.deck.active += world.resource::().total as isize - 1; + let bubble_texture = world.resource::().bubble.clone(); world .entity_mut(id) @@ -174,6 +179,18 @@ impl EntityCommand for Actor { size: vec2(8.0, 1.0), }) .insert(Transform::from_translation(vec3(0.0, -4.5, 1.0))); + children + .spawn(( + Name::new("Shield"), + SpriteBundle { + transform: Transform::default(), + texture: bubble_texture, + visibility: Visibility::Hidden, + ..default() + }, + IsShield, + )) + .insert(Transform::from_translation(vec3(0.0, -0.5, 2.0))); }); } } diff --git a/src/game/actor/player.rs b/src/game/actor/player.rs index c0dc6d8..d7ee42f 100644 --- a/src/game/actor/player.rs +++ b/src/game/actor/player.rs @@ -7,7 +7,6 @@ use bevy::prelude::*; use crate::core::camera::CameraRoot; use crate::core::camera::SmoothFollow; -use crate::core::UpdateSet; use crate::game::actor::attack::input::attack_action; use crate::game::actor::facing::FaceCursor; use crate::game::actor::facing::FacingIndicator; @@ -17,7 +16,6 @@ use crate::game::actor::ActorConfig; use crate::game::combat::death::DeathSfx; use crate::game::combat::hit::Hitbox; use crate::game::combat::hit::HurtSfx; -use crate::game::combat::hit::Immune; use crate::game::combat::knockback::HitboxKnockback; use crate::game::GameLayer; use crate::game::GameRoot; @@ -25,7 +23,7 @@ use crate::screen::playing::PlayingAssets; use crate::util::prelude::*; pub(super) fn plugin(app: &mut App) { - app.configure::<(IsPlayer, IsImmuneBubble)>(); + app.configure::(); } #[derive(Component, Reflect, Default)] @@ -42,7 +40,7 @@ pub fn player(key: impl Into) -> impl EntityCommand { let key = key.into(); move |entity: Entity, world: &mut World| { - let (actor, parent, camera, sfx_hurt, sfx_death, bubble_texture) = { + let (actor, parent, camera, sfx_hurt, sfx_death) = { let (config, game_root, camera_root, assets) = SystemState::<( ConfigRef, Res, @@ -59,7 +57,6 @@ pub fn player(key: impl Into) -> impl EntityCommand { camera_root.primary, assets.sfx_player_hurt.clone(), assets.sfx_restart.clone(), - assets.bubble.clone(), ) }; @@ -85,17 +82,6 @@ pub fn player(key: impl Into) -> impl EntityCommand { offset: vec2(6.0, 5.0), }) .insert(Transform::from_translation(vec3(0.0, -0.5, 2.0))); - children - .spawn(( - SpriteBundle { - transform: Transform::default(), - texture: bubble_texture, - visibility: Visibility::Hidden, - ..default() - }, - IsImmuneBubble, - )) - .insert(Transform::from_translation(vec3(0.0, -0.5, 2.0))); }); // Allow manual movement / attack input in dev builds. @@ -108,27 +94,3 @@ pub fn player(key: impl Into) -> impl EntityCommand { r!(world.entity_mut(camera).get_mut::()).target = entity; } } - -#[derive(Component, Reflect)] -#[reflect(Component)] -struct IsImmuneBubble; - -impl Configure for IsImmuneBubble { - fn configure(app: &mut App) { - app.register_type::(); - app.add_systems(Update, update_immune_bubble.in_set(UpdateSet::SyncLate)); - } -} - -fn update_immune_bubble( - mut bubble_query: Query<(&mut Visibility, &Parent), With>, - immune_query: Query<(), With>, -) { - for (mut visibility, parent) in &mut bubble_query { - *visibility = if immune_query.contains(parent.get()) { - Visibility::Inherited - } else { - Visibility::Hidden - }; - } -} diff --git a/src/game/actor/shield.rs b/src/game/actor/shield.rs new file mode 100644 index 0000000..afeb9b7 --- /dev/null +++ b/src/game/actor/shield.rs @@ -0,0 +1,33 @@ +use bevy::prelude::*; + +use crate::core::UpdateSet; +use crate::game::combat::hit::Immune; +use crate::util::prelude::*; + +pub(super) fn plugin(app: &mut App) { + app.configure::(); +} + +#[derive(Component, Reflect)] +#[reflect(Component)] +pub struct IsShield; + +impl Configure for IsShield { + fn configure(app: &mut App) { + app.register_type::(); + app.add_systems(Update, update_shield.in_set(UpdateSet::SyncLate)); + } +} + +fn update_shield( + mut shield_query: Query<(&mut Visibility, &Parent), With>, + immune_query: Query<(), With>, +) { + for (mut visibility, parent) in &mut shield_query { + *visibility = if immune_query.contains(parent.get()) { + Visibility::Inherited + } else { + Visibility::Hidden + }; + } +} diff --git a/src/game/combat/hit.rs b/src/game/combat/hit.rs index 380eca8..18cdd6b 100644 --- a/src/game/combat/hit.rs +++ b/src/game/combat/hit.rs @@ -8,7 +8,7 @@ use crate::game::cleanup::RemoveOnTimer; use crate::util::prelude::*; pub(super) fn plugin(app: &mut App) { - app.configure::<(Hitbox, Hurtbox, OnHit, HurtSfx, Immune)>(); + app.configure::<(Hitbox, Hurtbox, Immune, OnHit, HurtSfx)>(); } #[derive(Component, Reflect)] @@ -23,21 +23,21 @@ impl Configure for Hitbox { #[derive(Component, Reflect)] #[reflect(Component)] -pub struct Immune; +pub struct Hurtbox; -impl Configure for Immune { +impl Configure for Hurtbox { fn configure(app: &mut App) { - app.configure::>(); app.register_type::(); } } #[derive(Component, Reflect)] #[reflect(Component)] -pub struct Hurtbox; +pub struct Immune; -impl Configure for Hurtbox { +impl Configure for Immune { fn configure(app: &mut App) { + app.configure::>(); app.register_type::(); } }