2021-01-18 22:58:56 +00:00
|
|
|
use crate::{
|
2021-03-01 20:44:29 +00:00
|
|
|
combat::GroupTarget,
|
2021-01-18 22:58:56 +00:00
|
|
|
comp::buff::{BuffCategory, BuffData, BuffKind, BuffSource},
|
|
|
|
uid::Uid,
|
|
|
|
};
|
2020-12-04 22:24:56 +00:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use slotmap::{new_key_type, SlotMap};
|
2021-01-07 20:25:12 +00:00
|
|
|
use specs::{Component, DerefFlaggedStorage};
|
2020-12-04 22:24:56 +00:00
|
|
|
use specs_idvs::IdvStorage;
|
|
|
|
use std::time::Duration;
|
|
|
|
|
|
|
|
new_key_type! { pub struct AuraKey; }
|
|
|
|
|
|
|
|
/// AuraKind is what kind of effect an aura applies
|
|
|
|
/// Currently only buffs are implemented
|
|
|
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
|
|
|
pub enum AuraKind {
|
|
|
|
/// The Buff kind is (surprise!) a buff :D
|
|
|
|
Buff {
|
|
|
|
kind: BuffKind,
|
|
|
|
data: BuffData,
|
|
|
|
category: BuffCategory,
|
|
|
|
source: BuffSource,
|
|
|
|
},
|
|
|
|
/* TODO: Implement other effects here. Things to think about
|
|
|
|
* are terrain/sprite effects, collision and physics, and
|
|
|
|
* environmental conditions like temperature and humidity
|
|
|
|
* Multiple auras can be given to an entity. */
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Aura
|
|
|
|
/// Applies a buff to entities in the radius if meeting
|
|
|
|
/// conditions set forth in the aura system.
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
|
|
pub struct Aura {
|
|
|
|
/// The kind of aura applied
|
|
|
|
pub aura_kind: AuraKind,
|
|
|
|
/// The radius of the aura
|
|
|
|
pub radius: f32,
|
|
|
|
/// How long the aura lasts. None corresponds to an indefinite length
|
|
|
|
pub duration: Option<Duration>,
|
2021-01-18 22:58:56 +00:00
|
|
|
/* TODO: Add functionality for fading or a gradient */
|
|
|
|
/// Used to filter which entities this aura will apply to. For example,
|
|
|
|
/// globally neutral auras which affect all entities will have the type
|
|
|
|
/// `AuraTarget::All`. Whereas auras which only affect a player's party
|
|
|
|
/// members will have the type `AuraTarget::GroupOf`.
|
|
|
|
pub target: AuraTarget,
|
2020-12-04 22:24:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Information about whether aura addition or removal was requested.
|
|
|
|
/// This to implement "on_add" and "on_remove" hooks for auras
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub enum AuraChange {
|
|
|
|
/// Adds this aura
|
|
|
|
Add(Aura),
|
|
|
|
/// Removes auras of these indices
|
|
|
|
RemoveByKey(Vec<AuraKey>),
|
|
|
|
}
|
|
|
|
|
2021-01-18 22:58:56 +00:00
|
|
|
/// Used by the aura system to filter entities when applying an effect.
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
|
|
pub enum AuraTarget {
|
|
|
|
/// Targets the group of the entity specified by the `Uid`. This is useful
|
|
|
|
/// for auras which should only affect a player's party.
|
|
|
|
GroupOf(Uid),
|
2021-03-01 20:44:29 +00:00
|
|
|
/// Targets everyone not in the group of the entity specified by the `Uid`.
|
|
|
|
/// This is useful for auras which should only affect a player's
|
|
|
|
/// enemies.
|
|
|
|
NotGroupOf(Uid),
|
2021-01-18 22:58:56 +00:00
|
|
|
/// Targets all entities. This is for auras which are global or neutral.
|
|
|
|
All,
|
|
|
|
}
|
|
|
|
|
2021-07-10 07:10:31 +00:00
|
|
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)]
|
2021-07-11 04:39:11 +00:00
|
|
|
pub enum Specifier {
|
2021-07-10 07:10:31 +00:00
|
|
|
WardingAura,
|
|
|
|
HealingAura,
|
|
|
|
}
|
|
|
|
|
2021-03-01 20:44:29 +00:00
|
|
|
impl From<(Option<GroupTarget>, Option<&Uid>)> for AuraTarget {
|
|
|
|
fn from((target, uid): (Option<GroupTarget>, Option<&Uid>)) -> Self {
|
|
|
|
match (target, uid) {
|
|
|
|
(Some(GroupTarget::InGroup), Some(uid)) => Self::GroupOf(*uid),
|
|
|
|
(Some(GroupTarget::OutOfGroup), Some(uid)) => Self::NotGroupOf(*uid),
|
|
|
|
_ => Self::All,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-04 22:24:56 +00:00
|
|
|
impl Aura {
|
|
|
|
/// Creates a new Aura to be assigned to an entity
|
2021-01-18 22:58:56 +00:00
|
|
|
pub fn new(
|
|
|
|
aura_kind: AuraKind,
|
|
|
|
radius: f32,
|
|
|
|
duration: Option<Duration>,
|
|
|
|
target: AuraTarget,
|
|
|
|
) -> Self {
|
2020-12-04 22:24:56 +00:00
|
|
|
Self {
|
|
|
|
aura_kind,
|
|
|
|
radius,
|
|
|
|
duration,
|
2021-01-18 22:58:56 +00:00
|
|
|
target,
|
2020-12-04 22:24:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Component holding all auras emitted by an entity.
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize, Default)]
|
|
|
|
pub struct Auras {
|
|
|
|
pub auras: SlotMap<AuraKey, Aura>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Auras {
|
2021-02-28 20:02:03 +00:00
|
|
|
pub fn new(auras: Vec<Aura>) -> Self {
|
|
|
|
let mut auras_comp: SlotMap<AuraKey, Aura> = SlotMap::with_key();
|
|
|
|
for aura in auras {
|
|
|
|
auras_comp.insert(aura);
|
|
|
|
}
|
|
|
|
Self { auras: auras_comp }
|
2020-12-04 22:24:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn insert(&mut self, aura: Aura) { self.auras.insert(aura); }
|
|
|
|
|
|
|
|
pub fn remove(&mut self, key: AuraKey) { self.auras.remove(key); }
|
|
|
|
}
|
|
|
|
|
2021-03-01 20:44:29 +00:00
|
|
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)]
|
|
|
|
pub struct AuraBuffConstructor {
|
|
|
|
pub kind: BuffKind,
|
|
|
|
pub strength: f32,
|
|
|
|
pub duration: Option<f32>,
|
|
|
|
pub category: BuffCategory,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl AuraBuffConstructor {
|
|
|
|
pub fn to_aura(
|
|
|
|
self,
|
|
|
|
uid: &Uid,
|
|
|
|
radius: f32,
|
|
|
|
duration: Option<Duration>,
|
|
|
|
target: AuraTarget,
|
|
|
|
) -> Aura {
|
|
|
|
let aura_kind = AuraKind::Buff {
|
|
|
|
kind: self.kind,
|
|
|
|
data: BuffData {
|
|
|
|
strength: self.strength,
|
|
|
|
duration: self.duration.map(Duration::from_secs_f32),
|
|
|
|
},
|
|
|
|
category: self.category,
|
|
|
|
source: BuffSource::Character { by: *uid },
|
|
|
|
};
|
|
|
|
Aura::new(aura_kind, radius, duration, target)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-04 22:24:56 +00:00
|
|
|
impl Component for Auras {
|
2021-01-07 20:25:12 +00:00
|
|
|
type Storage = DerefFlaggedStorage<Self, IdvStorage<Self>>;
|
2020-12-04 22:24:56 +00:00
|
|
|
}
|