Use or() for target selection

This commit is contained in:
James Melkonian 2021-05-24 22:35:04 -07:00 committed by Avi Weinstock
parent bf5336f97f
commit a6018f8ed3

View File

@ -1413,54 +1413,71 @@ impl<'a> AgentData<'a> {
&& !invulnerability_is_in_buffs(read_data.buffs.get(*e)) && !invulnerability_is_in_buffs(read_data.buffs.get(*e))
}) })
.filter_map(|(e, e_pos, e_health, e_stats, e_inventory, e_alignment, _char_state)| { .filter_map(|(e, e_pos, e_health, e_stats, e_inventory, e_alignment, _char_state)| {
if 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) { // Hostile entities
Some((e, e_pos)) 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).then(|| Some((e, e_pos))).flatten()
} else if let Some(rtsim_entity) = &self.rtsim_entity { .or({
if can_speak(agent) && rtsim_entity.brain.remembers_fight_with_character(&e_stats.name) { // I remember fighting this entity
remember_fight(agent, e_stats.name.clone(), read_data.time.0); self.rtsim_entity.and_then(|rtsim_entity| {
let msg = format!("{}! How dare you cross me again!", e_stats.name.clone()); if rtsim_entity.brain.remembers_fight_with_character(&e_stats.name) {
self.chat_general(msg, event_emitter); if can_speak(agent) {
Some((e, e_pos))
} else {
None
}
} else if let Some(alignment) = self.alignment {
if matches!(alignment, Alignment::Npc) && e_inventory.equipped_items().filter(|item| item.tags().contains(&ItemTag::Cultist)).count() > 2 {
if can_speak(agent) {
if self.rtsim_entity.is_some() {
remember_fight(agent, e_stats.name.clone(), read_data.time.0); remember_fight(agent, e_stats.name.clone(), read_data.time.0);
let msg = format!("{}! How dare you cross me again!", e_stats.name.clone());
self.chat_general(msg, event_emitter);
} }
let msg = "npc.speech.villager_cultist_alarm".to_string(); Some((e, e_pos))
self.chat_general(msg, event_emitter); } else {
self.emit_villager_alarm(read_data.time.0, event_emitter); None
} }
Some((e, e_pos)) })
} else { }).or({
None // Cultists!
} self.alignment.and_then(|alignment| {
} else if let Some(agent_stats) = read_data.stats.get(*self.entity) { (matches!(alignment, Alignment::Npc) && e_inventory.equipped_items().filter(|item| item.tags().contains(&ItemTag::Cultist)).count() > 2).then(|| {
let is_village_guard = agent_stats.name == *"Guard".to_string(); if can_speak(agent) {
if is_village_guard { if self.rtsim_entity.is_some() {
e_alignment.map(|alignment| { remember_fight(agent, e_stats.name.clone(), read_data.time.0);
let is_npc = matches!(alignment, Alignment::Npc);
if is_npc && e_health.last_change.0 < DAMAGE_MEMORY_DURATION {
if let comp::HealthSource::Damage { by: Some(by), .. } = e_health.last_change.1.cause {
get_entity_by_id(by.id(), read_data).map(|attacker| {
read_data.positions.get(attacker).map(|a_pos| (attacker, a_pos))
}).flatten()
} else {
None
} }
let msg = "npc.speech.villager_cultist_alarm".to_string();
self.chat_general(msg, event_emitter);
self.emit_villager_alarm(read_data.time.0, event_emitter);
}
Some((e, e_pos))
})
}).flatten()
}).or({
// I'm a guard and a villager is in distress
read_data.stats.get(*self.entity).map_or(false, |stats| stats.name == "Guard")
.then(|| {
let other_is_npc = matches!(e_alignment, Some(Alignment::Npc));
if other_is_npc {
let remembers_damage = e_health.last_change.0 < DAMAGE_MEMORY_DURATION;
remembers_damage
// TODO: add `.by()` helper method to HealthSource?
.then(|| {
println!("remembers damage");
match e_health.last_change.1.cause {
comp::HealthSource::Damage { by, .. } => by,
_ => None,
}
})
.flatten()
.and_then(|attacker_uid| {
println!("attacker has a uid");
get_entity_by_id(attacker_uid.id(), read_data)
})
.and_then(|attacker| {
println!("attacker has pos");
read_data
.positions
.get(attacker)
.map(|a_pos| (attacker, a_pos))
})
} else { } else {
None None
} }
}).flatten() }).flatten()
} else { })
None
}
} else {
None
}
}) })
// Can we even see them? // Can we even see them?
.filter(|(_e, e_pos)| { .filter(|(_e, e_pos)| {
@ -1492,13 +1509,14 @@ impl<'a> AgentData<'a> {
selected_at: read_data.time.0, selected_at: read_data.time.0,
}); });
//// TODO: REMOVE THIS BEFORE MERGE // TODO: REMOVE THIS BEFORE MERGE
//if let Some(agent_stats) = read_data.stats.get(*self.entity) { if let Some(agent_stats) = read_data.stats.get(*self.entity) {
// let is_village_guard = agent_stats.name == *"Guard".to_string(); let is_village_guard = agent_stats.name == *"Guard".to_string();
// if is_village_guard { if is_village_guard {
// println!("guard's target is: {:?}", agent.target); let msg = "I'm a guard".to_string();
// } self.chat_general(msg, event_emitter);
//} }
}
} }
fn attack( fn attack(