aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/goblin.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob/goblin.cpp')
-rw-r--r--engines/gob/goblin.cpp142
1 files changed, 86 insertions, 56 deletions
diff --git a/engines/gob/goblin.cpp b/engines/gob/goblin.cpp
index ee2b4f52c9..402b33d5fd 100644
--- a/engines/gob/goblin.cpp
+++ b/engines/gob/goblin.cpp
@@ -23,9 +23,10 @@
*
*/
+#include "common/str.h"
+
#include "gob/gob.h"
#include "gob/goblin.h"
-#include "gob/helper.h"
#include "gob/global.h"
#include "gob/util.h"
#include "gob/draw.h"
@@ -668,11 +669,11 @@ void Goblin::adjustDest(int16 posX, int16 posY) {
resDelta = i;
}
- for (i = 1; ((i + _pressedMapX) < _vm->_map->_mapWidth) &&
+ for (i = 1; ((i + _pressedMapX) < _vm->_map->getMapWidth()) &&
(_vm->_map->getPass(_pressedMapX + i, _pressedMapY) == 0); i++)
;
- if ((_pressedMapX + i) < _vm->_map->_mapWidth) {
+ if ((_pressedMapX + i) < _vm->_map->getMapWidth()) {
deltaPix = (i * 12) - (posX % 12);
if ((resDelta == -1) || (deltaPix < resDeltaPix)) {
resDeltaPix = deltaPix;
@@ -681,11 +682,11 @@ void Goblin::adjustDest(int16 posX, int16 posY) {
}
}
- for (i = 1; ((i + _pressedMapY) < _vm->_map->_mapHeight) &&
+ for (i = 1; ((i + _pressedMapY) < _vm->_map->getMapHeight()) &&
(_vm->_map->getPass(_pressedMapX, _pressedMapY + i) == 0); i++)
;
- if ((_pressedMapY + i) < _vm->_map->_mapHeight) {
+ if ((_pressedMapY + i) < _vm->_map->getMapHeight()) {
deltaPix = (i * 6) - (posY % 6);
if ((resDelta == -1) || (deltaPix < resDeltaPix)) {
resDeltaPix = deltaPix;
@@ -726,8 +727,8 @@ void Goblin::adjustDest(int16 posX, int16 posY) {
}
}
- _pressedMapX = CLIP((int) _pressedMapX, 0, _vm->_map->_mapWidth - 1);
- _pressedMapY = CLIP((int) _pressedMapY, 0, _vm->_map->_mapHeight - 1);
+ _pressedMapX = CLIP((int) _pressedMapX, 0, _vm->_map->getMapWidth() - 1);
+ _pressedMapY = CLIP((int) _pressedMapY, 0, _vm->_map->getMapHeight() - 1);
}
void Goblin::adjustTarget() {
@@ -737,18 +738,18 @@ void Goblin::adjustTarget() {
if ((_pressedMapY > 0) &&
(_vm->_map->getItem(_pressedMapX, _pressedMapY - 1) != 0)) {
_pressedMapY--;
- } else if ((_pressedMapX < (_vm->_map->_mapWidth - 1)) &&
+ } else if ((_pressedMapX < (_vm->_map->getMapWidth() - 1)) &&
(_vm->_map->getItem(_pressedMapX + 1, _pressedMapY) != 0)) {
_pressedMapX++;
- } else if ((_pressedMapX < (_vm->_map->_mapWidth - 1)) &&
+ } else if ((_pressedMapX < (_vm->_map->getMapWidth() - 1)) &&
(_pressedMapY > 0) &&
(_vm->_map->getItem(_pressedMapX + 1, _pressedMapY - 1) != 0)) {
_pressedMapY--;
_pressedMapX++;
}
}
- _pressedMapX = CLIP((int) _pressedMapX, 0, _vm->_map->_mapWidth - 1);
- _pressedMapY = CLIP((int) _pressedMapY, 0, _vm->_map->_mapHeight - 1);
+ _pressedMapX = CLIP((int) _pressedMapX, 0, _vm->_map->getMapWidth() - 1);
+ _pressedMapY = CLIP((int) _pressedMapY, 0, _vm->_map->getMapHeight() - 1);
}
void Goblin::targetDummyItem(Gob_Object *gobDesc) {
@@ -847,7 +848,7 @@ void Goblin::targetItem() {
}
}
- if (_pressedMapY < (_vm->_map->_mapHeight-1)) {
+ if (_pressedMapY < (_vm->_map->getMapHeight()-1)) {
if ((_vm->_map->getItem(_pressedMapX, _pressedMapY + 1)) ==
(_vm->_map->getItem(_pressedMapX, _pressedMapY))) {
_pressedMapY++;
@@ -898,8 +899,8 @@ void Goblin::targetItem() {
}
}
}
- _pressedMapX = CLIP((int) _pressedMapX, 0, _vm->_map->_mapWidth - 1);
- _pressedMapY = CLIP((int) _pressedMapY, 0, _vm->_map->_mapHeight - 1);
+ _pressedMapX = CLIP((int) _pressedMapX, 0, _vm->_map->getMapWidth() - 1);
+ _pressedMapY = CLIP((int) _pressedMapY, 0, _vm->_map->getMapHeight() - 1);
}
void Goblin::moveFindItem(int16 posX, int16 posY) {
@@ -933,23 +934,23 @@ void Goblin::moveFindItem(int16 posX, int16 posY) {
break;
}
- _pressedMapX = CLIP(posX / 12, 0, _vm->_map->_mapWidth - 1);
- _pressedMapY = CLIP(posY / 6, 0, _vm->_map->_mapHeight - 1);
+ _pressedMapX = CLIP(posX / 12, 0, _vm->_map->getMapWidth() - 1);
+ _pressedMapY = CLIP(posY / 6, 0, _vm->_map->getMapHeight() - 1);
if ((_vm->_map->getItem(_pressedMapX, _pressedMapY) == 0) && (i < 20)) {
- if ((_pressedMapY < (_vm->_map->_mapHeight - 1)) &&
+ if ((_pressedMapY < (_vm->_map->getMapHeight() - 1)) &&
(_vm->_map->getItem(_pressedMapX, _pressedMapY + 1) != 0)) {
_pressedMapY++;
- } else if ((_pressedMapX < (_vm->_map->_mapWidth - 1)) &&
- (_pressedMapY < (_vm->_map->_mapHeight - 1)) &&
+ } else if ((_pressedMapX < (_vm->_map->getMapWidth() - 1)) &&
+ (_pressedMapY < (_vm->_map->getMapHeight() - 1)) &&
(_vm->_map->getItem(_pressedMapX + 1, _pressedMapY + 1) != 0)) {
_pressedMapX++;
_pressedMapY++;
- } else if ((_pressedMapX < (_vm->_map->_mapWidth - 1)) &&
+ } else if ((_pressedMapX < (_vm->_map->getMapWidth() - 1)) &&
(_vm->_map->getItem(_pressedMapX + 1, _pressedMapY) != 0)) {
_pressedMapX++;
- } else if ((_pressedMapX < (_vm->_map->_mapWidth - 1)) &&
+ } else if ((_pressedMapX < (_vm->_map->getMapWidth() - 1)) &&
(_pressedMapY > 0) &&
(_vm->_map->getItem(_pressedMapX + 1, _pressedMapY - 1) != 0)) {
_pressedMapX++;
@@ -965,15 +966,15 @@ void Goblin::moveFindItem(int16 posX, int16 posY) {
(_vm->_map->getItem(_pressedMapX - 1, _pressedMapY) != 0)) {
_pressedMapX--;
} else if ((_pressedMapX > 0) &&
- (_pressedMapY < (_vm->_map->_mapHeight - 1)) &&
+ (_pressedMapY < (_vm->_map->getMapHeight() - 1)) &&
(_vm->_map->getItem(_pressedMapX - 1, _pressedMapY + 1) != 0)) {
_pressedMapX--;
_pressedMapY++;
}
}
} else {
- _pressedMapX = CLIP(posX / 12, 0, _vm->_map->_mapWidth - 1);
- _pressedMapY = CLIP(posY / 6, 0, _vm->_map->_mapHeight - 1);
+ _pressedMapX = CLIP(posX / 12, 0, _vm->_map->getMapWidth() - 1);
+ _pressedMapY = CLIP(posY / 6, 0, _vm->_map->getMapHeight() - 1);
}
}
@@ -1186,7 +1187,7 @@ void Goblin::loadObjects(const char *source) {
freeObjects();
initList();
- strncpy0(_vm->_map->_sourceFile, source, 14);
+ Common::strlcpy(_vm->_map->_sourceFile, source, 15);
_vm->_map->_sourceFile[strlen(_vm->_map->_sourceFile) - 4] = 0;
_vm->_map->loadMapObjects(source);
@@ -1386,8 +1387,8 @@ void Goblin::pickItem(int16 indexToPocket, int16 idToPocket) {
_itemIndInPocket = indexToPocket;
_itemIdInPocket = idToPocket;
- for (int y = 0; y < _vm->_map->_mapHeight; y++) {
- for (int x = 0; x < _vm->_map->_mapWidth; x++) {
+ for (int y = 0; y < _vm->_map->getMapHeight(); y++) {
+ for (int x = 0; x < _vm->_map->getMapWidth(); x++) {
if (_itemByteFlag == 1) {
if (((_vm->_map->getItem(x, y) & 0xFF00) >> 8) == idToPocket)
_vm->_map->setItem(x, y, _vm->_map->getItem(x, y) & 0xFF);
@@ -1450,7 +1451,7 @@ void Goblin::placeItem(int16 indexInPocket, int16 idInPocket) {
_vm->_map->placeItem(xPos, yPos - 1, idInPocket);
if (lookDir == 4) {
- if (xPos < _vm->_map->_mapWidth - 1) {
+ if (xPos < _vm->_map->getMapWidth() - 1) {
_vm->_map->placeItem(xPos + 1, yPos, idInPocket);
if (yPos > 0)
@@ -1497,16 +1498,16 @@ void Goblin::swapItems(int16 indexToPick, int16 idToPick) {
_itemIdInPocket = idToPick;
if (_itemByteFlag == 0) {
- for (y = 0; y < _vm->_map->_mapHeight; y++) {
- for (x = 0; x < _vm->_map->_mapWidth; x++) {
+ for (y = 0; y < _vm->_map->getMapHeight(); y++) {
+ for (x = 0; x < _vm->_map->getMapWidth(); x++) {
if ((_vm->_map->getItem(x, y) & 0xFF) == idToPick)
_vm->_map->setItem(x, y, (_vm->_map->getItem(x, y) & 0xFF00) + idToPlace);
}
}
} else {
- for (y = 0; y < _vm->_map->_mapHeight; y++) {
- for (x = 0; x < _vm->_map->_mapWidth; x++) {
+ for (y = 0; y < _vm->_map->getMapHeight(); y++) {
+ for (x = 0; x < _vm->_map->getMapWidth(); x++) {
if (((_vm->_map->getItem(x, y) & 0xFF00) >> 8) == idToPick)
_vm->_map->setItem(x, y, (_vm->_map->getItem(x, y) & 0xFF) + (idToPlace << 8));
}
@@ -1704,15 +1705,15 @@ void Goblin::setState(int16 index, int16 state) {
animData->newCycle = _vm->_scenery->getAnimLayer(animation, layer)->framesCount;
_vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 1);
- if (_vm->_map->_bigTiles) {
- *obj->pPosY = ((obj->goblinY + 1) * _vm->_map->_tilesHeight) -
+ if (_vm->_map->hasBigTiles()) {
+ *obj->pPosY = ((obj->goblinY + 1) * _vm->_map->getTilesHeight()) -
(_vm->_scenery->_animBottom - _vm->_scenery->_animTop) -
(obj->goblinY + 1) / 2;
} else {
- *obj->pPosY = (obj->goblinY + 1) * _vm->_map->_tilesHeight -
+ *obj->pPosY = (obj->goblinY + 1) * _vm->_map->getTilesHeight() -
(_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
}
- *obj->pPosX = obj->goblinX * _vm->_map->_tilesWidth;
+ *obj->pPosX = obj->goblinX * _vm->_map->getTilesWidth();
}
void Goblin::animate(Mult::Mult_Object *obj) {
@@ -1780,40 +1781,69 @@ void Goblin::animate(Mult::Mult_Object *obj) {
}
void Goblin::move(int16 destX, int16 destY, int16 objIndex) {
- Mult::Mult_Object *obj;
- Mult::Mult_AnimData *animData;
- int16 mouseX;
- int16 mouseY;
- int16 gobDestX;
- int16 gobDestY;
- obj = &_vm->_mult->_objects[objIndex];
- animData = obj->pAnimData;
+ Mult::Mult_Object *obj = &_vm->_mult->_objects[objIndex];
+ Mult::Mult_AnimData *animData = obj->pAnimData;
- obj->gobDestX = destX;
- obj->gobDestY = destY;
+ obj->gobDestX = destX;
+ obj->gobDestY = destY;
animData->destX = destX;
animData->destY = destY;
if (animData->isBusy != 0) {
if ((destX == -1) && (destY == -1)) {
- mouseX = _vm->_global->_inter_mouseX;
- mouseY = _vm->_global->_inter_mouseY;
- if (_vm->_map->_bigTiles)
- mouseY += ((_vm->_global->_inter_mouseY / _vm->_map->_tilesHeight) + 1) / 2;
+ int16 mouseX = _vm->_global->_inter_mouseX;
+ int16 mouseY = _vm->_global->_inter_mouseY;
+
+ if (_vm->_map->hasBigTiles())
+ mouseY += ((_vm->_global->_inter_mouseY / _vm->_map->getTilesHeight()) + 1) / 2;
- gobDestX = mouseX / _vm->_map->_tilesWidth;
- gobDestY = mouseY / _vm->_map->_tilesHeight;
+ int16 gobDestX = mouseX / _vm->_map->getTilesWidth();
+ int16 gobDestY = mouseY / _vm->_map->getTilesHeight();
if (_vm->_map->getPass(gobDestX, gobDestY) == 0)
_vm->_map->findNearestWalkable(gobDestX, gobDestY, mouseX, mouseY);
- animData->destX = obj->gobDestX =
- (gobDestX == -1) ? obj->goblinX : gobDestX;
- animData->destY = obj->gobDestY =
- (gobDestY == -1) ? obj->goblinY : gobDestY;
+ obj->gobDestX = (gobDestX == -1) ? obj->goblinX : gobDestX;
+ obj->gobDestY = (gobDestY == -1) ? obj->goblinY : gobDestY;
+
+ animData->destX = obj->gobDestX;
+ animData->destY = obj->gobDestY;
+ }
+ }
+
+ WRITE_VAR(56, 0);
+
+ byte passType = _vm->_map->getPass(obj->gobDestX, obj->gobDestY);
+
+ // Prevent continuous walking on wide stairs
+ if (passType == 11) {
+ if (_vm->_map->getScreenWidth() == 640) {
+ obj->gobDestY++;
+ animData->destY++;
}
}
+
+ // Prevent stopping in the middle of big ladders
+ if ((passType == 19) || (passType == 20)) {
+ int ladderTop = 0;
+ while (_vm->_map->getPass(obj->gobDestX, obj->gobDestY + ladderTop) == passType)
+ ladderTop++;
+
+ int ladderBottom = 0;
+ while (_vm->_map->getPass(obj->gobDestX, obj->gobDestY + ladderBottom) == passType)
+ ladderBottom--;
+
+ int ladderDest;
+ if (ABS(ladderBottom) <= ladderTop)
+ ladderDest = obj->gobDestY + ladderBottom;
+ else
+ ladderDest = obj->gobDestY + ladderTop;
+
+ obj->gobDestY = ladderDest;
+ animData->destY = ladderDest;
+ }
+
initiateMove(obj);
}