diff --git a/common/src/rtsim.rs b/common/src/rtsim.rs index bc62900979..07c1340a00 100644 --- a/common/src/rtsim.rs +++ b/common/src/rtsim.rs @@ -22,6 +22,7 @@ impl Component for RtSimEntity { pub enum RtSimEvent { AddMemory(Memory), SetMood(Memory), + ForgetEnemy(String), PrintMemories, } diff --git a/server/src/rtsim/entity.rs b/server/src/rtsim/entity.rs index fbeb959267..3f24371038 100644 --- a/server/src/rtsim/entity.rs +++ b/server/src/rtsim/entity.rs @@ -500,6 +500,14 @@ pub struct Brain { impl Brain { pub fn add_memory(&mut self, memory: Memory) { self.memories.push(memory); } + pub fn forget_enemy(&mut self, to_forget: &str) { + self.memories.retain(|memory| { + !matches!( + &memory.item, + MemoryItem::CharacterFight {name, ..} if name == to_forget) + }) + } + pub fn remembers_mood(&self) -> bool { self.memories .iter() @@ -538,8 +546,8 @@ impl Brain { pub fn remembers_fight_with_character(&self, name_to_remember: &str) -> bool { self.memories.iter().any(|memory| { matches!( - &memory.item, - MemoryItem::CharacterFight { name, .. } if name == name_to_remember) + &memory.item, + MemoryItem::CharacterFight { name, .. } if name == name_to_remember) }) } } diff --git a/server/src/rtsim/mod.rs b/server/src/rtsim/mod.rs index 827bd81728..218fe6e293 100644 --- a/server/src/rtsim/mod.rs +++ b/server/src/rtsim/mod.rs @@ -82,6 +82,12 @@ impl RtSim { .map(|entity| entity.brain.add_memory(memory)); } + pub fn forget_entity_enemy(&mut self, entity: RtSimId, name: &str) { + if let Some(entity) = self.entities.get_mut(entity) { + entity.brain.forget_enemy(name); + } + } + pub fn set_entity_mood(&mut self, entity: RtSimId, memory: Memory) { self.entities .get_mut(entity) diff --git a/server/src/sys/agent.rs b/server/src/sys/agent.rs index f9046768bc..950b9f17de 100644 --- a/server/src/sys/agent.rs +++ b/server/src/sys/agent.rs @@ -14,7 +14,7 @@ use common::{ invite::{InviteKind, InviteResponse}, item::{ tool::{AbilitySpec, ToolKind}, - Item, ItemDesc, ItemKind, ConsumableKind, + ConsumableKind, Item, ItemDesc, ItemKind, }, skills::{AxeSkill, BowSkill, HammerSkill, SceptreSkill, Skill, StaffSkill, SwordSkill}, Agent, Alignment, BehaviorCapability, BehaviorState, Body, CharacterAbility, @@ -418,6 +418,11 @@ impl<'a> System<'a> for Sys { if let Some(tgt_health) = read_data.healths.get(target) { // If target is dead, leave it if tgt_health.is_dead { + if let Some(tgt_stats) = + data.rtsim_entity.and(read_data.stats.get(target)) + { + rtsim_forget_enemy(&tgt_stats.name, agent); + } relax(agent, controller, event_emitter); // If the target is hostile // (either based on alignment or if @@ -473,9 +478,8 @@ impl<'a> System<'a> for Sys { }; data.attack(agent, controller, &target_data, &read_data); // Remember this encounter if an RtSim entity - if let Some(tgt_stats) = data - .rtsim_entity - .and_then(|_| read_data.stats.get(attacker)) + if let Some(tgt_stats) = + data.rtsim_entity.and(read_data.stats.get(attacker)) { rtsim_new_enemy(&tgt_stats.name, agent, &read_data); } @@ -524,6 +528,9 @@ impl<'a> System<'a> for Sys { RtSimEvent::AddMemory(memory) => { rtsim.insert_entity_memory(rtsim_entity.0, memory.clone()); }, + RtSimEvent::ForgetEnemy(name) => { + rtsim.forget_entity_enemy(rtsim_entity.0, &name); + }, RtSimEvent::SetMood(memory) => { rtsim.set_entity_mood(rtsim_entity.0, memory.clone()); }, @@ -4125,6 +4132,13 @@ fn rtsim_new_enemy(target_name: &str, agent: &mut Agent, read_data: &ReadData) { })); } +fn rtsim_forget_enemy(target_name: &str, agent: &mut Agent) { + agent + .rtsim_controller + .events + .push(RtSimEvent::ForgetEnemy(target_name.to_owned())); +} + fn can_see_tgt(terrain: &TerrainGrid, pos: &Pos, tgt_pos: &Pos, dist_sqrd: f32) -> bool { terrain .ray(pos.0 + Vec3::unit_z(), tgt_pos.0 + Vec3::unit_z())