SUPERNOVA2: Finish Pyramid, add PyrEntrance rooms

This commit is contained in:
Jaromir Wysoglad 2019-06-07 11:16:41 +02:00 committed by Thierry Crozat
parent 8c6515182f
commit 29f83a0887
7 changed files with 423 additions and 48 deletions

View File

@ -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,

View File

@ -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] = {

View File

@ -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;
}

View File

@ -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);

View File

@ -49,6 +49,7 @@ enum AudioId {
kAudioShip3,
kAudioShipDeath,
kAudioDeath,
kAudioPyramid1,
kAudioNumSamples
};

View File

@ -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);
}
}

View File

@ -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;