aboutsummaryrefslogtreecommitdiff
path: root/engines/gob/goblin_v2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob/goblin_v2.cpp')
-rw-r--r--engines/gob/goblin_v2.cpp419
1 files changed, 409 insertions, 10 deletions
diff --git a/engines/gob/goblin_v2.cpp b/engines/gob/goblin_v2.cpp
index 9c4befc5cc..ab35e979dd 100644
--- a/engines/gob/goblin_v2.cpp
+++ b/engines/gob/goblin_v2.cpp
@@ -35,6 +35,10 @@ namespace Gob {
Goblin_v2::Goblin_v2(GobEngine *vm) : Goblin_v1(vm) {
_gobsCount = -1;
+ _rotStates[0][0] = 0; _rotStates[0][1] = 18; _rotStates[0][2] = 19; _rotStates[0][3] = 20;
+ _rotStates[1][0] = 13; _rotStates[1][1] = 2; _rotStates[1][2] = 12; _rotStates[1][3] = 14;
+ _rotStates[2][0] = 16; _rotStates[2][1] = 15; _rotStates[2][2] = 4; _rotStates[2][3] = 17;
+ _rotStates[3][0] = 23; _rotStates[3][1] = 21; _rotStates[3][2] = 22; _rotStates[3][3] = 6;
}
void Goblin_v2::freeObjects(void) {
@@ -101,26 +105,421 @@ void Goblin_v2::placeObject(Gob_Object *objDesc, char animated,
*obj->pPosY = ((y + 1) / 2) * _vm->_map->_tilesHeight
- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
*obj->pPosX = x * _vm->_map->_tilesWidth;
- initiateMove(index);
+ initiateMove(obj);
} else
- initiateMove(index);
+ initiateMove(obj);
}
}
-void Goblin_v2::initiateMove(int16 index) {
- Mult::Mult_Object *obj = &_vm->_mult->_objects[index];
-
+void Goblin_v2::initiateMove(Mult::Mult_Object *obj) {
obj->destX = obj->gobDestX;
obj->destY = obj->gobDestY;
- _vm->_map->findNearestToDest(index);
- _vm->_map->findNearestToGob(index);
- _vm->_map->optimizePoints(index, obj->goblinX, obj->goblinY);
- obj->pAnimData->field_12 = _vm->_map->checkDirectPath(index,
+ _vm->_map->findNearestToDest(obj);
+ _vm->_map->findNearestToGob(obj);
+ _vm->_map->optimizePoints(obj, obj->goblinX, obj->goblinY);
+ obj->pAnimData->pathExistence = _vm->_map->checkDirectPath(obj,
obj->goblinX, obj->goblinY, obj->gobDestX, obj->gobDestY);
- if (obj->pAnimData->field_12 == 3) {
+ if (obj->pAnimData->pathExistence == 3) {
obj->destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x;
obj->destY = _vm->_map->_wayPoints[obj->nearestWayPoint].y;
}
}
+void Goblin_v2::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct) {
+ Mult::Mult_AnimData *animData;
+ int16 framesCount;
+ int16 gobX;
+ int16 gobY;
+ int16 gobDestX;
+ int16 gobDestY;
+ int16 destX;
+ int16 destY;
+ int16 dir;
+
+ dir = 0;
+ animData = obj->pAnimData;
+ framesCount =
+ _vm->_scenery->_animations[(int)animData->animation].layers[animData->layer]->framesCount;
+ gobX = obj->goblinX;
+ gobY = obj->goblinY;
+ animData->order = gobY;
+ gobDestX = obj->gobDestX;
+ gobDestY = obj->gobDestY;
+ animData->field_13 = gobDestX;
+ animData->field_14 = gobDestY;
+ destX = obj->destX;
+ destY = obj->destY;
+
+ if (animData->pathExistence == 1) {
+ dir = _vm->_map->getDirection(gobX, gobY, destX, destY);
+ if (dir == 0)
+ animData->pathExistence = 0;
+ if ((gobX == destX) && (gobY == destY))
+ animData->pathExistence = 4;
+ } else if (animData->pathExistence == 3) {
+ if ((gobX == gobDestX) && (gobY == gobDestY)) {
+ animData->pathExistence = 4;
+ destX = gobDestX;
+ destY = gobDestY;
+ } else {
+ if (_vm->_map->checkDirectPath(obj, gobX, gobY, gobDestX, gobDestY) != 1) {
+ if ((gobX == destX) && (gobY == destY)) {
+ if (obj->nearestWayPoint > obj->nearestDest) {
+ _vm->_map->optimizePoints(obj, gobX, gobY);
+ destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x;
+ destY = _vm->_map->_wayPoints[obj->nearestWayPoint].y;
+ if (_vm->_map->checkDirectPath(obj, gobX, gobY, destX, destY) == 3) {
+ WRITE_VAR(56, 1);
+ animData->pathExistence = 0;
+ }
+ if (obj->nearestWayPoint > obj->nearestDest)
+ obj->nearestWayPoint--;
+ } else if (obj->nearestWayPoint < obj->nearestDest) { // loc_10E96
+ _vm->_map->optimizePoints(obj, gobX, gobY);
+ destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x;
+ destY = _vm->_map->_wayPoints[obj->nearestWayPoint].y;
+ if (_vm->_map->checkDirectPath(obj, gobX, gobY, destX, destY) == 3) {
+ WRITE_VAR(56, 1);
+ animData->pathExistence = 0;
+ }
+ if (obj->nearestWayPoint < obj->nearestDest)
+ obj->nearestWayPoint++;
+ } else {
+ if ((_vm->_map->checkDirectPath(obj, gobX, gobY, gobDestX, gobDestY) == 3) &&
+ (_vm->_map->getPass(gobDestX, gobDestY) != 0)) {
+ destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x;
+ destY = _vm->_map->_wayPoints[obj->nearestWayPoint].y;
+ WRITE_VAR(56, 1);
+ } else {
+ animData->pathExistence = 1;
+ destX = gobDestX;
+ destY = gobDestY;
+ }
+ }
+ }
+ } else {
+ destX = gobDestX;
+ destY = gobDestY;
+ }
+ dir = _vm->_map->getDirection(gobX, gobY, destX, destY);
+ }
+ }
+
+ obj->goblinX = gobX;
+ obj->goblinY = gobY;
+ obj->gobDestX = gobDestX;
+ obj->gobDestY = gobDestY;
+ obj->destX = destX;
+ obj->destY = destY;
+
+ switch (dir) {
+ case Map::kDirNW:
+ animData->nextState = 1;
+ if (_vm->_map->_screenWidth == 640) {
+ if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
+ animData->nextState = 40;
+ if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY - 2) != 10)
+ animData->nextState = 1;
+ }
+ break;
+
+ case Map::kDirN:
+ animData->nextState = animData->curLookDir == 2 ? 2 : rotateState(2, animData->curLookDir);
+ if (_vm->_map->_screenWidth == 640) {
+ if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10) {
+ if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY - 2) != 10) {
+ if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY - 2) == 10)
+ animData->nextState = 42;
+ else
+ animData->nextState = 2;
+ } else
+ animData->nextState = 40;
+ } else if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 20)
+ animData->nextState = 38;
+ else if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 19)
+ animData->nextState = 26;
+ }
+ break;
+
+ case Map::kDirNE:
+ animData->nextState = 3;
+ if (_vm->_map->_screenWidth == 640) {
+ if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
+ animData->nextState = 42;
+ if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY - 2) != 10)
+ animData->nextState = 3;
+ }
+ break;
+
+ case Map::kDirW:
+ animData->nextState = rotateState(0, animData->curLookDir);
+ break;
+
+ case Map::kDirE:
+ animData->nextState = rotateState(4, animData->curLookDir);
+ break;
+
+ case Map::kDirSW:
+ animData->nextState = 7;
+ if (_vm->_map->_screenWidth == 640) {
+ if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
+ animData->nextState = 41;
+ if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY) != 10)
+ animData->nextState = 7;
+ }
+ break;
+
+ case Map::kDirS:
+ animData->nextState = animData->curLookDir == 6 ? 6 : rotateState(6, animData->curLookDir);
+ if (_vm->_map->_screenWidth == 640) {
+ if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 20)
+ animData->nextState = 39;
+ else if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 19)
+ animData->nextState = 27;
+ }
+ break;
+
+ case Map::kDirSE:
+ animData->nextState = 5;
+ if (_vm->_map->_screenWidth == 640) {
+ if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
+ animData->nextState = 43;
+ if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY) != 10)
+ animData->nextState = 5;
+ }
+ break;
+
+ default:
+ if (animData->curLookDir == 0)
+ animData->nextState = 8;
+ else if (animData->curLookDir == 2)
+ animData->nextState = 29;
+ else if (animData->curLookDir == 4)
+ animData->nextState = 9;
+ else if (animData->curLookDir == 6)
+ animData->nextState = 28;
+ break;
+ }
+}
+
+void Goblin_v2::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc,
+ int16 nextAct, int16 framesCount) {
+ Mult::Mult_AnimData *animData;
+ int16 gobX;
+ int16 gobY;
+ int16 animation;
+ int16 state;
+ int16 layer;
+
+ movePathFind(obj, 0, 0);
+ playSounds(obj);
+
+ animData = obj->pAnimData;
+
+ framesCount =
+ _vm->_scenery->_animations[(int)animData->animation].layers[animData->layer]->framesCount;
+
+ if (animData->isPaused == 0)
+ animData->frame++;
+
+ switch (animData->field_16) {
+ case 0:
+ case 1:
+ animData->isPaused = 0;
+ break;
+
+ case 4:
+ if (animData->frame == 0)
+ animData->isPaused = 1;
+ break;
+
+ case 6:
+ if (animData->frame >= framesCount)
+ animData->isPaused = 1;
+ break;
+ }
+
+ switch(animData->state) {
+ case 0:
+ case 1:
+ case 7:
+ case 13:
+ case 16:
+ case 23:
+ // loc_11452
+ animData->curLookDir = 0;
+ break;
+
+ case 2:
+ case 15:
+ case 18:
+ case 21:
+ animData->curLookDir = 2;
+ break;
+
+ case 3:
+ case 4:
+ case 5:
+ case 12:
+ case 19:
+ case 22:
+ animData->curLookDir = 4;
+ break;
+
+ case 6:
+ case 14:
+ case 17:
+ case 20:
+ animData->curLookDir = 6;
+ break;
+
+ case 8:
+ case 9:
+ case 28:
+ case 29:
+ if (animData->pathExistence == 4)
+ animData->pathExistence = 5;
+ break;
+ }
+
+ if ((animData->field_F != -1) && (animData->frame == framesCount) &&
+ (animData->field_F != animData->state)) { // loc_114B6
+ animData->nextState = animData->field_F;
+ animData->field_F = -1;
+ animData->state = animData->nextState;
+ *obj->pPosX +=
+ _vm->_scenery->_animations[animData->animation].layers[animData->layer]->animDeltaX;
+ *obj->pPosY +=
+ _vm->_scenery->_animations[animData->animation].layers[animData->layer]->animDeltaY;
+ animation = obj->goblinStates[animData->nextState][0].animation;
+ layer = obj->goblinStates[animData->nextState][0].layer;
+ animData->layer = layer;
+ animData->animation = animation;
+ animData->frame = 0;
+ } else {
+ if (((animData->state >= 0) && (animData->state < 8)) ||
+ (animData->state == 38) || (animData->state == 39)) { // loc_115C4
+ state = animData->nextState;
+ if (animData->frame == ((framesCount + 1) / 2)) {
+ gobX = obj->goblinX;
+ gobY = obj->goblinY;
+ switch (state) {
+ case 0:
+ obj->goblinX--;
+ break;
+
+ case 1:
+ obj->goblinX--;
+ obj->goblinY--;
+ break;
+
+ case 2:
+ case 38:
+ obj->goblinY--;
+ break;
+
+ case 3:
+ obj->goblinX++;
+ obj->goblinY--;
+ break;
+
+ case 4:
+ obj->goblinX++;
+ break;
+
+ case 5:
+ obj->goblinX++;
+ obj->goblinY++;
+ break;
+
+ case 6:
+ case 39:
+ obj->goblinY++;
+ break;
+
+ case 7:
+ obj->goblinX--;
+ obj->goblinY++;
+ break;
+ }
+ if (animData->state != state) {
+ animation = obj->goblinStates[state][0].animation;
+ layer = obj->goblinStates[state][0].layer;
+ animData->layer = layer;
+ animData->animation = animation;
+ animData->frame = 0;
+ animData->state = state;
+ _vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0);
+ if (_vm->_map->_bigTiles)
+ *obj->pPosY = ((gobY + 1) * _vm->_map->_tilesHeight) -
+ (_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - (gobY + 1) / 2;
+ else
+ *obj->pPosY = ((gobY + 1) * _vm->_map->_tilesHeight) -
+ (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
+ *obj->pPosX = gobX * _vm->_map->_tilesWidth;
+ }
+ }
+ }
+
+ if (animData->frame >= framesCount) {
+ state = animData->nextState;
+ animation = obj->goblinStates[state][0].animation;
+ layer = obj->goblinStates[state][0].layer;
+ animData->layer = layer;
+ animData->animation = animation;
+ animData->frame = 0;
+ animData->state = state;
+ gobX = obj->goblinX;
+ gobY = obj->goblinY;
+ switch (state) {
+ case 0:
+ obj->goblinX--;
+ break;
+
+ case 1:
+ obj->goblinX--;
+ obj->goblinY--;
+ break;
+
+ case 2:
+ case 38:
+ obj->goblinY--;
+ break;
+
+ case 3:
+ obj->goblinX++;
+ obj->goblinY--;
+ break;
+
+ case 4:
+ obj->goblinX++;
+ break;
+
+ case 5:
+ obj->goblinX++;
+ obj->goblinY++;
+ break;
+
+ case 6:
+ case 39:
+ obj->goblinY++;
+ break;
+
+ case 7:
+ obj->goblinX--;
+ obj->goblinY++;
+ break;
+ }
+ _vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0);
+ if (_vm->_map->_bigTiles)
+ *obj->pPosY = ((gobY + 1) * _vm->_map->_tilesHeight) -
+ (_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - (gobY + 1) / 2;
+ else
+ *obj->pPosY = ((gobY + 1) * _vm->_map->_tilesHeight) -
+ (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
+ *obj->pPosX = gobX * _vm->_map->_tilesWidth;
+ }
+ }
+}
+
} // End of namespace Gob