From bebd51479ebc5f2cdd25b872f80db03b048b8937 Mon Sep 17 00:00:00 2001 From: Nipun Garg Date: Wed, 3 Jul 2019 07:06:35 +0530 Subject: HDB: Add traceStraightPath() --- engines/hdb/ai-waypoint.cpp | 134 ++++++++++++++++++++++++++++++++++++++++++++ engines/hdb/ai.h | 1 + 2 files changed, 135 insertions(+) (limited to 'engines') 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() { -- cgit v1.2.3