1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
use crate::protocol::*;
use crate::server::entity_map::*;
use crate::shared::buffs::*;
use crate::shared::player::*;
use bevy::ecs::system::*;
use bevy::prelude::*;
use lightyear::prelude::*;
use serde::*;
#[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);
},
)
})
},
),
}
}
}
|