diff options
Diffstat (limited to 'engines/gob')
-rw-r--r-- | engines/gob/goblin.cpp | 722 | ||||
-rw-r--r-- | engines/gob/goblin.h | 33 | ||||
-rw-r--r-- | engines/gob/goblin_v1.cpp | 555 | ||||
-rw-r--r-- | engines/gob/goblin_v2.cpp | 419 | ||||
-rw-r--r-- | engines/gob/inter_v2.cpp | 112 | ||||
-rw-r--r-- | engines/gob/map.cpp | 10 | ||||
-rw-r--r-- | engines/gob/map.h | 21 | ||||
-rw-r--r-- | engines/gob/map_v1.cpp | 10 | ||||
-rw-r--r-- | engines/gob/map_v2.cpp | 39 | ||||
-rw-r--r-- | engines/gob/mult.h | 48 | ||||
-rw-r--r-- | engines/gob/mult_v2.cpp | 66 |
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++; } |