/** * \brief Returns whether this entity is an obstacle for another one. * \param other Another entity. * \return \c true if this entity is an obstacle for the other one. */ bool Enemy::is_obstacle_for(const MapEntity& other) const { if (!is_enabled()) { return false; } return !is_traversable() || other.is_enemy_obstacle(*this); }
bool is_safe_to_follow (struct anim *k0, struct anim *k1, enum dir dir) { /* not aware of enemy position */ if (! is_valid_pos (&k0->enemy_pos)) return false; struct pos p0, p, p1, pke, pk; survey (_m, pos, &k0->f, NULL, &p0, NULL); survey ((k0->f.dir == LEFT) ? _mr : _ml, pos, &k1->f, NULL, &p1, NULL); pos2room (&p1, p0.room, &p1); /* not reachable, to start with */ if (p0.room != p1.room) return false; if (p0.floor > p1.floor) return false; /* the character went down after the enemy */ if (p0.floor != k0->enemy_pos.floor) { /* enum dir odir = (dir == LEFT) ? RIGHT : LEFT; */ /* if (is_on_back (k0, k1) && is_seeing (k0, k1, odir) */ /* && p0.floor == p1.floor) return true; */ if (is_anim_seeing (k0, k1, LEFT) || is_anim_seeing (k0, k1, RIGHT)) return true; return false; } /* if falling the chasing is inevitable (necessary to prevent leave_fight_logic from forgeting enemy based on the facing direction of the is_in_range check) */ if (is_anim_fall (&k0->f)) return true; if (dir == LEFT) { if (! is_safe_at_left (&p0)) return false; if (! is_safe_at_right (&k0->enemy_pos, &k0->f)) return false; if (peqr (&k0->enemy_pos, &p0, +0, -1)) return true; prel (&p0, &pk, +0, -1); prel (&k0->enemy_pos, &pke, +0, +1); if (is_collidable_at_right (&pk, &k0->f)) return false; } else { if (! is_safe_at_right (&p0, &k0->f)) return false; if (! is_safe_at_left (&k0->enemy_pos)) return false; if (peqr (&k0->enemy_pos, &p0, +0, +1)) return true; prel (&p0, &pk, +0, +1); prel (&k0->enemy_pos, &pke, +0, -1); if (is_collidable_at_right (&p0, &k0->f)) return false; } /* enemy went down */ if (is_traversable (&k0->enemy_pos)) { prel (&k0->enemy_pos, &pke, +1, +0); if (is_traversable (&pke) || fg (&pke) == SPIKES_FLOOR) return false; int d = (dir == LEFT) ? -1 : +1; if (peq (&pk, &k0->enemy_pos)) return true; prel (&k0->enemy_pos, &pke, +0, -1 * d); } else if (peq (&p0, &k0->enemy_pos) && ! (is_anim_seeing (k0, k1, LEFT) || is_anim_seeing (k0, k1, RIGHT))) return false; first_confg (&pk, &pke, dangerous_cs, &p); if (is_valid_pos (&p)) return false; first_confg (&pk, &pke, door_cs, &p); if (! is_valid_pos (&p)) return true; else return door_at_pos (&p)->action == OPEN_DOOR || ! is_collidable_at_right (&p, &k0->f); }