mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-01 16:35:20 +00:00
HDB: Add traceStraightPath()
This commit is contained in:
parent
34b9457adc
commit
bebd51479e
@ -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:
|
||||
|
@ -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() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user