aboutsummaryrefslogtreecommitdiffstats
path: root/src/shared
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared')
-rw-r--r--src/shared/ability.rs12
-rw-r--r--src/shared/area_of_effect.rs64
2 files changed, 75 insertions, 1 deletions
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<f32>,
+ 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<dyn FnOnce(&mut Commands, PlayerId, PlayerId) -> ()>;
+
+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<EntityMap>, 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);
+ },
+ )
+ })
+ },
+ ),
+ }
+ }
+}