aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob/map.cpp')
-rw-r--r--engines/gob/map.cpp451
1 files changed, 269 insertions, 182 deletions
diff --git a/engines/gob/map.cpp b/engines/gob/map.cpp
index 9f1f5bdc59..500f6515ec 100644
--- a/engines/gob/map.cpp
+++ b/engines/gob/map.cpp
@@ -32,33 +32,40 @@
namespace Gob {
Map::Map(GobEngine *vm) : _vm(vm) {
- _widthByte = 0;
- _mapWidth = -1;
+ _mapVersion = 0;
+
+ _passWidth = 0;
+ _mapWidth = -1;
_mapHeight = -1;
- _screenWidth = 0;
+ _passMap = 0;
+
+ _screenWidth = 0;
_screenHeight = 0;
- _tilesWidth = 0;
+
+ _tilesWidth = 0;
_tilesHeight = 0;
- _passWidth = 0;
- _passMap = 0;
- _itemsMap = 0;
- _wayPointsCount = 0;
- _wayPoints = 0;
_bigTiles = false;
+ _wayPointCount = 0;
+ _wayPoints = 0;
+
+ _nearestWayPoint = 0;
+ _nearestDest = 0;
+
+ _itemsMap = 0;
+
for (int i = 0; i < 40; i++) {
- _itemPoses[i].x = 0;
- _itemPoses[i].y = 0;
+ _itemPoses[i].x = 0;
+ _itemPoses[i].y = 0;
_itemPoses[i].orient = 0;
}
- _nearestWayPoint = 0;
- _nearestDest = 0;
_curGoblinX = 0;
_curGoblinY = 0;
_destX = 0;
_destY = 0;
+
_sourceFile[0] = 0;
_loadFromAvo = false;
@@ -76,6 +83,87 @@ Map::~Map() {
delete[] _wayPoints;
}
+uint8 Map::getVersion() const {
+ return _mapVersion;
+}
+
+int16 Map::getMapWidth() const {
+ return _mapWidth;
+}
+
+int16 Map::getMapHeight() const {
+ return _mapHeight;
+}
+
+int16 Map::getScreenWidth() const {
+ return _screenWidth;
+}
+
+int16 Map::getScreenHeight() const {
+ return _screenHeight;
+}
+
+int16 Map::getTilesWidth() const {
+ return _tilesWidth;
+}
+
+int16 Map::getTilesHeight() const {
+ return _tilesHeight;
+}
+
+bool Map::hasBigTiles() const {
+ return _bigTiles;
+}
+
+int8 Map::getPass(int x, int y, int width) const {
+ if (!_passMap)
+ return 0;
+
+ if ((x < 0) || (y < 0) || (x >= _mapWidth) || (y >= _mapHeight))
+ return 0;
+
+ if (width == -1)
+ width = _passWidth;
+ return _passMap[y * width + x];
+}
+
+void Map::setPass(int x, int y, int8 pass, int width) {
+ if (!_passMap)
+ return;
+
+ if ((x < 0) || (y < 0) || (x >= _mapWidth) || (y >= _mapHeight))
+ return;
+
+ if (width == -1)
+ width = _passWidth;
+ _passMap[y * width + x] = pass;
+}
+
+const WayPoint &Map::getWayPoint(int n) const {
+ assert(_wayPoints);
+ assert(n < _wayPointCount);
+
+ return _wayPoints[n];
+}
+
+int16 Map::getItem(int x, int y) const {
+ assert(_itemsMap);
+
+ x = CLIP<int>(x, 0, _mapWidth - 1);
+ y = CLIP<int>(y, 0, _mapHeight - 1);
+
+ return _itemsMap[y][x];
+}
+
+void Map::setItem(int x, int y, int16 item) {
+ assert(_itemsMap);
+
+ x = CLIP<int>(x, 0, _mapWidth - 1);
+ y = CLIP<int>(y, 0, _mapHeight - 1);
+
+ _itemsMap[y][x] = item;
+}
+
void Map::placeItem(int16 x, int16 y, int16 id) {
if ((getItem(x, y) & 0xFF00) != 0)
setItem(x, y, (getItem(x, y) & 0xFF00) | id);
@@ -83,150 +171,175 @@ void Map::placeItem(int16 x, int16 y, int16 id) {
setItem(x, y, (getItem(x, y) & 0x00FF) | (id << 8));
}
-enum {
- kLeft = (1 << 0),
- kUp = (1 << 1),
- kRight = (1 << 2),
- kDown = (1 << 3)
-};
-
-int16 Map::getDirection(int16 x0, int16 y0, int16 x1, int16 y1) {
- int16 dir = 0;
-
+Direction Map::getDirection(int16 x0, int16 y0, int16 x1, int16 y1) {
if ((x0 == x1) && (y0 == y1))
- return 0;
+ // Already at the destination
+ return kDirNone;
if ((x1 < 0) || (x1 > _mapWidth) || (y1 < 0) || (y1 > _mapHeight))
- return 0;
+ // Destination out of range
+ return kDirNone;
+ RelativeDirection relDir = kRelDirNone;
+
+ // Find the direct direction we want to move
if (y1 > y0)
- dir |= kDown;
+ relDir = kRelDirDown;
else if (y1 < y0)
- dir |= kUp;
+ relDir = kRelDirUp;
if (x1 > x0)
- dir |= kRight;
+ relDir = (RelativeDirection)(relDir | kRelDirRight);
else if (x1 < x0)
- dir |= kLeft;
+ relDir = (RelativeDirection)(relDir | kRelDirLeft);
- if ((getPass(x0, y0) == 3) && (dir & kUp)) {
- if ((getPass(x0, y0 - 1) != 0))
- return kDirN;
- }
- if ((getPass(x0, y0) == 3) && (dir & kDown)) {
- if ((getPass(x0, y0 + 1) != 0))
- return kDirS;
- }
+ // Are we on ladders and can continue the ladder in the wanted direction?
+ if ((getPass(x0, y0) == 3) && (relDir & kRelDirUp ) && (getPass(x0, y0 - 1) != 0))
+ return kDirN;
- if ((getPass(x0, y0) == 6) && (dir & kUp)) {
- if ((getPass(x0, y0 - 1) != 0))
- return kDirN;
- }
+ if ((getPass(x0, y0) == 3) && (relDir & kRelDirDown) && (getPass(x0, y0 + 1) != 0))
+ return kDirS;
- if ((getPass(x0, y0) == 6) && (dir & kDown)) {
- if ((getPass(x0, y0 + 1) != 0))
- return kDirS;
- }
+ if ((getPass(x0, y0) == 6) && (relDir & kRelDirUp ) && (getPass(x0, y0 - 1) != 0))
+ return kDirN;
- if (dir == kLeft) {
- if (((x0 - 1) >= 0) && (getPass(x0 - 1, y0) != 0))
+ if ((getPass(x0, y0) == 6) && (relDir & kRelDirDown) && (getPass(x0, y0 + 1) != 0))
+ return kDirS;
+
+
+ // Want to go left
+ if (relDir == kRelDirLeft) {
+ if (getPass(x0 - 1, y0) != 0)
+ // Can go west
return kDirW;
- return 0;
+
+ // Can't go
+ return kDirNone;
}
- if (dir == kRight) {
- if (((x0 + 1) < _mapWidth) && (getPass(x0 + 1, y0) != 0))
+ // Want to go left
+ if (relDir == kRelDirRight) {
+ if (getPass(x0 + 1, y0) != 0)
+ // Can go east
return kDirE;
- return 0;
+
+ // Can't go
+ return kDirNone;
}
- if (dir == kUp) {
- if (((y0 - 1) >= 0) && (getPass(x0, y0 - 1) != 0))
+
+ // Want to go up
+ if (relDir == kRelDirUp) {
+ if (getPass(x0 , y0 - 1) != 0)
+ // Can go north
return kDirN;
- if (((y0 - 1) >= 0) && ((x0 - 1) >= 0) &&
- (getPass(x0 - 1, y0 - 1) != 0))
+ if (getPass(x0 - 1, y0 - 1) != 0)
+ // Can up north-west instead
return kDirNW;
- if (((y0 - 1) >= 0) && ((x0 + 1) < _mapWidth) &&
- (getPass(x0 + 1, y0 - 1) != 0))
+ if (getPass(x0 + 1, y0 - 1) != 0)
+ // Can up north-east instead
return kDirNE;
- return 0;
+ // Can't go at all
+ return kDirNone;
}
- if (dir == kDown) {
- if (((y0 + 1) < _mapHeight) && (getPass(x0, y0 + 1) != 0))
+ // Want to go down
+ if (relDir == kRelDirDown) {
+ if (getPass(x0 , y0 + 1) != 0)
+ // Can go south
return kDirS;
- if (((y0 + 1) < _mapHeight) && ((x0 - 1) >= 0) &&
- (getPass(x0 - 1, y0 + 1) != 0))
+ if (getPass(x0 - 1, y0 + 1) != 0)
+ // Can up south-west instead
return kDirSW;
- if (((y0 + 1) < _mapHeight) && ((x0 + 1) < _mapWidth) &&
- (getPass(x0 + 1, y0 + 1) != 0))
+ if (getPass(x0 + 1, y0 + 1) != 0)
+ // Can up south-east instead
return kDirSE;
- return 0;
+ // Can't go at all
+ return kDirNone;
}
- if (dir == (kRight | kUp)) {
- if (((y0 - 1) >= 0) && ((x0 + 1) < _mapWidth) &&
- (getPass(x0 + 1, y0 - 1) != 0))
+
+ // Want to go up and right
+ if (relDir == kRelDirRightUp) {
+ if (getPass(x0 + 1, y0 - 1) != 0)
+ // Can go north-east
return kDirNE;
- if (((y0 - 1) >= 0) && (getPass(x0, y0 - 1) != 0))
+ if (getPass(x0 , y0 - 1) != 0)
+ // Can only go north
return kDirN;
- if (((x0 + 1) < _mapWidth) && (getPass(x0 + 1, y0) != 0))
+ if (getPass(x0 + 1, y0 ) != 0)
+ // Can only go east
return kDirE;
- return 0;
+ // Can't go at all
+ return kDirNone;
}
- if (dir == (kRight | kDown)) {
- if (((x0 + 1) < _mapWidth) && ((y0 + 1) < _mapHeight) &&
- (getPass(x0 + 1, y0 + 1) != 0))
+ // Want to go down and right
+ if (relDir == kRelDirRightDown) {
+ if (getPass(x0 + 1, y0 + 1) != 0)
+ // Can go south-east
return kDirSE;
- if (((y0 + 1) < _mapHeight) && (getPass(x0, y0 + 1) != 0))
+ if (getPass(x0 , y0 + 1) != 0)
+ // Can only go south
return kDirS;
- if (((x0 + 1) < _mapWidth) && (getPass(x0 + 1, y0) != 0))
+ if (getPass(x0 + 1, y0 ) != 0)
+ // Can only go east
return kDirE;
- return 0;
+ // Can't go at all
+ return kDirNone;
}
- if (dir == (kLeft | kUp)) {
- if (((x0 - 1) >= 0) && ((y0 - 1) >= 0) &&
- (getPass(x0 - 1, y0 - 1) != 0))
+ // Want to go up and left
+ if (relDir == kRelDirLeftUp) {
+ if (getPass(x0 - 1, y0 - 1) != 0)
+ // Can go north-west
return kDirNW;
- if (((y0 - 1) >= 0) && (getPass(x0, y0 - 1) != 0))
+ if (getPass(x0 , y0 - 1) != 0)
+ // Can only go north
return kDirN;
- if (((x0 - 1) >= 0) && (getPass(x0 - 1, y0) != 0))
+ if (getPass(x0 - 1, y0 ) != 0)
+ // Can only go west
return kDirW;
- return 0;
+ // Can't go at all
+ return kDirNone;
}
- if (dir == (kLeft | kDown)) {
- if (((x0 - 1) >= 0) && ((y0 + 1) < _mapHeight) &&
- (getPass(x0 - 1, y0 + 1) != 0))
+ // Want to go left and down
+ if (relDir == kRelDirLeftDown) {
+ if (getPass(x0 - 1, y0 + 1) != 0)
+ // Can go south-west
return kDirSW;
- if (((y0 + 1) < _mapHeight) && (getPass(x0, y0 + 1) != 0))
+ if (getPass(x0 , y0 + 1) != 0)
+ // Can only go south
return kDirS;
- if (((x0 - 1) >= 0) && (getPass(x0 - 1, y0) != 0))
+ if (getPass(x0 - 1, y0 ) != 0)
+ // Can only go west
return kDirW;
- return 0;
+ // Can't go at all
+ return kDirNone;
}
- return -1;
+
+ warning("Map::getDirection(): Invalid direction?!?");
+ return kDirNone;
}
int16 Map::findNearestWayPoint(int16 x, int16 y) {
@@ -236,7 +349,7 @@ int16 Map::findNearestWayPoint(int16 x, int16 y) {
length = 30000;
- for (int i = 0; i < _wayPointsCount; i++) {
+ for (int i = 0; i < _wayPointCount; i++) {
if ((_wayPoints[i].x < 0) || (_wayPoints[i].x >= _mapWidth) ||
(_wayPoints[i].y < 0) || (_wayPoints[i].y >= _mapHeight))
break;
@@ -318,73 +431,81 @@ void Map::findNearestWalkable(int16 &gobDestX, int16 &gobDestY,
gobDestY -= distance;
}
-int16 Map::checkDirectPath(Mult::Mult_Object *obj,
- int16 x0, int16 y0, int16 x1, int16 y1) {
- uint16 dir;
+void Map::moveDirection(Direction dir, int16 &x, int16 &y) {
+ switch (dir) {
+ case kDirNW:
+ x--;
+ y--;
+ break;
+
+ case kDirN:
+ y--;
+ break;
+
+ case kDirNE:
+ x++;
+ y--;
+ break;
+
+ case kDirW:
+ x--;
+ break;
+
+ case kDirE:
+ x++;
+ break;
+
+ case kDirSW:
+ x--;
+ y++;
+ break;
+
+ case kDirS:
+ y++;
+ break;
+
+ case kDirSE:
+ x++;
+ y++;
+ break;
+
+ default:
+ break;
+ }
+}
+
+int16 Map::checkDirectPath(Mult::Mult_Object *obj, int16 x0, int16 y0, int16 x1, int16 y1) {
while (1) {
- dir = getDirection(x0, y0, x1, y1);
+ Direction dir = getDirection(x0, y0, x1, y1);
if (obj) {
- if (obj->nearestWayPoint < obj->nearestDest) {
- if (_wayPoints[obj->nearestWayPoint + 1].notWalkable == 1)
- return 3;
- } else if (obj->nearestWayPoint > obj->nearestDest) {
- if (obj->nearestDest > 0)
- if (_wayPoints[obj->nearestDest - 1].notWalkable == 1)
+ // Check for a blocking waypoint
+
+ if (obj->nearestWayPoint < obj->nearestDest)
+ if ((obj->nearestWayPoint + 1) < _wayPointCount)
+ if (_wayPoints[obj->nearestWayPoint + 1].notWalkable == 1)
+ return 3;
+
+ if (obj->nearestWayPoint > obj->nearestDest)
+ if (obj->nearestWayPoint > 0)
+ if (_wayPoints[obj->nearestWayPoint - 1].notWalkable == 1)
return 3;
- }
}
if ((x0 == x1) && (y0 == y1))
+ // Successfully reached the destination
return 1;
- if (dir == 0)
+ if (dir == kDirNone)
+ // No way
return 3;
- switch (dir) {
- case kDirNW:
- x0--;
- y0--;
- break;
-
- case kDirN:
- y0--;
- break;
-
- case kDirNE:
- x0++;
- y0--;
- break;
-
- case kDirW:
- x0--;
- break;
-
- case kDirE:
- x0++;
- break;
-
- case kDirSW:
- x0--;
- y0++;
- break;
-
- case kDirS:
- y0++;
- break;
-
- case kDirSE:
- x0++;
- y0++;
- break;
- }
+ moveDirection(dir, x0, y0);
}
}
-int16 Map::checkLongPath(int16 x0, int16 y0,
- int16 x1, int16 y1, int16 i0, int16 i1) {
- uint16 dir = 0;
+int16 Map::checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16 i1) {
int16 curX = x0;
int16 curY = y0;
int16 nextLink = 1;
@@ -417,47 +538,13 @@ int16 Map::checkLongPath(int16 x0, int16 y0,
return 1;
return 0;
}
- dir = getDirection(x0, y0, curX, curY);
- switch (dir) {
- case 0:
- return 0;
-
- case kDirNW:
- x0--;
- y0--;
- break;
- case kDirN:
- y0--;
- break;
-
- case kDirNE:
- x0++;
- y0--;
- break;
-
- case kDirW:
- x0--;
- break;
-
- case kDirE:
- x0++;
- break;
-
- case kDirSW:
- x0--;
- y0++;
- break;
-
- case kDirS:
- y0++;
- break;
+ Direction dir = getDirection(x0, y0, curX, curY);
+ if (dir == kDirNone)
+ // No way
+ return 0;
- case kDirSE:
- x0++;
- y0++;
- break;
- }
+ moveDirection(dir, x0, y0);
}
}