aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorSven Hesse2006-06-07 18:49:20 +0000
committerSven Hesse2006-06-07 18:49:20 +0000
commit34dae22c1a1db184c380f5b30ecde367f0d12485 (patch)
tree0a924639163fd5bf2e92b736ca6dd6deb4aab4e7 /engines
parentd5255cd2ad62bc44194028f991024e0fbf46c7b3 (diff)
downloadscummvm-rg350-34dae22c1a1db184c380f5b30ecde367f0d12485.tar.gz
scummvm-rg350-34dae22c1a1db184c380f5b30ecde367f0d12485.tar.bz2
scummvm-rg350-34dae22c1a1db184c380f5b30ecde367f0d12485.zip
More goblin handling functions, now the deactivated goblin shows
his boredom. It's the wrong goblin that's deactivated, though. Also, the entering animation is still missing (now nothing is drawn instead). svn-id: r22979
Diffstat (limited to 'engines')
-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++;
}