/* 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/gamesys.h" #include "gnap/resource.h" #include "gnap/scenes/group1.h" namespace Gnap { Scene10::Scene10(GnapEngine *vm) : Scene(vm) { _nextCookSequenceId = -1; _currCookSequenceId = -1; } int Scene10::init() { GameSys& gameSys = *_vm->_gameSys; gameSys.setAnimation(0, 0, 0); gameSys.setAnimation(0, 0, 1); gameSys.setAnimation(0, 0, 2); return 0x10F; } void Scene10::updateHotspots() { _vm->setHotspot(kHS10Platypus, 0, 0, 0, 0, SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS10ExitBar, 0, 75, 85, 455, SF_EXIT_NW_CURSOR); _vm->setHotspot(kHS10ExitBackdoor, 75, 590, 500, 599, SF_EXIT_D_CURSOR | SF_WALKABLE); _vm->setHotspot(kHS10Cook, 370, 205, 495, 460, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS10Tongs, 250, 290, 350, 337, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS10Box, 510, 275, 565, 330, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS10Oven, 690, 280, 799, 420, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS10WalkArea1, 59, 0, 495, 460); _vm->setHotspot(kHS10WalkArea2, 495, 0, 650, 420); _vm->setHotspot(kHS10WalkArea3, 651, 0, 725, 400); _vm->setHotspot(kHS10WalkArea4, 725, 0, 799, 441); _vm->setDeviceHotspot(kHS10Device, -1, -1, -1, -1); _vm->_hotspotsCount = 12; } void Scene10::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; _currCookSequenceId = 0x103; gameSys.setAnimation(0x103, 100, 2); gameSys.insertSequence(0x103, 100, 0, 0, kSeqNone, 0, 0, 0); _nextCookSequenceId = 0x106; if (!_vm->isFlag(kGFMudTaken)) gameSys.insertSequence(0x107, 100, 0, 0, kSeqNone, 0, 0, 0); _vm->queueInsertDeviceIcon(); if (_vm->_prevSceneNum == 9) { 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(-1, 7, kDirBottomRight); plat.initPos(-2, 8, kDirIdleLeft); _vm->endSceneInit(); gnap.walkTo(Common::Point(1, 7), -1, 0x107B9, 1); plat.walkTo(Common::Point(1, 8), -1, 0x107C2, 1); } _vm->_timers[4] = _vm->getRandom(80) + 150; _vm->_timers[5] = _vm->getRandom(100) + 100; while (!_vm->_sceneDone) { if (!_vm->isSoundPlaying(0x1091E)) _vm->playSound(0x1091E, true); if (!_vm->isSoundPlaying(0x1091A)) _vm->playSound(0x1091A, true); _vm->updateMouseCursor(); _vm->testWalk(0, 0, -1, -1, -1, -1); _vm->updateCursorByHotspot(); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS10Platypus: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: if (_vm->isFlag(kGFMudTaken)) gnap.playMoan1(plat._pos); else gnap.playScratchingHead(plat._pos); break; case GRAB_CURSOR: gnap.kissPlatypus(10); break; case TALK_CURSOR: gnap.playBrainPulsating(plat._pos); plat.playSequence(plat.getSequenceId()); break; case PLAT_CURSOR: break; } } break; case kHS10ExitBar: _vm->_isLeavingScene = true; gnap.actionIdle(0x10C); gnap.walkTo(Common::Point(0, 7), 0, 0x107AF, 1); gnap._actionStatus = kAS10LeaveScene; plat.walkTo(Common::Point(0, 7), -1, 0x107CF, 1); _vm->_newSceneNum = 11; break; case kHS10ExitBackdoor: _vm->_isLeavingScene = true; gnap.actionIdle(0x10C); gnap.walkTo(Common::Point(2, 9), 0, 0x107AE, 1); gnap._actionStatus = kAS10LeaveScene; plat.walkTo(Common::Point(3, 9), -1, 0x107C7, 1); _vm->_newSceneNum = 9; break; case kHS10Cook: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(4, 8), 6, 0); gameSys.setAnimation(makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, 0); gnap._actionStatus = kAS10AnnoyCook; } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(6, 0)); break; case GRAB_CURSOR: gnap.playImpossible(); gnap._idleFacing = kDirBottomRight; break; case TALK_CURSOR: gnap._idleFacing = kDirUpRight; gnap.actionIdle(0x10C); gnap.walkTo(Common::Point(4, 8), 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS10AnnoyCook; break; case PLAT_CURSOR: gnap.actionIdle(0x10C); gnap.useDeviceOnPlatypus(); plat.walkTo(Common::Point(4, 6), -1, -1, 1); gnap.walkTo(Common::Point(4, 8), 0, 0x107BB, 1); gnap._actionStatus = kAS10AnnoyCook; break; } } break; case kHS10Tongs: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(3, 7), 4, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: if (_vm->isFlag(kGFMudTaken)) gnap.playMoan2(Common::Point(-1, -1)); else gnap.playScratchingHead(Common::Point(4, 3)); break; case GRAB_CURSOR: if (_vm->isFlag(kGFMudTaken)) gnap.playMoan2(Common::Point(-1, -1)); else { gnap.actionIdle(0x10C); gnap.walkTo(Common::Point(4, 8), 0, 0x107BB, 1); gnap._actionStatus = kAS10AnnoyCook; } break; case TALK_CURSOR: gnap.playImpossible(); break; case PLAT_CURSOR: if (_vm->isFlag(kGFMudTaken)) gnap.playMoan2(Common::Point(-1, -1)); else { gnap.actionIdle(0x10C); gnap.useDeviceOnPlatypus(); plat.walkTo(Common::Point(3, 7), -1, -1, 1); gnap.walkTo(Common::Point(4, 8), 0, 0x107BB, 1); gnap._actionStatus = kAS10AnnoyCook; } break; } } break; case kHS10Box: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(7, 6), 6, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(7, 3)); break; case GRAB_CURSOR: gnap.actionIdle(0x10C); gnap.walkTo(Common::Point(4, 8), 0, 0x107BB, 1); gnap._actionStatus = kAS10AnnoyCook; break; case TALK_CURSOR: gnap.playImpossible(); break; case PLAT_CURSOR: if (_vm->isFlag(kGFMudTaken)) gnap.playMoan2(Common::Point(-1, -1)); else { _vm->invAdd(kItemTongs); _vm->setFlag(kGFMudTaken); gnap.actionIdle(0x10C); gnap.useDeviceOnPlatypus(); plat.walkTo(Common::Point(7, 6), 1, 0x107D2, 1); plat._actionStatus = kAS10PlatWithBox; plat._idleFacing = kDirIdleRight; _vm->_largeSprite = gameSys.createSurface(0xC3); gnap.playIdle(Common::Point(7, 6)); } break; } } break; case kHS10Oven: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(9, 6), 10, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playSequence(gnap.getSequenceId(kGSDeflect, Common::Point(10, 5)) | 0x10000); break; case GRAB_CURSOR: gnap.actionIdle(0x10C); gnap.walkTo(Common::Point(9, 6), 0, 0x107BB, 1); gameSys.insertSequence(0x10E, 120, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0x10E; gnap._id = 120; gnap._idleFacing = kDirUpRight; gnap._sequenceDatNum = 0; gnap._pos = Common::Point(9, 6); _vm->_timers[2] = 360; break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } break; case kHS10WalkArea1: case kHS10WalkArea2: case kHS10WalkArea3: case kHS10WalkArea4: gnap.actionIdle(0x10C); gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); break; case kHS10Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); } break; default: if (_vm->_mouseClickState._left) { gnap.actionIdle(0x10C); 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(80) + 150; _vm->playSound(0x12B, false); } if (!_vm->_timers[5]) { _vm->_timers[5] = _vm->getRandom(100) + 100; int _gnapRandomValue = _vm->getRandom(4); if (_gnapRandomValue) { int sequenceId; if (_gnapRandomValue == 1) { sequenceId = 0x8A5; } else if (_gnapRandomValue == 2) { sequenceId = 0x8A6; } else { sequenceId = 0x8A7; } gameSys.insertSequence(sequenceId | 0x10000, 179, 0, 0, kSeqNone, 0, 0, 0); } } } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); } _vm->gameUpdateTick(); } } void Scene10::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 kAS10LeaveScene: _vm->_sceneDone = true; break; case kAS10AnnoyCook: _nextCookSequenceId = 0x105; break; } } if (gameSys.getAnimationStatus(1) == 2) { gameSys.setAnimation(0, 0, 1); switch (plat._actionStatus) { case kAS10PlatWithBox: _nextCookSequenceId = 0x109; break; } } if (gameSys.getAnimationStatus(2) == 2 && _nextCookSequenceId != -1) { switch (_nextCookSequenceId) { case 0x109: plat._pos = Common::Point(4, 8); gameSys.insertSequence(0x109, 100, _currCookSequenceId, 100, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x107C9, 160, plat._sequenceId | (plat._sequenceDatNum << 16), plat._id, kSeqSyncWait, _vm->getSequenceTotalDuration(0x109) + _vm->getSequenceTotalDuration(0x10A) + _vm->getSequenceTotalDuration(0x10843), 75 * plat._pos.x - plat._gridX, 48 * plat._pos.y - plat._gridY); gameSys.removeSequence(0x107, 100, true); _currCookSequenceId = 0x109; _nextCookSequenceId = 0x843; plat._sequenceId = 0x7C9; plat._id = 160; plat._idleFacing = kDirIdleLeft; plat._sequenceDatNum = 1; break; case 0x843: _vm->hideCursor(); gameSys.insertSpriteDrawItem(_vm->_largeSprite, 0, 0, 300); gameSys.insertSequence(0x10843, 301, _currCookSequenceId, 100, kSeqSyncWait, 0, 0, 0); _currCookSequenceId = 0x843; _nextCookSequenceId = 0x10A; break; case 0x10A: gameSys.insertSequence(_nextCookSequenceId, 100, 0x10843, 301, kSeqSyncWait, 0, 0, 0); _currCookSequenceId = _nextCookSequenceId; _nextCookSequenceId = 0x104; _vm->showCursor(); gameSys.removeSpriteDrawItem(_vm->_largeSprite, 300); _vm->delayTicksCursor(5); _vm->deleteSurface(&_vm->_largeSprite); _vm->setGrabCursorSprite(kItemTongs); if (plat._actionStatus == kAS10PlatWithBox) plat._actionStatus = -1; if (gnap._pos == Common::Point(4, 8)) gnap.walkStep(); break; default: gameSys.insertSequence(_nextCookSequenceId, 100, _currCookSequenceId, 100, kSeqSyncWait, 0, 0, 0); _currCookSequenceId = _nextCookSequenceId; break; } switch (_currCookSequenceId) { case 0x106: if (gnap._actionStatus >= 0 || plat._actionStatus >= 0) _nextCookSequenceId = 0x106; else { int rnd = _vm->getRandom(7); switch (rnd) { case 0: _nextCookSequenceId = 0x104; break; case 1: _nextCookSequenceId = 0x103; break; case 2: _nextCookSequenceId = 0x106; gameSys.insertSequence(0x10D, 1, 0, 0, kSeqNone, 0, 0, 0); break; default: _nextCookSequenceId = 0x106; } } break; case 0x103: if (gnap._actionStatus >= 0 || plat._actionStatus >= 0) _nextCookSequenceId = 0x106; else if (_vm->getRandom(7) == 0) _nextCookSequenceId = 0x104; else _nextCookSequenceId = 0x106; break; case 0x104: if (gnap._actionStatus >= 0 || plat._actionStatus >= 0) _nextCookSequenceId = 0x106; else if (_vm->getRandom(7) == 0) _nextCookSequenceId = 0x103; else _nextCookSequenceId = 0x106; break; case 0x105: if (gnap._actionStatus >= 0 || plat._actionStatus >= 0) _nextCookSequenceId = 0x106; else { int rnd = _vm->getRandom(7); switch (rnd) { case 0: _nextCookSequenceId = 0x104; break; case 1: _nextCookSequenceId = 0x103; break; default: _nextCookSequenceId = 0x106; } } _vm->_timers[2] = _vm->getRandom(30) + 20; _vm->_timers[3] = 300; gameSys.insertSequence(0x10C, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0x10C; gnap._idleFacing = kDirUpRight; gnap._sequenceDatNum = 0; gnap._actionStatus = -1; plat._actionStatus = -1; break; } if (_currCookSequenceId == 0x843) gameSys.setAnimation(_currCookSequenceId | 0x10000, 301, 2); else gameSys.setAnimation(_currCookSequenceId, 100, 2); } } void Scene10::updateAnimationsCb() { GameSys& gameSys = *_vm->_gameSys; if (gameSys.getAnimationStatus(2) == 2) { gameSys.setAnimation(_nextCookSequenceId, 100, 2); gameSys.insertSequence(_nextCookSequenceId, 100, _currCookSequenceId, 100, kSeqSyncWait, 0, 0, 0); _currCookSequenceId = _nextCookSequenceId; _nextCookSequenceId = 0x106; } } /*****************************************************************************/ Scene11::Scene11(GnapEngine *vm) : Scene(vm) { _billardBallCtr = 0; _nextHookGuySequenceId = -1; _currHookGuySequenceId = -1; _nextGoggleGuySequenceId = -1; _currGoggleGuySequenceId = -1; } int Scene11::init() { GameSys& gameSys = *_vm->_gameSys; gameSys.setAnimation(0, 0, 0); gameSys.setAnimation(0, 0, 3); gameSys.setAnimation(0, 0, 2); if (_vm->_prevSceneNum == 10 || _vm->_prevSceneNum == 13) { _vm->playSound(0x108EC, false); _vm->playSound(0x10928, false); } return 0x209; } void Scene11::updateHotspots() { _vm->setHotspot(kHS11Platypus, 0, 0, 0, 0, SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS11ExitKitchen, 420, 140, 520, 345, SF_EXIT_U_CURSOR); _vm->setHotspot(kHS11ExitToilet, 666, 130, 740, 364, SF_EXIT_R_CURSOR); _vm->setHotspot(kHS11ExitLeft, 0, 350, 10, 599, SF_EXIT_L_CURSOR | SF_WALKABLE); _vm->setHotspot(kHS11GoggleGuy, 90, 185, 185, 340, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS11HookGuy, 210, 240, 340, 430, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS11Billard, 640, 475, 700, 530, SF_WALKABLE | SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS11WalkArea1, 0, 0, 365, 453); _vm->setHotspot(kHS11WalkArea2, 0, 0, 629, 353); _vm->setHotspot(kHS11WalkArea3, 629, 0, 799, 364); _vm->setHotspot(kHS11WalkArea4, 735, 0, 799, 397); _vm->setHotspot(kHS11WalkArea5, 510, 540, 799, 599); _vm->setDeviceHotspot(kHS11Device, -1, -1, -1, -1); _vm->_hotspotsCount = 13; } void Scene11::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; bool flag = true; _vm->_timers[7] = 50; _vm->_hotspots[kHS11Billard]._flags |= SF_DISABLED; _currGoggleGuySequenceId = 0x1F9; _currHookGuySequenceId = 0x201; switch (_vm->_prevSceneNum) { case 13: gnap.initPos(8, 5, kDirBottomLeft); plat.initPos(9, 6, kDirIdleRight); break; case 47: gnap.initPos(8, 5, kDirBottomLeft); plat.initPos(9, 5, kDirIdleRight); _currGoggleGuySequenceId = 0x1FA; _currHookGuySequenceId = 0x1FF; _vm->_timers[7] = 180; break; case 12: gnap.initPos(-1, 9, kDirBottomRight); plat.initPos(-2, 8, kDirIdleLeft); break; default: gnap.initPos(6, 6, kDirBottomLeft); plat.initPos(6, 5, kDirIdleRight); break; } _vm->queueInsertDeviceIcon(); gameSys.insertSequence(_currHookGuySequenceId, 120, 0, 0, kSeqNone, 0, 0, 0); _nextHookGuySequenceId = -1; gameSys.setAnimation(_currHookGuySequenceId, 120, 3); gameSys.insertSequence(_currGoggleGuySequenceId, 121, 0, 0, kSeqNone, 0, 0, 0); _nextGoggleGuySequenceId = -1; gameSys.setAnimation(_currGoggleGuySequenceId, 121, 2); _vm->_timers[5] = _vm->getRandom(100) + 75; _vm->_timers[4] = _vm->getRandom(40) + 20; _vm->_timers[6] = _vm->getRandom(100) + 100; _vm->endSceneInit(); if (_vm->_prevSceneNum == 12) { gnap.walkTo(Common::Point(2, 8), -1, 0x107B9, 1); plat.walkTo(Common::Point(1, 8), -1, 0x107C2, 1); } gameSys.insertSequence(0x208, 256, 0, 0, kSeqNone, 40, 0, 0); while (!_vm->_sceneDone) { _vm->testWalk(0, 0, -1, -1, -1, -1); _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS11Platypus: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(); } else { 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 kHS11ExitKitchen: _vm->_isLeavingScene = true; gnap.walkTo(Common::Point(6, 5), 0, 0x107BF, 1); gnap._actionStatus = kAS11LeaveScene; plat.walkTo(Common::Point(6, 6), -1, -1, 1); _vm->_newSceneNum = 10; break; case kHS11ExitToilet: _vm->_isLeavingScene = true; gnap.walkTo(Common::Point(8, 5), 0, 0x107BF, 1); gnap._actionStatus = kAS11LeaveScene; plat.walkTo(Common::Point(8, 6), -1, -1, 1); _vm->_newSceneNum = 13; break; case kHS11ExitLeft: _vm->_isLeavingScene = true; gnap.walkTo(Common::Point(-1, 8), 0, 0x107AF, 1); gnap._actionStatus = kAS11LeaveScene; plat.walkTo(Common::Point(-1, 9), -1, 0x107CF, 1); _vm->_newSceneNum = 12; break; case kHS11GoggleGuy: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex == kItemMagazine) { gnap.walkTo(Common::Point(3, 7), 0, 0x107BC, 1); gnap._actionStatus = kAS11ShowMagazineToGoggleGuy; gnap.playShowItem(_vm->_grabCursorSpriteIndex, 2, 0); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(3, 7), 2, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(1, 6)); break; case GRAB_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; case TALK_CURSOR: gnap._idleFacing = kDirUpLeft; gnap.walkTo(Common::Point(3, 7), 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS11TalkGoggleGuy; break; } } } break; case kHS11HookGuy: if (gnap._actionStatus < 0) { gnap._idleFacing = kDirUpRight; if (_vm->_grabCursorSpriteIndex >= 0) { gnap.walkTo(Common::Point(5, 6), 0, 0x107BC, 9); gnap._actionStatus = kAS11ShowItemToHookGuy; gnap.playShowItem(_vm->_grabCursorSpriteIndex, 4, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playSequence(gnap.getSequenceId(kGSDeflect, Common::Point(3, 6)) | 0x10000); break; case GRAB_CURSOR: gnap.walkTo(Common::Point(5, 6), 0, 0x107BC, 1); gnap._actionStatus = kAS11GrabHookGuy; break; case TALK_CURSOR: gnap._idleFacing = kDirBottomLeft; gnap.walkTo(Common::Point(5, 6), 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS11TalkHookGuy; break; case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS11Billard: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(Common::Point(9, 8)); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(9, 8)); break; case GRAB_CURSOR: gnap.walkTo(Common::Point(9, 8), 0, 0x107BA, 1); gnap._actionStatus = kAS11GrabBillardBall; break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(Common::Point(9, 8)); break; } } } break; case kHS11WalkArea1: case kHS11WalkArea2: case kHS11WalkArea3: case kHS11WalkArea4: case kHS11WalkArea5: if (gnap._actionStatus < 0) gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); break; case kHS11Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); } 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 (flag && !_vm->_timers[7]) { flag = false; gameSys.setAnimation(0x207, 257, 4); gameSys.insertSequence(0x207, 257, 0, 0, kSeqNone, 0, 0, 0); } plat.updateIdleSequence2(); gnap.updateIdleSequence2(); if (!_vm->_timers[5]) { _vm->_timers[5] = _vm->getRandom(100) + 75; if (gnap._actionStatus < 0 && plat._actionStatus < 0 && _nextGoggleGuySequenceId == -1) { if (_vm->getRandom(2)) _nextGoggleGuySequenceId = 0x1F6; else _nextGoggleGuySequenceId = 0x1F9; } } if (!_vm->_timers[4]) { _vm->_timers[4] = _vm->getRandom(40) + 20; if (gnap._actionStatus < 0 && plat._actionStatus < 0 && _nextHookGuySequenceId == -1) { if (_currHookGuySequenceId == 0x201) { switch (_vm->getRandom(7)) { case 0: _nextHookGuySequenceId = 0x200; break; case 1: _nextHookGuySequenceId = 0x205; break; case 2: _nextHookGuySequenceId = 0x202; break; default: _nextHookGuySequenceId = 0x201; break; } } else { _nextHookGuySequenceId = 0x201; } } } if (!_vm->_timers[6]) { _vm->_timers[6] = _vm->getRandom(100) + 100; int _gnapRandomValue = _vm->getRandom(3); switch (_gnapRandomValue) { case 0: gameSys.insertSequence(0x8A5 | 0x10000, 179, 0, 0, kSeqNone, 0, 0, 0); break; case 1: gameSys.insertSequence(0x8A7 | 0x10000, 179, 0, 0, kSeqNone, 0, 0, 0); break; case 2: gameSys.insertSequence(0x8A6 | 0x10000, 179, 0, 0, kSeqNone, 0, 0, 0); break; } } } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); _vm->_timers[5] = _vm->getRandom(50) + 75; _vm->_timers[4] = _vm->getRandom(40) + 20; } _vm->gameUpdateTick(); } } void Scene11::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; if (gameSys.getAnimationStatus(0) == 2) { if (gnap._actionStatus != kAS11GrabBillardBall) gameSys.setAnimation(0, 0, 0); switch (gnap._actionStatus) { case kAS11LeaveScene: _vm->_sceneDone = true; break; case kAS11ShowMagazineToGoggleGuy: _nextGoggleGuySequenceId = 0x1F7; break; case kAS11TalkGoggleGuy: _nextGoggleGuySequenceId = 0x1FB; break; case kAS11GrabHookGuy: _nextHookGuySequenceId = 0x204; break; case kAS11ShowItemToHookGuy: _nextHookGuySequenceId = 0x203; break; case kAS11TalkHookGuy: _nextHookGuySequenceId = 0x206; break; case kAS11GrabBillardBall: if (gameSys.getAnimationStatus(2) == 2 && gameSys.getAnimationStatus(3) == 2) { gameSys.setAnimation(0, 0, 0); _vm->_timers[2] = _vm->getRandom(30) + 20; _vm->_timers[3] = _vm->getRandom(50) + 200; gameSys.insertSequence(0x1F4, 255, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0x1F4; gnap._id = 255; gnap._sequenceDatNum = 0; gameSys.removeSequence(0x207, 257, true); gameSys.removeSequence(0x208, 256, true); _nextGoggleGuySequenceId = 0x1F8; _vm->_timers[5] = _vm->getRandom(100) + 75; gameSys.insertSequence(_nextGoggleGuySequenceId, 121, _currGoggleGuySequenceId, 121, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(_nextGoggleGuySequenceId, 121, 2); _currGoggleGuySequenceId = _nextGoggleGuySequenceId; _nextGoggleGuySequenceId = -1; switch (_billardBallCtr) { case 0: _nextHookGuySequenceId = 0x1FC; break; case 1: _nextHookGuySequenceId = 0x1FD; break; default: _nextHookGuySequenceId = 0x1FE; break; } ++_billardBallCtr; gameSys.insertSequence(_nextHookGuySequenceId, 120, _currHookGuySequenceId, 120, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(_nextHookGuySequenceId, 120, 3); _currHookGuySequenceId = _nextHookGuySequenceId; _nextHookGuySequenceId = -1; _vm->_timers[4] = _vm->getRandom(40) + 20; gameSys.insertSequence(0x208, 256, 0, 0, kSeqNone, _vm->getSequenceTotalDuration(0x1F4) - 5, 0, 0); _vm->_hotspots[kHS11Billard]._flags |= SF_DISABLED; gameSys.setAnimation(0x207, 257, 4); gameSys.insertSequence(0x207, 257, 0, 0, kSeqNone, _vm->getSequenceTotalDuration(0x1FE), 0, 0); gnap._actionStatus = -1; } break; } } if (gameSys.getAnimationStatus(2) == 2 && _nextGoggleGuySequenceId != -1) { _vm->_timers[5] = _vm->getRandom(100) + 75; gameSys.insertSequence(_nextGoggleGuySequenceId, 121, _currGoggleGuySequenceId, 121, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(_nextGoggleGuySequenceId, 121, 2); _currGoggleGuySequenceId = _nextGoggleGuySequenceId; _nextGoggleGuySequenceId = -1; if (gnap._actionStatus >= 1 && gnap._actionStatus <= 4) gnap._actionStatus = -1; } if (gameSys.getAnimationStatus(3) == 2) { if (_nextHookGuySequenceId == 0x204) { gameSys.setAnimation(_nextHookGuySequenceId, 120, 3); gameSys.insertSequence(0x204, 120, _currHookGuySequenceId, 120, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x1F5, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); _currHookGuySequenceId = 0x204; _nextHookGuySequenceId = -1; gnap._sequenceId = 0x1F5; gnap._sequenceDatNum = 0; _vm->_timers[4] = _vm->getRandom(40) + 20; _vm->_timers[2] = _vm->getRandom(20) + 70; _vm->_timers[3] = _vm->getRandom(50) + 200; if (gnap._actionStatus == kAS11GrabHookGuy) gnap._actionStatus = -1; } else if (_nextHookGuySequenceId != -1) { gameSys.insertSequence(_nextHookGuySequenceId, 120, _currHookGuySequenceId, 120, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(_nextHookGuySequenceId, 120, 3); _currHookGuySequenceId = _nextHookGuySequenceId; _nextHookGuySequenceId = -1; _vm->_timers[4] = _vm->getRandom(40) + 20; if (gnap._actionStatus >= 6 && gnap._actionStatus <= 9) gnap._actionStatus = -1; } } if (gameSys.getAnimationStatus(4) == 2) { gameSys.setAnimation(0, 0, 4); _vm->_hotspots[kHS11Billard]._flags &= ~SF_DISABLED; } } /*****************************************************************************/ Scene12::Scene12(GnapEngine *vm) : Scene(vm) { _nextBeardGuySequenceId = -1; _currBeardGuySequenceId = -1; _nextToothGuySequenceId = -1; _currToothGuySequenceId = -1; _nextBarkeeperSequenceId = -1; _currBarkeeperSequenceId = -1; } int Scene12::init() { return 0x209; } void Scene12::updateHotspots() { _vm->setHotspot(kHS12Platypus, 0, 0, 0, 0, SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS12ExitRight, 790, 360, 799, 599, SF_EXIT_R_CURSOR); _vm->setHotspot(kHS12ToothGuy, 80, 180, 160, 380, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS12Barkeeper, 490, 175, 580, 238, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS12BeardGuy, 620, 215, 720, 350, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS12Jukebox, 300, 170, 410, 355, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS12WalkArea1, 0, 0, 260, 460); _vm->setHotspot(kHS12WalkArea2, 0, 0, 380, 410); _vm->setHotspot(kHS12WalkArea3, 0, 0, 799, 395); _vm->setHotspot(kHS12WalkArea4, 585, 0, 799, 455); _vm->setDeviceHotspot(kHS12Device, -1, -1, -1, -1); _vm->_hotspotsCount = 11; } void Scene12::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; int v18 = 1; _vm->queueInsertDeviceIcon(); gameSys.insertSequence(0x207, 256, 0, 0, kSeqNone, 0, 0, 0); gameSys.insertSequence(0x200, 50, 0, 0, kSeqNone, 0, 0, 0); _currToothGuySequenceId = 0x200; _nextToothGuySequenceId = -1; gameSys.setAnimation(0x200, 50, 2); gameSys.insertSequence(0x202, 50, 0, 0, kSeqNone, 0, 0, 0); _currBeardGuySequenceId = 0x202; _nextBeardGuySequenceId = -1; gameSys.setAnimation(0x202, 50, 4); gameSys.insertSequence(0x203, 50, 0, 0, kSeqNone, 0, 0, 0); _currBarkeeperSequenceId = 0x203; _nextBarkeeperSequenceId = -1; gameSys.setAnimation(0x203, 50, 3); _vm->_timers[4] = 30; _vm->_timers[6] = _vm->getRandom(30) + 20; _vm->_timers[5] = _vm->getRandom(30) + 20; _vm->_timers[7] = _vm->getRandom(100) + 100; if (_vm->_prevSceneNum == 15) { gnap.initPos(5, 6, kDirBottomRight); plat.initPos(3, 7, kDirIdleLeft); _vm->endSceneInit(); } else { gnap.initPos(11, 8, kDirBottomLeft); plat.initPos(12, 8, kDirIdleRight); _vm->endSceneInit(); gnap.walkTo(Common::Point(8, 8), -1, 0x107BA, 1); plat.walkTo(Common::Point(9, 8), -1, 0x107D2, 1); } while (!_vm->_sceneDone) { _vm->testWalk(0, 0, -1, -1, -1, -1); _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->updateGrabCursorSprite(0, 0); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS12Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); } break; case kHS12Platypus: 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 kHS12ExitRight: _vm->_isLeavingScene = true; gnap.walkTo(Common::Point(10, -1), 0, 0x107AB, 1); gnap._actionStatus = kAS12LeaveScene; plat.walkTo(Common::Point(10, -1), -1, -1, 1); _vm->_newSceneNum = 11; break; case kHS12ToothGuy: if (_vm->_grabCursorSpriteIndex == kItemQuarter) { _vm->_largeSprite = gameSys.createSurface(0x141); gnap.walkTo(Common::Point(3, 7), 0, 0x107BC, 9); gnap._idleFacing = kDirUpLeft; gnap._actionStatus = kAS12QuarterToToothGuy; gnap.playShowItem(_vm->_grabCursorSpriteIndex, 2, 0); _vm->setGrabCursorSprite(-1); } else if (_vm->_grabCursorSpriteIndex == kItemQuarterWithHole) { gnap.walkTo(Common::Point(3, 7), 0, 0x107BC, 9); gnap._idleFacing = kDirUpLeft; gnap._actionStatus = kAS12QuarterWithHoleToToothGuy; gnap.playShowItem(_vm->_grabCursorSpriteIndex, 2, 0); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.walkTo(Common::Point(3, 7), 0, 0x107BC, 9); gnap._idleFacing = kDirUpLeft; gnap._actionStatus = kAS12ShowItemToToothGuy; gnap.playShowItem(_vm->_grabCursorSpriteIndex, 2, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(1, 2)); break; case GRAB_CURSOR: gnap.walkTo(Common::Point(3, 7), 0, 0x107BC, 1); gnap._actionStatus = kAS12GrabToothGuy; break; case TALK_CURSOR: gnap._idleFacing = kDirUpLeft; gnap.walkTo(Common::Point(3, 7), 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS12TalkToothGuy; break; case PLAT_CURSOR: gnap.useDeviceOnPlatypus(); plat.walkTo(Common::Point(3, 7), 1, 0x107D2, 1); plat._actionStatus = kAS12PlatWithToothGuy; plat._idleFacing = kDirIdleRight; gnap.playIdle(Common::Point(2, 7)); break; } } break; case kHS12Barkeeper: if (_vm->_grabCursorSpriteIndex == kItemQuarter || _vm->_grabCursorSpriteIndex == kItemQuarterWithHole) { gnap.walkTo(Common::Point(6, 6), 0, 0x107BB, 9); gnap._idleFacing = kDirUpRight; gnap._actionStatus = kAS12QuarterWithBarkeeper; gnap.playShowItem(_vm->_grabCursorSpriteIndex, 7, 0); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.walkTo(Common::Point(6, 6), 0, 0x107BB, 9); gnap._idleFacing = kDirUpRight; gnap._actionStatus = kAS12ShowItemToBarkeeper; gnap.playShowItem(_vm->_grabCursorSpriteIndex, 7, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.walkTo(Common::Point(6, 6), 0, 0x107BB, 1); gnap._idleFacing = kDirUpRight; gnap._actionStatus = kAS12LookBarkeeper; break; case GRAB_CURSOR: gnap.playImpossible(); break; case TALK_CURSOR: gnap._idleFacing = kDirUpRight; gnap.walkTo(Common::Point(6, 6), 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS12TalkBarkeeper; break; case PLAT_CURSOR: gnap.playPullOutDevice(plat._pos); gameSys.setAnimation(makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, 0); gnap._actionStatus = kAS12PlatWithBarkeeper; break; } } break; case kHS12BeardGuy: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.walkTo(Common::Point(7, 6), 0, 0x107BB, 9); gnap._idleFacing = kDirUpRight; gnap._actionStatus = kAS12ShowItemToBeardGuy; gnap.playShowItem(_vm->_grabCursorSpriteIndex, 8, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.walkTo(Common::Point(7, 6), 0, 0x107BB, 1); gnap._idleFacing = kDirUpRight; gnap._actionStatus = kAS12LookBeardGuy; break; case GRAB_CURSOR: // NOTE Bug in the original. It has 9 as flags which seems wrong here. gnap.walkTo(Common::Point(7, 6), 0, 0x107BB, 1); gnap._idleFacing = kDirUpRight; gnap._actionStatus = kAS12GrabBeardGuy; break; case TALK_CURSOR: gnap._idleFacing = kDirUpRight; gnap.walkTo(Common::Point(7, 6), 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS12TalkBeardGuy; break; case PLAT_CURSOR: gnap.useDeviceOnPlatypus(); plat.walkTo(Common::Point(7, 6), 1, 0x107C2, 1); plat._actionStatus = kAS12PlatWithBeardGuy; plat._idleFacing = kDirIdleLeft; gnap.playIdle(Common::Point(7, 6)); break; } } break; case kHS12Jukebox: _vm->_newSceneNum = 15; _vm->_isLeavingScene = true; gnap.walkTo(Common::Point(5, 6), 0, 0x107BC, 1); gnap._actionStatus = kAS12LeaveScene; break; case kHS12WalkArea1: case kHS12WalkArea2: case kHS12WalkArea3: case kHS12WalkArea4: 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) { plat.updateIdleSequence(); gnap.updateIdleSequence(); if (!_vm->_timers[4]) { _vm->_timers[4] = 15; if (_nextToothGuySequenceId == -1) { if (v18 == 0 && _currBeardGuySequenceId == 0x202 && _currBarkeeperSequenceId == 0x203 && gnap._actionStatus < 0 && plat._actionStatus < 0) { if (_vm->getRandom(2) != 0) _nextToothGuySequenceId = 0x1EC; else _nextToothGuySequenceId = 0x204; } else if (_currToothGuySequenceId != 0x200) _nextToothGuySequenceId = 0x200; v18 = (v18 + 1) % 15; } } if (!_vm->_timers[5]) { _vm->_timers[5] = _vm->getRandom(30) + 20; if (_nextBarkeeperSequenceId == -1 && gnap._actionStatus < 0 && plat._actionStatus < 0) { if (v18 == 0 && _currToothGuySequenceId == 0x200 && _currBeardGuySequenceId == 0x202 && gnap._actionStatus < 0 && plat._actionStatus < 0) { if (_vm->getRandom(2) != 0) _nextBarkeeperSequenceId = 0x208; else _nextBarkeeperSequenceId = 0x1FB; } else _nextBarkeeperSequenceId = 0x203; v18 = (v18 + 1) % 15; } } if (!_vm->_timers[6]) { _vm->_timers[6] = _vm->getRandom(30) + 15; if (_nextBeardGuySequenceId == -1 && gnap._actionStatus < 0 && plat._actionStatus < 0) { if (v18 == 0 && _currToothGuySequenceId == 0x200 && _currBarkeeperSequenceId == 0x203 && gnap._actionStatus < 0 && plat._actionStatus < 0) _nextBeardGuySequenceId = 0x1F2; else _nextBeardGuySequenceId = 0x202; v18 = (v18 + 1) % 15; } } if (!_vm->_timers[7]) { _vm->_timers[7] = _vm->getRandom(100) + 100; int _gnapRandomValue = _vm->getRandom(3); switch (_gnapRandomValue) { case 0: gameSys.insertSequence(0x8A5 | 0x10000, 179, 0, 0, kSeqNone, 0, 0, 0); break; case 1: gameSys.insertSequence(0x8A7 | 0x10000, 179, 0, 0, kSeqNone, 0, 0, 0); break; case 2: gameSys.insertSequence(0x8A6 | 0x10000, 179, 0, 0, kSeqNone, 0, 0, 0); break; } } } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); _vm->_timers[4] = 30; _vm->_timers[5] = _vm->getRandom(30) + 20; _vm->_timers[6] = _vm->getRandom(30) + 20; } _vm->gameUpdateTick(); } } void Scene12::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 kAS12LeaveScene: _vm->_sceneDone = true; break; case kAS12TalkToothGuy: if (_vm->isKeyStatus1(Common::KEYCODE_j)) { // Easter egg _vm->clearKeyStatus1(Common::KEYCODE_j); _nextToothGuySequenceId = 0x206; } else { _nextToothGuySequenceId = 0x1EE; } break; case 3: break; case kAS12GrabToothGuy: if (_vm->isKeyStatus1(Common::KEYCODE_j)) { _vm->clearKeyStatus1(Common::KEYCODE_j); _nextToothGuySequenceId = 0x206; } else { _nextToothGuySequenceId = 0x1EF; } break; case kAS12ShowItemToToothGuy: if (_vm->isKeyStatus1(Common::KEYCODE_j)) { _vm->clearKeyStatus1(Common::KEYCODE_j); _nextToothGuySequenceId = 0x206; } else { _nextToothGuySequenceId = 0x1ED; } break; case kAS12QuarterWithHoleToToothGuy: if (_vm->isKeyStatus1(Common::KEYCODE_j)) { _vm->clearKeyStatus1(Common::KEYCODE_j); _nextToothGuySequenceId = 0x206; } else { _nextToothGuySequenceId = 0x1EA; } break; case kAS12QuarterToToothGuy: if (_vm->isKeyStatus1(Common::KEYCODE_j)) { _vm->clearKeyStatus1(Common::KEYCODE_j); _nextToothGuySequenceId = 0x206; } else { _nextToothGuySequenceId = 0x1E9; } break; case kAS12QuarterToToothGuyDone: gnap._actionStatus = -1; _vm->showCursor(); gameSys.removeSpriteDrawItem(_vm->_largeSprite, 300); _vm->deleteSurface(&_vm->_largeSprite); _vm->setGrabCursorSprite(kItemQuarterWithHole); break; case kAS12TalkBeardGuy: _nextBeardGuySequenceId = 0x1F4; break; case kAS12LookBeardGuy: _nextBeardGuySequenceId = 0x1F3; break; case kAS12GrabBeardGuy: _nextBeardGuySequenceId = 0x1F1; break; case kAS12ShowItemToBeardGuy: _nextBeardGuySequenceId = 0x1F0; break; case kAS12TalkBarkeeper: if (_vm->getRandom(2) != 0) _nextBarkeeperSequenceId = 0x1FD; else _nextBarkeeperSequenceId = 0x1FF; break; case kAS12LookBarkeeper: _nextBarkeeperSequenceId = 0x1F8; break; case 14: _nextBarkeeperSequenceId = 0x1F6; break; case kAS12ShowItemToBarkeeper: _nextBarkeeperSequenceId = 0x1F5; break; case kAS12QuarterWithBarkeeper: _nextBarkeeperSequenceId = 0x1FA; break; case kAS12PlatWithBarkeeper: _nextBarkeeperSequenceId = 0x1F9; break; } } if (gameSys.getAnimationStatus(1) == 2) { gameSys.setAnimation(0, 0, 1); switch (plat._actionStatus) { case kAS12PlatWithToothGuy: _nextToothGuySequenceId = 0x1EB; break; case kAS12PlatWithBeardGuy: _nextBeardGuySequenceId = 0x1F3; break; } } if (gameSys.getAnimationStatus(2) == 2) { if (_currToothGuySequenceId == 0x1E9) { gameSys.setAnimation(0, 0, 2); _vm->hideCursor(); gameSys.setAnimation(0x10843, 301, 0); gnap._actionStatus = kAS12QuarterToToothGuyDone; gameSys.insertSpriteDrawItem(_vm->_largeSprite, 0, 0, 300); gameSys.insertSequence(0x10843, 301, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x107B7, gnap._id, 0x10843, 301, kSeqSyncWait, 0, 75 * gnap._pos.x - gnap._gridX, 48 * gnap._pos.y - gnap._gridY); gnap._sequenceId = 0x7B7; gnap._sequenceDatNum = 1; _vm->setFlag(kGFTwigTaken); _vm->invAdd(kItemQuarterWithHole); _vm->invRemove(kItemQuarter); } if (_nextToothGuySequenceId == 0x1EF) { gameSys.setAnimation(_nextToothGuySequenceId, 50, 2); gameSys.insertSequence(_nextToothGuySequenceId, 50, _currToothGuySequenceId, 50, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x205, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); _currToothGuySequenceId = _nextToothGuySequenceId; _nextToothGuySequenceId = -1; gnap._sequenceId = 0x205; gnap._sequenceDatNum = 0; _vm->_timers[4] = 40; _vm->_timers[2] = _vm->getRandom(20) + 70; _vm->_timers[3] = _vm->getRandom(50) + 200; if (gnap._actionStatus == kAS12GrabToothGuy) gnap._actionStatus = -1; } else if (_nextToothGuySequenceId != -1) { gameSys.insertSequence(_nextToothGuySequenceId, 50, _currToothGuySequenceId, 50, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(_nextToothGuySequenceId, 50, 2); _currToothGuySequenceId = _nextToothGuySequenceId; _nextToothGuySequenceId = -1; _vm->_timers[4] = 50; if (gnap._actionStatus >= kAS12TalkToothGuy && gnap._actionStatus <= kAS12QuarterToToothGuy && _currToothGuySequenceId != 0x1E9 && _currToothGuySequenceId != 0x1EC && _currToothGuySequenceId != 0x200) gnap._actionStatus = -1; if (plat._actionStatus == kAS12PlatWithToothGuy) plat._actionStatus = -1; } } if (gameSys.getAnimationStatus(3) == 2) { if (gnap._actionStatus == kAS12PlatWithBarkeeper && _currBarkeeperSequenceId == 0x1F9) { gnap._actionStatus = -1; gnap.playIdle(Common::Point(7, 6)); _vm->_timers[5] = 0; } if (_nextBarkeeperSequenceId != -1) { gameSys.insertSequence(_nextBarkeeperSequenceId, 50, _currBarkeeperSequenceId, 50, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(_nextBarkeeperSequenceId, 50, 3); _currBarkeeperSequenceId = _nextBarkeeperSequenceId; _nextBarkeeperSequenceId = -1; _vm->_timers[5] = _vm->getRandom(30) + 20; if (gnap._actionStatus >= kAS12TalkBarkeeper && gnap._actionStatus <= kAS12QuarterWithBarkeeper && _currBarkeeperSequenceId != 0x203 && _currBarkeeperSequenceId != 0x1FB && _currBarkeeperSequenceId != 0x208) gnap._actionStatus = -1; } } if (gameSys.getAnimationStatus(4) == 2 && _nextBeardGuySequenceId != -1) { gameSys.insertSequence(_nextBeardGuySequenceId, 50, _currBeardGuySequenceId, 50, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(_nextBeardGuySequenceId, 50, 4); _currBeardGuySequenceId = _nextBeardGuySequenceId; _nextBeardGuySequenceId = -1; _vm->_timers[6] = _vm->getRandom(30) + 20; if (gnap._actionStatus >= kAS12TalkBeardGuy && gnap._actionStatus <= kAS12ShowItemToBeardGuy && _currBeardGuySequenceId != 0x202 && _currBeardGuySequenceId != 0x1F2) gnap._actionStatus = -1; if (plat._actionStatus == kAS12PlatWithBeardGuy) plat._actionStatus = -1; } } /*****************************************************************************/ Scene13::Scene13(GnapEngine *vm) : Scene(vm) { _backToiletCtr = -1; } int Scene13::init() { _vm->playSound(0x108EC, false); return 0xAC; } void Scene13::updateHotspots() { _vm->setHotspot(kHS13Platypus, 0, 0, 0, 0, SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS13ExitBar, 113, 160, 170, 455, SF_EXIT_L_CURSOR); _vm->setHotspot(kHS13BackToilet, 385, 195, 478, 367, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS13FrontToilet, 497, 182, 545, 432, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS13Urinal, 680, 265, 760, 445, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS13Scribble, 560, 270, 660, 370, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS13Sink, 310, 520, 560, 599, SF_WALKABLE | SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS13WalkArea1, 268, 270, 325, 385); _vm->setHotspot(kHS13WalkArea2, 0, 0, 52, 599); _vm->setHotspot(kHS13WalkArea3, 0, 0, 113, 550); _vm->setHotspot(kHS13WalkArea4, 0, 0, 226, 438); _vm->setHotspot(kHS13WalkArea5, 0, 0, 268, 400); _vm->setHotspot(kHS13WalkArea6, 0, 0, 799, 367); _vm->setHotspot(kHS13WalkArea7, 478, 0, 799, 401); _vm->setHotspot(kHS13WalkArea8, 545, 0, 799, 473); _vm->setHotspot(kHS13WalkArea9, 0, 549, 799, 599); _vm->setDeviceHotspot(kHS13Device, -1, -1, -1, -1); _vm->_hotspotsCount = 17; } void Scene13::showScribble() { GameSys& gameSys = *_vm->_gameSys; _vm->hideCursor(); _vm->_largeSprite = gameSys.createSurface(0x6F); gameSys.insertSpriteDrawItem(_vm->_largeSprite, 0, 0, 300); while (!_vm->_mouseClickState._left && !_vm->isKeyStatus1(Common::KEYCODE_ESCAPE) && !_vm->isKeyStatus1(Common::KEYCODE_SPACE) && !_vm->isKeyStatus1(Common::KEYCODE_RETURN) && !_vm->_gameDone) _vm->gameUpdateTick(); _vm->_mouseClickState._left = false; _vm->clearKeyStatus1(Common::KEYCODE_ESCAPE); _vm->clearKeyStatus1(Common::KEYCODE_RETURN); _vm->clearKeyStatus1(Common::KEYCODE_SPACE); gameSys.removeSpriteDrawItem(_vm->_largeSprite, 300); _vm->deleteSurface(&_vm->_largeSprite); _vm->showCursor(); } void Scene13::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; int currSoundId = 0; _vm->queueInsertDeviceIcon(); gameSys.insertSequence(0xAA, 256, 0, 0, kSeqNone, 0, 0, 0); if (_vm->_prevSceneNum == 14) { gnap.initPos(6, 6, kDirBottomLeft); plat.initPos(9, 8, kDirIdleLeft); } else { gnap.initPos(3, 7, kDirBottomRight); plat.initPos(2, 7, kDirIdleLeft); } _vm->endSceneInit(); _vm->_timers[4] = _vm->getRandom(20) + 20; _vm->_timers[5] = _vm->getRandom(50) + 50; while (!_vm->_sceneDone) { if (!_vm->isSoundPlaying(0x1091A)) _vm->playSound(0x1091A, 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 kHS13Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); _vm->_timers[4] = _vm->getRandom(20) + 20; _vm->_timers[5] = _vm->getRandom(50) + 50; } break; case kHS13Platypus: 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 kHS13ExitBar: _vm->_isLeavingScene = true; gnap.walkTo(Common::Point(2, 7), 0, 0x107C0, 1); gnap._actionStatus = kAS13LeaveScene; plat.walkTo(Common::Point(2, 8), -1, -1, 1); if (_vm->isFlag(kGFUnk14) || _vm->isFlag(kGFSpringTaken)) { _vm->_newSceneNum = 11; } else { _vm->setFlag(kGFSpringTaken); _vm->_newSceneNum = 47; } break; case kHS13BackToilet: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(5, 5), 6, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: case GRAB_CURSOR: case TALK_CURSOR: if (gnap._pos == Common::Point(5, 5)) { _backToiletCtr = MIN(5, _backToiletCtr + 1); gameSys.setAnimation(_backToiletCtr + 0xA3, gnap._id, 0); gameSys.insertSequence(_backToiletCtr + 0xA3, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqScale | kSeqSyncWait, 0, 0, 0); gnap._actionStatus = kAS13Wait; gnap._sequenceId = _backToiletCtr + 0xA3; gnap._idleFacing = kDirUpRight; gnap._sequenceDatNum = 0; } else { gnap.walkTo(Common::Point(5, 5), 0, 0x107BB, 1); gnap._actionStatus = kAS13BackToilet; gnap._idleFacing = kDirUpRight; } break; case PLAT_CURSOR: gnap.playImpossible(); break; } } break; case kHS13FrontToilet: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(6, 7), 7, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: case GRAB_CURSOR: case TALK_CURSOR: case PLAT_CURSOR: gnap.walkTo(Common::Point(6, 7), 0, 0xA9, 5); gnap._actionStatus = kAS13FrontToilet; gnap._idleFacing = kDirBottomRight; break; } } break; case kHS13Scribble: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(7, 7), 8, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.walkTo(Common::Point(7, 7), 0, 0x107BB, 1); gnap._actionStatus = kAS13LookScribble; gnap._idleFacing = kDirUpRight; break; case GRAB_CURSOR: gnap.playScratchingHead(); break; case TALK_CURSOR: gnap._idleFacing = kDirUpRight; gnap.walkTo(Common::Point(7, 7), -1, gnap.getSequenceId(kGSBrainPulsating, Common::Point(0, 0)), 1); break; case PLAT_CURSOR: gnap.playImpossible(); break; } } break; case kHS13Urinal: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(Common::Point(8, 7), 9, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playSequence(gnap.getSequenceId(kGSDeflect, Common::Point(9, 6))); gnap.walkTo(gnap._pos, 0, -1, 1); gnap._actionStatus = kAS13Wait; break; case GRAB_CURSOR: gnap.walkTo(Common::Point(8, 7), 0, -1, 1); gnap._actionStatus = kAS13GrabUrinal; break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } break; case kHS13Sink: if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playSequence(gnap.getSequenceId(kGSDeflect, Common::Point(5, 9))); gnap.walkTo(gnap._pos, 0, -1, 1); gnap._actionStatus = kAS13Wait; break; case GRAB_CURSOR: gnap.walkTo(Common::Point(4, 8), 0, 0x107B9, 1); gnap._actionStatus = kAS13GrabSink; break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } break; case kHS13WalkArea2: case kHS13WalkArea3: case kHS13WalkArea4: case kHS13WalkArea5: case kHS13WalkArea6: case kHS13WalkArea7: case kHS13WalkArea8: case kHS13WalkArea9: gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); break; case kHS13WalkArea1: // 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) { plat.updateIdleSequence(); if (plat._pos.y == 5 || plat._pos.y == 6) plat.walkTo(Common::Point(-1, 7), -1, -1, 1); if (gnap._actionStatus < 0) gnap.updateIdleSequence(); if (!_vm->_timers[4]) { _vm->_timers[4] = _vm->getRandom(20) + 20; switch (_vm->getRandom(5)) { case 0: _vm->playSound(0xD2, false); break; case 1: _vm->playSound(0xD3, false); break; case 2: _vm->playSound(0xD4, false); break; case 3: _vm->playSound(0xD5, false); break; case 4: _vm->playSound(0xD6, false); break; } } if (!_vm->_timers[5]) { int newSoundId; _vm->_timers[5] = _vm->getRandom(50) + 50; switch (_vm->getRandom(7)) { case 0: newSoundId = 0xD7; _vm->_timers[5] = 2 * _vm->getRandom(50) + 100; break; case 1: case 2: newSoundId = 0xCF; break; case 3: case 4: newSoundId = 0xD0; break; default: newSoundId = 0xD1; break; } if (newSoundId != currSoundId) { _vm->playSound(newSoundId, false); currSoundId = newSoundId; } } } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); _vm->_timers[4] = _vm->getRandom(20) + 20; _vm->_timers[5] = _vm->getRandom(50) + 50; } _vm->gameUpdateTick(); } } void Scene13::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; if (gameSys.getAnimationStatus(0) == 2) { gameSys.setAnimation(0, 0, 0); switch (gnap._actionStatus) { case kAS13LeaveScene: _vm->_sceneDone = true; gnap._actionStatus = -1; break; case kAS13BackToilet: _backToiletCtr = MIN(5, _backToiletCtr + 1); gameSys.insertSequence(_backToiletCtr + 0xA3, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, 9, 0, 0, 0); gnap._sequenceId = _backToiletCtr + 0xA3; gnap._sequenceDatNum = 0; gnap._actionStatus = -1; break; case kAS13FrontToilet: _vm->_sceneDone = true; _vm->_newSceneNum = 14; break; case kAS13LookScribble: gnap._actionStatus = -1; showScribble(); break; case kAS13GrabSink: gameSys.setAnimation(0xAB, 160, 0); gameSys.insertSequence(0xAB, 160, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.removeSequence(0xAA, 256, true); gnap._sequenceId = 0xAB; gnap._id = 160; gnap._idleFacing = kDirBottomRight; gnap._sequenceDatNum = 0; gnap._pos = Common::Point(4, 8); _vm->_timers[2] = 360; gnap._actionStatus = kAS13GrabSinkDone; break; case kAS13GrabSinkDone: gameSys.insertSequence(0xAA, 256, 0, 0, kSeqNone, 0, 0, 0); gnap._actionStatus = -1; break; case kAS13Wait: gnap._actionStatus = -1; break; case kAS13GrabUrinal: gameSys.setAnimation(0xA2, 120, 0); gameSys.insertSequence(0xA2, 120, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0xA2; gnap._id = 120; gnap._idleFacing = kDirBottomLeft; gnap._sequenceDatNum = 0; gnap._pos = Common::Point(4, 6); _vm->_timers[2] = 360; gnap._actionStatus = kAS13Wait; break; } } if (gameSys.getAnimationStatus(1) == 2) { gameSys.setAnimation(0, 0, 1); _vm->_plat->_actionStatus = -1; } } /*****************************************************************************/ Scene14::Scene14(GnapEngine *vm) : Scene(vm) { } int Scene14::init() { GameSys& gameSys = *_vm->_gameSys; gameSys.setAnimation(0, 0, 0); gameSys.setAnimation(0, 0, 1); return 0x27; } void Scene14::updateHotspots() { _vm->setHotspot(kHS14Platypus, 0, 0, 0, 0); _vm->setHotspot(kHS14Exit, 0, 590, 799, 599, SF_EXIT_D_CURSOR); _vm->setHotspot(kHS14Coin, 330, 390, 375, 440, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS14Toilet, 225, 250, 510, 500, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setDeviceHotspot(kHS14Device, -1, -1, -1, -1); if (_vm->isFlag(kGFNeedleTaken)) _vm->_hotspots[kHS14Coin]._flags = SF_DISABLED; _vm->_hotspotsCount = 5; } void Scene14::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; _vm->_largeSprite = nullptr; _vm->queueInsertDeviceIcon(); if (!_vm->isFlag(kGFNeedleTaken)) gameSys.insertSequence(0x23, 10, 0, 0, kSeqNone, 0, 0, 0); _vm->endSceneInit(); if (!_vm->isFlag(kGFNeedleTaken) && _vm->invHas(kItemTongs)) _vm->_largeSprite = gameSys.createSurface(1); if (!_vm->isFlag(kGFNeedleTaken)) { gameSys.insertSequence(0x24, 10, 0x23, 10, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0x24; _vm->_timers[2] = _vm->getRandom(40) + 50; } while (!_vm->_sceneDone) { _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS14Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); } break; case kHS14Exit: _vm->_sceneDone = true; _vm->_newSceneNum = 13; break; case kHS14Coin: if (_vm->_grabCursorSpriteIndex == kItemTongs) { _vm->invAdd(kItemQuarter); _vm->setFlag(kGFNeedleTaken); _vm->setGrabCursorSprite(-1); _vm->hideCursor(); gameSys.setAnimation(0x26, 10, 0); gameSys.insertSequence(0x26, 10, gnap._sequenceId, 10, kSeqSyncWait, 0, 0, 0); } else if (_vm->_grabCursorSpriteIndex >= 0) { _vm->playSound(0x108E9, false); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: _vm->playSound(0x108E9, false); break; case GRAB_CURSOR: gameSys.insertSequence(0x25, 10, gnap._sequenceId, 10, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x23, 10, 0x25, 10, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0x23; break; case TALK_CURSOR: _vm->playSound((_vm->getRandom(5) + 0x8D5) | 0x10000, false); break; case PLAT_CURSOR: gameSys.insertSequence(0x107A8, 1, 0, 0, kSeqNone, 0, 900 - gnap._gridX, 576 - gnap._gridY); break; } } break; case kHS14Toilet: if (_vm->_grabCursorSpriteIndex >= 0) { gameSys.insertSequence(0x107A8, 1, 0, 0, kSeqNone, 0, 900 - gnap._gridX, 576 - gnap._gridY); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: case GRAB_CURSOR: _vm->playSound(0x108B1, false); break; case TALK_CURSOR: _vm->playSound((_vm->getRandom(5) + 0x8D5) | 0x10000, false); break; case PLAT_CURSOR: gameSys.insertSequence(0x107A8, 1, 0, 0, kSeqNone, 0, 900 - gnap._gridX, 576 - gnap._gridY); break; } } break; default: _vm->_mouseClickState._left = false; break; } updateAnimations(); _vm->checkGameKeys(); if (!_vm->isFlag(kGFNeedleTaken) && !_vm->_timers[2]) { gameSys.insertSequence(0x24, 10, gnap._sequenceId, 10, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0x24; _vm->_timers[2] = _vm->getRandom(40) + 50; } if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); } _vm->gameUpdateTick(); } if (_vm->_largeSprite) _vm->deleteSurface(&_vm->_largeSprite); } void Scene14::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; if (gameSys.getAnimationStatus(0) == 2) { gameSys.setAnimation(0, 0, 0); gameSys.insertSpriteDrawItem(_vm->_largeSprite, 0, 0, 300); gameSys.setAnimation(0x10843, 301, 1); gameSys.insertSequence(0x10843, 301, 0x26, 10, kSeqSyncWait, 0, 0, 0); } if (gameSys.getAnimationStatus(1) == 2) { gameSys.setAnimation(0, 0, 1); _vm->_sceneDone = true; _vm->_newSceneNum = 13; _vm->_grabCursorSpriteIndex = kItemQuarter; } } /*****************************************************************************/ Scene15::Scene15(GnapEngine *vm) : Scene(vm) { _nextRecordSequenceId = -1; _currRecordSequenceId = -1; _nextSlotSequenceId = -1; _currSlotSequenceId = -1; _nextUpperButtonSequenceId = -1; _currUpperButtonSequenceId = -1; _nextLowerButtonSequenceId = -1; _currLowerButtonSequenceId = -1; } int Scene15::init() { return 0xDD; } void Scene15::updateHotspots() { _vm->setHotspot(kHS15Platypus, 0, 0, 0, 0, SF_DISABLED); _vm->setHotspot(kHS15Exit, 50, 590, 750, 599, SF_EXIT_D_CURSOR); _vm->setHotspot(kHS15Button1, 210, 425, 260, 475, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS15Button2, 280, 425, 325, 475, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS15Button3, 340, 425, 385, 475, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS15Button4, 400, 425, 445, 475, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS15Button5, 460, 425, 510, 475, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS15Button6, 520, 425, 560, 475, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS15ButtonA, 205, 480, 250, 535, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS15ButtonB, 270, 480, 320, 535, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS15ButtonC, 335, 480, 380, 535, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS15ButtonD, 395, 480, 445, 535, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS15ButtonE, 460, 480, 505, 535, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS15ButtonF, 515, 480, 560, 535, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS15CoinSlot, 585, 475, 620, 535, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS15PlayButton, 622, 431, 650, 482, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setDeviceHotspot(kHS15Device, -1, -1, -1, -1); _vm->_hotspotsCount = 17; } void Scene15::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; _currSlotSequenceId = -1; _currUpperButtonSequenceId = -1; _currLowerButtonSequenceId = -1; _nextSlotSequenceId = -1; _nextUpperButtonSequenceId = -1; _nextLowerButtonSequenceId = -1; _currRecordSequenceId = 0xD5; _nextRecordSequenceId = -1; gameSys.setAnimation(0xD5, 1, 0); gameSys.insertSequence(_currRecordSequenceId, 1, 0, 0, kSeqNone, 0, 0, 0); _vm->queueInsertDeviceIcon(); _vm->endSceneInit(); while (!_vm->_sceneDone) { _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->_hotspots[kHS15Platypus].clearRect(); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS15Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); } break; case kHS15Exit: _vm->_newSceneNum = 12; _vm->_isLeavingScene = true; break; case kHS15CoinSlot: if (_vm->_grabCursorSpriteIndex == kItemQuarter || _vm->_grabCursorSpriteIndex == kItemQuarterWithHole) { _nextSlotSequenceId = 0xDC; // Insert coin } else if (_vm->_grabCursorSpriteIndex == kItemDiceQuarterHole) { _nextSlotSequenceId = 0xDB; } else if (_vm->_grabCursorSpriteIndex >= 0) { gameSys.insertSequence(0x107A8, 1, 0, 0, kSeqNone, 0, 900 - gnap._gridX, 576 - gnap._gridY); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: case GRAB_CURSOR: _vm->playSound(0x108E9, false); break; case TALK_CURSOR: _vm->playSound((_vm->getRandom(5) + 0x8D5) | 0x10000, false); break; case PLAT_CURSOR: gameSys.insertSequence(0x107A8, 1, 0, 0, kSeqNone, 0, 900 - gnap._gridX, 576 - gnap._gridY); break; } } break; case kHS15PlayButton: if (_vm->_grabCursorSpriteIndex >= 0) { gameSys.insertSequence(0x107A8, 1, 0, 0, kSeqNone, 0, 900 - gnap._gridX, 576 - gnap._gridY); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: if (_vm->isFlag(kGFGnapControlsToyUFO) || _vm->isFlag(kGFUnk13)) _vm->playSound(0x108E9, false); else _nextSlotSequenceId = 0xDA; break; case GRAB_CURSOR: if (_vm->isFlag(kGFGnapControlsToyUFO) || _vm->isFlag(kGFUnk13)) _nextSlotSequenceId = 0xD9; else _nextSlotSequenceId = 0xDA; break; case TALK_CURSOR: _vm->playSound((_vm->getRandom(5) + 0x8D5) | 0x10000, false); break; case PLAT_CURSOR: gameSys.insertSequence(0x107A8, 1, 0, 0, kSeqNone, 0, 900 - gnap._gridX, 576 - gnap._gridY); break; } } break; case kHS15Button1: case kHS15Button2: case kHS15Button3: case kHS15Button4: case kHS15Button5: case kHS15Button6: if (_vm->_grabCursorSpriteIndex >= 0) { gameSys.insertSequence(0x107A8, 1, 0, 0, kSeqNone, 0, 900 - gnap._gridX, 576 - gnap._gridY); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: _vm->playSound(0x108E9, false); break; case GRAB_CURSOR: _nextUpperButtonSequenceId = _vm->_sceneClickedHotspot + 0xC5; break; case TALK_CURSOR: _vm->playSound((_vm->getRandom(5) + 0x8D5) | 0x10000, false); break; case PLAT_CURSOR: gameSys.insertSequence(0x107A8, 1, 0, 0, kSeqNone, 0, 900 - gnap._gridX, 576 - gnap._gridY); break; } } break; case kHS15ButtonA: case kHS15ButtonB: case kHS15ButtonC: case kHS15ButtonD: case kHS15ButtonE: case kHS15ButtonF: if (_vm->_grabCursorSpriteIndex >= 0) { gameSys.insertSequence(0x107A8, 1, 0, 0, kSeqNone, 0, 900 - gnap._gridX, 576 - gnap._gridY); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: _vm->playSound(0x108E9, false); break; case GRAB_CURSOR: _nextLowerButtonSequenceId = _vm->_sceneClickedHotspot + 0xC5; break; case TALK_CURSOR: _vm->playSound((_vm->getRandom(5) + 0x8D5) | 0x10000, false); break; case PLAT_CURSOR: gameSys.insertSequence(0x107A8, 1, 0, 0, kSeqNone, 0, 900 - gnap._gridX, 576 - gnap._gridY); break; } } break; default: _vm->_mouseClickState._left = false; break; } updateAnimations(); _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); } _vm->gameUpdateTick(); } } void Scene15::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; if (gameSys.getAnimationStatus(0) == 2) { if (_vm->_isLeavingScene) { _vm->_sceneDone = true; } else if (_nextSlotSequenceId != -1) { gameSys.setAnimation(_nextSlotSequenceId, 1, 0); gameSys.insertSequence(_nextSlotSequenceId, 1, 0, 0, kSeqNone, 0, 0, 0); _currSlotSequenceId = _nextSlotSequenceId; _nextSlotSequenceId = -1; switch (_currSlotSequenceId) { case 0xDC: if (_vm->_grabCursorSpriteIndex == kItemQuarter) { _vm->invRemove(kItemQuarter); } else { _vm->invRemove(kItemQuarterWithHole); _vm->setFlag(kGFUnk13); } _vm->setGrabCursorSprite(-1); break; case 0xDB: _vm->setFlag(kGFUnk14); _vm->setGrabCursorSprite(-1); _nextSlotSequenceId = 0xD8; break; case 0xD9: if (_vm->isFlag(kGFGnapControlsToyUFO)) { _vm->clearFlag(kGFGnapControlsToyUFO); _vm->invAdd(kItemQuarter); _vm->_newGrabCursorSpriteIndex = kItemQuarter; } else if (_vm->isFlag(kGFUnk13)) { _vm->clearFlag(kGFUnk13); _vm->invAdd(kItemQuarterWithHole); _vm->_newGrabCursorSpriteIndex = kItemQuarterWithHole; } _vm->_newSceneNum = 12; _vm->_isLeavingScene = true; break; case 0xD8: case 0xDA: if (_currUpperButtonSequenceId != -1) { gameSys.removeSequence(_currUpperButtonSequenceId, 1, true); _currUpperButtonSequenceId = -1; } if (_currLowerButtonSequenceId != -1) { gameSys.removeSequence(_currLowerButtonSequenceId, 1, true); _currLowerButtonSequenceId = -1; } break; } } else if (_nextRecordSequenceId != -1) { gameSys.setAnimation(_nextRecordSequenceId, 1, 0); gameSys.insertSequence(_nextRecordSequenceId, 1, _currRecordSequenceId, 1, kSeqSyncWait, 0, 0, 0); _currRecordSequenceId = _nextRecordSequenceId; _nextRecordSequenceId = -1; if (_currRecordSequenceId == 0xD3) { _vm->invRemove(kItemDiceQuarterHole); _vm->_newSceneNum = 16; _vm->_isLeavingScene = true; } gameSys.removeSequence(_currUpperButtonSequenceId, 1, true); _currUpperButtonSequenceId = -1; gameSys.removeSequence(_currLowerButtonSequenceId, 1, true); _currLowerButtonSequenceId = -1; } else if (_nextUpperButtonSequenceId != -1) { gameSys.setAnimation(_nextUpperButtonSequenceId, 1, 0); if (_currUpperButtonSequenceId == -1) gameSys.insertSequence(_nextUpperButtonSequenceId, 1, 0, 0, kSeqNone, 0, 0, 0); else gameSys.insertSequence(_nextUpperButtonSequenceId, 1, _currUpperButtonSequenceId, 1, kSeqSyncWait, 0, 0, 0); _currUpperButtonSequenceId = _nextUpperButtonSequenceId; _nextUpperButtonSequenceId = -1; if (_currLowerButtonSequenceId != -1 && _vm->isFlag(kGFUnk14)) { if (_currUpperButtonSequenceId == 0xCC && _currLowerButtonSequenceId == 0xCE) _nextRecordSequenceId = 0xD3; else _nextRecordSequenceId = 0xD4; } } else if (_nextLowerButtonSequenceId != -1) { gameSys.setAnimation(_nextLowerButtonSequenceId, 1, 0); if (_currLowerButtonSequenceId == -1) gameSys.insertSequence(_nextLowerButtonSequenceId, 1, 0, 0, kSeqNone, 0, 0, 0); else gameSys.insertSequence(_nextLowerButtonSequenceId, 1, _currLowerButtonSequenceId, 1, kSeqSyncWait, 0, 0, 0); _currLowerButtonSequenceId = _nextLowerButtonSequenceId; _nextLowerButtonSequenceId = -1; if (_currUpperButtonSequenceId != -1 && _vm->isFlag(kGFUnk14)) { if (_currUpperButtonSequenceId == 0xCC && _currLowerButtonSequenceId == 0xCE) _nextRecordSequenceId = 0xD3; else _nextRecordSequenceId = 0xD4; } } } } /*****************************************************************************/ Scene17::Scene17(GnapEngine *vm) : Scene(vm) { _platTryGetWrenchCtr = 0; _wrenchCtr = 2; _nextCarWindowSequenceId = -1; _nextWrenchSequenceId = -1; _canTryGetWrench = true; _platPhoneCtr = 0; _nextPhoneSequenceId = -1; _currPhoneSequenceId = -1; _currWrenchSequenceId = -1; _currCarWindowSequenceId = -1; } int Scene17::init() { return 0x263; } void Scene17::updateHotspots() { // The original is using (1, 0, 0, 0) _vm->setHotspot(kHS17Platypus, 0, 0, 0, 0, SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS17Phone1, 61, 280, 97, 322, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 1, 7); _vm->setHotspot(kHS17Phone2, 80, 204, 178, 468, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 1, 7); _vm->setHotspot(kHS17ExitGrubCity, 196, 207, 280, 304, SF_EXIT_U_CURSOR, 3, 5); _vm->setHotspot(kHS17ExitToyStore, 567, 211, 716, 322, SF_EXIT_U_CURSOR, 5, 6); _vm->setHotspot(kHS17Wrench, 586, 455, 681, 547, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 5, 7); _vm->setHotspot(kHS17WalkArea1, 0, 0, 800, 434); _vm->setHotspot(kHS17WalkArea2, 541, 0, 800, 600); _vm->setHotspot(kHS17WalkArea3, 0, 204, 173, 468); _vm->setDeviceHotspot(kHS17Device, -1, -1, -1, -1); if (_vm->isFlag(kGFGrassTaken)) _vm->_hotspots[kHS17Wrench]._flags = SF_NONE; if (_vm->isFlag(kGFPlatypusTalkingToAssistant)) { _vm->_hotspots[kHS17Device]._flags = SF_DISABLED; _vm->_hotspots[kHS17Platypus]._flags = SF_DISABLED; } _vm->_hotspotsCount = 10; } void Scene17::update() { _vm->gameUpdateTick(); _vm->updateMouseCursor(); _vm->updateGrabCursorSprite(0, 0); if (_vm->_mouseClickState._left) { _vm->_gnap->walkTo(Common::Point(-1, -1), -1, -1, 1); _vm->_mouseClickState._left = false; } } void Scene17::platHangUpPhone() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; int savedGnapActionStatus = gnap._actionStatus; if (plat._actionStatus == kAS17PlatPhoningAssistant) { gnap._actionStatus = kAS17PlatHangUpPhone; _vm->updateMouseCursor(); _platPhoneCtr = 0; plat._actionStatus = -1; gameSys.setAnimation(0x257, 254, 4); gameSys.insertSequence(0x257, 254, _currPhoneSequenceId, 254, kSeqSyncExists, 0, 0, 0); while (gameSys.getAnimationStatus(4) != 2 && !_vm->_gameDone) _vm->gameUpdateTick(); gameSys.setAnimation(0x25B, plat._id, 1); gameSys.insertSequence(0x25B, plat._id, plat._sequenceId | (plat._sequenceDatNum << 16), plat._id, kSeqSyncWait, 0, 0, 0); plat._sequenceId = 0x25B; plat._sequenceDatNum = 0; _currPhoneSequenceId = -1; _nextPhoneSequenceId = -1; _vm->clearFlag(kGFPlatypusTalkingToAssistant); while (gameSys.getAnimationStatus(1) != 2 && !_vm->_gameDone) _vm->gameUpdateTick(); gnap._actionStatus = savedGnapActionStatus; _vm->updateMouseCursor(); } updateHotspots(); } void Scene17::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; _vm->playSound(0x10940, true); _vm->startSoundTimerA(8); _vm->_sceneWaiting = false; _vm->_timers[4] = _vm->getRandom(100) + 200; _vm->_timers[3] = 200; _vm->_timers[5] = _vm->getRandom(30) + 80; _vm->_timers[6] = _vm->getRandom(30) + 200; _vm->_timers[7] = _vm->getRandom(100) + 100; if (_vm->isFlag(kGFTruckKeysUsed)) { gameSys.insertSequence(0x25F, 20, 0, 0, kSeqNone, 0, 0, 0); } else { if (_vm->_s18GarbageCanPos >= 8) { gameSys.insertSequence(0x260, 20, 0, 0, kSeqNone, 0, 97, 1); } else if (_vm->_s18GarbageCanPos >= 6) { gameSys.insertSequence(0x260, 20, 0, 0, kSeqNone, 0, 68, 2); } else if (_vm->_s18GarbageCanPos >= 5) { gameSys.insertSequence(0x260, 20, 0, 0, kSeqNone, 0, 23, -1); } else if (_vm->_s18GarbageCanPos >= 4) { gameSys.insertSequence(0x260, 20, 0, 0, kSeqNone, 0, -11, -5); } else { gameSys.insertSequence(0x260, 20, 0, 0, kSeqNone, 0, -54, -8); } } if (_vm->isFlag(kGFGroceryStoreHatTaken)) gameSys.insertSequence(0x262, 1, 0, 0, kSeqNone, 0, 0, 0); _vm->queueInsertDeviceIcon(); if (_vm->isFlag(kGFGrassTaken)) _currWrenchSequenceId = 0x22D; else _currWrenchSequenceId = 0x22F; _currCarWindowSequenceId = 0x244; if (_vm->isFlag(kGFUnk14)) gameSys.insertSequence(0x261, 1, 0, 0, kSeqNone, 0, 0, 0); gameSys.setAnimation(_currWrenchSequenceId, 40, 2); gameSys.insertSequence(_currWrenchSequenceId, 40, 0, 0, kSeqNone, 0, 0, 0); if (_vm->isFlag(kGFGrassTaken)) { gameSys.setAnimation(0, 0, 3); } else { gameSys.setAnimation(_currCarWindowSequenceId, 40, 3); gameSys.insertSequence(_currCarWindowSequenceId, 40, 0, 0, kSeqNone, 0, 0, 0); } _canTryGetWrench = true; if (_vm->isFlag(kGFUnk18)) gameSys.insertSequence(0x24F, 100, 0, 0, kSeqNone, 0, 0, 0); if (_vm->_prevSceneNum == 53 || _vm->_prevSceneNum == 18 || _vm->_prevSceneNum == 20 || _vm->_prevSceneNum == 19) { if (_vm->_prevSceneNum == 20) { gnap.initPos(4, 6, kDirBottomRight); plat.initPos(5, 6, kDirIdleLeft); _vm->endSceneInit(); plat.walkTo(Common::Point(5, 9), -1, 0x107C2, 1); gnap.walkTo(Common::Point(4, 8), -1, 0x107B9, 1); } else if (_vm->isFlag(kGFUnk27)) { gnap.initPos(3, 9, kDirUpLeft); plat._pos = _vm->_hotspotsWalkPos[2]; plat._id = 20 * _vm->_hotspotsWalkPos[2].y; gameSys.insertSequence(0x25A, 20 * _vm->_hotspotsWalkPos[2].y, 0, 0, kSeqNone, 0, 0, 0); gameSys.insertSequence(0x257, 254, 0, 0, kSeqNone, 0, 0, 0); plat._sequenceId = 0x25A; plat._sequenceDatNum = 0; _vm->endSceneInit(); _vm->clearFlag(kGFSpringTaken); _vm->clearFlag(kGFUnk16); plat._actionStatus = kAS17PlatPhoningAssistant; platHangUpPhone(); gameSys.setAnimation(0, 0, 4); _vm->clearFlag(kGFPlatypusTalkingToAssistant); _vm->clearFlag(kGFUnk27); updateHotspots(); } else if (_vm->isFlag(kGFUnk25)) { _vm->clearFlag(kGFSpringTaken); _vm->clearFlag(kGFUnk16); plat.initPos(7, 9, kDirIdleLeft); gnap._pos = _vm->_hotspotsWalkPos[2]; gnap._id = 20 * _vm->_hotspotsWalkPos[2].y; gameSys.insertSequence(601, 20 * _vm->_hotspotsWalkPos[2].y, 0, 0, kSeqNone, 0, 0, 0); gnap._sequenceDatNum = 0; gnap._sequenceId = 601; gnap._actionStatus = kAS17GnapHangUpPhone; _vm->clearFlag(kGFUnk25); gameSys.insertSequence(0x251, 254, 0, 0, kSeqNone, 0, 0, 0); _vm->endSceneInit(); gameSys.setAnimation(0x257, 254, 0); gameSys.insertSequence(0x257, 254, 0x251, 254, kSeqSyncWait, 0, 0, 0); } else if (_vm->isFlag(kGFPlatypusTalkingToAssistant)) { _vm->clearFlag(kGFSpringTaken); _vm->clearFlag(kGFUnk16); _vm->_sceneWaiting = true; gnap.initPos(3, 9, kDirUpLeft); plat._pos = _vm->_hotspotsWalkPos[2]; plat._id = 20 * _vm->_hotspotsWalkPos[2].y; _currPhoneSequenceId = 0x251; gameSys.insertSequence(0x25A, 20 * _vm->_hotspotsWalkPos[2].y, 0, 0, kSeqNone, 0, 0, 0); gameSys.insertSequence(_currPhoneSequenceId, 254, 0, 0, kSeqNone, 0, 0, 0); plat._sequenceId = 0x25A; plat._sequenceDatNum = 0; _vm->endSceneInit(); gameSys.setAnimation(_currPhoneSequenceId, 254, 1); plat._actionStatus = kAS17PlatPhoningAssistant; updateHotspots(); } else if (_vm->_prevSceneNum == 18) { gnap.initPos(6, 6, kDirBottomRight); plat.initPos(5, 6, kDirIdleLeft); _vm->endSceneInit(); plat.walkTo(Common::Point(5, 9), -1, 0x107C2, 1); gnap.walkTo(Common::Point(4, 8), -1, 0x107B9, 1); } else { if (_vm->isFlag(kGFSpringTaken)) { gnap.initPos(_vm->_hotspotsWalkPos[2].x, _vm->_hotspotsWalkPos[2].y, kDirBottomRight); plat.initPos(1, 9, kDirIdleLeft); _vm->endSceneInit(); } else { gnap.initPos(3, 7, kDirBottomRight); plat.initPos(1, 7, kDirIdleLeft); _vm->endSceneInit(); } _vm->clearFlag(kGFSpringTaken); _vm->clearFlag(kGFUnk16); _vm->endSceneInit(); } } else { gnap._pos = Common::Point(3, 6); gnap._id = 120; gnap._sequenceId = 0x23D; gnap._sequenceDatNum = 0; gnap._idleFacing = kDirBottomRight; gameSys.insertSequence(makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, 0, 0, kSeqNone, 0, 0, 0); plat._pos = Common::Point(-1, 8); plat._id = 160; gameSys.insertSequence(0x241, 160, 0, 0, kSeqNone, 0, 0, 0); gameSys.insertSequence(0x107C1, plat._id, 0x241, plat._id, kSeqScale | kSeqSyncWait, 0, 75 * plat._pos.x - plat._gridX, 48 * plat._pos.y - plat._gridY); gameSys.insertSequence(0x22C, 2, 0, 0, kSeqNone, 0, 0, 0); _vm->delayTicksA(2, 9); _vm->endSceneInit(); plat._sequenceId = 0x7C1; plat._sequenceDatNum = 1; plat._idleFacing = kDirBottomRight; plat.walkTo(Common::Point(2, 9), -1, 0x107C2, 1); } while (!_vm->_sceneDone) { _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS17Device: if (gnap._actionStatus < 0 || gnap._actionStatus == 3) { _vm->runMenu(); updateHotspots(); } break; case kHS17Platypus: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex == kItemJoint) { if (_vm->isFlag(kGFGrassTaken)) { gnap.useJointOnPlatypus(); } else { gnap.useDeviceOnPlatypus(); plat.walkTo(_vm->_hotspotsWalkPos[6], 1, 0x107C2, 1); gnap.walkTo(_vm->_hotspotsWalkPos[6] + Common::Point(1, 0), 0, 0x107BA, 1); plat._actionStatus = kAS17GetWrench1; gnap._actionStatus = kAS17GetWrench1; _vm->_timers[5] = _vm->getRandom(30) + 80; _vm->setGrabCursorSprite(-1); _vm->invRemove(kItemJoint); } } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playScratchingHead(plat._pos); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: case GRAB_CURSOR: gnap.playScratchingHead(plat._pos); break; case TALK_CURSOR: gnap.playBrainPulsating(plat._pos); plat.playSequence(plat.getSequenceId()); break; case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS17Wrench: if (gnap._actionStatus < 0) { if (_vm->isFlag(kGFGrassTaken)) { gnap.playImpossible(); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 8, 7); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: case GRAB_CURSOR: gnap.playScratchingHead(Common::Point(8, 7)); break; case TALK_CURSOR: gnap.playImpossible(); break; case PLAT_CURSOR: if (_canTryGetWrench) { platHangUpPhone(); gnap.useDeviceOnPlatypus(); plat.walkTo(_vm->_hotspotsWalkPos[6] + Common::Point(1, 0), 1, 0x107C2, 1); plat._actionStatus = kAS17TryGetWrench; gnap._actionStatus = kAS17TryGetWrench; _vm->_timers[5] = _vm->getRandom(30) + 80; } else gnap.playImpossible(); break; } } } break; case kHS17Phone1: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex == kItemDiceQuarterHole) { gnap.walkTo(_vm->_hotspotsWalkPos[2], 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS17PutCoinIntoPhone; } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[2], 1, 3); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(1, 3)); break; case GRAB_CURSOR: if (_vm->isFlag(kGFUnk18)) { platHangUpPhone(); gnap.walkTo(gnap._pos, 0, gnap.getSequenceId(kGSIdle, _vm->_hotspotsWalkPos[2]) | 0x10000, 1); gnap._actionStatus = kAS17GetCoinFromPhone; } else gnap.playImpossible(); break; case TALK_CURSOR: gnap.playImpossible(); break; case PLAT_CURSOR: if (_vm->isFlag(kGFUnk18)) { platHangUpPhone(); _vm->_isLeavingScene = true; gnap.useDeviceOnPlatypus(); plat._idleFacing = kDirUpLeft; plat.walkTo(_vm->_hotspotsWalkPos[2], 1, 0x107C2, 1); _vm->setFlag(kGFUnk16); plat._actionStatus = kAS17PlatUsePhone; gnap._actionStatus = kAS17PlatUsePhone; } else gnap.playImpossible(); break; } } } break; case kHS17Phone2: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex == kItemDiceQuarterHole) { gnap.walkTo(_vm->_hotspotsWalkPos[2], 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS17PutCoinIntoPhone; } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[2], 1, 3); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(1, 3)); break; case GRAB_CURSOR: if (_vm->isFlag(kGFUnk18)) { platHangUpPhone(); _vm->_isLeavingScene = true; gnap._idleFacing = kDirUpLeft; gnap.walkTo(_vm->_hotspotsWalkPos[2], 0, gnap.getSequenceId(kGSIdle, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS17GnapUsePhone; _vm->setFlag(kGFSpringTaken); } else gnap.playImpossible(); break; case TALK_CURSOR: gnap.playImpossible(); break; case PLAT_CURSOR: if (_vm->isFlag(kGFUnk18)) { platHangUpPhone(); _vm->_isLeavingScene = true; gnap.useDeviceOnPlatypus(); plat._idleFacing = kDirUpLeft; plat.walkTo(_vm->_hotspotsWalkPos[2], 1, 0x107C2, 1); _vm->setFlag(kGFUnk16); plat._actionStatus = kAS17PlatUsePhone; gnap._actionStatus = kAS17PlatUsePhone; } else gnap.playImpossible(); break; } } } break; case kHS17ExitToyStore: if (gnap._actionStatus < 0) { _vm->_isLeavingScene = true; _vm->_newSceneNum = 18; gnap._idleFacing = kDirUpRight; gnap.walkTo(_vm->_hotspotsWalkPos[5], 0, 0x107BB, 1); gnap._actionStatus = kAS17LeaveScene; if (plat._actionStatus != kAS17PlatPhoningAssistant) plat.walkTo(_vm->_hotspotsWalkPos[5] + Common::Point(-1, 0), -1, 0x107C2, 1); } break; case kHS17ExitGrubCity: if (gnap._actionStatus < 0) { platHangUpPhone(); _vm->_isLeavingScene = true; _vm->_newSceneNum = 20; gnap._idleFacing = kDirUpLeft; gnap.walkTo(_vm->_hotspotsWalkPos[3], 0, 0x107BC, 1); gnap._actionStatus = kAS17LeaveScene; plat.walkTo(_vm->_hotspotsWalkPos[3] + Common::Point(1, 0), -1, 0x107C2, 1); } break; case kHS17WalkArea1: case kHS17WalkArea2: case kHS17WalkArea3: 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 = 0; } break; } updateAnimations(); if (!_vm->isSoundPlaying(0x10940)) _vm->playSound(0x10940, true); if (!_vm->_isLeavingScene) { if (plat._actionStatus < 0) plat.updateIdleSequence2(); gnap.updateIdleSequence2(); if (!_vm->_timers[4]) { _vm->_timers[4] = _vm->getRandom(100) + 200; if (gnap._actionStatus < 0 && plat._actionStatus < 0) gameSys.insertSequence(0x22B, 21, 0, 0, kSeqNone, 0, 0, 0); } if (!_vm->_timers[7]) { _vm->_timers[7] = _vm->getRandom(100) + 100; if (gnap._actionStatus < 0 && plat._actionStatus < 0) { switch (_vm->getRandom(3)) { case 0: gameSys.insertSequence(0x25C, 255, 0, 0, kSeqNone, 0, 0, 0); break; case 1: gameSys.insertSequence(0x25D, 255, 0, 0, kSeqNone, 0, 0, 0); break; case 2: gameSys.insertSequence(0x25E, 255, 0, 0, kSeqNone, 0, 0, 0); break; } } } if (plat._actionStatus < 0 && !_vm->_timers[5]) { _vm->_timers[5] = _vm->getRandom(30) + 80; if (_vm->isFlag(kGFGrassTaken) && _nextWrenchSequenceId == -1) { _nextWrenchSequenceId = 0x236; } else if (_canTryGetWrench) { switch (_vm->getRandom(6)) { case 0: _nextWrenchSequenceId = 0x231; break; case 1: _nextWrenchSequenceId = 0x232; break; case 2: case 3: _nextWrenchSequenceId = 0x23C; break; case 4: case 5: _nextWrenchSequenceId = 0x22E; break; } } else { --_wrenchCtr; if (_wrenchCtr) { switch (_vm->getRandom(6)) { case 0: _nextWrenchSequenceId = 0x237; break; case 1: _nextWrenchSequenceId = 0x238; break; case 2: _nextWrenchSequenceId = 0x239; break; case 3: _nextWrenchSequenceId = 0x23A; break; case 4: _nextWrenchSequenceId = 0x23B; break; case 5: _nextWrenchSequenceId = 0x235; break; } } else { _wrenchCtr = 2; _nextWrenchSequenceId = 0x235; } } } if (!_vm->_timers[6]) { _vm->_timers[6] = _vm->getRandom(30) + 200; if (_nextCarWindowSequenceId == -1 && !_vm->isFlag(kGFGrassTaken)) _nextCarWindowSequenceId = 0x246; } _vm->playSoundA(); } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); } _vm->gameUpdateTick(); } } void Scene17::updateAnimations() { static const int kPlatPhoneSequenceIds[] = { 0x251, 0x252, 0x253, 0x254, 0x255, 0x256, 0x257 }; 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 kAS17GetWrench1: gnap._actionStatus = kAS17GetWrenchGnapReady; break; case kAS17GetCoinFromPhone: gnap.playPullOutDevice(Common::Point(1, 3)); gnap.playUseDevice(); gameSys.setAnimation(0x250, 100, 0); gameSys.insertSequence(0x250, 100, 591, 100, kSeqSyncWait, 0, 0, 0); _vm->invAdd(kItemDiceQuarterHole); _vm->clearFlag(kGFUnk18); gnap._actionStatus = kAS17GetCoinFromPhoneDone; break; case kAS17GetCoinFromPhoneDone: _vm->setGrabCursorSprite(kItemDiceQuarterHole); gnap._actionStatus = -1; break; case kAS17PutCoinIntoPhone: gameSys.setAnimation(0x24C, gnap._id, 0); gameSys.insertSequence(0x24C, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x24C; _vm->invRemove(kItemDiceQuarterHole); _vm->setGrabCursorSprite(-1); _vm->setFlag(kGFUnk18); gnap._actionStatus = kAS17PutCoinIntoPhoneDone; break; case kAS17PutCoinIntoPhoneDone: gameSys.insertSequence(0x24F, 100, 0, 0, kSeqNone, 0, 0, 0); gnap._actionStatus = -1; break; case kAS17GnapUsePhone: gameSys.setAnimation(0x24D, gnap._id, 0); gameSys.insertSequence(0x24D, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._actionStatus = kAS17LeaveScene; _vm->_newSceneNum = 53; break; case kAS17GnapHangUpPhone: gameSys.insertSequence(0x258, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x258; gnap._actionStatus = -1; break; case kAS17LeaveScene: _vm->_sceneDone = true; break; } } if (gameSys.getAnimationStatus(1) == 2) { gameSys.setAnimation(0, 0, 1); switch (plat._actionStatus) { case kAS17TryGetWrench: plat._actionStatus = -1; ++_platTryGetWrenchCtr; if (_platTryGetWrenchCtr % 2 != 0) _nextWrenchSequenceId = 0x233; else _nextWrenchSequenceId = 0x234; _canTryGetWrench = false; break; case kAS17GetWrench1: _nextWrenchSequenceId = 0x230; break; case kAS17GetWrench2: _nextCarWindowSequenceId = 0x249; break; case kAS17GetWrenchDone: plat._actionStatus = -1; _vm->invAdd(kItemWrench); _vm->setGrabCursorSprite(kItemWrench); break; case kAS17PlatUsePhone: gameSys.setAnimation(0x24E, plat._id, 1); gameSys.insertSequence(0x24E, plat._id, plat._sequenceId | (plat._sequenceDatNum << 16), plat._id, kSeqSyncWait, 0, 0, 0); plat._sequenceDatNum = 0; plat._sequenceId = 0x24E; plat._actionStatus = kAS17LeaveScene; _vm->_newSceneNum = 53; break; case kAS17PlatPhoningAssistant: ++_platPhoneCtr; if (_platPhoneCtr >= 7) { _platPhoneCtr = 0; _nextPhoneSequenceId = -1; _currPhoneSequenceId = -1; gameSys.insertSequence(0x25B, plat._id, 0x25A, plat._id, kSeqSyncWait, 0, 0, 0); plat._sequenceDatNum = 0; plat._sequenceId = 0x25B; plat._actionStatus = -1; _vm->clearFlag(kGFPlatypusTalkingToAssistant); _vm->_sceneWaiting = false; updateHotspots(); } else { _nextPhoneSequenceId = kPlatPhoneSequenceIds[_platPhoneCtr]; gameSys.setAnimation(_nextPhoneSequenceId, 254, 1); gameSys.insertSequence(_nextPhoneSequenceId, 254, _currPhoneSequenceId, 254, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x25A, plat._id, 0x25A, plat._id, kSeqSyncWait, 0, 0, 0); plat._sequenceDatNum = 0; plat._sequenceId = 0x25A; _currPhoneSequenceId = _nextPhoneSequenceId; } break; case kAS17LeaveScene: _vm->_sceneDone = true; break; } } if (gameSys.getAnimationStatus(2) == 2) { switch (_nextWrenchSequenceId) { case 0x233: gnap._actionStatus = -1; gameSys.insertSequence(0x243, plat._id, plat._sequenceId | (plat._sequenceDatNum << 16), plat._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(_nextWrenchSequenceId, 40, _currWrenchSequenceId, 40, kSeqSyncWait, 0, 0, 0); _currWrenchSequenceId = _nextWrenchSequenceId; _nextWrenchSequenceId = -1; plat._sequenceId = 0x243; plat._sequenceDatNum = 0; gameSys.setAnimation(0x243, plat._id, 1); break; case 0x234: gnap._actionStatus = -1; gameSys.insertSequence(0x242, plat._id, plat._sequenceId | (plat._sequenceDatNum << 16), plat._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(_nextWrenchSequenceId, 40, _currWrenchSequenceId, 40, kSeqSyncWait, 0, 0, 0); _currWrenchSequenceId = _nextWrenchSequenceId; _nextWrenchSequenceId = -1; plat._sequenceId = 0x242; plat._sequenceDatNum = 0; gameSys.setAnimation(0x242, plat._id, 1); break; case 0x231: if (_vm->getRandom(2) != 0) _nextCarWindowSequenceId = 0x245; else _nextCarWindowSequenceId = 0x248; gameSys.setAnimation(0, 0, 2); break; case 0x232: _nextCarWindowSequenceId = 0x247; gameSys.setAnimation(0, 0, 2); break; case 0x22E: case 0x235: if (_nextWrenchSequenceId == 0x235) _vm->_hotspots[kHS17Wrench]._flags &= ~SF_DISABLED; else _vm->_hotspots[kHS17Wrench]._flags |= SF_DISABLED; _canTryGetWrench = !_canTryGetWrench; gameSys.setAnimation(_nextWrenchSequenceId, 40, 2); gameSys.insertSequence(_nextWrenchSequenceId, 40, _currWrenchSequenceId, 40, kSeqSyncWait, 0, 0, 0); _currWrenchSequenceId = _nextWrenchSequenceId; _nextWrenchSequenceId = -1; break; case 0x230: if (gnap._actionStatus == kAS17GetWrenchGnapReady) { gameSys.setAnimation(0, 0, 2); if (_canTryGetWrench) { gameSys.insertSequence(0x22E, 40, _currWrenchSequenceId, 40, kSeqSyncWait, 0, 0, 0); _currWrenchSequenceId = 0x22E; _canTryGetWrench = false; } gameSys.setAnimation(0x23F, plat._id, 1); gameSys.insertSequence(0x10875, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x23F, plat._id, plat._sequenceId | (plat._sequenceDatNum << 16), plat._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceDatNum = 1; plat._sequenceDatNum = 0; gnap._sequenceId = 0x875; plat._sequenceId = 0x23F; gnap.walkTo(Common::Point(3, 8), -1, 0x107B9, 1); plat._actionStatus = kAS17GetWrench2; } break; default: if (_nextWrenchSequenceId != -1) { gameSys.setAnimation(_nextWrenchSequenceId, 40, 2); gameSys.insertSequence(_nextWrenchSequenceId, 40, _currWrenchSequenceId, 40, kSeqSyncWait, 0, 0, 0); _currWrenchSequenceId = _nextWrenchSequenceId; _nextWrenchSequenceId = -1; } break; } } if (gameSys.getAnimationStatus(3) == 2) { switch (_nextCarWindowSequenceId) { case 0x246: gameSys.setAnimation(_nextCarWindowSequenceId, 40, 3); gameSys.insertSequence(_nextCarWindowSequenceId, 40, _currCarWindowSequenceId, 40, kSeqSyncWait, 0, 0, 0); _currCarWindowSequenceId = _nextCarWindowSequenceId; _nextCarWindowSequenceId = -1; break; case 0x245: case 0x247: case 0x248: gameSys.setAnimation(_nextWrenchSequenceId, 40, 2); gameSys.insertSequence(_nextWrenchSequenceId, 40, _currWrenchSequenceId, 40, kSeqSyncWait, 0, 0, 0); while (gameSys.getAnimationStatus(2) != 2) update(); gameSys.setAnimation(_nextCarWindowSequenceId, 40, 3); gameSys.insertSequence(_nextCarWindowSequenceId, 40, _currCarWindowSequenceId, 40, kSeqSyncWait, 0, 0, 0); _currCarWindowSequenceId = _nextCarWindowSequenceId; _nextCarWindowSequenceId = -1; _currWrenchSequenceId = _nextWrenchSequenceId; _nextWrenchSequenceId = -1; break; case 0x249: gameSys.setAnimation(0x230, 40, 2); gameSys.setAnimation(0x240, plat._id, 1); gameSys.insertSequence(0x230, 40, _currWrenchSequenceId, 40, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(_nextCarWindowSequenceId, 40, _currCarWindowSequenceId, 40, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x240, plat._id, plat._sequenceId, plat._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x23E, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceId = 0x23E; gnap._sequenceDatNum = 0; plat._sequenceId = 0x240; plat._sequenceDatNum = 0; gameSys.setAnimation(0x24A, 40, 3); gameSys.insertSequence(0x24A, 40, _nextCarWindowSequenceId, 40, kSeqSyncWait, 0, 0, 0); while (gameSys.getAnimationStatus(2) != 2) { update(); if (gameSys.getAnimationStatus(3) == 2) { gameSys.setAnimation(0x24A, 40, 3); gameSys.insertSequence(0x24A, 40, 586, 40, kSeqSyncWait, 0, 0, 0); } } gameSys.insertSequence(0x22D, 40, 560, 40, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(0x24B, 40, 3); gameSys.insertSequence(0x24B, 40, 586, 40, kSeqSyncWait, 0, 0, 0); _currCarWindowSequenceId = 0x24B; _nextCarWindowSequenceId = -1; _currWrenchSequenceId = 0x22D; _nextWrenchSequenceId = -1; _vm->setFlag(kGFGrassTaken); gnap._actionStatus = -1; plat._actionStatus = 2; updateHotspots(); _vm->_timers[5] = _vm->getRandom(30) + 80; break; } } } /*****************************************************************************/ static const int kScene18SequenceIds[] = { 0x219, 0x21A, 0x21B, 0x21C, 0x21D }; Scene18::Scene18(GnapEngine *vm) : Scene(vm) { _cowboyHatSurface = nullptr; _platPhoneCtr = 0; _platPhoneIter = 0; _nextPhoneSequenceId = -1; _currPhoneSequenceId = -1; } Scene18::~Scene18() { delete _cowboyHatSurface; } int Scene18::init() { _vm->_gameSys->setAnimation(0, 0, 3); return 0x222; } void Scene18::updateHotspots() { _vm->setHotspot(kHS18Platypus, 0, 0, 0, 0, SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS18GarbageCan, _vm->_gridMinX + 75 * _vm->_s18GarbageCanPos - 35, _vm->_gridMinY + 230, _vm->_gridMinX + 75 * _vm->_s18GarbageCanPos + 35, _vm->_gridMinY + 318, SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, _vm->_s18GarbageCanPos, 7); _vm->setHotspot(kHS18ExitToyStore, 460, 238, 592, 442, SF_EXIT_U_CURSOR, 7, 7); _vm->setHotspot(kHS18ExitPhoneBooth, 275, 585, 525, 600, SF_EXIT_D_CURSOR | SF_WALKABLE, 5, 10); _vm->setHotspot(kHS18ExitGrubCity, 0, 350, 15, 600, SF_EXIT_L_CURSOR, 0, 9); _vm->setHotspot(kHS18HydrantTopValve, 100, 345, 182, 410, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 1, 8); _vm->setHotspot(kHS18HydrantRightValve, 168, 423, 224, 470, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 3, 7); _vm->setHotspot(kHS18CowboyHat, 184, 63, 289, 171, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 4, 7); _vm->setHotspot(kHS18WalkArea1, 0, 0, 800, 448); _vm->setHotspot(kHS18WalkArea2, 0, 0, 214, 515); _vm->setDeviceHotspot(kHS18Device, -1, -1, -1, -1); if (_vm->isFlag(kGFTruckFilledWithGas)) { if (_vm->isFlag(kGFTruckKeysUsed)) { _vm->_hotspots[kHS18HydrantTopValve]._flags = SF_DISABLED; _vm->_hotspots[kHS18HydrantRightValve]._rect.left = 148; _vm->_hotspots[kHS18HydrantRightValve]._rect.top = 403; _vm->_hotspots[kHS18GarbageCan]._flags = SF_DISABLED; _vm->_hotspotsWalkPos[kHS18GarbageCan] = Common::Point(3, 7); } else { _vm->_hotspots[kHS18HydrantTopValve]._rect.top = 246; } } else if (_vm->isFlag(kGFBarnPadlockOpen)) { _vm->_hotspots[kHS18HydrantRightValve]._flags = SF_DISABLED; _vm->_hotspots[kHS18HydrantTopValve]._rect.left = 105; _vm->_hotspots[kHS18HydrantTopValve]._rect.right = 192; } else if (_vm->isFlag(kGFTruckKeysUsed)) { _vm->_hotspots[kHS18GarbageCan]._rect = Common::Rect(115, 365, 168, 470); _vm->_hotspots[kHS18GarbageCan]._flags = SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR; _vm->_hotspotsWalkPos[kHS18GarbageCan] = Common::Point(3, 7); } if (_vm->isFlag(kGFPlatypusDisguised)) _vm->_hotspots[kHS18GarbageCan]._flags = SF_DISABLED; if (_vm->isFlag(kGFPlatypusTalkingToAssistant)) { _vm->_hotspots[kHS18Device]._flags = SF_DISABLED; _vm->_hotspots[kHS18HydrantTopValve]._flags = SF_DISABLED; _vm->_hotspots[kHS18HydrantRightValve]._flags = SF_DISABLED; _vm->_hotspots[kHS18Platypus]._flags = SF_DISABLED; } if (_vm->isFlag(kGFUnk14)) { _vm->_hotspots[kHS18HydrantTopValve]._flags = SF_DISABLED; _vm->_hotspots[kHS18CowboyHat]._flags = SF_DISABLED; } _vm->_hotspotsCount = 11; } void Scene18::gnapCarryGarbageCanTo(int gridX) { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; int gnapSeqId, gnapId, gnapDatNum, gnapGridX; int destGridX, direction; int curGridX = (_vm->_leftClickMouseX - _vm->_gridMinX + 37) / 75; if (curGridX >= gnap._pos.x) destGridX = curGridX - 1; else destGridX = curGridX + 1; if (gridX < 0) gridX = 4; if (destGridX <= gridX) destGridX = gridX; int nextGridX = _vm->_gridMaxX - 1; if (nextGridX >= destGridX) nextGridX = destGridX; if (nextGridX == gnap._pos.x) { gnapSeqId = gnap._sequenceId; gnapId = gnap._id; gnapDatNum = gnap._sequenceDatNum; gnapGridX = gnap._pos.x; if (gnap._pos.x <= curGridX) direction = 1; else direction = -1; } else { PlayerPlat& plat = *_vm->_plat; if (gnap._pos.y == plat._pos.y) { if (nextGridX >= gnap._pos.x) { if (nextGridX >= plat._pos.x && gnap._pos.x <= plat._pos.x) plat.makeRoom(); } else if (nextGridX <= plat._pos.x && gnap._pos.x >= plat._pos.x) { plat.makeRoom(); } } gnapSeqId = gnap._sequenceId; gnapId = gnap._id; gnapDatNum = gnap._sequenceDatNum; gnapGridX = gnap._pos.x; int seqId; if (nextGridX < gnap._pos.x) { direction = -1; seqId = 0x204; } else { direction = 1; seqId = 0x203; } int seqId2 = 20 * gnap._pos.y + 1; do { if (_vm->isPointBlocked(gnapGridX + direction, gnap._pos.y)) break; seqId2 += direction; gameSys.insertSequence(seqId, seqId2, gnapSeqId | (gnapDatNum << 16), gnapId, kSeqSyncWait, 0, 75 * gnapGridX - gnap._gridX, 48 * gnap._pos.y - gnap._gridY); gnapSeqId = seqId; gnapId = seqId2; gnapDatNum = 0; gnapGridX += direction; } while (nextGridX != gnapGridX); } if (direction == 1) gnap._sequenceId = 0x20A; else gnap._sequenceId = 0x209; gnap._sequenceDatNum = 0; if (direction == 1) gnap._idleFacing = kDirBottomRight; else gnap._idleFacing = kDirBottomLeft; gnap._id = 20 * gnap._pos.y + 1; gameSys.setAnimation(makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, 0); gameSys.insertSequence(makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, gnapSeqId | (gnapDatNum << 16), gnapId, kSeqScale | kSeqSyncWait, 0, 75 * gnapGridX - gnap._gridX, 48 * gnap._pos.y - gnap._gridY); gnap._pos.x = gnapGridX; } void Scene18::putDownGarbageCan(int animationIndex) { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; if (animationIndex >= 0) { while (gameSys.getAnimationStatus(animationIndex) != 2 && !_vm->_gameDone) _vm->gameUpdateTick(); } if (gnap._idleFacing != kDirIdleLeft && gnap._idleFacing != kDirBottomRight && gnap._idleFacing != kDirUpRight) _vm->_s18GarbageCanPos = gnap._pos.x - 1; else _vm->_s18GarbageCanPos = gnap._pos.x + 1; _vm->clearFlag(kGFPlatypusDisguised); updateHotspots(); if (gnap._idleFacing != kDirIdleLeft && gnap._idleFacing != kDirBottomRight && gnap._idleFacing != kDirUpRight) { gameSys.insertSequence(0x107BA, 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 = 0x7BA; } else { gameSys.insertSequence(0x107B9, 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 = 0x7B9; } gnap._sequenceDatNum = 1; gameSys.insertSequence(0x1FB, 19, 0, 0, kSeqNone, 0, 15 * (5 * _vm->_s18GarbageCanPos - 40), 0); gameSys.setAnimation(0x1FA, 19, 4); gameSys.insertSequence(0x1FA, 19, 507, 19, kSeqSyncWait, 0, 15 * (5 * _vm->_s18GarbageCanPos - 40), 0); while (gameSys.getAnimationStatus(4) != 2 && !_vm->_gameDone) _vm->gameUpdateTick(); } void Scene18::platEndPhoning(bool platFl) { GameSys& gameSys = *_vm->_gameSys; PlayerPlat& plat = *_vm->_plat; if (_vm->isFlag(kGFPlatypusTalkingToAssistant)) { _platPhoneIter = 0; _platPhoneCtr = 0; plat._actionStatus = -1; if (_currPhoneSequenceId != -1) { gameSys.setAnimation(0x21E, 254, 3); gameSys.insertSequence(0x21E, 254, _currPhoneSequenceId, 254, kSeqSyncExists, 0, 0, 0); while (gameSys.getAnimationStatus(3) != 2 && !_vm->_gameDone) _vm->gameUpdateTick(); } gameSys.removeSequence(0x21F, 254, true); gameSys.setAnimation(0, 0, 3); _vm->clearFlag(kGFPlatypusTalkingToAssistant); if (platFl) { plat._actionStatus = kAS18PlatComesHere; _vm->_timers[6] = 50; _vm->_sceneWaiting = true; } _currPhoneSequenceId = -1; _nextPhoneSequenceId = -1; updateHotspots(); } } void Scene18::closeHydrantValve() { PlayerGnap& gnap = *_vm->_gnap; gnap._actionStatus = kAS18LeaveScene; _vm->updateMouseCursor(); if (_vm->isFlag(kGFTruckFilledWithGas)) { gnap.walkTo(_vm->_hotspotsWalkPos[kHS18HydrantRightValve], 0, 0x107BA, 1); if (_vm->isFlag(kGFTruckKeysUsed)) { gnap._actionStatus = kAS18CloseRightValveWithGarbageCan; waitForGnapAction(); } else { gnap._actionStatus = kAS18CloseRightValveNoGarbageCan; waitForGnapAction(); } } else if (_vm->isFlag(kGFBarnPadlockOpen)) { gnap.walkTo(_vm->_hotspotsWalkPos[kHS18HydrantTopValve], 0, 0x107BA, 1); gnap._actionStatus = kAS18CloseTopValve; waitForGnapAction(); } } void Scene18::waitForGnapAction() { PlayerGnap& gnap = *_vm->_gnap; while (gnap._actionStatus >= 0 && !_vm->_gameDone) { updateAnimations(); _vm->gameUpdateTick(); } } void Scene18::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; _cowboyHatSurface = nullptr; _vm->playSound(0x10940, true); _vm->startSoundTimerA(4); _vm->_timers[5] = _vm->getRandom(100) + 100; _vm->queueInsertDeviceIcon(); _vm->clearFlag(kGFPlatypusDisguised); if (!_vm->isFlag(kGFUnk14)) gameSys.insertSequence(0x1F8, 19, 0, 0, kSeqNone, 0, 0, 0); if (_vm->isFlag(kGFTruckKeysUsed)) { if (_vm->isFlag(kGFTruckFilledWithGas)) { gameSys.insertSequence(0x214, 39, 0, 0, kSeqLoop, 0, 0, 0); gameSys.insertSequence(0x20D, 39, 0, 0, kSeqLoop, 0, 0, 0); _vm->playSound(0x22B, true); } else { gameSys.insertSequence(0x1F9, 19, 0, 0, kSeqNone, 0, 0, 0); } } else { gameSys.insertSequence(0x1FA, 19, 0, 0, kSeqNone, 0, 15 * (5 * _vm->_s18GarbageCanPos - 40), 0); if (_vm->isFlag(kGFTruckFilledWithGas)) { gameSys.insertSequence(0x212, 39, 0, 0, kSeqLoop, 0, 0, 0); gameSys.insertSequence(0x20D, 39, 0, 0, kSeqLoop, 0, 0, 0); _vm->playSound(0x22B, true); } else if (_vm->isFlag(kGFBarnPadlockOpen)) { gameSys.insertSequence(0x20E, 39, 0, 0, kSeqLoop, 0, 0, 0); gameSys.insertSequence(0x217, 39, 0, 0, kSeqLoop, 0, 0, 0); _vm->playSound(0x22B, true); } } if (_vm->isFlag(kGFPlatypusTalkingToAssistant)) { if (_vm->_prevSceneNum == 17) gnap.initPos(4, 11, kDirBottomRight); else gnap.initPos(4, 7, kDirBottomRight); _platPhoneCtr = _vm->getRandom(5); if (_vm->isFlag(kGFUnk27)) { gameSys.insertSequence(0x21E, 254, 0, 0, kSeqNone, 0, 0, 0); _vm->endSceneInit(); _currPhoneSequenceId = -1; platEndPhoning(true); _vm->clearFlag(kGFUnk27); } else { _currPhoneSequenceId = kScene18SequenceIds[_platPhoneCtr]; _platPhoneIter = 0; gameSys.insertSequence(0x21F, 254, 0, 0, kSeqNone, 0, 0, 0); gameSys.insertSequence(_currPhoneSequenceId, 254, 0, 0, kSeqNone, 0, 0, 0); _vm->endSceneInit(); } if (_vm->isFlag(kGFUnk27)) { platEndPhoning(true); _vm->clearFlag(kGFUnk27); } else { gameSys.setAnimation(_currPhoneSequenceId, 254, 3); } gnap.walkTo(Common::Point(4, 8), -1, 0x107B9, 1); } else { if (_vm->isFlag(kGFGnapControlsToyUFO)) { _vm->clearFlag(kGFGnapControlsToyUFO); _vm->setGrabCursorSprite(kItemCowboyHat); _vm->_prevSceneNum = 19; } if (_vm->_prevSceneNum == 17) { gnap.initPos(4, 11, kDirBottomRight); plat.initPos(5, 11, kDirIdleLeft); _vm->endSceneInit(); gnap.walkTo(Common::Point(4, 8), -1, 0x107B9, 1); plat.walkTo(Common::Point(5, 9), -1, 0x107C2, 1); } else if (_vm->_prevSceneNum == 19) { gnap.initPos(7, 7, kDirBottomRight); plat.initPos(8, 7, kDirIdleLeft); _vm->endSceneInit(); gnap.walkTo(Common::Point(7, 8), -1, 0x107B9, 1); plat.walkTo(Common::Point(8, 8), -1, 0x107C2, 1); } else { gnap.initPos(-1, 10, kDirBottomRight); plat.initPos(-1, 10, kDirIdleLeft); _vm->endSceneInit(); gnap.walkTo(Common::Point(3, 7), -1, 0x107B9, 1); plat.walkTo(Common::Point(3, 8), -1, 0x107C2, 1); } } while (!_vm->_sceneDone) { _vm->updateMouseCursor(); _vm->updateCursorByHotspot(); _vm->testWalk(0, 20, -1, -1, -1, -1); _vm->_sceneClickedHotspot = _vm->getClickedHotspotId(); _vm->updateGrabCursorSprite(0, 0); switch (_vm->_sceneClickedHotspot) { case kHS18Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); } break; case kHS18Platypus: if (gnap._actionStatus < 0) { if (_vm->isFlag(kGFPlatypusDisguised)) { gnapCarryGarbageCanTo(-1); putDownGarbageCan(0); } if (_vm->_grabCursorSpriteIndex == kItemJoint) { gnap.useJointOnPlatypus(); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowItem(_vm->_grabCursorSpriteIndex, plat._pos.x, plat._pos.y); } else { 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: gnap.playImpossible(); break; } } } break; case kHS18CowboyHat: if (gnap._actionStatus == kAS18StandingOnHydrant) { gnap._actionStatus = kAS18GrabCowboyHat; _vm->_sceneWaiting = false; } else if (gnap._actionStatus < 0) { if (_vm->isFlag(kGFPlatypusDisguised)) { gnapCarryGarbageCanTo(-1); putDownGarbageCan(0); } if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[kHS18CowboyHat], 3, 2); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(3, 2)); break; case GRAB_CURSOR: gnap.walkTo(_vm->_hotspotsWalkPos[kHS18CowboyHat], 0, gnap.getSequenceId(kGSPullOutDeviceNonWorking, Common::Point(3, 2)) | 0x10000, 1); break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS18GarbageCan: if (gnap._actionStatus < 0) { if (_vm->isFlag(kGFUnk14)) { if (_vm->_grabCursorSpriteIndex >= 0) gnap.playShowCurrItem(_vm->_hotspotsWalkPos[kHS18GarbageCan], 1, 5); else gnap.playImpossible(); } else { if (_vm->isFlag(kGFPlatypusTalkingToAssistant)) platEndPhoning(true); if (_vm->_grabCursorSpriteIndex >= 0) { if (!_vm->isFlag(kGFTruckKeysUsed)) { Common::Point destPos; destPos.x = _vm->_hotspotsWalkPos[kHS18GarbageCan].x - (gnap._pos.x < _vm->_s18GarbageCanPos ? 1 : -1); destPos.y = _vm->_hotspotsWalkPos[kHS18GarbageCan].y; gnap.playShowCurrItem(destPos, _vm->_hotspotsWalkPos[kHS18GarbageCan].x, _vm->_hotspotsWalkPos[kHS18GarbageCan].y); } else gnap.playShowCurrItem(_vm->_hotspotsWalkPos[kHS18GarbageCan], 2, 4); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: if (!_vm->isFlag(kGFTruckKeysUsed)) gnap.playScratchingHead(Common::Point(_vm->_hotspotsWalkPos[kHS18GarbageCan].x - (gnap._pos.x < _vm->_s18GarbageCanPos ? 1 : -1), _vm->_hotspotsWalkPos[kHS18GarbageCan].y)); else if (!_vm->isFlag(kGFTruckFilledWithGas)) gnap.playScratchingHead(Common::Point(2, 4)); break; case GRAB_CURSOR: if (!_vm->isFlag(kGFTruckKeysUsed)) { gnap.walkTo(_vm->_hotspotsWalkPos[kHS18GarbageCan] + Common::Point((gnap._pos.x < _vm->_s18GarbageCanPos ? 1 : -1), 0), -1, -1, 1); gnap.walkTo(gnap._pos, 0, gnap.getSequenceId(kGSIdle, Common::Point(_vm->_s18GarbageCanPos, gnap._pos.y)) | 0x10000, 1); gnap._actionStatus = kAS18GrabGarbageCanFromStreet; } else if (!_vm->isFlag(kGFTruckFilledWithGas)) { if (gnap.walkTo(_vm->_hotspotsWalkPos[kHS18GarbageCan], 0, -1, 1)) gnap._actionStatus = kAS18GrabGarbageCanFromHydrant; } break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } } break; case kHS18HydrantTopValve: if (gnap._actionStatus < 0) { if (_vm->isFlag(kGFPlatypusDisguised)) { // While carrying garbage can if (_vm->_grabCursorSpriteIndex >= 0) { gnapCarryGarbageCanTo(-1); putDownGarbageCan(0); gnap.playShowItem(_vm->_grabCursorSpriteIndex, 0, 0); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnapCarryGarbageCanTo(-1); putDownGarbageCan(0); gnap.playScratchingHead(); break; case GRAB_CURSOR: if (_vm->isFlag(kGFTruckFilledWithGas)) { gnapCarryGarbageCanTo(2); gnap._actionStatus = kAS18PutGarbageCanOnRunningHydrant; } else if (!_vm->isFlag(kGFBarnPadlockOpen)) { gnapCarryGarbageCanTo(2); gnap._actionStatus = kAS18PutGarbageCanOnHydrant; } else { gnapCarryGarbageCanTo(-1); putDownGarbageCan(0); gnap.playImpossible(); } break; case TALK_CURSOR: case PLAT_CURSOR: gnapCarryGarbageCanTo(-1); putDownGarbageCan(0); gnap.playImpossible(); break; } } } else { if (_vm->_grabCursorSpriteIndex == kItemWrench) { gnap.walkTo(gnap._pos, 0, gnap.getSequenceId(kGSIdle, Common::Point(2, 8)) | 0x10000, 1); gnap._actionStatus = kAS18OpenTopValve; } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[kHS18HydrantTopValve], 1, 5); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(1, 5)); break; case GRAB_CURSOR: if (_vm->isFlag(kGFBarnPadlockOpen)) { _vm->_hotspots[kHS18WalkArea2]._flags |= SF_WALKABLE; gnap.walkTo(_vm->_hotspotsWalkPos[kHS18HydrantTopValve], 0, 0x107BA, 1); _vm->_hotspots[kHS18WalkArea2]._flags &= ~SF_WALKABLE; gnap._actionStatus = kAS18CloseTopValve; } else gnap.playImpossible(); break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } } break; case kHS18HydrantRightValve: if (gnap._actionStatus < 0) { if (_vm->isFlag(kGFUnk14)) { if (_vm->_grabCursorSpriteIndex == -1) { gnap.playImpossible(); } else { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[kHS18HydrantRightValve], 1, 5); } } else { if (_vm->isFlag(kGFPlatypusDisguised)) { gnapCarryGarbageCanTo(-1); putDownGarbageCan(0); } if (_vm->_grabCursorSpriteIndex == kItemWrench) { gnap.walkTo(gnap._pos, 0, gnap.getSequenceId(kGSIdle, Common::Point(2, 8)) | 0x10000, 1); if (_vm->isFlag(kGFTruckKeysUsed)) gnap._actionStatus = kAS18OpenRightValveWithGarbageCan; else gnap._actionStatus = kAS18OpenRightValveNoGarbageCan; } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[kHS18HydrantRightValve], 1, 5); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(1, 5)); break; case GRAB_CURSOR: if (_vm->isFlag(kGFTruckFilledWithGas)) { gnap.walkTo(_vm->_hotspotsWalkPos[kHS18HydrantRightValve], 0, 0x107BA, 1); if (_vm->isFlag(kGFTruckKeysUsed)) gnap._actionStatus = kAS18CloseRightValveWithGarbageCan; else gnap._actionStatus = kAS18CloseRightValveNoGarbageCan; } break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } } break; case kHS18ExitToyStore: if (gnap._actionStatus < 0) { if (_vm->isFlag(kGFPlatypusDisguised)) { gnapCarryGarbageCanTo(-1); putDownGarbageCan(0); } if (_vm->isFlag(kGFPictureTaken)) { gnap.playImpossible(); } else { _vm->_isLeavingScene = true; _vm->_newSceneNum = 19; gnap.walkTo(_vm->_hotspotsWalkPos[kHS18ExitToyStore], 0, 0x107C0, 1); gnap._actionStatus = kAS18LeaveScene; if (!_vm->isFlag(kGFPlatypusTalkingToAssistant)) plat.walkTo(_vm->_hotspotsWalkPos[kHS18ExitToyStore] + Common::Point(1, 0), -1, 0x107C2, 1); } } break; case kHS18ExitPhoneBooth: if (gnap._actionStatus < 0) { if (_vm->isFlag(kGFPlatypusDisguised)) { gnapCarryGarbageCanTo(-1); putDownGarbageCan(0); } closeHydrantValve(); _vm->_isLeavingScene = true; _vm->_newSceneNum = 17; gnap.walkTo(_vm->_hotspotsWalkPos[kHS18ExitPhoneBooth], 0, 0x107AE, 1); gnap._actionStatus = kAS18LeaveScene; if (_vm->isFlag(kGFPlatypusTalkingToAssistant)) _vm->setFlag(kGFUnk27); else plat.walkTo(_vm->_hotspotsWalkPos[kHS18ExitPhoneBooth] + Common::Point(1, 0), -1, 0x107C2, 1); } break; case kHS18ExitGrubCity: if (gnap._actionStatus < 0) { if (_vm->isFlag(kGFPlatypusDisguised)) { gnapCarryGarbageCanTo(-1); putDownGarbageCan(0); } closeHydrantValve(); _vm->_isLeavingScene = true; _vm->_newSceneNum = 20; _vm->_hotspots[kHS18WalkArea2]._flags |= SF_WALKABLE; gnap.walkTo(_vm->_hotspotsWalkPos[kHS18ExitGrubCity], 0, 0x107B2, 1); gnap._actionStatus = kAS18LeaveScene; if (_vm->isFlag(kGFPlatypusTalkingToAssistant)) platEndPhoning(false); else plat.walkTo(_vm->_hotspotsWalkPos[kHS18ExitGrubCity] + Common::Point(0, -1), -1, 0x107CF, 1); _vm->_hotspots[kHS18WalkArea2]._flags &= ~SF_WALKABLE; } break; case kHS18WalkArea1: case kHS18WalkArea2: if (gnap._actionStatus < 0) { if (_vm->isFlag(kGFPlatypusDisguised)) { gnapCarryGarbageCanTo(-1); putDownGarbageCan(0); } else { gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); } _vm->_mouseClickState._left = false; } break; default: if (gnap._actionStatus != kAS18StandingOnHydrant && _vm->_mouseClickState._left) { if (_vm->isFlag(kGFPlatypusDisguised)) { gnapCarryGarbageCanTo(-1); putDownGarbageCan(0); } else { gnap.walkTo(Common::Point(-1, -1), -1, -1, 1); } _vm->_mouseClickState._left = false; } break; } updateAnimations(); if (!_vm->isSoundPlaying(0x10940)) _vm->playSound(0x10940, true); if ((_vm->isFlag(kGFTruckFilledWithGas) || _vm->isFlag(kGFBarnPadlockOpen)) && !_vm->isSoundPlaying(0x22B) && gnap._actionStatus != kAS18OpenRightValveNoGarbageCanDone && gnap._actionStatus != kAS18OpenRightValveNoGarbageCan && gnap._actionStatus != kAS18OpenTopValve && gnap._actionStatus != kAS18OpenTopValveDone && gnap._actionStatus != kAS18OpenRightValveWithGarbageCan && gnap._actionStatus != kAS18OpenRightValveWithGarbageCanDone) _vm->playSound(0x22B, true); if (!_vm->_isLeavingScene) { if (!_vm->isFlag(kGFPlatypusTalkingToAssistant)) { if (plat._actionStatus == kAS18PlatComesHere) { if (!_vm->_timers[6]) { plat._actionStatus = -1; _vm->_sceneWaiting = false; plat.initPos(-1, 10, kDirIdleLeft); plat.walkTo(Common::Point(3, 9), -1, 0x107C2, 1); _vm->clearFlag(kGFPlatypusTalkingToAssistant); } } else { _vm->_hotspots[kHS18WalkArea1]._rect.bottom += 48; _vm->_hotspots[kHS18WalkArea2]._rect.left += 75; plat.updateIdleSequence(); _vm->_hotspots[kHS18WalkArea2]._rect.left -= 75; _vm->_hotspots[kHS18WalkArea1]._rect.bottom -= 48; } if (!_vm->_timers[5]) { _vm->_timers[5] = _vm->getRandom(100) + 100; if (gnap._actionStatus < 0) { if (_vm->getRandom(2) == 1) gameSys.insertSequence(0x220, 255, 0, 0, kSeqNone, 0, 0, 0); else gameSys.insertSequence(0x221, 255, 0, 0, kSeqNone, 0, 0, 0); } } _vm->playSoundA(); } if (!_vm->isFlag(kGFPlatypusDisguised)) gnap.updateIdleSequence(); } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); } _vm->gameUpdateTick(); } if (_vm->isFlag(kGFGnapControlsToyUFO)) _vm->deleteSurface(&_cowboyHatSurface); } void Scene18::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; if (gameSys.getAnimationStatus(0) == 2) { gameSys.setAnimation(0, 0, 0); switch (gnap._actionStatus) { case kAS18GrabGarbageCanFromStreet: if (gnap._idleFacing != kDirUpRight && gnap._idleFacing != kDirBottomRight) { gameSys.insertSequence(0x1FC, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 75 * gnap._pos.x - 675, 0); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x1FC; } else { gameSys.insertSequence(0x1FD, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 75 * gnap._pos.x - 525, 0); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x1FD; } gameSys.removeSequence(0x1FA, 19, true); _vm->setFlag(kGFPlatypusDisguised); updateHotspots(); gnap._actionStatus = -1; break; case kAS18GrabGarbageCanFromHydrant: gameSys.insertSequence(0x1FE, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.removeSequence(0x1F9, 19, true); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x1FE; _vm->clearFlag(kGFTruckKeysUsed); _vm->setFlag(kGFPlatypusDisguised); updateHotspots(); gnap._actionStatus = -1; break; case kAS18CloseRightValveNoGarbageCan: gameSys.insertSequence(0x205, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.removeSequence(0x20D, 39, true); gameSys.removeSequence(0x212, 39, true); gameSys.removeSequence(0x211, 39, true); _vm->stopSound(0x22B); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x205; _vm->clearFlag(kGFTruckFilledWithGas); _vm->invAdd(kItemWrench); _vm->setGrabCursorSprite(kItemWrench); updateHotspots(); gnap._actionStatus = -1; break; case kAS18OpenTopValve: _vm->setFlag(kGFBarnPadlockOpen); updateHotspots(); gnap.playPullOutDevice(Common::Point(2, 7)); gnap.playUseDevice(); gameSys.insertSequence(0x20C, 19, 0, 0, kSeqNone, 0, 0, 0); _vm->_hotspots[kHS18WalkArea2]._flags |= SF_WALKABLE; gnap.walkTo(_vm->_hotspotsWalkPos[kHS18HydrantTopValve], 0, 0x107BB, 1); _vm->_hotspots[kHS18WalkArea2]._flags &= ~SF_WALKABLE; gnap._actionStatus = kAS18OpenTopValveDone; break; case kAS18OpenTopValveDone: _vm->setGrabCursorSprite(-1); gameSys.insertSequence(0x208, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x216, 39, 0, 0, kSeqNone, 21, 0, 0); gameSys.removeSequence(0x20C, 19, true); gameSys.setAnimation(0x217, 39, 5); gameSys.insertSequence(0x217, 39, 0x216, 39, kSeqLoop | kSeqSyncWait, 0, 0, 0); while (gameSys.getAnimationStatus(5) != 2 && !_vm->_gameDone) _vm->gameUpdateTick(); _vm->playSound(0x22B, true); gameSys.insertSequence(0x20E, 39, 0, 0, kSeqNone, 0, 0, 0); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x208; _vm->invRemove(kItemWrench); _vm->setGrabCursorSprite(-1); gnap._actionStatus = -1; break; case kAS18CloseTopValve: gameSys.insertSequence(0x206, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.removeSequence(0x20E, 39, true); gameSys.removeSequence(0x216, 39, true); gameSys.removeSequence(0x217, 39, true); _vm->stopSound(0x22B); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x206; _vm->clearFlag(kGFBarnPadlockOpen); _vm->invAdd(kItemWrench); _vm->setGrabCursorSprite(kItemWrench); updateHotspots(); gnap._actionStatus = -1; break; case kAS18GrabCowboyHat: gameSys.setAnimation(0x200, gnap._id, 0); gameSys.insertSequence(0x200, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x200; gnap._actionStatus = kAS18GrabCowboyHatDone; break; case kAS18GrabCowboyHatDone: _vm->hideCursor(); _vm->setGrabCursorSprite(-1); _cowboyHatSurface = _vm->addFullScreenSprite(0x1D2, 255); gameSys.setAnimation(0x218, 256, 0); gameSys.insertSequence(0x218, 256, 0, 0, kSeqNone, 0, 0, 0); while (gameSys.getAnimationStatus(0) != 2 && !_vm->_gameDone) _vm->gameUpdateTick(); _vm->_newSceneNum = 18; _vm->invAdd(kItemCowboyHat); _vm->invAdd(kItemWrench); _vm->setFlag(kGFGnapControlsToyUFO); _vm->setFlag(kGFUnk14); _vm->clearFlag(kGFTruckFilledWithGas); _vm->setFlag(kGFTruckKeysUsed); _vm->setFlag(kGFUnk14); // Useless, already set updateHotspots(); gnap._actionStatus = kAS18LeaveScene; break; case kAS18LeaveScene: _vm->_sceneDone = true; gnap._actionStatus = -1; break; case kAS18PutGarbageCanOnRunningHydrant: _vm->setFlag(kGFTruckKeysUsed); _vm->clearFlag(kGFPlatypusDisguised); gameSys.requestRemoveSequence(0x211, 39); gameSys.requestRemoveSequence(0x212, 39); gameSys.insertSequence(0x210, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); _vm->stopSound(0x22B); gameSys.setAnimation(0x210, gnap._id, 0); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x210; gnap._actionStatus = kAS18PutGarbageCanOnRunningHydrant2; break; case kAS18PutGarbageCanOnRunningHydrant2: _vm->playSound(0x22B, true); gameSys.setAnimation(0x1FF, gnap._id, 0); gameSys.insertSequence(0x1FF, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x1FF; _vm->_sceneWaiting = true; gnap._actionStatus = kAS18StandingOnHydrant; break; case kAS18StandingOnHydrant: gameSys.setAnimation(0x1FF, gnap._id, 0); gameSys.insertSequence(0x1FF, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); break; case kAS18OpenRightValveNoGarbageCan: case kAS18OpenRightValveWithGarbageCan: _vm->setFlag(kGFTruckFilledWithGas); updateHotspots(); gnap.playPullOutDevice(Common::Point(2, 7)); gnap.playUseDevice(); gameSys.insertSequence(0x20B, 19, 0, 0, kSeqNone, 0, 0, 0); _vm->_hotspots[kHS18WalkArea2]._flags |= SF_WALKABLE; gnap.walkTo(_vm->_hotspotsWalkPos[kHS18HydrantRightValve], 0, 0x107BA, 1); _vm->_hotspots[kHS18WalkArea2]._flags &= ~SF_WALKABLE; if (gnap._actionStatus == kAS18OpenRightValveNoGarbageCan) gnap._actionStatus = kAS18OpenRightValveNoGarbageCanDone; else gnap._actionStatus = kAS18OpenRightValveWithGarbageCanDone; break; case kAS18OpenRightValveWithGarbageCanDone: _vm->setGrabCursorSprite(-1); gameSys.insertSequence(0x207, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x213, 39, 0, 0, kSeqNone, 21, 0, 0); gameSys.requestRemoveSequence(0x1F9, 19); gameSys.removeSequence(0x20B, 19, true); gameSys.setAnimation(0x213, 39, 5); gameSys.insertSequence(0x214, 39, 0x213, 39, kSeqLoop | kSeqSyncWait, 0, 0, 0); while (gameSys.getAnimationStatus(5) != 2 && !_vm->_gameDone) _vm->gameUpdateTick(); _vm->playSound(0x22B, true); gameSys.insertSequence(0x20D, 39, 0, 0, kSeqNone, 0, 0, 0); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x207; _vm->invRemove(kItemWrench); gnap._actionStatus = -1; break; case kAS18OpenRightValveNoGarbageCanDone: _vm->setGrabCursorSprite(-1); gameSys.insertSequence(0x207, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x211, 39, 0, 0, kSeqNone, 21, 0, 0); gameSys.removeSequence(0x20B, 19, true); gameSys.setAnimation(0x211, 39, 5); gameSys.insertSequence(0x212, 39, 0x211, 39, kSeqLoop | kSeqSyncWait, 0, 0, 0); while (gameSys.getAnimationStatus(5) != 2 && !_vm->_gameDone) _vm->gameUpdateTick(); _vm->playSound(0x22B, true); gameSys.insertSequence(0x20D, 39, 0, 0, kSeqNone, 0, 0, 0); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x207; _vm->invRemove(kItemWrench); gnap._actionStatus = -1; break; case kAS18CloseRightValveWithGarbageCan: gameSys.insertSequence(0x205, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.removeSequence(0x20D, 39, true); gameSys.insertSequence(0x215, 39, 0x214, 39, kSeqSyncWait, 0, 0, 0); _vm->stopSound(0x22B); gameSys.setAnimation(0x1F9, 19, 0); gameSys.insertSequence(0x1F9, 19, 0x215, 39, kSeqSyncWait, 0, 0, 0); _vm->clearFlag(kGFTruckFilledWithGas); _vm->invAdd(kItemWrench); _vm->setGrabCursorSprite(kItemWrench); gameSys.insertSequence(0x107B5, gnap._id, 517, gnap._id, kSeqSyncWait, 0, 75 * gnap._pos.x - gnap._gridX, 48 * gnap._pos.y - gnap._gridY); updateHotspots(); gnap._sequenceDatNum = 1; gnap._sequenceId = 0x7B5; gnap._actionStatus = kAS18CloseRightValveWithGarbageCanDone; break; case kAS18CloseRightValveWithGarbageCanDone: gnap._actionStatus = -1; break; case kAS18PutGarbageCanOnHydrant: _vm->setFlag(kGFTruckKeysUsed); _vm->clearFlag(kGFPlatypusDisguised); gameSys.insertSequence(0x20F, gnap._id, makeRid(gnap._sequenceDatNum, gnap._sequenceId), gnap._id, kSeqSyncWait, 0, 0, 0); gameSys.setAnimation(0x20F, gnap._id, 0); gnap._sequenceDatNum = 0; gnap._sequenceId = 0x20F; gnap._actionStatus = kAS18PutGarbageCanOnHydrantDone; break; case kAS18PutGarbageCanOnHydrantDone: gameSys.insertSequence(0x1F9, 19, 0x20F, gnap._id, kSeqNone, 0, 0, 0); updateHotspots(); gnap._actionStatus = -1; break; } } if (gameSys.getAnimationStatus(3) == 2) { gameSys.setAnimation(0, 0, 3); ++_platPhoneIter; if (_platPhoneIter <= 4) { ++_platPhoneCtr; _nextPhoneSequenceId = kScene18SequenceIds[_platPhoneCtr % 5]; gameSys.setAnimation(_nextPhoneSequenceId, 254, 3); gameSys.insertSequence(_nextPhoneSequenceId, 254, _currPhoneSequenceId, 254, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x21F, 254, 0x21F, 254, kSeqSyncWait, 0, 0, 0); _currPhoneSequenceId = _nextPhoneSequenceId; } else { platEndPhoning(true); } } } /*****************************************************************************/ static const int kS19ShopAssistantSequenceIds[] = { 0x6F, 0x70, 0x71, 0x72, 0x73 }; Scene19::Scene19(GnapEngine *vm) : Scene(vm) { _toyGrabCtr = 0; _shopAssistantCtr = 0; _currShopAssistantSequenceId = -1; _nextShopAssistantSequenceId = -1; _pictureSurface = nullptr; } Scene19::~Scene19() { delete _pictureSurface; } int Scene19::init() { _vm->playSound(0x79, false); return _vm->isFlag(kGFPlatypusTalkingToAssistant) ? 0x77 : 0x76; } void Scene19::updateHotspots() { _vm->setHotspot(kHS19Platypus, 0, 0, 0, 0, SF_WALKABLE | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR); _vm->setHotspot(kHS19ExitOutsideToyStore, 36, 154, 142, 338, SF_EXIT_NW_CURSOR, 4, 6); _vm->setHotspot(kHS19Picture, 471, 237, 525, 283, SF_DISABLED, 7, 2); _vm->setHotspot(kHS19ShopAssistant, 411, 151, 575, 279, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 5, 7); _vm->setHotspot(kHS19Phone, 647, 166, 693, 234, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 9, 0); _vm->setHotspot(kHS19Toy1, 181, 11, 319, 149, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 3, 0); _vm->setHotspot(kHS19Toy2, 284, 85, 611, 216, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 6, 0); _vm->setHotspot(kHS19Toy3, 666, 38, 755, 154, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 9, 0); _vm->setHotspot(kHS19Toy4, 154, 206, 285, 327, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 3, 3); _vm->setHotspot(kHS19Toy5, 494, 301, 570, 448, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 7, 5); _vm->setHotspot(kHS19Toy6, 0, 320, 188, 600, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 1, 6); _vm->setHotspot(kHS19Toy7, 597, 434, 800, 600, SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR, 9, 8); _vm->setHotspot(kHS19WalkArea1, 0, 0, 170, 600); _vm->setHotspot(kHS19WalkArea2, 622, 0, 800, 600); _vm->setHotspot(kHS19WalkArea3, 0, 0, 800, 437); _vm->setDeviceHotspot(kHS19Device, -1, -1, -1, -1); if (_vm->isFlag(kGFPlatypusTalkingToAssistant)) { _vm->_hotspots[kHS19Toy1]._flags = SF_DISABLED; _vm->_hotspots[kHS19Toy2]._flags = SF_DISABLED; _vm->_hotspots[kHS19Toy3]._flags = SF_DISABLED; _vm->_hotspots[kHS19Toy4]._flags = SF_DISABLED; _vm->_hotspots[kHS19Toy5]._flags = SF_DISABLED; _vm->_hotspots[kHS19Toy6]._flags = SF_DISABLED; _vm->_hotspots[kHS19Toy7]._flags = SF_DISABLED; _vm->_hotspots[kHS19ShopAssistant]._flags = SF_DISABLED; _vm->_hotspots[kHS19Phone]._flags = SF_DISABLED; _vm->_hotspots[kHS19Platypus]._flags = SF_DISABLED; _vm->_hotspots[kHS19Picture]._flags = SF_PLAT_CURSOR | SF_TALK_CURSOR | SF_GRAB_CURSOR | SF_LOOK_CURSOR; } _vm->_hotspotsCount = 16; } void Scene19::run() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; PlayerPlat& plat = *_vm->_plat; _vm->queueInsertDeviceIcon(); _toyGrabCtr = 0; _pictureSurface = nullptr; gameSys.insertSequence(0x74, 254, 0, 0, kSeqNone, 0, 0, 0); gameSys.insertSequence(0x75, 254, 0, 0, kSeqNone, 0, 0, 0); if (!_vm->isFlag(kGFPictureTaken)) gameSys.insertSequence(0x69, 19, 0, 0, kSeqNone, 0, 0, 0); if (_vm->isFlag(kGFPlatypusTalkingToAssistant)) { gnap.initPos(3, 6, kDirBottomRight); _currShopAssistantSequenceId = kS19ShopAssistantSequenceIds[_vm->getRandom(5)]; _nextShopAssistantSequenceId = _currShopAssistantSequenceId; gameSys.setAnimation(_currShopAssistantSequenceId, 20, 4); gameSys.insertSequence(0x6E, 254, 0, 0, kSeqNone, 0, 0, 0); gameSys.insertSequence(_currShopAssistantSequenceId, 20, 0, 0, kSeqNone, 0, 0, 0); _shopAssistantCtr = 0; _vm->endSceneInit(); gnap.walkTo(Common::Point(4, 9), -1, 0x107B9, 1); updateHotspots(); } else { _currShopAssistantSequenceId = 0x6D; _nextShopAssistantSequenceId = -1; gameSys.setAnimation(0x6D, 20, 4); gameSys.insertSequence(_currShopAssistantSequenceId, 20, 0, 0, kSeqNone, 0, 0, 0); _vm->_timers[6] = _vm->getRandom(40) + 50; gnap.initPos(3, 6, kDirBottomRight); plat.initPos(4, 6, kDirIdleLeft); _vm->endSceneInit(); gnap.walkTo(Common::Point(4, 9), -1, 0x107B9, 1); plat.walkTo(Common::Point(5, 9), -1, 0x107C2, 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 kHS19Device: if (gnap._actionStatus < 0) { _vm->runMenu(); updateHotspots(); } break; case kHS19Platypus: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex == kItemJoint) { gnap.useJointOnPlatypus(); } else if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(plat._pos); } else { 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: gnap.playImpossible(); break; } } } break; case kHS19ExitOutsideToyStore: if (gnap._actionStatus < 0) { _vm->_isLeavingScene = true; _vm->_newSceneNum = 18; _vm->_hotspots[kHS19WalkArea1]._flags |= SF_WALKABLE; gnap.walkTo(_vm->_hotspotsWalkPos[1], 0, 0x107B2, 1); gnap._actionStatus = kAS19LeaveScene; if (_vm->isFlag(kGFPlatypusTalkingToAssistant)) _vm->setFlag(kGFUnk27); else plat.walkTo(_vm->_hotspotsWalkPos[1] + Common::Point(1, 0), -1, 0x107C5, 1); _vm->_hotspots[kHS19WalkArea1]._flags &= ~SF_WALKABLE; } break; case kHS19Picture: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 6, 2); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(6, 2)); break; case GRAB_CURSOR: if (!_vm->isFlag(kGFPictureTaken)) { gnap.walkTo(gnap._pos, 0, gnap.getSequenceId(kGSIdle, _vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot]) | 0x10000, 1); gnap._actionStatus = kAS19GrabPicture; } break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS19ShopAssistant: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 6, 2); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(6, 2)); break; case TALK_CURSOR: gnap._idleFacing = kDirUpRight; gnap.walkTo(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 0, gnap.getSequenceId(kGSBrainPulsating, Common::Point(0, 0)) | 0x10000, 1); gnap._actionStatus = kAS19TalkShopAssistant; break; case GRAB_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS19Toy1: case kHS19Toy2: case kHS19Toy3: case kHS19Toy4: case kHS19Toy5: case kHS19Toy6: case kHS19Toy7: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playImpossible(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot]); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playMoan2(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot]); break; case GRAB_CURSOR: gnap.walkTo(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 0, -1, 1); gnap.playIdle(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot]); gnap._actionStatus = kAS19GrabToy; break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS19Phone: if (gnap._actionStatus < 0) { if (_vm->_grabCursorSpriteIndex >= 0) { gnap.playShowCurrItem(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 9, 1); } else { switch (_vm->_verbCursor) { case LOOK_CURSOR: gnap.playScratchingHead(Common::Point(9, 1)); break; case GRAB_CURSOR: gnap.walkTo(_vm->_hotspotsWalkPos[_vm->_sceneClickedHotspot], 0, -1, 1); gnap.playIdle(Common::Point(8, 2)); gnap._actionStatus = kAS19UsePhone; break; case TALK_CURSOR: case PLAT_CURSOR: gnap.playImpossible(); break; } } } break; case kHS19WalkArea1: case kHS19WalkArea2: case kHS19WalkArea3: if (gnap._actionStatus < 0) 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 = 0; } } updateAnimations(); if (!_vm->_isLeavingScene) { gnap.updateIdleSequence(); if (!_vm->isFlag(kGFPlatypusTalkingToAssistant)) { plat.updateIdleSequence(); if (!_vm->_timers[6] && _nextShopAssistantSequenceId == -1) { _vm->_timers[6] = _vm->getRandom(40) + 50; if (_vm->getRandom(4) != 0) { _nextShopAssistantSequenceId = 0x64; } else if (_vm->isFlag(kGFPictureTaken)) { _nextShopAssistantSequenceId = 0x64; } else { _nextShopAssistantSequenceId = 0x6C; } } } } _vm->checkGameKeys(); if (_vm->isKeyStatus1(Common::KEYCODE_BACKSPACE)) { _vm->clearKeyStatus1(Common::KEYCODE_BACKSPACE); _vm->runMenu(); updateHotspots(); } _vm->gameUpdateTick(); } if (_pictureSurface) _vm->deleteSurface(&_pictureSurface); } void Scene19::updateAnimations() { GameSys& gameSys = *_vm->_gameSys; PlayerGnap& gnap = *_vm->_gnap; if (gameSys.getAnimationStatus(0) == 2) { gameSys.setAnimation(0, 0, 0); switch (gnap._actionStatus) { case kAS19UsePhone: _nextShopAssistantSequenceId = 0x67; break; case kAS19GrabToy: ++_toyGrabCtr; switch (_toyGrabCtr) { case 1: _nextShopAssistantSequenceId = 0x62; break; case 2: _nextShopAssistantSequenceId = 0x6B; break; case 3: _nextShopAssistantSequenceId = 0x66; break; default: _nextShopAssistantSequenceId = 0x65; break; } break; case kAS19GrabPicture: gnap.playPullOutDevice(Common::Point(6, 2)); gnap.playUseDevice(); gameSys.setAnimation(0x68, 19, 0); gameSys.insertSequence(0x68, 19, 105, 19, kSeqSyncWait, 0, 0, 0); _vm->invAdd(kItemPicture); _vm->setFlag(kGFPictureTaken); updateHotspots(); gnap._actionStatus = kAS19GrabPictureDone; break; case kAS19GrabPictureDone: _vm->setGrabCursorSprite(-1); _vm->hideCursor(); _pictureSurface = _vm->addFullScreenSprite(0xF, 255); gameSys.setAnimation(0x61, 256, 0); gameSys.insertSequence(0x61, 256, 0, 0, kSeqNone, 0, 0, 0); while (gameSys.getAnimationStatus(0) != 2 && !_vm->_gameDone) _vm->gameUpdateTick(); _vm->setFlag(kGFUnk27); _vm->showCursor(); _vm->_newSceneNum = 17; _vm->_isLeavingScene = true; _vm->_sceneDone = true; _nextShopAssistantSequenceId = -1; break; case kAS19TalkShopAssistant: _nextShopAssistantSequenceId = 0x6D; gnap._actionStatus = -1; break; case kAS19LeaveScene: _vm->_sceneDone = true; break; } } if (gameSys.getAnimationStatus(4) == 2) { switch (_nextShopAssistantSequenceId) { case 0x6F: case 0x70: case 0x71: case 0x72: case 0x73: _shopAssistantCtr = (_shopAssistantCtr + 1) % 5; _nextShopAssistantSequenceId = kS19ShopAssistantSequenceIds[_shopAssistantCtr]; gameSys.setAnimation(_nextShopAssistantSequenceId, 20, 4); gameSys.insertSequence(_nextShopAssistantSequenceId, 20, _currShopAssistantSequenceId, 20, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x6E, 254, 0x6E, 254, kSeqSyncWait, 0, 0, 0); _currShopAssistantSequenceId = _nextShopAssistantSequenceId; break; case 0x62: case 0x66: case 0x6B: gameSys.setAnimation(_nextShopAssistantSequenceId, 20, 4); gameSys.insertSequence(_nextShopAssistantSequenceId, 20, _currShopAssistantSequenceId, 20, kSeqSyncWait, 0, 0, 0); _currShopAssistantSequenceId = _nextShopAssistantSequenceId; _nextShopAssistantSequenceId = -1; _vm->_timers[5] = 10; while (_vm->_timers[5] && !_vm->_gameDone) _vm->gameUpdateTick(); gnap.playIdle(Common::Point(6, 2)); gnap._actionStatus = -1; break; case 0x67: gameSys.setAnimation(_nextShopAssistantSequenceId, 20, 4); gameSys.insertSequence(_nextShopAssistantSequenceId, 20, _currShopAssistantSequenceId, 20, kSeqSyncWait, 0, 0, 0); _currShopAssistantSequenceId = _nextShopAssistantSequenceId; _nextShopAssistantSequenceId = -1; gnap._actionStatus = -1; break; case 0x65: gnap.playIdle(Common::Point(6, 2)); gameSys.setAnimation(_nextShopAssistantSequenceId, 20, 0); gameSys.insertSequence(_nextShopAssistantSequenceId, 20, _currShopAssistantSequenceId, 20, kSeqSyncWait, 0, 0, 0); _currShopAssistantSequenceId = _nextShopAssistantSequenceId; _nextShopAssistantSequenceId = -1; _vm->_newSceneNum = 18; gnap._actionStatus = kAS19LeaveScene; break; case 0x6D: gameSys.setAnimation(_nextShopAssistantSequenceId, 20, 4); gameSys.insertSequence(_nextShopAssistantSequenceId, 20, _currShopAssistantSequenceId, 20, kSeqSyncWait, 0, 0, 0); gameSys.insertSequence(0x69, 19, 0x69, 19, kSeqSyncWait, _vm->getSequenceTotalDuration(_nextShopAssistantSequenceId), 0, 0); _currShopAssistantSequenceId = _nextShopAssistantSequenceId; _nextShopAssistantSequenceId = -1; break; case 0x64: case 0x6C: gameSys.setAnimation(_nextShopAssistantSequenceId, 20, 4); gameSys.insertSequence(_nextShopAssistantSequenceId, 20, _currShopAssistantSequenceId, 20, kSeqSyncWait, 0, 0, 0); _currShopAssistantSequenceId = _nextShopAssistantSequenceId; _nextShopAssistantSequenceId = -1; break; } } } } // End of namespace Gnap