From 497a94cd7a4161401f599442b4c100afb0c9f876 Mon Sep 17 00:00:00 2001 From: juliancoffee Date: Fri, 30 Jul 2021 14:34:05 +0300 Subject: [PATCH] Post review refactoring * inline `target_dodging` into struct declaration as they are named anyway * move `avoid_harm` check out of `Attack::apply_attack` so we don't need to pass whole Player component. * another cosmetic things --- common/src/combat.rs | 9 +++------ common/src/comp/player.rs | 11 +++++++---- common/systems/src/aura.rs | 2 +- common/systems/src/beam.rs | 14 ++++++++------ common/systems/src/melee.rs | 10 +++++++--- common/systems/src/projectile.rs | 19 +++++++++++-------- common/systems/src/shockwave.rs | 15 ++++++++------- server/src/events/entity_manipulation.rs | 21 +++++++++++++-------- server/src/sys/msg/register.rs | 6 +++--- 9 files changed, 61 insertions(+), 46 deletions(-) diff --git a/common/src/combat.rs b/common/src/combat.rs index 237ddf46a4..a3a66c81be 100644 --- a/common/src/combat.rs +++ b/common/src/combat.rs @@ -53,7 +53,6 @@ pub enum AttackSource { #[derive(Copy, Clone)] pub struct AttackerInfo<'a> { pub entity: EcsEntity, - pub player: Option<&'a Player>, pub uid: Uid, pub energy: Option<&'a Energy>, pub combo: Option<&'a Combo>, @@ -63,7 +62,6 @@ pub struct AttackerInfo<'a> { #[cfg(not(target_arch = "wasm32"))] pub struct TargetInfo<'a> { pub entity: EcsEntity, - pub player: Option<&'a Player>, pub uid: Uid, pub inventory: Option<&'a Inventory>, pub stats: Option<&'a Stats>, @@ -76,6 +74,7 @@ pub struct TargetInfo<'a> { #[derive(Clone, Copy)] pub struct AttackOptions { pub target_dodging: bool, + pub avoid_harm: bool, pub target_group: GroupTarget, } @@ -182,12 +181,10 @@ impl Attack { ) -> bool { let AttackOptions { target_dodging, + avoid_harm, target_group, } = options; - let avoid_harm = - attacker.map_or(false, |attacker| avoid_harm(attacker.player, target.player)); - // target == OutOfGroup is basic heuristic that this // "attack" has negative effects. // @@ -464,7 +461,7 @@ impl Attack { // This code works only with players. // You still can kill someone's pet and // you still can be killed by someone's pet -pub fn avoid_harm(attacker: Option<&Player>, target: Option<&Player>) -> bool { +pub fn avoid_player_harm(attacker: Option<&Player>, target: Option<&Player>) -> bool { if let (Some(attacker), Some(target)) = (attacker, target) { return attacker.disallow_harm(target); } diff --git a/common/src/comp/player.rs b/common/src/comp/player.rs index f3ab03a081..c2666ef11c 100644 --- a/common/src/comp/player.rs +++ b/common/src/comp/player.rs @@ -23,6 +23,12 @@ pub struct Player { uuid: Uuid, } +impl BattleMode { + pub fn allow_harm(self, other: Self) -> bool { + matches!((self, other), (BattleMode::PvP, BattleMode::PvP)) + } +} + impl Player { pub fn new(alias: String, battle_mode: BattleMode, uuid: Uuid) -> Self { Self { @@ -38,10 +44,7 @@ impl Player { /// tea. pub fn allow_harm(&self, other: &Player) -> bool { // TODO: discuss if we want to keep self-harm - matches!( - (self.battle_mode, other.battle_mode), - (BattleMode::PvP, BattleMode::PvP) - ) + self.battle_mode.allow_harm(other.battle_mode) } /// Inverse of `allow_harm`. Read its doc to learn more. diff --git a/common/systems/src/aura.rs b/common/systems/src/aura.rs index 96638d4067..1d9f2cb3a0 100644 --- a/common/systems/src/aura.rs +++ b/common/systems/src/aura.rs @@ -180,7 +180,7 @@ fn activate_aura( owner.map_or(false, |attacker| { let attacker = read_data.players.get(attacker); let target = read_data.players.get(target); - combat::avoid_harm(attacker, target) + combat::avoid_player_harm(attacker, target) }) }; diff --git a/common/systems/src/beam.rs b/common/systems/src/beam.rs index b22bca06f8..959c61cd7f 100644 --- a/common/systems/src/beam.rs +++ b/common/systems/src/beam.rs @@ -1,5 +1,5 @@ use common::{ - combat::{AttackOptions, AttackSource, AttackerInfo, TargetInfo}, + combat::{self, AttackOptions, AttackSource, AttackerInfo, TargetInfo}, comp::{ agent::{Sound, SoundKind}, Beam, BeamSegment, Body, CharacterState, Combo, Energy, Group, Health, HealthSource, @@ -196,7 +196,6 @@ impl<'a> System<'a> for Sys { .zip(beam_segment.owner) .map(|(entity, uid)| AttackerInfo { entity, - player: read_data.players.get(entity), uid, energy: read_data.energies.get(entity), combo: read_data.combos.get(entity), @@ -205,7 +204,6 @@ impl<'a> System<'a> for Sys { let target_info = TargetInfo { entity: target, - player: read_data.players.get(target), uid: *uid_b, inventory: read_data.inventories.get(target), stats: read_data.stats.get(target), @@ -215,11 +213,15 @@ impl<'a> System<'a> for Sys { char_state: read_data.character_states.get(target), }; - // No luck with dodging beams - let target_dodging = false; + let avoid_harm = combat::avoid_player_harm( + beam_owner.and_then(|owner| read_data.players.get(owner)), + read_data.players.get(target), + ); let attack_options = AttackOptions { - target_dodging, + // No luck with dodging beams + target_dodging: false, + avoid_harm, target_group, }; diff --git a/common/systems/src/melee.rs b/common/systems/src/melee.rs index d7134396ff..aefdee9db1 100644 --- a/common/systems/src/melee.rs +++ b/common/systems/src/melee.rs @@ -1,5 +1,5 @@ use common::{ - combat::{AttackOptions, AttackSource, AttackerInfo, TargetInfo}, + combat::{self, AttackOptions, AttackSource, AttackerInfo, TargetInfo}, comp::{ agent::{Sound, SoundKind}, Body, CharacterState, Combo, Energy, Group, Health, Inventory, Melee, Ori, Player, Pos, @@ -145,7 +145,6 @@ impl<'a> System<'a> for Sys { let attacker_info = Some(AttackerInfo { entity: attacker, - player: read_data.players.get(attacker), uid: *uid, energy: read_data.energies.get(attacker), combo: read_data.combos.get(attacker), @@ -154,7 +153,6 @@ impl<'a> System<'a> for Sys { let target_info = TargetInfo { entity: target, - player: read_data.players.get(target), uid: *uid_b, inventory: read_data.inventories.get(target), stats: read_data.stats.get(target), @@ -164,8 +162,14 @@ impl<'a> System<'a> for Sys { char_state: read_data.char_states.get(target), }; + let avoid_harm = combat::avoid_player_harm( + read_data.players.get(attacker), + read_data.players.get(target), + ); + let attack_options = AttackOptions { target_dodging, + avoid_harm, target_group, }; diff --git a/common/systems/src/projectile.rs b/common/systems/src/projectile.rs index e19430d328..a183306bbd 100644 --- a/common/systems/src/projectile.rs +++ b/common/systems/src/projectile.rs @@ -1,5 +1,5 @@ use common::{ - combat::{AttackOptions, AttackSource, AttackerInfo, TargetInfo}, + combat::{self, AttackOptions, AttackSource, AttackerInfo, TargetInfo}, comp::{ agent::{Sound, SoundKind}, projectile, Body, CharacterState, Combo, Energy, Group, Health, HealthSource, Inventory, @@ -115,6 +115,7 @@ impl<'a> System<'a> for Sys { } let projectile = &mut *projectile; + // FIXME: this code is highway to hell, resolve this for effect in projectile.hit_entity.drain(..) { match effect { projectile::Effect::Attack(attack) => { @@ -135,7 +136,6 @@ impl<'a> System<'a> for Sys { owner_entity.zip(projectile.owner).map(|(entity, uid)| { AttackerInfo { entity, - player: read_data.players.get(entity), uid, energy: read_data.energies.get(entity), combo: read_data.combos.get(entity), @@ -145,7 +145,6 @@ impl<'a> System<'a> for Sys { let target_info = TargetInfo { entity: target, - player: read_data.players.get(target), uid: other, inventory: read_data.inventories.get(target), stats: read_data.stats.get(target), @@ -155,10 +154,6 @@ impl<'a> System<'a> for Sys { char_state: read_data.character_states.get(target), }; - // They say witchers can dodge arrows, - // but we don't have witchers - let target_dodging = false; - if let Some(&body) = read_data.bodies.get(entity) { outcomes.push(Outcome::ProjectileHit { pos: pos.0, @@ -172,8 +167,16 @@ impl<'a> System<'a> for Sys { }); } + let avoid_harm = combat::avoid_player_harm( + owner_entity.and_then(|owner| read_data.players.get(owner)), + read_data.players.get(target), + ); + let attack_options = AttackOptions { - target_dodging, + // They say witchers can dodge arrows, + // but we don't have witchers + target_dodging: false, + avoid_harm, target_group, }; attack.apply_attack( diff --git a/common/systems/src/shockwave.rs b/common/systems/src/shockwave.rs index 19f49f7f1c..6e6a66bd65 100644 --- a/common/systems/src/shockwave.rs +++ b/common/systems/src/shockwave.rs @@ -1,5 +1,5 @@ use common::{ - combat::{AttackOptions, AttackSource, AttackerInfo, TargetInfo}, + combat::{self, AttackOptions, AttackSource, AttackerInfo, TargetInfo}, comp::{ agent::{Sound, SoundKind}, Body, CharacterState, Combo, Energy, Group, Health, HealthSource, Inventory, Ori, @@ -192,7 +192,6 @@ impl<'a> System<'a> for Sys { .zip(shockwave.owner) .map(|(entity, uid)| AttackerInfo { entity, - player: read_data.players.get(entity), uid, energy: read_data.energies.get(entity), combo: read_data.combos.get(entity), @@ -201,7 +200,6 @@ impl<'a> System<'a> for Sys { let target_info = TargetInfo { entity: target, - player: read_data.players.get(target), uid: *uid_b, inventory: read_data.inventories.get(target), stats: read_data.stats.get(target), @@ -211,11 +209,14 @@ impl<'a> System<'a> for Sys { char_state: read_data.character_states.get(target), }; - // Trying roll during earthquake isn't the best idea - let target_dodging = false; - + let avoid_harm = combat::avoid_player_harm( + shockwave_owner.and_then(|owner| read_data.players.get(owner)), + read_data.players.get(target), + ); let attack_options = AttackOptions { - target_dodging, + // Trying roll during earthquake isn't the best idea + target_dodging: false, + avoid_harm, target_group, }; diff --git a/server/src/events/entity_manipulation.rs b/server/src/events/entity_manipulation.rs index aab9831833..ea10d993ad 100644 --- a/server/src/events/entity_manipulation.rs +++ b/server/src/events/entity_manipulation.rs @@ -871,7 +871,6 @@ pub fn handle_explosion(server: &Server, pos: Vec3, explosion: Explosion, o .zip(owner) .map(|(entity, uid)| combat::AttackerInfo { entity, - player: players.get(entity), uid, energy: energies.get(entity), combo: combos.get(entity), @@ -880,7 +879,6 @@ pub fn handle_explosion(server: &Server, pos: Vec3, explosion: Explosion, o let target_info = combat::TargetInfo { entity: entity_b, - player: players.get(entity_b), uid: *uid_b, inventory: inventories.get(entity_b), stats: stats_b_maybe, @@ -890,10 +888,15 @@ pub fn handle_explosion(server: &Server, pos: Vec3, explosion: Explosion, o char_state: char_state_b_maybe, }; + let avoid_harm = combat::avoid_player_harm( + owner_entity.and_then(|owner| players.get(owner)), + players.get(entity_b), + ); let attack_options = combat::AttackOptions { // cool guyz maybe don't look at explosions // but they still got hurt, it's not Hollywood target_dodging: false, + avoid_harm, target_group, }; @@ -926,6 +929,13 @@ pub fn handle_explosion(server: &Server, pos: Vec3, explosion: Explosion, o 1.0 - distance_squared / explosion.radius.powi(2) }; + let avoid_harm = || { + owner_entity.map_or(false, |attacker| { + let attacker = players.get(attacker); + let target = players.get(entity_b); + combat::avoid_player_harm(attacker, target) + }) + }; if strength > 0.0 { let is_alive = ecs .read_storage::() @@ -933,13 +943,8 @@ pub fn handle_explosion(server: &Server, pos: Vec3, explosion: Explosion, o .map_or(true, |h| !h.is_dead); if is_alive { - let avoid_harm = owner_entity.map_or(false, |attacker| { - let attacker = players.get(attacker); - let target = players.get(entity_b); - combat::avoid_harm(attacker, target) - }); effect.modify_strength(strength); - if !(effect.is_harm() && avoid_harm) { + if !(effect.is_harm() && avoid_harm()) { server.state().apply_effect(entity_b, effect.clone(), owner); } } diff --git a/server/src/sys/msg/register.rs b/server/src/sys/msg/register.rs index 9f2e22f3b4..f67d4c35c3 100644 --- a/server/src/sys/msg/register.rs +++ b/server/src/sys/msg/register.rs @@ -37,8 +37,8 @@ pub struct ReadData<'a> { uids: ReadStorage<'a, Uid>, clients: ReadStorage<'a, Client>, server_event_bus: Read<'a, EventBus>, - _health_comp: ReadStorage<'a, Health>, // used by plugin feature - _plugin_mgr: ReadPlugin<'a>, // used by plugin feature + _healths: ReadStorage<'a, Health>, // used by plugin feature + _plugin_mgr: ReadPlugin<'a>, // used by plugin feature _uid_allocator: Read<'a, UidAllocator>, // used by plugin feature } @@ -117,7 +117,7 @@ impl<'a> System<'a> for Sys { #[cfg(feature = "plugins")] let ecs_world = EcsWorld { entities: &read_data.entities, - health: (&read_data._health_comp).into(), + health: (&read_data._healths).into(), uid: (&read_data.uids).into(), player: (&players).into(), uid_allocator: &read_data._uid_allocator,