From 2d21d709901c96b05d7f0169dd9d1207436c658c Mon Sep 17 00:00:00 2001 From: Alexander Foremny Date: Tue, 19 Mar 2024 14:13:16 +0100 Subject: feat: area of effect --- src/shared/ability.rs | 12 ++++++++- src/shared/area_of_effect.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/shared/area_of_effect.rs (limited to 'src/shared') diff --git a/src/shared/ability.rs b/src/shared/ability.rs index 80c74b2..2cd44c4 100644 --- a/src/shared/ability.rs +++ b/src/shared/ability.rs @@ -1,4 +1,5 @@ use crate::server::entity_map::*; +use crate::shared::area_of_effect::*; use crate::shared::buffs::*; use crate::shared::player::*; use crate::shared::projectile::*; @@ -220,7 +221,8 @@ fn dash_activation(dash: Dash) -> DirectionalAbilityActivation { mut set: ParamSet<( Query<&mut PlayerPosition>, Query<(&PlayerId, &PlayerPosition)>, - )>| { + )>, + mut commands: Commands| { let Some(source_entity) = ({ let mut source_entity = None; for (entity, player_id) in players.iter() { @@ -261,6 +263,14 @@ fn dash_activation(dash: Dash) -> DirectionalAbilityActivation { if let Ok(mut position) = positions.get_mut(source_entity) { position.0 = dash_end; } + + commands.spawn(AreaOfEffectBundle::new(AreaOfEffect { + position: dash_end, + radius: 1.5 * PLAYER_RADIUS, + duration: None, + source_player, + area_of_effect_type: AreaOfEffectType::Slow, + })); }, ) }); diff --git a/src/shared/area_of_effect.rs b/src/shared/area_of_effect.rs new file mode 100644 index 0000000..dcdc86c --- /dev/null +++ b/src/shared/area_of_effect.rs @@ -0,0 +1,64 @@ +use crate::server::entity_map::*; +use crate::shared::buffs::*; +use crate::shared::player::*; +use crate::shared::*; +use bevy::ecs::system::*; + +#[derive(Bundle)] +pub struct AreaOfEffectBundle { + area_of_effect: AreaOfEffect, + replicate: Replicate, +} + +impl AreaOfEffectBundle { + pub fn new(area_of_effect: AreaOfEffect) -> Self { + AreaOfEffectBundle { + area_of_effect, + replicate: Replicate::default(), + } + } +} + +#[derive(Component, Message, Serialize, Deserialize, Clone, PartialEq, Debug)] +pub struct AreaOfEffect { + pub position: Vec2, + pub radius: f32, + // `duration = None` means `AreaOfEffect` exists only for a single server tick + pub duration: Option, + pub source_player: PlayerId, + pub area_of_effect_type: AreaOfEffectType, +} + +#[derive(Component, Message, Serialize, Deserialize, Clone, PartialEq, Debug)] +pub enum AreaOfEffectType { + Slow, +} + +pub type AreaOfEffectActivation = Box ()>; + +impl AreaOfEffect { + pub fn activate(&self) -> AreaOfEffectActivation { + match self.area_of_effect_type { + AreaOfEffectType::Slow => Box::new( + move |commands: &mut Commands, + _source_player_id: PlayerId, + target_player_id: PlayerId| { + commands.add(move |world: &mut World| { + world.run_system_once( + move |entity_map: Res, mut buffs: Query<&mut Buffs>| { + let Some(target_entity) = entity_map.0.get(&target_player_id.0) + else { + return; + }; + let Ok(mut buffs) = buffs.get_mut(*target_entity) else { + return; + }; + buffs.slow = Some(0.75); + }, + ) + }) + }, + ), + } + } +} -- cgit v1.2.3