aboutsummaryrefslogtreecommitdiffstats
path: root/src/shared/area_of_effect.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/area_of_effect.rs')
-rw-r--r--src/shared/area_of_effect.rs64
1 files changed, 64 insertions, 0 deletions
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);
+ },
+ )
+ })
+ },
+ ),
+ }
+ }
+}