aboutsummaryrefslogtreecommitdiff
path: root/engines/gob
diff options
context:
space:
mode:
Diffstat (limited to 'engines/gob')
-rw-r--r--engines/gob/goblin.cpp722
-rw-r--r--engines/gob/goblin.h33
-rw-r--r--engines/gob/goblin_v1.cpp555
-rw-r--r--engines/gob/goblin_v2.cpp419
-rw-r--r--engines/gob/inter_v2.cpp112
-rw-r--r--engines/gob/map.cpp10
-rw-r--r--engines/gob/map.h21
-rw-r--r--engines/gob/map_v1.cpp10
-rw-r--r--engines/gob/map_v2.cpp39
-rw-r--r--engines/gob/mult.h48
-rw-r--r--engines/gob/mult_v2.cpp66
11 files changed, 1355 insertions, 680 deletions
diff --git a/engines/gob/goblin.cpp b/engines/gob/goblin.cpp
index 24eb64e85e..9794ca9b07 100644
--- a/engines/gob/goblin.cpp
+++ b/engines/gob/goblin.cpp
@@ -61,11 +61,6 @@ Goblin::Goblin(GobEngine *vm) : _vm(vm) {
_forceNextState[8] = 0;
_forceNextState[9] = 0;
- _rotStates[0][0] = 0; _rotStates[0][1] = 22; _rotStates[0][2] = 23; _rotStates[0][3] = 24;
- _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] = 27; _rotStates[3][1] = 25; _rotStates[3][2] = 26; _rotStates[3][3] = 6;
-
_boreCounter = 0;
_positionedGob = 5;
@@ -1220,552 +1215,6 @@ void Goblin::moveTreatRopeStairs(Gob_Object *gobDesc) {
}
-void Goblin::movePathFind(Gob_Object *gobDesc, int16 nextAct) {
- if (_pathExistence == 1) {
- _vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
- _vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
-
- if (_vm->_map->_curGoblinX == _pressedMapX &&
- _vm->_map->_curGoblinY == _pressedMapY && _gobAction != 0) {
- _readyToAct = 1;
- _pathExistence = 0;
- }
-
- nextAct = _vm->_map->getDirection(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
- _vm->_map->_destX, _vm->_map->_destY);
-
- if (nextAct == 0)
- _pathExistence = 0;
- } else if (_pathExistence == 3) {
- _vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
- _vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
-
- if (_vm->_map->_curGoblinX == _gobDestX && _vm->_map->_curGoblinY == _gobDestY) {
- _pathExistence = 1;
- _vm->_map->_destX = _pressedMapX;
- _vm->_map->_destY = _pressedMapY;
- } else {
-
- if (_vm->_map->checkDirectPath(-1, _vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
- _gobDestX, _gobDestY) == 1) {
- _vm->_map->_destX = _gobDestX;
- _vm->_map->_destY = _gobDestY;
- } else if (_vm->_map->_curGoblinX == _vm->_map->_destX && _vm->_map->_curGoblinY == _vm->_map->_destY) {
-
- if (_vm->_map->_nearestWayPoint > _vm->_map->_nearestDest) {
- _vm->_map->optimizePoints(0, 0, 0);
-
- _vm->_map->_destX =
- _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
- x;
- _vm->_map->_destY =
- _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
- y;
-
- if (_vm->_map->_nearestWayPoint > _vm->_map->_nearestDest)
- _vm->_map->_nearestWayPoint--;
- } else if (_vm->_map->_nearestWayPoint < _vm->_map->_nearestDest) {
- _vm->_map->optimizePoints(0, 0, 0);
-
- _vm->_map->_destX =
- _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
- x;
- _vm->_map->_destY =
- _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
- y;
-
- if (_vm->_map->_nearestWayPoint < _vm->_map->_nearestDest)
- _vm->_map->_nearestWayPoint++;
- } else {
- if (_vm->_map->checkDirectPath(-1, _vm->_map->_curGoblinX,
- _vm->_map->_curGoblinY, _gobDestX,
- _gobDestY) == 3 && _vm->_map->getPass(_pressedMapX, _pressedMapY) != 0) {
- _vm->_map->_destX = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].x;
- _vm->_map->_destY = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].y;
- } else {
- _pathExistence = 1;
- _vm->_map->_destX = _pressedMapX;
- _vm->_map->_destY = _pressedMapY;
- }
- }
- }
- nextAct =
- _vm->_map->getDirection(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
- _vm->_map->_destX, _vm->_map->_destY);
- }
- }
-
- if (_readyToAct != 0 && (_gobAction == 3 || _gobAction == 4))
- nextAct = 0x4dc8;
-
- switch (nextAct) {
- case Map::kDirW:
- gobDesc->nextState = rotateState(gobDesc->curLookDir, 0);
- break;
-
- case Map::kDirE:
- gobDesc->nextState = rotateState(gobDesc->curLookDir, 4);
- break;
-
- case 16:
- gobDesc->nextState = 16;
- break;
-
- case 23:
- gobDesc->nextState = 23;
- break;
-
- case Map::kDirN:
- if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6 &&
- _currentGoblin != 1) {
- _pathExistence = 0;
- break;
- }
-
- if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
- gobDesc->nextState = 8;
- break;
- }
-
- if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 &&
- _currentGoblin == 1) {
- gobDesc->nextState = 28;
- break;
- }
-
- gobDesc->nextState = rotateState(gobDesc->curLookDir, 2);
- break;
-
- case Map::kDirS:
- if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6 &&
- _currentGoblin != 1) {
- _pathExistence = 0;
- break;
- }
-
- if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
- gobDesc->nextState = 9;
- break;
- }
-
- if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 &&
- _currentGoblin == 1) {
- gobDesc->nextState = 29;
- break;
- }
-
- gobDesc->nextState = rotateState(gobDesc->curLookDir, 6);
- break;
-
- case Map::kDirSE:
- if (_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY + 1) == 6 &&
- _currentGoblin != 1) {
- _pathExistence = 0;
- break;
- }
-
- gobDesc->nextState = 5;
- if (gobDesc->curLookDir == 4)
- break;
-
- gobDesc->nextState = rotateState(gobDesc->curLookDir, 4);
- break;
-
- case Map::kDirSW:
- if (_vm->_map->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY + 1) == 6 &&
- _currentGoblin != 1) {
- _pathExistence = 0;
- break;
- }
-
- gobDesc->nextState = 7;
- if (gobDesc->curLookDir == 0)
- break;
-
- gobDesc->nextState = rotateState(gobDesc->curLookDir, 0);
- break;
-
- case Map::kDirNW:
- if (_vm->_map->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY - 1) == 6 &&
- _currentGoblin != 1) {
- _pathExistence = 0;
- break;
- }
-
- gobDesc->nextState = 1;
- if (gobDesc->curLookDir == 0)
- break;
-
- gobDesc->nextState = rotateState(gobDesc->curLookDir, 0);
- break;
-
- case Map::kDirNE:
- if (_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY - 1) == 6 &&
- _currentGoblin != 1) {
- _pathExistence = 0;
- break;
- }
-
- gobDesc->nextState = 3;
- if (gobDesc->curLookDir == 4)
- break;
-
- gobDesc->nextState = rotateState(gobDesc->curLookDir, 4);
- break;
-
- case 0x4dc8:
-
- if (_currentGoblin == 0 && _gobAction == 3
- && _itemIndInPocket == -1) {
- _destItemId = -1;
- _readyToAct = 0;
- break;
- }
-
- if (_currentGoblin == 0 && _gobAction == 4 &&
- _itemIndInPocket == -1 && _destActionItem == 0) {
- gobDesc->multState = 104;
- _destItemId = -1;
- _readyToAct = 0;
- break;
- }
-
- if (_currentGoblin == 0 && _gobAction == 4 &&
- _itemIndInPocket == -1 && _destActionItem != 0 &&
- _itemToObject[_destActionItem] != -1 &&
- _objects[_itemToObject[_destActionItem]]->
- pickable == 0) {
- gobDesc->multState = 104;
- _destItemId = -1;
- _readyToAct = 0;
- break;
- }
-
- switch (_vm->_map->_itemPoses[_destActionItem].orient) {
- case 0:
- case -4:
- gobDesc->nextState = 10;
- gobDesc->curLookDir = 0;
- _destItemId = -1;
- break;
-
- case -1:
- case 4:
- gobDesc->nextState = 11;
- gobDesc->curLookDir = 4;
- _destItemId = -1;
- break;
- }
- break;
-
- default:
- if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3 ||
- (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6
- && _currentGoblin == 1)) {
- gobDesc->nextState = 20;
- break;
- }
-
- switch (gobDesc->curLookDir) {
- case 2:
- case 4:
- gobDesc->nextState = 18;
- break;
-
- case 6:
- case 0:
- gobDesc->nextState = 19;
- break;
- }
- break;
- }
- return;
-}
-
-void Goblin::moveAdvance(Gob_Object *gobDesc, int16 nextAct, int16 framesCount) {
- int16 i;
- int16 newX;
- int16 newY;
- int16 flag;
-
- movePathFind(gobDesc, nextAct);
-
- gobDesc->curFrame++;
- if (gobDesc->curFrame == 1)
- gobDesc->actionStartState = gobDesc->state;
-
- if (_goesAtTarget == 0
- && gobDesc->stateMach == gobDesc->realStateMach) {
- switch (gobDesc->state) {
- case 0:
- case 1:
- case 7:
- case 13:
- case 16:
- case 27:
- gobDesc->curLookDir = 0;
- break;
-
- case 3:
- case 4:
- case 5:
- case 12:
- case 23:
- case 26:
- gobDesc->curLookDir = 4;
- break;
-
- case 28:
- if (_currentGoblin != 1)
- break;
- gobDesc->curLookDir = 2;
- break;
-
- case 2:
- case 8:
- case 15:
- case 22:
- case 25:
- gobDesc->curLookDir = 2;
- break;
-
- case 29:
- if (_currentGoblin != 1)
- break;
-
- gobDesc->curLookDir = 6;
- break;
-
- case 6:
- case 9:
- case 14:
- case 17:
- case 24:
- gobDesc->curLookDir = 6;
- break;
- }
- }
-
- if (gobDesc->state >= 0 && gobDesc->state < 10 &&
- gobDesc->stateMach == gobDesc->realStateMach &&
- (gobDesc->curFrame == 3 || gobDesc->curFrame == 6)) {
- _vm->_snd->speakerOn(10 * _vm->_util->getRandom(3) + 50, 5);
- }
-
- if (_currentGoblin == 0
- && gobDesc->stateMach == gobDesc->realStateMach
- && (gobDesc->state == 10 || gobDesc->state == 11)
- && gobDesc->curFrame == 9) {
- _vm->_snd->stopSound(0);
- if (_itemIndInPocket != -1) {
- _vm->_snd->playSample(_soundData[14], 1, 9000);
- }
-
- if (_itemIndInPocket == -1) {
- _vm->_snd->playSample(_soundData[14], 1, 5000);
- }
- }
-
- if (_boreCounter++ == 120) {
- _boreCounter = 0;
- for (i = 0; i < 3; i++)
- showBoredom(i);
- }
-
- if (gobDesc->multState != -1 && gobDesc->curFrame == framesCount &&
- gobDesc->state != gobDesc->multState) {
- gobDesc->nextState = gobDesc->multState;
- gobDesc->multState = -1;
-
- newX =
- _vm->_scenery->_animations[gobDesc->animation].
- layers[_gobStateLayer]->animDeltaX + gobDesc->xPos;
-
- newY =
- _vm->_scenery->_animations[gobDesc->animation].
- layers[_gobStateLayer]->animDeltaY + gobDesc->yPos;
-
- _gobStateLayer = nextLayer(gobDesc);
-
- gobDesc->xPos = newX;
- gobDesc->yPos = newY;
- } else {
- if (gobDesc->curFrame == 3 &&
- gobDesc->stateMach == gobDesc->realStateMach &&
- (gobDesc->state < 10 ||
- (_currentGoblin == 1 && (gobDesc->state == 28
- || gobDesc->state == 29))
- )) {
- flag = 0;
- if (_forceNextState[0] != -1) {
- gobDesc->nextState = _forceNextState[0];
- for (i = 0; i < 9; i++)
- _forceNextState[i] =
- _forceNextState[i + 1];
- }
-
- _vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
- _vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
-
- if (gobDesc->nextState != gobDesc->state) {
- _gobStateLayer = nextLayer(gobDesc);
- flag = 1;
- }
-
- switch (gobDesc->state) {
- case 0:
- _gobPositions[_currentGoblin].x--;
- break;
-
- case 2:
- case 8:
- _gobPositions[_currentGoblin].y--;
- break;
-
- case 4:
- _gobPositions[_currentGoblin].x++;
- break;
-
- case 6:
- case 9:
- _gobPositions[_currentGoblin].y++;
- break;
-
- case 1:
- _gobPositions[_currentGoblin].x--;
- _gobPositions[_currentGoblin].y--;
- break;
-
- case 3:
- _gobPositions[_currentGoblin].x++;
- _gobPositions[_currentGoblin].y--;
- break;
-
- case 5:
- _gobPositions[_currentGoblin].x++;
- _gobPositions[_currentGoblin].y++;
- break;
-
- case 7:
- _gobPositions[_currentGoblin].x--;
- _gobPositions[_currentGoblin].y++;
- break;
-
- case 38:
- _gobPositions[_currentGoblin].y++;
- break;
- }
-
- if (_currentGoblin == 1) {
- if (gobDesc->state == 28)
- _gobPositions[1].y--;
-
- if (gobDesc->state == 29)
- _gobPositions[1].y++;
- }
-
- if (flag != 0) {
- _vm->_scenery->updateAnim(_gobStateLayer, 0,
- gobDesc->animation, 0, gobDesc->xPos,
- gobDesc->yPos, 0);
-
- gobDesc->yPos =
- (_vm->_map->_curGoblinY + 1) * 6 -
- (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop);
- gobDesc->xPos =
- _vm->_map->_curGoblinX * 12 - (_vm->_scenery->_toRedrawLeft -
- _vm->_scenery->_animLeft);
- }
-
- if ((gobDesc->state == 10 || gobDesc->state == 11)
- && _currentGoblin != 0)
- _goesAtTarget = 1;
- }
-
- if (gobDesc->curFrame != framesCount)
- return;
-
- if (_forceNextState[0] != -1) {
- gobDesc->nextState = _forceNextState[0];
- for (i = 0; i < 10; i++)
- _forceNextState[i] =
- _forceNextState[i + 1];
- }
-
- _vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
- _vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
-
- _gobStateLayer = nextLayer(gobDesc);
- if (gobDesc->stateMach == gobDesc->realStateMach) {
-
- switch (gobDesc->nextState) {
- case 0:
- _gobPositions[_currentGoblin].x--;
- break;
-
- case 2:
- case 8:
- _gobPositions[_currentGoblin].y--;
- break;
-
- case 4:
- _gobPositions[_currentGoblin].x++;
- break;
-
- case 6:
- case 9:
- _gobPositions[_currentGoblin].y++;
- break;
-
- case 1:
- _gobPositions[_currentGoblin].x--;
- _gobPositions[_currentGoblin].y--;
- break;
-
- case 3:
- _gobPositions[_currentGoblin].x++;
- _gobPositions[_currentGoblin].y--;
- break;
-
- case 5:
- _gobPositions[_currentGoblin].x++;
- _gobPositions[_currentGoblin].y++;
- break;
-
- case 7:
- _gobPositions[_currentGoblin].x--;
- _gobPositions[_currentGoblin].y++;
- break;
-
- case 38:
- _gobPositions[_currentGoblin].y++;
- break;
- }
- if (_currentGoblin == 1) {
- if (gobDesc->nextState == 28)
- _gobPositions[1].y--;
-
- if (gobDesc->nextState == 29)
- _gobPositions[1].y++;
- }
- }
-
- _vm->_scenery->updateAnim(_gobStateLayer, 0, gobDesc->animation, 0,
- gobDesc->xPos, gobDesc->yPos, 0);
-
- gobDesc->yPos =
- (_vm->_map->_curGoblinY + 1) * 6 - (_vm->_scenery->_toRedrawBottom -
- _vm->_scenery->_animTop);
- gobDesc->xPos =
- _vm->_map->_curGoblinX * 12 - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft);
-
- if ((gobDesc->state == 10 || gobDesc->state == 11)
- && _currentGoblin != 0)
- _goesAtTarget = 1;
- }
- return;
-}
-
int16 Goblin::doMove(Gob_Object *gobDesc, int16 cont, int16 action) {
int16 framesCount;
int16 nextAct;
@@ -1801,7 +1250,7 @@ int16 Goblin::doMove(Gob_Object *gobDesc, int16 cont, int16 action) {
moveInitStep(framesCount, action, cont, gobDesc, &gobIndex,
&nextAct);
moveTreatRopeStairs(gobDesc);
- moveAdvance(gobDesc, nextAct, framesCount);
+ moveAdvance(0, gobDesc, nextAct, framesCount);
return gobIndex;
}
@@ -2312,6 +1761,38 @@ int16 Goblin::treatItem(int16 action) {
}
}
+void Goblin::playSounds(Mult::Mult_Object *obj) {
+ int i;
+ Mult::Mult_AnimData *animData;
+ bool speaker;
+ int16 frequency;
+ int16 repCount;
+ int16 sndSlot;
+ int16 frame;
+
+ animData = obj->pAnimData;
+
+ for (i = 1; i <= obj->goblinStates[animData->state][0].dataCount; i++) {
+ speaker = obj->goblinStates[animData->state][i].speaker;
+ if ((obj->goblinStates[animData->state][i].sndItem != -1) || (speaker == 1)) {
+ frame = obj->goblinStates[animData->state][i].sndFrame;
+ repCount = obj->goblinStates[animData->state][i].repCount;
+ frequency = obj->goblinStates[animData->state][i].freq;
+ if (animData->frame == frame) {
+ if (!speaker) {
+ sndSlot = obj->goblinStates[animData->state][i].sndItem;
+ _vm->_snd->stopSound(0);
+ if (sndSlot < _soundSlotsCount)
+ _vm->_snd->playSample(_vm->_game->_soundSamples[_soundSlots[sndSlot] & 0x7FFF],
+ repCount, frequency);
+ } else
+ _vm->_snd->speakerOn(frequency, repCount * 10);
+ }
+ }
+ }
+
+}
+
void Goblin::sub_19BD3(void) {
Mult::Mult_Object *obj0;
Mult::Mult_Object *obj1;
@@ -2327,8 +1808,8 @@ void Goblin::sub_19BD3(void) {
int16 di;
int16 si;
- obj0 = &(_vm->_mult->_objects[0]);
- obj1 = &(_vm->_mult->_objects[1]);
+ obj0 = &_vm->_mult->_objects[0];
+ obj1 = &_vm->_mult->_objects[1];
anim0 = obj0->pAnimData;
anim1 = obj1->pAnimData;
@@ -2339,66 +1820,66 @@ void Goblin::sub_19BD3(void) {
if ((_word_2F9BC == 0) && (anim0->isStatic == 0)) {
if ((VAR(_dword_2F9B6) == 0) && (si == 28)) {
si = _vm->_util->getRandom(3) + 24;
- warning("GOB2 Stub! sub_195C7(0, si);");
+ sub_195C7(0, si);
WRITE_VAR(_dword_2F9B6, 100);
} else
WRITE_VAR(_dword_2F9B6, VAR(_dword_2F9B6) - 1);
}
if ((si == 8) || (si == 9) || (si == 29))
- anim0->field_10 = 6;
+ anim0->curLookDir = 6;
}
if (anim1->someFlag == 0) {
if ((_word_2F9BA == 0) && (anim1->isStatic == 0)) {
if ((VAR(_dword_2F9B2) == 0) && (di == 28)) {
di = _vm->_util->getRandom(3) + 24;
- warning("GOB2 Stub! sub_195C7(1, di);");
+ sub_195C7(1, di);
WRITE_VAR(_dword_2F9B2, 100);
} else
WRITE_VAR(_dword_2F9B2, VAR(_dword_2F9B2) - 1);
}
if ((di == 8) || (di == 9) || (di == 29))
- anim1->field_10 = 6;
+ anim1->curLookDir = 6;
}
if ((anim0->someFlag == 1) && (anim0->isStatic == 0) &&
((anim0->state == 28) || (anim0->state == 29)))
- anim0->field_10 = 0;
+ anim0->curLookDir = 0;
if ((anim1->someFlag == 1) && (anim1->isStatic == 0) &&
((anim1->state == 28) || (anim1->state == 29)))
- anim1->field_10 = 0;
+ anim1->curLookDir = 0;
if (VAR(18) != ((uint32) -1)) {
if (anim0->layer == 44)
- anim0->field_10 = 4;
+ anim0->curLookDir = 4;
else if (anim0->layer == 45)
- anim0->field_10 = 0;
+ anim0->curLookDir = 0;
if (anim0->someFlag == 0)
- anim0->field_10 = 6;
+ anim0->curLookDir = 6;
}
if (VAR(19) != ((uint32) -1)) {
if (anim1->layer == 48)
- anim1->field_10 = 4;
+ anim1->curLookDir = 4;
else if (anim1->layer == 49)
- anim1->field_10 = 0;
+ anim1->curLookDir = 0;
if (anim1->someFlag == 0)
- anim1->field_10 = 6;
+ anim1->curLookDir = 6;
}
- if ((anim0->layer == 45) && (anim0->field_10 == 4) && (anim0->field_12 == 5) &&
+ if ((anim0->layer == 45) && (anim0->curLookDir == 4) && (anim0->pathExistence == 5) &&
(VAR(18) == ((uint32) -1)) && (_word_2F9C0 == 0)) {
- warning("GOB2 Stub! sub_195C7(0, 19);");
+ sub_195C7(0, 19);
}
- if ((anim0->layer == 44) && (anim0->field_10 == 0) && (anim0->field_12 == 5) &&
+ if ((anim0->layer == 44) && (anim0->curLookDir == 0) && (anim0->pathExistence == 5) &&
(VAR(18) == ((uint32) -1)) && (_word_2F9C0 == 0)) {
- warning("GOB2 Stub! sub_195C7(0, 16);");
+ sub_195C7(0, 16);
}
- if ((anim1->layer == 49) && (anim1->field_10 == 4) && (anim1->field_12 == 5) &&
+ if ((anim1->layer == 49) && (anim1->curLookDir == 4) && (anim1->pathExistence == 5) &&
(VAR(19) == ((uint32) -1)) && (_word_2F9BE == 0)) {
- warning("GOB2 Stub! sub_195C7(1, 19);");
+ sub_195C7(1, 19);
}
- if ((anim1->layer == 48) && (anim1->field_10 == 0) && (anim1->field_12 == 5) &&
+ if ((anim1->layer == 48) && (anim1->curLookDir == 0) && (anim1->pathExistence == 5) &&
(VAR(19) == ((uint32) -1)) && (_word_2F9BE == 0)) {
- warning("GOB2 Stub! sub_195C7(1, 16);");
+ sub_195C7(1, 16);
}
gob1X = obj0->goblinX;
@@ -2476,4 +1957,97 @@ void Goblin::sub_19BD3(void) {
}
}
+void Goblin::sub_195C7(int16 index, int16 state) {
+ Mult::Mult_Object *obj;
+ Mult::Mult_AnimData *animData;
+ int16 layer;
+ int16 animation;
+
+ obj = &_vm->_mult->_objects[index];
+ animData = obj->pAnimData;
+
+ if (obj->goblinStates[state] == 0)
+ return;
+
+ layer = obj->goblinStates[state][0].layer;
+ animation = obj->goblinStates[state][0].animation;
+ animData->layer = layer;
+ animData->animation = animation;
+ animData->state = state;
+ animData->frame = 0;
+ animData->isPaused = 0;
+ animData->isStatic = 0;
+ animData->newCycle = _vm->_scenery->_animations[animation].layers[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) -
+ (_vm->_scenery->_animBottom - _vm->_scenery->_animTop) -
+ (obj->goblinY + 1) / 2;
+ } else {
+ *obj->pPosY = (obj->goblinY + 1) * _vm->_map->_tilesHeight -
+ (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
+ }
+ *obj->pPosX = obj->goblinX * _vm->_map->_tilesWidth;
+}
+
+void Goblin::sub_11984(Mult::Mult_Object *obj) {
+ Mult::Mult_AnimData *animData;
+ int16 layer;
+ int16 animation;
+ int16 framesCount;
+
+ animData = obj->pAnimData;
+
+ if (animData->isStatic != 0)
+ return;
+
+ layer = obj->goblinStates[animData->state][0].layer;
+ animation = obj->goblinStates[animData->state][0].animation;
+ framesCount = _vm->_scenery->_animations[animation].layers[layer]->framesCount;
+ animData->newCycle = framesCount;
+ playSounds(obj);
+
+ 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;
+ }
+
+ if ((animData->field_F == -1) && (animData->frame >= framesCount)) {
+ if (animData->field_15 <= 0) {
+ animData->field_15 = animData->unknown;
+ animData->frame = 0;
+ } else
+ animData->field_15--;
+ }
+
+ if (animData->field_F != -1) {
+ animData->frame = 0;
+ animData->state = animData->field_F;
+ animData->field_F = -1;
+ animData->animation = obj->goblinStates[animData->state][0].animation;
+ animData->layer = obj->goblinStates[animData->state][0].layer;
+ *obj->pPosX += _vm->_scenery->_animations[animation].layers[layer]->animDeltaX;
+ *obj->pPosY += _vm->_scenery->_animations[animation].layers[layer]->animDeltaY;
+ animData->newCycle = _vm->_scenery->_animations[animation].layers[layer]->framesCount;
+ animData->isPaused = 0;
+ } else
+ animData->frame--;
+}
+
} // End of namespace Gob
diff --git a/engines/gob/goblin.h b/engines/gob/goblin.h
index 68e19d9018..6058595ece 100644
--- a/engines/gob/goblin.h
+++ b/engines/gob/goblin.h
@@ -26,6 +26,7 @@
#include "gob/gob.h"
#include "gob/util.h"
#include "gob/sound.h"
+#include "gob/mult.h"
namespace Gob {
@@ -34,6 +35,7 @@ namespace Gob {
#define TYPE_MOBILE 3
class Goblin {
+
public:
#pragma START_PACK_STRUCTS
struct Gob_State {
@@ -47,12 +49,6 @@ public:
int16 sndFrame; // +Eh
} GCC_PACK;
- struct Gob2_State {
- int16 animation;
- int16 layer;
- int16 field_4;
- };
-
typedef Gob_State *Gob_PState;
typedef Gob_PState Gob_StateLine[6];
@@ -219,11 +215,15 @@ public:
int16 doMove(Gob_Object *gobDesc, int16 cont, int16 action);
void sub_19BD3(void);
+ void sub_195C7(int16 index, int16 state);
+ void sub_11984(Mult::Mult_Object *obj);
virtual void placeObject(Gob_Object * objDesc, char animated,
int16 index, int16 x, int16 y, int16 state) = 0;
virtual void freeObjects(void) = 0;
- virtual void initiateMove(int16 index) = 0;
+ virtual void initiateMove(Mult::Mult_Object *obj) = 0;
+ virtual void moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc,
+ int16 nextAct, int16 framesCount) = 0;
Goblin(GobEngine *vm);
virtual ~Goblin();
@@ -244,8 +244,9 @@ protected:
void moveInitStep(int16 framesCount, int16 action, int16 cont,
Gob_Object *gobDesc, int16 *pGobIndex, int16 *pNextAct);
void moveTreatRopeStairs(Gob_Object *gobDesc);
- void movePathFind(Gob_Object *gobDesc, int16 nextAct);
- void moveAdvance(Gob_Object *gobDesc, int16 nextAct, int16 framesCount);
+ void playSounds(Mult::Mult_Object *obj);
+
+ virtual void movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct) = 0;
};
class Goblin_v1 : public Goblin {
@@ -253,10 +254,15 @@ public:
virtual void placeObject(Gob_Object * objDesc, char animated,
int16 index, int16 x, int16 y, int16 state);
virtual void freeObjects(void);
- virtual void initiateMove(int16 index);
+ virtual void initiateMove(Mult::Mult_Object *obj);
+ virtual void moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc,
+ int16 nextAct, int16 framesCount);
Goblin_v1(GobEngine *vm);
virtual ~Goblin_v1() {};
+
+protected:
+ virtual void movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct);
};
class Goblin_v2 : public Goblin_v1 {
@@ -264,10 +270,15 @@ public:
virtual void placeObject(Gob_Object * objDesc, char animated,
int16 index, int16 x, int16 y, int16 state);
virtual void freeObjects(void);
- virtual void initiateMove(int16 index);
+ virtual void initiateMove(Mult::Mult_Object *obj);
+ virtual void moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc,
+ int16 nextAct, int16 framesCount);
Goblin_v2(GobEngine *vm);
virtual ~Goblin_v2() {};
+
+protected:
+ virtual void movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct);
};
} // End of namespace Gob
diff --git a/engines/gob/goblin_v1.cpp b/engines/gob/goblin_v1.cpp
index 387af3a7df..8417e409ee 100644
--- a/engines/gob/goblin_v1.cpp
+++ b/engines/gob/goblin_v1.cpp
@@ -32,6 +32,10 @@
namespace Gob {
Goblin_v1::Goblin_v1(GobEngine *vm) : Goblin(vm) {
+ _rotStates[0][0] = 0; _rotStates[0][1] = 22; _rotStates[0][2] = 23; _rotStates[0][3] = 24;
+ _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] = 27; _rotStates[3][1] = 25; _rotStates[3][2] = 26; _rotStates[3][3] = 6;
}
void Goblin_v1::freeObjects(void) {
@@ -138,12 +142,12 @@ void Goblin_v1::placeObject(Gob_Object *objDesc, char animated,
}
}
-void Goblin_v1::initiateMove(int16 index) {
+void Goblin_v1::initiateMove(Mult::Mult_Object *obj) {
_vm->_map->findNearestToDest(0);
_vm->_map->findNearestToGob(0);
_vm->_map->optimizePoints(0, 0, 0);
- _pathExistence = _vm->_map->checkDirectPath(-1, _vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
+ _pathExistence = _vm->_map->checkDirectPath(0, _vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
_pressedMapX, _pressedMapY);
if (_pathExistence == 3) {
@@ -158,4 +162,551 @@ void Goblin_v1::initiateMove(int16 index) {
}
}
+void Goblin_v1::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct) {
+ if (_pathExistence == 1) {
+ _vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
+ _vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
+
+ if (_vm->_map->_curGoblinX == _pressedMapX &&
+ _vm->_map->_curGoblinY == _pressedMapY && _gobAction != 0) {
+ _readyToAct = 1;
+ _pathExistence = 0;
+ }
+
+ nextAct = _vm->_map->getDirection(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
+ _vm->_map->_destX, _vm->_map->_destY);
+
+ if (nextAct == 0)
+ _pathExistence = 0;
+ } else if (_pathExistence == 3) {
+ _vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
+ _vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
+
+ if (_vm->_map->_curGoblinX == _gobDestX && _vm->_map->_curGoblinY == _gobDestY) {
+ _pathExistence = 1;
+ _vm->_map->_destX = _pressedMapX;
+ _vm->_map->_destY = _pressedMapY;
+ } else {
+
+ if (_vm->_map->checkDirectPath(0, _vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
+ _gobDestX, _gobDestY) == 1) {
+ _vm->_map->_destX = _gobDestX;
+ _vm->_map->_destY = _gobDestY;
+ } else if (_vm->_map->_curGoblinX == _vm->_map->_destX && _vm->_map->_curGoblinY == _vm->_map->_destY) {
+
+ if (_vm->_map->_nearestWayPoint > _vm->_map->_nearestDest) {
+ _vm->_map->optimizePoints(0, 0, 0);
+
+ _vm->_map->_destX =
+ _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
+ x;
+ _vm->_map->_destY =
+ _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
+ y;
+
+ if (_vm->_map->_nearestWayPoint > _vm->_map->_nearestDest)
+ _vm->_map->_nearestWayPoint--;
+ } else if (_vm->_map->_nearestWayPoint < _vm->_map->_nearestDest) {
+ _vm->_map->optimizePoints(0, 0, 0);
+
+ _vm->_map->_destX =
+ _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
+ x;
+ _vm->_map->_destY =
+ _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
+ y;
+
+ if (_vm->_map->_nearestWayPoint < _vm->_map->_nearestDest)
+ _vm->_map->_nearestWayPoint++;
+ } else {
+ if (_vm->_map->checkDirectPath(0, _vm->_map->_curGoblinX,
+ _vm->_map->_curGoblinY, _gobDestX,
+ _gobDestY) == 3 && _vm->_map->getPass(_pressedMapX, _pressedMapY) != 0) {
+ _vm->_map->_destX = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].x;
+ _vm->_map->_destY = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].y;
+ } else {
+ _pathExistence = 1;
+ _vm->_map->_destX = _pressedMapX;
+ _vm->_map->_destY = _pressedMapY;
+ }
+ }
+ }
+ nextAct =
+ _vm->_map->getDirection(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
+ _vm->_map->_destX, _vm->_map->_destY);
+ }
+ }
+
+ if (_readyToAct != 0 && (_gobAction == 3 || _gobAction == 4))
+ nextAct = 0x4dc8;
+
+ switch (nextAct) {
+ case Map::kDirW:
+ gobDesc->nextState = rotateState(gobDesc->curLookDir, 0);
+ break;
+
+ case Map::kDirE:
+ gobDesc->nextState = rotateState(gobDesc->curLookDir, 4);
+ break;
+
+ case 16:
+ gobDesc->nextState = 16;
+ break;
+
+ case 23:
+ gobDesc->nextState = 23;
+ break;
+
+ case Map::kDirN:
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6 &&
+ _currentGoblin != 1) {
+ _pathExistence = 0;
+ break;
+ }
+
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
+ gobDesc->nextState = 8;
+ break;
+ }
+
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 &&
+ _currentGoblin == 1) {
+ gobDesc->nextState = 28;
+ break;
+ }
+
+ gobDesc->nextState = rotateState(gobDesc->curLookDir, 2);
+ break;
+
+ case Map::kDirS:
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6 &&
+ _currentGoblin != 1) {
+ _pathExistence = 0;
+ break;
+ }
+
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
+ gobDesc->nextState = 9;
+ break;
+ }
+
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 &&
+ _currentGoblin == 1) {
+ gobDesc->nextState = 29;
+ break;
+ }
+
+ gobDesc->nextState = rotateState(gobDesc->curLookDir, 6);
+ break;
+
+ case Map::kDirSE:
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY + 1) == 6 &&
+ _currentGoblin != 1) {
+ _pathExistence = 0;
+ break;
+ }
+
+ gobDesc->nextState = 5;
+ if (gobDesc->curLookDir == 4)
+ break;
+
+ gobDesc->nextState = rotateState(gobDesc->curLookDir, 4);
+ break;
+
+ case Map::kDirSW:
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY + 1) == 6 &&
+ _currentGoblin != 1) {
+ _pathExistence = 0;
+ break;
+ }
+
+ gobDesc->nextState = 7;
+ if (gobDesc->curLookDir == 0)
+ break;
+
+ gobDesc->nextState = rotateState(gobDesc->curLookDir, 0);
+ break;
+
+ case Map::kDirNW:
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY - 1) == 6 &&
+ _currentGoblin != 1) {
+ _pathExistence = 0;
+ break;
+ }
+
+ gobDesc->nextState = 1;
+ if (gobDesc->curLookDir == 0)
+ break;
+
+ gobDesc->nextState = rotateState(gobDesc->curLookDir, 0);
+ break;
+
+ case Map::kDirNE:
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY - 1) == 6 &&
+ _currentGoblin != 1) {
+ _pathExistence = 0;
+ break;
+ }
+
+ gobDesc->nextState = 3;
+ if (gobDesc->curLookDir == 4)
+ break;
+
+ gobDesc->nextState = rotateState(gobDesc->curLookDir, 4);
+ break;
+
+ case 0x4dc8:
+
+ if (_currentGoblin == 0 && _gobAction == 3
+ && _itemIndInPocket == -1) {
+ _destItemId = -1;
+ _readyToAct = 0;
+ break;
+ }
+
+ if (_currentGoblin == 0 && _gobAction == 4 &&
+ _itemIndInPocket == -1 && _destActionItem == 0) {
+ gobDesc->multState = 104;
+ _destItemId = -1;
+ _readyToAct = 0;
+ break;
+ }
+
+ if (_currentGoblin == 0 && _gobAction == 4 &&
+ _itemIndInPocket == -1 && _destActionItem != 0 &&
+ _itemToObject[_destActionItem] != -1 &&
+ _objects[_itemToObject[_destActionItem]]->
+ pickable == 0) {
+ gobDesc->multState = 104;
+ _destItemId = -1;
+ _readyToAct = 0;
+ break;
+ }
+
+ switch (_vm->_map->_itemPoses[_destActionItem].orient) {
+ case 0:
+ case -4:
+ gobDesc->nextState = 10;
+ gobDesc->curLookDir = 0;
+ _destItemId = -1;
+ break;
+
+ case -1:
+ case 4:
+ gobDesc->nextState = 11;
+ gobDesc->curLookDir = 4;
+ _destItemId = -1;
+ break;
+ }
+ break;
+
+ default:
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3 ||
+ (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6
+ && _currentGoblin == 1)) {
+ gobDesc->nextState = 20;
+ break;
+ }
+
+ switch (gobDesc->curLookDir) {
+ case 2:
+ case 4:
+ gobDesc->nextState = 18;
+ break;
+
+ case 6:
+ case 0:
+ gobDesc->nextState = 19;
+ break;
+ }
+ break;
+ }
+ return;
+}
+
+void Goblin_v1::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc,
+ int16 nextAct, int16 framesCount) {
+ int16 i;
+ int16 newX;
+ int16 newY;
+ int16 flag;
+
+ movePathFind(0, gobDesc, nextAct);
+
+ gobDesc->curFrame++;
+ if (gobDesc->curFrame == 1)
+ gobDesc->actionStartState = gobDesc->state;
+
+ if (_goesAtTarget == 0
+ && gobDesc->stateMach == gobDesc->realStateMach) {
+ switch (gobDesc->state) {
+ case 0:
+ case 1:
+ case 7:
+ case 13:
+ case 16:
+ case 27:
+ gobDesc->curLookDir = 0;
+ break;
+
+ case 3:
+ case 4:
+ case 5:
+ case 12:
+ case 23:
+ case 26:
+ gobDesc->curLookDir = 4;
+ break;
+
+ case 28:
+ if (_currentGoblin != 1)
+ break;
+ gobDesc->curLookDir = 2;
+ break;
+
+ case 2:
+ case 8:
+ case 15:
+ case 22:
+ case 25:
+ gobDesc->curLookDir = 2;
+ break;
+
+ case 29:
+ if (_currentGoblin != 1)
+ break;
+
+ gobDesc->curLookDir = 6;
+ break;
+
+ case 6:
+ case 9:
+ case 14:
+ case 17:
+ case 24:
+ gobDesc->curLookDir = 6;
+ break;
+ }
+ }
+
+ if (gobDesc->state >= 0 && gobDesc->state < 10 &&
+ gobDesc->stateMach == gobDesc->realStateMach &&
+ (gobDesc->curFrame == 3 || gobDesc->curFrame == 6)) {
+ _vm->_snd->speakerOn(10 * _vm->_util->getRandom(3) + 50, 5);
+ }
+
+ if (_currentGoblin == 0
+ && gobDesc->stateMach == gobDesc->realStateMach
+ && (gobDesc->state == 10 || gobDesc->state == 11)
+ && gobDesc->curFrame == 9) {
+ _vm->_snd->stopSound(0);
+ if (_itemIndInPocket != -1) {
+ _vm->_snd->playSample(_soundData[14], 1, 9000);
+ }
+
+ if (_itemIndInPocket == -1) {
+ _vm->_snd->playSample(_soundData[14], 1, 5000);
+ }
+ }
+
+ if (_boreCounter++ == 120) {
+ _boreCounter = 0;
+ for (i = 0; i < 3; i++)
+ showBoredom(i);
+ }
+
+ if (gobDesc->multState != -1 && gobDesc->curFrame == framesCount &&
+ gobDesc->state != gobDesc->multState) {
+ gobDesc->nextState = gobDesc->multState;
+ gobDesc->multState = -1;
+
+ newX =
+ _vm->_scenery->_animations[gobDesc->animation].
+ layers[_gobStateLayer]->animDeltaX + gobDesc->xPos;
+
+ newY =
+ _vm->_scenery->_animations[gobDesc->animation].
+ layers[_gobStateLayer]->animDeltaY + gobDesc->yPos;
+
+ _gobStateLayer = nextLayer(gobDesc);
+
+ gobDesc->xPos = newX;
+ gobDesc->yPos = newY;
+ } else {
+ if (gobDesc->curFrame == 3 &&
+ gobDesc->stateMach == gobDesc->realStateMach &&
+ (gobDesc->state < 10 ||
+ (_currentGoblin == 1 && (gobDesc->state == 28
+ || gobDesc->state == 29))
+ )) {
+ flag = 0;
+ if (_forceNextState[0] != -1) {
+ gobDesc->nextState = _forceNextState[0];
+ for (i = 0; i < 9; i++)
+ _forceNextState[i] =
+ _forceNextState[i + 1];
+ }
+
+ _vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
+ _vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
+
+ if (gobDesc->nextState != gobDesc->state) {
+ _gobStateLayer = nextLayer(gobDesc);
+ flag = 1;
+ }
+
+ switch (gobDesc->state) {
+ case 0:
+ _gobPositions[_currentGoblin].x--;
+ break;
+
+ case 2:
+ case 8:
+ _gobPositions[_currentGoblin].y--;
+ break;
+
+ case 4:
+ _gobPositions[_currentGoblin].x++;
+ break;
+
+ case 6:
+ case 9:
+ _gobPositions[_currentGoblin].y++;
+ break;
+
+ case 1:
+ _gobPositions[_currentGoblin].x--;
+ _gobPositions[_currentGoblin].y--;
+ break;
+
+ case 3:
+ _gobPositions[_currentGoblin].x++;
+ _gobPositions[_currentGoblin].y--;
+ break;
+
+ case 5:
+ _gobPositions[_currentGoblin].x++;
+ _gobPositions[_currentGoblin].y++;
+ break;
+
+ case 7:
+ _gobPositions[_currentGoblin].x--;
+ _gobPositions[_currentGoblin].y++;
+ break;
+
+ case 38:
+ _gobPositions[_currentGoblin].y++;
+ break;
+ }
+
+ if (_currentGoblin == 1) {
+ if (gobDesc->state == 28)
+ _gobPositions[1].y--;
+
+ if (gobDesc->state == 29)
+ _gobPositions[1].y++;
+ }
+
+ if (flag != 0) {
+ _vm->_scenery->updateAnim(_gobStateLayer, 0,
+ gobDesc->animation, 0, gobDesc->xPos,
+ gobDesc->yPos, 0);
+
+ gobDesc->yPos =
+ (_vm->_map->_curGoblinY + 1) * 6 -
+ (_vm->_scenery->_toRedrawBottom - _vm->_scenery->_animTop);
+ gobDesc->xPos =
+ _vm->_map->_curGoblinX * 12 - (_vm->_scenery->_toRedrawLeft -
+ _vm->_scenery->_animLeft);
+ }
+
+ if ((gobDesc->state == 10 || gobDesc->state == 11)
+ && _currentGoblin != 0)
+ _goesAtTarget = 1;
+ }
+
+ if (gobDesc->curFrame != framesCount)
+ return;
+
+ if (_forceNextState[0] != -1) {
+ gobDesc->nextState = _forceNextState[0];
+ for (i = 0; i < 10; i++)
+ _forceNextState[i] =
+ _forceNextState[i + 1];
+ }
+
+ _vm->_map->_curGoblinX = _gobPositions[_currentGoblin].x;
+ _vm->_map->_curGoblinY = _gobPositions[_currentGoblin].y;
+
+ _gobStateLayer = nextLayer(gobDesc);
+ if (gobDesc->stateMach == gobDesc->realStateMach) {
+
+ switch (gobDesc->nextState) {
+ case 0:
+ _gobPositions[_currentGoblin].x--;
+ break;
+
+ case 2:
+ case 8:
+ _gobPositions[_currentGoblin].y--;
+ break;
+
+ case 4:
+ _gobPositions[_currentGoblin].x++;
+ break;
+
+ case 6:
+ case 9:
+ _gobPositions[_currentGoblin].y++;
+ break;
+
+ case 1:
+ _gobPositions[_currentGoblin].x--;
+ _gobPositions[_currentGoblin].y--;
+ break;
+
+ case 3:
+ _gobPositions[_currentGoblin].x++;
+ _gobPositions[_currentGoblin].y--;
+ break;
+
+ case 5:
+ _gobPositions[_currentGoblin].x++;
+ _gobPositions[_currentGoblin].y++;
+ break;
+
+ case 7:
+ _gobPositions[_currentGoblin].x--;
+ _gobPositions[_currentGoblin].y++;
+ break;
+
+ case 38:
+ _gobPositions[_currentGoblin].y++;
+ break;
+ }
+ if (_currentGoblin == 1) {
+ if (gobDesc->nextState == 28)
+ _gobPositions[1].y--;
+
+ if (gobDesc->nextState == 29)
+ _gobPositions[1].y++;
+ }
+ }
+
+ _vm->_scenery->updateAnim(_gobStateLayer, 0, gobDesc->animation, 0,
+ gobDesc->xPos, gobDesc->yPos, 0);
+
+ gobDesc->yPos =
+ (_vm->_map->_curGoblinY + 1) * 6 - (_vm->_scenery->_toRedrawBottom -
+ _vm->_scenery->_animTop);
+ gobDesc->xPos =
+ _vm->_map->_curGoblinX * 12 - (_vm->_scenery->_toRedrawLeft - _vm->_scenery->_animLeft);
+
+ if ((gobDesc->state == 10 || gobDesc->state == 11)
+ && _currentGoblin != 0)
+ _goesAtTarget = 1;
+ }
+ return;
+}
+
} // End of namespace Gob
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
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 44eb2d3578..d47517ff7a 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -715,7 +715,7 @@ const char *Inter_v2::getOpcodeGoblinDesc(int i) {
void Inter_v2::o2_stub0x54(void) {
int16 index = _vm->_parse->parseValExpr();
- _vm->_mult->_objects[index].pAnimData->field_12 = 4;
+ _vm->_mult->_objects[index].pAnimData->pathExistence = 4;
}
void Inter_v2::o2_stub0x80(void) {
@@ -958,9 +958,24 @@ void Inter_v2::o2_placeGoblin(void) {
void Inter_v2::o2_moveGoblin(void) {
Mult::Mult_Object *obj;
Mult::Mult_AnimData *objAnim;
- int16 destX = _vm->_parse->parseValExpr();
- int16 destY = _vm->_parse->parseValExpr();
- int16 index = _vm->_parse->parseValExpr();
+ int16 destX;
+ int16 destY;
+ int16 index;
+ int16 mouseX;
+ int16 mouseY;
+ int16 gobDestX;
+ int16 gobDestY;
+ int16 mapWidth;
+ int16 mapHeight;
+ int16 di;
+ int16 si;
+ int16 var_1E;
+ int16 var_20;
+ int i;
+
+ destX = _vm->_parse->parseValExpr();
+ destY = _vm->_parse->parseValExpr();
+ index = _vm->_parse->parseValExpr();
obj = &_vm->_mult->_objects[index];
objAnim = obj->pAnimData;
@@ -971,10 +986,89 @@ void Inter_v2::o2_moveGoblin(void) {
objAnim->field_14 = destY;
if (objAnim->someFlag != 0) {
if ((destX == -1) && (destY == -1)) {
- warning("STUB: Gob2 drawOperation moveGoblin (%d %d %d), someFlag: %d", destX, destY, index, objAnim->someFlag);
+ mouseX = _vm->_global->_inter_mouseX;
+ mouseY = _vm->_global->_inter_mouseY;
+ if (_vm->_map->_bigTiles)
+ mouseY += ((_vm->_global->_inter_mouseX / _vm->_map->_tilesHeight) + 1) / 2;
+ obj->gobDestX = mouseX / _vm->_map->_tilesWidth;
+ obj->gobDestY = mouseY / _vm->_map->_tilesHeight;
+ gobDestX = obj->gobDestX;
+ gobDestY = obj->gobDestY;
+ if (_vm->_map->getPass(obj->gobDestX, obj->gobDestY) == 0) {
+ mapWidth = _vm->_map->_screenWidth / _vm->_map->_tilesWidth;
+ mapHeight = 200 / _vm->_map->_tilesHeight;
+ var_20 = 0;
+ di = -1;
+ si = -1;
+
+ for (i = 1; i <= gobDestX; i++)
+ if (_vm->_map->getPass(gobDestX - i, gobDestY) != 0)
+ break;
+ if (i <= gobDestX)
+ di = ((i - 1) * _vm->_map->_tilesWidth) + (mouseX % _vm->_map->_tilesWidth) + 1;
+ var_1E = i;
+
+ for (i = 1; (gobDestX + i) < mapWidth; i++)
+ if (_vm->_map->getPass(gobDestX + i, gobDestY) != 0)
+ break;
+ if ((gobDestX + i) < mapWidth)
+ si = (i * _vm->_map->_tilesWidth) - (mouseX % _vm->_map->_tilesWidth);
+
+ if ((si != -1) && ((di == -1) || (di > si))) {
+ di = si;
+ var_20 = 1;
+ var_1E = i;
+ }
+ si = -1;
+
+ for (i = 1; (gobDestY + i) < mapHeight; i++)
+ if (_vm->_map->getPass(gobDestX, gobDestY + i) != 0)
+ break;
+ if ((gobDestY + i) < mapHeight)
+ si = (i * _vm->_map->_tilesHeight) - (mouseY % _vm->_map->_tilesHeight);
+
+ if ((si != -1) && ((di == -1) || (di > si))) {
+ di = si;
+ var_20 = 2;
+ var_1E = i;
+ }
+ si = -1;
+
+ for (i = 1; i <= gobDestY; i++)
+ if (_vm->_map->getPass(gobDestX, gobDestY - i) != 0)
+ break;
+ if (i <= gobDestY)
+ si = ((i - 1) * _vm->_map->_tilesHeight) + (mouseY % _vm->_map->_tilesHeight) + 1;
+
+ if ((si != -1) && ((di == -1) || (di > si))) {
+ var_20 = 3;
+ var_1E = i;
+ }
+
+ if (var_20 == 0)
+ gobDestX -= var_1E;
+ else if (var_20 == 1)
+ gobDestX += var_1E;
+ else if (var_20 == 2)
+ gobDestY += var_1E;
+ else if (var_20 == 3)
+ gobDestY -= var_1E;
+ }
+ obj->gobDestX = gobDestX;
+ obj->gobDestY = gobDestY;
+ objAnim->field_13 = gobDestX;
+ objAnim->field_14 = gobDestY;
+ if (objAnim->field_13 == -1) {
+ objAnim->field_13 = obj->goblinX;
+ obj->gobDestX = obj->goblinX;
+ }
+ if (objAnim->field_14 == -1) {
+ objAnim->field_14 = obj->goblinY;
+ obj->gobDestY = obj->goblinY;
+ }
}
}
- _vm->_goblin->initiateMove(index);
+ _vm->_goblin->initiateMove(obj);
}
void Inter_v2::o2_writeGoblinPos(void) {
@@ -1042,9 +1136,9 @@ void Inter_v2::loadMult(void) {
obj->goblinY = val;
*obj->pPosX *= _vm->_map->_tilesWidth;
objAnim->field_15 = objAnim->unknown;
- objAnim->field_E = -1;
+ objAnim->nextState = -1;
objAnim->field_F = -1;
- objAnim->field_12 = 0;
+ objAnim->pathExistence = 0;
objAnim->state = objAnim->layer;
objAnim->layer = obj->goblinStates[objAnim->state][0].layer;
objAnim->animation = obj->goblinStates[objAnim->state][0].animation;
@@ -1065,7 +1159,7 @@ void Inter_v2::loadMult(void) {
obj = &_vm->_mult->_objects[objIndex];
objAnim = obj->pAnimData;
- objAnim->field_E = -1;
+ objAnim->nextState = -1;
objAnim->field_F = -1;
objAnim->state = objAnim->layer;
objAnim->layer = obj->goblinStates[objAnim->state][0].layer;
diff --git a/engines/gob/map.cpp b/engines/gob/map.cpp
index c69706b5e4..4068850be1 100644
--- a/engines/gob/map.cpp
+++ b/engines/gob/map.cpp
@@ -248,13 +248,9 @@ int16 Map::findNearestWayPoint(int16 x, int16 y) {
return lnearestWayPoint;
}
-int16 Map::checkDirectPath(int16 index, int16 x0, int16 y0, int16 x1, int16 y1) {
- Mult::Mult_Object *obj = 0;
+int16 Map::checkDirectPath(Mult::Mult_Object *obj, int16 x0, int16 y0, int16 x1, int16 y1) {
uint16 dir;
- if ((index >= 0) && (index < _vm->_mult->_objCount))
- obj = &_vm->_mult->_objects[index];
-
while (1) {
dir = getDirection(x0, y0, x1, y1);
@@ -329,7 +325,7 @@ int16 Map::checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16
nextLink = 1;
if (nextLink != 0) {
- if (checkDirectPath(-1, x0, y0, x1, y1) == 1)
+ if (checkDirectPath(0, x0, y0, x1, y1) == 1)
return 1;
nextLink = 0;
@@ -348,7 +344,7 @@ int16 Map::checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16
}
if (i0 == i1 && _wayPoints[i0].x == x0
&& _wayPoints[i0].y == y0) {
- if (checkDirectPath(-1, x0, y0, x1, y1) == 1)
+ if (checkDirectPath(0, x0, y0, x1, y1) == 1)
return 1;
return 0;
}
diff --git a/engines/gob/map.h b/engines/gob/map.h
index cb2dc625d1..6be36b21ff 100644
--- a/engines/gob/map.h
+++ b/engines/gob/map.h
@@ -24,6 +24,7 @@
#define GOB_MAP_H
#include "gob/util.h"
+#include "gob/mult.h"
namespace Gob {
@@ -87,7 +88,7 @@ public:
void placeItem(int16 x, int16 y, int16 id);
int16 getDirection(int16 x0, int16 y0, int16 x1, int16 y1);
- int16 checkDirectPath(int16 index, int16 x0, int16 y0, int16 x1, int16 y1);
+ int16 checkDirectPath(Mult::Mult_Object *obj, int16 x0, int16 y0, int16 x1, int16 y1);
int16 checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16 i1);
void loadItemToObject(void);
void loadDataFromAvo(char *dest, int16 size);
@@ -97,9 +98,9 @@ public:
virtual void setPass(int x, int y, int8 pass, int heightOff = -1) = 0;
virtual void loadMapObjects(char *avjFile) = 0;
- virtual void findNearestToGob(int16 index) = 0;
- virtual void findNearestToDest(int16 index) = 0;
- virtual void optimizePoints(int16 index, int16 x, int16 y) = 0;
+ virtual void findNearestToGob(Mult::Mult_Object *obj) = 0;
+ virtual void findNearestToDest(Mult::Mult_Object *obj) = 0;
+ virtual void optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y) = 0;
Map(GobEngine *vm);
virtual ~Map() {};
@@ -115,9 +116,9 @@ protected:
class Map_v1 : public Map {
public:
virtual void loadMapObjects(char *avjFile);
- virtual void optimizePoints(int16 index, int16 x, int16 y);
- virtual void findNearestToGob(int16 index);
- virtual void findNearestToDest(int16 index);
+ virtual void findNearestToGob(Mult::Mult_Object *obj);
+ virtual void findNearestToDest(Mult::Mult_Object *obj);
+ virtual void optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y);
virtual inline int8 getPass(int x, int y, int heightOff = -1) {
return _passMap[y * _mapWidth + x];
@@ -134,9 +135,9 @@ public:
class Map_v2 : public Map_v1 {
public:
virtual void loadMapObjects(char *avjFile);
- virtual void optimizePoints(int16 index, int16 x, int16 y);
- virtual void findNearestToGob(int16 index);
- virtual void findNearestToDest(int16 index);
+ virtual void findNearestToGob(Mult::Mult_Object *obj);
+ virtual void findNearestToDest(Mult::Mult_Object *obj);
+ virtual void optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y);
virtual inline int8 getPass(int x, int y, int heightOff = -1) {
if (heightOff == -1)
diff --git a/engines/gob/map_v1.cpp b/engines/gob/map_v1.cpp
index 8adc7e1a16..892b848ef6 100644
--- a/engines/gob/map_v1.cpp
+++ b/engines/gob/map_v1.cpp
@@ -389,32 +389,32 @@ void Map_v1::loadMapObjects(char *avjFile) {
}
}
-void Map_v1::optimizePoints(int16 index, int16 x, int16 y) {
+void Map_v1::optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y) {
int16 i;
if (_nearestWayPoint < _nearestDest) {
for (i = _nearestWayPoint; i <= _nearestDest; i++) {
- if (checkDirectPath(-1, _curGoblinX, _curGoblinY,
+ if (checkDirectPath(0, _curGoblinX, _curGoblinY,
_wayPoints[i].x, _wayPoints[i].y) == 1)
_nearestWayPoint = i;
}
} else if (_nearestWayPoint > _nearestDest) {
for (i = _nearestWayPoint; i >= _nearestDest; i--) {
- if (checkDirectPath(-1, _curGoblinX, _curGoblinY,
+ if (checkDirectPath(0, _curGoblinX, _curGoblinY,
_wayPoints[i].x, _wayPoints[i].y) == 1)
_nearestWayPoint = i;
}
}
}
-void Map_v1::findNearestToGob(int16 index) {
+void Map_v1::findNearestToGob(Mult::Mult_Object *obj) {
int16 wayPoint = findNearestWayPoint(_curGoblinX, _curGoblinY);
if (wayPoint != -1)
_nearestWayPoint = wayPoint;
}
-void Map_v1::findNearestToDest(int16 index) {
+void Map_v1::findNearestToDest(Mult::Mult_Object *obj) {
int16 wayPoint = findNearestWayPoint(_destX, _destY);
if (wayPoint != -1)
diff --git a/engines/gob/map_v2.cpp b/engines/gob/map_v2.cpp
index d5c02fd078..fa982fbbaa 100644
--- a/engines/gob/map_v2.cpp
+++ b/engines/gob/map_v2.cpp
@@ -60,7 +60,7 @@ void Map_v2::loadMapObjects(char *avjFile) {
char *dataPtrBak;
char *dataPtrBak2;
int8 statesMask[102];
- Goblin::Gob2_State *statesPtr;
+ Mult::Mult_GobState *statesPtr;
var = _vm->_parse->parseVarIndex();
variables = _vm->_global->_inter_variables + var;
@@ -138,8 +138,8 @@ void Map_v2::loadMapObjects(char *avjFile) {
_vm->_goblin->_gobsCount = tmp;
for (i = 0; i < _vm->_goblin->_gobsCount; i++) {
memset(statesMask, -1, 101);
- _vm->_mult->_objects[i].goblinStates = new Goblin::Gob2_State*[101];
- memset(_vm->_mult->_objects[i].goblinStates, 0, 101 * sizeof(Goblin::Gob2_State *));
+ _vm->_mult->_objects[i].goblinStates = new Mult::Mult_GobState*[101];
+ memset(_vm->_mult->_objects[i].goblinStates, 0, 101 * sizeof(Mult::Mult_GobState *));
memcpy(statesMask, dataPtr, 100);
dataPtr += 100;
dataPtrBak2 = dataPtr;
@@ -153,7 +153,7 @@ void Map_v2::loadMapObjects(char *avjFile) {
dataPtr += numData * 9;
}
}
- statesPtr = new Goblin::Gob2_State[statesCount];
+ statesPtr = new Mult::Mult_GobState[statesCount];
_vm->_mult->_objects[i].goblinStates[0] = statesPtr;
dataPtr = dataPtrBak2;
for (j = 0; j < 100; j++) {
@@ -165,18 +165,17 @@ void Map_v2::loadMapObjects(char *avjFile) {
_vm->_mult->_objects[i].goblinStates[state][0].layer = READ_LE_UINT16(dataPtr);
dataPtr += 2;
numData = *dataPtr++;
- _vm->_mult->_objects[i].goblinStates[state][0].field_4 = numData;
- for (k = 0; k < numData; k++) {
+ _vm->_mult->_objects[i].goblinStates[state][0].dataCount = numData;
+ for (k = 1; k <= numData; k++) {
dataPtr++;
- _vm->_mult->_objects[i].goblinStates[state][k].animation = *((byte *) dataPtr) << 8;
+ _vm->_mult->_objects[i].goblinStates[state][k].sndItem = *dataPtr;
dataPtr += 2;
- _vm->_mult->_objects[i].goblinStates[state][k].animation += *((byte *) dataPtr);
+ _vm->_mult->_objects[i].goblinStates[state][k].sndFrame = *dataPtr;
dataPtr += 2;
- _vm->_mult->_objects[i].goblinStates[state][k].layer = *((byte *) dataPtr) << 8;
- dataPtr += 2;
- _vm->_mult->_objects[i].goblinStates[state][k].layer += *((byte *) dataPtr);
- _vm->_mult->_objects[i].goblinStates[state][k].field_4 = READ_LE_UINT16(dataPtr);
+ _vm->_mult->_objects[i].goblinStates[state][k].freq = READ_LE_UINT16(dataPtr);
dataPtr += 2;
+ _vm->_mult->_objects[i].goblinStates[state][k].repCount = *dataPtr++;
+ _vm->_mult->_objects[i].goblinStates[state][k].speaker = *dataPtr++;
statesPtr++;
}
}
@@ -188,39 +187,33 @@ void Map_v2::loadMapObjects(char *avjFile) {
_vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1);
}
-void Map_v2::findNearestToGob(int16 index) {
- Mult::Mult_Object *obj = &_vm->_mult->_objects[index];
+void Map_v2::findNearestToGob(Mult::Mult_Object *obj) {
int16 wayPoint = findNearestWayPoint(obj->goblinX, obj->goblinY);
if (wayPoint != -1)
obj->nearestWayPoint = wayPoint;
}
-void Map_v2::findNearestToDest(int16 index) {
- Mult::Mult_Object *obj = &_vm->_mult->_objects[index];
+void Map_v2::findNearestToDest(Mult::Mult_Object *obj) {
int16 wayPoint = findNearestWayPoint(obj->destX, obj->destY);
if (wayPoint != -1)
obj->nearestDest = wayPoint;
}
-void Map_v2::optimizePoints(int16 index, int16 x, int16 y) {
- Mult::Mult_Object *obj;
+void Map_v2::optimizePoints(Mult::Mult_Object *obj, int16 x, int16 y) {
int i;
-
int16 var_2;
- obj = &_vm->_mult->_objects[index];
-
if (obj->nearestWayPoint < obj->nearestDest) {
var_2 = obj->nearestWayPoint;
for (i = obj->nearestWayPoint; i <= obj->nearestDest; i++) {
- if (checkDirectPath(index, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
+ if (checkDirectPath(obj, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
obj->nearestWayPoint = i;
}
} else {
for (i = obj->nearestWayPoint; i >= obj->nearestDest && _wayPoints[i].field_2 != 1; i--) {
- if (checkDirectPath(index, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
+ if (checkDirectPath(obj, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
obj->nearestWayPoint = i;
}
}
diff --git a/engines/gob/mult.h b/engines/gob/mult.h
index 2012aaddda..0ee6879d5b 100644
--- a/engines/gob/mult.h
+++ b/engines/gob/mult.h
@@ -26,7 +26,6 @@
#include "gob/gob.h"
#include "gob/sound.h"
#include "gob/video.h"
-#include "gob/goblin.h"
namespace Gob {
@@ -52,16 +51,28 @@ public:
int8 somethingFrame; // New in GOB2
int8 someFlag; // New in GOB2
int8 state; // New in GOB2
- int8 field_E; // New in GOB2
+ int8 nextState; // New in GOB2
int8 field_F; // New in GOB2
- int8 field_10; // New in GOB2
- int8 field_12; // New in GOB2
+ int8 curLookDir; // New in GOB2
+ int8 pathExistence; // New in GOB2
int8 field_13; // New in GOB2
int8 field_14; // New in GOB2
int8 field_15; // New in GOB2
+ int8 field_16; // New in GOB2
int8 field_17; // New in GOB2
} GCC_PACK;
+ struct Mult_GobState {
+ int16 animation; // .
+ int16 layer; // |- [0]
+ int16 dataCount; // '
+ int8 sndItem; // .
+ uint8 sndFrame; // |
+ int16 freq; // |- [1+]
+ int8 repCount; // |
+ uint8 speaker; // '
+ };
+
struct Mult_Object {
int32 *pPosX;
int32 *pPosY;
@@ -71,20 +82,20 @@ public:
int16 lastRight;
int16 lastTop;
int16 lastBottom;
- int8 someFlag; // New in GOB2
- int16 somethingLeft; // New in GOB2
- int16 somethingTop; // New in GOB2
- int16 somethingRight; // New in GOB2
- int16 somethingBottom; // New in GOB2
- int8 goblinX; // New in GOB2
- int8 goblinY; // New in GOB2
- int8 destX; // New in GOB2
- int8 destY; // New in GOB2
- int8 gobDestX; // New in GOB2
- int8 gobDestY; // New in GOB2
- int8 nearestWayPoint; // New in GOB2
- int8 nearestDest; // New in GOB2
- Goblin::Gob2_State **goblinStates; // New in GOB2
+ int8 someFlag; // New in GOB2
+ int16 somethingLeft; // New in GOB2
+ int16 somethingTop; // New in GOB2
+ int16 somethingRight; // New in GOB2
+ int16 somethingBottom; // New in GOB2
+ int8 goblinX; // New in GOB2
+ int8 goblinY; // New in GOB2
+ int8 destX; // New in GOB2
+ int8 destY; // New in GOB2
+ int8 gobDestX; // New in GOB2
+ int8 gobDestY; // New in GOB2
+ int8 nearestWayPoint; // New in GOB2
+ int8 nearestDest; // New in GOB2
+ Mult::Mult_GobState **goblinStates; // New in GOB2
};
struct Mult_StaticKey {
@@ -346,6 +357,7 @@ protected:
void sub_62DD(int16 index);
void sub_6A35(void);
+ void sub_10C87(Mult_Object *obj);
};
} // End of namespace Gob
diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp
index d26919d53a..a1f80ea4e8 100644
--- a/engines/gob/mult_v2.cpp
+++ b/engines/gob/mult_v2.cpp
@@ -35,6 +35,7 @@
#include "gob/palanim.h"
#include "gob/parse.h"
#include "gob/music.h"
+#include "gob/map.h"
namespace Gob {
@@ -309,7 +310,9 @@ void Mult_v2::setMultData(uint16 multindex) {
void Mult_v2::multSub(uint16 multindex) {
uint16 flags;
int16 expr;
+ int16 textFrame;
int i;
+ int j;
int16 di;
flags = multindex;
@@ -353,7 +356,56 @@ void Mult_v2::multSub(uint16 multindex) {
expr = _vm->_parse->parseValExpr();
_multData2->animKeysIndices1[di] = expr;
_multData2->animKeysIndices2[di] = expr;
- // loc_5D0E
+
+ WRITE_VAR(18 + di, expr);
+ if (expr == -1) { // loc_5D0E
+ if (_objects)
+ for (i = 0; i < 4; i++)
+ if ((_multData2->field_124[di][i] != -1) && (_multData2->field_124[di][i] != 1024))
+ _objects[_multData2->field_124[di][i]].pAnimData->animType =
+ _objects[_multData2->field_124[di][i]].pAnimData->field_17;
+ } else { // loc_5DDC
+ if (_multData2->field_156 == 1) {
+ _multData2->field_157[di] = 32000;
+ for (i = 0; i < _multData2->textKeysCount; i++) {
+ textFrame = _multData2->textKeys[i].frame;
+ if ((textFrame > _multData2->animKeysIndices2[di]) &&
+ (textFrame < _multData2->field_157[di])) {
+ _multData2->field_157[di] = textFrame;
+ }
+ }
+ } else {
+ _multData2->field_157[di] = 0;
+ for (i = 0; i < _multData2->textKeysCount; i++) {
+ textFrame = _multData2->textKeys[i].frame;
+ if ((textFrame < _multData2->animKeysIndices2[di]) &&
+ (textFrame > _multData2->field_157[di])) {
+ _multData2->field_157[di] = textFrame;
+ }
+ }
+ }
+ if (_objects) {
+ for (i = 0; i < 4; i++) {
+ if ((_multData2->field_124[di][i] != -1) && (_multData2->field_124[di][i] != 1024))
+ _objects[_multData2->field_124[di][i]].pAnimData->field_17 =
+ _objects[_multData2->field_124[di][i]].pAnimData->animType;
+ }
+ }
+ // loc_5FCF
+ for (i = 0; i < 4; i++ /* var_C += 2, var_E += 4*/) {
+ _multData2->field_15F[di][i] = 0;
+ for (j = 0; j < _multData2->animKeysCount[i]; j++) {
+ if (_multData2->animKeys[i][j].frame >= _multData2->animKeysIndices2[di])
+ _multData2->field_15F[di][i] = j;
+ }
+ }
+ if (_multData2->field_156 == -1) { // loc_60CF
+ warning("Mult_v2::multSub(), somepointer05 and somepointer05indices");
+ }
+ // loc_6187
+ warning("Mult_v2::multSub(), somepointer05");
+ }
+
warning("GOB2 Stub! Mult_v2::multSub()");
}
@@ -412,14 +464,6 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape,
_animArrayY = new int32[_objCount];
_animArrayData = new Mult_AnimData[_objCount];
- // TODO: Delete that after the code that initializes these fields exists!
- int i;
- for (i = 0; i < _objCount; i++) {
- _animArrayData[i].field_13 = 0;
- _animArrayData[i].field_14 = 0;
- _animArrayData[i].field_17 = 0;
- }
- // ---'
for (_counter = 0; _counter < _objCount; _counter++) {
multObj = &_objects[_counter];
@@ -1277,9 +1321,9 @@ void Mult_v2::animate(void) {
}
}
else if (animData1->animType == 100)
- warning("GOB2 Stub! sub_10C87(animObj1);");
+ _vm->_goblin->moveAdvance(animObj1, 0, 0, 0);
else if (animData1->animType == 101)
- warning("GOB2 Stub! sub_11984(animObj1);");
+ _vm->_goblin->sub_11984(animObj1);
} else
animObj1->tick++;
}