aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorJaromir Wysoglad2019-06-07 16:24:56 +0200
committerThierry Crozat2019-07-28 15:09:14 +0100
commitd40d52cb2fd9c520044794606c3349157a94a381 (patch)
tree712e2c0e0a935bc843811d196bb2d55e4ea56d4c /engines
parentc8b900bd4a9d4f230e18a4db94c888a211690ae1 (diff)
downloadscummvm-rg350-d40d52cb2fd9c520044794606c3349157a94a381.tar.gz
scummvm-rg350-d40d52cb2fd9c520044794606c3349157a94a381.tar.bz2
scummvm-rg350-d40d52cb2fd9c520044794606c3349157a94a381.zip
SUPERNOVA2: Add pyramid puzzle
Diffstat (limited to 'engines')
-rw-r--r--engines/supernova2/ms2_def.h2
-rw-r--r--engines/supernova2/resman.cpp3
-rw-r--r--engines/supernova2/rooms.cpp103
-rw-r--r--engines/supernova2/sound.h1
-rw-r--r--engines/supernova2/state.cpp26
-rw-r--r--engines/supernova2/state.h3
6 files changed, 131 insertions, 7 deletions
diff --git a/engines/supernova2/ms2_def.h b/engines/supernova2/ms2_def.h
index d46dbe0f2d..56635b3643 100644
--- a/engines/supernova2/ms2_def.h
+++ b/engines/supernova2/ms2_def.h
@@ -149,7 +149,7 @@ kStringEntrance, kStringDoor, kString97, kString98, kString99,
kString100, kStringCorridor, kString102, kStringDinosaurHead, kString104,
kString105, kStringSuctionCup, kString107, kStringOpening, kString109,
kStringMassive, kString111, kStringPyramid0, kStringPyramid1, kStringPyramid2,
-kStringPyramid3, kStringPyramid4, kString117, kString118, kString119,
+kStringPyramid3, kStringPyramid4, kStringPiece, kStringPyramid5, kString119,
kString120, kString121, kString122, kString123, kString124,
kString125, kString126, kString127, kString128, kString129,
kString130, kString131, kStringDirection1, kStringDirection2, kStringDirection3,
diff --git a/engines/supernova2/resman.cpp b/engines/supernova2/resman.cpp
index b4fdb48e53..7074731a55 100644
--- a/engines/supernova2/resman.cpp
+++ b/engines/supernova2/resman.cpp
@@ -62,8 +62,7 @@ static const AudioInfo audioInfo[kAudioNumSamples] = {
{51, 0, 6010},
{50, 0, -1},
{51, 6010, 9020},
- {54, 0, -1},
- {50, 0, -1}
+ {54, 0, -1}
};
static const byte mouseNormal[64] = {
diff --git a/engines/supernova2/rooms.cpp b/engines/supernova2/rooms.cpp
index eff6a4d602..1c2311b4ca 100644
--- a/engines/supernova2/rooms.cpp
+++ b/engines/supernova2/rooms.cpp
@@ -2330,7 +2330,7 @@ void PyrEntrance::animation() {
_gm->wait(3);
_vm->renderImage(9);
_gm->_rooms[FLOORDOOR]->setSectionVisible(8, kShownFalse);
- _vm->playSound(kAudioPyramid1);
+ _vm->playSound(kAudioShip3);
_gm->screenShake();
_gm->_rooms[FLOORDOOR]->setSectionVisible(kMaxSection - 1, kShownTrue);
}
@@ -2555,7 +2555,7 @@ bool BottomRightDoor::interact(Action verb, Object &obj1, Object &obj2) {
_gm->_rooms[UPPER_DOOR]->getObject(2)->_id = DOOR;
_gm->_rooms[UPPER_DOOR]->getObject(2)->_description = kStringMassive;
}
- _vm->playSound(kAudioPyramid1);
+ _vm->playSound(kAudioShip3);
_gm->screenShake();
}
else
@@ -2708,9 +2708,45 @@ PuzzleFront::PuzzleFront(Supernova2Engine *vm, GameManager *gm) {
_vm = vm;
_gm = gm;
- _fileNumber = 6;
+ _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() {
@@ -2721,6 +2757,67 @@ void PuzzleFront::animation() {
}
bool PuzzleFront::interact(Action verb, Object &obj1, Object &obj2) {
+ MS2Image *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;
}
diff --git a/engines/supernova2/sound.h b/engines/supernova2/sound.h
index 2da2ac29c1..d54bac9cf0 100644
--- a/engines/supernova2/sound.h
+++ b/engines/supernova2/sound.h
@@ -49,7 +49,6 @@ enum AudioId {
kAudioShip3,
kAudioShipDeath,
kAudioDeath,
- kAudioPyramid1,
kAudioNumSamples
};
diff --git a/engines/supernova2/state.cpp b/engines/supernova2/state.cpp
index ffd10be081..d0e918f1d7 100644
--- a/engines/supernova2/state.cpp
+++ b/engines/supernova2/state.cpp
@@ -52,6 +52,9 @@ bool GameManager::serialize(Common::WriteStream *out) {
out->writeSint16LE(_state._pyraDirection);
out->writeUint32LE(_state._eventTime);
out->writeSint32LE(_state._eventCallback);
+ for (int i = 0; i < 15; i++) {
+ out->writeSint16LE(_state._puzzleTab[i]);
+ }
// Inventory
out->writeSint32LE(_inventory.getSize());
@@ -94,6 +97,8 @@ bool GameManager::deserialize(Common::ReadStream *in, int version) {
_state._pyraDirection = in->readSint16LE();
_state._eventTime = in->readUint32LE();
_state._eventCallback = (EventFunction)in->readSint32LE();
+ 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();
@@ -370,6 +375,9 @@ void GameManager::initState() {
_state._pyraDirection = 0;
_state._eventTime = kMaxTimerValue;
_state._eventCallback = kNoFn;
+ 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 GameManager::initRooms() {
@@ -1490,6 +1498,8 @@ void GameManager::handleInput() {
}
void GameManager::executeRoom() {
+ if (_currentRoom == _rooms[PUZZLE_FRONT])
+ puzzleConstruction();
if (_processInput && !_vm->_screen->isMessageShown() && _guiEnabled) {
handleInput();
if (_mouseClicked) {
@@ -1995,5 +2005,21 @@ void GameManager::compass() {
_vm->renderText(dirs[_state._pyraDirection + 3], 283, 179, kColorBlack);
}
+void GameManager::puzzleConstruction() {
+ _vm->setCurrentImage(12);
+ MS2Image *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;
+ }
+}
+
}
diff --git a/engines/supernova2/state.h b/engines/supernova2/state.h
index 2be9826a26..8bd1a02c24 100644
--- a/engines/supernova2/state.h
+++ b/engines/supernova2/state.h
@@ -61,6 +61,7 @@ struct GameState {
char _pyraS;
char _pyraZ;
int16 _pyraDirection;
+ int16 _puzzleTab[15];
};
class Inventory {
@@ -178,6 +179,7 @@ public:
byte _rowsStart[6];
byte _dials[6];
int _taxi_possibility;
+ unsigned char _puzzleField[16];
void takeObject(Object &obj);
@@ -234,6 +236,7 @@ public:
byte wall(int s, int z, int direction, int stepsForward, int stepsRight);
bool move(Action verb, Object &obj);
void compass();
+ void puzzleConstruction();
private:
int _prevImgId;