/* ScummVM - Graphic Adventure Engine * * ScummVM is the legal property of its developers, whose names * are too numerous to list here. Please refer to the COPYRIGHT * file distributed with this source distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ #include "gnap/gnap.h" #include "gnap/character.h" #include "gnap/gamesys.h" #include "gnap/resource.h" #include "gnap/scenes/group0.h" namespace Gnap { Scene01::Scene01(GnapEngine *vm) : Scene(vm) { _pigsIdCtr = 0; _smokeIdCtr = 0; _spaceshipSurface = nullptr; } Scene01::~Scene01() { delete _spaceshipSurface; } int Scene01::init() { GameSys& gameSys = *_vm->_gameSys; gameSys.setAnimation(0, 0, 0); gameSys.setAnimation(0, 0, 3); return 0x88; } void Scene01::updateHotspots() { _vm->setHotspot(kHS01Platypus, 0, 0, 0, 0, SF_DISABLED | SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS01ExitTruck, 780, 226, 800, 455, SF_EXIT_R_CURSOR | SF_WALKABLE, 10, 6); _vm->setHotspot(kHS01Mud, 138, 282, 204, 318, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 3, 5); _vm->setHotspot(kHS01Pigs, 408, 234, 578, 326, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 6, 4); _vm->setHotspot(kHS01Spaceship, 0, 200, 94, 292, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 1, 6); _vm->setHotspot(kHS01WalkArea1, 0, 0, 162, 426); _vm->setHotspot(kHS01WalkArea2, 162, 0, 237, 396); _vm->setHotspot(kHS01WalkArea3, 237, 0, 319, 363); _vm->setHotspot(kHS01WalkArea4, 520, 0, 800, 404); _vm->setHotspot(kHS01WalkArea5, 300, 447, 800, 600); _vm->setHotspot(kHS01WalkArea6, 678, 0, 800, 404); _vm->setHotspot(kHS01WalkArea7, 0, 0, 520, 351); _vm->setHotspot(kHS01WalkArea8, 0, 546, 300, 600); _vm->setDeviceHotspot(kHS01Device, -1, -1, -1, -1); if (_vm->isFlag(kGFPlatypus)) _vm->_hotspots[kHS01Platypus]._flags = SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR; if (_vm->isFlag(kGFMudTaken)) _vm->_hotspots[kHS01Mud]._flags = SF_WALKABLE | SF_DISABLED; _vm->_hotspotsCount = 14; } void Scene01::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; _vm->playSound(0x1091C, true); _vm->startSoundTimerC(5); gameSys.setAnimation(134, 20, 4); gameSys.insertSequence(134, 20, 0, 0, kSeqNone, 0, 0, 0); gameSys.setAnimation(0x7F, 40, 2); gameSys.insertSequence(0x7F, 40, 0, 0, kSeqNone, 0, 0, 0); _vm->_timers[4] = _vm->getRandom(100) + 300; if (!_vm->isFlag(kGFMudTaken)) gameSys.insertSequence(129, 40, 0, 0, kSeqNone, 0, 0, 0); _vm->queueInsertDeviceIcon(); if (_vm->_prevSceneNum == 2) { gnap.initPos(11, 6, kDirBottomLeft); if (_vm->isFlag(kGFPlatypus)) plat.initPos(12, 6, kDirIdleRight); _vm->endSceneInit(); if (_vm->isFlag(kGFPlatypus)) plat.walkTo(Common::Point(9, 6), -1, 0x107C2, 1); gnap.walkTo(Common::Point(8, 6), -1, 0x107B9, 1); } else { gnap.initPos(1, 6, kDirBottomRight); if (_vm->isFlag(kGFPlatypus)) plat.initPos(1, 7, kDirIdleLeft); _vm->endSceneInit(); } while (!_vm->_sceneDone) { _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->testWalk(0, 3, -1, -1, -1, -1); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS01Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); } break; case kHS01Platypus: if (gnap._actionStatus < 0 && _vm->isFlag(kGFPlatypus)) { if (_vm->_grabCursorSpriteIndex == kItemDisguise) { gnap.useDisguiseOnPlatypus(); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: if (_vm->isFlag(kGFKeysTaken)) gnap.playMoan1(plat._pos); else gnap.playScratchingHead(plat._pos); break; case GRAB_CURSOR: gnap.kissPlatypus(0); break; case TALK_CURSOR: gnap.playBrainPulsating(plat._pos); plat.playSequence(plat.getSequenceId()); break; case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS01Spaceship: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[4], 0, 2); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap._idleFacing = kDirUpLeft; if (gnap.walkTo(_vm->_hotspotsWalkPos[4], 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1)) gnap._actionStatus = kAS01LookSpaceship; break; case GRAB_CURSOR: case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS01Mud: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[2], 2, 3); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(3, 3)); break; case GRAB_CURSOR: gnap.walkTo(_vm->_hotspotsWalkPos[2], 0, gnap.getSequenceId(kGSIdle, Common::Point(2, 3)) | 0x10000, 1); gnap._actionStatus = kAS01TakeMud; break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS01Pigs: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[3], 7, 2); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap._idleFacing = kDirUpRight; gnap.walkTo(_vm->_hotspotsWalkPos[3], 0, gnap.getSequenceId(kGSIdle, Common::Point(7, 2)) | 0x10000, 1); gnap._actionStatus = kAS01LookPigs; break; case GRAB_CURSOR: gnap._idleFacing = kDirUpRight; gnap.walkTo(_vm->_hotspotsWalkPos[3], 0, gnap.getSequenceId(kGSIdle, Common::Point(7, 2)) | 0x10000, 1); gnap._actionStatus = kAS01UsePigs; break; case TALK_CURSOR: gnap._idleFacing = kDirUpRight; gnap.walkTo(_vm->_hotspotsWalkPos[3], 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(7, 2)) | 0x10000, 1); gnap._actionStatus = kAS01LookPigs; break; case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS01ExitTruck: if (gnap._actionStatus < 0) { _vm->_isLeavingScene = true; gnap.walkTo(_vm->_hotspotsWalkPos[1], 0, 0x107AB, 1); gnap._actionStatus = kAS01LeaveScene; if (_vm->isFlag(kGFPlatypus)) plat.walkTo(_vm->_hotspotsWalkPos[1] + Common::Point(0, 1), -1, 0x107CD, 1); _vm->_newSceneNum = 2; } break; case kHS01WalkArea1: case kHS01WalkArea2: case kHS01WalkArea3: case kHS01WalkArea4: case kHS01WalkArea5: case kHS01WalkArea6: case kHS01WalkArea7: case kHS01WalkArea8: if (gnap._actionStatus < 0) gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); break; default: if (_vm->_mouseClickState._left && gnap._actionStatus < 0) { gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); _vm->_mouseClickState._left = false; } break; } updateAnimations(); if (!_vm->isSoundPlaying(0x1091C)) _vm->playSound(0x1091C, true); if (!_vm->_isLeavingScene) { if (plat._actionStatus < 0 && _vm->isFlag(kGFPlatypus)) plat.updateIdleSequence(); if (gnap._actionStatus < 0) gnap.updateIdleSequence(); if (_vm->_timers[4] == 0) { // Update bird animation _vm->_timers[4] = _vm->getRandom(100) + 300; if (_vm->getRandom(1) == 0) gameSys.insertSequence(0x84, 180, 0, 0, kSeqNone, 0, 0, 0); else gameSys.insertSequence(0x83, 180, 0, 0, kSeqNone, 0, 0, 0); } _vm->playSoundC(); } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); } _vm->gameUpdateTick(); } } void Scene01::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; if (gameSys.getAnimationStatus(0) == 2) { gameSys.setAnimation(0, 0, 0); switch (gnap._actionStatus) { case kAS01LookSpaceship: _spaceshipSurface = gameSys.createSurface(47); gameSys.insertSpriteDrawItem(_spaceshipSurface, 0, 0, 255); gameSys.setAnimation(133, 256, 0); gameSys.insertSequence(133, 256, 0, 0, kSeqNone, 0, 0, 0); gnap._actionStatus = kAS01LookSpaceshipDone; break; case kAS01LookSpaceshipDone: gameSys.removeSequence(133, 256, true); gameSys.removeSpriteDrawItem(_spaceshipSurface, 255); _vm->deleteSurface(&_spaceshipSurface); gnap._actionStatus = -1; break; case kAS01LeaveScene: _vm->_sceneDone = true; break; case kAS01TakeMud: gnap.playPullOutDevice(Common::Point(2, 3)); gnap.playUseDevice(); gameSys.insertSequence(128, 40, 129, 40, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(128, 40, 3); gnap._actionStatus = -1; break; case kAS01LookPigs: _vm->playSound(0x8A, false); _vm->playSound(0x8B, false); _vm->playSound(0x8C, false); gnap._actionStatus = -1; break; case kAS01UsePigs: gnap.playPullOutDevice(Common::Point(7, 2)); gnap.playUseDevice(); gameSys.insertSequence(135, 39, 0, 0, kSeqNone, 25, _vm->getRandom(140) - 40, 0); gnap._actionStatus = -1; break; } } if (gameSys.getAnimationStatus(3) == 2) { gameSys.setAnimation(0, 0, 3); _vm->invAdd(kItemMud); _vm->setGrabCursorSprite(kItemMud); _vm->setFlag(kGFMudTaken); updateHotspots(); } if (gameSys.getAnimationStatus(4) == 2) { _smokeIdCtr = (_smokeIdCtr + 1) % 2; gameSys.setAnimation(0x86, _smokeIdCtr + 20, 4); gameSys.insertSequence(0x86, _smokeIdCtr + 20, 0x86, (_smokeIdCtr + 1) % 2 + 20, kSeqSyncWait, 0, 0, 0); } if (gameSys.getAnimationStatus(2) == 2) { _pigsIdCtr = (_pigsIdCtr + 1) % 2; gameSys.setAnimation(0x7F, _pigsIdCtr + 40, 2); gameSys.insertSequence(0x7F, _pigsIdCtr + 40, 0x7F, (_pigsIdCtr + 1) % 2 + 40, kSeqSyncWait, 0, 0, 0); } } /*****************************************************************************/ Scene02::Scene02(GnapEngine *vm) : Scene(vm) { _truckGrillCtr = 0; _nextChickenSequenceId = 0; _currChickenSequenceId = 0; _gnapTruckSequenceId = 0; } int Scene02::init() { _vm->_gameSys->setAnimation(0, 0, 0); return _vm->isFlag(kGFTruckKeysUsed) ? 0x15A : 0x15B; } void Scene02::updateHotspots() { _vm->setHotspot(kHS02Platypus, 0, 0, 0, 0, SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); if (!_vm->isFlag(kGFPlatypus)) _vm->_hotspots[kHS02Platypus]._flags |= SF_DISABLED; _vm->setHotspot(kHS02Chicken, 606, 455, 702, 568, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 7, 8); _vm->setHotspot(kHS02Truck1, 385, 258, 464, 304, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 6, 5); _vm->setHotspot(kHS02Truck2, 316, 224, 390, 376, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 5, 6); _vm->setHotspot(kHS02TruckGrill, 156, 318, 246, 390, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 2, 7); _vm->setHotspot(kHS02ExitHouse, 480, 120, 556, 240, SF_EXIT_U_CURSOR, 7, 5); _vm->setHotspot(kHS02ExitBarn, 610, 0, 800, 164, SF_EXIT_U_CURSOR, 10, 5); _vm->setHotspot(kHS02ExitCreek, 780, 336, 800, 556, SF_EXIT_R_CURSOR | SF_WALKABLE, 10, 8); _vm->setHotspot(kHS02ExitPigpen, 0, 300, 20, 600, SF_EXIT_L_CURSOR | SF_WALKABLE, 0, 8); _vm->setHotspot(kHS02WalkArea1, 92, 140, 304, 430, SF_NONE, 3, 1); _vm->setHotspot(kHS02WalkArea2, 0, 0, 800, 380); _vm->setHotspot(kHS02WalkArea3, 0, 0, 386, 445); _vm->setHotspot(kHS02WalkArea4, 386, 0, 509, 410); _vm->setDeviceHotspot(kHS02Device, -1, -1, -1, -1); _vm->_hotspotsCount = 14; } void Scene02::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; _vm->playSound(0x1091C, true); _vm->startSoundTimerC(6); _currChickenSequenceId = 0x14B; gameSys.setAnimation(0x14B, 179, 2); gameSys.insertSequence(0x14B, 179, 0, 0, kSeqNone, 0, 0, 0); _nextChickenSequenceId = -1; _vm->_timers[5] = _vm->getRandom(20) + 30; _vm->_timers[4] = _vm->getRandom(100) + 300; _vm->queueInsertDeviceIcon(); switch (_vm->_prevSceneNum) { case 3: gnap.initPos(11, 6, kDirBottomLeft); if (_vm->isFlag(kGFPlatypus)) plat.initPos(12, 6, kDirIdleRight); _vm->endSceneInit(); if (_vm->isFlag(kGFPlatypus)) plat.walkTo(Common::Point(9, 6), -1, 0x107C2, 1); gnap.walkTo(Common::Point(8, 6), -1, 0x107BA, 1); break; case 4: gnap.initPos(_vm->_hotspotsWalkPos[6].x, _vm->_hotspotsWalkPos[6].y, kDirBottomLeft); if (_vm->isFlag(kGFPlatypus)) plat.initPos(_vm->_hotspotsWalkPos[6].x + 1, _vm->_hotspotsWalkPos[6].y, kDirIdleRight); _vm->endSceneInit(); gnap.walkTo(Common::Point(7, 6), 0, 0x107B9, 1); if (_vm->isFlag(kGFPlatypus)) plat.walkTo(Common::Point(8, 6), 1, 0x107C2, 1); updateHotspots(); gameSys.waitForUpdate(); break; case 47: _vm->clearFlag(kGFUnk25); gnap.initPos(5, 6, kDirBottomLeft); plat.initPos(6, 7, kDirIdleRight); _vm->endSceneInit(); break; case 49: gnap.initPos(5, 6, kDirBottomRight); if (_vm->isFlag(kGFPlatypus)) plat.initPos(6, 7, kDirIdleLeft); _vm->endSceneInit(); break; default: gnap.initPos(-1, 6, kDirBottomRight); if (_vm->isFlag(kGFPlatypus)) plat.initPos(-1, 7, kDirIdleLeft); _vm->endSceneInit(); if (_vm->isFlag(kGFPlatypus)) plat.walkTo(Common::Point(2, 7), -1, 0x107C2, 1); gnap.walkTo(Common::Point(2, 8), -1, 0x107B9, 1); break; } while (!_vm->_sceneDone) { _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->testWalk(0, 6, 7, 6, 8, 6); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS02Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); } break; case kHS02Platypus: if (gnap._actionStatus < 0 && _vm->isFlag(kGFPlatypus)) { if (_vm->_grabCursorSpriteIndex == kItemDisguise) { gnap.useDisguiseOnPlatypus(); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: if (_vm->isFlag(kGFKeysTaken)) gnap.playMoan1(plat._pos); else gnap.playScratchingHead(plat._pos); break; case GRAB_CURSOR: gnap.kissPlatypus(0); break; case TALK_CURSOR: gnap.playBrainPulsating(plat._pos); plat.playSequence(plat.getSequenceId()); break; case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS02Chicken: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex == kItemTwig) { gnap._idleFacing = kDirUpRight; Common::Point destPos = _vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot] + Common::Point(0, 1); gnap.walkTo(destPos, 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS02UseTwigWithChicken; } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[1] + Common::Point(0, 1), 9, 8); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playMoan2(Common::Point(9, 8)); break; case GRAB_CURSOR: gnap._idleFacing = kDirBottomRight; if (gnap.walkTo(_vm->_hotspotsWalkPos[1], 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1)) gnap._actionStatus = kAS02GrabChicken; else gnap._actionStatus = -1; break; case TALK_CURSOR: gnap._idleFacing = kDirBottomRight; gnap.walkTo(_vm->_hotspotsWalkPos[1], 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS02TalkChicken; break; case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS02Truck1: case kHS02Truck2: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex == kItemKeys) { if (gnap.walkTo(_vm->_hotspotsWalkPos[3], 0, gnap.getSequenceId(kGSIdle, Common::Point(2, 2)) | 0x10000, 1)) { _vm->setGrabCursorSprite(-1); _vm->invRemove(kItemKeys); if (_vm->isFlag(kGFTruckFilledWithGas)) gnap._actionStatus = kAS02UseTruckGas; else gnap._actionStatus = kAS02UseTruckNoGas; } } else if (_vm->_grabCursorSpriteIndex == kItemGas) { _vm->_hotspots[kHS02WalkArea4]._flags |= SF_WALKABLE; if (gnap.walkTo(_vm->_hotspotsWalkPos[2], 0, gnap.getSequenceId(kGSIdle, Common::Point(2, 2)) | 0x10000, 1)) gnap._actionStatus = kAS02UseGasWithTruck; _vm->_hotspots[kHS02WalkArea4]._flags &= ~SF_WALKABLE; } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[2], 2, 2); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(2, 2)); break; case GRAB_CURSOR: if (_vm->isFlag(kGFTruckKeysUsed)) { if (gnap.walkTo(_vm->_hotspotsWalkPos[3], 0, gnap.getSequenceId(kGSIdle, Common::Point(2, 2)) | 0x10000, 1)) { if (_vm->isFlag(kGFTruckFilledWithGas)) gnap._actionStatus = kAS02UseTruckGas; else gnap._actionStatus = kAS02UseTruckNoGas; } } else { gnap._idleFacing = kDirIdleRight; if (gnap.walkTo(_vm->_hotspotsWalkPos[3], 0, gnap.getSequenceId(kGSIdle, Common::Point(2, 2)) | 0x10000, 1)) gnap._actionStatus = kAS02UseTruckNoKeys; } break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS02TruckGrill: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[4], 2, 4); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playMoan2(Common::Point(2, 4)); break; case GRAB_CURSOR: gnap._idleFacing = kDirUpRight; gnap.walkTo(_vm->_hotspotsWalkPos[4], 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS02GrabTruckGrill; break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS02ExitHouse: if (gnap._actionStatus < 0) { _vm->_isLeavingScene = true; gnap.walkTo(_vm->_hotspotsWalkPos[6], 0, 0x107AD, 1); gnap._actionStatus = kAS02LeaveScene; if (_vm->isFlag(kGFPlatypus)) plat.walkTo(_vm->_hotspotsWalkPos[6] + Common::Point(1, 0), -1, 0x107C1, 1); updateHotspots(); _vm->_newSceneNum = 4; } break; case kHS02ExitBarn: if (gnap._actionStatus < 0) { _vm->_isLeavingScene = true; gnap.walkTo(_vm->_hotspotsWalkPos[7], 0, 0x107AD, 1); gnap._actionStatus = kAS02LeaveScene; if (_vm->isFlag(kGFPlatypus)) plat.walkTo(_vm->_hotspotsWalkPos[7] + Common::Point(1, 0), -1, 0x107C1, 1); updateHotspots(); _vm->_newSceneNum = 5; } break; case kHS02ExitCreek: if (gnap._actionStatus < 0) { _vm->_isLeavingScene = true; gnap.walkTo(_vm->_hotspotsWalkPos[8], 0, 0x107AB, 1); gnap._actionStatus = kAS02LeaveScene; if (_vm->isFlag(kGFPlatypus)) plat.walkTo(_vm->_hotspotsWalkPos[8], -1, 0x107CD, 1); _vm->_newSceneNum = 3; } break; case kHS02ExitPigpen: if (gnap._actionStatus < 0) { _vm->_isLeavingScene = true; gnap.walkTo(_vm->_hotspotsWalkPos[9], 0, 0x107AF, 1); gnap._actionStatus = kAS02LeaveScene; if (_vm->isFlag(kGFPlatypus)) plat.walkTo(_vm->_hotspotsWalkPos[9], -1, 0x107CF, 1); _vm->_newSceneNum = 1; } break; case kHS02WalkArea1: case kHS02WalkArea2: case kHS02WalkArea3: case kHS02WalkArea4: if (gnap._actionStatus < 0) gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); break; default: if (_vm->_mouseClickState._left && gnap._actionStatus < 0) { gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); _vm->_mouseClickState._left = false; } break; } updateAnimations(); if (!_vm->isSoundPlaying(0x1091C)) _vm->playSound(0x1091C, true); if (!_vm->_isLeavingScene) { if (plat._actionStatus < 0 && _vm->isFlag(kGFPlatypus)) plat.updateIdleSequence(); if (gnap._actionStatus < 0) gnap.updateIdleSequence(); if (!_vm->_timers[4]) { // Update bird animation _vm->_timers[4] = _vm->getRandom(100) + 300; if (_vm->getRandom(2) != 0) gameSys.insertSequence(0x156, 256, 0, 0, kSeqNone, 0, 0, 0); else gameSys.insertSequence(0x154, 256, 0, 0, kSeqNone, 0, 0, 0); } if (!_vm->_timers[5] && _nextChickenSequenceId == -1 && gnap._actionStatus != 7 && gnap._actionStatus != 8) { if (_vm->getRandom(6) != 0) { _nextChickenSequenceId = 0x14B; _vm->_timers[5] = _vm->getRandom(20) + 30; } else { _nextChickenSequenceId = 0x14D; _vm->_timers[5] = _vm->getRandom(20) + 50; } } _vm->playSoundC(); } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); } _vm->gameUpdateTick(); } } void Scene02::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; if (gameSys.getAnimationStatus(0) == 2) { switch (gnap._actionStatus) { case kAS02UseTruckNoKeys: gameSys.insertSequence(0x14E, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(0x14E, gnap._id, 0); gnap._sequenceId = 0x14E; gnap._sequenceDatNum = 0; gnap._actionStatus = kAS02UseTruckNoKeysDone; break; case kAS02UseGasWithTruck: gameSys.insertSequence(0x151, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(0x151, gnap._id, 0); gnap._sequenceId = 0x151; gnap._sequenceDatNum = 0; _vm->invRemove(kItemGas); _vm->setGrabCursorSprite(-1); _vm->setFlag(kGFTruckFilledWithGas); gnap._actionStatus = kAS02UseGasWithTruckDone; break; case kAS02UseTruckGas: _vm->_timers[5] = 9999; _vm->_timers[4] = 9999; _vm->hideCursor(); _vm->setGrabCursorSprite(-1); if (!_vm->isFlag(kGFTruckKeysUsed)) { gameSys.insertSequence(0x14F, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.waitForUpdate(); _vm->setFlag(kGFTruckKeysUsed); gnap._sequenceId = 0x14F; gnap._sequenceDatNum = 0; _vm->invRemove(kItemKeys); _vm->setGrabCursorSprite(-1); } _vm->_newSceneNum = 47; _vm->_sceneDone = true; break; case kAS02UseTruckNoGas: _vm->hideCursor(); _vm->setGrabCursorSprite(-1); _vm->_timers[4] = 250; if (!_vm->isFlag(kGFTruckKeysUsed)) { gameSys.insertSequence(0x14F, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.waitForUpdate(); _vm->setFlag(kGFTruckKeysUsed); gnap._sequenceId = 0x14F; gnap._sequenceDatNum = 0; _vm->invRemove(kItemKeys); _vm->setGrabCursorSprite(-1); } _vm->_newSceneNum = 47; _vm->_sceneDone = true; _vm->setFlag(kGFUnk25); break; case kAS02GrabTruckGrill: switch (_truckGrillCtr) { case 0: _gnapTruckSequenceId = 0x158; break; case 1: _gnapTruckSequenceId = 0x159; break; case 2: _gnapTruckSequenceId = 0x157; break; } _truckGrillCtr = (_truckGrillCtr + 1) % 3; gameSys.insertSequence(_gnapTruckSequenceId, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(_gnapTruckSequenceId, gnap._id, 0); gnap._sequenceId = _gnapTruckSequenceId; gnap._sequenceDatNum = 0; gnap._actionStatus = -1; break; case kAS02LeaveScene: _vm->_sceneDone = true; break; case kAS02TalkChicken: _nextChickenSequenceId = 0x14C; break; case kAS02GrabChicken: _nextChickenSequenceId = 0x150; _vm->_timers[2] = 100; break; case kAS02GrabChickenDone: gameSys.insertSequence(0x107B5, gnap._id, 0x150, 179, kSeqSyncWait, 0, 75 * gnap._pos.x - gnap._gridX, 48 * gnap._pos.y - gnap._gridY); gnap._sequenceId = 0x7B5; gnap._sequenceDatNum = 1; _currChickenSequenceId = 0x14B; gameSys.setAnimation(0x14B, 179, 2); gameSys.insertSequence(_currChickenSequenceId, 179, 0, 0, kSeqNone, 0, 0, 0); gnap._actionStatus = -1; _vm->_timers[5] = 30; break; case kAS02UseTwigWithChicken: gnap.playShowItem(5, 0, 0); gameSys.insertSequence(0x155, 179, _currChickenSequenceId, 179, kSeqSyncExists, 0, 0, 0); _currChickenSequenceId = 0x155; _nextChickenSequenceId = -1; gnap._actionStatus = -1; break; case kAS02UseTruckNoKeysDone: case kAS02UseGasWithTruckDone: default: gnap._actionStatus = -1; break; } } if (gameSys.getAnimationStatus(2) == 2) { if (_nextChickenSequenceId == 0x150) { gameSys.setAnimation(_nextChickenSequenceId, 179, 0); gameSys.insertSequence(_nextChickenSequenceId, 179, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.removeSequence(_currChickenSequenceId, 179, true); _nextChickenSequenceId = -1; _currChickenSequenceId = -1; gnap._actionStatus = kAS02GrabChickenDone; _vm->_timers[5] = 500; } else if (_nextChickenSequenceId == 0x14C) { gameSys.setAnimation(_nextChickenSequenceId, 179, 2); gameSys.insertSequence(_nextChickenSequenceId, 179, _currChickenSequenceId, 179, kSeqSyncWait, 0, 0, 0); _currChickenSequenceId = _nextChickenSequenceId; _nextChickenSequenceId = -1; gnap._actionStatus = -1; } else if (_nextChickenSequenceId != -1) { gameSys.setAnimation(_nextChickenSequenceId, 179, 2); gameSys.insertSequence(_nextChickenSequenceId, 179, _currChickenSequenceId, 179, kSeqSyncWait, 0, 0, 0); _currChickenSequenceId = _nextChickenSequenceId; _nextChickenSequenceId = -1; } } } /*****************************************************************************/ Scene03::Scene03(GnapEngine *vm) : Scene(vm) { _nextPlatSequenceId = -1; _platypusScared = false; _platypusHypnotized = false; _nextFrogSequenceId = -1; _currFrogSequenceId = -1; } int Scene03::init() { GameSys& gameSys = *_vm->_gameSys; gameSys.setAnimation(0, 0, 0); gameSys.setAnimation(0, 0, 1); gameSys.setAnimation(0, 0, 5); return 0x1CC; } void Scene03::updateHotspots() { _vm->setHotspot(kHS03Platypus, 0, 0, 0, 0, SF_DISABLED | SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS03Grass, 646, 408, 722, 458, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 9, 6); _vm->setHotspot(kHS03ExitTruck, 218, 64, 371, 224, SF_EXIT_U_CURSOR | SF_WALKABLE, 4, 4); _vm->setHotspot(kHS03Creek, 187, 499, 319, 587, SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 3, 7); _vm->setHotspot(kHS03TrappedPlatypus, 450, 256, 661, 414, SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 2, 5); _vm->setHotspot(kHS03WalkAreas1, 0, 500, 300, 600); _vm->setHotspot(kHS03WalkAreas2, 300, 447, 800, 600); _vm->setHotspot(kHS03PlatypusWalkArea, 235, 0, 800, 600); _vm->setHotspot(kHS03WalkAreas3, 0, 0, 800, 354); _vm->setDeviceHotspot(kHS03Device, -1, -1, -1, -1); if (_vm->isFlag(kGFPlatypus)) _vm->_hotspots[kHS03Platypus]._flags = SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR; if (_vm->isFlag(kGFGrassTaken)) _vm->_hotspots[kHS03Grass]._flags = SF_WALKABLE | SF_DISABLED; if (_vm->isFlag(kGFPlatypus)) _vm->_hotspots[kHS03TrappedPlatypus]._flags = SF_DISABLED; if (_vm->isFlag(kGFPlatypus) || _platypusHypnotized) _vm->_hotspots[kHS03PlatypusWalkArea]._flags |= SF_WALKABLE; _vm->_hotspotsCount = 10; } void Scene03::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; _vm->playSound(0x10925, true); _vm->startSoundTimerC(7); gameSys.insertSequence(0x1CA, 251, 0, 0, kSeqLoop, 0, 0, 0); gameSys.insertSequence(0x1CB, 251, 0, 0, kSeqLoop, 0, 0, 0); _platypusHypnotized = false; gnap.initPos(3, 4, kDirBottomRight); gameSys.insertSequence(0x1C6, 253, 0, 0, kSeqNone, 0, 0, 0); _currFrogSequenceId = 0x1C6; _nextFrogSequenceId = -1; gameSys.setAnimation(0x1C6, 253, 2); _vm->_timers[6] = _vm->getRandom(20) + 30; _vm->_timers[4] = _vm->getRandom(100) + 300; _vm->_timers[5] = _vm->getRandom(100) + 200; if (_vm->isFlag(kGFPlatypus)) { plat.initPos(5, 4, kDirIdleLeft); } else { _vm->_timers[1] = _vm->getRandom(40) + 20; gameSys.setAnimation(0x1C2, 99, 1); gameSys.insertSequence(0x1C2, 99, 0, 0, kSeqNone, 0, 0, 0); plat._sequenceId = 0x1C2; plat._sequenceDatNum = 0; } gameSys.insertSequence(0x1C4, 255, 0, 0, kSeqNone, 0, 0, 0); if (!_vm->isFlag(kGFGrassTaken)) gameSys.insertSequence(0x1B2, 253, 0, 0, kSeqNone, 0, 0, 0); _vm->queueInsertDeviceIcon(); _vm->endSceneInit(); if (_vm->isFlag(kGFPlatypus)) plat.walkTo(Common::Point(4, 7), -1, 0x107C2, 1); gnap.walkTo(Common::Point(3, 6), -1, 0x107B9, 1); while (!_vm->_sceneDone) { _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS03Platypus: if (gnap._actionStatus < 0 && _vm->isFlag(kGFPlatypus)) { if (_vm->_grabCursorSpriteIndex == kItemDisguise) { gnap.useDisguiseOnPlatypus(); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: if (_vm->isFlag(kGFKeysTaken)) gnap.playMoan1(plat._pos); else gnap.playScratchingHead(plat._pos); break; case GRAB_CURSOR: gnap.kissPlatypus(0); break; case TALK_CURSOR: gnap.playBrainPulsating(plat._pos); plat.playSequence(plat.getSequenceId()); break; case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS03Grass: if (gnap._actionStatus < 0) { if (_vm->isFlag(kGFGrassTaken)) { gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowItem(_vm->_grabCursorSpriteIndex, 9, 6); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(9, 6)); break; case GRAB_CURSOR: gnap.playPullOutDevice(Common::Point(9, 6)); gnap.playUseDevice(); gameSys.insertSequence(0x1B3, 253, 0x1B2, 253, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(0x1B3, 253, 5); _vm->_hotspots[kHS03Grass]._flags |= SF_WALKABLE | SF_DISABLED; break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS03ExitTruck: if (gnap._actionStatus < 0) { _vm->_isLeavingScene = true; _vm->_hotspots[kHS03PlatypusWalkArea]._flags |= SF_WALKABLE; gnap.walkTo(_vm->_hotspotsWalkPos[2], 0, 0x107AD, 1); gnap._actionStatus = kAS03LeaveScene; if (_vm->isFlag(kGFPlatypus)) plat.walkTo(_vm->_hotspotsWalkPos[2], -1, 0x107C2, 1); _vm->_hotspots[kHS03PlatypusWalkArea]._flags &= ~SF_WALKABLE; if (_vm->_cursorValue == 1) _vm->_newSceneNum = 2; else _vm->_newSceneNum = 33; } break; case kHS03Creek: if (gnap._actionStatus == -1) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playMoan2(Common::Point(2, 8)); break; case GRAB_CURSOR: if (!_vm->isFlag(kGFPlatypus)) _vm->_hotspots[kHS03PlatypusWalkArea]._flags |= SF_WALKABLE; if (gnap.walkTo(_vm->_hotspotsWalkPos[3], 0, gnap.getSequenceId(kGSIdle, _vm->_hotspotsWalkPos[3] + Common::Point(1, 1)) | 0x10000, 1)) gnap._actionStatus = kAS03GrabCreek; if (!_vm->isFlag(kGFPlatypus)) _vm->_hotspots[kHS03PlatypusWalkArea]._flags &= ~SF_WALKABLE; break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS03TrappedPlatypus: if (gnap._actionStatus < 0) { if (_vm->isFlag(kGFPlatypus)) { gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowItem(_vm->_grabCursorSpriteIndex, 8, 4); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(8, 4)); break; case GRAB_CURSOR: if (_platypusHypnotized) { gnap.walkTo(Common::Point(7, 6), 0, 0x107B5, 1); gnap._actionStatus = kAS03FreePlatypus; } else { gnap.walkTo(_vm->_hotspotsWalkPos[4], 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1); if (_platypusScared) gnap._actionStatus = kAS03GrabScaredPlatypus; else gnap._actionStatus = kAS03GrabPlatypus; } break; case TALK_CURSOR: if (_platypusHypnotized) { gnap.playBrainPulsating(Common::Point(8, 4)); } else { gnap._idleFacing = kDirBottomRight; gnap.walkTo(_vm->_hotspotsWalkPos[4], 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1); if (_platypusScared) gnap._actionStatus = kAS03HypnotizeScaredPlat; else gnap._actionStatus = kAS03HypnotizePlat; } break; case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS03Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); } break; case kHS03WalkAreas1: case kHS03WalkAreas2: case kHS03WalkAreas3: if (gnap._actionStatus < 0) gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); break; case kHS03PlatypusWalkArea: if (gnap._actionStatus < 0) { if (_vm->isFlag(kGFPlatypus) || _platypusHypnotized) { gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); } else { gnap.walkTo(_vm->_hotspotsWalkPos[4], 0, 0x107B5, 1); if (_platypusScared) gnap._actionStatus = kAS03GrabScaredPlatypus; else gnap._actionStatus = kAS03GrabPlatypus; } } break; default: if (_vm->_mouseClickState._left && gnap._actionStatus < 0) { gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); _vm->_mouseClickState._left = false; } break; } updateAnimations(); if (!_vm->isSoundPlaying(0x10925)) _vm->playSound(0x10925, true); if (!_vm->_isLeavingScene) { if (plat._actionStatus < 0 && _vm->isFlag(kGFPlatypus)) plat.updateIdleSequence(); if (gnap._actionStatus < 0) gnap.updateIdleSequence(); if (!_vm->_timers[1] && !_platypusScared) { _vm->_timers[1] = _vm->getRandom(40) + 20; if (gnap._actionStatus < 0 && plat._actionStatus < 0 && !_vm->isFlag(kGFPlatypus) && !_platypusHypnotized) _nextPlatSequenceId = 450; } if (!_vm->_timers[6]) { _vm->_timers[6] = _vm->getRandom(20) + 30; if (gnap._actionStatus < 0 && plat._actionStatus < 0 && _nextFrogSequenceId == -1) { if (_vm->getRandom(5) == 1) _nextFrogSequenceId = 0x1C6; else _nextFrogSequenceId = 0x1C7; } } if (!_vm->_timers[4]) { // Update bird animation _vm->_timers[4] = _vm->getRandom(100) + 300; if (gnap._actionStatus < 0 && plat._actionStatus < 0) gameSys.insertSequence(_vm->getRandom(2) != 0 ? 0x1C8 : 0x1C3, 253, 0, 0, kSeqNone, 0, 0, 0); } if (!_vm->_timers[5]) { _vm->_timers[5] = _vm->getRandom(100) + 200; if (gnap._actionStatus < 0 && plat._actionStatus < 0) { gameSys.setAnimation(0x1C5, 253, 4); gameSys.insertSequence(0x1C5, 253, 0, 0, kSeqNone, 0, 0, 0); } } _vm->playSoundC(); } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); _vm->_timers[5] = _vm->getRandom(100) + 200; _vm->_timers[4] = _vm->getRandom(100) + 300; _vm->_timers[6] = _vm->getRandom(20) + 30; } _vm->gameUpdateTick(); } } void Scene03::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; if (gameSys.getAnimationStatus(0) == 2) { gameSys.setAnimation(0, 0, 0); switch (gnap._actionStatus) { case kAS03LeaveScene: _vm->_sceneDone = true; break; case kAS03FreePlatypus: _nextPlatSequenceId = 0x1BC; break; case kAS03FreePlatypusDone: gnap._actionStatus = -1; plat._pos = Common::Point(6, 6); plat._idleFacing = kDirIdleRight; plat._id = 120; gameSys.insertSequence(0x107CA, plat._id, 0x1BC, 99, kSeqSyncWait, 0, 75 * plat._pos.x - plat._gridX, 48 * plat._pos.y - plat._gridY); gameSys.insertSequence(0x1B7, 99, 0, 0, kSeqNone, 0, 0, 0); plat._sequenceDatNum = 1; plat._sequenceId = 0x7CA; _vm->setFlag(kGFPlatypus); _nextPlatSequenceId = -1; updateHotspots(); break; case kAS03HypnotizePlat: gnap.playBrainPulsating(); _vm->addFullScreenSprite(0x106, 255); gameSys.setAnimation(0x1C9, 256, 1); gameSys.insertSequence(0x1C9, 256, 0, 0, kSeqNone, 0, 0, 0); while (gameSys.getAnimationStatus(1) != 2 && !_vm->_gameDone) _vm->gameUpdateTick(); _vm->removeFullScreenSprite(); gameSys.setAnimation(0x1BA, 99, 1); gameSys.insertSequence(0x1BA, 99, plat._sequenceId | (plat._sequenceDatNum << 16), 99, kSeqSyncExists, 0, 0, 0); plat._sequenceDatNum = 0; plat._sequenceId = 0x1BA; gnap._actionStatus = -1; _platypusHypnotized = true; updateHotspots(); break; case kAS03HypnotizeScaredPlat: gnap.playBrainPulsating(); gameSys.insertSequence(0x1BF, 99, plat._sequenceId | (plat._sequenceDatNum << 16), 99, kSeqSyncExists, 0, 0, 0); gameSys.setAnimation(0x1BF, 99, 1); while (gameSys.getAnimationStatus(1) != 2 && !_vm->_gameDone) _vm->gameUpdateTick(); _vm->addFullScreenSprite(0x106, 255); gameSys.setAnimation(0x1C9, 256, 1); gameSys.insertSequence(0x1C9, 256, 0, 0, kSeqNone, 0, 0, 0); while (gameSys.getAnimationStatus(1) != 2 && !_vm->_gameDone) _vm->gameUpdateTick(); _vm->removeFullScreenSprite(); gameSys.setAnimation(0x1BA, 99, 1); gameSys.insertSequence(0x1BA, 99, 447, 99, kSeqSyncWait, 0, 0, 0); plat._sequenceDatNum = 0; plat._sequenceId = 0x1BA; gnap._actionStatus = -1; _platypusHypnotized = true; updateHotspots(); break; case kAS03GrabPlatypus: _nextPlatSequenceId = 0x1BD; _platypusHypnotized = false; break; case kAS03GrabScaredPlatypus: _nextPlatSequenceId = 0x1C0; _platypusHypnotized = false; break; case kAS03GrabCreek: gameSys.insertSequence(0x1B4, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(0x1B4, gnap._id, 0); gnap._sequenceId = 0x1B4; gnap._sequenceDatNum = 0; gnap._actionStatus = kAS03GrabCreekDone; break; default: gnap._actionStatus = -1; break; } } if (gameSys.getAnimationStatus(1) == 2) { if (_nextPlatSequenceId == 0x1BD || _nextPlatSequenceId == 0x1C0) { gameSys.setAnimation(0, 0, 1); _platypusScared = true; gameSys.insertSequence(0x1B5, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(_nextPlatSequenceId, 99, plat._sequenceId | (plat._sequenceDatNum << 16), 99, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0x1B5; gnap._sequenceDatNum = 0; gnap._idleFacing = kDirIdleLeft; plat._sequenceId = _nextPlatSequenceId; plat._sequenceDatNum = 0; gameSys.setAnimation(_nextPlatSequenceId, 99, 1); _nextPlatSequenceId = -1; gnap._actionStatus = -1; } else if (_nextPlatSequenceId == 0x1BC) { gnap._pos = Common::Point(3, 6); gameSys.insertSequence(0x1B6, 120, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x1BC, 99, plat._sequenceId | (plat._sequenceDatNum << 16), 99, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(0x1BC, 99, 0); gnap._id = 20 * gnap._pos.y; gnap._sequenceId = 0x1B6; gnap._sequenceDatNum = 0; gnap._idleFacing = kDirIdleLeft; gnap._actionStatus = kAS03FreePlatypusDone; _nextPlatSequenceId = -1; } else if (_nextPlatSequenceId == 0x1C2 && !_platypusScared) { gameSys.setAnimation(0, 0, 1); gameSys.insertSequence(0x1C2, 99, plat._sequenceId | (plat._sequenceDatNum << 16), 99, kSeqSyncWait, 0, 0, 0); plat._sequenceId = 0x1C2; plat._sequenceDatNum = 0; gameSys.setAnimation(0x1C2, 99, 1); _nextPlatSequenceId = -1; } else if (_nextPlatSequenceId == -1 && _platypusScared && !_platypusHypnotized) { gameSys.setAnimation(0, 0, 1); gameSys.setAnimation(0x1BE, 99, 1); gameSys.insertSequence(0x1BE, 99, plat._sequenceId | (plat._sequenceDatNum << 16), 99, kSeqSyncWait, 0, 0, 0); plat._sequenceId = 0x1BE; plat._sequenceDatNum = 0; _nextPlatSequenceId = -1; } } if (gameSys.getAnimationStatus(2) == 2 && _nextFrogSequenceId != -1) { gameSys.setAnimation(_nextFrogSequenceId, 253, 2); gameSys.insertSequence(_nextFrogSequenceId, 253, _currFrogSequenceId, 253, kSeqSyncWait, 0, 0, 0); _currFrogSequenceId = _nextFrogSequenceId; _nextFrogSequenceId = -1; } if (gameSys.getAnimationStatus(5) == 2) { gameSys.setAnimation(0, 0, 5); _vm->invAdd(kItemGrass); _vm->setGrabCursorSprite(kItemGrass); _vm->setFlag(kGFGrassTaken); updateHotspots(); } } /*****************************************************************************/ Scene04::Scene04(GnapEngine *vm) : Scene(vm) { _dogIdCtr = 0; _triedWindow = false; _nextDogSequenceId = -1; _currDogSequenceId = -1; } int Scene04::init() { GameSys& gameSys = *_vm->_gameSys; gameSys.setAnimation(0, 0, 0); gameSys.setAnimation(0, 0, 1); gameSys.setAnimation(0, 0, 2); return 0x214; } void Scene04::updateHotspots() { _vm->setHotspot(kHS04Platypus, 0, 0, 0, 0, SF_DISABLED | SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS04Twig, 690, 394, 769, 452, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 9, 6); _vm->setHotspot(kHS04Dog, 550, 442, 680, 552, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 6, 8); _vm->setHotspot(kHS04Axe, 574, 342, 680, 412, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 6, 7); _vm->setHotspot(kHS04Door, 300, 244, 386, 410, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 6, 7); _vm->setHotspot(kHS04ExitTruck, 226, 580, 688, 600, SF_EXIT_D_CURSOR | SF_WALKABLE, 5, 9); _vm->setHotspot(kHS04Window, 121, 295, 237, 342, SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 3, 7); _vm->setHotspot(kHS04ExitBarn, 585, 154, 800, 276, SF_EXIT_U_CURSOR, 10, 8); _vm->setHotspot(kHS04WalkArea1, 0, 0, 562, 461); _vm->setHotspot(kHS04WalkArea2, 562, 0, 800, 500); _vm->setDeviceHotspot(kHS04Device, -1, -1, -1, -1); if (_vm->isFlag(kGFPlatypus)) _vm->_hotspots[kHS04Platypus]._flags = SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR; if (_vm->isFlag(kGFTwigTaken)) _vm->_hotspots[kHS04Twig]._flags = SF_WALKABLE | SF_DISABLED; if (_vm->isFlag(kGFPlatypusTalkingToAssistant) || _vm->_cursorValue == 1) _vm->_hotspots[kHS04Axe]._flags = SF_DISABLED; _vm->_hotspotsCount = 11; } void Scene04::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; _vm->playSound(0x1091C, true); _vm->startSoundTimerC(4); gameSys.insertSequence(0x210, 139 - _dogIdCtr, 0, 0, kSeqNone, 0, 0, 0); _currDogSequenceId = 0x210; _nextDogSequenceId = -1; gameSys.setAnimation(0x210, 139 - _dogIdCtr, 3); _dogIdCtr = (_dogIdCtr + 1) % 2; _vm->_timers[6] = _vm->getRandom(20) + 60; _vm->_timers[5] = _vm->getRandom(150) + 300; _vm->_timers[7] = _vm->getRandom(150) + 200; _vm->_timers[8] = _vm->getRandom(150) + 400; if (!_vm->isFlag(kGFPlatypusTalkingToAssistant) && _vm->_cursorValue == 4) gameSys.insertSequence(0x212, 100, 0, 0, kSeqNone, 0, 0, 0); if (!_vm->isFlag(kGFTwigTaken)) gameSys.insertSequence(0x1FE, 100, 0, 0, kSeqNone, 0, 0, 0); _vm->queueInsertDeviceIcon(); if (_vm->isFlag(kGFPlatypusDisguised)) { _vm->_timers[3] = 300; _vm->setGrabCursorSprite(kItemKeys); gnap._pos = Common::Point(4, 7); gnap._id = 140; plat._pos = Common::Point(6, 7); plat._id = 141; gameSys.insertSequence(0x107B5, 140, 0, 0, kSeqNone, 0, 300 - gnap._gridX, 336 - gnap._gridY); gameSys.insertSequence(0x20C, 141, 0, 0, kSeqNone, 0, 0, 0); gameSys.insertSequence(0x208, 121, 0, 0, kSeqNone, 0, 0, 0); gameSys.insertSequence(0x209, 121, 0x208, 121, kSeqSyncWait, 0, 0, 0); _vm->endSceneInit(); _vm->invRemove(kItemDisguise); _vm->invAdd(kItemKeys); _vm->setFlag(kGFKeysTaken); _vm->clearFlag(kGFPlatypusDisguised); plat._sequenceId = 0x20C; plat._sequenceDatNum = 0; plat._idleFacing = kDirBottomRight; gnap._sequenceId = 0x7B5; gnap._sequenceDatNum = 1; gameSys.waitForUpdate(); } else { gameSys.insertSequence(0x209, 121, 0, 0, kSeqNone, 0, 0, 0); if (_vm->_prevSceneNum == 2) { gnap.initPos(5, 11, kDirUpRight); if (_vm->isFlag(kGFPlatypus)) plat.initPos(6, 11, kDirUpLeft); _vm->endSceneInit(); if (_vm->isFlag(kGFPlatypus)) plat.walkTo(Common::Point(5, 8), -1, 0x107C2, 1); gnap.walkTo(Common::Point(6, 9), -1, 0x107BA, 1); } else if (_vm->_prevSceneNum == 38) { gnap.initPos(5, 7, kDirBottomRight); plat.initPos(4, 7, kDirIdleLeft); _vm->endSceneInit(); } else { gnap.initPos(12, 9, kDirBottomRight); if (_vm->isFlag(kGFPlatypus)) plat.initPos(12, 8, kDirIdleLeft); _vm->endSceneInit(); if (_vm->isFlag(kGFPlatypus)) plat.walkTo(Common::Point(9, 8), -1, 0x107C2, 1); gnap.walkTo(Common::Point(9, 9), -1, 0x107BA, 1); } } while (!_vm->_sceneDone) { _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->testWalk(0, 4, -1, -1, -1, -1); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS04Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); } break; case kHS04Platypus: if (gnap._actionStatus < 0 && _vm->isFlag(kGFPlatypus)) { if (_vm->_grabCursorSpriteIndex == kItemDisguise) { gnap.useDisguiseOnPlatypus(); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: if (_vm->isFlag(kGFKeysTaken)) gnap.playMoan1(plat._pos); else gnap.playScratchingHead(plat._pos); break; case GRAB_CURSOR: if (_vm->_cursorValue == 4) gnap.kissPlatypus(0); else gnap.playMoan1(plat._pos); break; case TALK_CURSOR: gnap.playBrainPulsating(plat._pos); plat.playSequence(plat.getSequenceId()); break; case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS04Twig: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowItem(_vm->_grabCursorSpriteIndex, 9, 6); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(_vm->_hotspotsWalkPos[1]); break; case GRAB_CURSOR: gnap.playPullOutDevice(_vm->_hotspotsWalkPos[1]); gnap.playUseDevice(_vm->_hotspotsWalkPos[1]); gameSys.insertSequence(0x1FD, 100, 510, 100, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(0x1FD, 100, 2); break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS04Axe: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[3], 9, 5); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playMoan2(_vm->_hotspotsWalkPos[3]); break; case GRAB_CURSOR: gnap._idleFacing = kDirUpRight; gnap.walkTo(_vm->_hotspotsWalkPos[3], 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS04GrabAxe; _vm->setFlag(kGFPlatypusTalkingToAssistant); updateHotspots(); break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS04Dog: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[2], 9, 7); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: if (gnap.walkTo(gnap._pos, 0, -1, 1)) { gnap.playMoan2(_vm->_hotspotsWalkPos[2]); _nextDogSequenceId = 0x20F; } break; case GRAB_CURSOR: gnap._idleFacing = kDirBottomRight; if (gnap.walkTo(_vm->_hotspotsWalkPos[2], 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1)) gnap._actionStatus = kAS04GrabDog; break; case TALK_CURSOR: gnap._idleFacing = kDirBottomRight; if (gnap.walkTo(gnap._pos, 0, -1, 1)) { gnap.playBrainPulsating(_vm->_hotspotsWalkPos[2]); _nextDogSequenceId = 0x20E; } break; case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS04Door: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 4, 3); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: case PLAT_CURSOR: gnap.playScratchingHead(Common::Point(4, 3)); break; case GRAB_CURSOR: if (_vm->_cursorValue == 1) { gnap.walkTo(_vm->_hotspotsWalkPos[4], 0, 0x107BC, 1); gnap._actionStatus = kAS04OpenDoor; _vm->_timers[5] = 300; gnap._idleFacing = kDirUpLeft; } else { _vm->_isLeavingScene = true; gnap.walkTo(_vm->_hotspotsWalkPos[4], 0, 0x107BC, 1); gnap._actionStatus = kAS04LeaveScene; _vm->_newSceneNum = 38; } break; case TALK_CURSOR: gnap.playImpossible(); break; } } } break; case kHS04ExitTruck: if (gnap._actionStatus < 0) { _vm->_isLeavingScene = true; gnap.walkTo(_vm->_hotspotsWalkPos[5], 0, 0x107AE, 1); gnap._actionStatus = kAS04LeaveScene; if (_vm->isFlag(kGFPlatypus)) plat.walkTo(_vm->_hotspotsWalkPos[5], -1, 0x107C7, 1); if (_vm->_cursorValue == 1) _vm->_newSceneNum = 2; else _vm->_newSceneNum = 33; } break; case kHS04Window: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 2, 3); } else if (_vm->isFlag(kGFKeysTaken)) { gnap.playImpossible(); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: if (gnap.walkTo(_vm->_hotspotsWalkPos[7], 0, gnap.getSequenceId(kGSIdle, Common::Point(10, 2)) | 0x10000, 1)) { if (_triedWindow) { gnap._actionStatus = kAS04GetKeyAnother; } else { gnap._actionStatus = kAS04GetKeyFirst; _triedWindow = true; } } break; case GRAB_CURSOR: gnap.playScratchingHead(_vm->_hotspotsWalkPos[7]); break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS04ExitBarn: if (gnap._actionStatus < 0) { _vm->_isLeavingScene = true; gnap.walkTo(_vm->_hotspotsWalkPos[8], 0, 0x107AB, 1); gnap._actionStatus = kAS04LeaveScene; if (_vm->isFlag(kGFPlatypus)) plat.walkTo(_vm->_hotspotsWalkPos[8] + Common::Point(0, 1), -1, 0x107C1, 1); if (_vm->_cursorValue == 1) _vm->_newSceneNum = 5; else _vm->_newSceneNum = 35; } break; case kHS04WalkArea1: case kHS04WalkArea2: if (gnap._actionStatus < 0) gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); break; default: if (_vm->_mouseClickState._left && gnap._actionStatus < 0) { gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); _vm->_mouseClickState._left = false; } break; } updateAnimations(); if (!_vm->isSoundPlaying(0x1091C)) _vm->playSound(0x1091C, true); if (!_vm->_isLeavingScene) { if (plat._actionStatus < 0 && _vm->isFlag(kGFPlatypus)) plat.updateIdleSequence2(); if (gnap._actionStatus < 0) gnap.updateIdleSequence2(); if (!_vm->_timers[5]) { _vm->_timers[5] = _vm->getRandom(150) + 300; if (gnap._actionStatus < 0) gameSys.insertSequence(0x20D, 79, 0, 0, kSeqNone, 0, 0, 0); } if (!_vm->_timers[7]) { _vm->_timers[7] = _vm->getRandom(150) + 200; gameSys.insertSequence(0x1FC, 59, 0, 0, kSeqNone, 0, 0, 0); } if (!_vm->_timers[6]) { _vm->_timers[6] = _vm->getRandom(20) + 60; if (_nextDogSequenceId == -1) _nextDogSequenceId = 0x210; } if (!_vm->_timers[8]) { _vm->_timers[8] = _vm->getRandom(150) + 400; gameSys.insertSequence(0x213, 20, 0, 0, kSeqNone, 0, 0, 0); } _vm->playSoundC(); } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); } _vm->gameUpdateTick(); } } void Scene04::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; if (gameSys.getAnimationStatus(0) == 2) { gameSys.setAnimation(0, 0, 0); switch (gnap._actionStatus) { case kAS04LeaveScene: _vm->_sceneDone = true; break; case kAS04OpenDoor: gameSys.insertSequence(0x205, gnap._id, 0, 0, kSeqNone, 0, 0, 0); gameSys.insertSequence(0x207, 121, 521, 121, kSeqSyncWait, 0, 0, 0); gnap._pos = Common::Point(6, 7); gameSys.insertSequence(0x107B5, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, _vm->getSequenceTotalDuration(0x205) - 1, 450 - gnap._gridX, 336 - gnap._gridY); gameSys.setAnimation(0x107B5, gnap._id, 0); gnap._sequenceId = 0x7B5; gnap._sequenceDatNum = 1; gnap._actionStatus = kAS04OpenDoorDone; break; case kAS04OpenDoorDone: gameSys.insertSequence(0x209, 121, 0x207, 121, kSeqSyncWait, 0, 0, 0); gnap._actionStatus = -1; break; case kAS04GetKeyFirst: gameSys.insertSequence(0x204, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(0x204, gnap._id, 0); gnap._sequenceId = 0x204; gnap._sequenceDatNum = 0; gnap._actionStatus = kAS04GetKeyFirst2; break; case kAS04GetKeyFirst2: gameSys.insertSequence(0x206, 255, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x1FF, 256, 0, 0, kSeqNone, 0, 0, 0); gameSys.insertSequence(0x20B, 256, 0, 0, kSeqNone, 0, 0, 0); gameSys.setAnimation(0x20B, 256, 0); gnap._sequenceId = 0x206; gnap._sequenceDatNum = 0; gnap._actionStatus = kAS04GetKeyFirstDone; break; case kAS04GetKeyFirstDone: gameSys.requestRemoveSequence(0x1FF, 256); gameSys.requestRemoveSequence(0x20B, 256); gameSys.insertSequence(0x107B5, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), 255, kSeqSyncWait, 0, 75 * gnap._pos.x - gnap._gridX, 48 * gnap._pos.y - gnap._gridY); gnap._idleFacing = kDirBottomRight; gnap._sequenceId = 0x7B5; gnap._sequenceDatNum = 1; gnap._actionStatus = -1; break; case kAS04GetKeyAnother: gameSys.insertSequence(0x202, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(0x202, gnap._id, 0); gnap._sequenceId = 0x202; gnap._sequenceDatNum = 0; gnap._actionStatus = kAS04GetKeyAnother2; break; case kAS04GetKeyAnother2: gameSys.insertSequence(0x203, 255, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x1FF, 256, 0, 0, kSeqNone, 0, 0, 0); gameSys.insertSequence(0x20A, 256, 0, 0, kSeqNone, 0, 0, 0); gameSys.setAnimation(0x20A, 256, 0); gnap._sequenceId = 0x203; gnap._sequenceDatNum = 0; gnap._actionStatus = kAS04GetKeyAnotherDone; break; case kAS04GetKeyAnotherDone: gameSys.removeSequence(0x1FF, 256, true); gameSys.removeSequence(0x20A, 256, true); gameSys.insertSequence(0x107B5, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), 255, kSeqSyncWait, 0, 75 * gnap._pos.x - gnap._gridX, 48 * gnap._pos.y - gnap._gridY); gnap._sequenceId = 0x7B5; gnap._sequenceDatNum = 1; gnap._idleFacing = kDirBottomRight; gnap._actionStatus = -1; break; case kAS04GrabDog: _nextDogSequenceId = 0x201; break; case kAS04GrabAxe: gameSys.insertSequence(0x211, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.requestRemoveSequence(0x212, 100); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x211; gnap._actionStatus = -1; break; default: gnap._actionStatus = -1; break; } } if (gameSys.getAnimationStatus(2) == 2) { gameSys.setAnimation(0, 0, 2); _vm->invAdd(kItemTwig); _vm->setGrabCursorSprite(kItemTwig); _vm->setFlag(kGFTwigTaken); updateHotspots(); } if (gameSys.getAnimationStatus(3) == 2) { if (_nextDogSequenceId == 0x201) { gameSys.insertSequence(_nextDogSequenceId, 139 - _dogIdCtr, _currDogSequenceId, 139 - (_dogIdCtr + 1) % 2, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x200, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(_nextDogSequenceId, 139 - _dogIdCtr, 3); _dogIdCtr = (_dogIdCtr + 1) % 2; _currDogSequenceId = 0x201; gnap._sequenceId = 0x200; gnap._sequenceDatNum = 0; gnap._actionStatus = -1; _vm->_timers[6] = _vm->getRandom(20) + 60; _nextDogSequenceId = -1; } else if (_nextDogSequenceId != -1) { gameSys.insertSequence(_nextDogSequenceId, 139 - _dogIdCtr, _currDogSequenceId, 139 - (_dogIdCtr + 1) % 2, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(_nextDogSequenceId, 139 - _dogIdCtr, 3); _dogIdCtr = (_dogIdCtr + 1) % 2; _currDogSequenceId = _nextDogSequenceId; _nextDogSequenceId = -1; } } } /*****************************************************************************/ Scene05::Scene05(GnapEngine *vm) : Scene(vm) { _nextChickenSequenceId = -1; _currChickenSequenceId = -1; } int Scene05::init() { GameSys& gameSys = *_vm->_gameSys; gameSys.setAnimation(0, 0, 0); gameSys.setAnimation(0, 0, 1); gameSys.setAnimation(0, 0, 3); return _vm->isFlag(kGFBarnPadlockOpen) ? 0x151 : 0x150; } void Scene05::updateHotspots() { _vm->setHotspot(kHS05Platypus, 0, 0, 0, 0, SF_DISABLED | SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS05Haystack, 236, 366, 372, 442, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 5, 7); _vm->setHotspot(kHS05Padlock, 386, 230, 626, 481, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 5, 7); _vm->setHotspot(kHS05Ladder, 108, 222, 207, 444, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 4, 7); _vm->setHotspot(kHS05ExitHouse, 0, 395, 20, 600, SF_EXIT_L_CURSOR | SF_WALKABLE, 0, 8); _vm->setHotspot(kHS05Chicken, 612, 462, 722, 564, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 7, 8); _vm->setHotspot(kHS05WalkArea1, 104, 0, 421, 480); _vm->setHotspot(kHS05WalkArea2, 422, 0, 800, 487); _vm->setHotspot(kHS05WalkArea3, 0, 0, 104, 499); _vm->setDeviceHotspot(kHS05Device, -1, -1, -1, -1); if (_vm->isFlag(kGFPlatypus)) _vm->_hotspots[kHS05Platypus]._flags = SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR; if (_vm->isFlag(kGFBarnPadlockOpen)) _vm->_hotspots[kHS05Padlock]._flags = SF_EXIT_U_CURSOR; _vm->_hotspotsCount = 10; } void Scene05::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; _vm->playSound(0x1091C, true); _vm->startSoundTimerC(7); _currChickenSequenceId = 0x142; gameSys.setAnimation(0x142, 100, 3); gameSys.insertSequence(0x142, 100, 0, 0, kSeqNone, 0, 0, 0); _nextChickenSequenceId = -1; _vm->_timers[5] = _vm->getRandom(10) + 30; _vm->_timers[6] = _vm->getRandom(150) + 300; if (_vm->isFlag(kGFBarnPadlockOpen)) gameSys.insertSequence(0x14A, 141, 0, 0, kSeqNone, 0, 0, 0); _vm->queueInsertDeviceIcon(); if (_vm->_prevSceneNum != 6 && _vm->_prevSceneNum != 36) { gnap.initPos(-1, 8, kDirBottomRight); if (_vm->isFlag(kGFPlatypus)) plat.initPos(-1, 9, kDirIdleLeft); _vm->endSceneInit(); if (_vm->isFlag(kGFPlatypus)) plat.walkTo(Common::Point(2, 8), -1, 0x107C2, 1); gnap.walkTo(Common::Point(2, 9), -1, 0x107B9, 1); } else { gnap.initPos(6, 8, kDirBottomRight); if (_vm->isFlag(kGFPlatypus)) plat.initPos(7, 9, kDirIdleLeft); _vm->endSceneInit(); } while (!_vm->_sceneDone) { _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->testWalk(0, 12, -1, -1, -1, -1); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS05Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); } break; case kHS05Platypus: if (gnap._actionStatus < 0 && _vm->isFlag(kGFPlatypus)) { if (_vm->_grabCursorSpriteIndex == kItemDisguise) { gnap.useDisguiseOnPlatypus(); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: if (_vm->isFlag(kGFKeysTaken)) gnap.playMoan1(plat._pos); else gnap.playScratchingHead(plat._pos); break; case GRAB_CURSOR: gnap.kissPlatypus(0); break; case TALK_CURSOR: gnap.playBrainPulsating(plat._pos); plat.playSequence(plat.getSequenceId()); break; case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS05Haystack: if (gnap._actionStatus < 0 && plat._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[1] + Common::Point(-2, 0), 4, 5); } else if (_vm->isFlag(kGFNeedleTaken)) { gnap.playImpossible(); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(_vm->_hotspotsWalkPos[1] + Common::Point(0, -1)); break; case GRAB_CURSOR: case TALK_CURSOR: gnap.playImpossible(); break; case PLAT_CURSOR: if (_vm->isFlag(kGFPlatypus)) { gnap.useDeviceOnPlatypus(); if (plat.walkTo(_vm->_hotspotsWalkPos[1], 1, 0x107C2, 1)) { plat._actionStatus = kAS05PlatSearchHaystack; plat._idleFacing = kDirIdleRight; } if (gnap._pos.x == 4 && (gnap._pos.y == 8 || gnap._pos.y == 7)) gnap.walkStep(); gnap.playIdle(plat._pos); } break; } } } break; case kHS05Chicken: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex == kItemTwig) { gnap._idleFacing = kDirUpRight; Common::Point checkPt = _vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot] + Common::Point(0, 1); gnap.walkTo(checkPt, 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS05UseTwigWithChicken; } else if (_vm->_grabCursorSpriteIndex >= 0) gnap.playShowCurrItem(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot] + Common::Point(0, 1), 9, 7); else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playMoan2(Common::Point(9, 7)); break; case GRAB_CURSOR: gnap._idleFacing = kDirBottomRight; gnap.walkTo(_vm->_hotspotsWalkPos[5], 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS05GrabChicken; break; case TALK_CURSOR: gnap._idleFacing = kDirBottomRight; gnap.walkTo(_vm->_hotspotsWalkPos[5], 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS05TalkChicken; break; case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS05Ladder: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 2, 5); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playMoan2(Common::Point(2, 4)); break; case GRAB_CURSOR: gnap._idleFacing = kDirBottomLeft; gnap.walkTo(_vm->_hotspotsWalkPos[3], 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS05GrabLadder; break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS05Padlock: if (_vm->isFlag(kGFBarnPadlockOpen)) { _vm->_isLeavingScene = true; Common::Point destPt = _vm->_hotspotsWalkPos[2] + Common::Point(- 1, 1); gnap.walkTo(destPt, 0, -1, 1); gnap._actionStatus = kAS05EnterBarn; if (_vm->_cursorValue == 1) _vm->_newSceneNum = 6; else _vm->_newSceneNum = 36; } else if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex == kItemNeedle) { if (gnap.walkTo(_vm->_hotspotsWalkPos[2], 0, gnap.getSequenceId(kGSIdle, _vm->_hotspotsWalkPos[2]) | 0x10000, 1)) gnap._actionStatus = kAS05PickPadlock; } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[2], 7, 4); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(7, 4)); break; case GRAB_CURSOR: gnap._idleFacing = kDirUpRight; gnap.walkTo(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS05TryPickPadlock; break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS05ExitHouse: if (gnap._actionStatus < 0) { _vm->_isLeavingScene = true; gnap.walkTo(_vm->_hotspotsWalkPos[4], 0, 0x107AF, 1); gnap._actionStatus = kAS05LeaveScene; if (_vm->isFlag(kGFPlatypus)) plat.walkTo(_vm->_hotspotsWalkPos[4] + Common::Point(0, 1), -1, 0x107C7, 1); if (_vm->_cursorValue == 1) _vm->_newSceneNum = 4; else _vm->_newSceneNum = 37; } break; case kHS05WalkArea1: case kHS05WalkArea2: if (gnap._actionStatus < 0) gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); break; case kHS05WalkArea3: // Nothing break; default: if (_vm->_mouseClickState._left && gnap._actionStatus < 0) { gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); _vm->_mouseClickState._left = false; } break; } updateAnimations(); if (!_vm->isSoundPlaying(0x1091C)) _vm->playSound(0x1091C, true); if (!_vm->_isLeavingScene) { if (_vm->isFlag(kGFPlatypus)) plat.updateIdleSequence(); gnap.updateIdleSequence(); if (!_vm->_timers[5]) { _vm->_timers[5] = _vm->getRandom(20) + 30; if (gnap._actionStatus != kAS05TalkChicken && _nextChickenSequenceId == -1) { if (_vm->getRandom(4) != 0) _nextChickenSequenceId = 0x142; else _nextChickenSequenceId = 0x143; } } if (!_vm->_timers[6]) { _vm->_timers[6] = _vm->getRandom(150) + 300; if (gnap._actionStatus < 0) gameSys.insertSequence(0x149, 39, 0, 0, kSeqNone, 0, 0, 0); } _vm->playSoundC(); } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); _vm->_timers[5] = _vm->getRandom(20) + 30; } _vm->gameUpdateTick(); } } void Scene05::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; if (gameSys.getAnimationStatus(0) == 2) { gameSys.setAnimation(0, 0, 0); switch (gnap._actionStatus) { case kAS05LeaveScene: _vm->_sceneDone = true; gnap._actionStatus = -1; break; case kAS05TryPickPadlock: gameSys.insertSequence(0x148, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0x148; gnap._sequenceDatNum = 0; gnap._actionStatus = -1; break; case kAS05PickPadlock: gameSys.setAnimation(0x147, gnap._id, 0); gameSys.insertSequence(0x147, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0x147; gnap._sequenceDatNum = 0; _vm->setFlag(kGFBarnPadlockOpen); _vm->setFlag(kGFSceneFlag1); _vm->setGrabCursorSprite(-1); _vm->_newSceneNum = 6; _vm->_timers[2] = 100; _vm->invRemove(kItemNeedle); gnap._actionStatus = kAS05LeaveScene; break; case kAS05TalkChicken: _nextChickenSequenceId = 0x144; gnap._actionStatus = -1; break; case kAS05GrabChicken: _nextChickenSequenceId = 0x14B; break; case kAS05GrabLadder: while (gameSys.isSequenceActive(0x149, 39) && !_vm->_gameDone) _vm->gameUpdateTick(); gameSys.insertSequence(0x14E, gnap._id + 1, 0, 0, kSeqNone, 0, 0, 0); gameSys.insertSequence(0x14D, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0x14D; gnap._sequenceDatNum = 0; _vm->_timers[2] = 200; _vm->_timers[6] = 300; gnap._actionStatus = -1; break; case kAS05EnterBarn: gameSys.insertSequence(0x107B1, 1, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 75 * gnap._pos.x - gnap._gridX, 48 * gnap._pos.y - gnap._gridY); gameSys.setAnimation(0x107B1, 1, 0); gnap._actionStatus = kAS05LeaveScene; break; case kAS05UseTwigWithChicken: gnap.playShowItem(5, 0, 0); _nextChickenSequenceId = 0x14F; gnap._actionStatus = -1; break; } } if (gameSys.getAnimationStatus(1) == 2) { PlayerPlat& plat = *_vm->_plat; if (plat._sequenceId == 0x146) { plat._pos = Common::Point(4, 8); gameSys.insertSequence(0x107C1, 160, 0x146, 256, kSeqSyncWait, 0, 300 - plat._gridX, 384 - plat._gridY); plat._sequenceId = 0x7C1; plat._sequenceDatNum = 1; plat._id = 20 * plat._pos.y; _vm->invAdd(kItemNeedle); _vm->setFlag(kGFNeedleTaken); _vm->setGrabCursorSprite(kItemNeedle); _vm->showCursor(); _vm->_timers[1] = 30; plat._actionStatus = -1; } if (plat._actionStatus == kAS05PlatSearchHaystack) { gameSys.setAnimation(0, 0, 1); gameSys.insertSequence(0x145, plat._id, plat._sequenceId | (plat._sequenceDatNum << 16), plat._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x146, 256, 0x145, plat._id, kSeqSyncWait, 0, 0, 0); _vm->hideCursor(); _vm->setGrabCursorSprite(-1); plat._sequenceId = 0x146; plat._sequenceDatNum = 0; gameSys.setAnimation(0x146, 256, 1); _vm->_timers[1] = 300; } } if (gameSys.getAnimationStatus(3) == 2) { if (_nextChickenSequenceId == 0x14B) { gameSys.setAnimation(_nextChickenSequenceId, 100, 3); gameSys.insertSequence(_nextChickenSequenceId, 100, _currChickenSequenceId, 100, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x14C, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x14C; _currChickenSequenceId = _nextChickenSequenceId; _nextChickenSequenceId = -1; gnap._actionStatus = -1; } else if (_nextChickenSequenceId != -1) { gameSys.setAnimation(_nextChickenSequenceId, 100, 3); gameSys.insertSequence(_nextChickenSequenceId, 100, _currChickenSequenceId, 100, kSeqSyncWait, 0, 0, 0); _currChickenSequenceId = _nextChickenSequenceId; _nextChickenSequenceId = -1; } } } /*****************************************************************************/ Scene06::Scene06(GnapEngine *vm) : Scene(vm) { _horseTurnedBack = false; _nextPlatSequenceId = -1; _nextHorseSequenceId = -1; _currHorseSequenceId = -1; } int Scene06::init() { GameSys& gameSys = *_vm->_gameSys; gameSys.setAnimation(0, 0, 0); gameSys.setAnimation(0, 0, 1); gameSys.setAnimation(0, 0, 2); if (_vm->isFlag(kGFSceneFlag1)) { _vm->playSound(0x11B, false); _vm->clearFlag(kGFSceneFlag1); } return 0x101; } void Scene06::updateHotspots() { _vm->setHotspot(kHS06Platypus, 0, 0, 0, 0, SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS06Gas, 300, 120, 440, 232, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 4, 7); _vm->setHotspot(kHS06Ladder, 497, 222, 614, 492, SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 6, 8); _vm->setHotspot(kHS06Horse, 90, 226, 259, 376, SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 4, 7); _vm->setHotspot(kHS06ExitOutsideBarn, 226, 580, 688, 600, SF_EXIT_D_CURSOR | SF_WALKABLE, 5, 10); _vm->setHotspot(kHS06WalkArea1, 0, 0, 200, 515); _vm->setHotspot(kHS06WalkArea2, 200, 0, 285, 499); _vm->setHotspot(kHS06WalkArea3, 688, 0, 800, 499); _vm->setHotspot(kHS06WalkArea4, 475, 469, 800, 505); _vm->setHotspot(kHS06WalkArea5, 0, 0, 800, 504); _vm->setDeviceHotspot(kHS06Device, -1, -1, -1, -1); if (_vm->isFlag(kGFGasTaken)) _vm->_hotspots[kHS06Ladder]._flags = SF_DISABLED; if (_vm->_cursorValue == 4) { _vm->_hotspots[kHS06Ladder]._flags = SF_DISABLED; _vm->_hotspots[kHS06Gas]._flags = SF_DISABLED; } _vm->_hotspotsCount = 11; } void Scene06::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; bool triedDeviceOnGas = false; _vm->startSoundTimerC(7); _horseTurnedBack = false; gameSys.insertSequence(0xF1, 120, 0, 0, kSeqNone, 0, 0, 0); _currHorseSequenceId = 0xF1; _nextHorseSequenceId = -1; gameSys.setAnimation(0xF1, 120, 2); _vm->_timers[4] = _vm->getRandom(40) + 25; if (_vm->isFlag(kGFUnk04)) gameSys.insertSequence(0xF7, 20, 0, 0, kSeqNone, 0, 0, 0); else gameSys.insertSequence(0xF8, 20, 0, 0, kSeqNone, 0, 0, 0); if (!_vm->isFlag(kGFGasTaken) && _vm->_cursorValue != 4) gameSys.insertSequence(0xFE, 20, 0, 0, kSeqNone, 0, 0, 0); _vm->queueInsertDeviceIcon(); gnap.initPos(5, 12, kDirBottomRight); plat.initPos(6, 12, kDirIdleLeft); _vm->endSceneInit(); plat.walkTo(Common::Point(6, 8), -1, 0x107C2, 1); gnap.walkTo(Common::Point(5, 8), -1, 0x107B9, 1); while (!_vm->_sceneDone) { _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->testWalk(0, 5, -1, -1, -1, -1); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS06Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); } break; case kHS06Platypus: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex == kItemDisguise) { gnap.useDisguiseOnPlatypus(); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: if (_vm->isFlag(kGFKeysTaken)) gnap.playMoan1(plat._pos); else gnap.playScratchingHead(plat._pos); break; case GRAB_CURSOR: gnap.kissPlatypus(0); break; case TALK_CURSOR: gnap.playBrainPulsating(plat._pos); plat.playSequence(plat.getSequenceId()); break; case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS06Gas: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 5, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(5, 0)); break; case GRAB_CURSOR: if (_vm->isFlag(kGFUnk04)) { gnap.playImpossible(); } else if (triedDeviceOnGas) { _vm->_hotspots[kHS06WalkArea5]._flags |= SF_WALKABLE; gnap.walkTo(_vm->_hotspotsWalkPos[1], 0, 0x107BC, 1); _vm->_hotspots[kHS06WalkArea5]._flags &= ~SF_WALKABLE; gnap._actionStatus = kAS06TryToGetGas; } else { triedDeviceOnGas = true; gnap.playPullOutDeviceNonWorking(_vm->_hotspotsWalkPos[1]); } break; case TALK_CURSOR: case PLAT_CURSOR: if (_vm->isFlag(kGFUnk04)) gnap.playImpossible(); else gnap.playScratchingHead(Common::Point(5, 0)); break; } } } break; case kHS06Ladder: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 8, 4); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(8, 4)); break; case GRAB_CURSOR: if (_vm->isFlag(kGFGasTaken)) gnap.playImpossible(); else { gnap.walkTo(_vm->_hotspotsWalkPos[2], 0, 0x107BB, 1); gnap._actionStatus = kAS06TryToClimbLadder; _vm->setFlag(kGFGasTaken); } break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS06Horse: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex == kItemTwig && _horseTurnedBack) { _vm->_hotspots[kHS06WalkArea5]._flags |= SF_WALKABLE; gnap.walkTo(_vm->_hotspotsWalkPos[3], 0, 0x107BC, 1); _vm->_hotspots[kHS06WalkArea5]._flags &= ~SF_WALKABLE; gnap._idleFacing = kDirUpLeft; plat.walkTo(Common::Point(6, 8), 1, 0x107C2, 1); plat._idleFacing = kDirIdleLeft; gnap._actionStatus = kAS06UseTwigOnHorse; _vm->setGrabCursorSprite(-1); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 3, 2); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(3, 2)); break; case TALK_CURSOR: if (_horseTurnedBack) { gnap.walkTo(_vm->_hotspotsWalkPos[3], 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(3, 2)) | 0x10000, 1); } else { gnap._idleFacing = kDirBottomLeft; _vm->_hotspots[kHS06WalkArea5]._flags |= SF_WALKABLE; gnap.walkTo(_vm->_hotspotsWalkPos[3], 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(0, 0)) | 0x10000, 1); _vm->_hotspots[kHS06WalkArea5]._flags &= ~SF_WALKABLE; gnap._actionStatus = kAS06TalkToHorse; } break; case GRAB_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS06ExitOutsideBarn: if (gnap._actionStatus < 0) { _vm->_isLeavingScene = true; gnap.walkTo(_vm->_hotspotsWalkPos[4], 0, 0x107AE, 1); gnap._actionStatus = kAS06LeaveScene; if (_vm->_cursorValue == 1) _vm->_newSceneNum = 5; else _vm->_newSceneNum = 35; } break; case kHS06WalkArea1: case kHS06WalkArea2: case kHS06WalkArea3: case kHS06WalkArea4: case kHS06WalkArea5: if (gnap._actionStatus < 0) gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); break; default: if (_vm->_mouseClickState._left && gnap._actionStatus < 0) { gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); _vm->_mouseClickState._left = false; } break; } updateAnimations(); if (!_vm->_isLeavingScene) { if (plat._actionStatus < 0) plat.updateIdleSequence(); if (gnap._actionStatus < 0) gnap.updateIdleSequence(); if (!_vm->_timers[4]) { _vm->_timers[4] = _vm->getRandom(40) + 25; if (gnap._actionStatus < 0 && plat._actionStatus < 0 && _nextHorseSequenceId == -1) { if (_horseTurnedBack) { _nextHorseSequenceId = 0xF5; } else { switch (_vm->getRandom(5)) { case 0: case 1: case 2: _nextHorseSequenceId = 0xF1; break; case 3: _nextHorseSequenceId = 0xF3; break; case 4: _nextHorseSequenceId = 0xF4; break; } } } } _vm->playSoundC(); } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); } _vm->gameUpdateTick(); } } void Scene06::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; if (gameSys.getAnimationStatus(0) == 2) { gameSys.setAnimation(0, 0, 0); switch (gnap._actionStatus) { case kAS06LeaveScene: _vm->_sceneDone = true; gnap._actionStatus = -1; break; case kAS06TryToGetGas: gameSys.insertSequence(0xFC, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0xFC; gnap._sequenceDatNum = 0; gnap._actionStatus = -1; break; case kAS06TryToClimbLadder: gameSys.insertSequence(0xFF, 20, 0xFE, 20, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(0xFD, gnap._id, 0); gameSys.insertSequence(0xFD, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0xFD; gnap._sequenceDatNum = 0; gnap._actionStatus = kAS06TryToClimbLadderDone; break; case kAS06TryToClimbLadderDone: gnap._pos = Common::Point(6, 7); gnap._actionStatus = -1; break; case kAS06TalkToHorse: _nextHorseSequenceId = 0xF6; break; case kAS06UseTwigOnHorse: _nextPlatSequenceId = 0xFB; break; default: gnap._actionStatus = -1; break; } } if (gameSys.getAnimationStatus(1) == 2) { gameSys.setAnimation(0, 0, 1); if (plat._sequenceId == 0xFA) { gameSys.setAnimation(0, 0, 1); _vm->invAdd(kItemGas); _vm->setFlag(kGFGasTaken); _vm->_hotspots[kHS06Ladder]._flags = SF_DISABLED; _vm->setGrabCursorSprite(kItemGas); plat._actionStatus = -1; plat._pos = Common::Point(6, 8); gameSys.insertSequence(0x107C1, plat._id, 0, 0, kSeqNone, 0, 450 - plat._gridX, 384 - plat._gridY); plat._sequenceId = 0x7C1; plat._sequenceDatNum = 1; _vm->setFlag(kGFUnk04); gnap._actionStatus = -1; _vm->showCursor(); } if (_nextPlatSequenceId == 0xFB) { gameSys.setAnimation(0, 0, 1); _nextHorseSequenceId = 0xF2; plat._actionStatus = 6; } } if (gameSys.getAnimationStatus(2) == 2 && _nextHorseSequenceId != -1) { switch (_nextHorseSequenceId) { case 0xF2: _vm->setGrabCursorSprite(-1); _vm->hideCursor(); gameSys.setAnimation(0xFA, 256, 1); gameSys.insertSequence(0xF2, 120, _currHorseSequenceId, 120, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x100, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0xF7, 20, 0xF8, 20, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0xFB, plat._id, plat._sequenceId | (plat._sequenceDatNum << 16), plat._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0xFA, 256, 0xFB, plat._id, kSeqSyncWait, 0, 0, 0); plat._sequenceId = 0xFA; plat._sequenceDatNum = 0; gameSys.insertSequence(0x107B7, gnap._id, 0x100, gnap._id, kSeqSyncWait, 0, 75 * gnap._pos.x - gnap._gridX, 48 * gnap._pos.y - gnap._gridY); gnap._sequenceId = 0x7B7; gnap._sequenceDatNum = 1; _currHorseSequenceId = _nextHorseSequenceId; _nextHorseSequenceId = -1; _nextPlatSequenceId = -1; _vm->invRemove(kItemTwig); break; case 0xF6: gameSys.setAnimation(_nextHorseSequenceId, 120, 2); gameSys.insertSequence(0xF6, 120, _currHorseSequenceId, 120, kSeqSyncWait, 0, 0, 0); _horseTurnedBack = true; _currHorseSequenceId = _nextHorseSequenceId; _nextHorseSequenceId = -1; gnap._actionStatus = -1; break; default: gameSys.setAnimation(_nextHorseSequenceId, 120, 2); gameSys.insertSequence(_nextHorseSequenceId, 120, _currHorseSequenceId, 120, kSeqSyncWait, 0, 0, 0); _currHorseSequenceId = _nextHorseSequenceId; _nextHorseSequenceId = -1; break; } } } /*****************************************************************************/ Scene07::Scene07(GnapEngine *vm) : Scene(vm) { } int Scene07::init() { return 0x92; } void Scene07::updateHotspots() { _vm->setHotspot(kHS07Platypus, 0, 0, 0, 0, SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS07ExitHouse, 700, 125, 799, 290, SF_EXIT_NE_CURSOR); _vm->setHotspot(kHS07Dice, 200, 290, 270, 360, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS07WalkArea1, 0, 0, 325, 445); _vm->setHotspot(kHS07WalkArea2, 325, 0, 799, 445, _vm->_isLeavingScene ? SF_WALKABLE : SF_NONE); _vm->setHotspot(kHS07WalkArea3, 160, 0, 325, 495); _vm->setDeviceHotspot(kHS07Device, -1, -1, -1, -1); if (_vm->isFlag(kGFPlatypus)) _vm->_hotspots[kHS07Dice]._flags = SF_DISABLED; _vm->_hotspotsCount = 7; } void Scene07::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; _vm->queueInsertDeviceIcon(); gameSys.insertSequence(0x8C, 1, 0, 0, kSeqLoop, 0, 0, 0); gameSys.insertSequence(0x90, 1, 0, 0, kSeqLoop, 0, 0, 0); _vm->invRemove(kItemGas); _vm->invRemove(kItemNeedle); if (!_vm->isFlag(kGFPlatypus)) gameSys.insertSequence(0x8D, 1, 0, 0, kSeqNone, 0, 0, 0); if (_vm->_prevSceneNum == 8) { gnap.initPos(7, 7, kDirBottomLeft); plat.initPos(9, 7, kDirIdleRight); _vm->endSceneInit(); } else { gnap._pos = Common::Point(6, 7); gnap._id = 140; gnap._sequenceId = 0x8F; gnap._sequenceDatNum = 0; gnap._idleFacing = kDirBottomRight; gameSys.insertSequence(0x8F, 140, 0, 0, kSeqNone, 0, 0, 0); gameSys.setAnimation(makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, 0); gnap._actionStatus = kAS07Wait; plat._pos = Common::Point(3, 8); plat._id = 160; plat._sequenceId = 0x91; plat._sequenceDatNum = 0; plat._idleFacing = kDirIdleLeft; gameSys.insertSequence(0x91, 160, 0, 0, kSeqNone, 0, 0, 0); _vm->endSceneInit(); } _vm->_timers[3] = 600; _vm->_timers[4] = _vm->getRandom(40) + 50; while (!_vm->_sceneDone) { if (!_vm->isSoundPlaying(0x10919)) _vm->playSound(0x10919, true); if (_vm->testWalk(0, 1, 8, 7, 6, 7)) updateHotspots(); _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS07Platypus: switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playMoan1(plat._pos); break; case GRAB_CURSOR: gnap.kissPlatypus(0); break; case TALK_CURSOR: gnap.playBrainPulsating(plat._pos); plat.playSequence(plat.getSequenceId()); break; case PLAT_CURSOR: break; } break; case kHS07ExitHouse: _vm->_isLeavingScene = true; if (gnap._pos.x > 8) gnap.walkTo(Common::Point(gnap._pos.x, 7), 0, 0x107AD, 1); else gnap.walkTo(Common::Point(8, 7), 0, 0x107AD, 1); gnap._actionStatus = kAS07LeaveScene; break; case kHS07Dice: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(4, 8), 3, 3); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: break; case GRAB_CURSOR: _vm->setFlag(kGFPlatypus); _vm->invAdd(kItemDice); updateHotspots(); gnap.playPullOutDevice(Common::Point(3, 3)); gameSys.setAnimation(0x8E, 1, 2); gameSys.insertSequence(0x8E, 1, 141, 1, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(gnap.getSequenceId(kGSUseDevice, Common::Point(0, 0)) | 0x10000, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 75 * gnap._pos.x - gnap._gridX, 48 * gnap._pos.y - gnap._gridY); gnap._sequenceId = gnap.getSequenceId(kGSUseDevice, Common::Point(0, 0)); gnap._sequenceDatNum = 1; break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } break; case kHS07Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); _vm->_timers[4] = _vm->getRandom(40) + 50; } break; case kHS07WalkArea1: case kHS07WalkArea2: gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); break; case kHS07WalkArea3: // Nothing break; default: if (_vm->_mouseClickState._left) { gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); _vm->_mouseClickState._left = false; } break; } updateAnimations(); if (!_vm->_isLeavingScene) { gnap.updateIdleSequence(); if (plat._actionStatus < 0 && gnap._actionStatus < 0) { if (_vm->_timers[0]) { if (!_vm->_timers[1]) { _vm->_timers[1] = _vm->getRandom(20) + 30; int gnapRandomValue = _vm->getRandom(20); if (plat._idleFacing != kDirIdleLeft) { if (gnapRandomValue == 0 && plat._sequenceId == 0x7CA) plat.playSequence(0x107CC); else if (gnapRandomValue == 1 && plat._sequenceId == 0x7CA) plat.playSequence(0x10845); else if (plat._pos.y == 9) plat.playSequence(0x107CA); } else if (gnapRandomValue == 0 && plat._sequenceId == 0x7C9) plat.playSequence(0x107CB); else if (gnapRandomValue == 1 && plat._sequenceId == 0x7C9) plat.playSequence(0x10844); else if (plat._pos.y == 9) plat.playSequence(0x107C9); gameSys.setAnimation(plat._sequenceId | (plat._sequenceDatNum << 16), plat._id, 1); } } else { _vm->_timers[0] = _vm->getRandom(75) + 75; plat.makeRoom(); } } else { _vm->_timers[0] = 100; _vm->_timers[1] = 35; } playRandomSound(4); } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); _vm->_timers[4] = _vm->getRandom(40) + 50; } _vm->gameUpdateTick(); } } void Scene07::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; if (gameSys.getAnimationStatus(0) == 2) { gameSys.setAnimation(0, 0, 0); switch (gnap._actionStatus) { case kAS07LeaveScene: _vm->_newSceneNum = 8; _vm->_sceneDone = true; break; } gnap._actionStatus = -1; } if (gameSys.getAnimationStatus(2) == 2) { gameSys.setAnimation(0, 0, 2); _vm->setGrabCursorSprite(kItemDice); } } /*****************************************************************************/ Scene08::Scene08(GnapEngine *vm) : Scene(vm) { _nextDogSequenceId = -1; _currDogSequenceId = -1; _nextManSequenceId = -1; _currManSequenceId = -1; } int Scene08::init() { return 0x150; } void Scene08::updateHotspots() { _vm->setHotspot(kH08SPlatypus, 0, 0, 0, 0, SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS08ExitBackdoor, 0, 280, 10, 400, SF_EXIT_L_CURSOR | SF_WALKABLE); _vm->setHotspot(kHS08ExitCrash, 200, 590, 400, 599, SF_EXIT_D_CURSOR | SF_WALKABLE); _vm->setHotspot(kHS08Man, 510, 150, 610, 380, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS08Door, 350, 170, 500, 410, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS08Meat, 405, 450, 480, 485, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS08Bone, 200, 405, 270, 465, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS08Toy, 540, 430, 615, 465, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS08WalkArea1, 0, 0, 290, 340); _vm->setHotspot(kHS08WalkArea2, 0, 0, 799, 420); _vm->setDeviceHotspot(kHS08Device, -1, -1, -1, -1); if (_vm->isFlag(kGFBarnPadlockOpen)) _vm->_hotspots[kHS08Meat]._flags = SF_WALKABLE | SF_DISABLED; if (_vm->isFlag(kGFTruckFilledWithGas)) _vm->_hotspots[kHS08Bone]._flags = SF_WALKABLE | SF_DISABLED; if (_vm->isFlag(kGFTruckKeysUsed)) _vm->_hotspots[kHS08Toy]._flags = SF_WALKABLE | SF_DISABLED; _vm->_hotspotsCount = 11; } void Scene08::updateAnimationsCb() { GameSys& gameSys = *_vm->_gameSys; if (gameSys.getAnimationStatus(3) == 2) { gameSys.setAnimation(_nextDogSequenceId, 100, 3); gameSys.insertSequence(_nextDogSequenceId, 100, _currDogSequenceId, 100, kSeqSyncWait, 0, 0, 0); _currDogSequenceId = _nextDogSequenceId; if ( _nextDogSequenceId != 0x135 ) _nextDogSequenceId = 0x134; } } void Scene08::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; _vm->queueInsertDeviceIcon(); gameSys.insertSequence(0x14F, 1, 0, 0, kSeqLoop, 0, 0, 0); gameSys.insertSequence(0x14E, 256, 0, 0, kSeqNone, 0, 0, 0); _currDogSequenceId = 0x135; _nextDogSequenceId = 0x135; gameSys.setAnimation(0x135, 100, 3); gameSys.insertSequence(_currDogSequenceId, 100, 0, 0, kSeqNone, 0, 0, 0); _currManSequenceId = 0x140; _nextManSequenceId = -1; gameSys.setAnimation(0x140, 100, 2); gameSys.insertSequence(_currManSequenceId, 100, 0, 0, kSeqNone, 0, 0, 0); _vm->_timers[4] = _vm->getRandom(50) + 75; if (!_vm->isFlag(kGFBarnPadlockOpen)) gameSys.insertSequence(0x144, 1, 0, 0, kSeqNone, 0, 0, 0); if (!_vm->isFlag(kGFTruckFilledWithGas)) gameSys.insertSequence(0x145, 1, 0, 0, kSeqNone, 0, 0, 0); if (!_vm->isFlag(kGFTruckKeysUsed)) gameSys.insertSequence(0x146, 1, 0, 0, kSeqNone, 0, 0, 0); gnap.initPos(-1, 8, kDirBottomRight); plat.initPos(-1, 7, kDirIdleLeft); _vm->endSceneInit(); gnap.walkTo(Common::Point(1, 8), -1, 0x107B9, 1); plat.walkTo(Common::Point(1, 7), -1, 0x107C2, 1); _vm->_timers[5] = _vm->getRandom(40) + 50; while (!_vm->_sceneDone) { if (!_vm->isSoundPlaying(0x10919)) _vm->playSound(0x10919, true); _vm->testWalk(0, 0, -1, -1, -1, -1); _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS08Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); _vm->_timers[4] = _vm->getRandom(50) + 75; _vm->_timers[5] = _vm->getRandom(40) + 50; } break; case kH08SPlatypus: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: if (_vm->isFlag(kGFSceneFlag1)) gnap.playMoan1(plat._pos); else gnap.playScratchingHead(plat._pos); break; case GRAB_CURSOR: gnap.actionIdle(0x14D); gnap.kissPlatypus(8); break; case TALK_CURSOR: gnap.playBrainPulsating(plat._pos); plat.playSequence(plat.getSequenceId()); break; case PLAT_CURSOR: break; } } break; case kHS08ExitBackdoor: _vm->_isLeavingScene = true; gnap.actionIdle(0x14D); gnap.walkTo(Common::Point(0, 6), 0, 0x107AF, 1); gnap._actionStatus = kAS08LeaveScene; plat.walkTo(Common::Point(0, 7), 1, 0x107CF, 1); _vm->_newSceneNum = 9; break; case kHS08ExitCrash: _vm->_isLeavingScene = true; gnap.actionIdle(0x14D); gnap.walkTo(Common::Point(3, 9), 0, 0x107AE, 1); gnap._actionStatus = kAS08LeaveScene; plat.walkTo(Common::Point(4, 9), 1, 0x107C1, 1); _vm->_newSceneNum = 7; break; case kHS08Man: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(6, 6), 7, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.actionIdle(0x14D); gnap.walkTo(Common::Point(6, 6), 0, 0x107BB, 1); gnap._actionStatus = kAS08LookMan; gnap._idleFacing = kDirUpRight; break; case GRAB_CURSOR: gnap.playImpossible(); break; case TALK_CURSOR: gnap._idleFacing = kDirUpLeft; gnap.actionIdle(0x14D); gnap.walkTo(Common::Point(8, 6), 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS08TalkMan; break; case PLAT_CURSOR: gnap.actionIdle(0x14D); gnap.useDeviceOnPlatypus(); plat.walkTo(Common::Point(6, 6), 1, 0x107C2, 1); plat._actionStatus = kAS08PlatWithMan; plat._idleFacing = kDirIdleLeft; gnap.playIdle(Common::Point(6, 6)); break; } } break; case kHS08Door: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(4, 7), 5, 0); gameSys.setAnimation(makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, 0); gnap._actionStatus = kAS08GrabDog; } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(6, 0)); gameSys.setAnimation(makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, 0); gnap._actionStatus = kAS08LookDog; break; case GRAB_CURSOR: gnap.walkTo(Common::Point(4, 7), 0, 0x107BB, 1); gnap._actionStatus = kAS08GrabDog; gnap._idleFacing = kDirUpRight; break; case TALK_CURSOR: gnap._idleFacing = kDirUpRight; gnap.actionIdle(0x14D); gnap.walkTo(Common::Point(4, 7), 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS08TalkDog; break; case PLAT_CURSOR: _vm->setFlag(kGFSceneFlag1); gnap.actionIdle(0x14D); gnap.useDeviceOnPlatypus(); plat.walkTo(Common::Point(3, 7), 1, 0x107C2, 1); plat._actionStatus = kAS08PlatWithDog; plat._idleFacing = kDirIdleLeft; gnap.playIdle(Common::Point(3, 7)); break; } } break; case kHS08Meat: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(6, 8), 5, 6); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(6, 7)); break; case GRAB_CURSOR: if (_currDogSequenceId == 0x135) { gnap.playScratchingHead(Common::Point(6, 7)); } else { gnap.actionIdle(0x14D); gnap.playPullOutDevice(Common::Point(6, 7)); gnap.playUseDevice(); _nextDogSequenceId = 0x149; } break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } break; case kHS08Bone: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(2, 7), 3, 6); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(3, 6)); break; case GRAB_CURSOR: if (_currDogSequenceId == 0x135) { gnap.playScratchingHead(Common::Point(3, 6)); } else { gnap.actionIdle(0x14D); gnap.playPullOutDevice(Common::Point(3, 6)); gnap.playUseDevice(); _nextDogSequenceId = 0x14A; } break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } break; case kHS08Toy: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(8, 7), 7, 6); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(7, 6)); break; case GRAB_CURSOR: if (_currDogSequenceId == 0x135) { gnap.playScratchingHead(Common::Point(7, 6)); } else { gnap.actionIdle(0x14D); gnap.playPullOutDevice(Common::Point(7, 6)); gnap.playUseDevice(); _nextDogSequenceId = 0x14B; } break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } break; case kHS08WalkArea1: case kHS08WalkArea2: gnap.actionIdle(0x14D); gnap.walkTo(Common::Point(-1, 6), -1, -1, 1); break; default: if (_vm->_mouseClickState._left) { gnap.actionIdle(0x14D); gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); _vm->_mouseClickState._left = false; } break; } updateAnimations(); if (!_vm->_isLeavingScene) { plat.updateIdleSequence(); gnap.updateIdleSequence(); if (!_vm->_timers[4]) { _vm->_timers[4] = _vm->getRandom(50) + 125; if (gnap._actionStatus < 0 && plat._actionStatus < 0 && _nextManSequenceId == -1 && (_currDogSequenceId == 0x134 || _currDogSequenceId == 0x135)) { int _gnapRandomValue = _vm->getRandom(4); switch (_gnapRandomValue) { case 0: _nextManSequenceId = 0x138; break; case 1: _nextManSequenceId = 0x136; break; case 2: _nextManSequenceId = 0x13B; break; case 3: _nextManSequenceId = 0x13A; break; } } } playRandomSound(5); } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); _vm->_timers[4] = _vm->getRandom(50) + 75; _vm->_timers[5] = _vm->getRandom(40) + 50; } _vm->gameUpdateTick(); } } void Scene08::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; if (gameSys.getAnimationStatus(0) == 2) { gameSys.setAnimation(0, 0, 0); switch (gnap._actionStatus) { case kAS08LeaveScene: _vm->_sceneDone = true; gnap._actionStatus = -1; break; case kAS08TalkMan: _nextManSequenceId = 0x13F; gnap._actionStatus = -1; break; case kAS08LookMan: _nextManSequenceId = 0x140; gnap._actionStatus = -1; break; case kAS08LookDog: _nextManSequenceId = 0x137; gnap._actionStatus = -1; break; case kAS08GrabDog: if (_currDogSequenceId == 0x135) _nextDogSequenceId = 0x133; else _nextDogSequenceId = 0x13C; gnap._actionStatus = -1; break; case kAS08TalkDog: if (_currDogSequenceId == 0x135) _nextDogSequenceId = 0x133; else _nextDogSequenceId = 0x13C; gnap._actionStatus = -1; break; } } if (gameSys.getAnimationStatus(1) == 2) { gameSys.setAnimation(0, 0, 1); switch (plat._actionStatus) { case kAS08PlatWithDog: _nextDogSequenceId = 0x147; break; case kAS08PlatWithMan: _nextManSequenceId = 0x140; plat._actionStatus = -1; break; } } if (gameSys.getAnimationStatus(2) == 2 && _nextManSequenceId != -1) { gameSys.setAnimation(_nextManSequenceId, 100, 2); gameSys.insertSequence(_nextManSequenceId, 100, _currManSequenceId, 100, kSeqSyncWait, 0, 0, 0); _currManSequenceId = _nextManSequenceId; _nextManSequenceId = -1; } if (gameSys.getAnimationStatus(3) == 2) { if (_currDogSequenceId == 0x147) plat._actionStatus = -1; if (_currDogSequenceId == 0x149 || _currDogSequenceId == 0x14A || _currDogSequenceId == 0x14B) { if (_vm->getRandom(2) != 0) _nextManSequenceId = 0x13D; else _nextManSequenceId = 0x13E; } else if (_currDogSequenceId == 0x133) _nextManSequenceId = 0x139; if (_nextDogSequenceId == 0x149 || _nextDogSequenceId == 0x14A || _nextDogSequenceId == 0x14B) { gameSys.setAnimation(_nextDogSequenceId, 100, 3); gameSys.insertSequence(_nextDogSequenceId, 100, _currDogSequenceId, 100, kSeqSyncWait, 0, 0, 0); switch (_nextDogSequenceId) { case 0x149: _vm->setFlag(kGFBarnPadlockOpen); _vm->_hotspots[kHS08Meat]._flags = SF_DISABLED | SF_WALKABLE; gameSys.removeSequence(0x144, 1, true); break; case 0x14A: _vm->setFlag(kGFTruckFilledWithGas); _vm->_hotspots[kHS08Bone]._flags = SF_DISABLED | SF_WALKABLE; gameSys.removeSequence(0x145, 1, true); break; case 0x14B: _vm->setFlag(kGFTruckKeysUsed); _vm->_hotspots[kHS08Toy]._flags = SF_DISABLED | SF_WALKABLE; gameSys.removeSequence(0x146, 1, true); break; } _currDogSequenceId = _nextDogSequenceId; _nextDogSequenceId = 0x134; } else if (_nextDogSequenceId == 0x147) { gameSys.setAnimation(_nextDogSequenceId, 100, 3); gameSys.insertSequence(_nextDogSequenceId, 100, _currDogSequenceId, 100, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x148, 160, plat._sequenceId | (plat._sequenceDatNum << 16), plat._id, kSeqSyncWait, 0, 0, 0); _currDogSequenceId = _nextDogSequenceId; _nextDogSequenceId = 0x134; plat._pos = Common::Point(1, 8); plat._id = 160; plat._sequenceId = 0x148; plat._idleFacing = kDirIdleRight; plat._sequenceDatNum = 0; if (gnap._pos == Common::Point(1, 8)) gnap.walkStep(); } else if (_nextDogSequenceId != -1) { gameSys.setAnimation(_nextDogSequenceId, 100, 3); gameSys.insertSequence(_nextDogSequenceId, 100, _currDogSequenceId, 100, kSeqSyncWait, 0, 0, 0); _currDogSequenceId = _nextDogSequenceId; if (_nextDogSequenceId != 0x135) _nextDogSequenceId = 0x134; if (_currDogSequenceId == 0x133) { _vm->_timers[2] = _vm->getRandom(30) + 20; _vm->_timers[3] = _vm->getRandom(50) + 200; gameSys.insertSequence(0x14D, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0x14D; gnap._idleFacing = kDirUpRight; gnap._sequenceDatNum = 0; gnap._actionStatus = -1; } } } } /*****************************************************************************/ Scene09::Scene09(GnapEngine *vm) : Scene(vm) { } int Scene09::init() { return 0x4E; } void Scene09::updateHotspots() { _vm->setHotspot(kHS09Platypus, 0, 0, 0, 0, SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS09ExitKitchen, 280, 200, 380, 400, SF_EXIT_U_CURSOR); _vm->setHotspot(kHS09ExitHouse, 790, 200, 799, 450, SF_EXIT_R_CURSOR | SF_WALKABLE); _vm->setHotspot(kHS09Trash, 440, 310, 680, 420, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS09WalkArea1, 0, 0, 799, 400); _vm->setHotspot(kHS09WalkArea2, 0, 0, 630, 450); _vm->setHotspot(kHS09WalkArea2, 0, 0, 175, 495); _vm->setDeviceHotspot(kHS09Device, -1, -1, -1, -1); _vm->_hotspotsCount = 8; } void Scene09::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; _vm->queueInsertDeviceIcon(); gameSys.insertSequence(0x4D, 1, 0, 0, kSeqLoop, 0, 0, 0); gameSys.insertSequence(0x4B, 2, 0, 0, kSeqNone, 0, 0, 0); if (_vm->_prevSceneNum == 8) { gnap.initPos(11, 8, kDirBottomLeft); plat.initPos(12, 7, kDirIdleRight); _vm->endSceneInit(); gnap.walkTo(Common::Point(9, 8), -1, 0x107BA, 1); plat.walkTo(Common::Point(9, 7), -1, 0x107D2, 1); } else { gnap.initPos(4, 7, kDirBottomRight); plat.initPos(5, 7, kDirIdleLeft); _vm->endSceneInit(); } _vm->_timers[4] = _vm->getRandom(150) + 50; _vm->_timers[5] = _vm->getRandom(40) + 50; while (!_vm->_sceneDone) { if (!_vm->isSoundPlaying(0x10919)) _vm->playSound(0x10919, true); _vm->testWalk(0, 0, -1, -1, -1, -1); _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS09Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); _vm->_timers[4] = _vm->getRandom(150) + 50; _vm->_timers[5] = _vm->getRandom(40) + 50; } break; case kHS09Platypus: switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playMoan1(plat._pos); break; case GRAB_CURSOR: gnap.kissPlatypus(0); break; case TALK_CURSOR: gnap.playBrainPulsating(plat._pos); plat.playSequence(plat.getSequenceId()); break; case PLAT_CURSOR: break; } break; case kHS09ExitKitchen: _vm->_isLeavingScene = true; _vm->_newSceneNum = 10; gnap.walkTo(Common::Point(4, 7), 0, 0x107BF, 1); gnap._actionStatus = kAS09LeaveScene; plat.walkTo(Common::Point(4, 8), -1, 0x107D2, 1); plat._idleFacing = kDirIdleRight; break; case kHS09ExitHouse: _vm->_isLeavingScene = true; _vm->_newSceneNum = 8; gnap.walkTo(Common::Point(10, -1), 0, 0x107AB, 1); gnap._actionStatus = kAS09LeaveScene; plat.walkTo(Common::Point(10, -1), -1, 0x107CD, 1); plat._idleFacing = kDirIdleRight; break; case kHS09Trash: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(9, 6), 8, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(8, 3)); break; case GRAB_CURSOR: gnap._actionStatus = kAS09SearchTrash; gnap.walkTo(Common::Point(9, 6), 0, 0x107BC, 1); break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } break; case kHS09WalkArea1: case kHS09WalkArea2: case kHS09WalkArea3: gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); break; default: if (_vm->_mouseClickState._left) { gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); _vm->_mouseClickState._left = false; } break; } updateAnimations(); if (!_vm->_isLeavingScene && gnap._actionStatus != 1 && gnap._actionStatus != 2) { plat.updateIdleSequence(); gnap.updateIdleSequence(); if (!_vm->_timers[4]) { _vm->_timers[4] = _vm->getRandom(150) + 100; if (_vm->_timers[4] & 1) gameSys.insertSequence(0x49, 1, 0, 0, kSeqNone, 0, 0, 0); else gameSys.insertSequence(0x4A, 1, 0, 0, kSeqNone, 0, 0, 0); } playRandomSound(5); } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); _vm->_timers[4] = _vm->getRandom(150) + 50; _vm->_timers[5] = _vm->getRandom(40) + 50; } _vm->gameUpdateTick(); } } void Scene09::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; if (gameSys.getAnimationStatus(0) == 2) { gameSys.setAnimation(0, 0, 0); switch (gnap._actionStatus) { case kAS09LeaveScene: _vm->_sceneDone = true; gnap._actionStatus = -1; break; case kAS09SearchTrash: gameSys.setAnimation(0x4C, 120, 0); gameSys.insertSequence(0x4C, 120, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.removeSequence(0x4B, 2, true); gnap._sequenceId = 0x4C; gnap._id = 120; gnap._idleFacing = kDirUpLeft; gnap._sequenceDatNum = 0; gnap._pos = Common::Point(9, 6); gnap._actionStatus = kAS09SearchTrashDone; break; case kAS09SearchTrashDone: gameSys.insertSequence(0x4B, 2, 0, 0, kSeqNone, 0, 0, 0); _vm->_timers[2] = 360; _vm->_timers[4] = _vm->getRandom(150) + 100; gnap._actionStatus = -1; break; } } } } // End of namespace Gnap