From 29f83a0887eaeb53f08f874e5767c8699991cd1f Mon Sep 17 00:00:00 2001 From: Jaromir Wysoglad Date: Fri, 7 Jun 2019 11:16:41 +0200 Subject: SUPERNOVA2: Finish Pyramid, add PyrEntrance rooms --- engines/supernova2/ms2_def.h | 18 +-- engines/supernova2/resman.cpp | 3 +- engines/supernova2/rooms.cpp | 129 ++++++++++++++++--- engines/supernova2/rooms.h | 17 ++- engines/supernova2/sound.h | 1 + engines/supernova2/state.cpp | 286 +++++++++++++++++++++++++++++++++++++++--- engines/supernova2/state.h | 17 ++- 7 files changed, 423 insertions(+), 48 deletions(-) (limited to 'engines') diff --git a/engines/supernova2/ms2_def.h b/engines/supernova2/ms2_def.h index 4afbd757ba..3006c5ebd1 100644 --- a/engines/supernova2/ms2_def.h +++ b/engines/supernova2/ms2_def.h @@ -88,7 +88,7 @@ enum RoomId { 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, - LGANG1,LGANG2,HOLE_ROOM,IN_HOLE,BODENTUER,BODENTUER_U, + LGANG1,LGANG2,HOLE_ROOM,IN_HOLE,FLOORDOOR,FLOORDOOR_U, BST_DOOR,HALL,COFFIN_ROOM,MASK, MUSEUM,MUS_EING,MUS1,MUS2,MUS3,MUS4,MUS5,MUS6,MUS7,MUS8, @@ -101,7 +101,7 @@ enum ObjectId { INVALIDOBJECT = -1, NULLOBJECT = 0, TAXI=1,WALLET,TRANSMITTER,KNIFE,ROD,OCCUPIED_CABIN,MONEY, - SLOT1,CHAIR,GANG,G_RIGHT,G_LEFT,PYRA_ENTRANCE,DOOR,BUTTON, + SLOT1,CHAIR,CORRIDOR,G_RIGHT,G_LEFT,PYRA_ENTRANCE,DOOR,BUTTON, PART0,PART1,PART2,PART3,PART4,PART5,PART6,PART7, PART8,PART9,PART10,PART11,PART12,PART13,PART14,PART15, TKNIFE,ROPE,NOTE,MOUTH, @@ -146,16 +146,16 @@ kString80, kString81, kString82, kString83, kString84, kString85, kString86, kString87, kString88, kString89, kString90, kString91, kString92, kString93, kString94, kStringEntrance, kStringDoor, kString97, kString98, kString99, -kString100, kString101, kString102, kStringDinosaurHead, kString104, +kString100, kStringCorridor, kString102, kStringDinosaurHead, kString104, kString105, kStringSuctionCup, kString107, kStringOpening, kString109, -kString110, kString111, kString112, kStringPyramid1, kStringPyramid2, -kStringPyramid3, kString116, kString117, kString118, kString119, +kString110, kString111, kStringPyramid0, kStringPyramid1, kStringPyramid2, +kStringPyramid3, kStringPyramid4, kString117, kString118, kString119, kString120, kString121, kString122, kString123, kString124, kString125, kString126, kString127, kString128, kString129, -kString130, kString131, kString132, kString133, kString134, -kString135, kStringRope, kStringSign, kStringSignDescription, kStringEntrance1Description, -kStringPyramid, kStringPyramidDescription, kStringSun, kStringSunDescription, kString144, -kString145, kString146, kString147, kString148, kString149, +kString130, kString131, kStringDirection1, kStringDirection2, kStringDirection3, +kStringDirection4, kStringRope, kStringSign, kStringSignDescription, kStringEntrance1Description, +kStringPyramid, kStringPyramidDescription, kStringSun, kStringSunDescription, kStringSign5Description, +kStringRight, kStringLeft, kString147, kString148, kString149, kString150, kString151, kString152, kString153, kString154, kString155, kString156, kString157, kString158, kString159, kString160, kString161, kString162, kStringSlot, kString164, diff --git a/engines/supernova2/resman.cpp b/engines/supernova2/resman.cpp index 7074731a55..b4fdb48e53 100644 --- a/engines/supernova2/resman.cpp +++ b/engines/supernova2/resman.cpp @@ -62,7 +62,8 @@ static const AudioInfo audioInfo[kAudioNumSamples] = { {51, 0, 6010}, {50, 0, -1}, {51, 6010, 9020}, - {54, 0, -1} + {54, 0, -1}, + {50, 0, -1} }; static const byte mouseNormal[64] = { diff --git a/engines/supernova2/rooms.cpp b/engines/supernova2/rooms.cpp index 7bbd537397..87b2cea512 100644 --- a/engines/supernova2/rooms.cpp +++ b/engines/supernova2/rooms.cpp @@ -2161,13 +2161,13 @@ Pyramid::Pyramid(Supernova2Engine *vm, GameManager *gm) { _vm = vm; _gm = gm; - _fileNumber = 6; + _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, 19); + _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); @@ -2270,7 +2270,7 @@ bool Pyramid::interact(Action verb, Object &obj1, Object &obj2) { _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._type == SUN) { + } else if (verb == ACTION_WALK && obj1._id == SUN) { _vm->renderMessage(kStringPyramid3); } else return false; @@ -2281,19 +2281,117 @@ PyrEntrance::PyrEntrance(Supernova2Engine *vm, GameManager *gm) { _vm = vm; _gm = gm; - _fileNumber = 6; + _fileNumber = 9; _id = PYR_ENTRANCE; _shown[0] = kShownTrue; + _shown[1] = kShownFalse; + _shown[2] = kShownFalse; + _shown[3] = kShownFalse; + _shown[4] = kShownTrue; + _shown[5] = kShownFalse; + _shown[6] = kShownFalse; + _shown[7] = kShownFalse; + _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() { - setRoomSeen(true); + if (_gm->_state._pyraS != 8 || _gm->_state._pyraZ != 5) + _waitTime = 0; } void PyrEntrance::animation() { + if (_gm->_state._pyraS == 8 && _gm->_state._pyraZ == 5) { + if (_waitTime == 700) { // 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(kAudioPyramid1); + _gm->screenShake(); + _gm->_rooms[FLOORDOOR]->setSectionVisible(kMaxSection - 1, kShownTrue); + } + else { + _waitTime++; + _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, LGANG1}, + {1, 1, 5, 1, LGANG2}, + {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); + return true; + } + } + _gm->passageConstruction(); + _gm->_newRoom = true; return true; } @@ -2777,43 +2875,44 @@ bool InHole::interact(Action verb, Object &obj1, Object &obj2) { return true; } -Bodentuer::Bodentuer(Supernova2Engine *vm, GameManager *gm) { +Floordoor::Floordoor(Supernova2Engine *vm, GameManager *gm) { _vm = vm; _gm = gm; _fileNumber = 6; - _id = BODENTUER; + _id = FLOORDOOR; _shown[0] = kShownTrue; + _shown[14] = kShownTrue; } -void Bodentuer::onEntrance() { +void Floordoor::onEntrance() { setRoomSeen(true); } -void Bodentuer::animation() { +void Floordoor::animation() { } -bool Bodentuer::interact(Action verb, Object &obj1, Object &obj2) { +bool Floordoor::interact(Action verb, Object &obj1, Object &obj2) { return true; } -BodentuerU::BodentuerU(Supernova2Engine *vm, GameManager *gm) { +FloordoorU::FloordoorU(Supernova2Engine *vm, GameManager *gm) { _vm = vm; _gm = gm; _fileNumber = 6; - _id = BODENTUER_U; + _id = FLOORDOOR_U; _shown[0] = kShownTrue; } -void BodentuerU::onEntrance() { +void FloordoorU::onEntrance() { setRoomSeen(true); } -void BodentuerU::animation() { +void FloordoorU::animation() { } -bool BodentuerU::interact(Action verb, Object &obj1, Object &obj2) { +bool FloordoorU::interact(Action verb, Object &obj1, Object &obj2) { return true; } diff --git a/engines/supernova2/rooms.h b/engines/supernova2/rooms.h index aed69012a5..1f3faaced3 100644 --- a/engines/supernova2/rooms.h +++ b/engines/supernova2/rooms.h @@ -37,6 +37,14 @@ namespace Supernova2 { class GameManager; class Supernova2Engine; +struct RoomEntry { + int _e; + int _s; + int _z; + int _r; + RoomId _exitRoom; +}; + class Room { public: Room(); @@ -242,6 +250,7 @@ public: virtual bool interact(Action verb, Object &obj1, Object &obj2); private: + int _waitTime; }; class Upstairs1 : public Room { @@ -484,9 +493,9 @@ public: private: }; -class Bodentuer : public Room { +class Floordoor : public Room { public: - Bodentuer(Supernova2Engine *vm, GameManager *gm); + Floordoor(Supernova2Engine *vm, GameManager *gm); virtual void onEntrance(); virtual void animation(); virtual bool interact(Action verb, Object &obj1, Object &obj2); @@ -494,9 +503,9 @@ public: private: }; -class BodentuerU : public Room { +class FloordoorU : public Room { public: - BodentuerU(Supernova2Engine *vm, GameManager *gm); + FloordoorU(Supernova2Engine *vm, GameManager *gm); virtual void onEntrance(); virtual void animation(); virtual bool interact(Action verb, Object &obj1, Object &obj2); diff --git a/engines/supernova2/sound.h b/engines/supernova2/sound.h index d54bac9cf0..2da2ac29c1 100644 --- a/engines/supernova2/sound.h +++ b/engines/supernova2/sound.h @@ -49,6 +49,7 @@ enum AudioId { kAudioShip3, kAudioShipDeath, kAudioDeath, + kAudioPyramid1, kAudioNumSamples }; diff --git a/engines/supernova2/state.cpp b/engines/supernova2/state.cpp index d5decdeb3a..ffd10be081 100644 --- a/engines/supernova2/state.cpp +++ b/engines/supernova2/state.cpp @@ -46,10 +46,10 @@ bool GameManager::serialize(Common::WriteStream *out) { out->writeByte(_state._elevatorE); out->writeByte(_state._elevatorNumber); out->writeByte(_state._toMuseum); - out->writeByte(_state._pyraE); + out->writeSint16LE(_state._pyraE); out->writeByte(_state._pyraS); out->writeByte(_state._pyraZ); - out->writeByte(_state._pyraDirection); + out->writeSint16LE(_state._pyraDirection); out->writeUint32LE(_state._eventTime); out->writeSint32LE(_state._eventCallback); @@ -88,10 +88,10 @@ bool GameManager::deserialize(Common::ReadStream *in, int version) { _state._elevatorE = in->readByte(); _state._elevatorNumber = in->readByte(); _state._toMuseum = in->readByte(); - _state._pyraE = in->readByte(); + _state._pyraE = in->readSint16LE(); _state._pyraS = in->readByte(); _state._pyraZ = in->readByte(); - _state._pyraDirection = in->readByte(); + _state._pyraDirection = in->readSint16LE(); _state._eventTime = in->readUint32LE(); _state._eventCallback = (EventFunction)in->readSint32LE(); _vm->setGameString(kStringMoney, Common::String::format("%d Xa", _state._money)); @@ -287,8 +287,8 @@ void GameManager::destroyRooms() { delete _rooms[LGANG2]; delete _rooms[HOLE_ROOM]; delete _rooms[IN_HOLE]; - delete _rooms[BODENTUER]; - delete _rooms[BODENTUER_U]; + delete _rooms[FLOORDOOR]; + delete _rooms[FLOORDOOR_U]; delete _rooms[BST_DOOR]; delete _rooms[HALL]; delete _rooms[COFFIN_ROOM]; @@ -413,8 +413,8 @@ void GameManager::initRooms() { _rooms[LGANG2] = new LGang2(_vm, this); _rooms[HOLE_ROOM] = new HoleRoom(_vm, this); _rooms[IN_HOLE] = new InHole(_vm, this); - _rooms[BODENTUER] = new Bodentuer(_vm, this); - _rooms[BODENTUER_U] = new BodentuerU(_vm, this); + _rooms[FLOORDOOR] = new Floordoor(_vm, this); + _rooms[FLOORDOOR_U] = new FloordoorU(_vm, this); _rooms[BST_DOOR] = new BstDoor(_vm, this); _rooms[HALL] = new Hall(_vm, this); _rooms[COFFIN_ROOM] = new CoffinRoom(_vm, this); @@ -787,6 +787,15 @@ bool GameManager::isNullObject(Object *obj) { return obj == &_nullObject; } +void GameManager::screenShake() { + for (int i = 0; i < 12; ++i) { + _vm->_system->setShakePos(8); + wait(1); + _vm->_system->setShakePos(0); + wait(1); + } +} + void GameManager::showMenu() { _vm->renderBox(0, 138, 320, 62, 0); _vm->renderBox(0, 140, 320, 9, kColorWhite25); @@ -799,15 +808,20 @@ void GameManager::drawMapExits() { // TODO: Preload _exitList on room entry instead on every call _vm->renderBox(281, 161, 39, 39, kColorWhite25); - 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); + 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); + } } } } @@ -1738,9 +1752,247 @@ bool GameManager::talkRest(int mod1, int mod2, int rest) { } void GameManager::pyramidEnd() { + _vm->renderMessage(kStringPyramid0); + waitOnInput(_messageDuration); + _vm->removeMessage(); + _vm->paletteFadeOut(); + _vm->loadGame(kSleepAutosaveSlot); + changeRoom(CABIN); + drawGUI(); + _rooms[CABIN]->setSectionVisible(kMaxSection - 1, kShownFalse); + _rooms[CABIN]->setSectionVisible(kMaxSection - 2, kShownTrue); + _rooms[CABIN]->setSectionVisible(1, kShownFalse); } void GameManager::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 GameManager::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 GameManager::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 GameManager::compass() { + static StringId dirs[7] = { + kStringDirection1, + kStringDirection2, + kStringDirection3, + kStringDirection4, + kStringDirection1, + kStringDirection2, + kStringDirection3 + }; + _vm->renderBox(281, 161, 39, 39, kColorWhite63); + _vm->renderBox(295, 180, 13, 3, kColorDarkBlue); + _vm->renderBox(300, 175, 3, 13, kColorDarkBlue); + _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); } } diff --git a/engines/supernova2/state.h b/engines/supernova2/state.h index 4ea490784e..2be9826a26 100644 --- a/engines/supernova2/state.h +++ b/engines/supernova2/state.h @@ -31,6 +31,14 @@ namespace Supernova2 { +struct ConstructionEntry { + int _e; + int _s; + int _z; + int _r; + int _a; +}; + const int32 kMaxTimerValue = 0x7FFFFFFF; enum EventFunction { kNoFn, kSoberFn, kPyramidEndFn}; @@ -49,10 +57,10 @@ struct GameState { bool _toMuseum; EventFunction _eventCallback; uint32 _eventTime; - char _pyraE; + int16 _pyraE; char _pyraS; char _pyraZ; - char _pyraDirection; + int16 _pyraDirection; }; class Inventory { @@ -171,6 +179,7 @@ public: byte _dials[6]; int _taxi_possibility; + void takeObject(Object &obj); void setObjectNull(Object *&obj); bool isNullObject(Object *obj); @@ -185,6 +194,7 @@ public: void wait(int ticks); void waitOnInput(int ticks); bool waitOnInput(int ticks, Common::KeyCode &keycode); + void screenShake(); void showMenu(); void animationOff(); void animationOn(); @@ -221,6 +231,9 @@ public: 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(); private: int _prevImgId; -- cgit v1.2.3