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