summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dungeon/src/entity.rs25
1 files changed, 17 insertions, 8 deletions
diff --git a/dungeon/src/entity.rs b/dungeon/src/entity.rs
index 3463618..794ef05 100644
--- a/dungeon/src/entity.rs
+++ b/dungeon/src/entity.rs
@@ -320,15 +320,24 @@ impl Updater<'_> {
fn update_enemy_ai(&mut self, entity: &mut Entity, ai: &mut EnemyMoveState) {
use EnemyMoveState as State;
- // get the position in front
- let front_pos = entity.pos.step(entity.dir).unwrap_or(entity.pos);
+ // get the next position this entity may be moving to.
+ //
+ // we want to be able to short circut past pathed movement
+ // if we generate a new path, without allowing the entity to move
+ // off grid! thus this is the best position to start the new
+ // movement from :)
+ let next_pos = entity
+ .in_front()
+ .filter(|pos| self.floor.get(*pos).is_walkable())
+ .or(entity.moving_to)
+ .unwrap_or(entity.pos);
// check if player is in range
if !matches!(ai, State::Attack { .. })
- && let Some(m_state) = State::attack(front_pos, self.player_pos, self.floor)
+ && let Some(m_state) = State::attack(next_pos, self.player_pos, self.floor)
{
*ai = m_state;
- entity.moving_to = Some(front_pos);
+ entity.moving_to = Some(next_pos);
return;
}
@@ -339,8 +348,8 @@ impl Updater<'_> {
return;
}
- *ai = State::roam(entity.pos, self.floor, self.rng);
- entity.moving_to = Some(front_pos);
+ *ai = State::roam(next_pos, self.floor, self.rng);
+ entity.moving_to = Some(next_pos);
}
State::Roam(moves) => {
if moves.is_empty() {
@@ -354,9 +363,9 @@ impl Updater<'_> {
}
State::Attack(moves, old_player_pos) => {
if *old_player_pos != self.player_pos {
- *ai = State::attack(front_pos, self.player_pos, self.floor)
+ *ai = State::attack(next_pos, self.player_pos, self.floor)
.unwrap_or_default();
- entity.moving_to = Some(front_pos);
+ entity.moving_to = Some(next_pos);
return;
}
*old_player_pos = self.player_pos;