diff options
author | Jaromir Wysoglad | 2019-06-12 11:30:06 +0200 |
---|---|---|
committer | Thierry Crozat | 2019-07-28 15:09:14 +0100 |
commit | 006880ea7cfc906a8ca0f4bfb5f7fcf9955f6e39 (patch) | |
tree | 58b7dd268763ce49061a2b9635fd8ef92ee70dd2 | |
parent | f00c19604e412e26004a22fd7ac14ae0a308d9f0 (diff) | |
download | scummvm-rg350-006880ea7cfc906a8ca0f4bfb5f7fcf9955f6e39.tar.gz scummvm-rg350-006880ea7cfc906a8ca0f4bfb5f7fcf9955f6e39.tar.bz2 scummvm-rg350-006880ea7cfc906a8ca0f4bfb5f7fcf9955f6e39.zip |
SUPERNOVA2: Add Museum room.
-rw-r--r-- | engines/supernova2/ms2_def.h | 12 | ||||
-rw-r--r-- | engines/supernova2/resman.cpp | 3 | ||||
-rw-r--r-- | engines/supernova2/rooms.cpp | 101 | ||||
-rw-r--r-- | engines/supernova2/sound.h | 1 | ||||
-rw-r--r-- | engines/supernova2/state.cpp | 166 | ||||
-rw-r--r-- | engines/supernova2/state.h | 20 |
6 files changed, 286 insertions, 17 deletions
diff --git a/engines/supernova2/ms2_def.h b/engines/supernova2/ms2_def.h index c457bf7c2e..7ab8d9d260 100644 --- a/engines/supernova2/ms2_def.h +++ b/engines/supernova2/ms2_def.h @@ -140,12 +140,12 @@ kString50, kString51, kString52, kString53, kString54, kString55, kString56, kString57, kString58, kString59, kString60, kString61, kString62, kString63, kString64, kString65, kString66, kString67, kString68, kString69, -kString70, kString71, kString72, kString73, kString74, -kString75, kString76, kString77, kString78, kString79, -kString80, kString81, kString82, kString83, kString84, +kStringMuseum8, kStringMuseum9, kStringMuseum7, kStringMuseum6, kStringMuseum15, +kStringMuseum16, kStringMuseum10, kStringMuseum12, kStringMuseum13, kStringMuseum14, +kStringMuseum1, kStringMuseum2, kStringMuseum3, kStringMuseum4, kStringMuseum5, kString85, kString86, kString87, kString88, kString89, -kString90, kString91, kString92, kString93, kString94, -kStringEntrance, kStringDoor, kString97, kString98, kString99, +kString90, kString91, kString92, kStringDinosaur, kStringDinosaurDescription, +kStringEntrance, kStringDoor, kStringRoad, kString98, kString99, kString100, kStringCorridor, kString102, kStringDinosaurHead, kString104, kString105, kStringSuctionCup, kString107, kStringOpening, kStringLetter, kStringMassive, kStringInscriptionDescription, kStringPyramid0, kStringPyramid1, kStringPyramid2, @@ -249,7 +249,7 @@ kStringIntroTV3, kStringIntroTV4, kStringIntroTV5, kStringIntroTV6, kStringIntro kStringIntroTV8, kStringIntroTV9, kStringIntroTV10, kStringIntroTV11, kStringIntroTV12, kStringIntroTV13, kStringIntroTV14, kStringIntroTV15, kStringIntroTV16, kStringIntro9, kStringIntro10, kStringIntro11, kStringIntro12, kStringIntro13, kStringIntro14, -kStringMonsterDescription, kStringPyramid16, kStringDialogSeparator +kStringMonsterDescription, kStringPyramid16, kStringMuseum11, kStringDialogSeparator }; ObjectType operator|(ObjectType a, ObjectType b); diff --git a/engines/supernova2/resman.cpp b/engines/supernova2/resman.cpp index 42f6f62949..3e1cb7d0e8 100644 --- a/engines/supernova2/resman.cpp +++ b/engines/supernova2/resman.cpp @@ -63,7 +63,8 @@ static const AudioInfo audioInfo[kAudioNumSamples] = { {51, 0, 6010}, {50, 0, -1}, {51, 6010, 9020}, - {54, 0, -1} + {54, 0, -1}, + {48, 0, -1} }; static const byte mouseNormal[64] = { diff --git a/engines/supernova2/rooms.cpp b/engines/supernova2/rooms.cpp index f036b226d3..de92a9246a 100644 --- a/engines/supernova2/rooms.cpp +++ b/engines/supernova2/rooms.cpp @@ -677,7 +677,7 @@ bool Games::interact(Action verb, Object &obj1, Object &obj2) { _vm->renderMessage(kStringCabinOccupiedSay); } else if (verb == ACTION_LOOK && obj1._id == POSTER) { - _gm->_taxi_possibility &= ~4; // add culture palace + _gm->_state._taxiPossibility &= ~4; // add culture palace return false; } else @@ -1884,7 +1884,7 @@ void Elevator::jobDescription() { _vm->removeMessage(); _vm->renderMessage(kStringElevator58); _gm->drawGUI(); - _gm->_state._startTime = g_system->getMillis() - 2390000; + _gm->_state._startTime = g_system->getMillis() - 150000000; _gm->_state._tipsy = false; _gm->_state._toMuseum = true; } @@ -3783,19 +3783,114 @@ Museum::Museum(Supernova2Engine *vm, GameManager *gm) { _vm = vm; _gm = gm; - _fileNumber = 6; + _fileNumber = 29; _id = MUSEUM; _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringDinosaur, kStringDinosaurDescription, NULLOBJECT, NULLTYPE, 0, 0, 0); + _objectState[1] = Object(_id, kStringEntrance, kStringDefaultDescription, BIG_DOOR, EXIT | OPENABLE | CLOSED, 1, 1, 0, NULLROOM, 0); + _objectState[2] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE | CLOSED, 2, 2, 1, MUS_EING, 9); + _objectState[3] = Object(_id, kStringRoad, kStringDefaultDescription, MUS_STREET, EXIT, 3, 3, 0); } void Museum::onEntrance() { + _gm->setAnimationTimer(1); + if (_gm->_state._alarmCracked && !_gm->_state._alarmOn) { + _gm->_state._eventTime = kMaxTimerValue; + _gm->_state._alarmOn = false; + _gm->_state._haste = false; + _vm->renderMessage(kStringMuseum1); + _gm->waitOnInput(_gm->_messageDuration); + _gm->_state._sirenOn = false; + _vm->stopSound(); + _vm->paletteFadeOut(); + _vm->_system->fillScreen(kColorBlack); + _vm->_screen->setViewportBrightness(255); + _vm->renderMessage(kStringMuseum2); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->_screen->setViewportBrightness(0); + _vm->setCurrentImage(26); + _vm->loadGame(kSleepAutosaveSlot); + _vm->renderImage(0); + _vm->paletteFadeIn(); + if (_gm->_rooms[MUS_RUND]->getObject(4)->_type & CARRIED) { + _gm->reply(kStringMuseum3, 1, 1 + 128); + _gm->reply(kStringMuseum4, 1, 1 + 128); + _gm->takeMoney(30000); + _vm->playSound(kAudioAppearance1); + } else { + _gm->reply(kStringMuseum5, 1, 1 + 128); + _gm->say(kStringMuseum6); + _gm->reply(kStringMuseum7, 1, 1 + 128); + } + _vm->paletteFadeOut(); + _gm->changeRoom(CITY2); + _gm->_newRoom = true; + _gm->drawGUI(); + } setRoomSeen(true); } void Museum::animation() { + _gm->drawClock(); + _gm->setAnimationTimer(11); } bool Museum::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_WALK && obj1._id == MUS_STREET) { + if (!_gm->_state._alarmOn && + !(_gm->_rooms[MUS_RUND]->getObject(4)->_type & CARRIED)) { + _vm->renderMessage(kStringMuseum10); + } else { + _gm->_state._eventTime = kMaxTimerValue; + if (!_gm->_state._alarmOn) { + _vm->renderMessage(kStringMuseum11); + if (_gm->_state._sirenOn) { + _vm->stopSound(); + _gm->_state._sirenOn = false; + } + } else + _vm->renderMessage(kStringMuseum12); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->paletteFadeOut(); + _vm->_system->fillScreen(kColorBlack); + _vm->_screen->setViewportBrightness(255); + _vm->renderMessage(kStringMuseum13); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->_screen->setViewportBrightness(0); + _vm->loadGame(kSleepAutosaveSlot); + if (_gm->_state._money >= 8) + _gm->takeMoney(-8); + if (_gm->_rooms[MUS_RUND]->getObject(4)->_type & CARRIED) + _gm->takeObject(*_gm->_rooms[INTRO]->getObject(7)); + _gm->changeRoom(CULTURE_PALACE); + _gm->_newRoom = true; + _gm->_state._alarmOn = false; + _gm->_state._haste = false; + _gm->drawGUI(); + } + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, SP_KEYCARD, DOOR) && + !(_objectState[2]._type & OPENED)) { + if (_gm->crackDoor(20)) { + _vm->renderImage(1); + _objectState[2]._type = EXIT | OPENABLE | OPENED; + _vm->playSound(kAudioTaxiOpen); + } + } else if (verb == ACTION_CLOSE && obj1._id == DOOR && (obj1._type & OPENED)) { + _vm->renderImage(1 + 128); + _objectState[2]._type = EXIT | OPENABLE | CLOSED; + _vm->playSound(kAudioElevator1); + } else if (verb == ACTION_USE && + Object::combine(obj1, obj2, SP_KEYCARD, BIG_DOOR)) { + _vm->renderMessage(kStringMuseum14); + } else if (verb == ACTION_WALK && obj1._id == DOOR) { + _gm->_state._haste = true; + return false; + } else + return false; return true; } diff --git a/engines/supernova2/sound.h b/engines/supernova2/sound.h index ac65b19d0b..17555c475f 100644 --- a/engines/supernova2/sound.h +++ b/engines/supernova2/sound.h @@ -49,6 +49,7 @@ enum AudioId { kAudioShip3, kAudioShipDeath, kAudioDeath, + kAudioCaught, kAudioNumSamples }; diff --git a/engines/supernova2/state.cpp b/engines/supernova2/state.cpp index 69eadc55c5..3cb268a448 100644 --- a/engines/supernova2/state.cpp +++ b/engines/supernova2/state.cpp @@ -49,9 +49,14 @@ bool GameManager::serialize(Common::WriteStream *out) { out->writeSint16LE(_state._pyraE); out->writeByte(_state._pyraS); out->writeByte(_state._pyraZ); + out->writeByte(_state._alarmOn); + out->writeByte(_state._alarmCracked); + out->writeByte(_state._haste); + out->writeByte(_state._sirenOn); out->writeSint16LE(_state._pyraDirection); out->writeUint32LE(_state._eventTime); out->writeSint32LE(_state._eventCallback); + out->writeByte(_state._taxiPossibility); for (int i = 0; i < 15; i++) { out->writeSint16LE(_state._puzzleTab[i]); } @@ -94,9 +99,14 @@ bool GameManager::deserialize(Common::ReadStream *in, int version) { _state._pyraE = in->readSint16LE(); _state._pyraS = in->readByte(); _state._pyraZ = in->readByte(); + _state._alarmOn = in->readByte(); + _state._alarmCracked = in->readByte(); + _state._haste = in->readByte(); + _state._sirenOn = in->readByte(); _state._pyraDirection = in->readSint16LE(); _state._eventTime = in->readUint32LE(); _state._eventCallback = (EventFunction)in->readSint32LE(); + _state._taxiPossibility = in->readByte(); for (int i = 0; i < 15; i++) _state._puzzleTab[i] = in->readSint16LE(); _vm->setGameString(kStringMoney, Common::String::format("%d Xa", _state._money)); @@ -345,7 +355,13 @@ void GameManager::initState() { _timePaused = false; _messageDuration = 0; _animationTimer = 0; - _taxi_possibility = 4; + _mapOn = false; + _steps = false; + _cracking = false; + _alarmBefore = false; + RoomId startSecurityTab[10] = {MUS6, MUS7, MUS11, MUS10, MUS3, MUS2, MUS1, MUS8, MUS9, MUS5}; + for (int i = 0; i < 10; i++) + _securityTab[i] = startSecurityTab[i]; _currentSentence = -1; for (int i = 0 ; i < 6 ; ++i) { @@ -372,9 +388,14 @@ void GameManager::initState() { _state._pyraE = 0; _state._pyraS = 4; _state._pyraZ = 10; + _state._alarmOn = false; + _state._alarmCracked = false; + _state._haste = false; + _state._sirenOn = false; _state._pyraDirection = 0; _state._eventTime = kMaxTimerValue; _state._eventCallback = kNoFn; + _state._taxiPossibility = 4; int16 startPuzzleTab[15] = {12, 3, 14, 1, 11, 0, 2, 13, 9, 5, 4, 10, 7, 6, 8}; for (int i = 0; i < 15; i++) _state._puzzleTab[i] = startPuzzleTab[i]; @@ -516,6 +537,9 @@ void GameManager::updateEvents() { case kPyramidEndFn: pyramidEnd(); break; + case kCaughtFn: + caught(); + break; } _vm->_allowLoadGame = true; _vm->_allowSaveGame = true; @@ -1500,6 +1524,8 @@ void GameManager::handleInput() { void GameManager::executeRoom() { if (_currentRoom == _rooms[PUZZLE_FRONT]) puzzleConstruction(); + if (_state._sirenOn && !_vm->_sound->isPlaying()) + _vm->_sound->playSiren(); if (_processInput && !_vm->_screen->isMessageShown() && _guiEnabled) { handleInput(); if (_mouseClicked) { @@ -1520,7 +1546,10 @@ void GameManager::executeRoom() { g_system->fillScreen(kColorBlack); _vm->renderRoom(*_currentRoom); } - drawMapExits(); + if (_currentRoom->getId() < MUSEUM) + drawMapExits(); + else + drawClock(); drawInventory(); drawStatus(); drawCommandBox(); @@ -1626,7 +1655,7 @@ void GameManager::taxi() { kStringLeaveTaxi }; Common::String input; - int possibility = _taxi_possibility; + int possibility = _state._taxiPossibility; _state._previousRoom = _currentRoom; _currentRoom = _rooms[INTRO]; @@ -1643,7 +1672,7 @@ void GameManager::taxi() { _currentRoom->removeSentenceByMask(possibility, 1); switch (answer = dialog(6, _dials, dest, 1)) { case 3: - _taxi_possibility += 8; + _state._taxiPossibility += 8; possibility += 8; taxiUnknownDestination(); break; @@ -2022,5 +2051,134 @@ void GameManager::puzzleConstruction() { } } +void GameManager::alarm() { + _vm->_sound->playSiren(); + _state._sirenOn = true; + if (_vm->_screen->isMessageShown()) + _vm->removeMessage(); + _vm->renderMessage(kStringMuseum7); + _state._eventTime = g_system->getMillis() + 270; + _state._eventCallback = kCaughtFn; + _state._alarmOn = true; +} + +void GameManager::caught() { + if (_vm->_screen->isMessageShown()) + _vm->removeMessage(); + if (_currentRoom < _rooms[MUS1]) { + } else if (_currentRoom <= _rooms[MUS2]) { + _vm->renderImage( 8); + _vm->renderImage(18); + } else if (_currentRoom == _rooms[MUS3]) { + _vm->renderImage(12); + _vm->renderImage(30); + } else if (_currentRoom == _rooms[MUS4]) { + _vm->renderImage( 8); + _vm->renderImage(18); + } else if (_currentRoom == _rooms[MUS5]) { + _vm->renderImage( 9); + _vm->renderImage(29); + } else if (_currentRoom <= _rooms[MUS7]) { + _vm->renderImage( 7); + _vm->renderImage(17); + } else if (_currentRoom <= _rooms[MUS9]) { + _vm->renderImage( 1); + _vm->renderImage( 7); + } else if (_currentRoom <= _rooms[MUS11]) { + _vm->renderImage( 2); + _vm->renderImage( 8); + } + caught2(); +} + +void GameManager::caught2() { + _vm->renderMessage(kStringMuseum8); + _vm->playSound(kAudioCaught); + waitOnInput(_messageDuration); + _vm->removeMessage(); + _state._sirenOn = false; + _mapOn = false; + _state._haste = false; + dead(kStringMuseum9); +} + +void GameManager::drawClock() { + int time = (g_system->getMillis() - _state._startTime) / 700; + int second = time % 100; + Room *r; + if (!_mapOn) { + _vm->renderBox(281, 161, 39, 39, kColorWhite25); + char s[9] = "00"; + s[1] = time % 10 + 48; + time /= 10; + s[0] = time % 10 + 48; + time /= 10; + _vm->renderText(s, 293, 180, kColorWhite99); + strcpy(s, " 0:00"); + s[4] = time % 10 + 48; + time /= 10; + s[3] = time % 10 + 48; + time /= 10; + s[1] = time % 10 + 48; + time /= 10; + if (time) + s[0] = time % 10 + 48; + _vm->renderText(s, 285, 170, kColorWhite99); + } + if ((r = _rooms[_securityTab[second / 10]]) == _currentRoom) { + //arrow(); + _state._alarmCracked = false; + caught(); + } + for (int i = 0; i < 3; i++) { + Object *o = r->getObject(i); + if ((o->_id == DOOR || o->_id == ENCRYPTED_DOOR || o->_id == SMALL_DOOR) && + (o->_type & OPENED) && ! _state._alarmOn) + alarm(); + } + if (!_state._alarmOn && _currentRoom == _rooms[MUS4] && + second >= 21 && second <= 40) + alarm(); + if (_currentRoom == _rooms[MUS_EING] && second >= 22 && second <= 29) { + if (!_steps && !_state._alarmCracked) { + _steps = true; + _vm->renderMessage(kStringMuseum6); + } + } + else _steps = false; +} + +void GameManager::crack(int time) { + _alarmBefore = _state._alarmOn; + _cracking = true; + //hourglass + int t = 0; + int z; + int zv = 0; + do { + do { + wait(1); + } while ((z = (g_system->getMillis() - _state._startTime) / 700) == zv); + zv = z; + drawClock(); + t++; + } while (t < time && _state._alarmOn == _alarmBefore) ; + _cracking = false; + //arrow + if (_state._alarmOn == _alarmBefore) + _vm->removeMessage(); +} + +bool GameManager::crackDoor(int time) { + _vm->renderMessage(kStringMuseum15); + crack(time); + if (_state._alarmOn != _alarmBefore) { + waitOnInput(_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringMuseum16); + } + return !_state._alarmOn; +} + } diff --git a/engines/supernova2/state.h b/engines/supernova2/state.h index 8bd1a02c24..25b0cd91ec 100644 --- a/engines/supernova2/state.h +++ b/engines/supernova2/state.h @@ -41,7 +41,7 @@ struct ConstructionEntry { const int32 kMaxTimerValue = 0x7FFFFFFF; -enum EventFunction { kNoFn, kSoberFn, kPyramidEndFn}; +enum EventFunction { kNoFn, kSoberFn, kPyramidEndFn, kCaughtFn}; struct GameState { int16 _money; @@ -62,6 +62,11 @@ struct GameState { char _pyraZ; int16 _pyraDirection; int16 _puzzleTab[15]; + bool _alarmCracked; + bool _alarmOn; + bool _haste; + bool _sirenOn; + byte _taxiPossibility; }; class Inventory { @@ -178,9 +183,12 @@ public: byte _rows[6]; byte _rowsStart[6]; byte _dials[6]; - int _taxi_possibility; unsigned char _puzzleField[16]; - + bool _mapOn; + bool _steps; + bool _cracking; + bool _alarmBefore; + RoomId _securityTab[10]; void takeObject(Object &obj); void setObjectNull(Object *&obj); @@ -237,6 +245,12 @@ public: bool move(Action verb, Object &obj); void compass(); void puzzleConstruction(); + void drawClock(); + void caught(); + void caught2(); + void alarm(); + void crack(int time); + bool crackDoor(int time); private: int _prevImgId; |