mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Teach AI how to forgive
This commit is contained in:
parent
325acc9daf
commit
b6460f6c61
@ -22,6 +22,7 @@ impl Component for RtSimEntity {
|
||||
pub enum RtSimEvent {
|
||||
AddMemory(Memory),
|
||||
SetMood(Memory),
|
||||
ForgetEnemy(String),
|
||||
PrintMemories,
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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())
|
||||
|
Loading…
Reference in New Issue
Block a user