From a00121bedf12a8b763b346dd37e4411e0416a9e5 Mon Sep 17 00:00:00 2001 From: "Tormod G. Hellen" Date: Fri, 4 Feb 2022 01:59:27 +0100 Subject: [PATCH] Make entities protect owned bodies. --- CHANGELOG.md | 1 + server/src/sys/agent.rs | 87 +++++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1eaef1588e..d6a24540fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bumped tracing-subscriber to resolve [RUSTSEC-2022-0006](https://rustsec.org/advisories/RUSTSEC-2022-0006) - Made /home command a mod+ exclusive - Friendly creatures will now defend each other +- Creatures will now defend their pets ### Removed diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index b22e5b83f4..dd99385152 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -1503,53 +1503,56 @@ impl<'a> AgentData<'a> { }) }; - let guard_other = |e_health: &Health, - e_body: Option<&Body>, - e_alignment: Option<&Alignment>| { - let i_am_a_guard = read_data - .stats - .get(*self.entity) - .map_or(false, |stats| stats.name == "Guard"); - let other_is_a_villager = matches!(e_alignment, Some(Alignment::Npc)); - let we_are_friendly: bool = self.alignment.map_or(false, |ma| { - e_alignment.map_or(false, |ea| !ea.hostile_towards(*ma)) - }); - let we_share_species: bool = self.body.map_or(false, |mb| { - e_body.map_or(false, |eb| { - eb.is_same_species_as(mb) || (eb.is_humanoid() && mb.is_humanoid()) - }) - }); - let other_has_taken_damage = read_data.time.0 - e_health.last_change.time.0 < 5.0; - let attacker_of = |health: &Health| health.last_change.damage_by(); + let guard_other = + |e_health: &Health, e_body: Option<&Body>, e_alignment: Option<&Alignment>| { + let i_am_a_guard = read_data + .stats + .get(*self.entity) + .map_or(false, |stats| stats.name == "Guard"); + let other_is_a_villager = matches!(e_alignment, Some(Alignment::Npc)); + let we_are_friendly: bool = self.alignment.map_or(false, |ma| { + e_alignment.map_or(false, |ea| !ea.hostile_towards(*ma)) + }); + let we_share_species: bool = self.body.map_or(false, |mb| { + e_body.map_or(false, |eb| { + eb.is_same_species_as(mb) || (eb.is_humanoid() && mb.is_humanoid()) + }) + }); + let i_own_other = + matches!(e_alignment, Some(Alignment::Owned(ouid)) if self.uid == ouid); + let other_has_taken_damage = read_data.time.0 - e_health.last_change.time.0 < 5.0; + let attacker_of = |health: &Health| health.last_change.damage_by(); - let i_should_defend = other_has_taken_damage - && ((we_are_friendly && we_share_species) || (i_am_a_guard && other_is_a_villager)); + let i_should_defend = other_has_taken_damage + && ((we_are_friendly && we_share_species) + || (i_am_a_guard && other_is_a_villager) + || i_own_other); - i_should_defend - .then(|| { - attacker_of(e_health) - .and_then(|damage_contributor| { - get_entity_by_id(damage_contributor.uid().0, read_data) - }) - .and_then(|attacker| { - read_data.alignments.get(attacker).and_then(|aa| { - self.alignment.and_then({ - |ma| { - if !ma.passive_towards(*aa) { - read_data - .positions - .get(attacker) - .map(|a_pos| (attacker, *a_pos)) - } else { - None + i_should_defend + .then(|| { + attacker_of(e_health) + .and_then(|damage_contributor| { + get_entity_by_id(damage_contributor.uid().0, read_data) + }) + .and_then(|attacker| { + read_data.alignments.get(attacker).and_then(|aa| { + self.alignment.and_then({ + |ma| { + if !ma.passive_towards(*aa) { + read_data + .positions + .get(attacker) + .map(|a_pos| (attacker, *a_pos)) + } else { + None + } } - } + }) }) }) - }) - }) - .flatten() - }; + }) + .flatten() + }; let rtsim_remember = |target_stats: &Stats,