From 5488f9f5255ed23c0225b01d31e303af728d3583 Mon Sep 17 00:00:00 2001 From: holychowders Date: Sun, 25 Apr 2021 21:24:06 +0000 Subject: [PATCH] Prevent safezoned villagers from spamming messages upon seeing an enemy --- CHANGELOG.md | 1 + server/src/sys/agent.rs | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c1f1b9c00..0632109896 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -102,6 +102,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Staff fire shockwave ability no longer has an unlimited vertical range - Skillbar buttons correctly account for skill points when checking if player has enough stamina for the ability. - Burning Debuff icon is now displayed correctly. +- Villagers in safezones no longer spam messages upon seeing an enemy ## [0.9.0] - 2021-03-20 diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index 2afa0d5ebd..12cfe96726 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -619,23 +619,25 @@ impl<'a> AgentData<'a> { self.idle(agent, controller, &read_data); } - // If not fleeing, attack the hostile - // entity! + // If not fleeing, attack the hostile entity! } else { - // If the hostile entity is dead or in a safezone, return to idle + // If the hostile entity is dead or has an invulnerability buff (eg, those + // applied in safezones), return to idle if should_stop_attacking( read_data.healths.get(target), read_data.buffs.get(target), ) { - agent.target = None; if agent.behavior.can(BehaviorCapability::SPEAK) { let msg = "npc.speech.villager_enemy_killed".to_string(); event_emitter .emit(ServerEvent::Chat(UnresolvedChatMsg::npc(*self.uid, msg))); } + + agent.target = None; // Choose a new target every 10 seconds, but only for // enemies - // TODO: This should be more principled. Consider factoring + // TODO: This should be more + // principled. Consider factoring // health, combat rating, wielded weapon, etc, into the // decision to change target. } else if read_data.time.0 - selected_at > RETARGETING_THRESHOLD_SECONDS @@ -1411,6 +1413,7 @@ impl<'a> AgentData<'a> { || e_pos.0.distance_squared(self.pos.0) < listen_dist.powi(2)) // TODO implement proper sound system for agents && e != self.entity && !e_health.is_dead + && !invulnerability_is_in_buffs(read_data.buffs.get(*e)) && (try_owner_alignment(self.alignment, &read_data).and_then(|a| try_owner_alignment(*e_alignment, &read_data).map(|b| a.hostile_towards(*b))).unwrap_or(false) || ( if let Some(rtsim_entity) = &self.rtsim_entity { if rtsim_entity.brain.remembers_fight_with_character(&e_stats.name) { @@ -2868,8 +2871,11 @@ fn can_see_tgt(terrain: &TerrainGrid, pos: &Pos, tgt_pos: &Pos, dist_sqrd: f32) // If target is dead or has invulnerability buff, returns true fn should_stop_attacking(health: Option<&Health>, buffs: Option<&Buffs>) -> bool { - health.map_or(true, |a| a.is_dead) - || buffs.map_or(false, |b| b.kinds.contains_key(&BuffKind::Invulnerability)) + health.map_or(true, |a| a.is_dead) || invulnerability_is_in_buffs(buffs) +} + +fn invulnerability_is_in_buffs(buffs: Option<&Buffs>) -> bool { + buffs.map_or(false, |b| b.kinds.contains_key(&BuffKind::Invulnerability)) } /// Attempts to get alignment of owner if entity has Owned alignment