HDB: Add traceStraightPath()

This commit is contained in:
Nipun Garg 2019-07-03 07:06:35 +05:30 committed by Eugene Sandulenko
parent 34b9457adc
commit bebd51479e
2 changed files with 135 additions and 0 deletions

View File

@ -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:

View File

@ -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() {