aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNipun Garg2019-07-03 07:06:35 +0530
committerEugene Sandulenko2019-09-03 17:17:09 +0200
commitbebd51479ebc5f2cdd25b872f80db03b048b8937 (patch)
tree0cf7b15cb32729edc4a731274f22bc76eb4704de
parent34b9457adcb7ffc428fc8ce069e8a10dc3e79077 (diff)
downloadscummvm-rg350-bebd51479ebc5f2cdd25b872f80db03b048b8937.tar.gz
scummvm-rg350-bebd51479ebc5f2cdd25b872f80db03b048b8937.tar.bz2
scummvm-rg350-bebd51479ebc5f2cdd25b872f80db03b048b8937.zip
HDB: Add traceStraightPath()
-rw-r--r--engines/hdb/ai-waypoint.cpp134
-rw-r--r--engines/hdb/ai.h1
2 files changed, 135 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:
diff --git a/engines/hdb/ai.h b/engines/hdb/ai.h
index 1ab2b86bb9..80f7a71221 100644
--- a/engines/hdb/ai.h
+++ b/engines/hdb/ai.h
@@ -946,6 +946,7 @@ public:
void addWaypoint(int px, int py, int x, int y, int level);
void removeFirstWaypoint();
void clearWaypoints();
+ bool traceStraightPath(int x1, int y1, int *x2, int *y2, int *lvl);
Tile *getStandFrameDir(AIEntity *e);
void drawWayPoints();
int waypointsLeft() {