/* 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 "neverhood/modules/module1900.h" #include "neverhood/modules/module1900_sprites.h" namespace Neverhood { static const uint32 kModule1900SoundList[] = { 0xB4005E60, 0x91835066, 0x90E14440, 0 }; Module1900::Module1900(NeverhoodEngine *vm, Module *parentModule, int which) : Module(vm, parentModule) { // NOTE: The original has a Scene1908 here as well but it's not used here but in another module... if (which < 0) createScene(_vm->gameState().sceneNum, -1); else createScene(0, 0); _vm->_soundMan->addSoundList(0x04E1C09C, kModule1900SoundList); _vm->_soundMan->setSoundListParams(kModule1900SoundList, true, 50, 600, 5, 150); } Module1900::~Module1900() { _vm->_soundMan->deleteGroup(0x04E1C09C); } void Module1900::createScene(int sceneNum, int which) { debug(1, "Module1900::createScene(%d, %d)", sceneNum, which); _sceneNum = sceneNum; switch (_sceneNum) { case 0: _vm->gameState().sceneNum = 0; _childObject = new Scene1901(_vm, this, which); break; case 6: _vm->gameState().sceneNum = 6; _childObject = new Scene1907(_vm, this); break; } SetUpdateHandler(&Module1900::updateScene); _childObject->handleUpdate(); } void Module1900::updateScene() { if (!updateChild()) { switch (_sceneNum) { case 0: if (_moduleResult == 1) createScene(6, 0); else leaveModule(0); break; case 6: createScene(0, 1); break; } } } Scene1901::Scene1901(NeverhoodEngine *vm, Module *parentModule, int which) : Scene(vm, parentModule) { Sprite *tempSprite; setRectList(0x004B34C8); setBackground(0x01303227); setPalette(0x01303227); insertScreenMouse(0x0322301B); insertStaticSprite(0x42213133, 1100); if (!getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) insertStaticSprite(0x40A40168, 100); else if (getGlobalVar(V_STAIRS_DOWN)) { insertStaticSprite(0x124404C4, 100); setGlobalVar(V_STAIRS_DOWN_ONCE, 1); } else insertStaticSprite(0x02840064, 100); if (which < 0) { // Restoring game insertKlaymen(120, 380); setMessageList(0x004B3408); } else if (which == 1) { // Klaymen returning from the puzzle insertKlaymen(372, 380); setMessageList(0x004B3410); } else { // Klaymen entering from the left insertKlaymen(0, 380); setMessageList(0x004B3400); } tempSprite = insertStaticSprite(0x4830A402, 1100); _klaymen->setClipRect(tempSprite->getDrawRect().x, 0, 640, 480); } Scene1907::Scene1907(NeverhoodEngine *vm, Module *parentModule) : Scene(vm, parentModule), _currMovingSymbolIndex(0), _pluggedInCount(0), _moveDownCountdown(0), _moveUpCountdown(0), _countdown3(0), _hasPlugInFailed(false) { setBackground(0x20628E05); setPalette(0x20628E05); for (int i = 0; i < 9; i++) _positionFree[i] = true; for (int i = 0; i < 9; i++) { _asSymbols[i] = insertSprite(this, i, getRandomPositionIndex()); addCollisionSprite(_asSymbols[i]); } _ssUpDownButton = insertSprite(this, _asSymbols[8]); addCollisionSprite(_ssUpDownButton); _asWaterHint = insertSprite(); insertPuzzleMouse(0x28E0120E, 20, 620); SetMessageHandler(&Scene1907::handleMessage); SetUpdateHandler(&Scene1907::update); if (getGlobalVar(V_STAIRS_PUZZLE_SOLVED)) _pluggedInCount = 9; loadSound(0, 0x72004A10); loadSound(1, 0x22082A12); loadSound(2, 0x21100A10); loadSound(3, 0x68E25540); } void Scene1907::update() { Scene::update(); if (_hasPlugInFailed) { int fallOffDelay = 0; _hasPlugInFailed = false; for (int i = 0; i < 9; i++) { AsScene1907Symbol *asSymbol = _asSymbols[8 - i]; if (asSymbol->isPluggedIn()) { asSymbol->fallOff(getRandomPositionIndex(), fallOffDelay); fallOffDelay += _vm->_rnd->getRandomNumber(10 - 1) + 4; } } } if (_moveDownCountdown != 0 && (--_moveDownCountdown == 0)) { _asSymbols[_currMovingSymbolIndex]->moveDown(); if (_currMovingSymbolIndex > 0) { _moveDownCountdown = 2; _currMovingSymbolIndex--; } } if (_moveUpCountdown != 0 && (--_moveUpCountdown == 0)) { _moveDownCountdown = 0; for (int i = 0; i < 9; i++) _asSymbols[i]->moveUp(); } if (_countdown3 != 0 && (--_countdown3 == 0)) { _asWaterHint->show(); _moveUpCountdown = 4; } } uint32 Scene1907::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { Scene::handleMessage(messageNum, param, sender); switch (messageNum) { case NM_MOUSE_CLICK: if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !_hasPlugInFailed && _moveDownCountdown == 0 && _moveUpCountdown == 0 && _countdown3 == 0) { leaveScene(0); } break; case NM_ANIMATION_UPDATE: if (getGlobalVar(V_STAIRS_DOWN)) { playSound(0); for (int i = 0; i < 9; i++) _asSymbols[i]->moveUp(); _ssUpDownButton->setToUpPosition(); setGlobalVar(V_STAIRS_DOWN, 0); } else { if (!getGlobalVar(V_WALL_BROKEN)) { playSound(2); _countdown3 = 5; } else { playSound(1); _ssUpDownButton->setToDownPosition(); setGlobalVar(V_STAIRS_DOWN, 1); } _moveDownCountdown = 1; _currMovingSymbolIndex = 8; } break; case 0x2001: playSound(3); setGlobalVar(V_STAIRS_PUZZLE_SOLVED, 1); break; } return 0; } void Scene1907::plugInFailed() { _pluggedInCount = 0; _hasPlugInFailed = true; } int Scene1907::getRandomPositionIndex() { bool found = false; int index = 0; // Check if any position is free for (int i = 0; i < 9; i++) if (_positionFree[i]) found = true; if (found) { // Get a random free position found = false; while (!found) { index = _vm->_rnd->getRandomNumber(9 - 1); if (_positionFree[index]) found = true; } } return index; } } // End of namespace Neverhood