Merge branch 'friendly-auras' into 'master'

Set up aura filtering

Closes #890

See merge request veloren/veloren!1698
This commit is contained in:
Samuel Keiffer 2021-01-18 22:58:56 +00:00
commit 1312dc9252
4 changed files with 65 additions and 10 deletions

View File

@ -1,4 +1,7 @@
use crate::comp::buff::{BuffCategory, BuffData, BuffKind, BuffSource};
use crate::{
comp::buff::{BuffCategory, BuffData, BuffKind, BuffSource},
uid::Uid,
};
use serde::{Deserialize, Serialize};
use slotmap::{new_key_type, SlotMap};
use specs::{Component, DerefFlaggedStorage};
@ -35,8 +38,12 @@ pub struct Aura {
pub radius: f32,
/// How long the aura lasts. None corresponds to an indefinite length
pub duration: Option<Duration>,
/* TODO: Add functionality for fading or a gradient
* TODO: Make alignment specific auras work */
/* 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,
}
/// Information about whether aura addition or removal was requested.
@ -49,13 +56,30 @@ pub enum AuraChange {
RemoveByKey(Vec<AuraKey>),
}
/// 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),
/// Targets all entities. This is for auras which are global or neutral.
All,
}
impl Aura {
/// Creates a new Aura to be assigned to an entity
pub fn new(aura_kind: AuraKind, radius: f32, duration: Option<Duration>) -> Self {
pub fn new(
aura_kind: AuraKind,
radius: f32,
duration: Option<Duration>,
target: AuraTarget,
) -> Self {
Self {
aura_kind,
radius,
duration,
target,
}
}
}

View File

@ -1,12 +1,15 @@
use common::{
comp::{
aura::AuraKey, buff, AuraChange, AuraKind, Auras, BuffKind, Buffs, CharacterState, Health,
Pos,
aura::{AuraChange, AuraKey, AuraKind, AuraTarget},
buff,
group::Group,
Auras, BuffKind, Buffs, CharacterState, Health, Pos,
},
event::{EventBus, ServerEvent},
resources::DeltaTime,
uid::UidAllocator,
};
use specs::{Entities, Join, Read, ReadStorage, System, WriteStorage};
use specs::{saveload::MarkerAllocator, Entities, Join, Read, ReadStorage, System, WriteStorage};
use std::time::Duration;
pub struct Sys;
@ -21,11 +24,24 @@ impl<'a> System<'a> for Sys {
WriteStorage<'a, Auras>,
WriteStorage<'a, Buffs>,
ReadStorage<'a, Health>,
ReadStorage<'a, Group>,
Read<'a, UidAllocator>,
);
fn run(
&mut self,
(entities, dt, positions, server_bus, character_states, mut auras, mut buffs, health): Self::SystemData,
(
entities,
dt,
positions,
server_bus,
character_states,
mut auras,
mut buffs,
health,
groups,
uid_allocator,
): Self::SystemData,
) {
let mut server_emitter = server_bus.emitter();
@ -64,6 +80,19 @@ impl<'a> System<'a> for Sys {
{
// Ensure entity is within the aura radius
if target_pos.0.distance_squared(pos.0) < aura.radius.powi(2) {
if let AuraTarget::GroupOf(uid) = aura.target {
let same_group = uid_allocator
.retrieve_entity_internal(uid.into())
.and_then(|e| groups.get(e))
.map_or(false, |owner_group| {
Some(owner_group) == groups.get(target_entity)
});
if !same_group {
continue;
}
}
// TODO: When more aura kinds (besides Buff) are
// implemented, match on them here
match aura.aura_kind {

View File

@ -11,7 +11,7 @@ use common::{
cmd::{ChatCommand, CHAT_COMMANDS, CHAT_SHORTCUTS},
comp::{
self,
aura::{Aura, AuraKind},
aura::{Aura, AuraKind, AuraTarget},
buff::{BuffCategory, BuffData, BuffKind, BuffSource},
ChatType, Inventory, Item, LightEmitter, WaypointArea,
},
@ -981,6 +981,7 @@ fn handle_spawn_campfire(
},
5.0,
None,
AuraTarget::All,
)))
.build();

View File

@ -3,7 +3,7 @@ use common::{
character::CharacterId,
comp::{
self,
aura::{Aura, AuraKind},
aura::{Aura, AuraKind, AuraTarget},
beam,
buff::{BuffCategory, BuffData, BuffKind, BuffSource},
group,
@ -195,6 +195,7 @@ pub fn handle_create_waypoint(server: &mut Server, pos: Vec3<f32>) {
},
5.0,
None,
AuraTarget::All,
)))
.build();
}