mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Don't forget about pets in PvP checks
This commit is contained in:
parent
0dcfe2721b
commit
6b0d016418
@ -469,11 +469,10 @@ impl Attack {
|
||||
}
|
||||
}
|
||||
|
||||
/// Checks if we should allow negative effects from one player to another
|
||||
// FIXME: handle pets?
|
||||
// This code works only with players.
|
||||
// You still can kill someone's pet and
|
||||
// you still can be killed by someone's pet
|
||||
/// Says if we should allow negative effects from one player to another
|
||||
///
|
||||
/// NOTE: this function doesn't handle pets or friendly-fire, you will need to
|
||||
/// figure it out on call-side.
|
||||
pub fn may_harm(attacker: Option<&Player>, target: Option<&Player>) -> bool {
|
||||
attacker
|
||||
.zip(target)
|
||||
|
@ -3,10 +3,10 @@ use crate::{
|
||||
path::Chaser,
|
||||
rtsim::RtSimController,
|
||||
trade::{PendingTrade, ReducedInventory, SiteId, SitePrices, TradeId, TradeResult},
|
||||
uid::Uid,
|
||||
uid::{Uid, UidAllocator},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use specs::{Component, Entity as EcsEntity};
|
||||
use specs::{saveload::MarkerAllocator, Component, Entity as EcsEntity};
|
||||
use specs_idvs::IdvStorage;
|
||||
use std::{collections::VecDeque, fmt};
|
||||
use strum::IntoEnumIterator;
|
||||
@ -34,6 +34,15 @@ pub enum Alignment {
|
||||
Passive,
|
||||
}
|
||||
|
||||
// Helper function to get owner
|
||||
pub fn owner_of(alignment: Option<Alignment>, uid_allocator: &UidAllocator) -> Option<EcsEntity> {
|
||||
if let Some(Alignment::Owned(uid)) = alignment {
|
||||
uid_allocator.retrieve_entity_internal(uid.into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum Mark {
|
||||
Merchant,
|
||||
|
@ -1,10 +1,11 @@
|
||||
use common::{
|
||||
combat,
|
||||
comp::{
|
||||
agent::owner_of,
|
||||
aura::{AuraChange, AuraKey, AuraKind, AuraTarget},
|
||||
buff::{Buff, BuffCategory, BuffChange, BuffSource},
|
||||
group::Group,
|
||||
Aura, Auras, BuffKind, Buffs, CharacterState, Health, Player, Pos,
|
||||
Alignment, Aura, Auras, BuffKind, Buffs, CharacterState, Health, Player, Pos,
|
||||
},
|
||||
event::{Emitter, EventBus, ServerEvent},
|
||||
resources::DeltaTime,
|
||||
@ -27,6 +28,7 @@ pub struct ReadData<'a> {
|
||||
cached_spatial_grid: Read<'a, common::CachedSpatialGrid>,
|
||||
positions: ReadStorage<'a, Pos>,
|
||||
char_states: ReadStorage<'a, CharacterState>,
|
||||
alignments: ReadStorage<'a, Alignment>,
|
||||
healths: ReadStorage<'a, Health>,
|
||||
groups: ReadStorage<'a, Group>,
|
||||
uids: ReadStorage<'a, Uid>,
|
||||
@ -174,7 +176,7 @@ fn activate_aura(
|
||||
// TODO: this check will disable friendly fire with PvE switch.
|
||||
//
|
||||
// Which means that you can't apply debuffs on you and your group
|
||||
// even if it's intented mechanics.
|
||||
// even if it's intented mechanic.
|
||||
//
|
||||
// Not that we have this for now, but think about this
|
||||
// when we will add this.
|
||||
@ -185,11 +187,19 @@ fn activate_aura(
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
owner.map_or(true, |attacker| {
|
||||
let attacker = read_data.players.get(attacker);
|
||||
let target = read_data.players.get(target);
|
||||
combat::may_harm(attacker, target)
|
||||
})
|
||||
let owner_if_pet = |entity| {
|
||||
// Return owner entity if pet,
|
||||
// or just return entity back otherwise
|
||||
owner_of(
|
||||
read_data.alignments.get(entity).copied(),
|
||||
&read_data.uid_allocator,
|
||||
)
|
||||
.unwrap_or(entity)
|
||||
};
|
||||
combat::may_harm(
|
||||
owner.and_then(|owner| read_data.players.get(owner_if_pet(owner))),
|
||||
read_data.players.get(owner_if_pet(target)),
|
||||
)
|
||||
};
|
||||
|
||||
conditions_held && (kind.is_buff() || may_harm())
|
||||
|
@ -1,9 +1,9 @@
|
||||
use common::{
|
||||
combat::{self, AttackOptions, AttackSource, AttackerInfo, TargetInfo},
|
||||
comp::{
|
||||
agent::{Sound, SoundKind},
|
||||
Beam, BeamSegment, Body, CharacterState, Combo, Energy, Group, Health, HealthSource,
|
||||
Inventory, Ori, Player, Pos, Scale, Stats,
|
||||
agent::{owner_of, Sound, SoundKind},
|
||||
Alignment, Beam, BeamSegment, Body, CharacterState, Combo, Energy, Group, Health,
|
||||
HealthSource, Inventory, Ori, Player, Pos, Scale, Stats,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
outcome::Outcome,
|
||||
@ -36,6 +36,7 @@ pub struct ReadData<'a> {
|
||||
uids: ReadStorage<'a, Uid>,
|
||||
positions: ReadStorage<'a, Pos>,
|
||||
orientations: ReadStorage<'a, Ori>,
|
||||
alignments: ReadStorage<'a, Alignment>,
|
||||
scales: ReadStorage<'a, Scale>,
|
||||
bodies: ReadStorage<'a, Body>,
|
||||
healths: ReadStorage<'a, Health>,
|
||||
@ -214,9 +215,19 @@ impl<'a> System<'a> for Sys {
|
||||
};
|
||||
|
||||
|
||||
// PvP check
|
||||
let owner_if_pet = |entity| {
|
||||
// Return owner entity if pet,
|
||||
// or just return entity back otherwise
|
||||
owner_of(
|
||||
read_data.alignments.get(entity).copied(),
|
||||
&read_data.uid_allocator,
|
||||
)
|
||||
.unwrap_or(entity)
|
||||
};
|
||||
let may_harm = combat::may_harm(
|
||||
beam_owner.and_then(|owner| read_data.players.get(owner)),
|
||||
read_data.players.get(target),
|
||||
beam_owner.and_then(|owner| read_data.players.get(owner_if_pet(owner))),
|
||||
read_data.players.get(owner_if_pet(target)),
|
||||
);
|
||||
let attack_options = AttackOptions {
|
||||
// No luck with dodging beams
|
||||
|
@ -1,14 +1,14 @@
|
||||
use common::{
|
||||
combat::{self, AttackOptions, AttackSource, AttackerInfo, TargetInfo},
|
||||
comp::{
|
||||
agent::{Sound, SoundKind},
|
||||
Body, CharacterState, Combo, Energy, Group, Health, Inventory, Melee, Ori, Player, Pos,
|
||||
Scale, Stats,
|
||||
agent::{owner_of, Sound, SoundKind},
|
||||
Alignment, Body, CharacterState, Combo, Energy, Group, Health, Inventory, Melee, Ori,
|
||||
Player, Pos, Scale, Stats,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
outcome::Outcome,
|
||||
resources::Time,
|
||||
uid::Uid,
|
||||
uid::{Uid, UidAllocator},
|
||||
util::Dir,
|
||||
GroupTarget,
|
||||
};
|
||||
@ -21,11 +21,13 @@ use vek::*;
|
||||
#[derive(SystemData)]
|
||||
pub struct ReadData<'a> {
|
||||
time: Read<'a, Time>,
|
||||
uid_allocator: Read<'a, UidAllocator>,
|
||||
entities: Entities<'a>,
|
||||
players: ReadStorage<'a, Player>,
|
||||
uids: ReadStorage<'a, Uid>,
|
||||
positions: ReadStorage<'a, Pos>,
|
||||
orientations: ReadStorage<'a, Ori>,
|
||||
alignments: ReadStorage<'a, Alignment>,
|
||||
scales: ReadStorage<'a, Scale>,
|
||||
bodies: ReadStorage<'a, Body>,
|
||||
healths: ReadStorage<'a, Health>,
|
||||
@ -162,9 +164,19 @@ impl<'a> System<'a> for Sys {
|
||||
char_state: read_data.char_states.get(target),
|
||||
};
|
||||
|
||||
// PvP check
|
||||
let owner_if_pet = |entity| {
|
||||
// Return owner entity if pet,
|
||||
// or just return entity back otherwise
|
||||
owner_of(
|
||||
read_data.alignments.get(entity).copied(),
|
||||
&read_data.uid_allocator,
|
||||
)
|
||||
.unwrap_or(entity)
|
||||
};
|
||||
let may_harm = combat::may_harm(
|
||||
read_data.players.get(attacker),
|
||||
read_data.players.get(target),
|
||||
read_data.players.get(owner_if_pet(attacker)),
|
||||
read_data.players.get(owner_if_pet(target)),
|
||||
);
|
||||
|
||||
let attack_options = AttackOptions {
|
||||
|
@ -1,9 +1,9 @@
|
||||
use common::{
|
||||
combat::{self, AttackOptions, AttackSource, AttackerInfo, TargetInfo},
|
||||
comp::{
|
||||
agent::{Sound, SoundKind},
|
||||
projectile, Body, CharacterState, Combo, Energy, Group, Health, HealthSource, Inventory,
|
||||
Ori, PhysicsState, Player, Pos, Projectile, Stats, Vel,
|
||||
agent::{owner_of, Sound, SoundKind},
|
||||
projectile, Alignment, Body, CharacterState, Combo, Energy, Group, Health, HealthSource,
|
||||
Inventory, Ori, PhysicsState, Player, Pos, Projectile, Stats, Vel,
|
||||
},
|
||||
event::{Emitter, EventBus, ServerEvent},
|
||||
outcome::Outcome,
|
||||
@ -31,6 +31,7 @@ pub struct ReadData<'a> {
|
||||
server_bus: Read<'a, EventBus<ServerEvent>>,
|
||||
uids: ReadStorage<'a, Uid>,
|
||||
positions: ReadStorage<'a, Pos>,
|
||||
alignments: ReadStorage<'a, Alignment>,
|
||||
physics_states: ReadStorage<'a, PhysicsState>,
|
||||
velocities: ReadStorage<'a, Vel>,
|
||||
inventories: ReadStorage<'a, Inventory>,
|
||||
@ -299,9 +300,19 @@ fn dispatch_hit(
|
||||
});
|
||||
}
|
||||
|
||||
// PvP check
|
||||
let owner_if_pet = |entity| {
|
||||
// Return owner entity if pet,
|
||||
// or just return entity back otherwise
|
||||
owner_of(
|
||||
read_data.alignments.get(entity).copied(),
|
||||
&read_data.uid_allocator,
|
||||
)
|
||||
.unwrap_or(entity)
|
||||
};
|
||||
let may_harm = combat::may_harm(
|
||||
owner.and_then(|owner| read_data.players.get(owner)),
|
||||
read_data.players.get(target),
|
||||
owner.and_then(|owner| read_data.players.get(owner_if_pet(owner))),
|
||||
read_data.players.get(owner_if_pet(target)),
|
||||
);
|
||||
|
||||
let attack_options = AttackOptions {
|
||||
|
@ -1,9 +1,9 @@
|
||||
use common::{
|
||||
combat::{self, AttackOptions, AttackSource, AttackerInfo, TargetInfo},
|
||||
comp::{
|
||||
agent::{Sound, SoundKind},
|
||||
Body, CharacterState, Combo, Energy, Group, Health, HealthSource, Inventory, Ori,
|
||||
PhysicsState, Player, Pos, Scale, Shockwave, ShockwaveHitEntities, Stats,
|
||||
agent::{owner_of, Sound, SoundKind},
|
||||
Alignment, Body, CharacterState, Combo, Energy, Group, Health, HealthSource, Inventory,
|
||||
Ori, PhysicsState, Player, Pos, Scale, Shockwave, ShockwaveHitEntities, Stats,
|
||||
},
|
||||
event::{EventBus, ServerEvent},
|
||||
outcome::Outcome,
|
||||
@ -31,6 +31,7 @@ pub struct ReadData<'a> {
|
||||
uids: ReadStorage<'a, Uid>,
|
||||
positions: ReadStorage<'a, Pos>,
|
||||
orientations: ReadStorage<'a, Ori>,
|
||||
alignments: ReadStorage<'a, Alignment>,
|
||||
scales: ReadStorage<'a, Scale>,
|
||||
bodies: ReadStorage<'a, Body>,
|
||||
healths: ReadStorage<'a, Health>,
|
||||
@ -209,9 +210,20 @@ impl<'a> System<'a> for Sys {
|
||||
char_state: read_data.character_states.get(target),
|
||||
};
|
||||
|
||||
// PvP check
|
||||
let owner_if_pet = |entity| {
|
||||
// Return owner entity if pet,
|
||||
// or just return entity back otherwise
|
||||
owner_of(
|
||||
read_data.alignments.get(entity).copied(),
|
||||
&read_data.uid_allocator,
|
||||
)
|
||||
.unwrap_or(entity)
|
||||
};
|
||||
let may_harm = combat::may_harm(
|
||||
shockwave_owner.and_then(|owner| read_data.players.get(owner)),
|
||||
read_data.players.get(target),
|
||||
shockwave_owner
|
||||
.and_then(|owner| read_data.players.get(owner_if_pet(owner))),
|
||||
read_data.players.get(owner_if_pet(target)),
|
||||
);
|
||||
let attack_options = AttackOptions {
|
||||
// Trying roll during earthquake isn't the best idea
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
client::Client,
|
||||
comp::{
|
||||
agent::{Agent, AgentEvent, Sound, SoundKind},
|
||||
agent::{owner_of, Agent, AgentEvent, Sound, SoundKind},
|
||||
biped_large, bird_large, quadruped_low, quadruped_medium, quadruped_small,
|
||||
skills::SkillGroupKind,
|
||||
theropod, BuffKind, BuffSource, PhysicsState,
|
||||
@ -873,6 +873,8 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
|
||||
let energies = &ecs.read_storage::<comp::Energy>();
|
||||
let combos = &ecs.read_storage::<comp::Combo>();
|
||||
let inventories = &ecs.read_storage::<comp::Inventory>();
|
||||
let alignments = &ecs.read_storage::<Alignment>();
|
||||
let uid_allocator = &ecs.read_resource::<UidAllocator>();
|
||||
let players = &ecs.read_storage::<comp::Player>();
|
||||
for (
|
||||
entity_b,
|
||||
@ -942,9 +944,16 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
|
||||
char_state: char_state_b_maybe,
|
||||
};
|
||||
|
||||
// PvP check
|
||||
let owner_if_pet = |entity| {
|
||||
// Return owner entity if pet,
|
||||
// or just return entity back otherwise
|
||||
owner_of(alignments.get(entity).copied(), uid_allocator)
|
||||
.unwrap_or(entity)
|
||||
};
|
||||
let may_harm = combat::may_harm(
|
||||
owner_entity.and_then(|owner| players.get(owner)),
|
||||
players.get(entity_b),
|
||||
owner_entity.and_then(|owner| players.get(owner_if_pet(owner))),
|
||||
players.get(owner_if_pet(entity_b)),
|
||||
);
|
||||
let attack_options = combat::AttackOptions {
|
||||
// cool guyz maybe don't look at explosions
|
||||
@ -968,6 +977,8 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
|
||||
}
|
||||
},
|
||||
RadiusEffect::Entity(mut effect) => {
|
||||
let alignments = &ecs.read_storage::<Alignment>();
|
||||
let uid_allocator = &ecs.read_resource::<UidAllocator>();
|
||||
let players = &ecs.read_storage::<comp::Player>();
|
||||
for (entity_b, pos_b, body_b_maybe) in (
|
||||
&ecs.entities(),
|
||||
@ -994,12 +1005,17 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
|
||||
// you want to harm yourself.
|
||||
//
|
||||
// This can be changed later.
|
||||
// PvP check
|
||||
let owner_if_pet = |entity| {
|
||||
// Return owner entity if pet,
|
||||
// or just return entity back otherwise
|
||||
owner_of(alignments.get(entity).copied(), uid_allocator).unwrap_or(entity)
|
||||
};
|
||||
let may_harm = || {
|
||||
owner_entity.map_or(false, |attacker| {
|
||||
let attacker_player = players.get(attacker);
|
||||
let target_player = players.get(entity_b);
|
||||
combat::may_harm(attacker_player, target_player) || attacker == entity_b
|
||||
})
|
||||
combat::may_harm(
|
||||
owner_entity.and_then(|owner| players.get(owner_if_pet(owner))),
|
||||
players.get(owner_if_pet(entity_b)),
|
||||
) || owner_entity.map_or(true, |entity_a| entity_a == entity_b)
|
||||
};
|
||||
if strength > 0.0 {
|
||||
let is_alive = ecs
|
||||
|
Loading…
Reference in New Issue
Block a user