diff options
author | Jaromir Wysoglad | 2019-06-21 22:30:43 +0200 |
---|---|---|
committer | Thierry Crozat | 2019-07-28 15:09:14 +0100 |
commit | 3cf9cfbf78433e81ac5dcc39b31f5fa76983bde4 (patch) | |
tree | 883aacdbb2473884e15fc81c8f20fda6316a2850 | |
parent | eb2a017a68e965b46881a2b41d9178d5e20b05b2 (diff) | |
download | scummvm-rg350-3cf9cfbf78433e81ac5dcc39b31f5fa76983bde4.tar.gz scummvm-rg350-3cf9cfbf78433e81ac5dcc39b31f5fa76983bde4.tar.bz2 scummvm-rg350-3cf9cfbf78433e81ac5dcc39b31f5fa76983bde4.zip |
SUPERNOVA: Merge in the supernova2 engine.
24 files changed, 8046 insertions, 294 deletions
diff --git a/engines/supernova/detection.cpp b/engines/supernova/detection.cpp index 0dc210e744..b68c44cdff 100644 --- a/engines/supernova/detection.cpp +++ b/engines/supernova/detection.cpp @@ -31,6 +31,7 @@ static const PlainGameDescriptor supernovaGames[] = { {"msn1", "Mission Supernova 1"}, + {"msn2", "Mission Supernova 2"}, {nullptr, nullptr} }; @@ -55,6 +56,25 @@ static const ADGameDescription gameDescriptions[] = { ADGF_UNSTABLE, GUIO1(GUIO_NONE) }, + // Mission Supernova 2 + { + "msn2", + nullptr, + AD_ENTRY1s("ms2_data.000", "e595610cba4a6d24a763e428d05cc83f", 24805), + Common::DE_DEU, + Common::kPlatformDOS, + ADGF_UNSTABLE, + GUIO1(GUIO_NONE) + }, + { + "msn2", + nullptr, + AD_ENTRY1s("ms2_data.000", "e595610cba4a6d24a763e428d05cc83f", 24805), + Common::EN_ANY, + Common::kPlatformDOS, + ADGF_UNSTABLE, + GUIO1(GUIO_NONE) + }, AD_TABLE_END_MARKER }; } @@ -114,7 +134,11 @@ bool SupernovaMetaEngine::createInstance(OSystem *syst, Engine **engine, const A SaveStateList SupernovaMetaEngine::listSaves(const char *target) const { Common::StringArray filenames; - Common::String pattern("msn_save.###"); + Common::String pattern; + if (!strcmp(target, "msn1")) + pattern = Common::String::format("msn_save.###"); + if (!strcmp(target, "msn2")) + pattern = Common::String::format("ms2_save.###"); filenames = g_system->getSavefileManager()->listSavefiles(pattern); @@ -126,7 +150,8 @@ SaveStateList SupernovaMetaEngine::listSaves(const char *target) const { Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(*file); if (savefile) { uint saveHeader = savefile->readUint32LE(); - if (saveHeader == SAVEGAME_HEADER) { + if ((saveHeader == SAVEGAME_HEADER && !strcmp(target, "msn1")) || + (saveHeader == SAVEGAME_HEADER2 && !strcmp(target, "msn2"))) { byte saveVersion = savefile->readByte(); if (saveVersion <= SAVEGAME_VERSION) { int saveFileDescSize = savefile->readSint16LE(); @@ -146,17 +171,26 @@ SaveStateList SupernovaMetaEngine::listSaves(const char *target) const { } void SupernovaMetaEngine::removeSaveState(const char *target, int slot) const { - Common::String filename = Common::String::format("msn_save.%03d", slot); + Common::String filename; + if (!strcmp(target, "msn1")) + filename = Common::String::format("msn_save.%03d", slot); + if (!strcmp(target, "msn2")) + filename = Common::String::format("ms2_save.%03d", slot); g_system->getSavefileManager()->removeSavefile(filename); } SaveStateDescriptor SupernovaMetaEngine::querySaveMetaInfos(const char *target, int slot) const { - Common::String fileName = Common::String::format("msn_save.%03d", slot); + Common::String fileName; + if (!strcmp(target, "msn1")) + fileName = Common::String::format("msn_save.%03d", slot); + if (!strcmp(target, "msn2")) + fileName = Common::String::format("ms2_save.%03d", slot); Common::InSaveFile *savefile = g_system->getSavefileManager()->openForLoading(fileName); if (savefile) { uint saveHeader = savefile->readUint32LE(); - if (saveHeader != SAVEGAME_HEADER) { + if ((!strcmp(target, "msn1") && saveHeader != SAVEGAME_HEADER) || + (!strcmp(target, "msn2") && saveHeader != SAVEGAME_HEADER2)) { delete savefile; return SaveStateDescriptor(); } diff --git a/engines/supernova/game-manager.cpp b/engines/supernova/game-manager.cpp index 99d9215649..6aae050bb8 100644 --- a/engines/supernova/game-manager.cpp +++ b/engines/supernova/game-manager.cpp @@ -140,12 +140,12 @@ void GuiElement::setHighlight(bool isHighlighted_) { } } -StringId GameManager::guiCommands[] = { +int GameManager::guiCommands[] = { kStringCommandGo, kStringCommandLook, kStringCommandTake, kStringCommandOpen, kStringCommandClose, kStringCommandPress, kStringCommandPull, kStringCommandUse, kStringCommandTalk, kStringCommandGive }; -StringId GameManager::guiStatusCommands[] = { +int GameManager::guiStatusCommands[] = { kStringStatusCommandGo, kStringStatusCommandLook, kStringStatusCommandTake, kStringStatusCommandOpen, kStringStatusCommandClose, kStringStatusCommandPress, kStringStatusCommandPull, kStringStatusCommandUse, kStringStatusCommandTalk, kStringStatusCommandGive }; @@ -480,7 +480,7 @@ void GameManager::sentence(int number, bool brightness) { } } -void GameManager::say(StringId textId) { +void GameManager::say(int textId) { Common::String str = _vm->getGameString(textId); if (!str.empty()) say(str.c_str()); @@ -510,7 +510,7 @@ void GameManager::say(const char *text) { _vm->renderBox(0, 138, 320, 62, kColorBlack); } -void GameManager::reply(StringId textId, int aus1, int aus2) { +void GameManager::reply(int textId, int aus1, int aus2) { Common::String str = _vm->getGameString(textId); if (!str.empty()) reply(str.c_str(), aus1, aus2); @@ -536,7 +536,7 @@ void GameManager::reply(const char *text, int aus1, int aus2) { _vm->removeMessage(); } -int GameManager::dialog(int num, byte rowLength[6], StringId text[6], int number) { +int GameManager::dialog(int num, byte rowLength[6], int text[6], int number) { _vm->_allowLoadGame = false; _guiEnabled = false; @@ -769,9 +769,14 @@ void GameManager::edit(Common::String &input, int x, int y, uint length) { bool isEditing = true; uint cursorIndex = input.size(); // NOTE: Pixels for char needed = kFontWidth + 2px left and right side bearing - int overdrawWidth = ((int)((length + 1) * (kFontWidth + 2)) > (kScreenWidth - x)) ? - kScreenWidth - x : (length + 1) * (kFontWidth + 2); + int overdrawWidth; + if (_vm->_MSPart == 1) + overdrawWidth = ((int)((length + 1) * (kFontWidth + 2)) > (kScreenWidth - x)) ? + kScreenWidth - x : (length + 1) * (kFontWidth + 2); + else if (_vm->_MSPart == 2) + overdrawWidth = ((int)((length + 1) * (kFontWidth2 + 2)) > (kScreenWidth - x)) + ? kScreenWidth - x : (length + 1) * (kFontWidth2 + 2); _guiEnabled = false; while (isEditing) { _vm->_screen->setTextCursorPos(x, y); @@ -788,10 +793,10 @@ void GameManager::edit(Common::String &input, int x, int y, uint length) { _vm->renderBox(_vm->_screen->getTextCursorPos().x, y - 1, Screen::textWidth(input[i]), 9, kColorWhite99); _vm->_screen->setTextCursorColor(background); - _vm->renderText(input[i]); + _vm->renderText((uint16)input[i]); _vm->_screen->setTextCursorColor(kColorWhite99); } else - _vm->renderText(input[i]); + _vm->renderText((uint16)input[i]); } if (cursorIndex == input.size()) { @@ -860,7 +865,7 @@ void GameManager::drawStatus() { } } -void GameManager::dead(StringId messageId) { +void GameManager::dead(int messageId) { _vm->paletteFadeOut(); _guiEnabled = false; if (_vm->_MSPart == 1) @@ -869,7 +874,10 @@ void GameManager::dead(StringId messageId) { _vm->setCurrentImage(43); _vm->renderImage(0); _vm->renderMessage(messageId); - _sound->play(kAudioDeath); + if (_vm->_MSPart == 1) + _sound->play(kAudioDeath); + else if (_vm->_MSPart == 2) + _sound->play(kAudioDeath2); _vm->paletteFadeIn(); getInput(); _vm->paletteFadeOut(); @@ -881,7 +889,7 @@ void GameManager::dead(StringId messageId) { if (_vm->_MSPart == 1) changeRoom(CABIN_R3); else if (_vm->_MSPart == 2) - changeRoom(CABIN_R3); + changeRoom(AIRPORT); initGui(); _inventory.clear(); g_system->fillScreen(kColorBlack); diff --git a/engines/supernova/game-manager.h b/engines/supernova/game-manager.h index 26c7a9eba4..5ee747f934 100644 --- a/engines/supernova/game-manager.h +++ b/engines/supernova/game-manager.h @@ -111,8 +111,8 @@ public: virtual bool serialize(Common::WriteStream *out); virtual bool deserialize(Common::ReadStream *in, int version); - static StringId guiCommands[]; - static StringId guiStatusCommands[]; + static int guiCommands[]; + static int guiStatusCommands[]; SupernovaEngine *_vm; Sound *_sound; Common::KeyState _key; @@ -125,7 +125,7 @@ public: Room *_currentRoom; Room *_lastRoom; bool _newRoom; - Room *_rooms[NUMROOMS]; + Room **_rooms; Inventory _inventory; bool _processInput; bool _guiEnabled; @@ -148,7 +148,7 @@ public: // Dialog int _currentSentence; int _sentenceNumber[6]; - StringId _texts[6]; + int _texts[6]; byte _rows[6]; byte _rowsStart[6]; int32 _time; @@ -189,12 +189,12 @@ public: virtual void loadTime(); virtual void saveTime(); void setAnimationTimer(int ticks); - void dead(StringId messageId); - int dialog(int num, byte rowLength[6], StringId text[6], int number); + void dead(int messageId); + int dialog(int num, byte rowLength[6], int text[6], int number); void sentence(int number, bool brightness); - void say(StringId textId); + void say(int textId); void say(const char *text); - void reply(StringId textId, int aus1, int aus2); + void reply(int textId, int aus1, int aus2); void reply(const char *text, int aus1, int aus2); void mousePosDialog(int x, int y); virtual void takeMoney(int amount); diff --git a/engines/supernova/module.mk b/engines/supernova/module.mk index 2665af4848..ae8a71abf8 100644 --- a/engines/supernova/module.mk +++ b/engines/supernova/module.mk @@ -7,10 +7,12 @@ MODULE_OBJS := \ resman.o \ room.o \ supernova1/rooms.o \ + supernova2/rooms.o \ screen.o \ sound.o \ game-manager.o \ supernova1/state.o \ + supernova2/state.o \ supernova.o MODULE_DIRS += \ diff --git a/engines/supernova/msn_def.h b/engines/supernova/msn_def.h index 5c3ee1f8a6..eebffc34cd 100644 --- a/engines/supernova/msn_def.h +++ b/engines/supernova/msn_def.h @@ -32,7 +32,7 @@ const int kMsecPerTick = 55; const int kMaxSection = 40; const int kMaxDialog = 2; -const int kMaxObject = 25; +const int kMaxObject = 30; const int kMaxCarry = 30; const int kSleepAutosaveSlot = 999; @@ -80,7 +80,8 @@ enum Action { }; enum RoomId { - INTRO,CORRIDOR,HALL,SLEEP,COCKPIT,AIRLOCK, + // Supernova 1 + INTRO1,CORRIDOR_ROOM,HALL,SLEEP,COCKPIT,AIRLOCK, HOLD,LANDINGMODULE,GENERATOR,OUTSIDE, CABIN_R1,CABIN_R2,CABIN_R3,CABIN_L1,CABIN_L2,CABIN_L3,BATHROOM, @@ -88,12 +89,31 @@ enum RoomId { CELL,CORRIDOR1,CORRIDOR2,CORRIDOR3,CORRIDOR4,CORRIDOR5,CORRIDOR6,CORRIDOR7,CORRIDOR8,CORRIDOR9, BCORRIDOR,GUARD,GUARD3,OFFICE_L1,OFFICE_L2,OFFICE_R1,OFFICE_R2,OFFICE_L, - ELEVATOR,STATION,SIGN,OUTRO,NUMROOMS,NULLROOM + ELEVATOR,STATION,SIGN_ROOM,OUTRO,NUMROOMS1, + + // Supernova 2 + INTRO2 = 0,AIRPORT,TAXISTAND,STREET,GAMES,CABIN2,KIOSK, + CULTURE_PALACE,CHECKOUT,CITY1,CITY2,ELEVATOR2,APARTMENT,SHIP, + + PYRAMID,PYR_ENTRANCE,UPSTAIRS1,DOWNSTAIRS1, + BOTTOM_RIGHT_DOOR,BOTTOM_LEFT_DOOR,UPSTAIRS2,DOWNSTAIRS2, + UPPER_DOOR,PUZZLE_FRONT,PUZZLE_BEHIND, + FORMULA1_F,FORMULA1_N,FORMULA2_F,FORMULA2_N,TOMATO_F,TOMATO_N, + MONSTER_F,MONSTER1_N,MONSTER2_N,UPSTAIRS3,DOWNSTAIRS3, + LCORRIDOR1,LCORRIDOR2,HOLE_ROOM,IN_HOLE,FLOORDOOR,FLOORDOOR_U, + BST_DOOR,HALL2,COFFIN_ROOM,MASK, + + MUSEUM,MUS_ENTRANCE,MUS1,MUS2,MUS3,MUS4,MUS5,MUS6,MUS7,MUS8, + MUS9,MUS10,MUS11,MUS_ROUND, + MUS12,MUS13,MUS14,MUS15,MUS16,MUS17,MUS18,MUS19,MUS20,MUS21,MUS22, + NUMROOMS2,NULLROOM }; enum ObjectId { INVALIDOBJECT = -1, NULLOBJECT = 0, + + // Supernova 1 KEYCARD,KNIFE,WATCH, SOCKET, BUTTON,HATCH1, @@ -132,7 +152,32 @@ enum ObjectId { PILLAR1,PILLAR2,DOOR1,DOOR2,DOOR3,DOOR4, GUARDIAN,LAMP, MASTERKEYCARD,PAINTING,MONEY,LOCKER,LETTER, - JUNGLE,STATION_SLOT,STATION_SIGN + JUNGLE,STATION_SLOT,STATION_SIGN, + + + // Supernova2 + TAXI,TRANSMITTER,ROD,OCCUPIED_CABIN, + SLOT1,CHAIR,CORRIDOR,G_RIGHT,G_LEFT,PYRA_ENTRANCE, + PART0,PART1,PART2,PART3,PART4,PART5,PART6,PART7, + PART8,PART9,PART10,PART11,PART12,PART13,PART14,PART15, + TKNIFE,NOTE,MOUTH, + HOLE1,HOLE2,HOLE3,HOLE4,HOLE5,HOLE6,HOLE7,HOLE8,HOLE9,HOLE10, + HOLE11,HOLE12,HOLE13,HOLE14,HOLE15,HOLE16,HOLE17,HOLE18,HOLE19,HOLE20, + HOLE21,HOLE22,HOLE23,HOLE24,HOLE25,SIGN, + SLOT,HOLE,STONES, + BST1,BST2,BST3,BST4,BST5,BST6,BST7,BST8, + BST9,BST10,BST11,BST12,BST13,BST14,BST15,BST16, + COFFIN,SUN,MONSTER,EYE,EYE1,EYE2,L_BALL,R_BALL, + PRIZE,REAR_STREET, + BMASK,BOTTLE,PLAYER,TOOTHBRUSH,BOOKS,LEXICON,PLANT,SNAKE, + JOYSTICK,BOTTLE1,BOTTLE2,BOTTLE3,BOTTLE4,BOX,FACES, + SELLER,POSTER,AXACUSSER,KP_ENTRANCE,CHIP,CARD, + SCRIBBLE1,SCRIBBLE2,BELL,KEYPAD,DOOR_L,DOOR_R,ID_CARD, + UNDER_BED,KEY,HATCH,CABINET, + SMALL_DOOR,BACK_MONEY,WALL,SUCTION_CUP,IMITATION,SP_KEYCARD,ALARM_CRACKER, + ENCRYPTED_DOOR,ALARM_SYSTEM,MUS_STREET,BIG_DOOR,MUSIC_SYSTEM, + HANDLE,SWITCH,DOOR_SWITCH,CABLE,RCABLE, + MUSCARD,HEAD, DISPLAY }; enum StringId { @@ -141,162 +186,7 @@ enum StringId { kStringCommandGo = 0, kStringCommandLook, kStringCommandTake, kStringCommandOpen, kStringCommandClose, kStringCommandPress, kStringCommandPull, kStringCommandUse, kStringCommandTalk, kStringCommandGive, kStringStatusCommandGo, kStringStatusCommandLook, kStringStatusCommandTake, kStringStatusCommandOpen, kStringStatusCommandClose, - kStringStatusCommandPress, kStringStatusCommandPull, kStringStatusCommandUse, kStringStatusCommandTalk, kStringStatusCommandGive, - kStringTitleVersion, kStringTitle1, kStringTitle2, kStringTitle3, kStringIntro1, - kStringIntro2, kStringIntro3, kStringIntro4, kStringIntro5, kStringIntro6, - kStringIntro7, kStringIntro8, kStringIntro9, kStringIntro10, kStringIntro11, - kStringIntro12, kStringIntro13, kStringBroken, kStringDefaultDescription, kStringTakeMessage, - kStringKeycard, kStringKeycardDescription, kStringKnife, kStringKnifeDescription, kStringWatch, - kStringDiscman, kStringDiscmanDescription, kStringHatch, kStringButton, kStringHatchButtonDescription, - // 50 - kStringLadder, kStringExit, kStringCockpitHatchDescription, kStringKitchenHatchDescription, kStringStasisHatchDescription, - kStringStasisHatchDescription2, kStringSlot, kStringSlotDescription, kStringCorridor, kStringComputer, - kStringComputerPassword, kStringInstruments, kStringInstrumentsDescription1, kStringMonitor, kStringMonitorDescription, - kStringImage, kStringGenericDescription1, kStringGenericDescription2, kStringGenericDescription3, kStringGenericDescription4, - kStringMagnete, kStringMagneteDescription, kStringPen, kStringPenDescription, kStringShelf, - kStringCompartment, kStringSocket, kStringToilet, kStringPistol, kStringPistolDescription, - kStringBooks, kStringBooksDescription, kStringSpool, kStringSpoolDescription, kStringBook, - kStringUnderwear, kStringUnderwearDescription, kStringClothes, kStringJunk, kStringJunkDescription, - kStringFolders, kStringFoldersDescription, kStringPoster, kStringPosterDescription1, kStringPosterDescription2, - kStringSpeaker, kStringRecord, kStringRecordDescription, kStringRecordStand, kStringRecordStandDescription, - // 100 - kStringTurntable, kStringTurntableDescription, kStringWire, kStringPlug, kStringImageDescription1, - kStringDrawingInstruments, kStringDrawingInstrumentsDescription, kStringChessGame, kStringChessGameDescription1, kStringTennisRacket, - kStringTennisRacketDescription, kStringTennisBall, kStringChessGameDescription2, kStringBed, kStringBedDescription, - kStringCompartmentDescription, kStringAlbums, kStringAlbumsDescription, kStringRope, kStringRopeDescription, - kStringShelfDescription, kStringClothesDescription, kStringSocks, kStringBookHitchhiker, kStringBathroom, - kStringBathroomDescription, kStringShower, kStringHatchDescription1, kStringHatchDescription2, kStringHelmet, - kStringHelmetDescription, kStringSuit, kStringSuitDescription, kStringLifeSupport, kStringLifeSupportDescription, - kStringScrap, kStringScrapDescription1, kStringTerminalStrip, kStringScrapDescription2, kStringReactor, - kStringReactorDescription, kStringNozzle, kStringPumpkin, kStringPumpkinDescription, kStringLandingModule, - kStringLandingModuleDescription, kStringHatchDescription3, kStringGenerator, kStringGeneratorDescription, kStringScrapDescription3, - // 150 - kSafetyButtonDescription, kStringKeyboard, kStringGeneratorWire, kStringEmptySpool, kStringKeycard2, - kStringKeycard2Description, kStringTrap, kStringVoltmeter, kStringClip, kStringWireDescription, - kStringStone, kStringCaveOpening, kStringCaveOpeningDescription, kStringExitDescription, kStringCave, - kStringSign, kStringSignDescription, kStringEntrance, kStringStar, kStringSpaceshift, - kStringPorter, kStringPorterDescription, kStringDoor, kStringChewingGum, kStringGummyBears, - kStringChocolateBall, kStringEgg, kStringLiquorice, kStringPill, kStringPillDescription, - kStringVendingMachine, kStringVendingMachineDescription, kStringToiletDescription, kStringStaircase, kStringCoins, - kStringCoinsDescription, kStringTabletPackage, kStringTabletPackageDescription, kStringChair, kStringShoes, - kStringShoesDescription, kStringFrogFace, kStringScrible, kStringScribleDescription, kStringWallet, - kStringMenu, kStringMenuDescription, kStringCup, kStringCupDescription, kStringBill, - // 200 - kStringBillDescription, kStringKeycard3, kStringAnnouncement, kStringAnnouncementDescription, kStringRoger, - kStringUfo, kStringUfoDescription, kStringTray, kStringTrayDescription, kStringLamp, - kStringLampDescription, kStringEyes, kStringEyesDescription, kStringSocketDescription, kStringMetalBlock, - kStringMetalBlockDescription, kStringRobot, kStringRobotDescription, kStringTable, kStringTableDescription, - kStringCellDoor, kStringCellDoorDescription, kStringLaptop, kStringWristwatch, kStringPillar, - kStringDoorDescription1, kStringDoorDescription2, kStringDoorDescription3, kStringDoorDescription4, kStringDontEnter, - kStringAxacussan, kStringAxacussanDescription, kStringImageDescription2, kStringMastercard, kStringMastercardDescription, - kStringLamp2, kStringGenericDescription5, kStringMoney, kStringMoneyDescription1, kStringLocker, - kStringLockerDescription, kStringLetter, kStringCube, kStringGenericDescription6, kStringGenericDescription7, - kStringStrangeThing, kStringGenericDescription8, kStringImageDescription3, kStringPlant, kStringStatue, - // 250 - kStringStatueDescription, kStringPlantDescription, kStringComputerDescription, kStringGraffiti, kStringGraffitiDescription, - kStringMoneyDescription2, kStringJungle, kStringJungleDescription, kStringOutro1, kStringOutro2, - kStringOutro3, kStringOutro4, kStringOutro5, kStringOutro6, kStringOutro7, - kStringOutro8, kStringOutro9, kStringOutro10, kStringOutro11, kStringOutro12, - kStringOutro13, kStringOutro14, kStringWireAndPlug, kStringWireAndClip, kStringWireAndPlug2, - // 275 - kStringSignDescription2, kStringCoin, kStringDoorDescription5, kStringDoorDescription6, kStringKeycard2Description2, - kSringSpoolAndClip, kStringIntroCutscene1, kStringIntroCutscene2, kStringIntroCutscene3, kStringIntroCutscene4, - kStringIntroCutscene5, kStringIntroCutscene6, kStringIntroCutscene7, kStringIntroCutscene8, kStringIntroCutscene9, - kStringIntroCutscene10, kStringIntroCutscene11, kStringIntroCutscene12, kStringIntroCutscene13, kStringIntroCutscene14, - kStringIntroCutscene15, kStringIntroCutscene16, kStringIntroCutscene17, kStringIntroCutscene18, kStringIntroCutscene19, - // 300 - kStringIntroCutscene20, kStringIntroCutscene21, kStringIntroCutscene22, kStringIntroCutscene23, kStringIntroCutscene24, - kStringIntroCutscene25, kStringIntroCutscene26, kStringIntroCutscene27, kStringIntroCutscene28, kStringIntroCutscene29, - kStringIntroCutscene30, kStringIntroCutscene31, kStringIntroCutscene32, kStringIntroCutscene33, kStringIntroCutscene34, - kStringIntroCutscene35, kStringIntroCutscene36, kStringIntroCutscene37, kStringIntroCutscene38, kStringIntroCutscene39, - kStringIntroCutscene40, kStringIntroCutscene41, kStringIntroCutscene42, kStringShipHall1, kStringShipSleepCabin1, - //325 - kStringShipSleepCabin2, kStringShipSleepCabin3, kStringShipSleepCabin4, kStringShipSleepCabin5, kStringShipSleepCabin6, - kStringShipSleepCabin7, kStringShipSleepCabin8, kStringShipSleepCabin9, kStringShipSleepCabin10, kStringShipSleepCabin11, - kStringShipSleepCabin12, kStringShipSleepCabin13, kStringShipSleepCabin14, kStringShipSleepCabin15, kStringShipSleepCabin16, - kStringShipCockpit1, kStringShipCockpit2, kStringShipCockpit3, kStringShipCockpit4, kStringShipCockpit5, - kStringShipCockpit6, kStringShipCockpit7, kStringShipCockpit8, kStringShipCockpit9, kStringShipCockpit10, - // 350 - kStringShipCockpit11, kStringShipCockpit12, kStringShipCockpit13, kStringShipCabinL3_1, kStringShipCabinL3_2, - kStringShipCabinL3_3, kStringShipCabinL3_4, kStringShipCabinL3_5, kStringShipAirlock1, kStringShipAirlock2, - kStringShipAirlock3, kStringShipAirlock4, kStringShipHold1, kStringCable1, kStringCable2, - kStringCable3, kStringCable4, kStringShipHold2, kStringShipHold3, kStringShipHold4, - kStringShipHold5, kStringShipHold6, kStringShipHold7, kStringShipHold8, kStringShipHold9, - // 375 - kStringShipHold10, kStringShipHold11, kStringShipHold12, kStringShipHold13, kStringShipHold14, - kStringShipHold15, kStringShipHold16, kStringArsanoMeetup1, kStringArsanoMeetup2, kStringArsanoMeetup3, - kStringArsanoEntrance1, kStringArsanoEntrance2, kStringArsanoEntrance3, kStringArsanoEntrance4, kStringArsanoEntrance5, - kStringArsanoEntrance6, kStringArsanoEntrance7, kStringArsanoEntrance8, kStringArsanoEntrance9, kStringArsanoEntrance10, - kStringArsanoEntrance11, kStringArsanoEntrance12, kStringArsanoEntrance13, kStringArsanoEntrance14, kStringArsanoEntrance15, - // 400 - kStringArsanoEntrance16, kStringArsanoEntrance17, kStringArsanoEntrance18, kStringArsanoEntrance19, kStringArsanoEntrance20, - kStringArsanoEntrance21, kStringArsanoEntrance22, kStringArsanoEntrance23, kStringArsanoEntrance24, kStringArsanoEntrance25, - kStringArsanoEntrance26, kStringArsanoEntrance27, kStringArsanoDialog1, kStringArsanoDialog2, kStringArsanoDialog3, - kStringArsanoDialog4, kStringArsanoDialog5, kStringArsanoDialog6, kStringArsanoDialog7, kStringArsanoDialog8, - kStringArsanoDialog9, kStringDialogSeparator, kStringDialogArsanoRoger1, kStringDialogArsanoRoger2, kStringDialogArsanoRoger3, - // 425 - kStringDialogArsanoMeetup3_1, kStringDialogArsanoMeetup3_2, kStringDialogArsanoMeetup3_3, kStringDialogArsanoMeetup3_4, kStringDialogArsanoMeetup3_5, - kStringArsanoRoger1, kStringArsanoRoger2, kStringArsanoRoger3, kStringArsanoRoger4, kStringArsanoRoger5, - kStringArsanoRoger6, kStringArsanoRoger7, kStringArsanoRoger8, kStringArsanoRoger9, kStringArsanoRoger10, - kStringArsanoRoger11, kStringArsanoRoger12, kStringArsanoRoger13, kStringArsanoRoger14, kStringArsanoRoger15, - kStringArsanoRoger16, kStringArsanoRoger17, kStringArsanoRoger18, kStringArsanoRoger19, kStringArsanoRoger20, - // 450 - kStringArsanoRoger21, kStringArsanoRoger22, kStringArsanoRoger23, kStringArsanoRoger24, kStringArsanoRoger25, - kStringArsanoRoger26, kStringArsanoRoger27, kStringArsanoRoger28, kStringArsanoRoger29, kStringArsanoRoger30, - kStringArsanoRoger31, kStringArsanoRoger32, kStringArsanoRoger33, kStringArsanoRoger34, kStringArsanoRoger35, - kStringArsanoRoger36, kStringArsanoRoger37, kStringArsanoRoger38, kStringArsanoRoger39, kStringArsanoRoger40, - kStringArsanoGlider1, kStringArsanoMeetup2_1, kStringArsanoMeetup2_2, kStringArsanoMeetup2_3, kStringArsanoMeetup2_4, - // 475 - kStringArsanoMeetup2_5, kStringArsanoMeetup2_6, kStringArsanoMeetup2_7, kStringArsanoMeetup2_8, kStringArsanoMeetup2_9, - kStringArsanoMeetup2_10, kStringArsanoMeetup2_11, kStringArsanoMeetup2_12, kStringArsanoMeetup2_13, kStringArsanoMeetup3_1, - kStringArsanoMeetup3_2, kStringArsanoMeetup3_3, kStringArsanoMeetup3_4, kStringArsanoMeetup3_5, kStringArsanoMeetup3_6, - kStringArsanoMeetup3_7, kStringArsanoMeetup3_8, kStringArsanoMeetup3_9, kStringArsanoMeetup3_10, kStringArsanoMeetup3_11, - kStringArsanoMeetup3_12, kStringArsanoMeetup3_13, kStringArsanoMeetup3_14, kStringArsanoMeetup3_15, kStringArsanoMeetup3_16, - // 500 - kStringArsanoMeetup3_17, kStringArsanoMeetup3_18, kStringArsanoMeetup3_19, kStringArsanoMeetup3_20, kStringArsanoMeetup3_21, - kStringArsanoMeetup3_22, kStringArsanoMeetup3_23, kStringArsanoMeetup3_24, kStringArsanoMeetup3_25, kStringArsanoMeetup3_26, - kStringArsanoMeetup3_27, kStringArsanoMeetup3_28, kStringAxacussCell_1, kStringAxacussCell_2, kStringAxacussCell_3, - kStringAxacussCell_4, kStringAxacussCell_5, kStringOk, kStringDialogArsanoMeetup2_1, kStringDialogArsanoMeetup2_2, - kStringDialogArsanoMeetup2_3, kStringDialogArsanoMeetup2_4, kStringDialogArsanoMeetup2_5, kStringDialogArsanoMeetup2_6, kStringDialogArsanoMeetup2_7, - // 525 - kStringDialogArsanoMeetup2_8, kStringDialogArsanoMeetup2_9, kStringDialogArsanoMeetup2_10, kStringDialogArsanoMeetup2_11, kStringDialogAxacussCorridor5_1, - kStringDialogAxacussCorridor5_2, kStringDialogAxacussCorridor5_3, kStringDialogAxacussCorridor5_4, kStringDialogAxacussCorridor5_5, kStringDialogAxacussCorridor5_6, - kStringDialogAxacussCorridor5_7, kStringDialogX1, kStringDialogX2, kStringDialogX3, kStringAxacussCorridor5_1, - kStringAxacussCorridor5_2, kStringAxacussCorridor5_3, kStringAxacussCorridor5_4, kStringAxacussCorridor5_5, kStringAxacussCorridor5_6, - kStringAxacussCorridor5_7, kStringAxacussBcorridor_1, kStringAxacussOffice1_1, kStringAxacussOffice1_2, kStringAxacussOffice1_3, - // 550 - kStringAxacussOffice1_4, kStringAxacussOffice1_5, kStringAxacussOffice1_6, kStringAxacussOffice1_7, kStringAxacussOffice1_8, - kStringAxacussOffice1_9, kStringAxacussOffice1_10, kStringAxacussOffice1_11, kStringAxacussOffice1_12, kStringAxacussOffice1_13, - kStringAxacussOffice1_14, kStringAxacussOffice1_15, kStringAxacussOffice1_16, kStringAxacussOffice3_1, kStringAxacussElevator_1, - kStringAxacussElevator_2, kStringAxacussElevator_3, kStringShock, kStringShot, kStringCloseLocker_1, - kStringIsHelmetOff_1, kStringGenericInteract_1, kStringGenericInteract_2, kStringGenericInteract_3, kStringGenericInteract_4, - // 575 - kStringGenericInteract_5, kStringGenericInteract_6, kStringGenericInteract_7, kStringGenericInteract_8, kStringGenericInteract_9, - kStringGenericInteract_10, kStringGenericInteract_11, kStringGenericInteract_12, kPhrasalVerbParticleGiveTo, kPhrasalVerbParticleUseWith, - kStringGenericInteract_13, kStringGenericInteract_14, kStringGenericInteract_15, kStringGenericInteract_16, kStringGenericInteract_17, - kStringGenericInteract_18, kStringGenericInteract_19, kStringGenericInteract_20, kStringGenericInteract_21, kStringGenericInteract_22, - kStringGenericInteract_23, kStringGenericInteract_24, kStringGenericInteract_25, kStringGenericInteract_26, kStringGenericInteract_27, - // 600 - kStringGenericInteract_28, kStringGenericInteract_29, kStringGenericInteract_30, kStringGenericInteract_31, kStringGenericInteract_32, - kStringGenericInteract_33, kStringGenericInteract_34, kStringGenericInteract_35, kStringGenericInteract_36, kStringGenericInteract_37, - kStringGenericInteract_38, kStringGenericInteract_39, kStringGenericInteract_40, kStringGenericInteract_41, kStringGenericInteract_42, - kStringGenericInteract_43, kStringConversationEnd, kStringSupernova1, kStringSupernova2, kStringSupernova3, - kStringSupernova4, kStringSupernova5, kStringSupernova6, kStringSupernova7, kStringSupernova8, - // 625 - kStringTextSpeed, kStringGuardNoticed1, kStringGuardNoticed2, kStringTelomat1, kStringTelomat2, - kStringTelomat3, kStringTelomat4, kStringTelomat5, kStringTelomat6, kStringTelomat7, - kStringTelomat8, kStringTelomat9, kStringTelomat10, kStringTelomat11, kStringTelomat12, - kStringTelomat13, kStringTelomat14, kStringTelomat15, kStringTelomat16, kStringTelomat17, - kStringTelomat18, kStringTelomat19, kStringTelomat20, kStringTelomat21, kStringAlarm, - // 650 - kStringLeaveGame, kStringYes, kStringNo, kStringHelpOverview1, kStringHelpOverview2, - kStringHelpOverview3, kStringHelpOverview4, kStringHelpOverview5, kStringHelpOverview6, kStringHelpOverview7, - - // Add two placeholder strings at the end for variable text - kStringPlaceholder1, kStringPlaceholder2, - - // String for money in inventory - kStringInventoryMoney + kStringStatusCommandPress, kStringStatusCommandPull, kStringStatusCommandUse, kStringStatusCommandTalk, kStringStatusCommandGive, kPhrasalVerbParticleGiveTo, kPhrasalVerbParticleUseWith, kStringDefaultDescription, kStringDialogSeparator, kStringConversationEnd }; ObjectType operator|(ObjectType a, ObjectType b); @@ -319,7 +209,7 @@ struct Object { , _exitRoom(NULLROOM) , _direction(0) {} - Object(byte roomId, StringId name, StringId description, ObjectId id, ObjectType type, + Object(byte roomId, int name, int description, ObjectId id, ObjectType type, byte click, byte click2, byte section = 0, RoomId exitRoom = NULLROOM, byte direction = 0) : _name(name) , _description(description) @@ -358,8 +248,8 @@ struct Object { } byte _roomId; - StringId _name; - StringId _description; + int _name; + int _description; ObjectId _id; ObjectTypes _type; byte _click; diff --git a/engines/supernova/resman.cpp b/engines/supernova/resman.cpp index f2b9f312c9..9b89b10d7a 100644 --- a/engines/supernova/resman.cpp +++ b/engines/supernova/resman.cpp @@ -44,7 +44,8 @@ struct AudioInfo { static Common::MemoryReadStream *convertToMod(const char *filename, int version = 1); -static const AudioInfo audioInfo[kAudioNumSamples] = { +static const AudioInfo audioInfo[] = { + // Supernova 1 {44, 0, -1}, {45, 0, -1}, {46, 0, 2510}, @@ -64,7 +65,29 @@ static const AudioInfo audioInfo[kAudioNumSamples] = { {54, 8010, 24020}, {54, 24020, 30030}, {54, 30030, 31040}, - {54, 31040, -1} + {54, 31040, -1}, + + {0 , 0, 0}, + // Supernova 2 + {55, 18230, -1}, + {47, 0, 16010}, + {47, 16010, 17020}, + {49, 8010, -1}, + {49, 0, 8010}, + {53, 30020, -1}, + {55, 7010, 17020}, + {55, 0, 7010}, + {53, 5010, 30020}, + {55, 18230, -1}, + {55, 17020, 18230}, + {53, 0, 5010}, + {47, 17020, -1}, + {51, 9020, -1}, + {51, 0, 6010}, + {50, 0, -1}, + {51, 6010, 9020}, + {54, 0, -1}, + {48, 0, -1} }; static const byte mouseNormal[64] = { @@ -95,16 +118,25 @@ static const byte mouseWait[64] = { ResourceManager::ResourceManager(int MSPart) : _audioRate(11931) , _MSPart(MSPart) { - initSoundFiles(); + if (MSPart == 1) + initSoundFiles1(); + else if (MSPart == 2) + initSoundFiles2(); initGraphics(); } ResourceManager::~ResourceManager() { - for (int i = 0; i < kNumImageFiles; i++) - delete _images[i]; + if (_MSPart == 1) { + for (int i = 0; i < 44; i++) + delete _images[i]; + } + if (_MSPart == 2) { + for (int i = 0; i < 47; i++) + delete _images[i]; + } } -void ResourceManager::initSoundFiles() { +void ResourceManager::initSoundFiles1() { // Sound // Note: // - samples start with a header of 6 bytes: 01 SS SS 00 AD 00 @@ -113,7 +145,7 @@ void ResourceManager::initSoundFiles() { // Skip those in the buffer Common::File file; - for (int i = 0; i < kAudioNumSamples; ++i) { + for (int i = 0; i < kAudioNumSamples1; ++i) { if (!file.open(Common::String::format("msn_data.%03d", audioInfo[i]._filenumber))) { error("File %s could not be read!", file.getName()); } @@ -141,10 +173,51 @@ void ResourceManager::initSoundFiles() { _musicOutroBuffer.reset(convertToMod("msn_data.049")); } +void ResourceManager::initSoundFiles2() { + // Sound + // Note: + // - samples start with a header of 6 bytes: 01 SS SS 00 AD 00 + // where SS SS (LE uint16) is the size of the sound sample + 2 + // - samples end with a footer of 4 bytes: 00 00 + // Skip those in the buffer + Common::File file; + + for (int i = 0; i < kAudioNumSamples2 - kAudioNumSamples1 - 1; ++i) { + if (!file.open(Common::String::format("ms2_data.%03d", audioInfo[i + kAudioNumSamples1 + 1]._filenumber))) { + error("File %s could not be read!", file.getName()); + } + + int length = 0; + byte *buffer = nullptr; + + if (audioInfo[i + kAudioNumSamples1 + 1]._offsetEnd == -1) { + file.seek(0, SEEK_END); + length = file.pos() - audioInfo[i + kAudioNumSamples1 + 1]._offsetStart - 10; + } else { + length = audioInfo[i + kAudioNumSamples1 + 1]._offsetEnd - audioInfo[i + kAudioNumSamples1 + 1]._offsetStart - 10; + } + buffer = new byte[length]; + file.seek(audioInfo[i + kAudioNumSamples1 + 1]._offsetStart + 6); + file.read(buffer, length); + file.close(); + + byte streamFlag = Audio::FLAG_UNSIGNED | Audio::FLAG_LITTLE_ENDIAN; + _soundSamples[i].reset(Audio::makeRawStream(buffer, length, _audioRate, + streamFlag, DisposeAfterUse::YES)); + } + initSiren(); + + _musicIntroBuffer.reset(convertToMod("ms2_data.052", 2)); + _musicMadMonkeysBuffer.reset(convertToMod("ms2_data.056", 2)); +} + void ResourceManager::initGraphics() { Screen::initPalette(); initCursorGraphics(); - initImages(); + if (_MSPart == 1) + initImages1(); + else if (_MSPart == 2) + initImages2(); } void ResourceManager::initCursorGraphics() { @@ -168,7 +241,7 @@ void ResourceManager::initCursorGraphics() { } } -void ResourceManager::initImages() { +void ResourceManager::initImages1() { for (int i = 0; i < 44; ++i) { _images[i] = new MSNImage(_MSPart); if (!_images[i]->init(i)) @@ -179,8 +252,20 @@ void ResourceManager::initImages() { error("Failed reading image file msn_data.055"); } +void ResourceManager::initImages2() { + for (int i = 0; i < 47; ++i) { + _images[i] = new MSNImage(_MSPart); + if (!_images[i]->init(i)) + error("Failed reading image file ms2_data.%03d", i); + } +} + Audio::SeekableAudioStream *ResourceManager::getSoundStream(AudioId index) { - Audio::SeekableAudioStream *stream = _soundSamples[index].get(); + Audio::SeekableAudioStream *stream; + if (_MSPart == 1) + stream = _soundSamples[index].get(); + else if (_MSPart == 2) + stream = _soundSamples[index - kAudioNumSamples1 - 1].get(); stream->rewind(); return stream; @@ -207,12 +292,20 @@ Audio::AudioStream *ResourceManager::getSirenStream() { } MSNImage *ResourceManager::getImage(int filenumber) { - if (filenumber < 44) - return _images[filenumber]; - else if (filenumber == 55) - return _images[44]; - else - return nullptr; + if (_MSPart == 1) { + if (filenumber < 44) + return _images[filenumber]; + else if (filenumber == 55) + return _images[44]; + else + return nullptr; + } else if (_MSPart == 2) { + if (filenumber < 47) + return _images[filenumber]; + else + return nullptr; + } + else return nullptr; } const byte *ResourceManager::getImage(CursorId id) const { diff --git a/engines/supernova/resman.h b/engines/supernova/resman.h index 194b79875b..9cbf83ab01 100644 --- a/engines/supernova/resman.h +++ b/engines/supernova/resman.h @@ -45,7 +45,7 @@ public: }; public: - static const int kNumImageFiles = 45; + static const int kNumImageFiles = 47; public: ResourceManager(int MSPart); @@ -60,15 +60,17 @@ public: int getAudioRate(); private: - void initSoundFiles(); + void initSoundFiles1(); + void initSoundFiles2(); void initGraphics(); void initCursorGraphics(); - void initImages(); + void initImages1(); + void initImages2(); void initSiren(); byte *generateTone(byte *buffer, int frequency, int length, int audioRate, Common::SineTable &table); private: - Common::ScopedPtr<Audio::SeekableAudioStream> _soundSamples[kAudioNumSamples]; + Common::ScopedPtr<Audio::SeekableAudioStream> _soundSamples[kAudioNumSamples1]; Common::ScopedPtr<Common::MemoryReadStream> _musicIntroBuffer; Common::ScopedPtr<Common::MemoryReadStream> _musicOutroBuffer; Common::ScopedPtr<Common::MemoryReadStream> _musicMadMonkeysBuffer; diff --git a/engines/supernova/room.cpp b/engines/supernova/room.cpp index 5ac00f1529..487aeee7bf 100644 --- a/engines/supernova/room.cpp +++ b/engines/supernova/room.cpp @@ -35,7 +35,6 @@ Room::Room() { _fileNumber = 0; _id = NULLROOM; _vm = nullptr; - _gm = nullptr; for (int i = 0; i < kMaxSection; ++i) _shown[i] = kShownFalse; @@ -96,8 +95,8 @@ bool Room::deserialize(Common::ReadStream *in, int version) { int numObjects = in->readSint32LE(); for (int i = 0; i < numObjects; ++i) { - _objectState[i]._name = static_cast<StringId>(in->readSint32LE()); - _objectState[i]._description = static_cast<StringId>(in->readSint32LE()); + _objectState[i]._name = in->readSint32LE(); + _objectState[i]._description = in->readSint32LE(); _objectState[i]._roomId = in->readByte(); _objectState[i]._id = static_cast<ObjectId>(in->readSint32LE()); _objectState[i]._type = static_cast<ObjectType>(in->readSint32LE()); diff --git a/engines/supernova/room.h b/engines/supernova/room.h index 38d80ab003..c784758423 100644 --- a/engines/supernova/room.h +++ b/engines/supernova/room.h @@ -64,12 +64,11 @@ public: protected: int _fileNumber; - bool _shown[kMaxSection]; + char _shown[kMaxSection]; byte _sentenceRemoved[kMaxDialog]; Object _objectState[kMaxObject]; RoomId _id; SupernovaEngine *_vm; - GameManager1 *_gm; private: bool _seen; diff --git a/engines/supernova/screen.cpp b/engines/supernova/screen.cpp index 5a89b40882..5cdbb4ccff 100644 --- a/engines/supernova/screen.cpp +++ b/engines/supernova/screen.cpp @@ -263,7 +263,7 @@ void Screen::setTextCursorColor(byte color) { _textColor = color; } -void Screen::renderMessage(StringId stringId, MessagePosition position, +void Screen::renderMessage(int stringId, MessagePosition position, Common::String var1, Common::String var2) { Common::String text = _vm->getGameString(stringId); @@ -293,7 +293,7 @@ void Screen::renderText(const char *text) { renderText(text, _textCursorX, _textCursorY, _textColor); } -void Screen::renderText(StringId stringId) { +void Screen::renderText(int stringId) { renderText(_vm->getGameString(stringId)); } @@ -357,7 +357,7 @@ void Screen::renderText(const Common::String &text, int x, int y, byte color) { renderText(text.c_str(), x, y, color); } -void Screen::renderText(StringId stringId, int x, int y, byte color) { +void Screen::renderText(int stringId, int x, int y, byte color) { renderText(_vm->getGameString(stringId), x, y, color); } @@ -458,7 +458,7 @@ void Screen::restoreScreen() { } void Screen::renderRoom(Room &room) { - if (room.getId() == INTRO) + if (room.getId() == INTRO1 || room.getId() == INTRO2) return; if (setCurrentImage(room.getFileNumber())) { diff --git a/engines/supernova/screen.h b/engines/supernova/screen.h index dc5aa4dc2f..0779973fe9 100644 --- a/engines/supernova/screen.h +++ b/engines/supernova/screen.h @@ -44,6 +44,7 @@ class Screen; const int kScreenWidth = 320; const int kScreenHeight = 200; const int kFontWidth = 5; +const int kFontWidth2 = 4; const int kFontHeight = 8; enum Color { @@ -158,17 +159,17 @@ public: void renderRoom(Room &room); void renderMessage(const char *text, MessagePosition position = kMessageNormal, int positionX = -1, int positionY = -1); void renderMessage(const Common::String &text, MessagePosition position = kMessageNormal); - void renderMessage(StringId stringId, MessagePosition position = kMessageNormal, + void renderMessage(int stringId, MessagePosition position = kMessageNormal, Common::String var1 = "", Common::String var2 = ""); void removeMessage(); void renderText(const uint16 character); void renderText(const char *text); void renderText(const Common::String &text); - void renderText(StringId stringId); + void renderText(int stringId); void renderText(const uint16 character, int x, int y, byte color); void renderText(const char *text, int x, int y, byte color); void renderText(const Common::String &text, int x, int y, byte color); - void renderText(StringId stringId, int x, int y, byte color); + void renderText(int stringId, int x, int y, byte color); void renderText(const GuiElement &guiElement); void renderBox(int x, int y, int width, int height, byte color); void renderBox(const GuiElement &guiElement); diff --git a/engines/supernova/sound.h b/engines/supernova/sound.h index bfea0194ac..c0ca635df8 100644 --- a/engines/supernova/sound.h +++ b/engines/supernova/sound.h @@ -31,6 +31,7 @@ class SupernovaEngine; class ResourceManager; enum AudioId { + // Supernova 1 kAudioFoundLocation, // 44|0 kAudioCrash, // 45|0 kAudioVoiceHalt, // 46|0 @@ -51,11 +52,34 @@ enum AudioId { kAudioSlideDoor, // 54|24020 kAudioDoorOpen, // 54|30030 kAudioDoorClose, // 54|31040 - kAudioNumSamples + kAudioNumSamples1, + + // Supernova 2 + kAudioIntroDing, + kAudioSuccess2, + kAudioTaxiOpen, + kAudioTaxiLeaving, + kAudioTaxiArriving, + kAudioKiosk, + kAudioStage1, + kAudioStage2, + kAudioAppearance1, + kAudioAppearance2, + kAudioAppearance3, + kAudioElevatorBell, + kAudioElevator1, + kAudioShip1, + kAudioShip2, + kAudioShip3, + kAudioShipDeath, + kAudioDeath2, + kAudioCaught, + kAudioNumSamples2 }; enum MusicId { kMusicIntro = 49, + kMusicIntro2 = 52, kMusicOutro = 52, kMusicMadMonkeys = 51 }; diff --git a/engines/supernova/supernova.cpp b/engines/supernova/supernova.cpp index 9c7cdde545..4ff5434aad 100644 --- a/engines/supernova/supernova.cpp +++ b/engines/supernova/supernova.cpp @@ -46,6 +46,7 @@ #include "supernova/sound.h" #include "supernova/supernova.h" #include "supernova/supernova1/state.h" +#include "supernova/supernova2/state.h" #include "supernova/game-manager.h" namespace Supernova { @@ -142,9 +143,11 @@ void SupernovaEngine::init() { _resMan = new ResourceManager(_MSPart); _sound = new Sound(_mixer, _resMan); + _screen = new Screen(this, _resMan); if (_MSPart == 1) _gm = new GameManager1(this, _sound); - _screen = new Screen(this, _resMan); + else if (_MSPart == 2) + _gm = new GameManager2(this, _sound); _console = new Console(this, _gm); setTotalPlayTime(0); @@ -320,12 +323,12 @@ void SupernovaEngine::renderMessage(const Common::String &text, MessagePosition _screen->renderMessage(text, position); } -void SupernovaEngine::renderMessage(StringId stringId, MessagePosition position, Common::String var1, Common::String var2) { +void SupernovaEngine::renderMessage(int stringId, MessagePosition position, Common::String var1, Common::String var2) { _gm->_messageDuration = (getGameString(stringId).size() + 20) * _textSpeed / 10; _screen->renderMessage(stringId, position, var1, var2); } -void SupernovaEngine::renderMessage(StringId stringId, int x, int y) { +void SupernovaEngine::renderMessage(int stringId, int x, int y) { _gm->_messageDuration = (getGameString(stringId).size() + 20) * _textSpeed / 10; _screen->renderMessage(getGameString(stringId).c_str(), kMessageNormal, x, y); } @@ -346,7 +349,7 @@ void SupernovaEngine::renderText(const Common::String &text) { _screen->renderText(text); } -void SupernovaEngine::renderText(StringId stringId) { +void SupernovaEngine::renderText(int stringId) { _screen->renderText(stringId); } @@ -366,7 +369,7 @@ void SupernovaEngine::renderText(const Common::String &text, int x, int y, byte _screen->renderText(text, x, y, color); } -void SupernovaEngine::renderText(StringId stringId, int x, int y, byte color) { +void SupernovaEngine::renderText(int stringId, int x, int y, byte color) { _screen->renderText(stringId, x, y, color); } @@ -688,7 +691,7 @@ bool SupernovaEngine::loadGame(int slot) { byte saveVersion = savefile->readByte(); // Save version 1 was used during development and is no longer supported - if (saveVersion > SAVEGAME_VERSION || saveVersion == 1) { + if (saveVersion > SAVEGAME_VERSION || saveVersion < 10) { warning("Save game version %i not supported", saveVersion); delete savefile; return false; //Common::kUnknownError; diff --git a/engines/supernova/supernova.h b/engines/supernova/supernova.h index d50fe6a2e1..7054fcdfd0 100644 --- a/engines/supernova/supernova.h +++ b/engines/supernova/supernova.h @@ -46,13 +46,13 @@ namespace Supernova { #define SAVEGAME_HEADER MKTAG('M','S','N','1') #define SAVEGAME_HEADER2 MKTAG('M','S','N','2') -#define SAVEGAME_VERSION 9 +#define SAVEGAME_VERSION 10 #define SUPERNOVA_DAT "supernova.dat" -#define SUPERNOVA_DAT_VERSION 1 +#define SUPERNOVA_DAT_VERSION 2 #define SUPERNOVA2_DAT "supernova2.dat" -#define SUPERNOVA2_DAT_VERSION 1 +#define SUPERNOVA2_DAT_VERSION 2 class GuiElement; class ResourceManager; @@ -120,18 +120,18 @@ public: void renderRoom(Room &room); void renderMessage(const char *text, MessagePosition position = kMessageNormal); void renderMessage(const Common::String &text, MessagePosition position = kMessageNormal); - void renderMessage(StringId stringId, MessagePosition position = kMessageNormal, + void renderMessage(int stringId, MessagePosition position = kMessageNormal, Common::String var1 = "", Common::String var2 = ""); - void renderMessage(StringId stringId, int x, int y); + void renderMessage(int stringId, int x, int y); void removeMessage(); void renderText(const uint16 character); void renderText(const char *text); void renderText(const Common::String &text); - void renderText(StringId stringId); + void renderText(int stringId); void renderText(const uint16 character, int x, int y, byte color); void renderText(const char *text, int x, int y, byte color); void renderText(const Common::String &text, int x, int y, byte color); - void renderText(StringId stringId, int x, int y, byte color); + void renderText(int stringId, int x, int y, byte color); void renderText(const GuiElement &guiElement); void renderBox(int x, int y, int width, int height, byte color); void renderBox(const GuiElement &guiElement); diff --git a/engines/supernova/supernova1/rooms.cpp b/engines/supernova/supernova1/rooms.cpp index 4c5290308d..7190a7584a 100644 --- a/engines/supernova/supernova1/rooms.cpp +++ b/engines/supernova/supernova1/rooms.cpp @@ -35,7 +35,7 @@ Intro::Intro(SupernovaEngine *vm, GameManager1 *gm) { _gm = gm; _fileNumber = -1; - _id = INTRO; + _id = INTRO1; _shown[0] = kShownFalse; _objectState[0] = @@ -162,7 +162,7 @@ bool Intro::animate(int section1, int section2, int duration) { } bool Intro::animate(int section1, int section2, int duration, - MessagePosition position, StringId textId) { + MessagePosition position, int textId) { Common::KeyCode key = Common::KEYCODE_INVALID; const Common::String& text = _vm->getGameString(textId); _vm->renderMessage(text, position); @@ -187,7 +187,7 @@ bool Intro::animate(int section1, int section2, int duration, } bool Intro::animate(int section1, int section2, int section3, int section4, - int duration, MessagePosition position, StringId textId) { + int duration, MessagePosition position, int textId) { Common::KeyCode key = Common::KEYCODE_INVALID; const Common::String& text = _vm->getGameString(textId); _vm->renderMessage(text, position); @@ -266,7 +266,7 @@ void Intro::cutscene() { exitOnEscape(28); _vm->removeMessage(); - StringId textCounting[4] = + int textCounting[4] = {kStringIntroCutscene7, kStringIntroCutscene8, kStringIntroCutscene9, kStringIntroCutscene10}; _vm->setCurrentImage(31); _vm->renderImage(0); @@ -461,7 +461,7 @@ ShipCorridor::ShipCorridor(SupernovaEngine *vm, GameManager1 *gm) { _gm = gm; _fileNumber = 17; - _id = CORRIDOR; + _id = CORRIDOR_ROOM; _shown[0] = kShownTrue; _shown[4] = kShownTrue; @@ -518,7 +518,7 @@ ShipHall::ShipHall(SupernovaEngine *vm, GameManager1 *gm) { _objectState[2] = Object(_id, kStringHatch, kStringStasisHatchDescription, NULLOBJECT, OPENABLE | CLOSED | EXIT, 1, 1, 2, SLEEP, 8); _objectState[3] = Object(_id, kStringSlot, kStringSlotDescription, SLEEP_SLOT, COMBINABLE, 2, 2, 0, NULLROOM, 0); _objectState[4] = Object(_id, kStringLadder, kStringDefaultDescription, NULLOBJECT, NULLTYPE, 3, SLEEP, 0, NULLROOM, 0); - _objectState[5] = Object(_id, kStringCorridor, kStringDefaultDescription, NULLOBJECT, EXIT, 6, 6, 0, CORRIDOR, 19); + _objectState[5] = Object(_id, kStringCorridor, kStringDefaultDescription, NULLOBJECT, EXIT, 6, 6, 0, CORRIDOR_ROOM, 19); } bool ShipHall::interact(Action verb, Object &obj1, Object &obj2) { @@ -869,7 +869,7 @@ ShipCabinL1::ShipCabinL1(SupernovaEngine *vm, GameManager1 *gm) { _objectState[3] = Object(_id, kStringMagnete, kStringMagneteDescription, NULLOBJECT, UNNECESSARY, 8, 8, 0, NULLROOM, 0); _objectState[4] = Object(_id, kStringImage, kStringGenericDescription4, NULLOBJECT, UNNECESSARY, 9, 9, 0); _objectState[5] = Object(_id, kStringPen, kStringPenDescription, PEN, TAKE | COMBINABLE, 10, 10, 5 | 128); - _objectState[6] = Object(_id, kStringHatch, kStringDefaultDescription, NULLOBJECT, OPENABLE | OPENED | EXIT, 3, 3, 24 | 128, CORRIDOR, 9); + _objectState[6] = Object(_id, kStringHatch, kStringDefaultDescription, NULLOBJECT, OPENABLE | OPENED | EXIT, 3, 3, 24 | 128, CORRIDOR_ROOM, 9); _objectState[7] = Object(_id, kStringSlot, kStringSlotDescription, NULLOBJECT, COMBINABLE, 0, 0, 0); _objectState[8] = Object(_id, kStringShelf, kStringDefaultDescription, NULLOBJECT, OPENABLE | CLOSED, 1, 1, 0); _objectState[9] = Object(_id, kStringCompartment, kStringDefaultDescription, NULLOBJECT, OPENABLE | CLOSED, 2, 2, 0); @@ -905,7 +905,7 @@ ShipCabinL2::ShipCabinL2(SupernovaEngine *vm, GameManager1 *gm) { _objectState[16] = Object(_id, kStringJunk,kStringJunkDescription,NULLOBJECT,UNNECESSARY,38,38,0); _objectState[17] = Object(_id, kStringMagnete,kStringMagneteDescription,NULLOBJECT,UNNECESSARY,23,23,0); _objectState[18] = Object(_id, kStringToilet,kStringDefaultDescription,BATHROOM_DOOR,EXIT,255,255,0,BATHROOM,22); - _objectState[19] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | OPENED | EXIT,3,3,24 | 128,CORRIDOR,9); + _objectState[19] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | OPENED | EXIT,3,3,24 | 128,CORRIDOR_ROOM,9); _objectState[20] = Object(_id, kStringSlot,kStringSlotDescription,NULLOBJECT,COMBINABLE,0,0,0); _objectState[21] = Object(_id, kStringShelf,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,1,1,0); _objectState[22] = Object(_id, kStringCompartment,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,2,2,0); @@ -979,7 +979,7 @@ ShipCabinL3::ShipCabinL3(SupernovaEngine *vm, GameManager1 *gm) { _objectState[8] = Object(_id, kStringWire,kStringDefaultDescription,WIRE,COMBINABLE,18,18,0); _objectState[9] = Object(_id, kStringWire,kStringDefaultDescription,WIRE2,COMBINABLE,19,19,0); _objectState[10] = Object(_id, kStringPlug,kStringDefaultDescription,PLUG,COMBINABLE,20,20,0); - _objectState[11] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | OPENED | EXIT,3,3,24 | 128,CORRIDOR,9); + _objectState[11] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | OPENED | EXIT,3,3,24 | 128,CORRIDOR_ROOM,9); _objectState[12] = Object(_id, kStringSlot,kStringSlotDescription,NULLOBJECT,COMBINABLE,0,0,0); _objectState[13] = Object(_id, kStringShelf,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,1,1,0); _objectState[14] = Object(_id, kStringCompartment,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,2,2,0); @@ -1081,7 +1081,7 @@ ShipCabinR1::ShipCabinR1(SupernovaEngine *vm, GameManager1 *gm) { _objectState[0] = Object(_id, kStringImage,kStringImageDescription1,NULLOBJECT,UNNECESSARY,5,5,0); _objectState[1] = Object(_id, kStringDrawingInstruments,kStringDrawingInstrumentsDescription,NULLOBJECT,UNNECESSARY,6,6,0); _objectState[2] = Object(_id, kStringMagnete,kStringMagneteDescription,NULLOBJECT,UNNECESSARY,7,7,0); - _objectState[3] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | OPENED | EXIT,3,3,15 | 128,CORRIDOR,5); + _objectState[3] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | OPENED | EXIT,3,3,15 | 128,CORRIDOR_ROOM,5); _objectState[4] = Object(_id, kStringSlot,kStringSlotDescription,NULLOBJECT,COMBINABLE,0,0,0); _objectState[5] = Object(_id, kStringShelf,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,1,1,0); _objectState[6] = Object(_id, kStringCompartment,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,2,2,0); @@ -1103,7 +1103,7 @@ ShipCabinR2::ShipCabinR2(SupernovaEngine *vm, GameManager1 *gm) { _objectState[0] = Object(_id, kStringChessGame,kStringChessGameDescription1,NULLOBJECT,UNNECESSARY,11,11,0); _objectState[1] = Object(_id, kStringTennisRacket,kStringTennisRacketDescription,NULLOBJECT,UNNECESSARY,8,8,0); _objectState[2] = Object(_id, kStringTennisBall,kStringGenericDescription2,NULLOBJECT,UNNECESSARY,9,9,0); - _objectState[3] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | OPENED | EXIT,3,3,15 | 128,CORRIDOR,5); + _objectState[3] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | OPENED | EXIT,3,3,15 | 128,CORRIDOR_ROOM,5); _objectState[4] = Object(_id, kStringSlot,kStringSlotDescription,NULLOBJECT,COMBINABLE,0,0,0); _objectState[5] = Object(_id, kStringShelf,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,1,1,0); _objectState[6] = Object(_id, kStringCompartment,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,2,2,0); @@ -1140,7 +1140,7 @@ ShipCabinR3::ShipCabinR3(SupernovaEngine *vm, GameManager1 *gm) { _objectState[15] = Object(_id, kStringCompartment,kStringCompartmentDescription,SHELF4,OPENABLE | CLOSED,24,25,13); _objectState[16] = Object(_id, kStringBook,kStringBookHitchhiker,BOOK,TAKE,26,26,14); _objectState[17] = Object(_id, kStringDiscman,kStringDiscmanDescription,DISCMAN,TAKE | COMBINABLE,33,33,16); - _objectState[18] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | EXIT,3,3,15 | 128,CORRIDOR,5); + _objectState[18] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | EXIT,3,3,15 | 128,CORRIDOR_ROOM,5); _objectState[19] = Object(_id, kStringSlot,kStringSlotDescription,NULLOBJECT,COMBINABLE,0,0,0); _objectState[20] = Object(_id, kStringShelf,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,1,1,0); _objectState[21] = Object(_id, kStringCompartment,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,2,2,0); @@ -1194,7 +1194,7 @@ bool ShipCabinR3::interact(Action verb, Object &obj1, Object &obj2) { void ShipCabinR3::onEntrance() { for (int i = 0; i < 3; ++i) - _gm->_inventory.add(*_gm->_rooms[INTRO]->getObject(i)); + _gm->_inventory.add(*_gm->_rooms[INTRO1]->getObject(i)); setRoomSeen(true); } @@ -1221,7 +1221,7 @@ ShipAirlock::ShipAirlock(SupernovaEngine *vm, GameManager1 *gm) { _shown[0] = kShownTrue; _shown[6] = kShownTrue; - _objectState[0] = Object(_id, kStringHatch,kStringHatchDescription1,NULLOBJECT,EXIT | OPENABLE | OPENED | CLOSED,0,0,0,CORRIDOR,10); + _objectState[0] = Object(_id, kStringHatch,kStringHatchDescription1,NULLOBJECT,EXIT | OPENABLE | OPENED | CLOSED,0,0,0,CORRIDOR_ROOM,10); _objectState[1] = Object(_id, kStringHatch,kStringHatchDescription2,NULLOBJECT,EXIT | OPENABLE | CLOSED,1,1,0,HOLD,14); _objectState[2] = Object(_id, kStringButton,kStringDefaultDescription,BUTTON1,PRESS,2,2,0); _objectState[3] = Object(_id, kStringButton,kStringDefaultDescription,BUTTON2,PRESS,3,3,0); @@ -2591,7 +2591,7 @@ bool ArsanoMeetup2::interact(Action verb, Object &obj1, Object &obj2) { if (((verb == ACTION_WALK) && ((obj1._id == SPACESHIP) || (obj1._id == ROGER_W))) || ((verb == ACTION_TALK) && (obj1._id == ROGER_W))) { - _gm->changeRoom(INTRO); + _gm->changeRoom(INTRO1); _vm->setCurrentImage(30); _vm->renderImage(0); _vm->paletteBrightness(); @@ -2823,17 +2823,17 @@ bool ArsanoMeetup3::interact(Action verb, Object &obj1, Object &obj2) { _gm->reply(kStringArsanoMeetup3_28, 1, 1 + 128); _vm->paletteFadeOut(); // Remove all objects from the inventory except the Knife, Watch and Discman - bool has_knife = _gm->_rooms[INTRO]->getObject(1)->hasProperty(CARRIED); - bool has_watch = _gm->_rooms[INTRO]->getObject(2)->hasProperty(CARRIED); - bool has_discman = _gm->_rooms[INTRO]->getObject(3)->hasProperty(CARRIED); + bool has_knife = _gm->_rooms[INTRO1]->getObject(1)->hasProperty(CARRIED); + bool has_watch = _gm->_rooms[INTRO1]->getObject(2)->hasProperty(CARRIED); + bool has_discman = _gm->_rooms[INTRO1]->getObject(3)->hasProperty(CARRIED); _gm->_inventory.clear(); _gm->_inventoryScroll = 0; if (has_knife) - _gm->_inventory.add(*_gm->_rooms[INTRO]->getObject(1)); + _gm->_inventory.add(*_gm->_rooms[INTRO1]->getObject(1)); if (has_watch) - _gm->_inventory.add(*_gm->_rooms[INTRO]->getObject(2)); + _gm->_inventory.add(*_gm->_rooms[INTRO1]->getObject(2)); if (has_discman) - _gm->_inventory.add(*_gm->_rooms[INTRO]->getObject(3)); + _gm->_inventory.add(*_gm->_rooms[INTRO1]->getObject(3)); _gm->changeRoom(CELL); _gm->_state._dream = true; } else @@ -3158,7 +3158,7 @@ bool AxacussCorridor4::interact(Action verb, Object &obj1, Object &obj2) { } else if ((verb == ACTION_TAKE) && (obj1._id == WATCH) && !obj1.hasProperty(CARRIED)) { setSectionVisible(29, false); getObject(4)->_click = 255; - _gm->takeObject(*_gm->_rooms[INTRO]->getObject(2)); + _gm->takeObject(*_gm->_rooms[INTRO1]->getObject(2)); if (isSectionVisible(9)) _vm->renderImage(9); } else @@ -4004,7 +4004,7 @@ AxacussStation::AxacussStation(SupernovaEngine *vm, GameManager1 *gm) { bool AxacussStation::interact(Action verb, Object &obj1, Object &obj2) { if ((verb == ACTION_LOOK) && (obj1._id == STATION_SIGN)) { - _gm->changeRoom(SIGN); + _gm->changeRoom(SIGN_ROOM); } else if ((verb == ACTION_WALK) && (obj1._id == DOOR) && obj1.hasProperty(OPENED)) { _gm->great(0); _gm->_guiEnabled = false; @@ -4022,7 +4022,7 @@ AxacussSign::AxacussSign(SupernovaEngine *vm, GameManager1 *gm) { _gm = gm; _fileNumber = 32; - _id = SIGN; + _id = SIGN_ROOM; _shown[0] = kShownTrue; _shown[1] = kShownTrue; diff --git a/engines/supernova/supernova1/rooms.h b/engines/supernova/supernova1/rooms.h index c49e8356c9..0b0dbc432b 100644 --- a/engines/supernova/supernova1/rooms.h +++ b/engines/supernova/supernova1/rooms.h @@ -26,6 +26,7 @@ #include "common/str.h" #include "supernova/msn_def.h" +#include "supernova/supernova1/stringid.h" #include "supernova/room.h" namespace Common { @@ -45,11 +46,12 @@ public: virtual void onEntrance(); private: + GameManager1 *_gm; bool animate(int section1, int section2, int duration); bool animate(int section1, int section2, int duration, MessagePosition position, - StringId text); + int text); bool animate(int section1, int section2, int section3, int section4, int duration, - MessagePosition position, StringId text); + MessagePosition position, int text); void titleScreen(); void titleFadeIn(); @@ -66,6 +68,9 @@ public: ShipCorridor(SupernovaEngine *vm, GameManager1 *gm); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class ShipHall: public Room { @@ -73,6 +78,9 @@ public: ShipHall(SupernovaEngine *vm, GameManager1 *gm); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class ShipSleepCabin: public Room { @@ -84,6 +92,7 @@ public: virtual void onEntrance(); private: + GameManager1 *_gm; byte _color; }; @@ -96,12 +105,16 @@ public: virtual void onEntrance(); private: + GameManager1 *_gm; byte _color; }; class ShipCabinL1: public Room { public: ShipCabinL1(SupernovaEngine *vm, GameManager1 *gm); + +private: + GameManager1 *_gm; }; class ShipCabinL2 : public Room { @@ -109,6 +122,9 @@ public: ShipCabinL2(SupernovaEngine *vm, GameManager1 *gm); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class ShipCabinL3 : public Room { @@ -116,16 +132,25 @@ public: ShipCabinL3(SupernovaEngine *vm, GameManager1 *gm); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class ShipCabinR1 : public Room { public: ShipCabinR1(SupernovaEngine *vm, GameManager1 *gm); + +private: + GameManager1 *_gm; }; class ShipCabinR2 : public Room { public: ShipCabinR2(SupernovaEngine *vm, GameManager1 *gm); + +private: + GameManager1 *_gm; }; class ShipCabinR3 : public Room { @@ -134,11 +159,17 @@ public: virtual bool interact(Action verb, Object &obj1, Object &obj2); virtual void onEntrance(); + +private: + GameManager1 *_gm; }; class ShipCabinBathroom : public Room { public: ShipCabinBathroom(SupernovaEngine *vm, GameManager1 *gm); + +private: + GameManager1 *_gm; }; class ShipAirlock : public Room { @@ -147,6 +178,9 @@ public: virtual bool interact(Action verb, Object &obj1, Object &obj2); virtual void onEntrance(); + +private: + GameManager1 *_gm; }; class ShipHold : public Room { @@ -155,6 +189,9 @@ public: virtual bool interact(Action verb, Object &obj1, Object &obj2); virtual void onEntrance(); + +private: + GameManager1 *_gm; }; class ShipLandingModule : public Room { @@ -162,6 +199,9 @@ public: ShipLandingModule(SupernovaEngine *vm, GameManager1 *gm); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class ShipGenerator : public Room { @@ -169,11 +209,17 @@ public: ShipGenerator(SupernovaEngine *vm, GameManager1 *gm); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class ShipOuterSpace : public Room { public: ShipOuterSpace(SupernovaEngine *vm, GameManager1 *gm); + +private: + GameManager1 *_gm; }; @@ -184,11 +230,17 @@ public: virtual void onEntrance(); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class ArsanoCave : public Room { public: ArsanoCave(SupernovaEngine *vm, GameManager1 *gm); + +private: + GameManager1 *_gm; }; class ArsanoMeetup : public Room { @@ -202,6 +254,7 @@ public: private: byte _sign; byte _beacon; + GameManager1 *_gm; }; class ArsanoEntrance : public Room { @@ -212,10 +265,11 @@ public: virtual void animation(); private: - StringId _dialog1[5]; - StringId _dialog2[5]; - StringId _dialog3[5]; + int _dialog1[5]; + int _dialog2[5]; + int _dialog3[5]; byte _eyewitness; + GameManager1 *_gm; }; class ArsanoRemaining : public Room { @@ -227,6 +281,7 @@ public: private: bool _chewing; int _i; + GameManager1 *_gm; }; class ArsanoRoger : public Room { @@ -238,9 +293,10 @@ public: virtual bool interact(Action verb, Object &obj1, Object &obj2); private: - StringId _dialog1[4]; + int _dialog1[4]; byte _eyewitness; byte _hands; + GameManager1 *_gm; }; class ArsanoGlider : public Room { @@ -252,6 +308,7 @@ public: private: byte _sinus; + GameManager1 *_gm; }; class ArsanoMeetup2 : public Room { @@ -265,10 +322,11 @@ public: private: // TODO: change to 6, fix initialization - StringId _dialog1[2]; - StringId _dialog2[2]; - StringId _dialog3[4]; - StringId _dialog4[3]; + int _dialog1[2]; + int _dialog2[2]; + int _dialog3[4]; + int _dialog4[3]; + GameManager1 *_gm; // FIXME: Remove following unused bool variables? //bool _found; @@ -282,11 +340,12 @@ public: virtual bool interact(Action verb, Object &obj1, Object &obj2); private: - StringId _dialog2[4]; - StringId _dialog3[2]; + int _dialog2[4]; + int _dialog3[2]; // TODO: Hack, to be move away and renamed when the other uses are found - StringId _dialogsX[6]; + int _dialogsX[6]; + GameManager1 *_gm; }; @@ -298,6 +357,9 @@ public: virtual bool interact(Action verb, Object &obj1, Object &obj2); virtual void animation(); virtual void onEntrance(); + +private: + GameManager1 *_gm; }; class AxacussCorridor1 : public Room { @@ -305,6 +367,9 @@ public: AxacussCorridor1(SupernovaEngine *vm, GameManager1 *gm); virtual void onEntrance(); + +private: + GameManager1 *_gm; }; class AxacussCorridor2 : public Room { @@ -312,6 +377,9 @@ public: AxacussCorridor2(SupernovaEngine *vm, GameManager1 *gm); virtual void onEntrance(); + +private: + GameManager1 *_gm; }; class AxacussCorridor3 : public Room { @@ -319,6 +387,9 @@ public: AxacussCorridor3(SupernovaEngine *vm, GameManager1 *gm); virtual void onEntrance(); + +private: + GameManager1 *_gm; }; class AxacussCorridor4 : public Room { @@ -328,6 +399,9 @@ public: virtual void onEntrance(); virtual void animation(); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class AxacussCorridor5 : public Room { @@ -342,11 +416,13 @@ private: bool handleMoneyDialog(); // TODO: Change to 6, or change struct, and fix initialization - StringId _dialog1[2]; - StringId _dialog2[2]; - StringId _dialog3[4]; + int _dialog1[2]; + int _dialog2[2]; + int _dialog3[4]; byte _rows[6]; + + GameManager1 *_gm; }; class AxacussCorridor6 : public Room { @@ -355,6 +431,9 @@ public: virtual void onEntrance(); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class AxacussCorridor7 : public Room { @@ -362,6 +441,9 @@ public: AxacussCorridor7(SupernovaEngine *vm, GameManager1 *gm); virtual void onEntrance(); + +private: + GameManager1 *_gm; }; class AxacussCorridor8 : public Room { @@ -370,6 +452,9 @@ public: virtual void onEntrance(); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class AxacussCorridor9 : public Room { @@ -378,6 +463,9 @@ public: virtual void onEntrance(); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class AxacussBcorridor : public Room { @@ -386,6 +474,9 @@ public: virtual void onEntrance(); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class AxacussIntersection : public Room { @@ -395,7 +486,8 @@ public: virtual bool interact(Action verb, Object &obj1, Object &obj2); private: - StringId _dialogsX[6]; + int _dialogsX[6]; + GameManager1 *_gm; }; class AxacussExit : public Room { @@ -405,7 +497,8 @@ public: virtual bool interact(Action verb, Object &obj1, Object &obj2); private: - StringId _dialogsX[6]; + int _dialogsX[6]; + GameManager1 *_gm; }; class AxacussOffice1 : public Room { @@ -413,6 +506,9 @@ public: AxacussOffice1(SupernovaEngine *vm, GameManager1 *gm); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class AxacussOffice2 : public Room { @@ -420,6 +516,9 @@ public: AxacussOffice2(SupernovaEngine *vm, GameManager1 *gm); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class AxacussOffice3 : public Room { @@ -427,6 +526,9 @@ public: AxacussOffice3(SupernovaEngine *vm, GameManager1 *gm); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class AxacussOffice4 : public Room { @@ -434,6 +536,9 @@ public: AxacussOffice4(SupernovaEngine *vm, GameManager1 *gm); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class AxacussOffice5 : public Room { @@ -442,6 +547,9 @@ public: virtual void onEntrance(); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class AxacussElevator : public Room { @@ -449,6 +557,9 @@ public: AxacussElevator(SupernovaEngine *vm, GameManager1 *gm); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class AxacussStation : public Room { @@ -456,6 +567,9 @@ public: AxacussStation(SupernovaEngine *vm, GameManager1 *gm); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class AxacussSign : public Room { @@ -463,6 +577,9 @@ public: AxacussSign(SupernovaEngine *vm, GameManager1 *gm); virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager1 *_gm; }; class Outro : public Room { @@ -480,6 +597,7 @@ private: MessagePosition position, const char *text); Common::String _outroText; + GameManager1 *_gm; }; } diff --git a/engines/supernova/supernova1/state.cpp b/engines/supernova/supernova1/state.cpp index fff5ad7993..f3f8bbac63 100644 --- a/engines/supernova/supernova1/state.cpp +++ b/engines/supernova/supernova1/state.cpp @@ -28,6 +28,7 @@ #include "supernova/screen.h" #include "supernova/supernova.h" #include "supernova/supernova1/state.h" +#include "supernova/supernova1/stringid.h" namespace Supernova { @@ -75,7 +76,7 @@ bool GameManager1::serialize(Common::WriteStream *out) { // Rooms out->writeByte(_currentRoom->getId()); - for (int i = 0; i < NUMROOMS; ++i) { + for (int i = 0; i < NUMROOMS1; ++i) { _rooms[i]->serialize(out); } @@ -144,7 +145,7 @@ bool GameManager1::deserialize(Common::ReadStream *in, int version) { // Rooms RoomId curRoomId = static_cast<RoomId>(in->readByte()); - for (int i = 0; i < NUMROOMS; ++i) { + for (int i = 0; i < NUMROOMS1; ++i) { _rooms[i]->deserialize(in, version); } changeRoom(curRoomId); @@ -179,7 +180,7 @@ static Common::String timeToString(int msec) { GameManager1::GameManager1(SupernovaEngine *vm, Sound *sound) : GameManager(vm, sound) { initRooms(); - changeRoom(INTRO); + changeRoom(INTRO1); initState(); } @@ -188,8 +189,8 @@ GameManager1::~GameManager1() { } void GameManager1::destroyRooms() { - delete _rooms[INTRO]; - delete _rooms[CORRIDOR]; + delete _rooms[INTRO1]; + delete _rooms[CORRIDOR_ROOM]; delete _rooms[HALL]; delete _rooms[SLEEP]; delete _rooms[COCKPIT]; @@ -236,8 +237,9 @@ void GameManager1::destroyRooms() { delete _rooms[OFFICE_L]; delete _rooms[ELEVATOR]; delete _rooms[STATION]; - delete _rooms[SIGN]; + delete _rooms[SIGN_ROOM]; delete _rooms[OUTRO]; + delete _rooms; } void GameManager1::initState() { @@ -297,8 +299,9 @@ void GameManager1::initState() { } void GameManager1::initRooms() { - _rooms[INTRO] = new Intro(_vm, this); - _rooms[CORRIDOR] = new ShipCorridor(_vm, this); + _rooms = new Room *[NUMROOMS1]; + _rooms[INTRO1] = new Intro(_vm, this); + _rooms[CORRIDOR_ROOM] = new ShipCorridor(_vm, this); _rooms[HALL] = new ShipHall(_vm, this); _rooms[SLEEP] = new ShipSleepCabin(_vm, this); _rooms[COCKPIT] = new ShipCockpit(_vm, this); @@ -345,7 +348,7 @@ void GameManager1::initRooms() { _rooms[OFFICE_L] = new AxacussOffice5(_vm, this); _rooms[ELEVATOR] = new AxacussElevator(_vm, this); _rooms[STATION] = new AxacussStation(_vm, this); - _rooms[SIGN] = new AxacussSign(_vm, this); + _rooms[SIGN_ROOM] = new AxacussSign(_vm, this); _rooms[OUTRO] = new Outro(_vm, this); } @@ -408,7 +411,7 @@ void GameManager1::updateEvents() { case Common::EVENT_LBUTTONUP: // fallthrough case Common::EVENT_RBUTTONUP: - if (_currentRoom->getId() != INTRO && _sound->isPlaying()) + if (_currentRoom->getId() != INTRO1 && _sound->isPlaying()) return; _mouseClicked = true; // fallthrough @@ -449,7 +452,7 @@ void GameManager1::telomat(int nr) { "Alga Hurz Li" }; - StringId dial1[4]; + int dial1[4]; dial1[0] = kStringTelomat1; dial1[1] = kNoString; dial1[2] = kStringTelomat3; @@ -457,7 +460,7 @@ void GameManager1::telomat(int nr) { static byte rows1[3] = {1, 2, 1}; - StringId dial2[4]; + int dial2[4]; dial2[0] = kStringTelomat4; dial2[1] = kStringTelomat5; dial2[2] = kStringTelomat6; @@ -947,7 +950,7 @@ void GameManager1::guardWalkEvent() { } void GameManager1::taxiEvent() { - if (_currentRoom->getId() == SIGN) { + if (_currentRoom->getId() == SIGN_ROOM) { changeRoom(STATION); _vm->renderRoom(*_currentRoom); } @@ -966,8 +969,8 @@ void GameManager1::taxiEvent() { _vm->renderImage(invertSection(i - 1)); _vm->renderImage(i); } - _rooms[SIGN]->setSectionVisible(2, false); - _rooms[SIGN]->setSectionVisible(3, true); + _rooms[SIGN_ROOM]->setSectionVisible(2, false); + _rooms[SIGN_ROOM]->setSectionVisible(3, true); } void GameManager1::searchStartEvent() { @@ -1098,7 +1101,7 @@ void GameManager1::shot(int a, int b) { } void GameManager1::takeMoney(int amount) { - Object *moneyObject = _rooms[INTRO]->getObject(4); + Object *moneyObject = _rooms[INTRO1]->getObject(4); _state._money += amount; _vm->setGameString(kStringInventoryMoney, Common::String::format("%d Xa", _state._money)); @@ -1567,7 +1570,7 @@ void GameManager1::guard3Shot() { } void GameManager1::alarm() { - if (_rooms[INTRO]->getObject(2)->hasProperty(CARRIED)) { + if (_rooms[INTRO1]->getObject(2)->hasProperty(CARRIED)) { alarmSound(); if (_currentRoom->getId() == GUARD) guardShot(); diff --git a/engines/supernova/supernova1/state.h b/engines/supernova/supernova1/state.h index ba02b012a5..9e997e95b7 100644 --- a/engines/supernova/supernova1/state.h +++ b/engines/supernova/supernova1/state.h @@ -64,7 +64,7 @@ class GameState { bool _playerHidden; }; -class GameManager1 : public GameManager { +class GameManager1: public GameManager { public: GameManager1(SupernovaEngine *vm, Sound *sound); virtual ~GameManager1(); diff --git a/engines/supernova/supernova1/stringid.h b/engines/supernova/supernova1/stringid.h new file mode 100644 index 0000000000..7f3c1f1fcb --- /dev/null +++ b/engines/supernova/supernova1/stringid.h @@ -0,0 +1,188 @@ +/* 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. + * + */ + +#ifndef SUPERNOVA_STRINGID_H +#define SUPERNOVA_STRINGID_H + +#include "common/scummsys.h" + +namespace Supernova { + +enum StringId1 { + kStringTitleVersion = 25, kStringTitle1, kStringTitle2, kStringTitle3, kStringIntro1, + kStringIntro2, kStringIntro3, kStringIntro4, kStringIntro5, kStringIntro6, + kStringIntro7, kStringIntro8, kStringIntro9, kStringIntro10, kStringIntro11, + kStringIntro12, kStringIntro13, kStringBroken, kStringTakeMessage, + kStringKeycard, kStringKeycardDescription, kStringKnife, kStringKnifeDescription, kStringWatch, + kStringDiscman, kStringDiscmanDescription, kStringHatch, kStringButton, kStringHatchButtonDescription, + // 50 + kStringLadder, kStringExit, kStringCockpitHatchDescription, kStringKitchenHatchDescription, kStringStasisHatchDescription, + kStringStasisHatchDescription2, kStringSlot, kStringSlotDescription, kStringCorridor, kStringComputer, + kStringComputerPassword, kStringInstruments, kStringInstrumentsDescription1, kStringMonitor, kStringMonitorDescription, + kStringImage, kStringGenericDescription1, kStringGenericDescription2, kStringGenericDescription3, kStringGenericDescription4, + kStringMagnete, kStringMagneteDescription, kStringPen, kStringPenDescription, kStringShelf, + kStringCompartment, kStringSocket, kStringToilet, kStringPistol, kStringPistolDescription, + kStringBooks, kStringBooksDescription, kStringSpool, kStringSpoolDescription, kStringBook, + kStringUnderwear, kStringUnderwearDescription, kStringClothes, kStringJunk, kStringJunkDescription, + kStringFolders, kStringFoldersDescription, kStringPoster, kStringPosterDescription1, kStringPosterDescription2, + kStringSpeaker, kStringRecord, kStringRecordDescription, kStringRecordStand, kStringRecordStandDescription, + // 100 + kStringTurntable, kStringTurntableDescription, kStringWire, kStringPlug, kStringImageDescription1, + kStringDrawingInstruments, kStringDrawingInstrumentsDescription, kStringChessGame, kStringChessGameDescription1, kStringTennisRacket, + kStringTennisRacketDescription, kStringTennisBall, kStringChessGameDescription2, kStringBed, kStringBedDescription, + kStringCompartmentDescription, kStringAlbums, kStringAlbumsDescription, kStringRope, kStringRopeDescription, + kStringShelfDescription, kStringClothesDescription, kStringSocks, kStringBookHitchhiker, kStringBathroom, + kStringBathroomDescription, kStringShower, kStringHatchDescription1, kStringHatchDescription2, kStringHelmet, + kStringHelmetDescription, kStringSuit, kStringSuitDescription, kStringLifeSupport, kStringLifeSupportDescription, + kStringScrap, kStringScrapDescription1, kStringTerminalStrip, kStringScrapDescription2, kStringReactor, + kStringReactorDescription, kStringNozzle, kStringPumpkin, kStringPumpkinDescription, kStringLandingModule, + kStringLandingModuleDescription, kStringHatchDescription3, kStringGenerator, kStringGeneratorDescription, kStringScrapDescription3, + // 150 + kSafetyButtonDescription, kStringKeyboard, kStringGeneratorWire, kStringEmptySpool, kStringKeycard2, + kStringKeycard2Description, kStringTrap, kStringVoltmeter, kStringClip, kStringWireDescription, + kStringStone, kStringCaveOpening, kStringCaveOpeningDescription, kStringExitDescription, kStringCave, + kStringSign, kStringSignDescription, kStringEntrance, kStringStar, kStringSpaceshift, + kStringPorter, kStringPorterDescription, kStringDoor, kStringChewingGum, kStringGummyBears, + kStringChocolateBall, kStringEgg, kStringLiquorice, kStringPill, kStringPillDescription, + kStringVendingMachine, kStringVendingMachineDescription, kStringToiletDescription, kStringStaircase, kStringCoins, + kStringCoinsDescription, kStringTabletPackage, kStringTabletPackageDescription, kStringChair, kStringShoes, + kStringShoesDescription, kStringFrogFace, kStringScrible, kStringScribleDescription, kStringWallet, + kStringMenu, kStringMenuDescription, kStringCup, kStringCupDescription, kStringBill, + // 200 + kStringBillDescription, kStringKeycard3, kStringAnnouncement, kStringAnnouncementDescription, kStringRoger, + kStringUfo, kStringUfoDescription, kStringTray, kStringTrayDescription, kStringLamp, + kStringLampDescription, kStringEyes, kStringEyesDescription, kStringSocketDescription, kStringMetalBlock, + kStringMetalBlockDescription, kStringRobot, kStringRobotDescription, kStringTable, kStringTableDescription, + kStringCellDoor, kStringCellDoorDescription, kStringLaptop, kStringWristwatch, kStringPillar, + kStringDoorDescription1, kStringDoorDescription2, kStringDoorDescription3, kStringDoorDescription4, kStringDontEnter, + kStringAxacussan, kStringAxacussanDescription, kStringImageDescription2, kStringMastercard, kStringMastercardDescription, + kStringLamp2, kStringGenericDescription5, kStringMoney, kStringMoneyDescription1, kStringLocker, + kStringLockerDescription, kStringLetter, kStringCube, kStringGenericDescription6, kStringGenericDescription7, + kStringStrangeThing, kStringGenericDescription8, kStringImageDescription3, kStringPlant, kStringStatue, + // 250 + kStringStatueDescription, kStringPlantDescription, kStringComputerDescription, kStringGraffiti, kStringGraffitiDescription, + kStringMoneyDescription2, kStringJungle, kStringJungleDescription, kStringOutro1, kStringOutro2, + kStringOutro3, kStringOutro4, kStringOutro5, kStringOutro6, kStringOutro7, + kStringOutro8, kStringOutro9, kStringOutro10, kStringOutro11, kStringOutro12, + kStringOutro13, kStringOutro14, kStringWireAndPlug, kStringWireAndClip, kStringWireAndPlug2, + // 275 + kStringSignDescription2, kStringCoin, kStringDoorDescription5, kStringDoorDescription6, kStringKeycard2Description2, + kSringSpoolAndClip, kStringIntroCutscene1, kStringIntroCutscene2, kStringIntroCutscene3, kStringIntroCutscene4, + kStringIntroCutscene5, kStringIntroCutscene6, kStringIntroCutscene7, kStringIntroCutscene8, kStringIntroCutscene9, + kStringIntroCutscene10, kStringIntroCutscene11, kStringIntroCutscene12, kStringIntroCutscene13, kStringIntroCutscene14, + kStringIntroCutscene15, kStringIntroCutscene16, kStringIntroCutscene17, kStringIntroCutscene18, kStringIntroCutscene19, + // 300 + kStringIntroCutscene20, kStringIntroCutscene21, kStringIntroCutscene22, kStringIntroCutscene23, kStringIntroCutscene24, + kStringIntroCutscene25, kStringIntroCutscene26, kStringIntroCutscene27, kStringIntroCutscene28, kStringIntroCutscene29, + kStringIntroCutscene30, kStringIntroCutscene31, kStringIntroCutscene32, kStringIntroCutscene33, kStringIntroCutscene34, + kStringIntroCutscene35, kStringIntroCutscene36, kStringIntroCutscene37, kStringIntroCutscene38, kStringIntroCutscene39, + kStringIntroCutscene40, kStringIntroCutscene41, kStringIntroCutscene42, kStringShipHall1, kStringShipSleepCabin1, + //325 + kStringShipSleepCabin2, kStringShipSleepCabin3, kStringShipSleepCabin4, kStringShipSleepCabin5, kStringShipSleepCabin6, + kStringShipSleepCabin7, kStringShipSleepCabin8, kStringShipSleepCabin9, kStringShipSleepCabin10, kStringShipSleepCabin11, + kStringShipSleepCabin12, kStringShipSleepCabin13, kStringShipSleepCabin14, kStringShipSleepCabin15, kStringShipSleepCabin16, + kStringShipCockpit1, kStringShipCockpit2, kStringShipCockpit3, kStringShipCockpit4, kStringShipCockpit5, + kStringShipCockpit6, kStringShipCockpit7, kStringShipCockpit8, kStringShipCockpit9, kStringShipCockpit10, + // 350 + kStringShipCockpit11, kStringShipCockpit12, kStringShipCockpit13, kStringShipCabinL3_1, kStringShipCabinL3_2, + kStringShipCabinL3_3, kStringShipCabinL3_4, kStringShipCabinL3_5, kStringShipAirlock1, kStringShipAirlock2, + kStringShipAirlock3, kStringShipAirlock4, kStringShipHold1, kStringCable1, kStringCable2, + kStringCable3, kStringCable4, kStringShipHold2, kStringShipHold3, kStringShipHold4, + kStringShipHold5, kStringShipHold6, kStringShipHold7, kStringShipHold8, kStringShipHold9, + // 375 + kStringShipHold10, kStringShipHold11, kStringShipHold12, kStringShipHold13, kStringShipHold14, + kStringShipHold15, kStringShipHold16, kStringArsanoMeetup1, kStringArsanoMeetup2, kStringArsanoMeetup3, + kStringArsanoEntrance1, kStringArsanoEntrance2, kStringArsanoEntrance3, kStringArsanoEntrance4, kStringArsanoEntrance5, + kStringArsanoEntrance6, kStringArsanoEntrance7, kStringArsanoEntrance8, kStringArsanoEntrance9, kStringArsanoEntrance10, + kStringArsanoEntrance11, kStringArsanoEntrance12, kStringArsanoEntrance13, kStringArsanoEntrance14, kStringArsanoEntrance15, + // 400 + kStringArsanoEntrance16, kStringArsanoEntrance17, kStringArsanoEntrance18, kStringArsanoEntrance19, kStringArsanoEntrance20, + kStringArsanoEntrance21, kStringArsanoEntrance22, kStringArsanoEntrance23, kStringArsanoEntrance24, kStringArsanoEntrance25, + kStringArsanoEntrance26, kStringArsanoEntrance27, kStringArsanoDialog1, kStringArsanoDialog2, kStringArsanoDialog3, + kStringArsanoDialog4, kStringArsanoDialog5, kStringArsanoDialog6, kStringArsanoDialog7, kStringArsanoDialog8, + kStringArsanoDialog9, kStringDialogArsanoRoger1, kStringDialogArsanoRoger2, kStringDialogArsanoRoger3, + // 425 + kStringDialogArsanoMeetup3_1, kStringDialogArsanoMeetup3_2, kStringDialogArsanoMeetup3_3, kStringDialogArsanoMeetup3_4, kStringDialogArsanoMeetup3_5, + kStringArsanoRoger1, kStringArsanoRoger2, kStringArsanoRoger3, kStringArsanoRoger4, kStringArsanoRoger5, + kStringArsanoRoger6, kStringArsanoRoger7, kStringArsanoRoger8, kStringArsanoRoger9, kStringArsanoRoger10, + kStringArsanoRoger11, kStringArsanoRoger12, kStringArsanoRoger13, kStringArsanoRoger14, kStringArsanoRoger15, + kStringArsanoRoger16, kStringArsanoRoger17, kStringArsanoRoger18, kStringArsanoRoger19, kStringArsanoRoger20, + // 450 + kStringArsanoRoger21, kStringArsanoRoger22, kStringArsanoRoger23, kStringArsanoRoger24, kStringArsanoRoger25, + kStringArsanoRoger26, kStringArsanoRoger27, kStringArsanoRoger28, kStringArsanoRoger29, kStringArsanoRoger30, + kStringArsanoRoger31, kStringArsanoRoger32, kStringArsanoRoger33, kStringArsanoRoger34, kStringArsanoRoger35, + kStringArsanoRoger36, kStringArsanoRoger37, kStringArsanoRoger38, kStringArsanoRoger39, kStringArsanoRoger40, + kStringArsanoGlider1, kStringArsanoMeetup2_1, kStringArsanoMeetup2_2, kStringArsanoMeetup2_3, kStringArsanoMeetup2_4, + // 475 + kStringArsanoMeetup2_5, kStringArsanoMeetup2_6, kStringArsanoMeetup2_7, kStringArsanoMeetup2_8, kStringArsanoMeetup2_9, + kStringArsanoMeetup2_10, kStringArsanoMeetup2_11, kStringArsanoMeetup2_12, kStringArsanoMeetup2_13, kStringArsanoMeetup3_1, + kStringArsanoMeetup3_2, kStringArsanoMeetup3_3, kStringArsanoMeetup3_4, kStringArsanoMeetup3_5, kStringArsanoMeetup3_6, + kStringArsanoMeetup3_7, kStringArsanoMeetup3_8, kStringArsanoMeetup3_9, kStringArsanoMeetup3_10, kStringArsanoMeetup3_11, + kStringArsanoMeetup3_12, kStringArsanoMeetup3_13, kStringArsanoMeetup3_14, kStringArsanoMeetup3_15, kStringArsanoMeetup3_16, + // 500 + kStringArsanoMeetup3_17, kStringArsanoMeetup3_18, kStringArsanoMeetup3_19, kStringArsanoMeetup3_20, kStringArsanoMeetup3_21, + kStringArsanoMeetup3_22, kStringArsanoMeetup3_23, kStringArsanoMeetup3_24, kStringArsanoMeetup3_25, kStringArsanoMeetup3_26, + kStringArsanoMeetup3_27, kStringArsanoMeetup3_28, kStringAxacussCell_1, kStringAxacussCell_2, kStringAxacussCell_3, + kStringAxacussCell_4, kStringAxacussCell_5, kStringOk, kStringDialogArsanoMeetup2_1, kStringDialogArsanoMeetup2_2, + kStringDialogArsanoMeetup2_3, kStringDialogArsanoMeetup2_4, kStringDialogArsanoMeetup2_5, kStringDialogArsanoMeetup2_6, kStringDialogArsanoMeetup2_7, + // 525 + kStringDialogArsanoMeetup2_8, kStringDialogArsanoMeetup2_9, kStringDialogArsanoMeetup2_10, kStringDialogArsanoMeetup2_11, kStringDialogAxacussCorridor5_1, + kStringDialogAxacussCorridor5_2, kStringDialogAxacussCorridor5_3, kStringDialogAxacussCorridor5_4, kStringDialogAxacussCorridor5_5, kStringDialogAxacussCorridor5_6, + kStringDialogAxacussCorridor5_7, kStringDialogX1, kStringDialogX2, kStringDialogX3, kStringAxacussCorridor5_1, + kStringAxacussCorridor5_2, kStringAxacussCorridor5_3, kStringAxacussCorridor5_4, kStringAxacussCorridor5_5, kStringAxacussCorridor5_6, + kStringAxacussCorridor5_7, kStringAxacussBcorridor_1, kStringAxacussOffice1_1, kStringAxacussOffice1_2, kStringAxacussOffice1_3, + // 550 + kStringAxacussOffice1_4, kStringAxacussOffice1_5, kStringAxacussOffice1_6, kStringAxacussOffice1_7, kStringAxacussOffice1_8, + kStringAxacussOffice1_9, kStringAxacussOffice1_10, kStringAxacussOffice1_11, kStringAxacussOffice1_12, kStringAxacussOffice1_13, + kStringAxacussOffice1_14, kStringAxacussOffice1_15, kStringAxacussOffice1_16, kStringAxacussOffice3_1, kStringAxacussElevator_1, + kStringAxacussElevator_2, kStringAxacussElevator_3, kStringShock, kStringShot, kStringCloseLocker_1, + kStringIsHelmetOff_1, kStringGenericInteract_1, kStringGenericInteract_2, kStringGenericInteract_3, kStringGenericInteract_4, + // 575 + kStringGenericInteract_5, kStringGenericInteract_6, kStringGenericInteract_7, kStringGenericInteract_8, kStringGenericInteract_9, + kStringGenericInteract_10, kStringGenericInteract_11, kStringGenericInteract_12, + kStringGenericInteract_13, kStringGenericInteract_14, kStringGenericInteract_15, kStringGenericInteract_16, kStringGenericInteract_17, + kStringGenericInteract_18, kStringGenericInteract_19, kStringGenericInteract_20, kStringGenericInteract_21, kStringGenericInteract_22, + kStringGenericInteract_23, kStringGenericInteract_24, kStringGenericInteract_25, kStringGenericInteract_26, kStringGenericInteract_27, + // 600 + kStringGenericInteract_28, kStringGenericInteract_29, kStringGenericInteract_30, kStringGenericInteract_31, kStringGenericInteract_32, + kStringGenericInteract_33, kStringGenericInteract_34, kStringGenericInteract_35, kStringGenericInteract_36, kStringGenericInteract_37, + kStringGenericInteract_38, kStringGenericInteract_39, kStringGenericInteract_40, kStringGenericInteract_41, kStringGenericInteract_42, + kStringGenericInteract_43, kStringSupernova1, kStringSupernova2, kStringSupernova3, + kStringSupernova4, kStringSupernova5, kStringSupernova6, kStringSupernova7, kStringSupernova8, + // 625 + kStringTextSpeed, kStringGuardNoticed1, kStringGuardNoticed2, kStringTelomat1, kStringTelomat2, + kStringTelomat3, kStringTelomat4, kStringTelomat5, kStringTelomat6, kStringTelomat7, + kStringTelomat8, kStringTelomat9, kStringTelomat10, kStringTelomat11, kStringTelomat12, + kStringTelomat13, kStringTelomat14, kStringTelomat15, kStringTelomat16, kStringTelomat17, + kStringTelomat18, kStringTelomat19, kStringTelomat20, kStringTelomat21, kStringAlarm, + // 650 + kStringLeaveGame, kStringYes, kStringNo, kStringHelpOverview1, kStringHelpOverview2, + kStringHelpOverview3, kStringHelpOverview4, kStringHelpOverview5, kStringHelpOverview6, kStringHelpOverview7, + + // Add two placeholder strings at the end for variable text + kStringPlaceholder1, kStringPlaceholder2, + + // String for money in inventory + kStringInventoryMoney +}; +} +#endif // SUPERNOVA_STRINGID_H diff --git a/engines/supernova/supernova2/rooms.cpp b/engines/supernova/supernova2/rooms.cpp new file mode 100644 index 0000000000..01ccb59463 --- /dev/null +++ b/engines/supernova/supernova2/rooms.cpp @@ -0,0 +1,4758 @@ +/* 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 "common/system.h" +#include "common/config-manager.h" +#include "graphics/palette.h" +#include "graphics/cursorman.h" + +#include "supernova/screen.h" +#include "supernova/supernova.h" +#include "supernova/supernova2/state.h" +#include "supernova/supernova2/rooms.h" +#include "supernova/supernova2/stringid.h" +#include "supernova/graphics.h" + +namespace Supernova { + +Intro2::Intro2(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = -1; + _id = INTRO2; + + _objectState[0] = Object(_id, kStringKnife, kStringKnifeDescription, KNIFE, TAKE | CARRIED | COMBINABLE, 255, 255, 0); + _objectState[1] = Object(_id, kStringMoney, kStringDefaultDescription, MONEY, TAKE | CARRIED | COMBINABLE, 255, 255, 0); + _objectState[2] = Object(_id, kStringDiscman, kStringDiscmanDescription, DISCMAN, TAKE | CARRIED | COMBINABLE, 255, 255, 0); + _objectState[3] = Object(_id, kStringSuctionCup, kStringSuctionCupDescription, SUCTION_CUP, TAKE | COMBINABLE, 255, 255, 0); + _objectState[4] = Object(_id, kStringDefaultDescription, kStringDefaultDescription, NULLOBJECT, NULLTYPE, 0, 0, 0); + _objectState[5] = Object(_id, kStringSpecialCard, kStringSpecialCardDescription, SP_KEYCARD, TAKE | COMBINABLE, 255, 255, 0); + _objectState[6] = Object(_id, kStringAlarmCracker, kStringAlarmCrackerDescription, ALARM_CRACKER, TAKE | COMBINABLE, 255, 255, 0); + _objectState[7] = Object(_id, kStringDinosaurHead, kStringDefaultDescription, NULLOBJECT, TAKE, 255, 255, 0); + _objectState[8] = Object(_id, kStringKeycard, kStringDefaultDescription, MUSCARD, TAKE, 255, 255, 0); + + _introText = + _vm->getGameString(kStringIntro1) + '\0' + + _vm->getGameString(kStringIntro2) + '\0' + + _vm->getGameString(kStringIntro3) + '\0' + + _vm->getGameString(kStringIntro4) + '\0' + + _vm->getGameString(kStringIntro5) + '\0' + + "^Matthias Neef#" + '\0' + + "^Sascha Otterbach#" + '\0' + + "^Thomas Mazzoni#" + '\0' + + "^Matthias Klein#" + '\0' + + "^Gerrit Rothmaier#" + '\0' + + "^Thomas Hassler#" + '\0' + + "^Rene Kach#" + '\0' + + '\233' + '\0'; +} + +void Intro2::onEntrance() { + _gm->_guiEnabled = false; + _vm->_allowSaveGame = false; + _vm->_allowLoadGame = false; + + titleScreen(); + if (!(thoughts1() && tvDialogue() && thoughts2())) + _gm->_rooms[AIRPORT]->setRoomSeen(true); + _vm->paletteFadeOut(); + + for (int i = 0; i < 3; ++i) + _gm->_inventory.add(*_gm->_rooms[INTRO2]->getObject(i)); + + _gm->changeRoom(AIRPORT); + _gm->_guiEnabled = true; + _vm->_allowSaveGame = true; + _vm->_allowLoadGame = true; +} + +void Intro2::titleScreen() { + CursorMan.showMouse(false); + _vm->_system->fillScreen(kColorBlack); + _vm->_screen->setViewportBrightness(0); + _vm->_screen->setGuiBrightness(0); + _vm->paletteBrightness(); + _vm->setCurrentImage(1); + _vm->renderImage(0); + _vm->paletteFadeIn(); + _gm->wait(15); + _vm->renderImage(1); + _gm->wait(15); + _vm->renderImage(2); + const Common::String title1 = "V1.02"; + _vm->_screen->renderText(title1, 295, 190, 3); + + _vm->playSound(kMusicIntro); + Marquee marquee(_vm->_screen, Marquee::kMarqueeIntro, _introText.c_str()); + while (!_vm->shouldQuit()) { + _gm->updateEvents(); + marquee.renderCharacter(); + if (_gm->_mouseClicked || _gm->_keyPressed) + break; + g_system->updateScreen(); + g_system->delayMillis(_vm->_delay); + } + _vm->stopSound(); + _vm->paletteFadeOut(); + CursorMan.showMouse(true); +} + +bool Intro2::displayThoughtMessage(int id) { + Common::KeyCode key = Common::KEYCODE_INVALID; + const Common::String& text = _vm->getGameString(id); + _vm->renderMessage(text, kMessageNormal); + if (_gm->waitOnInput((text.size() + 20) * _vm->_textSpeed / 10, key)) { + _vm->removeMessage(); + return key != Common::KEYCODE_ESCAPE && !_vm->shouldQuit(); + } + _vm->removeMessage(); + return true; +} + +bool Intro2::thoughts1() { + if(_vm->shouldQuit()) + return false; + + _vm->setCurrentImage(41); + _vm->renderImage(0); + _vm->paletteFadeIn(); + + if(!displayThoughtMessage(kStringIntro6)) + return false; + + if(!displayThoughtMessage(kStringIntro7)) + return false; + + if(!displayThoughtMessage(kStringIntro8)) + return false; + + _vm->paletteFadeOut(); + return true; +} + +bool Intro2::thoughts2() { + if(_vm->shouldQuit()) + return false; + + _vm->setCurrentImage(41); + _vm->renderImage(0); + _vm->paletteFadeIn(); + + if(!displayThoughtMessage(kStringIntro9)) + return false; + + if(!displayThoughtMessage(kStringIntro10)) + return false; + + if(!displayThoughtMessage(kStringIntro11)) + return false; + + _vm->paletteFadeOut(); + + _vm->setCurrentImage(2); + _vm->renderImage(0); + _vm->renderImage(1); + _vm->paletteFadeIn(); + + for (int i = 0; i < 35; i++) + { + _vm->renderImage((i % 3) + 2); + _gm->wait(3); + } + _vm->paletteFadeOut(); + + _vm->setCurrentImage(41); + _vm->renderImage(0); + _vm->renderImage(1); + _vm->paletteFadeIn(); + + if(!displayThoughtMessage(kStringIntro12)) + return false; + + if(!displayThoughtMessage(kStringIntro13)) + return false; + + if(!displayThoughtMessage(kStringIntro14)) + return false; + + _vm->paletteFadeOut(); + return true; +} + +bool Intro2::tvDialogue() { + if(_vm->shouldQuit()) + return false; + + _vm->setCurrentImage(39); + _vm->renderImage(0); + _vm->paletteFadeIn(); + _gm->wait(50); + _vm->setCurrentImage(40); + _vm->renderImage(0); + for (int i = 1; i < 11; i++) + { + _gm->wait(3); + _vm->renderImage(i); + } + _vm->playSound(kAudioIntroDing); + _gm->wait(30); + _vm->renderImage(11); + _vm->playSound(kAudioIntroDing); + _gm->wait(60); + + _vm->_system->fillScreen(kColorBlack); + _vm->setCurrentImage(42); + _vm->renderImage(0); + + if(!_gm->talk(1, 1+128, 0, kMessageLeft, kStringIntroTV1)) + return false; + + _vm->renderImage(4); + _gm->wait(3); + _vm->renderImage(6); + + if(!_gm->talk(8, 6, 7, kMessageLeft, kStringIntroTV2)) + return false; + debug("%d", _vm->shouldQuit()); + + _vm->renderImage(10); + + if(!_gm->talkRest(8, 6, _gm->_restTime)) + return false; + + _vm->removeMessage(); + + if(!_gm->talk(8, 6, 0, kMessageLeft, kStringIntroTV3)) + return false; + + if(!_gm->talk(8, 6, 0, kMessageLeft, kStringIntroTV4)) + return false; + + _vm->renderImage(10 + 128); + _gm->wait(3); + _vm->renderImage(5); + _gm->wait(3); + _vm->renderImage(7); + + if(!_gm->talk(9, 7, 0, kMessageCenter, kStringIntroTV5)) + return false; + + if(!_gm->talk(9, 7, 0, kMessageCenter, kStringIntroTV6)) + return false; + + if(!_gm->talk(9, 7, 0, kMessageCenter, kStringIntroTV7)) + return false; + + if(!_gm->talk(3, 3 + 128, 0, kMessageRight, kStringIntroTV8)) + return false; + + if(!_gm->talk(3, 3 + 128, 0, kMessageRight, kStringIntroTV9)) + return false; + + if(!_gm->talk(9, 7, 0, kMessageCenter, kStringIntroTV10)) + return false; + + if(!_gm->talk(3, 3 + 128, 0, kMessageRight, kStringIntroTV11)) + return false; + + if(!_gm->talk(3, 3 + 128, 0, kMessageRight, kStringIntroTV12)) + return false; + + if(!_gm->talk(9, 7, 8, kMessageCenter, kStringIntroTV13)) + return false; + + _vm->renderImage(4); + + if(!_gm->talkRest(9, 7, 1)) + return false; + + _vm->renderImage(4 + 128); + + if(!_gm->talkRest(9, 7, 3)) + return false; + + _vm->renderImage(4); + + if(!_gm->talkRest(9, 7, 1)) + return false; + + _vm->renderImage(6); + + if(!_gm->talkRest(9, 7, _gm->_restTime - 5)) + return false; + + _vm->removeMessage(); + + if(!_gm->talk(3, 3 + 128, 0, kMessageRight, kStringIntroTV14)) + return false; + + if(!_gm->talk(3, 3 + 128, 0, kMessageRight, kStringIntroTV15)) + return false; + + if(!_gm->talk(9, 7, 0, kMessageCenter, kStringIntroTV16)) + return false; + + return true; +} + +Airport::Airport(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 2; + _id = AIRPORT; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringSpaceship, kStringSpaceshipDescription, NULLOBJECT, NULLTYPE, 0, 0, 0, NULLROOM, 0); + _objectState[1] = Object(_id, kStringVehicles, kStringVehiclesDescription, NULLOBJECT, EXIT, 1, 1, 0, TAXISTAND, 8); +} + +void Airport::onEntrance() { + if (hasSeen() == false) { + _vm->renderMessage(kStringAirportEntrance); + } + setRoomSeen(true); +} + +TaxiStand::TaxiStand(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 3; + _id = TAXISTAND; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + _shown[2] = kShownTrue; + _shown[7] = kShownTrue; + + _objectState[0] = Object(_id, kStringVehicle, kStringVehicleDescription, TAXI, NULLTYPE, 2, 2, 0, NULLROOM, 11); + _objectState[1] = Object(_id, kStringVehicle, kStringVehicleDescription, NULLOBJECT, NULLTYPE, 1, 1, 0); + _objectState[2] = Object(_id, kStringEntrance, kStringEntranceDescription, DOOR, EXIT | OPENABLE | CLOSED, 3, 3, 0, NULLROOM, 1); + _objectState[3] = Object(_id, kStringWallet, kStringWalletDescription, WALLET, TAKE, 0, 0, 7 + 128); + _objectState[4] = Object(_id, kStringDevice, kStringDeviceDescription, TRANSMITTER, TAKE | PRESS, 255, 255, 0); + _objectState[5] = Object(_id, kStringIdCard, kStringIdCardDescription, ID_CARD, TAKE | COMBINABLE, 255, 255, 0); + _objectState[6] = Object(_id, kStringAirport, kStringDefaultDescription, NULLOBJECT, EXIT, 255, 255, 0, AIRPORT, 22); +} + +void TaxiStand::onEntrance() { + setRoomSeen(true); +} + +void TaxiStand::animation() { + if (isSectionVisible(4)) { + setSectionVisible(1, kShownFalse); + setSectionVisible(2, kShownFalse); + setSectionVisible(3, kShownFalse); + setSectionVisible(4, kShownFalse); + } + else if (isSectionVisible(3)) + setSectionVisible(4, kShownTrue); + else if (isSectionVisible(2)) + setSectionVisible(3, kShownTrue); + else if (isSectionVisible(1)) + setSectionVisible(2, kShownTrue); + else + setSectionVisible(1, kShownTrue); + _gm->setAnimationTimer(7); +} + +bool TaxiStand::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_WALK && obj1._id == TAXI && isSectionVisible(6)) + _gm->taxi(); + else if ((verb == ACTION_WALK || verb == ACTION_OPEN) && obj1._id == DOOR) + _vm->renderMessage(obj1._description); + else + return false; + return true; +} + +Street::Street(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 5; + _id = STREET; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringEntrance, kStringDefaultDescription, NULLOBJECT, EXIT, 0, 0, 0, GAMES, 10); + _objectState[1] = Object(_id, kStringStaircase, kStringStaircaseDescription, NULLOBJECT, NULLTYPE, 2, 2, 0); + _objectState[2] = Object(_id, kStringBusinessStreet, kStringBusinessStreetDescription, REAR_STREET, EXIT, 3, 3, 0, KIOSK, 3); + _objectState[3] = Object(_id, kStringRod, kStringLooksMetal, ROD, COMBINABLE, 7, 7, 22); + _objectState[4] = Object(_id, kStringRod, kStringLooksMetal, ROD, COMBINABLE, 6, 6, 0); + _objectState[5] = Object(_id, kStringPost, kStringLooksMetal, NULLOBJECT, NULLTYPE, 4, 4, 0); + _objectState[6] = Object(_id, kStringRailing, kStringLooksMetal, NULLOBJECT, NULLTYPE, 5, 5, 0); +} + +void Street::onEntrance() { + setRoomSeen(true); +} + +void Street::animation() { + static int ltab[36] = { + 8, 9 + 128, 10, 11 + 128, 6, 12, 13 + 128, 9, 14, 15 + 128, 19, + 16, 17 + 128, 9 + 128, 18, 19 + 128, 6 + 128, 20, 21 + 128, + 8 + 128, 9, 10 + 128, 11, 6, 12 + 128, 13, 14 + 128, 15, 19, + 16 + 128, 17, 18 + 128, 19 + 128, 6 + 128, 20 + 128, 21 + }; + + static int i, banks, light; + + if (isSectionVisible(7)) + setSectionVisible(7, kShownFalse); + else + setSectionVisible(7, kShownTrue); + + if (++i == 4) { + i = 0; + switch (banks) { + case 0: + setSectionVisible(1, kShownTrue); + break; + case 1: + setSectionVisible(2, kShownTrue); + break; + case 2: + setSectionVisible(3, kShownTrue); + break; + case 3: + setSectionVisible(4, kShownTrue); + break; + case 4: + setSectionVisible(5, kShownTrue); + break; + case 5: + // fall through + case 7: + // fall through + case 9: + setSectionVisible(1, kShownFalse); + setSectionVisible(2, kShownFalse); + setSectionVisible(3, kShownFalse); + setSectionVisible(4, kShownFalse); + setSectionVisible(5, kShownFalse); + break; + case 6: + // fall through + case 8: + setSectionVisible(1, kShownTrue); + setSectionVisible(2, kShownTrue); + setSectionVisible(3, kShownTrue); + setSectionVisible(4, kShownTrue); + setSectionVisible(5, kShownTrue); + break; + } + banks++; + if (banks == 10) banks = 0; + } + setSectionVisible(ltab[light], kShownTrue); + light++; + if (light == 36) + light = 0; + _gm->setAnimationTimer(2); +} + +bool Street::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_USE && Object::combine(obj1, obj2, KNIFE, ROD)) { + if (getObject(3)->_type & CARRIED) + _vm->renderMessage(kStringAlreadyHavePole); + else { + _vm->renderMessage(kStringSawPole); + _gm->takeObject(*getObject(3)); + _vm->playSound(kAudioSuccess2); + } + } else if (verb == ACTION_WALK && obj1._id == REAR_STREET) { + Common::String text = _vm->getGameString(kStringOnlyShop); + _vm->renderMessage(text); + _gm->waitOnInput((text.size() + 20) * _vm->_textSpeed / 10); + _vm->removeMessage(); + return false; + } else + return false; + return true; +} + +Games::Games(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 6; + _id = GAMES; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringPoster, kStringPosterDescription, POSTER, UNNECESSARY, 3, 3, 0); + _objectState[1] = Object(_id, kStringCabin, kStringCabinFree, NULLOBJECT, EXIT, 1, 1, 0, CABIN2, 9); + _objectState[2] = Object(_id, kStringCabin, kStringCabinOccupied, OCCUPIED_CABIN, NULLTYPE, 0, 0, 0); + _objectState[3] = Object(_id, kStringFeet, kStringFeetDescription, NULLOBJECT, NULLTYPE, 2, 2, 0); + _objectState[4] = Object(_id, kStringExit, kStringDefaultDescription, NULLOBJECT, EXIT, 255, 255, 0, STREET, 22); +} + +void Games::onEntrance() { + setRoomSeen(true); +} + +bool Games::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_WALK && obj1._id == OCCUPIED_CABIN) { + _vm->renderMessage(kStringCabinOccupiedSay); + } else if (verb == ACTION_LOOK && obj1._id == POSTER) { + _gm->_state._taxiPossibility &= ~4; // add culture palace + return false; + } else + return false; + return true; +} + +Cabin2::Cabin2(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 7; + _id = CABIN2; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringExit, kStringDefaultDescription, NULLOBJECT, EXIT, 255, 255, 0, GAMES, 22); + _objectState[1] = Object(_id, kStringHood, kStringHoodDescription, NULLOBJECT, NULLTYPE, 0, 0, 0); + _objectState[2] = Object(_id, kString400Xa, kStringDefaultDescription, PRIZE, TAKE, 255, 255, 2 + 180); + _objectState[3] = Object(_id, kString10Xa, kStringDefaultDescription, BACK_MONEY, TAKE, 255, 255, 2 + 128); + _objectState[4] = Object(_id, kStringSlot, kStringSlotDescription1, SLOT1, COMBINABLE, 2, 2, 0); + _objectState[5] = Object(_id, kStringSlot, kStringSlotDescription2, NULLOBJECT, COMBINABLE, 3, 3, 0); + _objectState[6] = Object(_id, kStringChair, kStringChairDescription, CHAIR, NULLTYPE, 4, 4, 0); + _objectState[7] = Object(_id, kStringScribble, kStringDefaultDescription, SCRIBBLE1, NULLTYPE, 5, 5, 0); + _objectState[8] = Object(_id, kStringScribble, kStringDefaultDescription, SCRIBBLE2, NULLTYPE, 6, 6, 0); + _objectState[9] = Object(_id, kStringFace, kStringFaceDescription, NULLOBJECT, NULLTYPE, 7, 7, 0); + _objectState[10] = Object(_id, kStringSign, kStringDefaultDescription, SIGN, UNNECESSARY, 1, 1, 0); +} + +void Cabin2::onEntrance() { + setRoomSeen(true); +} + +void Cabin2::animation() { + if (_shown[kMaxSection - 1]) { + if (isSectionVisible(1)) + _vm->renderImage(1 + 128); + else + _vm->renderImage(1); + } + _gm->setAnimationTimer(4); +} + +bool Cabin2::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_USE && Object::combine(obj1, obj2, MONEY, SLOT1)) { + if (isSectionVisible(2)) + _vm->renderMessage(kStringTakeMoney); + else if (_shown[kMaxSection - 1]) + _vm->renderMessage(kStringAlreadyPaid); + else if (_gm->_state._money < 10) + _vm->renderMessage(kStringNoMoney); + else { + _vm->renderMessage(kStringPay10Xa); + _gm->takeMoney(-10); + _shown[kMaxSection - 1] = true; + } + } else if (verb == ACTION_USE && obj1._id == CHAIR) { + if (_shown[kMaxSection - 1]) { + if (_shown[kMaxSection - 2]) { + _vm->paletteFadeOut(); + _vm->setCurrentImage(31); + _vm->renderImage(0); + _vm->paletteFadeIn(); + _shown[kMaxSection - 1] = true; + _gm->getInput(); + _vm->paletteFadeOut(); + _vm->setCurrentImage(7); + _vm->renderImage(0); + setSectionVisible(1, kShownFalse); + _shown[kMaxSection - 1] = false; + _vm->renderRoom(*this); + _vm->renderImage(2); + _gm->drawGUI(); + _vm->paletteFadeIn(); + getObject(3)->_click = 8; + } else { + _gm->_state._tipsy = false; + _vm->paletteFadeOut(); + _vm->_system->fillScreen(kColorBlack); + _vm->_screen->setViewportBrightness(255); + Common::String text = _vm->getGameString(kStringWillPassOut); + _vm->renderMessage(text); + _gm->waitOnInput((text.size() + 20) * _vm->_textSpeed / 10); + _vm->removeMessage(); + _vm->paletteFadeOut(); + _vm->saveGame(kSleepAutosaveSlot, "autosave"); + _gm->_inventory.clear(); + _gm->changeRoom(PYRAMID); + _gm->drawGUI(); + } + } else + _vm->renderMessage(kStringRest); + } else if (verb == ACTION_TAKE && obj1._id == PRIZE) { + _vm->renderImage(2 + 128); + obj1._click = 255; + _gm->takeMoney(400); + } else if (verb == ACTION_TAKE && obj1._id == BACK_MONEY) { + _vm->renderImage(2 + 128); + obj1._click = 255; + _gm->takeMoney(10); + } else if (verb == ACTION_LOOK && obj1._id == SCRIBBLE1) { + _vm->renderMessage(kStringCypher); + } else if (verb == ACTION_LOOK && obj1._id == SCRIBBLE2) { + _gm->animationOff(); + _vm->setCurrentImage(28); + _vm->renderImage(0); + _gm->getInput(); + _vm->setCurrentImage(7); + _vm->renderRoom(*this); + _gm->drawGUI(); + _gm->_state._addressKnown = true; + _gm->animationOn(); + } else if (verb == ACTION_LOOK && obj1._id == SIGN) { + _gm->animationOff(); + _vm->setCurrentImage(38); + _vm->renderImage(0); + _gm->getInput(); + _vm->setCurrentImage(7); + _vm->renderRoom(*this); + _gm->drawGUI(); + _gm->animationOn(); + } else + return false; + return true; +} + +Kiosk::Kiosk(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 19; + _id = KIOSK; + _shown[0] = kShownTrue; + _shown[2] = kShownTrue; + _shown[3] = kShownTrue; + _shown[4] = kShownTrue; + _shown[5] = kShownTrue; + + _objectState[0] = Object(_id, kStringExit, kStringDefaultDescription, NULLOBJECT, EXIT, 255, 255, 0, STREET, 22); + _objectState[1] = Object(_id, kStringBooks, kStringDefaultDescription, BOOKS, UNNECESSARY, 0, 0, 0); + _objectState[2] = Object(_id, kStringDictionary, kStringDefaultDescription, LEXICON, UNNECESSARY, 1, 1, 0); + _objectState[3] = Object(_id, kStringPlant, kStringDefaultDescription, PLANT, UNNECESSARY, 2, 2, 0); + _objectState[4] = Object(_id, kStringMask, kStringDefaultDescription, BMASK, UNNECESSARY, 4, 4, 2 + 128); + _objectState[5] = Object(_id, kStringSnake, kStringDefaultDescription, SNAKE, UNNECESSARY, 3, 3, 0); + _objectState[6] = Object(_id, kStringCup, kStringDefaultDescription, CUP, UNNECESSARY, 5, 5, 0); + _objectState[7] = Object(_id, kStringJoystick, kStringDefaultDescription, JOYSTICK, UNNECESSARY, 6, 6, 0); + _objectState[8] = Object(_id, kStringToothbrush, kStringToothbrushDescription, TOOTHBRUSH, TAKE, 7, 7, 5 + 128); + _objectState[9] = Object(_id, kStringMusic, kStringMusicDescription, PLAYER, TAKE | COMBINABLE, 8, 8, 4 + 128); + _objectState[10] = Object(_id, kStringBottle, kStringBottleDescription, BOTTLE, TAKE, 9, 9, 3 + 128); + _objectState[11] = Object(_id, kStringBottle, kStringDefaultDescription, BOTTLE1, UNNECESSARY, 10, 10, 0); + _objectState[12] = Object(_id, kStringBottle, kStringDefaultDescription, BOTTLE2, UNNECESSARY, 11, 11, 0); + _objectState[13] = Object(_id, kStringBottle, kStringDefaultDescription, BOTTLE3, UNNECESSARY, 12, 12, 0); + _objectState[14] = Object(_id, kStringBottle, kStringDefaultDescription, BOTTLE4, UNNECESSARY, 13, 13, 0); + _objectState[15] = Object(_id, kStringBox, kStringDefaultDescription, BOX, UNNECESSARY, 14, 14, 0); + _objectState[16] = Object(_id, kStringFace, kStringDefaultDescription, FACES, UNNECESSARY, 15, 15, 0); + _objectState[17] = Object(_id, kStringSeller, kStringDefaultDescription, SELLER, TALK, 16, 16, 0); +} + +void Kiosk::onEntrance() { + static int dialEntry[2] = { + kStringGoodEvening, + kStringHello + }; + + if (!hasSeen()) { + _gm->dialog(2, _gm->_dials, dialEntry, 0); + _vm->renderImage(6); + _vm->playSound(kAudioKiosk); + _gm->wait(8); + _vm->renderImage(6 + 128); + _gm->reply(kStringScaredMe, 1, 1 +128); + _gm->say(kStringHowSo); + _gm->reply(kStringDisguise, 1, 1 +128); + _gm->say(kStringWhatDisguise); + _gm->reply(kStringStopPretending, 1, 1 +128); + _gm->reply(kStringYouDisguised, 1, 1 +128); + _gm->say(kStringIAmHorstHummel); + _gm->reply(kStringGiveItUp, 1, 1 +128); + _gm->reply(kStringGestures, 1, 1 +128); + _gm->reply(kStringMovesDifferently, 1, 1 +128); + _gm->say(kStringHeIsRobot); + _gm->reply(kStringYouAreCrazy, 1, 1 +128); + _gm->say(kStringYouIdiot); + _gm->reply(kStringShutUp, 1, 1 +128); + _gm->drawGUI(); + setRoomSeen(true); + } +} + +void Kiosk::animation() { +} + +bool Kiosk::interact(Action verb, Object &obj1, Object &obj2) { + static int dialPrice[2] = { + kStringWillTakeIt, + kStringTooExpensive + }; + static int dialSay[3] = { + kStringWouldBuy, + kStringMeHorstHummel, + kStringHaveMusicChip + }; + static int dialSeller[16][3] = { + {kStringGreatMask, kStringThreeYears, kNoString}, + {kStringStrongDrink, kNoString, kNoString}, + {kStringMusicDevice, kNoString, kNoString}, + {kStringArtusToothbrush, kStringSellInBulk, kNoString}, + {kStringRarityBooks, kNoString, kNoString}, + {kStringEncyclopedia, kStringLargestDictionary, kStringOver400Words}, + {kStringNotSale, kNoString, kNoString}, + {kStringGaveOne, kStringExcited, kNoString}, + {kStringFromGame, kNoString, kNoString}, + {kStringRobust, kNoString, kNoString}, + {kStringCheapSwill, kNoString, kNoString}, + {kStringCheapSwill, kNoString, kNoString}, + {kStringCheapSwill, kNoString, kNoString}, + {kStringCheapSwill, kNoString, kNoString}, + {kStringStickers, kNoString, kNoString}, + {kStringDishes, kStringUgly, kStringSellsWell} + }; + + if (verb == ACTION_TAKE && !(obj1._type & CARRIED) && + obj1._id >= BOTTLE && obj1._id <= TOOTHBRUSH) { + int price = 0; + switch (obj1._id) { + case BOTTLE: + price = 30; + break; + case PLAYER: + price = 50; + break; + case TOOTHBRUSH: + price = 5; + break; + default: + break; + } + Common::String format = _vm->getGameString(kStringThatCosts); + Common::String cost = Common::String::format(format.c_str(), price); + _vm->renderMessage(cost, kMessageTop); + _gm->reply(cost.c_str(), 1, 1 +128); + + if (_gm->_state._money < price) + _gm->say(dialPrice[1]); + else if (_gm->dialog(2, _gm->_dials, dialPrice, 0) == 0) { + _gm->takeObject(obj1); + _gm->takeMoney(-price); + } + _gm->drawGUI(); + } else if (verb == ACTION_LOOK && obj1._id >= BMASK && obj1._id <= FACES) { + for(int i = 0; i < 3; i++) { + _gm->reply(dialSeller[obj1._id - BMASK][i], 1, 1 + 128); + } + } else if (verb == ACTION_TALK && obj1._id >= SELLER) { + int i = 2; + if (getObject(9)->_type & CARRIED) + i++; + switch (_gm->dialog(i, _gm->_dials, dialSay, 0)) { + case 0: + _gm->reply(kStringTakeALook, 1, 1 + 128); + break; + case 1: + _gm->reply(kStringNonsense, 1, 1 + 128); + break; + case 2: + _gm->reply(kStringImSorry, 1, 1 + 128); + break; + } + _gm->drawGUI(); + } else + return false; + return true; +} + +CulturePalace::CulturePalace(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 20; + _id = CULTURE_PALACE; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringEntrance, kStringDefaultDescription, NULLOBJECT, EXIT, 1, 1, 0, CHECKOUT, 6); + _objectState[1] = Object(_id, kStringCulturePalace, kStringFascinating, NULLOBJECT, NULLTYPE, 0, 0, 0); + _objectState[2] = Object(_id, kStringTaxis, kStringTaxisDescription, NULLOBJECT, NULLTYPE, 3, 3, 0); + _objectState[3] = Object(_id, kStringAxacussan, kStringDefaultDescription, AXACUSSER, TALK, 4, 4, 0); + _objectState[4] = Object(_id, kStringParticipationCard, kStringDefaultDescription, CARD, TAKE, 255, 255, 0); +} + +void CulturePalace::onEntrance() { + setRoomSeen(true); +} + +void CulturePalace::animation() { + static int i; + if (isSectionVisible(4)) + setSectionVisible(4, kShownFalse); + else + setSectionVisible(4, kShownTrue); + i--; + if (i <= 0) { + if (isSectionVisible(3)) { + setSectionVisible(3, kShownFalse); + i = 4; + } else { + setSectionVisible(3, kShownTrue); + i = 10; + } + } + _gm->setAnimationTimer(2); +} + +void CulturePalace::notEnoughMoney() { + _gm->reply(kStringWhat, 2, 1); + _gm->reply(kStringNotInformed, 2, 1); + _vm->renderImage(1 + 128); + setSectionVisible(2, kShownFalse); +} + +bool CulturePalace::interact(Action verb, Object &obj1, Object &obj2) { + static int dial1[3] = { + kStringHorstHummel, + kStringNiceWeather, + kStringTellTicket, + }; + static byte dials1[] = {1, 1, 2}; + + static int dial2[2] = { + kStringHereIsXa, + kStringYouAreCrazy + }; + static int dial3[4] = { + kString500Xa, + kString1000Xa, + kString5000Xa, + kString10000Xa + }; + + int e; + if (verb == ACTION_TALK && obj1._id == AXACUSSER) { + if (_shown[kMaxSection - 3]) { + _vm->renderImage(1); + _gm->reply(kStringThankYou, 2, 1); + } else if (_shown[kMaxSection - 2]) { + _vm->renderImage(1); + _gm->reply(kStringWhatYouOffer, 2, 1); + } else { + _gm->say(kStringHello2); + _vm->renderImage(1); + _gm->reply(kStringWhatYouWant, 2, 1); + addSentence(1, 1); + switch (_gm->dialog(3, dials1, dial1, 1)) { + case 0: + _gm->reply(kStringWhoAreYou, 2, 1); + _gm->say(kStringHorstHummel2); + _gm->reply(kStringNeverHeard, 2, 1); + _gm->say(kStringYouDontKnow); + _gm->say(kStringImOnTV); + _gm->reply(kStringIDontKnow, 2, 1); + _gm->say(kStringFunny); + break; + case 1: + _gm->reply(kStringAha, 2, 1); + break; + case 2: + _gm->reply(kStringICan, 2, 1); + _gm->say(kStringFromWhom); + _gm->reply(kStringCost, 2, 1); + if(!_gm->_state._money) + addSentence(2, 1); + else if (_gm->dialog(2, _gm->_dials, dial2, 0)) { + _gm->reply(kStringAsYouSay, 2, 1); + addSentence(2, 1); + } else { + _gm->takeMoney(-1); + _gm->reply(kStringGetCard, 2, 1); + _gm->reply(kStringOnlyParticipation, 2, 1); + _gm->say(kStringWhatForIt); + _gm->reply(kStringMakeOffer, 2, 1); + _shown[kMaxSection - 2] = true; + } + break; + } + } + _vm->renderImage(1 + 128); + setSectionVisible(2, kShownFalse); + _gm->drawGUI(); + } + else if (verb == ACTION_GIVE && obj2._id == AXACUSSER && _shown[kMaxSection - 2]) { + _vm->renderImage(1); + if (obj1._id != MONEY) + notEnoughMoney(); + else { + if (_gm->_state._money >= 10000) { + if ((e = _gm->dialog(4, _gm->_dials, dial3, 0)) >= 2) { + _gm->reply(kStringGoodOffer, 2, 1); + _vm->playSound(kAudioSuccess2); + _gm->reply(kStringGiveCard, 2, 1); + if (e == 2) + _gm->takeMoney(-5000); + else + _gm->takeMoney(-10000); + _gm->takeObject(*getObject(4)); + _vm->renderImage(1 + 128); + setSectionVisible(2, false); + _gm->reply(kStringIdiot, 0, 0); + _shown[kMaxSection - 2] = false; + _shown[kMaxSection - 3] = true; + _gm->_rooms[CHECKOUT]->addSentence(1,1); + _gm->drawGUI(); + } else { + notEnoughMoney(); + _gm->drawGUI(); + } + } else + notEnoughMoney(); + } + } else + return false; + return true; +} + +Checkout::Checkout(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 21; + _id = CHECKOUT; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringEntrance, kStringDefaultDescription, KP_ENTRANCE, EXIT, 0, 0, 0, NULLROOM, 3); + _objectState[1] = Object(_id, kStringExit, kStringDefaultDescription, NULLOBJECT, EXIT, 255, 255, 0, CULTURE_PALACE, 22); + _objectState[2] = Object(_id, kStringAxacussian, kStringDefaultDescription, AXACUSSER, TALK, 1, 1, 0); +} + +void Checkout::onEntrance() { + if (!_shown[kMaxSection - 3]) { + _shown[kMaxSection - 3] = true; + _gm->reply(kStringAtMusicContest, 1, 1 + 128); + _gm->say(kStringNoImitation); + _gm->reply(kStringGoodJoke, 1, 1 + 128); + _gm->say(kStringIAmHorstHummel); + _gm->reply(kStringCommon, 1, 1 + 128); + _gm->say(kStringIWillProof); + _gm->say(kStringIWillPerform); + _gm->drawGUI(); + } + setRoomSeen(true); +} + +void Checkout::animation() { +} + +bool Checkout::interact(Action verb, Object &obj1, Object &obj2) { + static int dialCheckout1[3] = { + kStringCheckout1, + kStringCheckout2, + kStringCheckout3 + }; + static int dialCheckout2[2] = { + kStringYes, + kStringNo + }; + static int dialStage1[3] = { + kStringCheckout4, + kStringCheckout5, + kStringCheckout6 + }; + static int dialStage2[2] = { + kStringCheckout7, + kStringCheckout8 + }; + static int dialStage3[3] = { + kStringCheckout9, + kStringCheckout10, + kStringCheckout11 + }; + static int dialStage4[3] = { + kStringCheckout12, + kStringCheckout13 + }; + if (verb == ACTION_WALK && obj1._id == KP_ENTRANCE) { + if (_shown[kMaxSection - 4]) { + _vm->renderImage(2); + _gm->reply(kStringCheckout14, 0, 0); + _vm->renderImage(2 + 128); + } else if (_shown[kMaxSection - 2] == 0) { + _vm->renderImage(2); + _gm->reply(kStringCheckout15, 0, 0); + _vm->renderImage(2 + 128); + if (_gm->_rooms[CULTURE_PALACE]->getObject(4)->_type & CARRIED) { + _gm->say(kStringCheckout16); + _gm->reply(kStringCheckout17, 0, 0); + } else + _gm->say(kStringCheckout18); + _gm->drawGUI(); + } else if (_shown[kMaxSection - 2] == 1) { + _gm->reply(kStringCheckout19, 1, 1 + 128); + } else { + if (_gm->_state._tipsy) { + _vm->setCurrentImage(22); + _vm->renderImage(0); + if (_shown[kMaxSection - 5] && _gm->_state._admission >= 2) + appearance(); + else { + _gm->dialog(3, _gm->_dials, dialStage1, 0); + _gm->dialog(2, _gm->_dials, dialStage2, 0); + _vm->renderMessage(kStringCheckout20, 100, 70); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringCheckout21, 200, 40); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _gm->say(kStringCheckout22); + _gm->dialog(3, _gm->_dials, dialStage3, 0); + _vm->renderMessage(kStringCheckout23, 120, 70); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _gm->say(kStringCheckout24); + _vm->renderMessage(kStringCheckout25, 40, 100); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _gm->dialog(2, _gm->_dials, dialStage4, 0); + _vm->playSound(kAudioStage1); + while(_vm->_sound->isPlaying()) + _gm->wait(1); + _vm->playSound(kAudioStage1); + while(_vm->_sound->isPlaying()) + _gm->wait(1); + _vm->playSound(kAudioStage2); + while(_vm->_sound->isPlaying()) + _gm->wait(1); + _vm->playSound(kAudioStage2); + _vm->renderMessage(kStringCheckout26, 250, 80); + while(_vm->_sound->isPlaying()) + _gm->wait(1); + _vm->playSound(kAudioStage1); + while(_vm->_sound->isPlaying()) + _gm->wait(1); + _vm->removeMessage(); + _vm->playSound(kAudioStage2); + _vm->renderMessage(kStringCheckout27, 140, 60); + while(_vm->_sound->isPlaying()) + _gm->wait(1); + _vm->playSound(kAudioStage2); + while(_vm->_sound->isPlaying()) + _gm->wait(1); + _gm->wait(2); + _vm->removeMessage(); + _vm->playSound(kAudioStage2); + _vm->renderMessage(kStringCheckout26, 180, 50); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringCheckout28, 50, 110); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _gm->say(kStringCheckout29); + _vm->renderRoom(*this); + if (_shown[kMaxSection - 5]) + _vm->renderMessage(kStringCheckout30); + else + _vm->renderMessage(kStringCheckout31); + _shown[kMaxSection - 4] = true; + _gm->drawGUI(); + } + } else { + _vm->renderMessage(kStringCheckout32); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringCheckout33); + } + } + } else if (verb == ACTION_GIVE && obj1._id == CHIP && obj2._id == AXACUSSER && + _shown[kMaxSection - 2] == 1) { + _gm->_inventory.remove(obj1); + _shown[kMaxSection - 5] = true; + _gm->reply(kStringCheckout37, 1, 1 + 128); + _shown[kMaxSection - 2] = 2; + _gm->drawGUI(); + } else if (verb == ACTION_GIVE && obj1._id == CARD && obj2._id == AXACUSSER) { + _gm->_inventory.remove(*_gm->_rooms[CULTURE_PALACE]->getObject(4)); + _gm->reply(kStringCheckout34, 1, 1 + 128); + _gm->reply(kStringCheckout35, 1, 1 + 128); + if (_gm->dialog(2, _gm->_dials, dialCheckout2, 0) == 1) { + _gm->reply(kStringCheckout36, 1, 1 + 128); + _shown[kMaxSection - 2] = 1; + } else { + _gm->reply(kStringCheckout37, 1, 1 + 128); + _shown[kMaxSection - 2] = 2; + } + _gm->drawGUI(); + } else if (verb == ACTION_TALK && obj1._id == AXACUSSER) { + if (_shown[kMaxSection - 4]) { + _gm->say(kStringCheckout38); + _gm->reply(kStringCheckout39, 1, 1 + 128); + _gm->drawGUI(); + } else { + switch (_shown[kMaxSection - 2]) { + case 0: + addSentence(2, 1); + switch (_gm->dialog(3, _gm->_dials, dialCheckout1, 1)) { + case 0: + _gm->reply(kStringCheckout40, 1, 1 + 128); + _gm->say(kStringNo); + _gm->reply(kStringCheckout41, 1, 1 + 128); + _gm->say(kStringCheckout42); + break; + case 1: + _gm->reply(kStringCheckout43, 1, 1 + 128); + if (_gm->_rooms[CULTURE_PALACE]->getObject(4)->_type & CARRIED) { + _gm->say(kStringCheckout44); + return interact(ACTION_GIVE, + *_gm->_rooms[CULTURE_PALACE]->getObject(4), + *_gm->_rooms[CHECKOUT]->getObject(2)); + } else { + _gm->say(kStringNo); + _gm->reply(kStringCheckout45, 1, 1 + 128); + _gm->say(kStringCheckout46); + } + break; + case 2: + _gm->reply(kStringCheckout47, 1, 1 + 128); + break; + } + _gm->drawGUI(); + break; + case 1: + _gm->reply(kStringCheckout48, 1, 1 + 128); + break; + case 2: + _gm->reply(kStringCheckout49, 1, 1 + 128); + break; + } + } + } else + return false; + return true; +} + +void Checkout::shouting() { + static int i = 0; + switch(i) + { + case 50: + _vm->renderMessage(kStringShout1, 100, 60); + break; + case 130: + _vm->renderMessage(kStringShout2, 50, 90); + break; + case 200: + _vm->renderMessage(kStringShout3, 200, 80); + break; + case 300: + _vm->renderMessage(kStringShout4, 70, 30); + break; + case 400: + _vm->renderMessage(kStringShout5, 190, 90); + break; + case 450: + _vm->renderMessage(kStringShout6, 160, 60); + break; + case 500: + _vm->renderMessage(kStringShout7, 180, 70); + break; + case 530: + _vm->renderMessage(kStringShout8, 50, 20); + break; + case 610: + _vm->renderMessage(kStringShout9, 230, 50); + break; + case 650: + _vm->renderMessage(kStringShout10, 100, 90); + break; + case 720: + _vm->renderMessage(kStringShout11, 176, 65); + break; + case 800: + _vm->renderMessage(kStringShout12, 60, 20); + break; + case 850: + _vm->renderMessage(kStringShout13, 160, 40); + break; + case 930: + _vm->renderMessage(kStringShout14, 60, 95); + break; + case 1000: + _vm->renderMessage(kStringShout15, 100, 65); + break; + case 70: + // fall through + case 150: + // fall through + case 220: + // fall through + case 320: + // fall through + case 420: + // fall through + case 470: + // fall through + case 520: + // fall through + case 550: + // fall through + case 630: + // fall through + case 680: + // fall through + case 740: + // fall through + case 820: + // fall through + case 870: + // fall through + case 950: + // fall through + case 1020: + _vm->removeMessage(); + break; + default: {} //do nothing + } + i++; +} + +void Checkout::appearance() { + _vm->_allowSaveGame = false; + _vm->_allowLoadGame = false; + int xp = 0; + CursorMan.showMouse(false); + _vm->playSound(kMusicMadMonkeys); + Common::KeyCode k = Common::KEYCODE_INVALID; + while(_vm->_sound->isPlaying()) { + if (_gm->waitOnInput(1, k)) + break; + shouting(); + } + _vm->_sound->stop(); + _vm->removeMessage(); + CursorMan.showMouse(true); + _vm->removeMessage(); + _vm->playSound(kAudioAppearance1); + while (_vm->_sound->isPlaying() && !_vm->shouldQuit()) + _gm->wait(1); + _vm->paletteFadeOut(); + + _vm->setCurrentImage(39); + _vm->renderImage(0); + _vm->paletteFadeIn(); + _gm->wait(50); + _vm->setCurrentImage(40); + _vm->renderImage(0); + for (int i = 1; i < 11; i++) { + _gm->wait(3); + _vm->renderImage(i); + } + _vm->playSound(kAudioAppearance2); + _gm->wait(30); + _vm->renderImage(11); + _vm->playSound(kAudioAppearance2); + _gm->wait(60); + + _vm->_system->fillScreen(kColorBlack); + _vm->setCurrentImage(42); + _vm->renderImage(0); + _vm->renderImage(11); + _gm->talk(1, 1 + 128, 0, kMessageLeft, kStringAppearance1); + _gm->talk(1, 1 + 128, 0, kMessageLeft, kStringAppearance2); + _vm->renderImage(4); + _gm->wait(3); + _vm->renderImage(6); + _gm->talk(8, 6, 0, kMessageLeft, kStringAppearance3); + _gm->talk(12, 13, 0, kMessageCenter, kStringAppearance4); + _gm->talk(12, 13, 0, kMessageCenter, kStringAppearance5); + _gm->talk(3, 3 + 128, 0, kMessageRight, kStringAppearance6); + _gm->talk(12, 13, 0, kMessageCenter, kStringAppearance7); + _gm->talk(8, 6, 0, kMessageLeft, kStringAppearance8); + _gm->talk(12, 13, 4, kMessageCenter, kStringAppearance9); + _vm->renderImage(4); + _gm->talkRest(12, 13, 1); + _vm->renderImage(4 + 128); + _gm->talkRest(12, 13, 4); + _vm->renderImage(4); + _gm->talkRest(12, 13, 1); + _vm->renderImage(6); + _gm->talkRest(12, 13, _gm->_restTime + 6); + _vm->removeMessage(); + _gm->talk(3, 3 + 128, 0, kMessageRight, kStringAppearance10); + _gm->talk(12, 13, 0, kMessageCenter, kStringAppearance11); + _gm->talk(12, 13, 0, kMessageCenter, kStringAppearance12); + _gm->talk(3, 3 + 128, 0, kMessageRight, kStringAppearance13); + _gm->talk(12, 13, 0, kMessageCenter, kStringAppearance14); + _gm->talk(12, 13, 0, kMessageCenter, kStringAppearance15); + _gm->talk(3, 3 + 128, 0, kMessageRight, kStringAppearance16); + _gm->talk(12, 13, 2, kMessageCenter, kStringAppearance17); + _vm->renderImage(4); + _gm->talkRest(12, 13, 1); + _vm->renderImage(4 + 128); + _gm->talkRest(12, 13, 4); + _vm->renderImage(4); + _gm->talkRest(12, 13, 1); + _vm->renderImage(6); + _gm->talkRest(12, 13, _gm->_restTime + 6); + _vm->removeMessage(); + _gm->talk(8, 6, 0, kMessageLeft, kStringAppearance18); + _gm->talk(12, 13, 1, kMessageCenter, kStringAppearance19); + _vm->renderImage(4); + _gm->talkRest(12, 13, 1); + _vm->renderImage(4 + 128); + _gm->talkRest(12, 13, 4); + _vm->renderImage(4); + _gm->talkRest(12, 13, 1); + _vm->renderImage(6); + _gm->talkRest(12, 13, _gm->_restTime + 6); + _vm->removeMessage(); + _gm->talk(8, 6, 0, kMessageLeft, kStringAppearance20); + _gm->talk(12, 13, 1, kMessageCenter, kStringAppearance21); + _vm->renderImage(17); + _gm->wait(2); + _vm->renderImage(18); + _gm->wait(2); + _vm->renderImage(19); + _gm->wait(2); + _vm->renderImage(20); + _gm->wait(3); + _vm->renderImage(21); + _vm->renderImage(19); + _gm->wait(1); + _vm->renderImage(21+128); + _vm->renderImage(22); + _vm->renderImage(18); + _gm->wait(1); + _vm->renderImage(22+128); + _vm->renderImage(23); + _gm->wait(1); + _vm->renderImage(23+128); + _vm->renderImage(24); + _vm->renderImage(17); + _gm->wait(1); + _vm->renderImage(24+128); + _vm->renderImage(25); + _gm->wait(1); + _vm->renderImage(25+128); + _vm->renderImage(32); + _vm->renderImage(11); + _vm->renderImage(26); + _vm->playSound(kAudioAppearance3); + _gm->wait(2); + _vm->renderImage(32+128); + _vm->renderImage(33); + _vm->renderImage(27); + _gm->wait(2); + _vm->renderImage(33+128); + _vm->renderImage(34); + _vm->renderImage(28); + _gm->wait(2); + _vm->renderImage(29); + _gm->wait(2); + _vm->renderImage(30); + _gm->wait(2); + _vm->renderImage(31); + _gm->wait(2); + _gm->wait(50); + _vm->paletteFadeOut(); + + _vm->_system->fillScreen(kColorBlack); + _vm->_screen->setViewportBrightness(255); + _vm->_screen->setGuiBrightness(255); + _vm->paletteBrightness(); + _vm->renderMessage(kStringAppearance22); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringAppearance23); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringAppearance24); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringAppearance25); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringAppearance26); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringAppearance27); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->_screen->setViewportBrightness(0); + _vm->_screen->setGuiBrightness(0); + _vm->paletteBrightness(); + _vm->setCurrentImage(44); + _vm->renderImage(0); + _vm->paletteFadeIn(); + + MSNImage *image = _vm->_screen->getCurrentImage(); + + int i = 0; + do { + _vm->renderImage(1); + _gm->wait(1); + _vm->renderImage(1 + 128); + image->_section[1].x1 += xp; + image->_section[1].x2 += xp; + image->_section[1].y1 -= 2; + image->_section[1].y2 -= 2; + i++; + if (i == 6) { + i = 0; + xp++; + } + } while (image->_section[1].y1 < 200); + _vm->paletteFadeOut(); + _vm->_system->fillScreen(kColorBlack); + _vm->_screen->setViewportBrightness(255); + _vm->_screen->setGuiBrightness(255); + _vm->paletteBrightness(); + _vm->renderMessage(kStringAppearance28); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringAppearance29); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringAppearance30); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringAppearance31); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _gm->changeRoom(SHIP); + _gm->_state._dark = true; + _vm->_screen->setViewportBrightness(1); + _vm->paletteBrightness(); + _gm->drawGUI(); + _vm->_allowSaveGame = true; + _vm->_allowLoadGame = true; +} + +City1::City1(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 23; + _id = CITY1; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringSign, kStringSign1Description, NULLOBJECT, NULLTYPE, 2, 2, 0); + _objectState[1] = Object(_id, kStringSign, kStringSign2Description, NULLOBJECT, NULLTYPE, 3, 3, 0); + _objectState[2] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR_L, EXIT | OPENABLE, 0, 0, 1, ELEVATOR2, 10); + _objectState[3] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR_R, EXIT | OPENABLE, 1, 1, 2, ELEVATOR2, 14); +} + +void City1::onEntrance() { + setRoomSeen(true); +} + +void City1::animation() { +} + +bool City1::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_OPEN && obj1._id == DOOR_L) { + _objectState[0]._click = 255; + } else if (verb == ACTION_CLOSE && obj1._id == DOOR_L) { + _objectState[0]._click = 2; + } else if (verb == ACTION_OPEN && obj1._id == DOOR_R) { + _objectState[1]._click = 255; + } else if (verb == ACTION_CLOSE && obj1._id == DOOR_R) { + _objectState[1]._click = 3; + } else if (verb == ACTION_WALK && obj1._id == DOOR_L) { + _gm->_state._elevatorNumber = 1; + } else if (verb == ACTION_WALK && obj1._id == DOOR_R) { + _gm->_state._elevatorNumber = 2; + } + _gm->_rooms[ELEVATOR2]->getObject(5)->_exitRoom = CITY1; + _gm->_state._elevatorE = 0; + return false; +} + +City2::City2(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 23; + _id = CITY2; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringSign, kStringSign3Description, NULLOBJECT, NULLTYPE, 2, 2, 0); + _objectState[1] = Object(_id, kStringSign, kStringSign4Description, NULLOBJECT, NULLTYPE, 3, 3, 0); + _objectState[2] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR_L, EXIT | OPENABLE, 0, 0, 1, ELEVATOR2, 10); + _objectState[3] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR_R, EXIT | OPENABLE, 1, 1, 2, ELEVATOR2, 14); +} + +void City2::onEntrance() { + setRoomSeen(true); +} + +void City2::animation() { +} + +bool City2::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_OPEN && obj1._id == DOOR_L) { + _objectState[0]._click = 255; + } else if (verb == ACTION_CLOSE && obj1._id == DOOR_L) { + _objectState[0]._click = 2; + } else if (verb == ACTION_OPEN && obj1._id == DOOR_R) { + _objectState[1]._click = 255; + } else if (verb == ACTION_CLOSE && obj1._id == DOOR_R) { + _objectState[1]._click = 3; + } else if (verb == ACTION_WALK && obj1._id == DOOR_L) { + _gm->_state._elevatorNumber = 3; + } else if (verb == ACTION_WALK && obj1._id == DOOR_R) { + _gm->_state._elevatorNumber = 4; + } + _gm->_rooms[ELEVATOR2]->getObject(5)->_exitRoom = CITY2; + _gm->_state._elevatorE = 0; + return false; +} + +Elevator2::Elevator2(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 24; + _id = ELEVATOR2; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringSlot, kStringDefaultDescription, SLOT, COMBINABLE, 0, 0, 0); + _objectState[1] = Object(_id, kStringBell, kStringDefaultDescription, BELL, PRESS, 1, 1, 0); + _objectState[2] = Object(_id, kStringDisplay, kStringDefaultDescription, DISPLAY, NULLTYPE, 2, 2, 0); + _objectState[3] = Object(_id, kStringKeypad, kStringKeypadDescription, KEYPAD, PRESS, 3, 3, 0); + _objectState[4] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE | CLOSED, 4, 4, 0, APARTMENT, 3); + _objectState[5] = Object(_id, kStringExit, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE | OPENED | CLOSED, 255, 255, 0, CITY1, 22); +} + +void Elevator2::onEntrance() { + if (_gm->_state._elevatorE) + _objectState[5]._type &= ~OPENED; + else + _objectState[5]._type |= OPENED; +} + +void Elevator2::animation() { +} + +bool Elevator2::interact(Action verb, Object &obj1, Object &obj2) { + static int dialLuke1[4] = { + kStringElevator2, + kStringElevator3, + kStringElevator4, + kStringElevator5 + }; + static byte dialsLuke1[3] = {2,1,1}; + static int dialBoss1[2] = { + kStringElevator6, + kStringElevator7 + }; + Common::String input; + + if (verb == ACTION_LOOK && obj1._id == DISPLAY) { + Common::String format = _vm->getGameString(kStringElevator1); + Common::String display = + Common::String::format(format.c_str(), _gm->_state._elevatorE); + _vm->renderMessage(display); + } else if (verb == ACTION_PRESS && obj1._id == BELL) { + _vm->renderImage(8); + _vm->playSound(kAudioElevatorBell); + while(_vm->_sound->isPlaying()) + _gm->wait(1); + _vm->renderImage(8 + 128); + if (_gm->_state._elevatorNumber == 4 && _gm->_state._elevatorE == 4 && !_gm->_state._toMuseum) { + _gm->wait(18); + _vm->renderImage(1); + _gm->wait(3); + _vm->renderImage(2); + setSectionVisible(1, kShownFalse); + _gm->wait(3); + _vm->renderImage(3); + setSectionVisible(2, kShownFalse); + _gm->reply(kStringWhatYouWant, 4, 3); + switch (_gm->dialog(3, dialsLuke1, dialLuke1, 1)) { + case 0: + _gm->reply(kStringElevator11, 4, 3); + _vm->renderImage(2); + setSectionVisible(3, kShownFalse); + _gm->wait(3); + _vm->renderImage(1); + setSectionVisible(2, kShownFalse); + _gm->wait(3); + _vm->renderImage(1 + 128); + _vm->renderMessage(kStringElevator12); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderImage(1); + _gm->wait(3); + _vm->renderImage(2); + setSectionVisible(1, kShownFalse); + _gm->wait(3); + _vm->renderImage(3); + setSectionVisible(2, kShownFalse); + _gm->reply(kStringElevator13, 4, 3); + setSectionVisible(3, kShownFalse); + setSectionVisible(4, kShownFalse); + _vm->paletteFadeOut(); + _vm->_system->fillScreen(kColorBlack); + _vm->_screen->setViewportBrightness(255); + _vm->renderMessage(kStringElevator14); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->_screen->setViewportBrightness(0); + _vm->setCurrentImage(26); + _vm->renderImage(0); + _vm->paletteFadeIn(); + _gm->reply(kStringElevator15, 1, 1 + 128); + _gm->say(kStringYes); + _gm->reply(kStringElevator16, 1, 1 + 128); + _gm->reply(kStringElevator17, 1, 1 + 128); + if (_gm->dialog(2, _gm->_dials, dialBoss1, 0)) { + _gm->reply(kStringElevator18, 1, 1 + 128); + _gm->reply(kStringElevator19, 1, 1 + 128); + _gm->say(kStringElevator20); + } + _gm->reply(kStringElevator21, 1, 1 + 128); + _gm->reply(kStringElevator22, 1, 1 + 128); + _gm->reply(kStringElevator23, 1, 1 + 128); + _gm->reply(kStringElevator24, 1, 1 + 128); + _gm->reply(kStringElevator25, 1, 1 + 128); + _gm->reply(kStringElevator26, 1, 1 + 128); + _gm->reply(kStringElevator27, 1, 1 + 128); + _gm->reply(kStringElevator28, 1, 1 + 128); + jobDescription(); + return true; + case 1: + _gm->reply(kStringElevator59, 4, 3); + _vm->renderImage(2); + setSectionVisible(3, kShownFalse); + setSectionVisible(4, kShownFalse); + _gm->wait(3); + _vm->renderImage(1); + setSectionVisible(2, kShownFalse); + _vm->renderImage(1 + 128); + break; + case 2: + _gm->reply(kStringElevator60, 4, 3); + _vm->renderImage(2); + setSectionVisible(3, kShownFalse); + setSectionVisible(4, kShownFalse); + _gm->wait(3); + _vm->renderImage(1); + setSectionVisible(2, kShownFalse); + _vm->renderImage(1 + 128); + break; + } + _gm->drawGUI(); + } else + _vm->renderMessage(kStringElevator61); + } else if ((verb == ACTION_USE || verb == ACTION_PRESS) && obj1._id == KEYPAD) { + _vm->renderMessage(kStringElevator62); + do { + _gm->edit(input, 237, 66, 2); + } while ((_gm->_key.keycode != Common::KEYCODE_RETURN) && + (_gm->_key.keycode != Common::KEYCODE_ESCAPE) && !_vm->shouldQuit()); + _vm->removeMessage(); + if (_gm->_key.keycode == Common::KEYCODE_RETURN && input[0] != 0) { + for (unsigned i = 0; i < input.size(); i++) { + if (input[i] < '0' || input[i] > '9') { + _vm->renderMessage(kStringElevator63); + return true; + } + } + int64 number = input.asUint64(); + if (number > 60) + _vm->renderMessage(kStringElevator63); + else if (number != _gm->_state._elevatorE) { + if (isSectionVisible(6)) { + _vm->renderImage(6 + 128); + _objectState[4]._type &= ~OPENED; + _vm->playSound(kAudioElevator1); + } + _vm->renderMessage(kStringElevator64); + _gm->_state._elevatorE = number; + if (number) + _objectState[5]._type &= ~OPENED; + else + _objectState[5]._type |= OPENED; + } + } + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, ID_CARD, SLOT)) { + if (_gm->_state._elevatorNumber == 1 && _gm->_state._elevatorE == 32) { + _vm->renderImage(6); + _objectState[4]._type |= OPENED; + _vm->playSound(kAudioTaxiOpen); + } else + _vm->renderMessage(kStringElevator65); + } else + return false; + return true; +} + +void Elevator2::jobDescription() { + static int dialBoss2[3] = { + kStringElevator8, + kStringElevator9, + kStringElevator10 + }; + byte dialsBoss2[4] = {1,1,1,1}; + + _gm->reply(kStringElevator29, 1, 1 + 128); + _gm->reply(kStringElevator30, 1, 1 + 128); + _gm->reply(kStringElevator31, 1, 1 + 128); + _gm->reply(kStringElevator32, 1, 1 + 128); + _vm->setCurrentImage(30); + _vm->renderImage(0); + _gm->waitOnInput(72); + _gm->reply(kStringElevator33, 0, 0); + _gm->reply(kStringElevator34, 0, 0); + _gm->reply(kStringElevator35, 0, 0); + _gm->reply(kStringElevator36, 0, 0); + _gm->reply(kStringElevator37, 0, 0); + _gm->reply(kStringElevator38, 0, 0); + _gm->reply(kStringElevator39, 0, 0); + _gm->reply(kStringElevator40, 0, 0); + _gm->reply(kStringElevator41, 0, 0); + _gm->reply(kStringElevator42, 0, 0); + _gm->reply(kStringElevator43, 0, 0); + _gm->reply(kStringElevator44, 0, 0); + _gm->reply(kStringElevator45, 0, 0); + _gm->reply(kStringElevator46, 0, 0); + _gm->reply(kStringElevator47, 0, 0); + _gm->reply(kStringElevator48, 0, 0); + _vm->setCurrentImage(26); + _vm->_system->fillScreen(kColorBlack); + _vm->renderImage(0); + _gm->reply(kStringElevator49, 1, 1 + 128); + int e; + do { + addSentence(0, 2); + switch (e = _gm->dialog(4, dialsBoss2, dialBoss2, 2)) { + case 0: + _gm->reply(kStringElevator50, 1, 1 + 128); + jobDescription(); + return; + case 1: + _gm->reply(kStringElevator51, 1, 1 + 128); + break; + case 2: + _gm->reply(kStringElevator52, 1, 1 + 128); + break; + } + if (e == 1 || e == 2) + _gm->reply(kStringElevator53, 1, 1 + 128); + } while (e != 3); + _gm->reply(kStringElevator54, 1, 1 + 128); + _vm->paletteFadeOut(); + _vm->_system->fillScreen(kColorBlack); + _vm->_screen->setViewportBrightness(255); + _vm->renderMessage(kStringElevator55); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->_screen->setViewportBrightness(0); + _gm->_state._tipsy = false; + _gm->_state._toMuseum = true; + _vm->saveGame(kSleepAutosaveSlot, "autosave"); + _gm->_inventory.clear(); + _gm->takeObject(*_gm->_rooms[INTRO2]->getObject(3)); + _gm->takeObject(*_gm->_rooms[INTRO2]->getObject(5)); + _gm->takeObject(*_gm->_rooms[INTRO2]->getObject(6)); + _gm->takeObject(*_gm->_rooms[INTRO2]->getObject(8)); + _vm->setCurrentImage(29); + _gm->changeRoom(MUSEUM); + _vm->renderImage(0); + _vm->paletteFadeIn(); + _vm->renderMessage(kStringElevator56); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringElevator57); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringElevator58); + _gm->drawGUI(); + + // 21:72:72 + _gm->_state._startTime = g_system->getMillis() - 130363200; +} + +Apartment::Apartment(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 25; + _id = APARTMENT; + _shown[0] = kShownTrue; + _shown[3] = kShownTrue; + + _objectState[0] = Object(_id, kStringChip, kStringChipDescription, CHIP, TAKE | COMBINABLE, 255, 255, 1); + _objectState[1] = Object(_id, kStringHatch, kStringHatchDescription, HATCH, OPENABLE | CLOSED | COMBINABLE, 0, 1, 1); + _objectState[2] = Object(_id, kStringDefaultDescription, kStringDefaultDescription, NULLOBJECT, NULLTYPE, 255, 255, 0); + _objectState[3] = Object(_id, kStringMusicSystem, kStringMusicSystemDescription, MUSIC_SYSTEM, COMBINABLE, 4, 4, 0); + _objectState[4] = Object(_id, kStringSpeakers, kStringSpeakersDescription, NULLOBJECT, NULLTYPE, 5, 5, 0); + _objectState[5] = Object(_id, kStringPencils, kStringPencilsDescription, NULLOBJECT, UNNECESSARY, 6, 6, 0); + _objectState[6] = Object(_id, kStringMetalBlocks, kStringMetalBlocksDescription, MAGNET, TAKE | COMBINABLE, 10, 10, 3 + 128); + _objectState[7] = Object(_id, kStringImage, kStringImageDescription, NULLOBJECT, UNNECESSARY, 7, 7, 0); + _objectState[8] = Object(_id, kStringCabinet, kStringCabinetDescription, CABINET, OPENABLE | CLOSED, 8, 8, 0); + _objectState[9] = Object(_id, kStringChair, kStringDefaultDescription, NULLOBJECT, NULLTYPE, 9, 9, 0); + _objectState[10] = Object(_id, kStringElevator, kStringDefaultDescription, NULLOBJECT, EXIT, 255, 255, 0, ELEVATOR2, 22); + _objectState[11] = Object(_id, kStringUnderBed, kStringUnderBedDescription, UNDER_BED, NULLTYPE, 11, 11, 0); + _objectState[12] = Object(_id, kStringKey, kStringKeyDescription, KEY, TAKE | COMBINABLE, 255, 255, 0); +} + +void Apartment::onEntrance() { + setRoomSeen(true); +} + +void Apartment::animation() { +} + +bool Apartment::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_USE && Object::combine(obj1, obj2, ROD, UNDER_BED)) { + if (_objectState[12]._type & CARRIED) + _vm->renderMessage(kStringApartment1); + else if (_shown[kMaxSection - 1]) { + _vm->renderMessage(kStringApartment2); + _gm->takeObject(_objectState[12]); + _vm->playSound(kAudioSuccess2); + } else { + _vm->renderMessage(kStringApartment3); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringApartment4); + } + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, KEY, HATCH)) { + if (_objectState[1]._type & OPENED) + _vm->renderMessage(kStringApartment5); + else { + _vm->renderImage(1); + _vm->playSound(kAudioTaxiOpen); + _objectState[1]._type |= OPENED; + _objectState[1]._click = 1; + if (!(_objectState[0]._type & CARRIED)) { + _vm->renderImage(2); + _objectState[0]._click = 2; + } + } + } else if (verb == ACTION_CLOSE && obj1._id == HATCH && obj1._type & OPENED) { + _vm->renderImage(1 + 128); + setSectionVisible(2, false); + _vm->playSound(kAudioElevator1); + obj1._type &= ~OPENED; + obj1._click = 0; + if (!(_objectState[0]._type & CARRIED)) + _objectState[0]._click = 255; + } else if (verb == ACTION_TAKE && obj1._id == CHIP && !(obj1._type & CARRIED)) { + setSectionVisible(2, kShownFalse); + return false; + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, KEY, CABINET)) { + _vm->renderMessage(kStringApartment6); + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, CHIP, MUSIC_SYSTEM)) { + _vm->renderMessage(kStringApartment7); + } else if (verb == ACTION_PRESS && obj1._id == MUSIC_SYSTEM) { + _vm->renderMessage(kStringApartment8); + } else + return false; + return true; +} + +Ship::Ship(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 45; + _id = SHIP; + _shown[0] = kShownTrue; + _shown[8] = kShownTrue; + + _objectState[0] = Object(_id, kStringSwitch, kStringDefaultDescription, SWITCH, PRESS | COMBINABLE, 0, 0, 0); + _objectState[1] = Object(_id, kStringHandle, kStringDefaultDescription, HANDLE, NULLTYPE, 255, 255, 0); + _objectState[2] = Object(_id, kStringHatch2, kStringDefaultDescription, NULLOBJECT, NULLTYPE, 255, 255, 0, SHIP, 19); + _objectState[3] = Object(_id, kStringSwitch, kStringDefaultDescription, DOOR_SWITCH, PRESS | COMBINABLE, 255, 255, 0); + _objectState[4] = Object(_id, kStringSpaceSuit, kStringSpaceSuitDescription, SUIT, TAKE, 255, 255, 1); + _objectState[5] = Object(_id, kStringCable, kStringCableDescription1, RCABLE, COMBINABLE, 255, 255, 0); + _objectState[6] = Object(_id, kStringCable, kStringCableDescription2, CABLE, TAKE | COMBINABLE, 255, 255, 8 + 128); + + _outroText = + _vm->getGameString(kStringIntro1) + '\0' + + _vm->getGameString(kStringIntro2) + '\0' + + _vm->getGameString(kStringIntro3) + '\0' + + _vm->getGameString(kStringIntro4) + '\0' + + _vm->getGameString(kStringIntro5) + '\0' + + "^Matthias Neef#" + '\0' + + "^Sascha Otterbach#" + '\0' + + "^Thomas Mazzoni#" + '\0' + + "^Matthias Klein#" + '\0' + + "^Gerrit Rothmaier#" + '\0' + + "^Thomas Hassler#" + '\0' + + "^Rene Kach#" + '\0' + + '\233' + '\0'; + Common::String waitString = "##################"; + _outroText2 = + waitString + '\0' + + _vm->getGameString(kStringOutro1) + '\0' + + _vm->getGameString(kStringOutro2) + '\0' + + _vm->getGameString(kStringOutro3) + '\0' + + _vm->getGameString(kStringOutro4) + '\0' + + _vm->getGameString(kStringOutro5) + '\0' + + '\233' + '\0'; +} + +void Ship::onEntrance() { + setRoomSeen(true); +} + +void Ship::animation() { +} + +bool Ship::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_PRESS && obj1._id == SWITCH) { + if (_gm->_state._dark) { + _gm->_state._dark = false; + _vm->_screen->setViewportBrightness(255); + _objectState[1]._click = 1; + _objectState[2]._click = 2; + _objectState[3]._click = 3; + _objectState[5]._click = 4; + _objectState[6]._click = 5; + _objectState[2]._type = EXIT | OPENABLE | CLOSED; + _gm->drawMapExits(); + } + } else if (verb == ACTION_PRESS && obj1._id == DOOR_SWITCH && + !isSectionVisible(7)) { + _vm->renderImage(3); + _gm->wait(2); + _vm->renderImage(6); + _vm->playSound(kAudioShip1); + while (_vm->_sound->isPlaying() && !_vm->shouldQuit()) + _gm->wait(1); + _vm->renderImage(6 + 128); + _vm->renderImage(7); + _objectState[3]._description = kStringShip1; + _objectState[2]._description = kStringShip2; + } else if (verb == ACTION_PULL && obj1._id == HANDLE) { + _vm->renderImage(2); + _vm->playSound(kAudioTaxiOpen); + obj1._click = 255; + _objectState[4]._click = 9; + } else if (verb == ACTION_TAKE && obj1._id == SUIT && !(obj1._type & CARRIED)) { + setSectionVisible(2, kShownFalse); + _gm->takeObject(obj1); + } else if (verb == ACTION_USE && obj1._id == SUIT) { + if (!(obj1._type & CARRIED)) { + setSectionVisible(2, kShownFalse); + _gm->takeObject(obj1); + } + if ((_shown[kMaxSection - 1] = !_shown[kMaxSection - 1])) + _vm->renderMessage(kStringShip3); + else + _vm->renderMessage(kStringShip4); + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, CABLE, RCABLE)) { + _objectState[6]._description = kStringDefaultDescription; + if (_objectState[6]._click == 5) + _vm->renderImage(8 + 128); + if (_objectState[6]._type & CARRIED) + _gm->_inventory.remove(_objectState[6]); + if (isSectionVisible(11) || isSectionVisible(10)) + _vm->renderMessage(kStringShip5); + else if (isSectionVisible(9)) { + _vm->renderImage(9 + 128); + _vm->renderImage(11); + if (!_shown[kMaxSection - 1]) + kill(); + _objectState[6]._click = 8; + _gm->wait(2); + _vm->renderImage(4); + _vm->playSound(kAudioShip2); + _gm->wait(3); + _vm->renderImage(5); + _objectState[2]._type |= OPENED; + _objectState[2]._description = kStringDefaultDescription; + } else { + _vm->renderImage(10); + if (!_shown[kMaxSection - 1]) + kill(); + _objectState[6]._click = 7; + } + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, CABLE, DOOR_SWITCH) && isSectionVisible(7)) { + _objectState[6]._description = kStringDefaultDescription; + if (_objectState[6]._click == 5) + _vm->renderImage(8 + 128); + if (_objectState[6]._type & CARRIED) + _gm->_inventory.remove(_objectState[6]); + if (isSectionVisible(11) || isSectionVisible(9)) + _vm->renderMessage(kStringShip5); + else if (isSectionVisible(10)) { + _vm->renderImage(10 + 128); + _vm->renderImage(11); + if (!_shown[kMaxSection - 1]) + kill(); + _objectState[6]._click = 8; + _gm->wait(2); + _vm->renderImage(4); + _vm->playSound(kAudioShip2); + _gm->wait(3); + _vm->renderImage(5); + _objectState[2]._type |= OPENED; + _objectState[2]._description = kStringDefaultDescription; + } else { + _vm->renderImage(9); + _objectState[6]._click = 6; + } + } else if (verb == ACTION_TAKE && obj1._id == CABLE && obj1._type & CARRIED) { + if (isSectionVisible(8)) { + obj1._description = kStringDefaultDescription; + _gm->takeObject(obj1); + } else + _vm->renderMessage(kStringShip6); + } else if (verb == ACTION_WALK && obj1._type == (EXIT | OPENABLE | CLOSED | OPENED)) { + _vm->setCurrentImage(46); + _vm->renderImage(0); + _gm->wait(16); + _vm->renderMessage(kStringShip7, kMessageRight); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _gm->reply(kStringShip8, 1, 1 + 128); + _vm->renderMessage(kStringShip9, kMessageRight); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _gm->reply(kStringShip10, 1, 1 + 128); + _gm->reply(kStringShip11, 1, 1 + 128); + _gm->reply(kStringShip12, 1, 1 + 128); + _gm->reply(kStringShip13, 1, 1 + 128); + _vm->renderMessage(kStringShip14, kMessageRight); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _gm->reply(kStringShip15, 1, 1 + 128); + _vm->renderMessage(kStringShip16, kMessageRight); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _gm->reply(kStringAha, 1, 1 + 128); + _gm->reply(kStringShip17, 1, 1 + 128); + _vm->renderMessage(kStringShip18, kMessageRight); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _gm->reply(kStringShip19, 1, 1 + 128); + _gm->wait(16); + CursorMan.showMouse(false); + _vm->renderImage(2); + for (int i = 3; i < 12; i++) { + _vm->renderImage(i); + if (i == 9) + _vm->playSound(kAudioShip3); + _gm->wait(2); + _vm->renderImage(i + 128); + } + _vm->renderImage(12); + _gm->wait(18); + // TODO some palette stuff + outro(); + } else + return false; + return true; +} + +void Ship::outro() { + _vm->_screen->paletteFadeOut(100); + _vm->renderImage(13); + // Because the screen is partialy faded out, the original values (63, 20, 20) + // should be multiplied by 2.55, but are multiplied by 3.5, because the color + // looks closer to the original + byte palette[768]; + _vm->_system->getPaletteManager()->grabPalette(palette, 0, 255); + palette[282] = 220; + palette[283] = 70; + palette[284] = 70; + // Restore marquee colors + for (int i = 0; i < 3; i++) { + palette[kColorPurple * 3 + i] *= 2.5; + palette[kColorLightYellow * 3 + i] *= 2.5; + } + _vm->_system->getPaletteManager()->setPalette(palette, 0, 255); + _vm->playSound(kMusicMadMonkeys); + _vm->renderBox(0, 190, 320, 10, kColorBlack); + Marquee marquee(_vm->_screen, Marquee::kMarqueeOutro, _outroText.c_str()); + for(int i = 0; i < 2; i++) { + while (!_vm->shouldQuit()) { + _gm->updateEvents(); + + if (!marquee.renderCharacter() || _gm->_mouseClicked || _gm->_keyPressed) + break; + g_system->updateScreen(); + g_system->delayMillis(_vm->_delay); + } + marquee.reset(); + } + Marquee marquee2(_vm->_screen, Marquee::kMarqueeOutro, _outroText2.c_str()); + while (!_vm->shouldQuit()) { + _gm->updateEvents(); + + if (!marquee2.renderCharacter() || _gm->_mouseClicked || _gm->_keyPressed) + break; + g_system->updateScreen(); + g_system->delayMillis(_vm->_delay); + } + // TODO: End with some end of music + int volume; + do { + volume = _vm->_sound->getVolume() - 10; + _vm->_sound->setVolume(volume); + _gm->waitOnInput(1); + } while (volume > 10 && !_vm->shouldQuit()); + Common::Event event; + event.type = Common::EVENT_RTL; + _vm->getEventManager()->pushEvent(event); +} + +void Ship::kill() { + _vm->playSound(kAudioShipDeath); + while (_vm->_sound->isPlaying() && !_vm->shouldQuit()) + _gm->wait(1); + _gm->dead(kStringShip0); +} + +Pyramid::Pyramid(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 8; + _id = PYRAMID; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringRope, kStringDefaultDescription, ROPE, TAKE | COMBINABLE, 255, 255, 1 + 128); + _objectState[1] = Object(_id, kStringSign, kStringSignDescription, SIGN, COMBINABLE, 25, 25, 0); + _objectState[2] = Object(_id, kStringEntrance, kStringEntrance1Description, PYRA_ENTRANCE, EXIT, 27, 27, 0, PYR_ENTRANCE, 7); + _objectState[3] = Object(_id, kStringPyramid, kStringPyramidDescription, NULLOBJECT, NULLTYPE, 26, 26, 0); + _objectState[4] = Object(_id, kStringSun, kStringSunDescription, SUN, NULLTYPE, 28, 28, 0); + _objectState[5] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE1, COMBINABLE, 0, 0, 0); + _objectState[6] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE2, COMBINABLE, 1, 0, 0); + _objectState[7] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE3, COMBINABLE, 2, 0, 0); + _objectState[8] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE4, COMBINABLE, 3, 0, 0); + _objectState[9] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE5, COMBINABLE, 4, 0, 0); + _objectState[10] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE6, COMBINABLE, 5, 0, 0); + _objectState[11] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE7, COMBINABLE, 6, 0, 0); + _objectState[12] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE8, COMBINABLE, 7, 0, 0); + _objectState[13] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE9, COMBINABLE, 8, 0, 0); + _objectState[14] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE10, COMBINABLE, 9, 0, 0); + _objectState[15] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE11, COMBINABLE, 10, 0, 0); + _objectState[16] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE12, COMBINABLE, 11, 0, 0); + _objectState[17] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE13, COMBINABLE, 12, 0, 0); + _objectState[18] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE14, COMBINABLE, 13, 0, 0); + _objectState[19] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE15, COMBINABLE, 14, 0, 0); + _objectState[20] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE16, COMBINABLE, 15, 0, 0); + _objectState[21] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE17, COMBINABLE, 16, 0, 0); + _objectState[22] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE18, COMBINABLE, 17, 0, 0); + _objectState[23] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE19, COMBINABLE, 18, 0, 0); + _objectState[24] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE20, COMBINABLE, 19, 0, 0); + _objectState[25] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE21, COMBINABLE, 20, 0, 0); + _objectState[26] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE22, COMBINABLE, 21, 0, 0); + _objectState[27] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE23, COMBINABLE, 22, 0, 0); + _objectState[28] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE24, COMBINABLE, 23, 0, 0); + _objectState[29] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE25, COMBINABLE, 24, 0, 0); +} + +void Pyramid::onEntrance() { + setRoomSeen(true); +} + +void Pyramid::animation() { +} + +bool Pyramid::interact(Action verb, Object &obj1, Object &obj2) { + Object *rope, *hole; + rope = hole = nullptr; + + if (obj1._id == ROPE) + rope = &obj1; + if (obj2._id == ROPE) + rope = &obj2; + if (obj1._id >= HOLE1 && obj1._id <= HOLE25) + hole = &obj1; + if (obj2._id >= HOLE1 && obj2._id <= HOLE25) + hole = &obj2; + + if (verb == ACTION_WALK && obj1._id == PYRA_ENTRANCE) { + _gm->_state._eventCallback = kPyramidEndFn; + _gm->_state._eventTime = g_system->getMillis() + 3600000; //hour + _gm->_state._pyraS = 4; + _gm->_state._pyraZ = 10; + _gm->_state._pyraDirection = 0; + _gm->passageConstruction(); + return false; + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, ROPE, SIGN)) { + if (rope->_type & CARRIED) { + _vm->renderImage(1); + _gm->_inventory.remove(*rope); + _objectState[0]._click = 29; + } else + _vm->renderMessage(kStringPyramid1); + } else if (verb == ACTION_USE && hole != nullptr && rope != nullptr) { + if (rope->_type & CARRIED) + _vm->renderMessage(kStringPyramid2); + else { + int number = hole->_id - HOLE1; + int start = number / 5 * 5 + 2; + for (int i = 1; i <= 26; i++) + _vm->renderImage(i + 128); + for (int i = start; i <= start + number % 5; i++) + _vm->renderImage(i); + _objectState[0]._click = 30; + if (number == 18) { + _gm->_rooms[HOLE_ROOM]->setSectionVisible(16, kShownTrue); + _gm->_rooms[HOLE_ROOM]->getObject(2)->_click = 5; + _gm->_rooms[HOLE_ROOM]->getObject(3)->_type = EXIT; + } else { + _gm->_rooms[HOLE_ROOM]->setSectionVisible(16, kShownFalse); + _gm->_rooms[HOLE_ROOM]->getObject(2)->_click = 255; + _gm->_rooms[HOLE_ROOM]->getObject(3)->_type = NULLTYPE; + } + } + } else if (verb == ACTION_PULL && rope != nullptr && !(rope->_type & CARRIED) && + !isSectionVisible(1)) { + for (int i = 2; i <= 26; i++) + _vm->renderImage(i + 128); + _vm->renderImage(1); + _objectState[0]._click = 29; + _gm->_rooms[HOLE_ROOM]->setSectionVisible(16, kShownFalse); + _gm->_rooms[HOLE_ROOM]->getObject(2)->_click = 255; + _gm->_rooms[HOLE_ROOM]->getObject(3)->_type = NULLTYPE; + } else if (verb == ACTION_TAKE && rope != nullptr && !(rope->_type & CARRIED)) { + for (int i = 2; i <= 26; i++) + _vm->renderImage(i + 128); + _gm->takeObject(*rope); + _gm->_rooms[HOLE_ROOM]->setSectionVisible(16, kShownFalse); + _gm->_rooms[HOLE_ROOM]->getObject(2)->_click = 255; + _gm->_rooms[HOLE_ROOM]->getObject(3)->_type = NULLTYPE; + } else if (verb == ACTION_WALK && obj1._id == SUN) { + _vm->renderMessage(kStringPyramid3); + } else + return false; + return true; +} + +PyrEntrance::PyrEntrance(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 9; + _id = PYR_ENTRANCE; + _shown[0] = kShownTrue; + _shown[4] = kShownTrue; + _shown[8] = kShownTrue; + + _objectState[0] = Object(_id, kStringSign, kStringSign5Description, SIGN, NULLTYPE, 255, 255, 0); + _objectState[1] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[2] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[3] = Object(_id, kStringCorridor, kStringDefaultDescription, CORRIDOR, EXIT, 0, 0, 0, PYR_ENTRANCE, 2); +} + +void PyrEntrance::onEntrance() { + if (_gm->_state._pyraS == 8 && _gm->_state._pyraZ == 5) { + _gm->setAnimationTimer(1); + _waitTime = g_system->getMillis() + 60000; + } +} + +void PyrEntrance::animation() { + if (_gm->_state._pyraS == 8 && _gm->_state._pyraZ == 5) { + if (g_system->getMillis() >= _waitTime) { // around 1 minute + _vm->renderMessage(kStringPyramid4); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _gm->_state._pyraZ++; + _gm->_state._pyraDirection = 0; + _gm->changeRoom(FLOORDOOR); + _vm->setCurrentImage(14); + _vm->renderRoom(*_gm->_rooms[FLOORDOOR]); + _gm->drawMapExits(); + _gm->wait(3); + _vm->renderImage(5); + _gm->wait(3); + _vm->renderImage(6); + _gm->_rooms[FLOORDOOR]->setSectionVisible(5, kShownFalse); + _gm->wait(3); + _vm->renderImage(7); + _gm->_rooms[FLOORDOOR]->setSectionVisible(6, kShownFalse); + _gm->wait(3); + _vm->renderImage(8); + _gm->_rooms[FLOORDOOR]->setSectionVisible(7, kShownFalse); + _gm->wait(3); + _vm->renderImage(9); + _gm->_rooms[FLOORDOOR]->setSectionVisible(8, kShownFalse); + _vm->playSound(kAudioShip3); + _gm->screenShake(); + _gm->_rooms[FLOORDOOR]->setSectionVisible(kMaxSection - 1, kShownTrue); + } else { + _gm->setAnimationTimer(1); + } + } else + _gm->setAnimationTimer(kMaxTimerValue); +} + +bool PyrEntrance::interact(Action verb, Object &obj1, Object &obj2) { + static RoomEntry roomTab[29] = { + {2, 8, 6, 0, FLOORDOOR}, + {0, 8, 4, 2, FLOORDOOR_U}, + {0, 4, 11, 2, PYRAMID}, + {0, 0, 2, 1, UPSTAIRS1}, + {1, 1, 2, 3, DOWNSTAIRS1}, + {0, 5, 8, 3, BOTTOM_RIGHT_DOOR}, + {0, 4, 8, 1, BOTTOM_LEFT_DOOR}, + {1, 5, 8, 3, UPPER_DOOR}, + {1, 4, 8, 1, UPPER_DOOR}, + {0, 4, 8, 0, UPSTAIRS2}, + {1, 4, 7, 2, DOWNSTAIRS2}, + {1, 6, 6, 2, PUZZLE_FRONT}, + {1, 6, 7, 0, PUZZLE_BEHIND}, + {0, 3, 6, 0, FORMULA1_N}, + {0, 3, 7, 0, FORMULA1_F}, + {0, 4, 6, 0, FORMULA2_N}, + {0, 4, 7, 0, FORMULA2_F}, + {0, 8, 9, 2, TOMATO_N}, + {0, 8, 8, 2, TOMATO_F}, + {1, 4, 2, 0, MONSTER_F}, + {1, 10, 8, 0, MONSTER_F}, + {1, 4, 1, 0, MONSTER1_N}, + {1, 10, 7, 0, MONSTER2_N}, + {0, 2, 4, 2, DOWNSTAIRS3}, + {1, 2, 5, 0, UPSTAIRS3}, + {1, 2, 5, 3, LCORRIDOR1}, + {1, 1, 5, 1, LCORRIDOR2}, + {1, 1, 5, 3, HOLE_ROOM}, + {0, 7, 4, 0, BST_DOOR} + }; + if (!_gm->move(verb, obj1)) + return false; + if (_gm->_rooms[FLOORDOOR]->isSectionVisible(kMaxSection - 1)) + roomTab[0]._e = 1; + else + roomTab[0]._e = 2; + for (int i = 0; i < 29; i++) { + if (_gm->_state._pyraE == roomTab[i]._e && + _gm->_state._pyraS == roomTab[i]._s && + _gm->_state._pyraZ == roomTab[i]._z && + _gm->_state._pyraDirection == roomTab[i]._r) { + _gm->changeRoom(roomTab[i]._exitRoom); + _gm->_newRoom = true; + return true; + } + } + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +Upstairs1::Upstairs1(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 10; + _id = UPSTAIRS1; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + _shown[2] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringCorridor, kStringDefaultDescription, CORRIDOR, EXIT, 0, 0, 0, PYR_ENTRANCE, 2); +} + +void Upstairs1::onEntrance() { + setRoomSeen(true); +} + +void Upstairs1::animation() { +} + +bool Upstairs1::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + if (obj1._id == CORRIDOR) { + if (_gm->_state._pyraE) + _gm->_state._pyraE = 0; + else + _gm->_state._pyraE = 1; + } + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +Downstairs1::Downstairs1(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 10; + _id = DOWNSTAIRS1; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + _shown[3] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringCorridor, kStringDefaultDescription, CORRIDOR, EXIT, 3, 3, 0, PYR_ENTRANCE, 2); +} + +void Downstairs1::onEntrance() { + setRoomSeen(true); +} + +void Downstairs1::animation() { +} + +bool Downstairs1::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + if (obj1._id == CORRIDOR) { + if (_gm->_state._pyraE) + _gm->_state._pyraE = 0; + else + _gm->_state._pyraE = 1; + } + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +BottomRightDoor::BottomRightDoor(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 12; + _id = BOTTOM_RIGHT_DOOR; + _shown[0] = kShownTrue; + _shown[19] = kShownTrue; + _shown[23] = kShownTrue; + _shown[29] = kShownTrue; + _shown[30] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringDoor, kStringMassive, DOOR, EXIT | OPENABLE | CLOSED, 0, 0, 0, PYR_ENTRANCE, 2); + _objectState[3] = Object(_id, kStringButton, kStringDefaultDescription, BUTTON, PRESS, 19, 19, 0); +} + +void BottomRightDoor::onEntrance() { + setRoomSeen(true); +} + +void BottomRightDoor::animation() { +} + +bool BottomRightDoor::interact(Action verb, Object &obj1, Object &obj2) { + if (_gm->move(verb, obj1)) { + _gm->passageConstruction(); + _gm->_newRoom = true; + } else if (verb == ACTION_PRESS && obj1._id == BUTTON) { + if (isSectionVisible(22)) { + _vm->renderImage(21); + setSectionVisible(22, kShownFalse); + _gm->wait(2); + _vm->renderImage(20); + setSectionVisible(21, kShownFalse); + _gm->wait(2); + _vm->renderImage(19); + setSectionVisible(20, kShownFalse); + _objectState[2]._type = EXIT | OPENABLE | CLOSED; + _objectState[2]._id = DOOR; + _objectState[2]._description = kStringMassive; + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(22, kShownFalse); + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(21, kShownFalse); + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(20, kShownFalse); + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(19, kShownTrue); + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(27, kShownFalse); + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(28, kShownFalse); + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(24, kShownFalse); + _gm->_rooms[BOTTOM_LEFT_DOOR]->getObject(2)->_type = EXIT | OPENABLE | CLOSED; + _gm->_rooms[BOTTOM_LEFT_DOOR]->getObject(2)->_id = DOOR; + _gm->_rooms[BOTTOM_LEFT_DOOR]->getObject(2)->_description = kStringMassive; + _gm->_rooms[UPPER_DOOR]->setSectionVisible(26, kShownTrue); + _gm->_rooms[UPPER_DOOR]->setSectionVisible(27, kShownTrue); + _gm->_rooms[UPPER_DOOR]->setSectionVisible(19, kShownFalse); + _gm->_rooms[UPPER_DOOR]->setSectionVisible(25, kShownFalse); + _gm->_rooms[UPPER_DOOR]->getObject(2)->_type = EXIT; + _gm->_rooms[UPPER_DOOR]->getObject(2)->_id = CORRIDOR; + _gm->_rooms[UPPER_DOOR]->getObject(2)->_description = kStringDefaultDescription; + } else { + _vm->renderImage(20); + setSectionVisible(19, kShownFalse); + _gm->wait(2); + _vm->renderImage(21); + _gm->wait(2); + _vm->renderImage(22); + _objectState[2]._type = EXIT; + _objectState[2]._id = CORRIDOR; + _objectState[2]._description = kStringDefaultDescription; + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(20, kShownTrue); + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(21, kShownTrue); + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(22, kShownTrue); + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(19, kShownFalse); + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(27, kShownTrue); + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(28, kShownTrue); + _gm->_rooms[BOTTOM_LEFT_DOOR]->setSectionVisible(24, kShownTrue); + _gm->_rooms[BOTTOM_LEFT_DOOR]->getObject(2)->_type = EXIT; + _gm->_rooms[BOTTOM_LEFT_DOOR]->getObject(2)->_id = CORRIDOR; + _gm->_rooms[BOTTOM_LEFT_DOOR]->getObject(2)->_description = kStringDefaultDescription; + _gm->_rooms[UPPER_DOOR]->setSectionVisible(26, kShownFalse); + _gm->_rooms[UPPER_DOOR]->setSectionVisible(27, kShownFalse); + _gm->_rooms[UPPER_DOOR]->setSectionVisible(19, kShownTrue); + _gm->_rooms[UPPER_DOOR]->setSectionVisible(25, kShownTrue); + _gm->_rooms[UPPER_DOOR]->getObject(2)->_type = EXIT | OPENABLE | CLOSED; + _gm->_rooms[UPPER_DOOR]->getObject(2)->_id = DOOR; + _gm->_rooms[UPPER_DOOR]->getObject(2)->_description = kStringMassive; + } + _vm->playSound(kAudioShip3); + _gm->screenShake(); + } else + return false; + return true; +} + +BottomLeftDoor::BottomLeftDoor(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 12; + _id = BOTTOM_LEFT_DOOR; + _shown[0] = kShownTrue; + _shown[19] = kShownTrue; + _shown[29] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringDoor, kStringMassive, DOOR, EXIT | OPENABLE | CLOSED, 0, 0, 0, PYR_ENTRANCE, 2); +} + +void BottomLeftDoor::onEntrance() { + setRoomSeen(true); +} + +void BottomLeftDoor::animation() { +} + +bool BottomLeftDoor::interact(Action verb, Object &obj1, Object &obj2) { + if (_gm->move(verb, obj1)) { + if (verb == ACTION_WALK && obj1._id == G_LEFT) + _gm->changeRoom(UPSTAIRS2); + else + _gm->passageConstruction(); + _gm->_newRoom = true; + } else + return false; + return true; +} + +Upstairs2::Upstairs2(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 10; + _id = UPSTAIRS2; + _shown[0] = kShownTrue; + _shown[2] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringCorridor, kStringDefaultDescription, CORRIDOR, EXIT, 0, 0, 0, PYR_ENTRANCE, 2); +} + +void Upstairs2::onEntrance() { + setRoomSeen(true); +} + +void Upstairs2::animation() { +} + +bool Upstairs2::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + if (obj1._id == CORRIDOR) { + if (_gm->_state._pyraE) + _gm->_state._pyraE = 0; + else + _gm->_state._pyraE = 1; + } + if (obj1._id == G_RIGHT) + _gm->changeRoom(BOTTOM_LEFT_DOOR); + else + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +Downstairs2::Downstairs2(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 10; + _id = DOWNSTAIRS2; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + _shown[3] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringCorridor, kStringDefaultDescription, CORRIDOR, EXIT, 3, 3, 0, PYR_ENTRANCE, 2); +} + +void Downstairs2::onEntrance() { + setRoomSeen(true); +} + +void Downstairs2::animation() { +} + +bool Downstairs2::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + if (obj1._id == CORRIDOR) { + if (_gm->_state._pyraE) + _gm->_state._pyraE = 0; + else + _gm->_state._pyraE = 1; + } + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; + return true; +} + +UpperDoor::UpperDoor(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 12; + _id = UPPER_DOOR; + _shown[0] = kShownTrue; + _shown[26] = kShownTrue; + _shown[27] = kShownTrue; + _shown[30] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringDoor, kStringDefaultDescription, CORRIDOR, EXIT, 0, 0, 0, PYR_ENTRANCE, 2); +} + +void UpperDoor::onEntrance() { + setRoomSeen(true); +} + +void UpperDoor::animation() { +} + +bool UpperDoor::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +PuzzleFront::PuzzleFront(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 12; + _id = PUZZLE_FRONT; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + _shown[2] = kShownTrue; + _shown[3] = kShownTrue; + _shown[4] = kShownTrue; + _shown[5] = kShownTrue; + _shown[6] = kShownTrue; + _shown[7] = kShownTrue; + _shown[8] = kShownTrue; + _shown[9] = kShownTrue; + _shown[10] = kShownTrue; + _shown[11] = kShownTrue; + _shown[12] = kShownTrue; + _shown[13] = kShownTrue; + _shown[14] = kShownTrue; + _shown[15] = kShownTrue; + _shown[30] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringDoor, kStringMassive, DOOR, EXIT | OPENABLE | CLOSED, 255, 255, 0, PYR_ENTRANCE, 2); + _objectState[3] = Object(_id, kStringPiece, kStringDefaultDescription, PART0, PRESS, 3, 3, 0); + _objectState[4] = Object(_id, kStringPiece, kStringDefaultDescription, PART1, PRESS, 4, 4, 0); + _objectState[5] = Object(_id, kStringPiece, kStringDefaultDescription, PART2, PRESS, 5, 5, 0); + _objectState[6] = Object(_id, kStringPiece, kStringDefaultDescription, PART3, PRESS, 6, 6, 0); + _objectState[7] = Object(_id, kStringPiece, kStringDefaultDescription, PART4, PRESS, 7, 7, 0); + _objectState[8] = Object(_id, kStringPiece, kStringDefaultDescription, PART5, PRESS, 8, 8, 0); + _objectState[9] = Object(_id, kStringPiece, kStringDefaultDescription, PART6, PRESS, 9, 9, 0); + _objectState[10] = Object(_id, kStringPiece, kStringDefaultDescription, PART7, PRESS, 10, 10, 0); + _objectState[11] = Object(_id, kStringPiece, kStringDefaultDescription, PART8, PRESS, 11, 11, 0); + _objectState[12] = Object(_id, kStringPiece, kStringDefaultDescription, PART9, PRESS, 12, 12, 0); + _objectState[13] = Object(_id, kStringPiece, kStringDefaultDescription, PART10, PRESS, 13, 13, 0); + _objectState[14] = Object(_id, kStringPiece, kStringDefaultDescription, PART11, PRESS, 14, 14, 0); + _objectState[15] = Object(_id, kStringPiece, kStringDefaultDescription, PART12, PRESS, 15, 15, 0); + _objectState[16] = Object(_id, kStringPiece, kStringDefaultDescription, PART13, PRESS, 16, 16, 0); + _objectState[17] = Object(_id, kStringPiece, kStringDefaultDescription, PART14, PRESS, 17, 17, 0); + _objectState[18] = Object(_id, kStringPiece, kStringDefaultDescription, PART15, PRESS, 18, 18, 0); +} + +void PuzzleFront::onEntrance() { + setRoomSeen(true); +} + +void PuzzleFront::animation() { +} + +bool PuzzleFront::interact(Action verb, Object &obj1, Object &obj2) { + MSNImage *image = _vm->_screen->getCurrentImage(); + if (_gm->move(verb, obj1)) { + _gm->passageConstruction(); + _gm->_newRoom = true; + } else if (verb == ACTION_PRESS && obj1._id >= PART0 && obj1._id <= PART15) { + int pos = obj1._id - PART0; + int newPos = 0; + if (pos > 3 && _gm->_puzzleField[pos - 4] == 255) + newPos = pos - 4; + else if (pos < 12 && _gm->_puzzleField[pos + 4] == 255) + newPos = pos + 4; + else if ((pos % 4) > 0 && _gm->_puzzleField[pos - 1] == 255) + newPos = pos - 1; + else if ((pos % 4) < 3 && _gm->_puzzleField[pos + 1] == 255) + newPos = pos + 1; + else { + _vm->renderMessage(kStringPyramid5); + return true; + } + int a = _gm->_puzzleField[pos] + 1; + _vm->renderImage(a + 128); + image->_section[a].x1 = 95 + (newPos % 4) * 33; + image->_section[a].x2 = image->_section[a].x1 + 31; + image->_section[a].y1 = 24 + (newPos / 4) * 25; + image->_section[a].y2 = image->_section[a].y1 + 23; + _vm->renderImage(a); + _vm->playSound(kAudioTaxiOpen); + _gm->_state._puzzleTab[a - 1] = newPos; + _gm->_puzzleField[pos] = 255; + _gm->_puzzleField[newPos] = a - 1; + _objectState[pos + 3]._click = 255; + _objectState[newPos + 3]._click = newPos + 3; + for (int i = 0; i < 15; i++) + if (_gm->_state._puzzleTab[i] != i) + return true; + + _gm->wait(2); + _vm->renderImage(16); + for (int i = 1; i < 16; i++) + setSectionVisible(i, kShownFalse); + _gm->wait(2); + _vm->renderImage(17); + _gm->wait(2); + _vm->renderImage(18); + _objectState[2]._type = EXIT; + _objectState[2]._id = CORRIDOR; + _objectState[2]._description = kStringDefaultDescription; + _objectState[2]._click = 0; + + _gm->_rooms[PUZZLE_BEHIND]->setSectionVisible(31, kShownFalse); + _gm->_rooms[PUZZLE_BEHIND]->setSectionVisible(26, kShownTrue); + _gm->_rooms[PUZZLE_BEHIND]->setSectionVisible(27, kShownTrue); + _gm->_rooms[PUZZLE_BEHIND]->setSectionVisible(29, kShownTrue); + _gm->_rooms[PUZZLE_BEHIND]->getObject(2)->_type = EXIT; + _gm->_rooms[PUZZLE_BEHIND]->getObject(2)->_id = CORRIDOR; + _gm->_rooms[PUZZLE_BEHIND]->getObject(2)->_description = kStringDefaultDescription; + _vm->playSound(kAudioShip3); + _gm->screenShake(); + } else + return false; + return true; +} + +PuzzleBehind::PuzzleBehind(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 12; + _id = PUZZLE_BEHIND; + _shown[0] = kShownTrue; + _shown[29] = kShownTrue; + _shown[31] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringDoor, kStringMassive, DOOR, EXIT | OPENABLE | CLOSED, 0, 0, 0, PYR_ENTRANCE, 2); +} + +void PuzzleBehind::onEntrance() { + setRoomSeen(true); +} + +void PuzzleBehind::animation() { +} + +bool PuzzleBehind::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +Formula1F::Formula1F(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 14; + _id = FORMULA1_F; + _shown[0] = kShownTrue; + _shown[2] = kShownTrue; + _shown[15] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 12, 12, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 11, 11, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringInscription, kStringInscriptionDescription, CORRIDOR, EXIT, 1, 1, 0, PYR_ENTRANCE, 2); +} + +void Formula1F::onEntrance() { + setRoomSeen(true); +} + +void Formula1F::animation() { +} + +bool Formula1F::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + if (obj1._id == CORRIDOR) + _gm->changeRoom(FORMULA1_N); + else + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +Formula1N::Formula1N(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 13; + _id = FORMULA1_N; + _shown[0] = kShownTrue; + _shown[5] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 8, 8, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 7, 7, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringInscription, kStringInscriptionDescription, NULLOBJECT, NULLTYPE, 2, 2, 0); +} + +void Formula1N::onEntrance() { + setRoomSeen(true); +} + +void Formula1N::animation() { +} + +bool Formula1N::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +Formula2F::Formula2F(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 14; + _id = FORMULA2_F; + _shown[0] = kShownTrue; + _shown[3] = kShownTrue; + _shown[14] = kShownTrue; + _shown[15] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 12, 12, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 11, 11, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringInscription, kStringInscriptionDescription, CORRIDOR, EXIT, 2, 2, 0, PYR_ENTRANCE, 2); +} + +void Formula2F::onEntrance() { + setRoomSeen(true); +} + +void Formula2F::animation() { +} + +bool Formula2F::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + if (obj1._id == CORRIDOR) + _gm->changeRoom(FORMULA2_N); + else + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +Formula2N::Formula2N(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 13; + _id = FORMULA2_N; + _shown[0] = kShownTrue; + _shown[6] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 8, 8, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 7, 7, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringInscription, kStringInscriptionDescription, NULLOBJECT, NULLTYPE, 3, 3, 0); +} + +void Formula2N::onEntrance() { + setRoomSeen(true); +} + +void Formula2N::animation() { +} + +bool Formula2N::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +TomatoF::TomatoF(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 14; + _id = TOMATO_F; + _shown[0] = kShownTrue; + _shown[4] = kShownTrue; + _shown[15] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 12, 12, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 11, 11, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringTomato, kStringFunnyDescription, CORRIDOR, EXIT, 3, 3, 0, PYR_ENTRANCE, 2); +} + +void TomatoF::onEntrance() { + setRoomSeen(true); +} + +void TomatoF::animation() { +} + +bool TomatoF::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + if (obj1._id == CORRIDOR) + _gm->changeRoom(TOMATO_N); + else + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +TomatoN::TomatoN(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 13; + _id = TOMATO_N; + _shown[0] = kShownTrue; + _shown[7] = kShownTrue; + _shown[8] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 8, 8, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 7, 7, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringKnife1, kStringKnife1Description, TKNIFE, TAKE | COMBINABLE, 5, 5, 7); + _objectState[3] = Object(_id, kStringTomato, kStringFunnyDescription, NULLOBJECT, UNNECESSARY, 4, 4, 0); +} + +void TomatoN::onEntrance() { + setRoomSeen(true); +} + +void TomatoN::animation() { +} + +bool TomatoN::interact(Action verb, Object &obj1, Object &obj2) { + if (_gm->move(verb, obj1)) { + _gm->passageConstruction(); + _gm->_newRoom = true; + } else if (verb == ACTION_TAKE && obj1._id == TKNIFE) { + _gm->takeObject(obj1); + setSectionVisible(8, kShownFalse); + } else + return false; + return true; +} + +MonsterF::MonsterF(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 14; + _id = MONSTER_F; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + _shown[14] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 12, 12, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 11, 11, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringMonster, kStringMonsterDescription, CORRIDOR, EXIT, 0, 0, 0, PYR_ENTRANCE, 2); +} + +void MonsterF::onEntrance() { + setRoomSeen(true); +} + +void MonsterF::animation() { +} + +bool MonsterF::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + if (obj1._id == CORRIDOR) { + if (_gm->_state._pyraS == 4) + _gm->changeRoom(MONSTER1_N); + else + _gm->changeRoom(MONSTER2_N); + } else + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +Monster1N::Monster1N(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 13; + _id = MONSTER1_N; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 8, 8, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 7, 7, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringRope, kStringRopeDescription, ROPE, TAKE | COMBINABLE, 255, 255, 2); + _objectState[3] = Object(_id, kStringEyes, kStringDefaultDescription, NULLOBJECT, NULLTYPE, 6, 6, 0); + _objectState[4] = Object(_id, kStringMouth, kStringDefaultDescription, MOUTH, NULLTYPE, 1, 1, 0); + _objectState[5] = Object(_id, kStringMonster, kStringMonster1Description, MONSTER, NULLTYPE, 0, 0, 0); +} + +void Monster1N::onEntrance() { + setRoomSeen(true); +} + +void Monster1N::animation() { +} + +bool Monster1N::interact(Action verb, Object &obj1, Object &obj2) { + if (_gm->move(verb, obj1)) { + _gm->passageConstruction(); + _gm->_newRoom = true; + } else if ((verb == ACTION_OPEN || verb == ACTION_PULL) && obj1._id == MOUTH) { + if (obj1._type & OPENED) + _vm->renderMessage(kStringGenericInteract8); + else { + obj1._type |= OPENED; + if (isSectionVisible(kMaxSection - 1)) + _vm->renderImage(2); + else { + _objectState[2]._click = 1; + _vm->renderImage(4); + setSectionVisible(2, kShownFalse); + } + _vm->playSound(kAudioTaxiOpen); + } + } else if (verb == ACTION_CLOSE && obj1._id == MOUTH) { + if (obj1._type & OPENED) { + _vm->renderImage(1); + setSectionVisible(2, kShownFalse); + obj1._type &= ~OPENED; + _vm->playSound(kAudioElevator1); + } else + _vm->renderMessage(kStringGenericInteract11); + } else if (verb == ACTION_TAKE && (obj1._id == ROPE || obj1._id == NOTE)) { + _gm->takeObject(obj1); + setSectionVisible(3, kShownFalse); + setSectionVisible(4, kShownFalse); + setSectionVisible(kMaxSection - 1, kShownTrue); + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, TKNIFE, MONSTER)) { + _vm->renderMessage(kStringPyramid6); + } else + return false; + return true; +} + +Monster2N::Monster2N(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 13; + _id = MONSTER2_N; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 8, 8, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 7, 7, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringNote, kStringNoteDescription, NOTE, TAKE | COMBINABLE, 255, 255, 2); + _objectState[3] = Object(_id, kStringEyes, kStringDefaultDescription, NULLOBJECT, NULLTYPE, 6, 6, 0); + _objectState[4] = Object(_id, kStringMouth, kStringDefaultDescription, MOUTH, NULLTYPE, 1, 1, 0); + _objectState[5] = Object(_id, kStringMonster, kStringMonster1Description, MONSTER, NULLTYPE, 0, 0, 0); +} + +void Monster2N::onEntrance() { + setRoomSeen(true); +} + +void Monster2N::animation() { +} + +bool Monster2N::interact(Action verb, Object &obj1, Object &obj2) { + if (_gm->move(verb, obj1)) { + _gm->passageConstruction(); + _gm->_newRoom = true; + } else if ((verb == ACTION_OPEN || verb == ACTION_PULL) && obj1._id == MOUTH) { + if (obj1._type & OPENED) + _vm->renderMessage(kStringGenericInteract8); + else { + obj1._type |= OPENED; + if (isSectionVisible(kMaxSection - 1)) + _vm->renderImage(2); + else { + _objectState[2]._click = 1; + _vm->renderImage(3); + setSectionVisible(2, kShownFalse); + } + _vm->playSound(kAudioTaxiOpen); + } + } else if (verb == ACTION_CLOSE && obj1._id == MOUTH) { + if (obj1._type & OPENED) { + _vm->renderImage(1); + setSectionVisible(2, kShownFalse); + obj1._type &= ~OPENED; + _vm->playSound(kAudioElevator1); + } else + _vm->renderMessage(kStringGenericInteract11); + } else if (verb == ACTION_TAKE && (obj1._id == ROPE || obj1._id == NOTE)) { + _gm->takeObject(obj1); + setSectionVisible(3, kShownFalse); + setSectionVisible(4, kShownFalse); + setSectionVisible(kMaxSection - 1, kShownTrue); + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, TKNIFE, MONSTER)) { + _vm->renderMessage(kStringPyramid6); + } else + return false; + return true; +} + +Upstairs3::Upstairs3(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 10; + _id = UPSTAIRS3; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringCorridor, kStringDefaultDescription, CORRIDOR, EXIT, 0, 0, 0, PYR_ENTRANCE, 2); +} + +void Upstairs3::onEntrance() { + setRoomSeen(true); +} + +void Upstairs3::animation() { +} + +bool Upstairs3::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + if (obj1._id == CORRIDOR) { + if (_gm->_state._pyraE) + _gm->_state._pyraE = 0; + else + _gm->_state._pyraE = 1; + } + if (obj1._id == G_LEFT) + _gm->changeRoom(LCORRIDOR1); + else + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +Downstairs3::Downstairs3(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 10; + _id = DOWNSTAIRS3; + _shown[0] = kShownTrue; + _shown[2] = kShownTrue; + _shown[3] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringCorridor, kStringDefaultDescription, CORRIDOR, EXIT, 3, 3, 0, PYR_ENTRANCE, 2); +} + +void Downstairs3::onEntrance() { + setRoomSeen(true); +} + +void Downstairs3::animation() { +} + +bool Downstairs3::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + if (obj1._id == CORRIDOR) { + if (_gm->_state._pyraE) + _gm->_state._pyraE = 0; + else + _gm->_state._pyraE = 1; + } + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +LCorridor1::LCorridor1(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 9; + _id = LCORRIDOR1; + _shown[0] = kShownTrue; + _shown[2] = kShownTrue; + _shown[17] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringCorridor, kStringDefaultDescription, CORRIDOR, EXIT, 6, 6, 0, PYR_ENTRANCE, 2); +} + +void LCorridor1::onEntrance() { + setRoomSeen(true); +} + +void LCorridor1::animation() { +} + +bool LCorridor1::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + if (obj1._id == G_RIGHT) + _gm->changeRoom(UPSTAIRS3); + else if (obj1._id == CORRIDOR) + _gm->changeRoom(HOLE_ROOM); + else + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +LCorridor2::LCorridor2(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 9; + _id = LCORRIDOR2; + _shown[0] = kShownTrue; + _shown[17] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringCorridor, kStringDefaultDescription, CORRIDOR, EXIT, 6, 6, 0, PYR_ENTRANCE, 2); +} + +void LCorridor2::onEntrance() { + setRoomSeen(true); +} + +void LCorridor2::animation() { +} + +bool LCorridor2::interact(Action verb, Object &obj1, Object &obj2) { + if (!_gm->move(verb, obj1)) + return false; + _gm->passageConstruction(); + _gm->_newRoom = true; + return true; +} + +HoleRoom::HoleRoom(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 9; + _id = HOLE_ROOM; + _shown[0] = kShownTrue; + _shown[8] = kShownTrue; + _shown[15] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 1, 1, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 2, 2, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringRope, kStringDefaultDescription, ROPE, NULLTYPE, 255, 255, 0); + _objectState[3] = Object(_id, kStringOpening, kStringOpeningDescription1, HOLE, EXIT, 3, 3, 0, IN_HOLE, 12); + _objectState[4] = Object(_id, kStringOpening, kStringOpeningDescription2, NULLOBJECT, NULLTYPE, 4, 4, 0); +} + +void HoleRoom::onEntrance() { + setRoomSeen(true); +} + +void HoleRoom::animation() { +} + +bool HoleRoom::interact(Action verb, Object &obj1, Object &obj2) { + if (_gm->move(verb, obj1)) { + _gm->passageConstruction(); + _gm->_newRoom = true; + } else if (verb == ACTION_USE && + (Object::combine(obj1, obj2, ROPE, G_RIGHT) || + Object::combine(obj1, obj2, ROPE, G_LEFT))) { + _vm->renderMessage(kStringPyramid7); + } else if (verb == ACTION_USE && + (Object::combine(obj1, obj2, TKNIFE, G_RIGHT) || + Object::combine(obj1, obj2, TKNIFE, G_LEFT))) { + _vm->renderMessage(kStringPyramid8); + } else if (verb == ACTION_TAKE && obj1._id == ROPE && !(obj1._type & CARRIED)) { + _vm->renderMessage(kStringPyramid9); + } else if (verb == ACTION_WALK && obj1._id == HOLE && !isSectionVisible(16)) { + _vm->renderMessage(kStringPyramid10); + } else if (verb == ACTION_USE && obj1._id == ROPE && isSectionVisible(16)) { + _gm->changeRoom(IN_HOLE); + _gm->_newRoom = true; + } else + return false; + return true; +} + +InHole::InHole(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 11; + _id = IN_HOLE; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringRope, kStringDefaultDescription, ROPE, EXIT, 0, 0, 0, HOLE_ROOM, 2); + _objectState[1] = Object(_id, kStringNote, kStringNoteDescription1, NULLOBJECT, TAKE, 255, 255, 1 + 128); + _objectState[2] = Object(_id, kStringSlot, kStringSlotDescription3, SLOT, COMBINABLE, 1, 1, 0); +} + +void InHole::onEntrance() { + setRoomSeen(true); +} + +void InHole::animation() { +} + +bool InHole::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_USE && Object::combine(obj1, obj2, TKNIFE, SLOT)) { + if (isSectionVisible(kMaxSection - 1)) + _vm->renderMessage(kStringPyramid11); + else { + _vm->renderImage(1); + _objectState[1]._click = 2; + setSectionVisible(kMaxSection - 1, kShownTrue); + } + } else if (verb == ACTION_TAKE && obj1._id == ROPE) { + _vm->renderMessage(kStringPyramid9); + } else if (verb == ACTION_USE && obj1._id == ROPE) { + _gm->changeRoom(HOLE_ROOM); + _gm->_newRoom = true; + } else + return false; + return true; +} + +Floordoor::Floordoor(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 14; + _id = FLOORDOOR; + _shown[0] = kShownTrue; + _shown[14] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 12, 12, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 11, 11, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringKnife1, kStringDefaultDescription, TKNIFE, TAKE | COMBINABLE, 255, 255, 9); + _objectState[3] = Object(_id, kStringRope, kStringDefaultDescription, ROPE, TAKE, 255, 255, 11+128); + _objectState[4] = Object(_id, kStringOpening, kStringOpeningDescription3, HOLE, EXIT, 4, 4, 0, FLOORDOOR_U, 12); + _objectState[5] = Object(_id, kStringStones, kStringDefaultDescription, STONES, COMBINABLE, 5, 5, 0); +} + +void Floordoor::onEntrance() { + setRoomSeen(true); +} + +void Floordoor::animation() { +} + +bool Floordoor::interact(Action verb, Object &obj1, Object &obj2) { + if (_gm->move(verb, obj1)) { + _gm->passageConstruction(); + _gm->_newRoom = true; + } else if (verb == ACTION_WALK && obj1._id == HOLE) { + if (isSectionVisible(11)) { + _gm->_state._pyraZ = 4; + _gm->_state._pyraDirection = 2; + _gm->_state._pyraE = 0; + return false; + } else + _vm->renderMessage(kStringPyramid12); + } else if (verb == ACTION_USE && obj1._id == ROPE && isSectionVisible(11)) { + _gm->_state._pyraZ = 4; + _gm->_state._pyraDirection = 2; + _gm->_state._pyraE = 0 ; + _gm->changeRoom(FLOORDOOR_U); + _gm->_newRoom = true; + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, TKNIFE, STONES)) { + _vm->renderImage(10); + if (obj1._id == TKNIFE) + _gm->_inventory.remove(obj1); + else + _gm->_inventory.remove(obj2); + _objectState[2]._click = 6; + } else if (verb == ACTION_USE && + (Object::combine(obj1, obj2, TKNIFE, G_RIGHT) || + Object::combine(obj1, obj2, TKNIFE, G_LEFT))) { + _vm->renderMessage(kStringPyramid8); + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, ROPE, TKNIFE) && + isSectionVisible(10)) { + _vm->renderImage(11); + setSectionVisible(10, kShownFalse); + if (obj1._id == ROPE) + _gm->_inventory.remove(obj1); + else + _gm->_inventory.remove(obj2); + _objectState[2]._click = 255; + _objectState[3]._click = 7; + _objectState[3]._type &= ~COMBINABLE; + } else if (verb == ACTION_USE && + (Object::combine(obj1, obj2, ROPE, G_RIGHT) || + Object::combine(obj1, obj2, ROPE, G_LEFT) || + Object::combine(obj1, obj2, ROPE, STONES))) { + _vm->renderMessage(kStringPyramid7); + } else if (verb == ACTION_TAKE && obj1._id == ROPE && !(obj1._type & CARRIED)) { + _gm->takeObject(obj1); + obj1._type |= COMBINABLE; + _vm->renderImage(9); + _vm->renderImage(10); + _objectState[2]._click = 6; + } else if (verb == ACTION_TAKE && obj1._id == TKNIFE && !(obj1._type & CARRIED)) { + _gm->takeObject(obj1); + setSectionVisible(10, kShownFalse); + } else + return false; + return true; +} + +FloordoorU::FloordoorU(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 14; + _id = FLOORDOOR_U; + _shown[0] = kShownTrue; + _shown[12] = kShownTrue; + _shown[13] = kShownTrue; + _shown[15] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 12, 12, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 11, 11, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringRope, kStringDefaultDescription, ROPE, NULLTYPE, 10, 10, 0, FLOORDOOR, 2); + _objectState[3] = Object(_id, kStringOpening, kStringDefaultDescription, HOLE, EXIT, 8, 8, 0, FLOORDOOR, 2); + _objectState[4] = Object(_id, kStringPlate, kStringDefaultDescription, NULLOBJECT, NULLTYPE, 9, 9, 0); +} + +void FloordoorU::onEntrance() { + setRoomSeen(true); +} + +void FloordoorU::animation() { +} + +bool FloordoorU::interact(Action verb, Object &obj1, Object &obj2) { + if (_gm->move(verb, obj1)) { + _gm->passageConstruction(); + _gm->_newRoom = true; + } else if (verb == ACTION_WALK && obj1._id == HOLE) { + _gm->_state._pyraZ = 6; + _gm->_state._pyraDirection = 0; + _gm->_state._pyraE = 1; + return false; + } else if (verb == ACTION_USE && obj1._id == ROPE) { + _gm->_state._pyraZ = 6; + _gm->_state._pyraDirection = 0; + _gm->_state._pyraE = 1; + _gm->changeRoom(FLOORDOOR); + _gm->_newRoom = true; + } else if (verb == ACTION_TAKE && obj1._id == ROPE) { + _vm->renderMessage(kStringPyramid9); + } else + return false; + return true; +} + +BstDoor::BstDoor(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 15; + _id = BST_DOOR; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringRight, kStringDefaultDescription, G_RIGHT, EXIT, 18, 18, 0, PYR_ENTRANCE, 14); + _objectState[1] = Object(_id, kStringLeft, kStringDefaultDescription, G_LEFT, EXIT, 17, 17, 0, PYR_ENTRANCE, 10); + _objectState[2] = Object(_id, kStringLetter, kStringDefaultDescription, BST1, PRESS, 0, 0, 0); + _objectState[3] = Object(_id, kStringLetter, kStringDefaultDescription, BST2, PRESS, 1, 0, 0); + _objectState[4] = Object(_id, kStringLetter, kStringDefaultDescription, BST3, PRESS, 2, 0, 0); + _objectState[5] = Object(_id, kStringLetter, kStringDefaultDescription, BST4, PRESS, 3, 0, 0); + _objectState[6] = Object(_id, kStringLetter, kStringDefaultDescription, BST5, PRESS, 4, 0, 0); + _objectState[7] = Object(_id, kStringLetter, kStringDefaultDescription, BST6, PRESS, 5, 0, 0); + _objectState[8] = Object(_id, kStringLetter, kStringDefaultDescription, BST7, PRESS, 6, 0, 0); + _objectState[9] = Object(_id, kStringLetter, kStringDefaultDescription, BST8, PRESS, 7, 0, 0); + _objectState[10] = Object(_id, kStringLetter, kStringDefaultDescription, BST9, PRESS, 8, 0, 0); + _objectState[11] = Object(_id, kStringLetter, kStringDefaultDescription, BST10, PRESS, 9, 0, 0); + _objectState[12] = Object(_id, kStringLetter, kStringDefaultDescription, BST11, PRESS, 10, 0, 0); + _objectState[13] = Object(_id, kStringLetter, kStringDefaultDescription, BST12, PRESS, 11, 0, 0); + _objectState[14] = Object(_id, kStringLetter, kStringDefaultDescription, BST13, PRESS, 12, 0, 0); + _objectState[15] = Object(_id, kStringLetter, kStringDefaultDescription, BST14, PRESS, 13, 0, 0); + _objectState[16] = Object(_id, kStringLetter, kStringDefaultDescription, BST15, PRESS, 14, 0, 0); + _objectState[17] = Object(_id, kStringLetter, kStringDefaultDescription, BST16, PRESS, 15, 0, 0); + _objectState[18] = Object(_id, kStringDoor, kStringMassive, DOOR, EXIT | OPENABLE | CLOSED, 16, 16, 0, HALL2, 2); + + char germanPassword[16] = {0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0}; + char englishPassword[16] = {0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}; + if (ConfMan.get("language") == "en") + for (int i = 0; i < 16; i++) + _password[i] = englishPassword[i]; + else + for (int i = 0; i < 16; i++) + _password[i] = germanPassword[i]; +} + +void BstDoor::onEntrance() { + if (ConfMan.get("language") == "en") + _vm->_screen->renderMessage("You are almost there", kMessageNormal, 105, 130); +} + +void BstDoor::animation() { +} + +bool BstDoor::interact(Action verb, Object &obj1, Object &obj2) { + if (_gm->move(verb, obj1)) { + _gm->passageConstruction(); + _gm->_newRoom = true; + } else if (verb == ACTION_PRESS && obj1._id >= BST1 && obj1._id <= BST16) { + int number = obj1._id - (BST1 - 1); + if (isSectionVisible(number)) + _vm->renderImage(number + 128); + else + _vm->renderImage(number); + _vm->playSound(kAudioTaxiOpen); + for (number = 1; number <= 16; number++) { + if (isSectionVisible(number) != _password[number - 1]) + return true; + } + _gm->wait(2); + _vm->renderImage(17); + for (number = 1; number <= 16; number++) { + setSectionVisible(number, kShownFalse); + _objectState[number + 1]._click = 255; + } + _gm->wait(2); + _vm->renderImage(18); + _gm->wait(2); + _vm->renderImage(19); + _objectState[18]._type = EXIT; + _objectState[18]._description = kStringDefaultDescription; + _vm->playSound(kAudioShip3); + _gm->screenShake(); + } else + return false; + return true; +} + +Hall2::Hall2(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 16; + _id = HALL2; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringCoffin, kStringDefaultDescription, NULLOBJECT, EXIT, 0, 0, 0, COFFIN_ROOM, 2); + _objectState[1] = Object(_id, kStringExit, kStringDefaultDescription, CORRIDOR, EXIT, 255, 255, 0, PYR_ENTRANCE, 22); +} + +void Hall2::onEntrance() { + setRoomSeen(true); +} + +void Hall2::animation() { +} + +bool Hall2::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_WALK && obj1._id == CORRIDOR) { + _gm->_state._pyraDirection = 2; + _gm->passageConstruction(); + } + return false; +} + +CoffinRoom::CoffinRoom(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 17; + _id = COFFIN_ROOM; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringExit, kStringDefaultDescription, NULLOBJECT, EXIT, 255, 255, 0, HALL2, 22); + _objectState[1] = Object(_id, kStringCoffin, kStringCreepy, COFFIN, NULLTYPE, 0, 0, 0); + _objectState[2] = Object(_id, kStringToothbrush, kStringToothbrushDescription1, NULLOBJECT, NULLTYPE, 1, 1, 0); + _objectState[3] = Object(_id, kStringToothpaste, kStringToothbrushDescription1, NULLOBJECT, NULLTYPE, 2, 2, 0); + _objectState[4] = Object(_id, kStringBall, kStringBallDescription, L_BALL, NULLTYPE, 3, 3, 0); + _objectState[5] = Object(_id, kStringBall, kStringBallDescription, R_BALL, NULLTYPE, 4, 4, 0); +} + +void CoffinRoom::onEntrance() { + setRoomSeen(true); +} + +void CoffinRoom::animation() { +} + +bool CoffinRoom::interact(Action verb, Object &obj1, Object &obj2) { + char change; + if (verb == ACTION_OPEN && obj1._id == COFFIN && !isSectionVisible(1)) { + _vm->renderMessage(kStringPyramid13); + } else if (verb == ACTION_PRESS && (obj1._id == L_BALL || obj1._id == R_BALL)) { + if (obj1._id == L_BALL) { + if ((change = !isSectionVisible(2))) { + _vm->renderImage(2); + _vm->playSound(kAudioTaxiOpen); + } else + _vm->renderMessage(kStringPyramid14); + } else { + if ((change = !isSectionVisible(3))) { + _vm->renderImage(3); + _vm->playSound(kAudioTaxiOpen); + } else + _vm->renderMessage(kStringPyramid14); + } if (change) { + if (isSectionVisible(2) && isSectionVisible(3)) { + _vm->playSound(kAudioShip2); + _vm->renderImage(4); + _gm->wait(4); + _vm->renderImage(5); + _gm->wait(4); + _vm->renderImage(5); + _gm->wait(4); + _vm->renderImage(5); + _gm->wait(4); + _vm->renderImage(1); + setSectionVisible(4, kShownFalse); + setSectionVisible(5, kShownFalse); + setSectionVisible(6, kShownFalse); + setSectionVisible(7, kShownFalse); + } + else + _vm->renderMessage(kStringPyramid15); + } + } else if (verb == ACTION_LOOK && obj1._id == COFFIN && isSectionVisible(1)) { + _gm->changeRoom(MASK); + _gm->_newRoom = true; + } else + return false; + return true; +} + +Mask::Mask(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 18; + _id = MASK; + _shown[0] = kShownTrue; + + _objectState[0] = Object(_id, kStringExit, kStringDefaultDescription, NULLOBJECT, EXIT, 255, 255, 0, COFFIN_ROOM, 22); + _objectState[1] = Object(_id, kStringEye, kStringEyeDescription, EYE1, NULLTYPE, 0, 0, 0); + _objectState[2] = Object(_id, kStringEye, kStringEyeDescription, EYE2, NULLTYPE, 1, 1, 0); + _objectState[3] = Object(_id, kStringMouth, kStringDefaultDescription, NULLOBJECT, NULLTYPE, 2, 2, 0); +} + +void Mask::onEntrance() { + setRoomSeen(true); +} + +void Mask::animation() { +} + +bool Mask::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_OPEN && (obj1._id == EYE1 || obj1._id == EYE2)) { + if (obj1._type & OPENED) + _vm->renderMessage(kStringPyramid16); + else + _vm->renderImage(obj1._id - EYE1 + 1); + if (isSectionVisible(1) && isSectionVisible(2)) { + _gm->reply(kStringPyramid17, 3, 3 + 128); + _gm->reply(kStringPyramid18, 3, 3 + 128); + _gm->reply(kStringPyramid19, 3, 3 + 128); + _vm->playSound(kAudioAppearance1); + while(_vm->_sound->isPlaying()) + _gm->wait(1); + _vm->paletteFadeOut(); + _vm->loadGame(kSleepAutosaveSlot); + _gm->changeRoom(CABIN2); + _gm->setAnimationTimer(1); + _gm->_newRoom = true; + _gm->drawGUI(); + _gm->_rooms[CABIN2]->setSectionVisible(2, kShownTrue); + _gm->_rooms[CABIN2]->setSectionVisible(kMaxSection - 1, kShownFalse); + _gm->_rooms[CABIN2]->setSectionVisible(kMaxSection - 2, kShownTrue); + _gm->_rooms[CABIN2]->setSectionVisible(1, kShownFalse); + _gm->_rooms[CABIN2]->getObject(2)->_click = 8; + _gm->_state._eventTime = kMaxTimerValue; + } + return true; + } + return false; +} + +Museum::Museum(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _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_ENTRANCE, 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); + bool hasDinosaurHead = false; + if (_gm->_rooms[MUS_ROUND]->getObject(4)->_type & CARRIED) + hasDinosaurHead = true; + _vm->loadGame(kSleepAutosaveSlot); + _vm->renderImage(0); + _vm->paletteFadeIn(); + if (hasDinosaurHead) { + _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(kStringMuseum23); + _gm->reply(kStringMuseum24, 1, 1 + 128); + } + _vm->paletteFadeOut(); + _gm->changeRoom(CITY2); + _gm->_newRoom = true; + _gm->drawGUI(); + } +} + +void Museum::animation() { +} + +bool Museum::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_WALK && obj1._id == MUS_STREET) { + if (!_gm->_state._alarmOn && + !(_gm->_rooms[MUS_ROUND]->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->_screen->setGuiBrightness(255); + _vm->_screen->paletteBrightness(); + _vm->renderMessage(kStringMuseum13); + _gm->waitOnInput(_gm->_messageDuration); + _vm->removeMessage(); + _vm->_screen->setViewportBrightness(0); + _vm->_screen->setGuiBrightness(0); + _vm->_screen->paletteBrightness(); + bool hasDinosaurHead = false; + if (_gm->_rooms[MUS_ROUND]->getObject(4)->_type & CARRIED) + hasDinosaurHead = true; + _vm->loadGame(kSleepAutosaveSlot); + if (_gm->_state._money >= 8) + _gm->takeMoney(-8); + if (hasDinosaurHead) + _gm->takeObject(*_gm->_rooms[INTRO2]->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; +} + +MusEntrance::MusEntrance(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 32; + _id = MUS_ENTRANCE; + _shown[0] = kShownTrue; + _shown[2] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, ENCRYPTED_DOOR, EXIT | OPENABLE | OPENED, 1, 1, 2, MUSEUM, 23); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 0, 0, 1, MUS11, 2); +} + +void MusEntrance::onEntrance() { + setRoomSeen(true); +} + +void MusEntrance::animation() { +} + +bool MusEntrance::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_OPEN && obj1._id == DOOR) + _gm->_rooms[MUS11]->getObject(2)->_type |= OPENED; + else if (verb == ACTION_CLOSE && obj1._id == DOOR) + _gm->_rooms[MUS11]->getObject(2)->_type &= ~OPENED; + else if (verb == ACTION_USE && + Object::combine(obj1, obj2, SP_KEYCARD, ENCRYPTED_DOOR) && + !(_objectState[0]._type & OPENED)) { + if (_gm->crackDoor(20)) { + _vm->renderImage(2); + _objectState[0]._type = EXIT | OPENABLE | OPENED; + _vm->playSound(kAudioTaxiOpen); + } + return true; + } else if (verb == ACTION_CLOSE && obj1._id == ENCRYPTED_DOOR && + (obj1._type & OPENED)) { + _vm->renderImage(2 + 128); + _objectState[0]._type = EXIT | OPENABLE | CLOSED; + _vm->playSound(kAudioElevator1); + return true; + } + return false; +} + +Mus1::Mus1(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 35; + _id = MUS1; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + _shown[3] = kShownTrue; + _shown[4] = kShownTrue; + _shown[6] = kShownTrue; + _shown[13] = kShownTrue; + _shown[15] = kShownTrue; + _shown[26] = kShownTrue; + _shown[27] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 1, 1, 8, MUS2, 22); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 4, 4, 11, MUS8, 9); +} + +void Mus1::onEntrance() { + _gm->securityEntrance(); + setRoomSeen(true); +} + +void Mus1::animation() { +} + +bool Mus1::interact(Action verb, Object &obj1, Object &obj2) { + _gm->museumDoorInteract(verb, obj1, obj2); + return false; +} + +Mus2::Mus2(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 35; + _id = MUS2; + _shown[0] = kShownTrue; + _shown[3] = kShownTrue; + _shown[4] = kShownTrue; + _shown[5] = kShownTrue; + _shown[6] = kShownTrue; + _shown[13] = kShownTrue; + _shown[14] = kShownTrue; + _shown[22] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 0, 0, 7, MUS1, 2); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 1, 1, 8, MUS3, 22); +} + +void Mus2::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus2::animation() { +} + +bool Mus2::interact(Action verb, Object &obj1, Object &obj2) { + _gm->museumDoorInteract(verb, obj1, obj2); + return false; +} + +Mus3::Mus3(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 35; + _id = MUS3; + _shown[0] = kShownTrue; + _shown[2] = kShownTrue; + _shown[3] = kShownTrue; + _shown[4] = kShownTrue; + _shown[5] = kShownTrue; + _shown[13] = kShownTrue; + _shown[23] = kShownTrue; + _shown[28] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 0, 0, 7, MUS2, 2); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 5, 5, 12, MUS10, 19); +} + +void Mus3::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus3::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus3::interact(Action verb, Object &obj1, Object &obj2) { + _gm->museumDoorInteract(verb, obj1, obj2); + return false; +} + +Mus4::Mus4(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 35; + _id = MUS4; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + _shown[3] = kShownTrue; + _shown[4] = kShownTrue; + _shown[5] = kShownTrue; + _shown[6] = kShownTrue; + _shown[14] = kShownTrue; + _shown[20] = kShownTrue; + _shown[21] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 1, 1, 8, MUS5, 22); + _objectState[1] = Object(_id, kStringCamera, kStringDefaultDescription, NULLOBJECT, NULLTYPE, 7, 7, 0); + +} + +void Mus4::onEntrance() { + setRoomSeen(true); +} + +void Mus4::animation() { +} + +bool Mus4::interact(Action verb, Object &obj1, Object &obj2) { + _gm->museumDoorInteract(verb, obj1, obj2); + return false; +} + +Mus5::Mus5(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 35; + _id = MUS5; + _shown[0] = kShownTrue; + _shown[4] = kShownTrue; + _shown[5] = kShownTrue; + _shown[6] = kShownTrue; + _shown[14] = kShownTrue; + _shown[24] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 0, 0, 7, MUS4, 2); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, ENCRYPTED_DOOR, EXIT | OPENABLE | CLOSED | COMBINABLE, 1, 1, 8, MUS6, 22); + _objectState[2] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 2, 2, 9, MUS9, 5); + +} + +void Mus5::onEntrance() { + _gm->securityEntrance(); + setRoomSeen(true); +} + +void Mus5::animation() { +} + +bool Mus5::interact(Action verb, Object &obj1, Object &obj2) { + _gm->museumDoorInteract(verb, obj1, obj2); + if (verb == ACTION_USE && + Object::combine(obj1, obj2, SP_KEYCARD, ENCRYPTED_DOOR) && + !(_objectState[1]._type & OPENED)) { + if (_gm->crackDoor(50)) { + _vm->renderImage(8); + _objectState[1]._type = EXIT | OPENABLE | OPENED; + _gm->_rooms[MUS6]->getObject(0)->_type = EXIT | OPENABLE | OPENED; + _gm->_rooms[MUS6]->setSectionVisible(7, kShownTrue); + _vm->playSound(kAudioTaxiOpen); + } + } else if (verb == ACTION_CLOSE && obj1._id == ENCRYPTED_DOOR && + (obj1._type & OPENED)) { + _vm->renderImage(8 + 128); + _objectState[1]._type = EXIT | OPENABLE | CLOSED; + _gm->_rooms[MUS6]->getObject(0)->_type = EXIT | OPENABLE | CLOSED; + _gm->_rooms[MUS6]->setSectionVisible(7, kShownFalse); + _vm->playSound(kAudioElevator1); + } else + return false; + return true; +} + +Mus6::Mus6(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 35; + _id = MUS6; + _shown[0] = kShownTrue; + _shown[3] = kShownTrue; + _shown[4] = kShownTrue; + _shown[5] = kShownTrue; + _shown[6] = kShownTrue; + _shown[13] = kShownTrue; + _shown[19] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, ENCRYPTED_DOOR, EXIT | OPENABLE | CLOSED | COMBINABLE, 0, 0, 7, MUS5, 2); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 1, 1, 8, MUS7, 22); + _objectState[2] = Object(_id, kStringDoor, kStringDefaultDescription, BIG_DOOR, EXIT | OPENABLE | CLOSED, 6, 6, 0); +} + +void Mus6::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus6::animation() { +} + +bool Mus6::interact(Action verb, Object &obj1, Object &obj2) { + _gm->museumDoorInteract(verb, obj1, obj2); + if (verb == ACTION_USE && + Object::combine(obj1, obj2, SP_KEYCARD, ENCRYPTED_DOOR) && + !(_objectState[0]._type & OPENED)) { + if (_gm->crackDoor(50)) { + _vm->renderImage(7); + _objectState[0]._type = EXIT | OPENABLE | OPENED; + _gm->_rooms[MUS5]->getObject(1)->_type = EXIT | OPENABLE | OPENED; + _gm->_rooms[MUS5]->setSectionVisible(8, kShownTrue); + _vm->playSound(kAudioTaxiOpen); + } + } else if (verb == ACTION_CLOSE && obj1._id == ENCRYPTED_DOOR && + (obj1._type & OPENED)) { + _vm->renderImage(7 + 128); + _objectState[0]._type = EXIT | OPENABLE | CLOSED; + _gm->_rooms[MUS5]->getObject(1)->_type = EXIT | OPENABLE | CLOSED; + _gm->_rooms[MUS5]->setSectionVisible(8, kShownFalse); + _vm->playSound(kAudioElevator1); + } else if (verb == ACTION_USE && + Object::combine(obj1, obj2, SP_KEYCARD, BIG_DOOR)) + _vm->renderMessage(kStringMuseum14); + else + return false; + return true; +} + +Mus7::Mus7(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 35; + _id = MUS7; + _shown[0] = kShownTrue; + _shown[2] = kShownTrue; + _shown[3] = kShownTrue; + _shown[5] = kShownTrue; + _shown[6] = kShownTrue; + _shown[14] = kShownTrue; + _shown[16] = kShownTrue; + _shown[25] = kShownTrue; + _shown[28] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 0, 0, 7, MUS6, 2); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 3, 3, 10, MUS11, 15); +} + +void Mus7::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus7::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus7::interact(Action verb, Object &obj1, Object &obj2) { + _gm->museumDoorInteract(verb, obj1, obj2); + return false; +} + +Mus8::Mus8(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 34; + _id = MUS8; + _shown[0] = kShownTrue; + _shown[12] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 0, 0, 1, MUS1, 10); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, ENCRYPTED_DOOR, EXIT | OPENABLE | CLOSED | COMBINABLE, 1, 1, 2, MUS9, 14); +} + +void Mus8::onEntrance() { + _gm->securityEntrance(); + setRoomSeen(true); +} + +void Mus8::animation() { +} + +bool Mus8::interact(Action verb, Object &obj1, Object &obj2) { + _gm->museumDoorInteract(verb, obj1, obj2); + if (verb == ACTION_USE && + Object::combine(obj1, obj2, SP_KEYCARD, ENCRYPTED_DOOR) && + !(_objectState[1]._type & OPENED)) { + if (_gm->crackDoor(50)) { + _vm->renderImage(2); + _objectState[1]._type = EXIT | OPENABLE | OPENED; + _gm->_rooms[MUS9]->getObject(0)->_type = EXIT | OPENABLE | OPENED; + _gm->_rooms[MUS9]->setSectionVisible(1, kShownTrue); + _vm->playSound(kAudioTaxiOpen); + } + } else if (verb == ACTION_CLOSE && obj1._id == ENCRYPTED_DOOR && + (obj1._type & OPENED)) { + _vm->renderImage(2 + 128); + _objectState[1]._type = EXIT | OPENABLE | CLOSED; + _gm->_rooms[MUS9]->getObject(0)->_type = EXIT | OPENABLE | CLOSED; + _gm->_rooms[MUS9]->setSectionVisible(1, kShownFalse); + _vm->playSound(kAudioElevator1); + } else + return false; + return true; +} + +Mus9::Mus9(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 34; + _id = MUS9; + _shown[0] = kShownTrue; + _shown[5] = kShownTrue; + _shown[10] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, ENCRYPTED_DOOR, EXIT | OPENABLE | CLOSED | COMBINABLE, 0, 0, 1, MUS8, 10); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 1, 1, 2, MUS5, 14); + _objectState[2] = Object(_id, kStringDoor, kStringDefaultDescription, SMALL_DOOR, EXIT | OPENABLE | CLOSED, 3, 3, 0, MUS_ROUND, 21); +} + +void Mus9::onEntrance() { + _gm->securityEntrance(); + setRoomSeen(true); +} + +void Mus9::animation() { +} + +bool Mus9::interact(Action verb, Object &obj1, Object &obj2) { + _gm->museumDoorInteract(verb, obj1, obj2); + if (verb == ACTION_USE && + Object::combine(obj1, obj2, SP_KEYCARD, ENCRYPTED_DOOR) && + !(_objectState[0]._type & OPENED)) { + if (_gm->crackDoor(50)) { + _vm->renderImage(1); + _objectState[0]._type = EXIT | OPENABLE | OPENED; + _gm->_rooms[MUS8]->getObject(1)->_type = EXIT | OPENABLE | OPENED; + _gm->_rooms[MUS8]->setSectionVisible(2, kShownTrue); + _vm->playSound(kAudioTaxiOpen); + } + } else if (verb == ACTION_CLOSE && obj1._id == ENCRYPTED_DOOR && + (obj1._type & OPENED)) { + _vm->renderImage(1 + 128); + _objectState[0]._type = EXIT | OPENABLE | CLOSED; + _gm->_rooms[MUS8]->getObject(1)->_type = EXIT | OPENABLE | CLOSED; + _gm->_rooms[MUS8]->setSectionVisible(2, kShownFalse); + _vm->playSound(kAudioElevator1); + } else if (verb == ACTION_USE && + Object::combine(obj1, obj2, SP_KEYCARD, SMALL_DOOR) && + !(_objectState[2]._type & OPENED)) { + if (_gm->crackDoor(50)) { + _vm->renderImage(6); + setSectionVisible(5, kShownFalse); + _objectState[2]._type = EXIT | OPENABLE | OPENED; + _gm->_rooms[MUS_ROUND]->getObject(0)->_type = EXIT | OPENABLE | OPENED; + _vm->playSound(kAudioTaxiOpen); + } + } else if (verb == ACTION_CLOSE && obj1._id == SMALL_DOOR && + (obj1._type & OPENED)) { + _vm->renderImage(5); + setSectionVisible(6, kShownFalse); + _objectState[2]._type = EXIT | OPENABLE | CLOSED; + _gm->_rooms[MUS_ROUND]->getObject(0)->_type = EXIT | OPENABLE | CLOSED; + _vm->playSound(kAudioElevator1); + } else + return false; + return true; +} + +Mus10::Mus10(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 34; + _id = MUS10; + _shown[0] = kShownTrue; + _shown[11] = kShownTrue; + _shown[13] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 0, 0, 1, MUS3, 10); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 1, 1, 2, MUS11, 14); + _objectState[2] = Object(_id, kStringMainEntrance, kStringDefaultDescription, BIG_DOOR, EXIT | OPENABLE | CLOSED, 4, 4, 0); +} + +void Mus10::onEntrance() { + _gm->securityEntrance(); + setRoomSeen(true); +} + +void Mus10::animation() { +} + +bool Mus10::interact(Action verb, Object &obj1, Object &obj2) { + _gm->museumDoorInteract(verb, obj1, obj2); + if (verb == ACTION_USE && Object::combine(obj1, obj2, SP_KEYCARD, BIG_DOOR)) { + _vm->renderMessage(kStringMuseum14); + return true; + } + return false; +} + +Mus11::Mus11(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 34; + _id = MUS11; + _shown[0] = kShownTrue; + _shown[4] = kShownTrue; + _shown[9] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 0, 0, 1, MUS10, 10); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 1, 1, 2, MUS7, 14); + _objectState[2] = Object(_id, kStringDoor, kStringDefaultDescription, SMALL_DOOR, EXIT | OPENABLE, 2, 2, 0, MUS_ENTRANCE, 21); +} + +void Mus11::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus11::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus11::interact(Action verb, Object &obj1, Object &obj2) { + _gm->museumDoorInteract(verb, obj1, obj2); + if (verb == ACTION_OPEN && obj1._id == SMALL_DOOR && !(obj1._type & OPENED)) { + obj1._type |= OPENED; + _vm->renderImage(4); + setSectionVisible(3, kShownFalse); + _vm->playSound(kAudioTaxiOpen); + } else if (verb == ACTION_CLOSE && obj1._id == SMALL_DOOR && + (obj1._type & OPENED)) { + obj1._type &= ~OPENED; + _vm->renderImage(3); + setSectionVisible(4, kShownFalse); + _vm->playSound(kAudioElevator1); + } else + return false; + return true; +} + +MusRound::MusRound(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 33; + _id = MUS_ROUND; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, ENCRYPTED_DOOR, EXIT | OPENABLE | OPENED | COMBINABLE, 0, 0, 1, MUS9, 2); + _objectState[1] = Object(_id, kStringCorridor, kStringDefaultDescription, NULLOBJECT, EXIT, 1, 1, 0, MUS13, 10); + _objectState[2] = Object(_id, kStringCorridor, kStringDefaultDescription, NULLOBJECT, EXIT, 2, 2, 0, MUS12, 14); + _objectState[3] = Object(_id, kStringDinosaur, kStringDinosaurDescription2, NULLOBJECT, NULLTYPE, 3, 3, 0); + _objectState[4] = Object(_id, kStringDinosaurHead, kStringDinosaurHeadDescription, HEAD, TAKE, 4, 4, 2); +} + +void MusRound::onEntrance() { + setRoomSeen(true); +} + +void MusRound::animation() { +} + +bool MusRound::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_USE && + Object::combine(obj1, obj2, SP_KEYCARD, ENCRYPTED_DOOR) && + !(_objectState[0]._type & OPENED)) { + if (_gm->crackDoor(50)) { + _vm->renderImage(1); + _objectState[0]._type = EXIT | OPENABLE | OPENED; + _gm->_rooms[MUS9]->getObject(2)->_type = EXIT | OPENABLE | OPENED; + _vm->playSound(kAudioTaxiOpen); + } + } else if (verb == ACTION_CLOSE && obj1._id == ENCRYPTED_DOOR && + (obj1._type & OPENED)) { + _vm->renderImage(1 + 128); + _objectState[0]._type = EXIT | OPENABLE | CLOSED; + _gm->_rooms[MUS9]->getObject(2)->_type = EXIT | OPENABLE | CLOSED; + _vm->playSound(kAudioElevator1); + } else if (verb == ACTION_TAKE && obj1._id == HEAD && !(obj1._type & CARRIED)) { + _gm->takeObject(obj1); + _vm->playSound(kAudioSuccess2); + } else + return false; + return true; +} + +Mus12::Mus12(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 37; + _id = MUS12; + _shown[0] = kShownTrue; + _shown[2] = kShownTrue; + _shown[3] = kShownTrue; + _shown[4] = kShownTrue; + _shown[5] = kShownTrue; + _shown[6] = kShownTrue; + _shown[13] = kShownTrue; + _shown[17] = kShownTrue; + + _objectState[0] = Object(_id, kStringCorridor, kStringDefaultDescription, NULLOBJECT, EXIT, 6, 6, 0, MUS_ROUND, 10); +} + +void Mus12::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus12::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus12::interact(Action verb, Object &obj1, Object &obj2) { + return false; +} + +Mus13::Mus13(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 37; + _id = MUS13; + _shown[0] = kShownTrue; + _shown[3] = kShownTrue; + _shown[5] = kShownTrue; + _shown[6] = kShownTrue; + _shown[14] = kShownTrue; + _shown[16] = kShownTrue; + _objectState[0] = Object(_id, kStringCorridor, kStringDefaultDescription, NULLOBJECT, EXIT, 7, 7, 0, MUS_ROUND, 14); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE, 0, 0, 7, MUS14, 10); + _objectState[2] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE, 3, 3, 10, MUS15, 16); +} + +void Mus13::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus13::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus13::interact(Action verb, Object &obj1, Object &obj2) { + return false; +} + +Mus14::Mus14(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 37; + _id = MUS14; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + _shown[3] = kShownTrue; + _shown[4] = kShownTrue; + _shown[5] = kShownTrue; + _shown[6] = kShownTrue; + _shown[8] = kShownTrue; + _shown[15] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE | OPENED, 1, 1, 8, MUS13, 14); +} + +void Mus14::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus14::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus14::interact(Action verb, Object &obj1, Object &obj2) { + return false; +} + +Mus15::Mus15(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 36; + _id = MUS15; + _shown[0] = kShownTrue; + _shown[3] = kShownTrue; + _shown[8] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE | OPENED, 0, 0, 3, MUS13, 2); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE, 1, 1, 4, MUS16, 22); +} + +void Mus15::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus15::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus15::interact(Action verb, Object &obj1, Object &obj2) { + return false; +} + +Mus16::Mus16(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 36; + _id = MUS16; + _shown[0] = kShownTrue; + _shown[3] = kShownTrue; + _shown[10] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE | OPENED, 0, 0, 3, MUS15, 2); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE, 1, 1, 4, MUS17, 22); +} + +void Mus16::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus16::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus16::interact(Action verb, Object &obj1, Object &obj2) { + return false; +} + +Mus17::Mus17(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 37; + _id = MUS17; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + _shown[6] = kShownTrue; + _shown[9] = kShownTrue; + _shown[17] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE | OPENED, 2, 2, 9, MUS16, 6); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE, 1, 1, 8, MUS21, 14); + _objectState[2] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE, 3, 3, 10, MUS18, 16); + _objectState[3] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE, 4, 4, 11, MUS20, 8); +} + +void Mus17::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus17::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus17::interact(Action verb, Object &obj1, Object &obj2) { + return false; +} + +Mus18::Mus18(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 36; + _id = MUS18; + _shown[0] = kShownTrue; + _shown[3] = kShownTrue; + _shown[11] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE | OPENED, 0, 0, 3, MUS17, 2); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE, 1, 1, 4, MUS19, 22); +} + +void Mus18::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus18::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus18::interact(Action verb, Object &obj1, Object &obj2) { + return false; +} + +Mus19::Mus19(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 37; + _id = MUS19; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + _shown[2] = kShownTrue; + _shown[3] = kShownTrue; + _shown[4] = kShownTrue; + _shown[6] = kShownTrue; + _shown[11] = kShownTrue; + _shown[15] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE | OPENED, 4, 4, 11, MUS18, 8); +} + +void Mus19::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus19::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus19::interact(Action verb, Object &obj1, Object &obj2) { + return false; +} + +Mus20::Mus20(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 36; + _id = MUS20; + _shown[0] = kShownTrue; + _shown[1] = kShownTrue; + _shown[4] = kShownTrue; + _shown[7] = kShownTrue; + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE | OPENED, 1, 1, 4, MUS17, 22); +} + +void Mus20::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus20::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus20::interact(Action verb, Object &obj1, Object &obj2) { + return false; +} + +Mus21::Mus21(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 37; + _id = MUS21; + _shown[0] = kShownTrue; + _shown[2] = kShownTrue; + _shown[3] = kShownTrue; + _shown[5] = kShownTrue; + _shown[6] = kShownTrue; + _shown[7] = kShownTrue; + _shown[18] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE | OPENED, 0, 0, 7, MUS17, 10); + _objectState[1] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE, 3, 3, 10, MUS22, 16); +} + +void Mus21::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus21::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus21::interact(Action verb, Object &obj1, Object &obj2) { + return false; +} + +Mus22::Mus22(SupernovaEngine *vm, GameManager2 *gm) { + _vm = vm; + _gm = gm; + + _fileNumber = 36; + _id = MUS22; + _shown[0] = kShownTrue; + _shown[2] = kShownTrue; + _shown[3] = kShownTrue; + _shown[5] = kShownTrue; + _shown[9] = kShownTrue; + + _objectState[0] = Object(_id, kStringDoor, kStringDefaultDescription, NULLOBJECT, EXIT | OPENABLE | OPENED, 0, 0, 3, MUS21, 2); + _objectState[1] = Object(_id, kStringAlarmSystem, kStringDefaultDescription, ALARM_SYSTEM, COMBINABLE, 2, 2, 0); + _objectState[2] = Object(_id, kStringSuctionCup, kStringDefaultDescription, SUCTION_CUP, TAKE | COMBINABLE, 255, 255, 0); + _objectState[3] = Object(_id, kStringWall, kStringDefaultDescription, WALL, COMBINABLE, 4, 4, 0); +} + +void Mus22::onEntrance() { + _gm->pressureAlarmEntrance(); +} + +void Mus22::animation() { + _gm->pressureAlarmCount(); +} + +bool Mus22::interact(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_USE && Object::combine(obj1, obj2, SUCTION_CUP, WALL)) { + if (isSectionVisible(6)) + _vm->renderMessage(kStringMuseum17); + else { + _vm->renderImage(6); + _vm->renderMessage(kStringMuseum18); + _objectState[2]._click = 3; + if (obj1._id == SUCTION_CUP) + _gm->_inventory.remove(obj1); + else + _gm->_inventory.remove(obj2); + } + } else if (verb == ACTION_TAKE && obj1._id == SUCTION_CUP && + !(obj1._type & CARRIED)) { + _vm->renderImage(2); + setSectionVisible(6, kShownFalse); + _vm->renderImage(5); + _gm->takeObject(obj1); + _vm->renderMessage(kStringMuseum19); + } else if (verb == ACTION_USE && + Object::combine(obj1, obj2, ALARM_CRACKER, ALARM_SYSTEM)) { + if (_gm->_state._alarmCracked) + _vm->renderMessage(kStringMuseum20); + else { + _vm->renderMessage(kStringMuseum21); + _gm->crack(20); + if (!_gm->_state._alarmOn) { + _vm->renderMessage(kStringMuseum22); + _vm->playSound(kAudioSuccess2); + _gm->_state._alarmCracked = true; + } + } + } else + return false; + return true; +} + +} diff --git a/engines/supernova/supernova2/rooms.h b/engines/supernova/supernova2/rooms.h new file mode 100644 index 0000000000..7f9f2720f0 --- /dev/null +++ b/engines/supernova/supernova2/rooms.h @@ -0,0 +1,847 @@ +/* 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. + * + */ + +#ifndef SUPERNOVA2_ROOMS_H +#define SUPERNOVA2_ROOMS_H + +#include "common/str.h" + +#include "supernova/msn_def.h" +#include "supernova/room.h" + +namespace Common { +class ReadStream; +class WriteStream; +} + +namespace Supernova { + +class GameManager2; +class SupernovaEngine; + +struct RoomEntry { + int _e; + int _s; + int _z; + int _r; + RoomId _exitRoom; +}; + + +class Intro2 : public Room { +public: + Intro2(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + +private: + GameManager2 *_gm; + void titleScreen(); + bool tvSay(int mod1, int mod2, int rest, MessagePosition pos, int id); + bool tvRest(int mod1, int mod2, int rest); + bool displayThoughtMessage(int id); + bool thoughts1(); + bool tvDialogue(); + bool thoughts2(); + + Common::String _introText; +}; + +class Airport : public Room { +public: + Airport(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + +private: + GameManager2 *_gm; +}; + +class TaxiStand : public Room { +public: + TaxiStand(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Street : public Room { +public: + Street(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Games : public Room { +public: + Games(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Cabin2 : public Room { +public: + Cabin2(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; + bool _paid; +}; + +class Kiosk : public Room { +public: + Kiosk(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class CulturePalace : public Room { +public: + CulturePalace(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; + void notEnoughMoney(); +}; + +class Checkout : public Room { +public: + Checkout(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; + void appearance(); + void shouting(); +}; + +class City1 : public Room { +public: + City1(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class City2 : public Room { +public: + City2(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Elevator2 : public Room { +public: + Elevator2(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; + void jobDescription(); +}; + +class Apartment : public Room { +public: + Apartment(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Ship : public Room { +public: + Ship(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + Common::String _outroText; + Common::String _outroText2; + +private: + GameManager2 *_gm; + void kill(); + void outro(); +}; + +class Pyramid : public Room { +public: + Pyramid(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class PyrEntrance : public Room { +public: + PyrEntrance(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; + uint32 _waitTime; +}; + +class Upstairs1 : public Room { +public: + Upstairs1(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Downstairs1 : public Room { +public: + Downstairs1(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class BottomRightDoor : public Room { +public: + BottomRightDoor(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class BottomLeftDoor : public Room { +public: + BottomLeftDoor(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Upstairs2 : public Room { +public: + Upstairs2(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Downstairs2 : public Room { +public: + Downstairs2(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class UpperDoor : public Room { +public: + UpperDoor(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class PuzzleFront : public Room { +public: + PuzzleFront(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class PuzzleBehind : public Room { +public: + PuzzleBehind(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Formula1F : public Room { +public: + Formula1F(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Formula1N : public Room { +public: + Formula1N(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Formula2F : public Room { +public: + Formula2F(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Formula2N : public Room { +public: + Formula2N(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class TomatoF : public Room { +public: + TomatoF(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class TomatoN : public Room { +public: + TomatoN(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class MonsterF : public Room { +public: + MonsterF(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Monster1N : public Room { +public: + Monster1N(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Monster2N : public Room { +public: + Monster2N(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Upstairs3 : public Room { +public: + Upstairs3(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Downstairs3 : public Room { +public: + Downstairs3(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class LCorridor1 : public Room { +public: + LCorridor1(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class LCorridor2 : public Room { +public: + LCorridor2(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class HoleRoom : public Room { +public: + HoleRoom(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class InHole : public Room { +public: + InHole(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Floordoor : public Room { +public: + Floordoor(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class FloordoorU : public Room { +public: + FloordoorU(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class BstDoor : public Room { +public: + BstDoor(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; + char _password[16]; +}; + +class Hall2 : public Room { +public: + Hall2(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class CoffinRoom : public Room { +public: + CoffinRoom(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mask : public Room { +public: + Mask(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Museum : public Room { +public: + Museum(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class MusEntrance : public Room { +public: + MusEntrance(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus1 : public Room { +public: + Mus1(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus2 : public Room { +public: + Mus2(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus3 : public Room { +public: + Mus3(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus4 : public Room { +public: + Mus4(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus5 : public Room { +public: + Mus5(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus6 : public Room { +public: + Mus6(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus7 : public Room { +public: + Mus7(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus8 : public Room { +public: + Mus8(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus9 : public Room { +public: + Mus9(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus10 : public Room { +public: + Mus10(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus11 : public Room { +public: + Mus11(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class MusRound : public Room { +public: + MusRound(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus12 : public Room { +public: + Mus12(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus13 : public Room { +public: + Mus13(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus14 : public Room { +public: + Mus14(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus15 : public Room { +public: + Mus15(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus16 : public Room { +public: + Mus16(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus17 : public Room { +public: + Mus17(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus18 : public Room { +public: + Mus18(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus19 : public Room { +public: + Mus19(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus20 : public Room { +public: + Mus20(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus21 : public Room { +public: + Mus21(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +class Mus22 : public Room { +public: + Mus22(SupernovaEngine *vm, GameManager2 *gm); + virtual void onEntrance(); + virtual void animation(); + virtual bool interact(Action verb, Object &obj1, Object &obj2); + +private: + GameManager2 *_gm; +}; + +} +#endif // SUPERNOVA2_ROOMS_H diff --git a/engines/supernova/supernova2/state.cpp b/engines/supernova/supernova2/state.cpp new file mode 100644 index 0000000000..1bafec87ae --- /dev/null +++ b/engines/supernova/supernova2/state.cpp @@ -0,0 +1,1491 @@ +/* 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 "common/system.h" +#include "graphics/cursorman.h" +#include "graphics/palette.h" +#include "gui/message.h" + +#include "supernova/screen.h" +#include "supernova/supernova.h" +#include "supernova/supernova2/state.h" +#include "supernova/supernova2/stringid.h" + +namespace Supernova { + +bool GameManager2::serialize(Common::WriteStream *out) { + if (out->err()) + return false; + + // GameState + out->writeSint16LE(_state._money); + out->writeSint32LE(_state._startTime - g_system->getMillis()); + out->writeByte(_state._addressKnown); + out->writeByte(_state._poleMagnet); + out->writeByte(_state._admission); + out->writeByte(_state._tipsy); + out->writeByte(_state._dark); + out->writeByte(_state._elevatorE); + out->writeByte(_state._elevatorNumber); + out->writeByte(_state._toMuseum); + 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._pressureCounter); + out->writeByte(_state._sirenOn); + out->writeSint16LE(_state._pyraDirection); + out->writeUint32LE(_state._eventTime - g_system->getMillis()); + out->writeSint32LE(_state._eventCallback); + out->writeByte(_state._taxiPossibility); + for (int i = 0; i < 15; i++) { + out->writeSint16LE(_state._puzzleTab[i]); + } + + // Inventory + out->writeSint32LE(_inventory.getSize()); + out->writeSint32LE(_inventoryScroll); + for (int i = 0; i < _inventory.getSize(); ++i) { + Object *objectStateBegin = _rooms[_inventory.get(i)->_roomId]->getObject(0); + byte objectIndex = _inventory.get(i) - objectStateBegin; + out->writeSint32LE(_inventory.get(i)->_roomId); + out->writeSint32LE(objectIndex); + } + + // Rooms + out->writeByte(_lastRoom->getId()); + out->writeByte(_currentRoom->getId()); + for (int i = 0; i < NUMROOMS2; ++i) { + _rooms[i]->serialize(out); + } + + return !out->err(); +} + + +bool GameManager2::deserialize(Common::ReadStream *in, int version) { + if (in->err()) + return false; + + // GameState + _state._money = in->readSint16LE(); + _state._startTime = in->readSint32LE() + g_system->getMillis(); + _state._addressKnown = in->readByte(); + _state._poleMagnet = in->readByte(); + _state._admission = in->readByte(); + _state._tipsy = in->readByte(); + _state._dark = in->readByte(); + _state._elevatorE = in->readByte(); + _state._elevatorNumber = in->readByte(); + _state._toMuseum = in->readByte(); + _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._pressureCounter = in->readByte(); + _state._sirenOn = in->readByte(); + _state._pyraDirection = in->readSint16LE(); + _state._eventTime = in->readUint32LE() + g_system->getMillis(); + _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)); + + _oldTime = g_system->getMillis(); + + // Inventory + int inventorySize = in->readSint32LE(); + _inventoryScroll = in->readSint32LE(); + _inventory.clear(); + for (int i = 0; i < inventorySize; ++i) { + RoomId objectRoom = static_cast<RoomId>(in->readSint32LE()); + int objectIndex = in->readSint32LE(); + _inventory.add(*_rooms[objectRoom]->getObject(objectIndex)); + } + + // Rooms + RoomId lastRoomId = static_cast<RoomId>(in->readByte()); + RoomId curRoomId = static_cast<RoomId>(in->readByte()); + for (int i = 0; i < NUMROOMS2; ++i) { + _rooms[i]->deserialize(in, version); + } + delete _rooms[BST_DOOR]; + _rooms[BST_DOOR] = new BstDoor(_vm, this); + _lastRoom = _rooms[lastRoomId]; + changeRoom(curRoomId); + + // Some additional variables + _state._previousRoom = _rooms[INTRO2]; + _guiEnabled = true; + _animationEnabled = true; + + return !in->err(); +} + +GameManager2::GameManager2(SupernovaEngine *vm, Sound *sound) + : GameManager(vm, sound) { + initRooms(); + changeRoom(INTRO2); + initState(); +} + +GameManager2::~GameManager2() { + destroyRooms(); +} + +void GameManager2::destroyRooms() { + delete _rooms[INTRO2]; + delete _rooms[AIRPORT]; + delete _rooms[TAXISTAND]; + delete _rooms[STREET]; + delete _rooms[GAMES]; + delete _rooms[CABIN2]; + delete _rooms[KIOSK]; + delete _rooms[CULTURE_PALACE]; + delete _rooms[CHECKOUT]; + delete _rooms[CITY1]; + delete _rooms[CITY2]; + delete _rooms[ELEVATOR2]; + delete _rooms[APARTMENT]; + delete _rooms[SHIP]; + delete _rooms[PYRAMID]; + delete _rooms[PYR_ENTRANCE]; + delete _rooms[UPSTAIRS1]; + delete _rooms[DOWNSTAIRS1]; + delete _rooms[BOTTOM_RIGHT_DOOR]; + delete _rooms[BOTTOM_LEFT_DOOR]; + delete _rooms[UPSTAIRS2]; + delete _rooms[DOWNSTAIRS2]; + delete _rooms[UPPER_DOOR]; + delete _rooms[PUZZLE_FRONT]; + delete _rooms[PUZZLE_BEHIND]; + delete _rooms[FORMULA1_F]; + delete _rooms[FORMULA1_N]; + delete _rooms[FORMULA2_F]; + delete _rooms[FORMULA2_N]; + delete _rooms[TOMATO_F]; + delete _rooms[TOMATO_N]; + delete _rooms[MONSTER_F]; + delete _rooms[MONSTER1_N]; + delete _rooms[MONSTER2_N]; + delete _rooms[UPSTAIRS3]; + delete _rooms[DOWNSTAIRS3]; + delete _rooms[LCORRIDOR1]; + delete _rooms[LCORRIDOR2]; + delete _rooms[HOLE_ROOM]; + delete _rooms[IN_HOLE]; + delete _rooms[FLOORDOOR]; + delete _rooms[FLOORDOOR_U]; + delete _rooms[BST_DOOR]; + delete _rooms[HALL2]; + delete _rooms[COFFIN_ROOM]; + delete _rooms[MASK]; + delete _rooms[MUSEUM]; + delete _rooms[MUS_ENTRANCE]; + delete _rooms[MUS1]; + delete _rooms[MUS2]; + delete _rooms[MUS3]; + delete _rooms[MUS4]; + delete _rooms[MUS5]; + delete _rooms[MUS6]; + delete _rooms[MUS7]; + delete _rooms[MUS8]; + delete _rooms[MUS9]; + delete _rooms[MUS10]; + delete _rooms[MUS11]; + delete _rooms[MUS_ROUND]; + delete _rooms[MUS12]; + delete _rooms[MUS13]; + delete _rooms[MUS14]; + delete _rooms[MUS15]; + delete _rooms[MUS16]; + delete _rooms[MUS17]; + delete _rooms[MUS18]; + delete _rooms[MUS19]; + delete _rooms[MUS20]; + delete _rooms[MUS21]; + delete _rooms[MUS22]; +} + +void GameManager2::initState() { + _currentInputObject = &_nullObject; + _inputObject[0] = &_nullObject; + _inputObject[1] = &_nullObject; + _inputVerb = ACTION_WALK; + _processInput = false; + _guiEnabled = true; + _animationEnabled = true; + _roomBrightness = 255; + _mouseClicked = false; + _keyPressed = false; + _mouseX = -1; + _mouseY = -1; + _mouseField = -1; + _inventoryScroll = 0; + _restTime = 0; + _oldTime = g_system->getMillis(); + _timerPaused = 0; + _timePaused = false; + _messageDuration = 0; + _animationTimer = 0; + _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) { + _sentenceNumber[i] = -1; + _texts[i] = kNoString; + _rows[i] = 0; + _rowsStart[i] = 0; + _dials[i] = 1; + } + + _prevImgId = 0; + + _state._money = 20; + _state._startTime = 0; + _state._addressKnown = false; + _state._previousRoom = _currentRoom; + _lastRoom = _rooms[INTRO2]; + _state._poleMagnet = false; + _state._admission = 0; + _state._tipsy = false; + _state._dark = false; + _state._elevatorE = 0; + _state._elevatorNumber = 0; + _state._toMuseum = false; + _state._pyraE = 0; + _state._pyraS = 4; + _state._pyraZ = 10; + _state._alarmOn = false; + _state._alarmCracked = false; + _state._haste = false; + _state._pressureCounter = 0; + _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]; +} + +void GameManager2::initRooms() { + _rooms = new Room *[NUMROOMS2]; + _rooms[INTRO2] = new Intro2(_vm, this); + _rooms[AIRPORT] = new Airport(_vm, this); + _rooms[TAXISTAND] = new TaxiStand(_vm, this); + _rooms[STREET] = new Street(_vm, this); + _rooms[GAMES] = new Games(_vm, this); + _rooms[CABIN2] = new Cabin2(_vm, this); + _rooms[KIOSK] = new Kiosk(_vm, this); + _rooms[CULTURE_PALACE] = new CulturePalace(_vm, this); + _rooms[CHECKOUT] = new Checkout(_vm, this); + _rooms[CITY1] = new City1(_vm, this); + _rooms[CITY2] = new City2(_vm, this); + _rooms[ELEVATOR2] = new Elevator2(_vm, this); + _rooms[APARTMENT] = new Apartment(_vm, this); + _rooms[SHIP] = new Ship(_vm, this); + _rooms[PYRAMID] = new Pyramid(_vm, this); + _rooms[PYR_ENTRANCE] = new PyrEntrance(_vm, this); + _rooms[UPSTAIRS1] = new Upstairs1(_vm, this); + _rooms[DOWNSTAIRS1] = new Downstairs1(_vm, this); + _rooms[BOTTOM_RIGHT_DOOR] = new BottomRightDoor(_vm, this); + _rooms[BOTTOM_LEFT_DOOR] = new BottomLeftDoor(_vm, this); + _rooms[UPSTAIRS2] = new Upstairs2(_vm, this); + _rooms[DOWNSTAIRS2] = new Downstairs2(_vm, this); + _rooms[UPPER_DOOR] = new UpperDoor(_vm, this); + _rooms[PUZZLE_FRONT] = new PuzzleFront(_vm, this); + _rooms[PUZZLE_BEHIND] = new PuzzleBehind(_vm, this); + _rooms[FORMULA1_F] = new Formula1F(_vm, this); + _rooms[FORMULA1_N] = new Formula1N(_vm, this); + _rooms[FORMULA2_F] = new Formula2F(_vm, this); + _rooms[FORMULA2_N] = new Formula2N(_vm, this); + _rooms[TOMATO_F] = new TomatoF(_vm, this); + _rooms[TOMATO_N] = new TomatoN(_vm, this); + _rooms[MONSTER_F] = new MonsterF(_vm, this); + _rooms[MONSTER1_N] = new Monster1N(_vm, this); + _rooms[MONSTER2_N] = new Monster2N(_vm, this); + _rooms[UPSTAIRS3] = new Upstairs3(_vm, this); + _rooms[DOWNSTAIRS3] = new Downstairs3(_vm, this); + _rooms[LCORRIDOR1] = new LCorridor1(_vm, this); + _rooms[LCORRIDOR2] = new LCorridor2(_vm, this); + _rooms[HOLE_ROOM] = new HoleRoom(_vm, this); + _rooms[IN_HOLE] = new InHole(_vm, this); + _rooms[FLOORDOOR] = new Floordoor(_vm, this); + _rooms[FLOORDOOR_U] = new FloordoorU(_vm, this); + _rooms[BST_DOOR] = new BstDoor(_vm, this); + _rooms[HALL2] = new Hall2(_vm, this); + _rooms[COFFIN_ROOM] = new CoffinRoom(_vm, this); + _rooms[MASK] = new Mask(_vm, this); + _rooms[MUSEUM] = new Museum(_vm, this); + _rooms[MUS_ENTRANCE] = new MusEntrance(_vm, this); + _rooms[MUS1] = new Mus1(_vm, this); + _rooms[MUS2] = new Mus2(_vm, this); + _rooms[MUS3] = new Mus3(_vm, this); + _rooms[MUS4] = new Mus4(_vm, this); + _rooms[MUS5] = new Mus5(_vm, this); + _rooms[MUS6] = new Mus6(_vm, this); + _rooms[MUS7] = new Mus7(_vm, this); + _rooms[MUS8] = new Mus8(_vm, this); + _rooms[MUS9] = new Mus9(_vm, this); + _rooms[MUS10] = new Mus10(_vm, this); + _rooms[MUS11] = new Mus11(_vm, this); + _rooms[MUS_ROUND] = new MusRound(_vm, this); + _rooms[MUS12] = new Mus12(_vm, this); + _rooms[MUS13] = new Mus13(_vm, this); + _rooms[MUS14] = new Mus14(_vm, this); + _rooms[MUS15] = new Mus15(_vm, this); + _rooms[MUS16] = new Mus16(_vm, this); + _rooms[MUS17] = new Mus17(_vm, this); + _rooms[MUS18] = new Mus18(_vm, this); + _rooms[MUS19] = new Mus19(_vm, this); + _rooms[MUS20] = new Mus20(_vm, this); + _rooms[MUS21] = new Mus21(_vm, this); + _rooms[MUS22] = new Mus22(_vm, this); +} + +bool GameManager2::canSaveGameStateCurrently() { + return _animationEnabled && _guiEnabled && !_state._haste; +} + +void GameManager2::updateEvents() { + handleTime(); + if (_animationEnabled && !_vm->_screen->isMessageShown() && _animationTimer == 0) + _currentRoom->animation(); + + if (_state._eventCallback != kNoFn && g_system->getMillis() >= _state._eventTime) { + _vm->_allowLoadGame = false; + _vm->_allowSaveGame = false; + _state._eventTime = kMaxTimerValue; + EventFunction fn = _state._eventCallback; + _state._eventCallback = kNoFn; + switch (fn) { + case kNoFn: + break; + case kSoberFn: + sober(); + break; + case kPyramidEndFn: + pyramidEnd(); + break; + case kCaughtFn: + caught(); + break; + default: //shouldn't happen + break; + } + _vm->_allowLoadGame = true; + _vm->_allowSaveGame = true; + return; + } + + _mouseClicked = false; + _keyPressed = false; + Common::Event event; + while (g_system->getEventManager()->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_KEYDOWN: + _keyPressed = true; + processInput(event.kbd); + break; + case Common::EVENT_LBUTTONUP: + // fallthrough + case Common::EVENT_RBUTTONUP: + _mouseClicked = true; + // fallthrough + case Common::EVENT_MOUSEMOVE: + _mouseClickType = event.type; + _mouseX = event.mouse.x; + _mouseY = event.mouse.y; + if (_guiEnabled) + processInput(); + break; + default: + break; + } + } +} + +void GameManager2::handleTime() { + if (_timerPaused) + return; + int32 newTime = g_system->getMillis(); + int32 delta = newTime - _oldTime; + _time += delta; + + if (_animationTimer > delta) + _animationTimer -= delta; + else + _animationTimer = 0; + + _oldTime = newTime; +} + +void GameManager2::drawMapExits() { +// TODO: Preload _exitList on room entry instead on every call + _vm->renderBox(281, 161, 39, 39, kColorWhite25); + + if ((_currentRoom >= _rooms[PYR_ENTRANCE] && _currentRoom <= _rooms[HOLE_ROOM]) || + (_currentRoom >= _rooms[FLOORDOOR] && _currentRoom <= _rooms[BST_DOOR])) + compass(); + else { + for (int i = 0; i < 25; i++) + _exitList[i] = -1; + for (int i = 0; i < kMaxObject; i++) { + if (_currentRoom->getObject(i)->hasProperty(EXIT)) { + byte r = _currentRoom->getObject(i)->_direction; + _exitList[r] = i; + int x = 284 + 7 * (r % 5); + int y = 164 + 7 * (r / 5); + _vm->renderBox(x, y, 5, 5, kColorDarkRed); + } + } + } +} + +void GameManager2::takeMoney(int amount) { + _state._money += amount; + _vm->setGameString(kStringMoney, Common::String::format("%d Xa", _state._money)); +} + +bool GameManager2::genericInteract(Action verb, Object &obj1, Object &obj2) { + if (verb == ACTION_OPEN && obj1._id == WALLET) { + if (_rooms[TAXISTAND]->getObject(4)->_type & CARRIED) + _vm->renderMessage(kStringEmpty); + else { + _vm->renderMessage(kStringWalletOpen); + takeObject(*_rooms[TAXISTAND]->getObject(4)); + takeObject(*_rooms[TAXISTAND]->getObject(5)); + takeMoney(1); + _vm->playSound(kAudioSuccess2); + } + } else if (verb == ACTION_PRESS && obj1._id == TRANSMITTER) { + if (_currentRoom == _rooms[TAXISTAND]) { + if (_currentRoom->getObject(0)->_type != EXIT) { + _vm->renderImage(5); + wait(3); + _vm->renderImage(6); + _vm->playSound(kAudioTaxiOpen); + _currentRoom->getObject(0)->_type = EXIT; + drawMapExits(); + } + } else if (_currentRoom == _rooms[STREET] || + _currentRoom == _rooms[CULTURE_PALACE] || + _currentRoom == _rooms[CITY1] || + _currentRoom == _rooms[CITY2]) { + Common::String t = _vm->getGameString(kStringTaxiArrives); + _vm->renderMessage(t); + waitOnInput((t.size() + 20) * _vm->_textSpeed / 10); + _vm->removeMessage(); + taxi(); + } else + _vm->renderMessage(kStringNothingHappens); + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, ROD, MAGNET)) { + Object *o1, *o2; + if (obj2._id == ROD) { + o1 = &obj2; + o2 = &obj1; + } else { + o1 = &obj1; + o2 = &obj2; + } + if (!(o1->_type & CARRIED)) + return false; + + if (!(o2->_type & CARRIED)) + takeObject(*o2); + + _vm->renderMessage(kStringAttachMagnet); + o1->_name = kStringPoleMagnet; + o1->_description = kStringCunning; + _inventory.remove(*o2); + _rooms[APARTMENT]->setSectionVisible(kMaxSection - 1, kShownTrue); + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, CHIP, PLAYER)) { + Object *o1, *o2; + if (obj2._id == CHIP) { + o1 = &obj2; + o2 = &obj1; + } else { + o1 = &obj1; + o2 = &obj2; + } + if (!(o2->_type & CARRIED)) + _vm->renderMessage(kStringMustBuyFirst); + else { + if (!(o1->_type & CARRIED)) + { + _vm->renderImage(1); + _vm->renderImage(2 + 128); + _currentRoom->getObject(0)->_click = 255; + } else + _inventory.remove(*o1); + + _vm->renderMessage(kStringInsertChip); + if (_state._admission) + _state._admission = 2; + else + _state._admission = 1; + } + } else if (verb == ACTION_USE && Object::combine(obj1, obj2, DISCMAN, PLAYER)) { + switch (_state._admission) { + case 1: + // fall through + case 2: + _vm->renderMessage(kStringTransferCD); + _state._admission = 2; + _vm->playSound(kAudioSuccess2); + break; + default: + _vm->renderMessage(kStringCDNotInserted); + } + } else if (verb == ACTION_OPEN && obj1._id == PLAYER) { + switch (_state._admission) { + case 1: + _state._admission = 0; + playerTakeOut(); + break; + case 2: + _state._admission = 3; + playerTakeOut(); + break; + default: + _vm->renderMessage(kStringChipNotInserted); + } + } else if (verb == ACTION_OPEN && obj1._id == DISCMAN) { + _vm->renderMessage(kStringWhatFor); + } else if (verb == ACTION_PRESS && obj1._id == DISCMAN) { + _vm->renderMessage(kStringMMCD); + playCD(); + } else if (verb == ACTION_PRESS && obj1._id == PLAYER) { + switch (_state._admission) { + case 1: + _vm->renderMessage(kStringChipEmpty); + break; + case 2: + _vm->renderMessage(kStringListeningToCD); + playCD(); + break; + default: + _vm->renderMessage(kStringNoChip); + } + } else if ((verb == ACTION_OPEN || verb == ACTION_USE) && + obj1._id == BOTTLE && (obj1._type & CARRIED)) { + _vm->renderMessage(kStringTipsy); + _state._tipsy = true; + _state._eventTime = g_system->getMillis() + 60000; + _state._eventCallback = kSoberFn; + } else if (verb == ACTION_LOOK && obj1._id == MUSCARD) { + _vm->setCurrentImage(30); + _vm->renderImage(0); + //karte_an = true + waitOnInput(100000); + //karte_an = false + _vm->removeMessage(); + _vm->renderRoom(*_currentRoom); + drawGUI(); + } else + return false; + return true; +} + +void GameManager2::playCD() { + CursorMan.showMouse(false); + _vm->playSound(kMusicMadMonkeys); + Common::KeyCode k = Common::KEYCODE_INVALID; + while(_vm->_sound->isPlaying()) + if (waitOnInput(1, k)) + break; + _vm->_sound->stop(); + _vm->removeMessage(); + CursorMan.showMouse(true); +} + +void GameManager2::handleInput() { + bool validCommand = genericInteract(_inputVerb, *_inputObject[0], *_inputObject[1]); + if (!validCommand) + validCommand = _currentRoom->interact(_inputVerb, *_inputObject[0], *_inputObject[1]); + if (!validCommand) { + switch (_inputVerb) { + case ACTION_LOOK: + _vm->renderMessage(_inputObject[0]->_description); + break; + + case ACTION_WALK: + if (_inputObject[0]->hasProperty(CARRIED)) { + // You already carry this. + _vm->renderMessage(kStringGenericInteract1); + } else if (!_inputObject[0]->hasProperty(EXIT)) { + // You're already there. + _vm->renderMessage(kStringGenericInteract2); + } else if (_inputObject[0]->hasProperty(OPENABLE) && !_inputObject[0]->hasProperty(OPENED)) { + // This is closed + _vm->renderMessage(kStringGenericInteract3); + } else { + _lastRoom = _currentRoom; + changeRoom(_inputObject[0]->_exitRoom); + } + + break; + + case ACTION_TAKE: + if (_inputObject[0]->hasProperty(OPENED)) { + // You already have that + _vm->renderMessage(kStringGenericInteract4); + } else if (_inputObject[0]->hasProperty(UNNECESSARY)) { + // You do not need that. + _vm->renderMessage(kStringGenericInteract5); + } else if (!_inputObject[0]->hasProperty(TAKE)) { + // You can't take that. + _vm->renderMessage(kStringGenericInteract6); + } else + takeObject(*_inputObject[0]); + + break; + + case ACTION_OPEN: + if (!_inputObject[0]->hasProperty(OPENABLE)) { + // This can't be opened + _vm->renderMessage(kStringGenericInteract7); + } else if (_inputObject[0]->hasProperty(OPENED)) { + // This is already opened. + _vm->renderMessage(kStringGenericInteract8); + } else if (_inputObject[0]->hasProperty(CLOSED)) { + // This is locked. + _vm->renderMessage(kStringGenericInteract9); + } else { + _vm->renderImage(_inputObject[0]->_section); + _inputObject[0]->setProperty(OPENED); + byte i = _inputObject[0]->_click; + _inputObject[0]->_click = _inputObject[0]->_click2; + _inputObject[0]->_click2 = i; + _vm->_sound->play(kAudioTaxiOpen); + } + break; + + case ACTION_CLOSE: + if (!_inputObject[0]->hasProperty(OPENABLE) || + (_inputObject[0]->hasProperty(CLOSED) && + _inputObject[0]->hasProperty(OPENED))) { + // This can't be closed. + _vm->renderMessage(kStringGenericInteract10); + } else if (!_inputObject[0]->hasProperty(OPENED)) { + // This is already closed. + _vm->renderMessage(kStringGenericInteract11); + } else { + _vm->renderImage(invertSection(_inputObject[0]->_section)); + _inputObject[0]->disableProperty(OPENED); + byte i = _inputObject[0]->_click; + _inputObject[0]->_click = _inputObject[0]->_click2; + _inputObject[0]->_click2 = i; + _vm->_sound->play(kAudioElevator1); + } + break; + + case ACTION_GIVE: + if (_inputObject[0]->hasProperty(CARRIED)) { + // Better keep it! + _vm->renderMessage(kStringGenericInteract12); + } + break; + + default: + // This is not possible. + _vm->renderMessage(kStringGenericInteract13); + } + } +} + +void GameManager2::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) { + Common::Event event; + event.type = Common::EVENT_MOUSEMOVE; + event.mouse = Common::Point(0, 0); + _vm->getEventManager()->pushEvent(event); + event.type = Common::EVENT_MOUSEMOVE; + event.mouse = Common::Point(_mouseX, _mouseY); + _vm->getEventManager()->pushEvent(event); + } + + resetInputState(); + } + + if (_guiEnabled) { + if (!_vm->_screen->isMessageShown()) { + g_system->fillScreen(kColorBlack); + _vm->renderRoom(*_currentRoom); + } + if (_currentRoom->getId() < MUSEUM) + drawMapExits(); + else + drawClock(); + drawInventory(); + drawStatus(); + drawCommandBox(); + } + + if (_vm->_screen->getViewportBrightness() == 0) + _vm->paletteFadeIn(); + + if (!_currentRoom->hasSeen() && _newRoom) { + _newRoom = false; + _currentRoom->onEntrance(); + } +} + +void GameManager2::leaveTaxi() { + _currentRoom = _state._previousRoom; + _vm->renderRoom(*_currentRoom); + _guiEnabled = true; +} + +void GameManager2::taxiUnknownDestination() { + _vm->renderImage(invertSection(2)); + _vm->renderImage(0); + _vm->renderImage(1); + _vm->renderImage(4); + waitOnInput(_vm->_textSpeed * 3); + _vm->renderImage(invertSection(4)); + _vm->renderImage(0); + _vm->renderImage(1); + _vm->renderImage(2); +} + +void GameManager2::taxiPayment(int price, int destination) { + static int answers[] = { + kStringPay, + kStringLeaveTaxi + }; + if (dialog(2, _dials, answers, 0)) { + leaveTaxi(); + } else if (_state._money < price) { + Common::String t = _vm->getGameString(kStringNotEnoughMoney); + _vm->renderMessage(t); + waitOnInput((t.size() + 20) * _vm->_textSpeed / 10); + _vm->removeMessage(); + leaveTaxi(); + } else { + takeMoney(-price); + _vm->renderImage(invertSection(5)); + _vm->renderImage(invertSection(6)); + _vm->renderImage(0); + _vm->renderImage(1); + _vm->renderImage(3); + + Common::String t = _vm->getGameString(kStringTaxiAccelerating); + _vm->renderMessage(t); + _vm->playSound(kAudioTaxiLeaving); + while(_vm->_sound->isPlaying()) + wait(1); + waitOnInput((t.size() + 20) * _vm->_textSpeed / 10); + _vm->removeMessage(); + + _vm->paletteFadeOut(); + _vm->_system->fillScreen(kColorBlack); + _vm->_screen->setViewportBrightness(255); + _vm->_screen->setGuiBrightness(255); + _vm->paletteBrightness(); + + Common::String t2 = _vm->getGameString(kString5MinutesLater); + _vm->renderMessage(t2); + _vm->playSound(kAudioTaxiArriving); + while(_vm->_sound->isPlaying()) + wait(1); + waitOnInput((t2.size() + 20) * _vm->_textSpeed / 10); + _vm->removeMessage(); + _vm->paletteFadeOut(); + + switch (destination) { + case 0: + changeRoom(TAXISTAND); + break; + case 1: + changeRoom(STREET); + break; + case 2: + changeRoom(CULTURE_PALACE); + break; + case 10: + changeRoom(CITY1); + break; + case 11: + changeRoom(CITY2); + break; + } + } +} + +void GameManager2::taxi() { + _vm->_allowSaveGame = false; + static int dest[] = { + kStringAirport, + kStringDowntown, + kStringCulturePalace, + kStringEarth, + kStringPrivateApartment, + kStringLeaveTaxi + }; + Common::String input; + int possibility = _state._taxiPossibility; + + _state._previousRoom = _currentRoom; + _currentRoom = _rooms[INTRO2]; + _vm->setCurrentImage(4); + _vm->renderImage(0); + _vm->renderImage(1); + _vm->renderImage(2); + + if (_state._previousRoom == _rooms[TAXISTAND]) possibility += 1; + else if (_state._previousRoom == _rooms[STREET]) possibility += 2; + else if (_state._previousRoom == _rooms[CULTURE_PALACE]) possibility += 4; + int answer; + do { + _currentRoom->removeSentenceByMask(possibility, 1); + switch (answer = dialog(6, _dials, dest, 1)) { + case 3: + _state._taxiPossibility += 8; + possibility += 8; + taxiUnknownDestination(); + break; + case 5: + leaveTaxi(); + break; + case 4: + _vm->renderMessage(kStringAddress); + do { + edit(input, 101, 70, 18); + } while ((_key.keycode != Common::KEYCODE_RETURN) && (_key.keycode != Common::KEYCODE_ESCAPE) && !_vm->shouldQuit()); + + _vm->removeMessage(); + if (_key.keycode == Common::KEYCODE_ESCAPE) { + leaveTaxi(); + break; + } + input.toUppercase(); + if (input == "115AY2,96A" || input == "115AY2,96B") + answer = 10; + else if (input == "341,105A" || input == "341,105B") { + if (_state._addressKnown) + answer = 11; + else { + Common::String t = _vm->getGameString(kStringCheater); + _vm->renderMessage(t); + waitOnInput((t.size() + 20) * _vm->_textSpeed / 10); + _vm->removeMessage(); + + leaveTaxi(); + break; + } + } else { + answer = 3; + input = ""; + taxiUnknownDestination(); + break; + } + _vm->renderImage(invertSection(2)); + _vm->renderImage(0); + _vm->renderImage(1); + _vm->renderImage(6); + _vm->playSound(kAudioSuccess2); + taxiPayment(14, answer); + break; + default: + _vm->renderImage(invertSection(2)); + _vm->renderImage(0); + _vm->renderImage(1); + _vm->renderImage(5); + taxiPayment(8, answer); + break; + } + _rooms[INTRO2]->addAllSentences(1); + } while(answer == 3 && !_vm->shouldQuit()); + _vm->_allowSaveGame = true; + +} + +void GameManager2::playerTakeOut() { + _vm->renderMessage(kStringRemoveChip); + Object *o = _rooms[APARTMENT]->getObject(0); + o->_section = 0; + takeObject(*o); +} + +void GameManager2::sober() { + _state._tipsy = false; +} + +bool GameManager2::talk(int mod1, int mod2, int rest, MessagePosition pos, int id) { + Common::KeyCode key = Common::KEYCODE_INVALID; + const Common::String& text = _vm->getGameString(id); + + _vm->renderMessage(text, pos); + int animation_count = (text.size() + 20) * (10 - rest) * _vm->_textSpeed / 400; + _restTime = (text.size() + 20) * rest * _vm->_textSpeed / 400; + + while (animation_count) { + if (mod1) + _vm->renderImage(mod1); + + if (waitOnInput(2, key)) { + _vm->removeMessage(); + return key != Common::KEYCODE_ESCAPE && !_vm->shouldQuit(); + } + if (mod2) + _vm->renderImage(mod2); + + if (waitOnInput(2, key)) { + _vm->removeMessage(); + return key != Common::KEYCODE_ESCAPE && !_vm->shouldQuit(); + } + animation_count--; + } + if (_restTime == 0) + _vm->removeMessage(); + + return true; +} + +bool GameManager2::talkRest(int mod1, int mod2, int rest) { + Common::KeyCode key = Common::KEYCODE_INVALID; + while (rest) { + _vm->renderImage(mod1); + if (waitOnInput(2, key)) { + _vm->removeMessage(); + return key != Common::KEYCODE_ESCAPE && !_vm->shouldQuit(); + } + _vm->renderImage(mod2); + if (waitOnInput(2, key)) { + _vm->removeMessage(); + return key != Common::KEYCODE_ESCAPE && !_vm->shouldQuit(); + } + rest--; + } + return true; +} + +void GameManager2::pyramidEnd() { + _vm->renderMessage(kStringPyramid0); + waitOnInput(_messageDuration); + _vm->removeMessage(); + _vm->paletteFadeOut(); + _vm->loadGame(kSleepAutosaveSlot); + changeRoom(CABIN2); + drawGUI(); + _rooms[CABIN2]->setSectionVisible(kMaxSection - 1, kShownFalse); + _rooms[CABIN2]->setSectionVisible(kMaxSection - 2, kShownTrue); + _rooms[CABIN2]->setSectionVisible(1, kShownFalse); +} + +void GameManager2::passageConstruction() { + static ConstructionEntry constructionTab[9] = { + {0, 4, 10, 2, 13}, + {0, 4, 9, 2, 14}, + {0, 4, 8, 3, 2}, + {1, 4, 7, 3, 1}, + {1, 5, 7, 3, 3}, + {1, 6, 7, 3, 5}, + {1, 4, 7, 1, 2}, + {1, 2, 5, 1, 1}, + {0, 4, 9, 2, 20} + }; + + changeRoom(PYR_ENTRANCE); + _rooms[PYR_ENTRANCE]->setSectionVisible(1, + !wall(_state._pyraS, _state._pyraZ, _state._pyraDirection, 0, -1)); + _rooms[PYR_ENTRANCE]->setSectionVisible(2, + !wall(_state._pyraS, _state._pyraZ, _state._pyraDirection, 0, 1)); + _rooms[PYR_ENTRANCE]->setSectionVisible(7, + wall(_state._pyraS, _state._pyraZ, _state._pyraDirection, 1, 0)); + + if (!_rooms[PYR_ENTRANCE]->isSectionVisible(7)) { + _rooms[PYR_ENTRANCE]->getObject(3)->_type = EXIT; + _rooms[PYR_ENTRANCE]->getObject(3)->_click = 0; + _rooms[PYR_ENTRANCE]->setSectionVisible(3, + !wall(_state._pyraS, _state._pyraZ, _state._pyraDirection, 1, -1)); + _rooms[PYR_ENTRANCE]->setSectionVisible(4, + !wall(_state._pyraS, _state._pyraZ, _state._pyraDirection, 1, 1)); + _rooms[PYR_ENTRANCE]->setSectionVisible(8, + wall(_state._pyraS, _state._pyraZ, _state._pyraDirection, 2, 0)); + if (!_rooms[PYR_ENTRANCE]->isSectionVisible(8)) { + _rooms[PYR_ENTRANCE]->setSectionVisible(5, + !wall(_state._pyraS, _state._pyraZ, _state._pyraDirection, 2, -1)); + _rooms[PYR_ENTRANCE]->setSectionVisible(6, + !wall(_state._pyraS, _state._pyraZ, _state._pyraDirection, 2, 1)); + } else { + _rooms[PYR_ENTRANCE]->setSectionVisible(5, kShownFalse); + _rooms[PYR_ENTRANCE]->setSectionVisible(6, kShownFalse); + } + } else { + _rooms[PYR_ENTRANCE]->getObject(3)->_type = NULLTYPE; + _rooms[PYR_ENTRANCE]->getObject(3)->_click = 255; + _rooms[PYR_ENTRANCE]->setSectionVisible(3, kShownFalse); + _rooms[PYR_ENTRANCE]->setSectionVisible(4, kShownFalse); + _rooms[PYR_ENTRANCE]->setSectionVisible(8, kShownFalse); + } + for (int i = 0; i < 9; i++) { + bool b = (_state._pyraE == constructionTab[i]._e && + _state._pyraS == constructionTab[i]._s && + _state._pyraZ == constructionTab[i]._z && + _state._pyraDirection == constructionTab[i]._r); + if (constructionTab[i]._a > 12) + _rooms[PYR_ENTRANCE]->setSectionVisible(constructionTab[i]._a, b); + else if (b) + _rooms[PYR_ENTRANCE]->setSectionVisible(constructionTab[i]._a, kShownTrue); + } + + _rooms[PYR_ENTRANCE]->setSectionVisible(18, kShownFalse); + _rooms[PYR_ENTRANCE]->setSectionVisible(19, kShownFalse); + _rooms[PYR_ENTRANCE]->setSectionVisible(21, kShownFalse); + _rooms[PYR_ENTRANCE]->getObject(0)->_click = 255; + + if (_state._pyraE == 0 && _state._pyraS == 4 && _state._pyraZ == 10) { + switch (_state._pyraDirection) { + case 0: + _rooms[PYR_ENTRANCE]->setSectionVisible(19, kShownTrue); + _rooms[PYR_ENTRANCE]->getObject(0)->_click = 8; + break; + case 2: + _rooms[PYR_ENTRANCE]->setSectionVisible(18, kShownTrue); + _rooms[PYR_ENTRANCE]->getObject(0)->_click = 7; + break; + case 1: + _rooms[PYR_ENTRANCE]->setSectionVisible(21, kShownTrue); + _rooms[PYR_ENTRANCE]->getObject(0)->_click = 9; + break; + } + } + _rooms[PYR_ENTRANCE]->setSectionVisible(9, + _rooms[PYR_ENTRANCE]->isSectionVisible(7) & + !_rooms[PYR_ENTRANCE]->isSectionVisible(1)); + _rooms[PYR_ENTRANCE]->setSectionVisible(10, + _rooms[PYR_ENTRANCE]->isSectionVisible(7) & + !_rooms[PYR_ENTRANCE]->isSectionVisible(2)); + _rooms[PYR_ENTRANCE]->setSectionVisible(11, + _rooms[PYR_ENTRANCE]->isSectionVisible(8) & + !_rooms[PYR_ENTRANCE]->isSectionVisible(3)); + _rooms[PYR_ENTRANCE]->setSectionVisible(12, + _rooms[PYR_ENTRANCE]->isSectionVisible(8) & + !_rooms[PYR_ENTRANCE]->isSectionVisible(4)); +} + +byte GameManager2::wall(int s, int z, int direction, int stepsForward, int stepsRight) { + static char vertical[2][12][11] = { + { + {0,0,0,0,0,0,0,0,0,0,0}, + {0,1,0,0,0,0,0,0,0,0,0}, + {1,0,1,0,0,0,0,0,0,0,0}, + {1,0,1,0,1,0,0,0,0,0,0}, + {0,1,0,0,1,0,0,1,0,0,0}, + {0,0,1,0,0,0,1,0,1,0,0}, + {0,0,0,1,1,0,1,0,0,0,0}, + {0,0,0,1,1,0,0,1,0,0,0}, + {0,0,0,0,0,1,0,1,0,0,0}, + {0,0,0,0,0,1,1,0,1,0,0}, + {0,0,0,0,1,0,0,0,1,0,0}, + {0,0,0,0,1,0,0,0,0,0,0} + }, + { + {0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,1,0,0,0,0,0,0}, + {0,0,0,0,1,0,0,0,0,0,0}, + {0,1,0,1,0,0,0,0,0,0,0}, + {0,1,0,1,1,0,0,0,0,0,0}, + {1,0,0,0,1,0,0,0,0,0,0}, + {0,0,0,0,0,1,0,0,1,0,0}, + {0,0,0,0,0,0,1,1,0,0,1}, + {0,0,0,0,0,1,0,1,0,0,1}, + {0,0,0,0,1,0,1,0,1,1,0}, + {0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0} + } + }; + + static char horizontal[2][11][12] = { + { + {0,1,1,0,0,0,0,0,0,0,0,0}, + {0,0,1,0,0,0,0,0,0,0,0,0}, + {0,1,0,1,1,0,0,0,0,0,0,0}, + {0,1,1,0,0,0,0,0,0,0,0,0}, + {0,0,1,0,0,1,1,0,1,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,1,0,0,0,0}, + {0,0,0,0,1,1,0,0,0,0,0,0}, + {0,0,0,0,0,1,0,1,1,0,0,0}, + {0,0,0,0,0,1,1,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0} + }, + { + {0,0,0,0,0,0,0,0,0,0,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0}, + {0,1,0,0,1,0,0,0,0,0,0,0}, + {0,0,0,0,1,0,0,0,0,0,0,0}, + {0,0,1,1,0,0,0,0,0,0,0,0}, + {0,1,1,0,0,1,0,0,0,0,0,0}, + {0,0,0,0,0,0,1,0,1,0,0,0}, + {0,0,0,0,0,1,1,0,0,0,0,0}, + {0,0,0,0,0,1,0,1,1,0,1,0}, + {0,0,0,0,0,1,1,0,0,1,0,0}, + {0,0,0,0,0,0,0,0,0,0,0,0} + } + }; + int newR; + if (stepsRight) { + if (stepsRight > 0) + newR = (direction + 1) & 3; + else { + newR = (direction - 1) & 3; + stepsRight = -stepsRight; + } + switch (direction) { + case 0: + return wall(s, z - stepsForward, newR, stepsRight, 0); + case 2: + return wall(s, z + stepsForward, newR, stepsRight, 0); + case 1: + return wall(s + stepsForward, z, newR, stepsRight, 0); + case 3: + return wall(s - stepsForward, z, newR, stepsRight, 0); + } + } + switch (direction) { + case 0: + return vertical [_state._pyraE][z + 1 - stepsForward][s] == 0; + case 2: + return vertical [_state._pyraE][z + stepsForward][s] == 0; + case 1: + return horizontal[_state._pyraE][z][s + stepsForward] == 0; + case 3: + return horizontal[_state._pyraE][z][s + 1 - stepsForward] == 0; + } + return 0; +} + +bool GameManager2::move(Action verb, Object &obj) { + if (verb == ACTION_WALK && obj._id == CORRIDOR) { + switch (_state._pyraDirection) { + case 0: + _state._pyraZ--; + break; + case 1: + _state._pyraS++; + break; + case 2: + _state._pyraZ++; + break; + case 3: + _state._pyraS--; + break; + } + } else if (verb == ACTION_WALK && obj._id == G_RIGHT) { + _state._pyraDirection++; + _state._pyraDirection &= 3; + } else if (verb == ACTION_WALK && obj._id == G_LEFT) { + _state._pyraDirection--; + _state._pyraDirection &= 3; + } else + return false; + return true; +} + +void GameManager2::compass() { + static int dirs[7] = { + kStringDirection1, + kStringDirection2, + kStringDirection3, + kStringDirection4, + kStringDirection1, + kStringDirection2, + kStringDirection3 + }; + _vm->renderBox(281, 161, 39, 39, kColorWhite63); + _vm->renderBox(295, 180, 13, 3, kColorWhite44); + _vm->renderBox(300, 175, 3, 13, kColorWhite44); + _vm->renderText(dirs[_state._pyraDirection ], 299, 163, kColorBlack); + _vm->renderText(dirs[_state._pyraDirection + 1], 312, 179, kColorBlack); + _vm->renderText(dirs[_state._pyraDirection + 2], 299, 191, kColorBlack); + _vm->renderText(dirs[_state._pyraDirection + 3], 283, 179, kColorBlack); +} + +void GameManager2::puzzleConstruction() { + _vm->setCurrentImage(12); + MSNImage *image = _vm->_screen->getCurrentImage(); + for (int i = 0; i < 16; i ++) { + _puzzleField[i] = 255; + } + for (int i = 0; i < 15; i++) { + image->_section[i + 1].x1 = 95 + (_state._puzzleTab[i] % 4) * 33; + image->_section[i + 1].x2 = image->_section[i + 1].x1 + 31; + image->_section[i + 1].y1 = 24 + (_state._puzzleTab[i] / 4) * 25; + image->_section[i + 1].y2 = image->_section[i + 1].y1 + 23; + + _puzzleField[_state._puzzleTab[i]] = i; + } +} + +void GameManager2::alarm() { + _vm->_sound->playSiren(); + _state._sirenOn = true; + if (_vm->_screen->isMessageShown()) + _vm->removeMessage(); + _vm->renderMessage(kStringMuseum7); + _state._eventTime = g_system->getMillis() + 16200; + _state._eventCallback = kCaughtFn; + _state._alarmOn = true; +} + +void GameManager2::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 GameManager2::caught2() { + _vm->renderMessage(kStringMuseum8); + _vm->playSound(kAudioCaught); + waitOnInput(_messageDuration); + _vm->removeMessage(); + _state._sirenOn = false; + _mapOn = false; + _state._haste = false; + dead(kStringMuseum9); +} + +void GameManager2::drawClock() { + int time = (g_system->getMillis() - _state._startTime) / 600; + 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_ENTRANCE] && second >= 22 && second <= 29) { + if (!_steps && !_state._alarmCracked) { + _steps = true; + _vm->renderMessage(kStringMuseum6); + } + } else _steps = false; +} + +void GameManager2::crack(int time) { + _alarmBefore = _state._alarmOn; + _cracking = true; + _vm->_screen->changeCursor(ResourceManager::kCursorWait); + int t = 0; + int z; + int zv = 0; + do { + do { + wait(1); + } while ((z = (g_system->getMillis() - _state._startTime) / 600) == zv); + zv = z; + drawClock(); + t++; + } while (t < time && _state._alarmOn == _alarmBefore); + _cracking = false; + _vm->_screen->changeCursor(ResourceManager::kCursorNormal); + if (_state._alarmOn == _alarmBefore) + _vm->removeMessage(); +} + +bool GameManager2::crackDoor(int time) { + _vm->renderMessage(kStringMuseum15); + crack(time); + if (_state._alarmOn != _alarmBefore) { + waitOnInput(_messageDuration); + _vm->removeMessage(); + _vm->renderMessage(kStringMuseum16); + } + return !_state._alarmOn; +} + +void GameManager2::museumDoorInteract(Action verb, Object &obj1, Object &obj2) { + static struct { + int _r1; + int _o1; + int _r2; + int _o2; + } doorTab[11] = { + {MUS1, 0, MUS2, 0}, + {MUS2, 1, MUS3, 0}, + {MUS3, 1, MUS10, 0}, + {MUS10, 1, MUS11, 0}, + {MUS11, 1, MUS7, 1}, + {MUS7, 0, MUS6, 1}, + {MUS6, 0, MUS5, 1}, + {MUS5, 0, MUS4, 0}, + {MUS5, 2, MUS9, 1}, + {MUS9, 0, MUS8, 1}, + {MUS8, 0, MUS1, 1} + }; + Room *r; + if (verb == ACTION_OPEN && obj1._id == DOOR) { + for (int i = 0; i < 11; i++) { + if ((_currentRoom == _rooms[doorTab[i]._r1]) && + &obj1 == _currentRoom->getObject(doorTab[i]._o1)) { + r = _rooms[doorTab[i]._r2]; + r->getObject(doorTab[i]._o2)->_type |= OPENED; + r->setSectionVisible(r->getObject(doorTab[i]._o2)->_section, kShownTrue); + } else if ((_currentRoom == _rooms[doorTab[i]._r2]) && + &obj1 == _currentRoom->getObject(doorTab[i]._o2)) { + r = _rooms[doorTab[i]._r1]; + r->getObject(doorTab[i]._o1)->_type |= OPENED; + r->setSectionVisible(r->getObject(doorTab[i]._o1)->_section, kShownTrue); + } + } + } else if (verb == ACTION_CLOSE && obj1._id == DOOR) { + for (int i = 0; i < 11; i++) { + if ((_currentRoom == _rooms[doorTab[i]._r1]) && + &obj1 == _currentRoom->getObject(doorTab[i]._o1)) { + r = _rooms[doorTab[i]._r2]; + r->getObject(doorTab[i]._o2)->_type &= ~OPENED; + r->setSectionVisible(r->getObject(doorTab[i]._o2)->_section, kShownFalse); + } else if ((_currentRoom == _rooms[doorTab[i]._r2]) && + &obj1 == _currentRoom->getObject(doorTab[i]._o2)) { + r = _rooms[doorTab[i]._r1]; + r->getObject(doorTab[i]._o1)->_type &= ~OPENED; + r->setSectionVisible(r->getObject(doorTab[i]._o1)->_section, kShownFalse); + } + } + } +} + +void GameManager2::securityEntrance() { + static struct { + RoomId _r; + int _a1; + int _a2; + } securityList[11] = { + {MUS1 ,11,31}, + {MUS2 , 7,17}, + {MUS3 , 7,17}, + {MUS10, 1, 7}, + {MUS11, 1, 7}, + {MUS7 ,10,32}, + {MUS6 , 8,18}, + {MUS5 , 8,18}, + {MUS9 , 2, 8}, + {MUS8 , 2, 8}, + {MUS1 , 0, 0} + }; + + int time = (g_system->getMillis() - _state._startTime) / 600; + int second = time % 100; + + if (_rooms[_securityTab[second / 10]] == _currentRoom) { + int i; + for (i = 0; _currentRoom != _rooms[securityList[i]._r]; i++) {} + if (_lastRoom == _rooms[securityList[i + 1]._r]) { + _vm->renderImage(securityList[i]._a1); + _vm->renderImage(securityList[i]._a2); + caught2(); + } else + caught(); + } +} + +void GameManager2::pressureAlarmEntrance() { + _state._pressureCounter = 0; + securityEntrance(); +} + +void GameManager2::pressureAlarmCount() { + if (!(_state._alarmOn || + (_currentRoom == _rooms[MUS22] && _currentRoom->isSectionVisible(6)))) { + _state._pressureCounter++; + if ((_currentRoom >= _rooms[MUS12] && _state._pressureCounter > 8) || + _state._pressureCounter > 16) + alarm(); + } + setAnimationTimer(11); +} + +} + diff --git a/engines/supernova/supernova2/state.h b/engines/supernova/supernova2/state.h new file mode 100644 index 0000000000..64d070dcf7 --- /dev/null +++ b/engines/supernova/supernova2/state.h @@ -0,0 +1,138 @@ +/* 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. + * + */ + +#ifndef SUPERNOVA2_STATE_H +#define SUPERNOVA2_STATE_H + +#include "common/events.h" +#include "common/rect.h" +#include "common/keyboard.h" +#include "supernova/room.h" +#include "supernova/supernova2/rooms.h" +#include "supernova/sound.h" +#include "supernova/game-manager.h" + +namespace Supernova { + +struct ConstructionEntry { + int _e; + int _s; + int _z; + int _r; + int _a; +}; + +struct GameState2 { + int16 _money; + int32 _startTime; + bool _addressKnown; + Room *_previousRoom; + bool _poleMagnet; + char _admission; + bool _tipsy; + bool _dark; + char _elevatorE; + char _elevatorNumber; + bool _toMuseum; + EventFunction _eventCallback; + uint32 _eventTime; + int16 _pyraE; + char _pyraS; + char _pyraZ; + int16 _pyraDirection; + int16 _puzzleTab[15]; + bool _alarmCracked; + bool _alarmOn; + bool _haste; + byte _pressureCounter; + bool _sirenOn; + byte _taxiPossibility; +}; + +class GameManager2: public GameManager{ +public: + GameManager2(SupernovaEngine *vm, Sound *sound); + ~GameManager2(); + + GameState2 _state; + + virtual void updateEvents(); + virtual void executeRoom(); + virtual bool serialize(Common::WriteStream *out); + virtual bool deserialize(Common::ReadStream *in, int version); + + byte _dials[6]; + + //state + unsigned char _puzzleField[16]; + bool _mapOn; + bool _steps; + bool _cracking; + bool _alarmBefore; + RoomId _securityTab[10]; + int _restTime; + + virtual void initState(); + virtual void initRooms(); + virtual void destroyRooms(); + virtual bool canSaveGameStateCurrently(); + virtual bool genericInteract(Action verb, Object &obj1, Object &obj2); + virtual void roomBrightness() {} + virtual void drawMapExits(); + virtual void handleInput(); + virtual void handleTime(); + virtual void loadTime() {} + virtual void saveTime() {} + virtual void takeMoney(int amount); + void taxi(); + void leaveTaxi(); + void taxiUnknownDestination(); + void taxiPayment(int price, int destination); + void playerTakeOut(); + void sober(); + void playCD(); + bool talk(int mod1, int mod2, int rest, MessagePosition pos, int id); + bool talkRest(int mod1, int mod2, int rest); + void pyramidEnd(); + void passageConstruction(); + byte wall(int s, int z, int direction, int stepsForward, int stepsRight); + 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); + void museumDoorInteract(Action verb, Object &obj1, Object &obj2); + void securityEntrance(); + void pressureAlarmCount(); + void pressureAlarmEntrance(); + +private: + int _prevImgId; +}; + +} + +#endif // SUPERNOVA2_STATE_H diff --git a/engines/supernova/supernova2/stringid.h b/engines/supernova/supernova2/stringid.h new file mode 100644 index 0000000000..fe765df3ce --- /dev/null +++ b/engines/supernova/supernova2/stringid.h @@ -0,0 +1,154 @@ +/* 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. + * + */ + +#ifndef SUPERNOVA2_STRINGID_H +#define SUPERNOVA2_STRINGID_H + +#include "common/scummsys.h" + +namespace Supernova { + +enum StringId2 { +kString23 = 25, kString24, +kString25, kString26, kString27, kStringTextSpeed, kStringLeaveGame, +kString30, kString31, kStringGenericInteract1, kStringGenericInteract2, kStringGenericInteract3, +kStringGenericInteract4, kStringGenericInteract5, kStringGenericInteract6, kStringGenericInteract7, kStringGenericInteract8, +kStringGenericInteract9, kStringGenericInteract10, kStringGenericInteract11, kStringGenericInteract12, kStringGenericInteract13, +kStringIntro1, kStringIntro2, kStringIntro3, kStringIntro4, kStringIntro5, +kStringOutro1, kStringOutro2, kStringOutro3, kStringOutro4, kStringOutro5, +kStringShout1, kStringShout2, kStringShout3, kStringShout4, kStringShout5, +kStringShout6, kStringShout7, kStringShout8, kStringShout9, kStringShout10, +kStringShout11, kStringShout12, kStringShout13, kStringShout14, kStringShout15, +kStringMuseum8, kStringMuseum9, kStringMuseum7, kStringMuseum6, kStringMuseum15, +kStringMuseum16, kStringMuseum10, kStringMuseum12, kStringMuseum13, kStringMuseum14, +kStringMuseum1, kStringMuseum2, kStringMuseum3, kStringMuseum4, kStringMuseum5, +kStringMuseum23, kStringMuseum24, kStringMuseum17, kStringMuseum18, kStringMuseum19, +kStringMuseum20, kStringMuseum21, kStringMuseum22, kStringDinosaur, kStringDinosaurDescription, +kStringEntrance, kStringDoor, kStringRoad, kStringCamera, kStringCameraDescription, +kStringMainEntrance, kStringCorridor, kStringDinosaurDescription2, kStringDinosaurHead, kStringDinosaurHeadDescription, +kStringAlarmSystem, kStringSuctionCup, kStringWall, kStringOpening, kStringLetter, +kStringMassive, kStringInscriptionDescription, kStringPyramid0, kStringPyramid1, kStringPyramid2, +kStringPyramid3, kStringPyramid4, kStringPiece, kStringPyramid5, kStringPyramid6, +kStringPyramid7, kStringPyramid8, kStringPyramid9, kStringPyramid10, kStringPyramid11, +kStringPyramid12, kStringPyramid13, kStringPyramid14, kStringPyramid15, kStringPyramid17, +kStringPyramid18, kStringPyramid19, kStringDirection1, kStringDirection2, kStringDirection3, +kStringDirection4, kStringRope, kStringSign, kStringSignDescription, kStringEntrance1Description, +kStringPyramid, kStringPyramidDescription, kStringSun, kStringSunDescription, kStringSign5Description, +kStringRight, kStringLeft, kStringButton, kStringInscription, kStringTomato, +kStringFunnyDescription, kStringKnife1, kStringKnife1Description, kStringMonster, kStringRopeDescription, +kStringEyes, kStringMouth, kStringMonster1Description, kStringNote, kStringNoteDescription, +kStringOpeningDescription1, kStringOpeningDescription2, kStringNoteDescription1, kStringSlot, kStringSlotDescription3, +kStringOpeningDescription3, kStringStones, kStringPlate, kStringCoffin, kStringExit, +kStringCreepy, kStringToothbrush, kStringToothbrushDescription1, kStringToothpaste, kStringBall, +kStringBallDescription, kStringEye, kStringEyeDescription, kStringLooksMetal, +kStringTaxiArrives, kStringNothingHappens, kStringEmpty, kStringWalletOpen, kStringAttachMagnet, +kStringPoleMagnet, kStringCunning, kStringMustBuyFirst, kStringInsertChip, kStringTransferCD, +kStringCDNotInserted, kStringRemoveChip, kStringChipNotInserted, kStringWhatFor, kStringMMCD, +kStringChipEmpty, kStringListeningToCD, kStringNoChip, kStringTipsy, kStringXa, +kStringAirportEntrance, kStringAirport, kStringDowntown, kStringCulturePalace, kStringEarth, +kStringPrivateApartment, kStringLeaveTaxi, kStringPay, kStringAddress, kStringCheater, +kStringNotEnoughMoney, kStringTaxiAccelerating, kString5MinutesLater, kStringAlreadyHavePole, kStringSawPole, +kStringOnlyShop, kStringCabinOccupiedSay, kStringTakeMoney, kStringAlreadyPaid, kStringNoMoney, +kStringPay10Xa, kStringWillPassOut, kStringRest, kStringCypher, kStringWillTakeIt, +kStringTooExpensive, kStringWouldBuy, kStringMeHorstHummel, kStringHaveMusicChip, kStringGreatMask, +kStringThreeYears, kStringStrongDrink, kStringMusicDevice, kStringArtusToothbrush, kStringSellInBulk, +kStringRarityBooks, kStringEncyclopedia, kStringLargestDictionary, kStringOver400Words, kStringNotSale, +kStringGaveOne, kStringExcited, kStringFromGame, kStringRobust, kStringCheapSwill, +kStringStickers, kStringDishes, kStringUgly, kStringSellsWell, kStringThatCosts, +kStringTakeALook, kStringNonsense, kStringImSorry, kStringGoodEvening, kStringHello, +kStringScaredMe, kStringHowSo, kStringDisguise, kStringWhatDisguise, kStringStopPretending, +kStringYouDisguised, kStringIAmHorstHummel, kStringGiveItUp, kStringGestures, kStringMovesDifferently, +kStringHeIsRobot, kStringYouAreCrazy, kStringYouIdiot, kStringShutUp, kStringKnife, +kStringKnifeDescription, kStringMoney, kStringDiscman, kStringDiscmanDescription, kStringSuctionCupDescription, +kStringSpecialCard, kStringSpecialCardDescription, kStringAlarmCracker, kStringAlarmCrackerDescription, kStringKeycard, +kStringSpaceship, kStringSpaceshipDescription, kStringVehicles, kStringVehiclesDescription, kStringVehicle, +kStringVehicleDescription, kStringEntranceDescription, kStringWallet, kStringWalletDescription, kStringDevice, +kStringDeviceDescription, kStringIdCard, kStringIdCardDescription, kStringStaircase, kStringStaircaseDescription, +kStringBusinessStreet, kStringBusinessStreetDescription, kStringRod, kStringPost, kStringRailing, +kStringPoster, kStringPosterDescription, kStringCabin, kStringCabinFree, kStringCabinOccupied, +kStringFeet, kStringFeetDescription, kStringHood, kStringHoodDescription, kString400Xa, +kString10Xa, kStringSlotDescription1, kStringSlotDescription2, kStringChair, kStringChairDescription, +kStringScribble, kStringFace, kStringFaceDescription, kStringBooks, kStringDictionary, +kStringPlant, kStringMask, kStringSnake, kStringCup, kStringJoystick, +kStringToothbrushDescription, kStringMusic, kStringMusicDescription, kStringBottle, kStringBottleDescription, +kStringBox, kStringSeller, kStringWhat, kStringNotInformed, kStringHorstHummel, +kStringNiceWeather, kStringTellTicket, kStringHereIsXa, kString500Xa, kString1000Xa, +kString5000Xa, kString10000Xa, kStringThankYou, kStringWhatYouOffer, kStringHello2, +kStringWhatYouWant, kStringWhoAreYou, kStringHorstHummel2, kStringNeverHeard, kStringYouDontKnow, +kStringImOnTV, kStringIDontKnow, kStringFunny, kStringAha, kStringICan, +kStringFromWhom, kStringCost, kStringAsYouSay, kStringGetCard, kStringOnlyParticipation, +kStringWhatForIt, kStringMakeOffer, kStringGoodOffer, kStringGiveCard, kStringIdiot, +kStringCheckout1, kStringCheckout2, kStringCheckout3, kStringYes, kStringNo, +kStringCheckout4, kStringCheckout5, kStringCheckout6, kStringCheckout7, kStringCheckout8, +kStringCheckout9, kStringCheckout10, kStringCheckout11, kStringCheckout12, kStringCheckout13, +kStringCheckout14, kStringCheckout15, kStringCheckout16, kStringCheckout17, kStringCheckout18, +kStringCheckout19, kStringCheckout20, kStringCheckout21, kStringCheckout22, kStringCheckout23, +kStringCheckout24, kStringCheckout25, kStringCheckout26, kStringCheckout27, kStringCheckout28, +kStringCheckout29, kStringCheckout30, kStringCheckout31, kStringCheckout32, kStringCheckout33, +kStringCheckout34, kStringCheckout35, kStringCheckout36, kStringCheckout37, kStringCheckout38, +kStringCheckout39, kStringCheckout40, kStringCheckout41, kStringCheckout42, kStringCheckout43, +kStringCheckout44, kStringCheckout45, kStringCheckout46, kStringCheckout47, kStringCheckout48, +kStringCheckout49, kStringAtMusicContest, kStringNoImitation, kStringGoodJoke, kStringCommon, +kStringIWillProof, kStringIWillPerform, kStringAppearance32, kStringAppearance1, kStringAppearance2, +kStringAppearance3, kStringAppearance4, kStringAppearance5, kStringAppearance6, kStringAppearance7, +kStringAppearance8, kStringAppearance9, kStringAppearance10, kStringAppearance11, kStringAppearance12, +kStringAppearance13, kStringAppearance14, kStringAppearance15, kStringAppearance16, kStringAppearance17, +kStringAppearance18, kStringAppearance19, kStringAppearance20, kStringAppearance21, kStringAppearance22, +kStringAppearance23, kStringAppearance24, kStringAppearance25, kStringAppearance26, kStringAppearance27, +kStringAppearance28, kStringAppearance29, kStringAppearance30, kStringAppearance31, kStringElevator1, +kStringElevator2, kStringElevator3, kStringElevator4, kStringElevator5, kStringElevator6, +kStringElevator7, kStringElevator8, kStringElevator9, kStringElevator10, kStringElevator11, +kStringElevator12, kStringElevator13, kStringElevator14, kStringElevator15, kStringElevator16, +kStringElevator17, kStringElevator18, kStringElevator19, kStringElevator20, kStringElevator21, +kStringElevator22, kStringElevator23, kStringElevator24, kStringElevator25, kStringElevator26, +kStringElevator27, kStringElevator28, kStringElevator29, kStringElevator30, kStringElevator31, +kStringElevator32, kStringElevator33, kStringElevator34, kStringElevator35, kStringElevator36, +kStringElevator37, kStringElevator38, kStringElevator39, kStringElevator40, kStringElevator41, +kStringElevator42, kStringElevator43, kStringElevator44, kStringElevator45, kStringElevator46, +kStringElevator47, kStringElevator48, kStringElevator49, kStringElevator50, kStringElevator51, +kStringElevator52, kStringElevator53, kStringElevator54, kStringElevator55, kStringElevator56, +kStringElevator57, kStringElevator58, kStringElevator59, kStringElevator60, kStringElevator61, +kStringElevator62, kStringElevator63, kStringElevator64, kStringElevator65, kStringApartment1, +kStringApartment2, kStringApartment3, kStringApartment4, kStringApartment5, kStringApartment6, +kStringApartment7, kStringApartment8, kStringShip0, kStringShip1, kStringShip2, +kStringShip3, kStringShip4, kStringShip5, kStringShip6, kStringShip7, +kStringShip8, kStringShip9, kStringShip10, kStringShip11, kStringShip12, +kStringShip13, kStringShip14, kStringShip15, kStringShip16, kStringShip17, +kStringShip18, kStringShip19, kStringFascinating, kStringTaxis, kStringTaxisDescription, +kStringAxacussan, kStringParticipationCard, kStringAxacussian, kStringSign1Description, kStringSign2Description, +kStringSign3Description, kStringSign4Description, kStringBell, kStringDisplay, kStringKeypad, +kStringKeypadDescription, kStringChip, kStringChipDescription, kStringHatch, kStringHatchDescription, +kStringMusicSystem, kStringMusicSystemDescription, kStringSpeakers, kStringSpeakersDescription, kStringPencils, +kStringPencilsDescription, kStringMetalBlocks, kStringMetalBlocksDescription, kStringImage, kStringImageDescription, +kStringCabinet, kStringCabinetDescription, kStringElevator, kStringUnderBed, kStringUnderBedDescription, +kStringKey, kStringKeyDescription, kStringSwitch, kStringHandle, kStringHatch2, +kStringSpaceSuit, kStringSpaceSuitDescription, kStringCable, kStringCableDescription1, kStringCableDescription2, +kStringIntro6, kStringIntro7, kStringIntro8, kStringIntroTV1, kStringIntroTV2, +kStringIntroTV3, kStringIntroTV4, kStringIntroTV5, kStringIntroTV6, kStringIntroTV7, +kStringIntroTV8, kStringIntroTV9, kStringIntroTV10, kStringIntroTV11, kStringIntroTV12, +kStringIntroTV13, kStringIntroTV14, kStringIntroTV15, kStringIntroTV16, kStringIntro9, +kStringIntro10, kStringIntro11, kStringIntro12, kStringIntro13, kStringIntro14, +kStringMonsterDescription, kStringPyramid16, kStringMuseum11 +}; +} + +#endif // SUPERNOVA2_STRINGID_H |