mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Merge branch 'friendly-auras' into 'master'
Set up aura filtering Closes #890 See merge request veloren/veloren!1698
This commit is contained in:
commit
1312dc9252
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user