faction-based visible ai, initial commit
This commit is contained in:
parent
bb8cf69b86
commit
b95f0cc1ad
4 changed files with 115 additions and 1 deletions
|
|
@ -1,5 +1,4 @@
|
|||
use crate::{raws::Reaction, Faction, Map, Position, TakingTurn, WantsToMelee};
|
||||
use rltk::prelude::*;
|
||||
use specs::prelude::*;
|
||||
|
||||
pub struct AdjacentAI {}
|
||||
|
|
|
|||
|
|
@ -14,3 +14,5 @@ mod monster_ai_system;
|
|||
pub use monster_ai_system::MonsterAI;
|
||||
mod adjacent_ai_system;
|
||||
pub use adjacent_ai_system::AdjacentAI;
|
||||
mod visible_ai_system;
|
||||
pub use visible_ai_system::VisibleAI;
|
||||
|
|
|
|||
111
src/ai/visible_ai_system.rs
Normal file
111
src/ai/visible_ai_system.rs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
use crate::{
|
||||
raws::Reaction, Faction, Map, Mind, Position, TakingTurn, Telepath, Viewshed, WantsToApproach, WantsToFlee,
|
||||
};
|
||||
use specs::prelude::*;
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub struct VisibleAI {}
|
||||
|
||||
impl<'a> System<'a> for VisibleAI {
|
||||
#[allow(clippy::type_complexity)]
|
||||
type SystemData = (
|
||||
WriteStorage<'a, TakingTurn>,
|
||||
ReadStorage<'a, Faction>,
|
||||
ReadStorage<'a, Position>,
|
||||
ReadExpect<'a, Map>,
|
||||
WriteStorage<'a, WantsToApproach>,
|
||||
WriteStorage<'a, WantsToFlee>,
|
||||
Entities<'a>,
|
||||
ReadExpect<'a, Entity>,
|
||||
ReadStorage<'a, Viewshed>,
|
||||
ReadStorage<'a, Telepath>,
|
||||
ReadStorage<'a, Mind>,
|
||||
);
|
||||
|
||||
fn run(&mut self, data: Self::SystemData) {
|
||||
let (
|
||||
mut turns,
|
||||
factions,
|
||||
positions,
|
||||
map,
|
||||
mut wants_to_approach,
|
||||
mut wants_to_flee,
|
||||
entities,
|
||||
player,
|
||||
viewsheds,
|
||||
telepaths,
|
||||
minds,
|
||||
) = data;
|
||||
|
||||
for (entity, _turn, faction, pos, viewshed) in (&entities, &turns, &factions, &positions, &viewsheds).join() {
|
||||
if entity == *player {
|
||||
continue;
|
||||
}
|
||||
let this_idx = map.xy_idx(pos.x, pos.y);
|
||||
let mut reactions: Vec<(usize, Reaction)> = Vec::new();
|
||||
let mut flee: Vec<usize> = Vec::new();
|
||||
let mut idxs: HashSet<usize> = HashSet::new();
|
||||
for visible_tile in viewshed.visible_tiles.iter() {
|
||||
let idx = map.xy_idx(visible_tile.x, visible_tile.y);
|
||||
if this_idx != idx {
|
||||
evaluate(idx, &map, &factions, &faction.name, &mut reactions, None);
|
||||
idxs.insert(idx);
|
||||
}
|
||||
}
|
||||
if let Some(is_telepath) = telepaths.get(entity) {
|
||||
for telepath_tile in is_telepath.telepath_tiles.iter() {
|
||||
let idx = map.xy_idx(telepath_tile.x, telepath_tile.y);
|
||||
// If we didn't already evaluate this idx (if it's not contained in the HashSet),
|
||||
// and it's not the idx we're standing on, then evaluate here w/ minds taken into
|
||||
// account.
|
||||
if this_idx != idx && idxs.contains(&idx) {
|
||||
evaluate(idx, &map, &factions, &faction.name, &mut reactions, Some(&minds));
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut done = false;
|
||||
for reaction in reactions.iter() {
|
||||
match reaction.1 {
|
||||
Reaction::Attack => {
|
||||
wants_to_approach
|
||||
.insert(entity, WantsToApproach { idx: reaction.0 as i32 })
|
||||
.expect("Error inserting WantsToApproach");
|
||||
done = true;
|
||||
}
|
||||
Reaction::Flee => {
|
||||
flee.push(reaction.0);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
if !done && !flee.is_empty() {
|
||||
wants_to_flee.insert(entity, WantsToFlee { indices: flee }).expect("Unable to insert");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn evaluate(
|
||||
idx: usize,
|
||||
map: &Map,
|
||||
factions: &ReadStorage<Faction>,
|
||||
this_faction: &str,
|
||||
reactions: &mut Vec<(usize, Reaction)>,
|
||||
minds: Option<&ReadStorage<Mind>>,
|
||||
) {
|
||||
for other_entity in map.tile_content[idx].iter() {
|
||||
// If minds are passed, we assume we're using telepathy here,
|
||||
// so if the other entity is mindless, we skip it.
|
||||
if minds.is_some() {
|
||||
if minds.unwrap().get(*other_entity).is_none() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if let Some(faction) = factions.get(*other_entity) {
|
||||
reactions.push((
|
||||
idx,
|
||||
crate::raws::faction_reaction(this_faction, &faction.name, &crate::raws::RAWS.lock().unwrap()),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -97,6 +97,7 @@ impl State {
|
|||
let mut turn_status_system = ai::TurnStatusSystem {};
|
||||
let mut quip_system = ai::QuipSystem {};
|
||||
let mut adjacent_ai = ai::AdjacentAI {};
|
||||
let mut visible_ai = ai::VisibleAI {};
|
||||
let mut mob = ai::MonsterAI {};
|
||||
let mut bystanders = ai::BystanderAI {};
|
||||
let mut trigger_system = trigger_system::TriggerSystem {};
|
||||
|
|
@ -118,6 +119,7 @@ impl State {
|
|||
turn_status_system.run_now(&self.ecs);
|
||||
quip_system.run_now(&self.ecs);
|
||||
adjacent_ai.run_now(&self.ecs);
|
||||
visible_ai.run_now(&self.ecs);
|
||||
mob.run_now(&self.ecs);
|
||||
bystanders.run_now(&self.ecs);
|
||||
trigger_system.run_now(&self.ecs);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue