aboutsummaryrefslogtreecommitdiff
path: root/engines/hdb/ai-waypoint.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/hdb/ai-waypoint.cpp')
-rw-r--r--engines/hdb/ai-waypoint.cpp134
1 files changed, 134 insertions, 0 deletions
diff --git a/engines/hdb/ai-waypoint.cpp b/engines/hdb/ai-waypoint.cpp
index 70847aba8b..c930a0c1a0 100644
--- a/engines/hdb/ai-waypoint.cpp
+++ b/engines/hdb/ai-waypoint.cpp
@@ -71,6 +71,140 @@ void AI::clearWaypoints() {
_numWaypoints = 0;
}
+bool AI::traceStraightPath(int x1, int y1, int *x2, int *y2, int *level) {
+ int xVel, yVel, ok, entOK;
+ AIEntity *e;
+
+ // this checks to make sure we're only going vert or horz
+ if (x1 != *x2 && y1 != *y2)
+ return false;
+
+ // this sets a -1, 0, or 1 step value
+ xVel = *x2 - x1;
+ if (xVel < 0)
+ xVel = -1;
+ if (xVel > 0)
+ xVel = 1;
+
+ yVel = *y2 - y1;
+ if (yVel < 0)
+ yVel = -1;
+ if (yVel > 0)
+ yVel = 1;
+
+ while (1) {
+ // clear tile ahead?
+ entOK = ok = 0;
+ uint32 flags = g_hdb->_map->getMapBGTileFlags(x1, y1);
+ if (flags & kFlagStairTop)
+ *level = 2;
+ else if (flags & kFlagStairBot)
+ *level = 1;
+
+ // Floor level 1
+ if (*level < 2) {
+ ok = !(flags & (kFlagPlayerBlock | kFlagMonsterBlock));
+ // if it's blocking, is it rad or plasma? (might be melted stuff on it)
+ if (!ok) {
+ ok = ((flags & kFlagPlasmaFloor) == kFlagPlasmaFloor) +
+ ((flags & kFlagPlasmaFloor) == kFlagRadFloor);
+ e = findEntity(x1, y1);
+ if (e && g_hdb->_ai->walkThroughEnt(e->type))
+ entOK = 1;
+ else if (ok && e && (e->state == STATE_FLOATING || e->state == STATE_MELTED || e == _player))
+ entOK = ok = 1;
+ else
+ ok = 0;
+ } else if (ok &&
+ ((flags & kFlagWater) == kFlagWater ||
+ (flags & kFlagSlime) == kFlagSlime)) {
+ // if it's non-blocking, is there water or slime?
+ e = findEntity(x1, y1);
+ if (e && g_hdb->_ai->walkThroughEnt(e->type))
+ entOK = 1;
+ else
+ if (e && (e->state == STATE_FLOATING || e->state == STATE_MELTED || e == _player))
+ entOK = ok = 1;
+ else
+ ok = 0;
+ }
+ } else {
+ // Floor level 2
+ if (g_hdb->_map->getMapFGTileIndex(x1, y1) >= 0) // is there a foregnd tile? its flags take precedence on Level 2
+ ok = !(g_hdb->_map->getMapFGTileFlags(x1, y1) & (kFlagPlayerBlock | kFlagMonsterBlock));
+ else {
+ flags = g_hdb->_map->getMapBGTileFlags(x1, y1);
+ ok = !(flags & (kFlagPlayerBlock | kFlagMonsterBlock));
+ // if it's blocking, is it rad or plasma? (might be melted stuff on it)
+ if (!ok) {
+ ok = ((flags & kFlagPlasmaFloor) == kFlagPlasmaFloor) +
+ ((flags & kFlagPlasmaFloor) == kFlagRadFloor);
+ e = findEntity(x1, y1);
+ if (e && g_hdb->_ai->walkThroughEnt(e->type))
+ entOK = 1;
+ else if (ok && e && (e->state == STATE_FLOATING || e->state == STATE_MELTED || e == _player))
+ entOK = ok = 1;
+ else
+ ok = 0;
+ } else if (ok &&
+ ((flags & kFlagWater) == kFlagWater ||
+ (flags & kFlagSlime) == kFlagSlime)) {
+ // if it's non-blocking, is there water or slime?
+ e = findEntity(x1, y1);
+ if (e && g_hdb->_ai->walkThroughEnt(e->type))
+ entOK = 1;
+ else
+ if (e && (e->state == STATE_FLOATING || e->state == STATE_MELTED || e == _player))
+ entOK = ok = 1;
+ else
+ ok = 0;
+ }
+ }
+ }
+
+ if (ok) {
+ e = findEntity(x1, y1);
+ if (e == _player)
+ e = NULL;
+ else if (g_hdb->_map->laserBeamExist(x1, y1)) {
+ *x2 = x1 - xVel;
+ *y2 = y1 - yVel;
+ return true;
+ } else if (e && (e->level != _player->level) && (g_hdb->_map->getMapFGTileFlags(e->tileX, e->tileY) & kFlagGrating)) {
+ // on the same level????
+ entOK = 1;
+ }
+
+ if (e && !entOK) {
+ if (g_hdb->_ai->walkThroughEnt(e->type)) {
+ // yes! are we at desired location?
+ if (x1 == *x2 && y1 == *y2)
+ return true;
+ } else {
+ // solid tile! back up one and return!
+ *x2 = x1 - xVel;
+ *y2 = y1 - yVel;
+ return true;
+ }
+ } else if (x1 == *x2 && y1 == *y2) {
+ // yes! are we at desired location?
+ return true;
+ }
+ } else {
+ // solid tile! back up one and return!
+ *x2 = x1 - xVel;
+ *y2 = y1 - yVel;
+
+ return true;
+ }
+
+ x1 += xVel;
+ y1 += yVel;
+ }
+
+ return true;
+}
+
Tile *AI::getStandFrameDir(AIEntity *e) {
switch (e->dir) {
case DIR_DOWN: