mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
1621 lines
47 KiB
C++
1621 lines
47 KiB
C++
/* 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.
|
|
*
|
|
* Copyright 2020 Google
|
|
*
|
|
*/
|
|
#include "hadesch/hadesch.h"
|
|
#include "hadesch/video.h"
|
|
#include "hadesch/ambient.h"
|
|
#include "common/translation.h"
|
|
|
|
namespace Hadesch {
|
|
|
|
static const char *kTalusImage = "r1100bb0";
|
|
static const char *kTalusImageWithShip = "r1100bc0";
|
|
static const char *kTalusMovie = "r1100ba0";
|
|
static const char *kTalusHotzone = "Talus";
|
|
static const char *kTavernImage = "r2190ba0";
|
|
static const char *kTavernHotzone = "Tavern";
|
|
static const char *kPoseidonHighlight = "r1230ba0";
|
|
static const char *kZeusHighlight = "r1240ba0";
|
|
static const char *kHermesHighlight = "r2320ba0";
|
|
static const char *kHornless1 = "g0170ob0";
|
|
static const char *kHornless2 = "g0170oe0";
|
|
static const char *kHornless3 = "g0170oh0";
|
|
static const char *kHornless4 = "g0170ok0";
|
|
static const char *kHorned = "g1800ob0";
|
|
static const char *kHornedHotzone = "HornedStatue";
|
|
static const char *kHornless1Hotzone = "HornlessStatue1";
|
|
static const char *kHornless2Hotzone = "HornlessStatue2";
|
|
static const char *kHornless3Hotzone = "HornlessStatue3";
|
|
static const char *kHornless4Hotzone = "HornlessStatue4";
|
|
static const char *kMerchantAnim = "r2130ba0";
|
|
static const char *kOneManBandAnim = "r2040ba1";
|
|
static const char *kOneManBandHotZone = "OneManBand";
|
|
static const char *kAtlantisOpening = "r1210bb0";
|
|
static const char *kAtlantisLargeDisk = "r1210be0";
|
|
static const char *kAtlantisMediumDisk = "r1210bf0";
|
|
static const char *kAtlantisSmallDisk = "r1210bg0";
|
|
static const char *kAtlantisDiskBackground = "r1210os0";
|
|
|
|
static const int vaseSol[] = {2, 3, 2, 3};
|
|
static const char *vaseSound[] = {
|
|
"r1220ec0",
|
|
"r1220ed0",
|
|
"r1220ee0",
|
|
"r1220ef0"
|
|
};
|
|
|
|
static const char *vaseSegment[] = {
|
|
"r1220bc0",
|
|
"r1220bd0",
|
|
"r1220be0",
|
|
"r1220bf0"
|
|
};
|
|
|
|
enum {
|
|
kBackgroundZ = 10000,
|
|
kTalusZ = 6000,
|
|
kTavernImageZ = 5000,
|
|
kOneManBandZ = 1600,
|
|
kMerchantStandZ = 1205,
|
|
kMerchantZ = 1200,
|
|
kAtlantisDiskBackgroundZ = 1100,
|
|
kAtlantisLargeDiskZ = 1000,
|
|
kAtlantisMediumDiskZ = 900,
|
|
kAtlantisSmallDiskZ = 800,
|
|
kAtlantisOpeningZ = 700
|
|
};
|
|
|
|
enum {
|
|
kIntroMerchantVideoFinished = 12107,
|
|
kTakenHorned = 12115,
|
|
kTakenHornless = 12118,
|
|
kMerchantIdleTimer = 12121,
|
|
kMerchantIdleAnimCleanup = 12122,
|
|
kTalueMovieCompleted = 12129,
|
|
// 12137 is the end of statue animation that we handle as functor instead
|
|
kAtlantisDoorOpens = 12307,
|
|
kTavernMovieCompleted = 1012001,
|
|
kIntroMerchantPanFinished = 1012002,
|
|
kAtlantisBoatIntro2Finished = 1012003,
|
|
kTakenWood = 1012005,
|
|
kSoundVaseSegment1Finished = 1012006,
|
|
kSoundVaseSegment2Finished = 1012007,
|
|
kSoundVaseSegment3Finished = 1012008,
|
|
kSoundVaseSegment4Finished = 1012009,
|
|
kCoinGiven = 1012010,
|
|
kSandalsPlaced = 1012011
|
|
};
|
|
|
|
static const PrePoint strongBoxSideDotOffsets[] = {
|
|
{1060, 278},
|
|
{1090, 310},
|
|
{1060, 339},
|
|
{1032, 305}
|
|
};
|
|
|
|
static const PrePoint strongBoxTileOffsets[] = {
|
|
{1005, 274},
|
|
{1035, 276},
|
|
{1064, 278},
|
|
{1093, 280},
|
|
{1005, 304},
|
|
{1035, 306},
|
|
{1064, 308},
|
|
{1093, 310},
|
|
{1035, 246},
|
|
{1064, 248},
|
|
{1035, 337},
|
|
{1064, 339}
|
|
};
|
|
|
|
static const int baseFrame[4][8] = {
|
|
{ 1, 3, 4, 6, 1, 3, 4, 6 },
|
|
{ 7, 9, 10, 12, 13, 15, 16, 18 },
|
|
{ 19, 21, 22, 24, 25, 27, 28, 30 },
|
|
{ 31, 33, 34, 36, 31, 33, 34, 36 }
|
|
};
|
|
|
|
static const int kTileMovementTime = 500;
|
|
|
|
class StrongBoxTile {
|
|
public:
|
|
enum Letter {
|
|
kLetterZ = 1,
|
|
kLetterE,
|
|
kLetterU,
|
|
kLetterS
|
|
};
|
|
enum Orientation {
|
|
kOrientation0 = 0,
|
|
kOrientation90 = 90,
|
|
kOrientation180 = 180,
|
|
kOrientation270 = 270
|
|
};
|
|
|
|
void rotate() {
|
|
_orientation = (Orientation) ((_orientation + 90) % 360);
|
|
}
|
|
|
|
void show() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
int orientation = _orientation / 45;
|
|
if (_nextPosition != -1 && g_vm->getCurrentTime() > kTileMovementTime + _movementStartTime) {
|
|
_position = _nextPosition;
|
|
_nextPosition = -1;
|
|
}
|
|
Common::Point pos = strongBoxTileOffsets[_position].get();
|
|
if (_nextPosition != -1) {
|
|
double frac = (g_vm->getCurrentTime() - _movementStartTime + 0.0) / kTileMovementTime;
|
|
pos = strongBoxTileOffsets[_position].get() * (1-frac) + strongBoxTileOffsets[_nextPosition].get() * frac;
|
|
}
|
|
int zVal = 500;
|
|
switch (_rotationPhase) {
|
|
case 0:
|
|
case 2:
|
|
pos += Common::Point(-5, 4);
|
|
zVal = 300;
|
|
break;
|
|
case 1:
|
|
orientation++;
|
|
switch (_position) {
|
|
case 1:
|
|
pos = Common::Point(1046, 277);
|
|
break;
|
|
case 2:
|
|
pos = Common::Point(1065, 298);
|
|
break;
|
|
case 5:
|
|
pos = Common::Point(1025, 297);
|
|
break;
|
|
case 6:
|
|
pos = Common::Point(1045, 318);
|
|
break;
|
|
}
|
|
zVal = 300;
|
|
break;
|
|
}
|
|
int frame = baseFrame[_letter - kLetterZ][orientation] - 1;
|
|
if (_position < 4 && _nextPosition == -1 && _rotationPhase < 0)
|
|
frame++;
|
|
room->selectFrame(LayerId("r2010om0", _position, "pos"),
|
|
zVal, frame, pos);
|
|
}
|
|
|
|
void setRotationPhase(int phase) {
|
|
_rotationPhase = phase;
|
|
}
|
|
|
|
bool isMoving() {
|
|
return _nextPosition != -1 || _rotationPhase != -1;
|
|
}
|
|
|
|
int getPosition() {
|
|
return _position;
|
|
}
|
|
|
|
Letter getLetter() {
|
|
return _letter;
|
|
}
|
|
|
|
Orientation getOrientation() {
|
|
return _orientation;
|
|
}
|
|
|
|
void setPosition(int position) {
|
|
_position = position;
|
|
}
|
|
|
|
void moveTo(int pos) {
|
|
_nextPosition = pos;
|
|
_movementStartTime = g_vm->getCurrentTime();
|
|
}
|
|
|
|
StrongBoxTile() {
|
|
_letter = kLetterZ;
|
|
_position = 0;
|
|
_orientation = kOrientation0;
|
|
_nextPosition = -1;
|
|
_rotationPhase = -1;
|
|
}
|
|
|
|
StrongBoxTile(Letter letter, Orientation orientation, int position) {
|
|
_letter = letter;
|
|
_position = position;
|
|
_orientation = orientation;
|
|
_nextPosition = -1;
|
|
_rotationPhase = -1;
|
|
}
|
|
private:
|
|
Letter _letter;
|
|
int _position;
|
|
int _nextPosition;
|
|
int _movementStartTime;
|
|
int _rotationPhase;
|
|
Orientation _orientation;
|
|
};
|
|
|
|
static const struct {
|
|
StrongBoxTile::Letter letter;
|
|
StrongBoxTile::Orientation orientation;
|
|
} initialLetters[12] = {
|
|
{StrongBoxTile::kLetterZ, StrongBoxTile::kOrientation90},
|
|
{StrongBoxTile::kLetterE, StrongBoxTile::kOrientation90},
|
|
{StrongBoxTile::kLetterU, StrongBoxTile::kOrientation90},
|
|
{StrongBoxTile::kLetterS, StrongBoxTile::kOrientation90},
|
|
{StrongBoxTile::kLetterE, StrongBoxTile::kOrientation0},
|
|
{StrongBoxTile::kLetterZ, StrongBoxTile::kOrientation0},
|
|
{StrongBoxTile::kLetterU, StrongBoxTile::kOrientation270},
|
|
{StrongBoxTile::kLetterS, StrongBoxTile::kOrientation90},
|
|
{StrongBoxTile::kLetterU, StrongBoxTile::kOrientation90},
|
|
{StrongBoxTile::kLetterE, StrongBoxTile::kOrientation90},
|
|
{StrongBoxTile::kLetterZ, StrongBoxTile::kOrientation0},
|
|
{StrongBoxTile::kLetterS, StrongBoxTile::kOrientation0}
|
|
};
|
|
|
|
class CreteHandler : public Handler {
|
|
public:
|
|
CreteHandler() {
|
|
_tavernCounter = 0;
|
|
_oneManBandCounter = 0;
|
|
_merchantIsBusy = false;
|
|
memset(_vaseBusy, 0, sizeof(_vaseBusy));
|
|
for (int i =0; i < 12; i++)
|
|
_strongBoxTiles[i] = StrongBoxTile(initialLetters[i].letter, initialLetters[i].orientation, i);
|
|
_strongBoxPopup = false;
|
|
_fadingHades = false;
|
|
_fadingHadesStartTime = 0;
|
|
}
|
|
|
|
void handleClick(const Common::String &name) override {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
if (name == kTalusHotzone) {
|
|
room->playVideo(kTalusMovie, kTalusZ, kTalueMovieCompleted,
|
|
Common::Point(54, 29));
|
|
room->setLayerEnabled(kTalusImageWithShip, false);
|
|
return;
|
|
}
|
|
|
|
if (name == "MinosPalace") {
|
|
room->disableMouse();
|
|
g_vm->moveToRoom(kMinosPalaceRoom);
|
|
return;
|
|
}
|
|
|
|
if (name == "Poseidon") {
|
|
Common::Array<Common::String> videos;
|
|
videos.push_back("r1230na0");
|
|
videos.push_back("r1230nb0");
|
|
videos.push_back("r1230nc0");
|
|
|
|
room->playStatueSMK(kPoseidonStatue,
|
|
kPoseidonHighlight,
|
|
5000,
|
|
videos, 16, 39);
|
|
return;
|
|
}
|
|
|
|
if (name == "Zeus") {
|
|
Common::Array<Common::String> videos;
|
|
videos.push_back("r1240wa0");
|
|
videos.push_back("r1240wb0");
|
|
|
|
room->playStatueSMK(kZeusStatue, kZeusHighlight, 5000,
|
|
videos, 23, 35);
|
|
return;
|
|
}
|
|
|
|
if (name == "Hermes") {
|
|
Common::Array<Common::String> videos;
|
|
videos.push_back("r2320na0");
|
|
videos.push_back("r2320nb0");
|
|
|
|
room->playStatueSMK(kHermesStatue,
|
|
kHermesHighlight,
|
|
4000,
|
|
videos, 22, 39, kOffsetRightRoom);
|
|
return;
|
|
}
|
|
|
|
if (name == kTavernHotzone) {
|
|
room->playAnimLoop(kTavernImage, 5000, kOffsetRightRoom);
|
|
room->playVideo(_tavernTalks[_tavernCounter], 5000,
|
|
kTavernMovieCompleted,
|
|
kOffsetRightRoom);
|
|
_tavernCounter = (_tavernCounter + 1) % _tavernTalks.size();
|
|
return;
|
|
}
|
|
|
|
if (name == "Argo") {
|
|
g_vm->moveToRoom(kArgoRoom);
|
|
return;
|
|
}
|
|
|
|
if (name == kHornedHotzone) {
|
|
g_vm->getHeroBelt()->placeToInventory(kHornedStatue, kTakenHornless);
|
|
room->setLayerEnabled(kHorned, false);
|
|
persistent->_creteShowHorned = false;
|
|
_merchantIsBusy = true;
|
|
room->disableHotzone(kHornedHotzone);
|
|
room->disableMouse();
|
|
return;
|
|
}
|
|
|
|
if (name == kHornless1Hotzone) {
|
|
g_vm->getHeroBelt()->placeToInventory(kHornlessStatue1, kTakenHorned);
|
|
room->setLayerEnabled(kHornless1, false);
|
|
persistent->_creteShowHornless1 = false;
|
|
room->disableHotzone(kHornless1Hotzone);
|
|
_merchantIsBusy = true;
|
|
room->disableMouse();
|
|
return;
|
|
}
|
|
|
|
if (name == kHornless2Hotzone) {
|
|
g_vm->getHeroBelt()->placeToInventory(kHornlessStatue2, kTakenHorned);
|
|
room->setLayerEnabled(kHornless2, false);
|
|
persistent->_creteShowHornless2 = false;
|
|
room->disableHotzone(kHornless2Hotzone);
|
|
_merchantIsBusy = true;
|
|
room->disableMouse();
|
|
return;
|
|
}
|
|
|
|
if (name == kHornless3Hotzone) {
|
|
g_vm->getHeroBelt()->placeToInventory(kHornlessStatue3, kTakenHorned);
|
|
room->setLayerEnabled(kHornless3, false);
|
|
persistent->_creteShowHornless3 = false;
|
|
room->disableHotzone(kHornless3Hotzone);
|
|
_merchantIsBusy = true;
|
|
room->disableMouse();
|
|
return;
|
|
}
|
|
|
|
if (name == kHornless4Hotzone) {
|
|
g_vm->getHeroBelt()->placeToInventory(kHornlessStatue4, kTakenHorned);
|
|
room->setLayerEnabled(kHornless4, false);
|
|
persistent->_creteShowHornless4 = false;
|
|
room->disableHotzone(kHornless4Hotzone);
|
|
_merchantIsBusy = true;
|
|
room->disableMouse();
|
|
return;
|
|
}
|
|
|
|
if (name == kOneManBandHotZone) {
|
|
room->playVideo(
|
|
Common::String::format(
|
|
"r2040b%c0", 'a' + (_oneManBandCounter % 3)),
|
|
1600,
|
|
12135, Common::Point(730, 183));
|
|
room->stopAnim(kOneManBandAnim);
|
|
_oneManBandCounter++;
|
|
return;
|
|
}
|
|
|
|
if (name == "AtlantisBoat") {
|
|
room->pushHotZones("Door.HOT");
|
|
room->disableHotzone("wood");
|
|
room->selectFrame("r1010ob0", 1200, 0);
|
|
room->selectFrame(kAtlantisDiskBackground, kAtlantisDiskBackgroundZ, 0);
|
|
for (unsigned i = 0; i < 3; i++)
|
|
_atlantisBoatPosition[i] = g_vm->getRnd().getRandomNumberRng(1, 7);
|
|
renderAtlantisDisks();
|
|
if (persistent->_creteIntroAtlantisWood) {
|
|
room->disableMouse();
|
|
room->playVideo("R1210BA0", 600, kAtlantisBoatIntro2Finished);
|
|
persistent->_creteIntroAtlantisWood = false;
|
|
}
|
|
return;
|
|
|
|
}
|
|
|
|
if (name == "SmallDisk") {
|
|
advanceAtlantisDisk(2);
|
|
return;
|
|
}
|
|
|
|
if (name == "MediumDisk") {
|
|
advanceAtlantisDisk(1);
|
|
return;
|
|
}
|
|
|
|
if (name == "LargeDisk") {
|
|
advanceAtlantisDisk(0);
|
|
return;
|
|
}
|
|
|
|
if (name == "wood") {
|
|
room->selectFrame(kAtlantisOpening, kAtlantisOpeningZ, 9);
|
|
g_vm->getHeroBelt()->placeToInventory(kWood, kTakenWood);
|
|
room->popHotZones();
|
|
room->disableHotzone("AtlantisBoat");
|
|
persistent->_creteShowAtlantisBoat = false;
|
|
return;
|
|
}
|
|
|
|
if (name == "Background") {
|
|
room->popHotZones();
|
|
room->stopAnim("r1010ob0");
|
|
hideStrongBox();
|
|
hideAtlantisPopupOverlays();
|
|
showMiniStrongBox();
|
|
return;
|
|
}
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
if (name == Common::String::format("VaseSegment%d", i + 1) && !_vaseBusy[i]) {
|
|
_vasePos[i]++;
|
|
if (i == 1 || i == 3)
|
|
_vasePos[i] %= 6;
|
|
else
|
|
_vasePos[i] %= 4;
|
|
_vaseBusy[i] = true;
|
|
renderVase();
|
|
room->playSFX(vaseSound[i], kSoundVaseSegment1Finished + i);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (name == "sandals") {
|
|
g_vm->getHeroBelt()->placeToInventory(kSandals, kSandalsPlaced);
|
|
room->selectFrame("r1220ba0", 500, 0);
|
|
room->disableMouse();
|
|
persistent->_creteSandalsState = Persistent::SANDALS_TAKEN;
|
|
return;
|
|
}
|
|
|
|
if (name == "AlchemistStand") {
|
|
_alchemistAmbient.play(false);
|
|
return;
|
|
}
|
|
|
|
if (name == "StrongBoxClosed"
|
|
|| name == "StrongBoxOpen"
|
|
|| name == "StrongBoxOpenPotion"
|
|
|| name == "StrongBoxOpenNoPotion") {
|
|
showStrongBox();
|
|
return;
|
|
}
|
|
|
|
if (name == "Latch") {
|
|
room->disableMouse();
|
|
persistent->_creteStrongBoxState = Persistent::BOX_OPEN;
|
|
room->playAnimWithSFX("r2230bb0", "g0082ea0", 1000,
|
|
PlayAnimParams::keepLastFrame().partial(1, 3),
|
|
12402, kOffsetRightRoom);
|
|
return;
|
|
}
|
|
|
|
if (name == "ButtonN" && !strongBoxIsBusy()) {
|
|
strongBoxMoveTiles(1, 8, 9, 2);
|
|
return;
|
|
}
|
|
|
|
if (name == "ButtonE" && !strongBoxIsBusy()) {
|
|
strongBoxMoveTiles(2, 3, 7, 6);
|
|
return;
|
|
}
|
|
|
|
if (name == "ButtonW" && !strongBoxIsBusy()) {
|
|
strongBoxMoveTiles(1, 5, 4, 0);
|
|
return;
|
|
}
|
|
|
|
if (name == "ButtonS" && !strongBoxIsBusy()) {
|
|
strongBoxMoveTiles(5, 6, 11, 10);
|
|
return;
|
|
}
|
|
|
|
if (name == "ButtonC" && !strongBoxIsBusy()) {
|
|
g_vm->addTimer(12409, 250);
|
|
room->playSFX("r2230ed0", 12412);
|
|
for (int i = 0; i < 12; i++) {
|
|
int pos = _strongBoxTiles[i].getPosition();
|
|
if (pos == 1 || pos == 2 || pos == 5 || pos == 6) {
|
|
_strongBoxTiles[i].setRotationPhase(0);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (name == "Potion") {
|
|
room->disableHotzone("Potion");
|
|
g_vm->getHeroBelt()->placeToInventory(kCoin, kCoinGiven);
|
|
persistent->_creteStrongBoxState = Persistent::BOX_OPEN_NO_POTION;
|
|
room->selectFrame("r2230bf0", 300, -1, kOffsetRightRoom);
|
|
return;
|
|
}
|
|
/*
|
|
TODO:
|
|
MNSH: Merchant
|
|
*/
|
|
}
|
|
|
|
void handleEvent(int eventId) override {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
switch (eventId) {
|
|
case kTakenWood:
|
|
room->stopAnim(kAtlantisOpening);
|
|
room->stopAnim("r1010ob0");
|
|
room->stopAnim(kAtlantisDiskBackground);
|
|
room->enableMouse();
|
|
break;
|
|
case kTalueMovieCompleted:
|
|
room->setLayerEnabled(kTalusImageWithShip, true);
|
|
break;
|
|
case kTavernMovieCompleted:
|
|
room->selectFrame(kTavernImage, kTavernImageZ, 0, kOffsetRightRoom);
|
|
break;
|
|
case kMerchantIdleTimer:
|
|
if (!persistent->_creteShowMerchant
|
|
|| !persistent->_creteShowHornless4 || _merchantIsBusy)
|
|
break;
|
|
room->setLayerEnabled(kHornless4, false);
|
|
room->disableHotzone(kHornless4Hotzone);
|
|
room->playAnim(kMerchantAnim, kMerchantZ,
|
|
PlayAnimParams::disappear().partial(1, -2),
|
|
kMerchantIdleAnimCleanup);
|
|
break;
|
|
case kMerchantIdleAnimCleanup:
|
|
room->selectFrame(kMerchantAnim, kMerchantZ, 0);
|
|
room->setLayerEnabled(kHornless4, persistent->_creteShowHornless4);
|
|
room->setHotzoneEnabled(kHornless4Hotzone, persistent->_creteShowHornless4 && persistent->_creteTriedHornless[2]);
|
|
break;
|
|
case kIntroMerchantPanFinished:
|
|
room->setLayerEnabled(kMerchantAnim, false);
|
|
room->playVideo("R2200BA0", kMerchantZ,
|
|
kIntroMerchantVideoFinished,
|
|
Common::Point(308, 99));
|
|
break;
|
|
// TODO: replay of R2200BB0 and R2200BC0
|
|
case kIntroMerchantVideoFinished:
|
|
room->disableMouse();
|
|
room->playVideo("R2200BB0", kMerchantZ,
|
|
12108,
|
|
Common::Point(304, 113));
|
|
_merchantIsBusy = true;
|
|
break;
|
|
case 12108:
|
|
room->disableMouse();
|
|
room->playVideo("R2200BC0", kMerchantZ,
|
|
12109,
|
|
Common::Point(304, 110));
|
|
_merchantIsBusy = true;
|
|
break;
|
|
case 12109:
|
|
room->selectFrame(kMerchantAnim, kMerchantZ, 0);
|
|
room->enableMouse();
|
|
_merchantIsBusy = false;
|
|
break;
|
|
case kTakenHorned:
|
|
room->setLayerEnabled(kMerchantAnim, false);
|
|
room->playVideo("r2210ba0", kMerchantZ, 12117,
|
|
Common::Point(344, 111));
|
|
room->disableMouse();
|
|
break;
|
|
case 12117:
|
|
room->playVideo("r2210bb0", kMerchantZ, 12119,
|
|
Common::Point(308, 112));
|
|
break;
|
|
case kTakenHornless:
|
|
room->setLayerEnabled(kMerchantAnim, false);
|
|
room->playVideo("r2240ba0", kMerchantZ, 12119,
|
|
Common::Point(314, 91));
|
|
_merchantIsBusy = true;
|
|
break;
|
|
case 12119:
|
|
room->selectFrame(kMerchantAnim, kMerchantZ, 0);
|
|
if (!persistent->_cretePlayedEyeGhostTown) {
|
|
room->playVideo("r2210bc0", 1000, 12120,
|
|
Common::Point(0, 216));
|
|
persistent->_cretePlayedEyeGhostTown = true;
|
|
} else {
|
|
room->enableMouse();
|
|
_merchantIsBusy = false;
|
|
}
|
|
break;
|
|
case 12120:
|
|
room->selectFrame(kMerchantAnim, kMerchantZ, 0);
|
|
room->enableMouse();
|
|
_merchantIsBusy = false;
|
|
break;
|
|
case 12128:
|
|
case 12134:
|
|
case 12143:
|
|
case 12146:
|
|
room->enableMouse();
|
|
break;
|
|
case 12135:
|
|
room->playAnimLoop(kOneManBandAnim, kOneManBandZ, kOffsetRightRoom);
|
|
break;
|
|
case 12142:
|
|
if (persistent->_quest == kMedusaQuest && !persistent->_cretePlayedPhilAlchemist) {
|
|
persistent->_cretePlayedPhilAlchemist = true;
|
|
room->playVideo("r2220bc0", 1000, 12143, Common::Point(640, 216));
|
|
room->disableMouse();
|
|
}
|
|
if (persistent->_quest == kRescuePhilQuest && !persistent->_cretePlayedZeusCheckOutThatBox && persistent->_hintsAreEnabled) {
|
|
g_vm->addTimer(12144, 5000, -1);
|
|
}
|
|
break;
|
|
case 12144:
|
|
if (!room->isMouseEnabled() || persistent->_cretePlayedZeusCheckOutThatBox)
|
|
break;
|
|
persistent->_cretePlayedZeusCheckOutThatBox = true;
|
|
room->disableMouse();
|
|
room->playAnimWithSpeech("r2230ba0",
|
|
TranscribedSound::make("r2230wa0",
|
|
"Hey, why don't you check out that box? Maybe it has something that can help"),
|
|
4000,
|
|
PlayAnimParams::keepLastFrame(),
|
|
12145,
|
|
kOffsetRightRoom);
|
|
break;
|
|
case kAtlantisBoatIntro2Finished:
|
|
room->enableMouse();
|
|
break;
|
|
case kAtlantisDoorOpens:
|
|
room->disableHotzone("LargeDisk");
|
|
room->disableHotzone("MediumDisk");
|
|
room->disableHotzone("SmallDisk");
|
|
room->disableHotzone("Background");
|
|
room->enableHotzone("wood");
|
|
room->playVideo("r1210bd0", 600, 12308);
|
|
break;
|
|
case 12308:
|
|
room->enableMouse();
|
|
break;
|
|
case kSoundVaseSegment1Finished:
|
|
case kSoundVaseSegment2Finished:
|
|
case kSoundVaseSegment3Finished:
|
|
case kSoundVaseSegment4Finished: {
|
|
int vase = eventId - kSoundVaseSegment1Finished;
|
|
bool won = true;
|
|
_vaseBusy[vase] = false;
|
|
for (int i = 0; i < 4; i++) {
|
|
if (_vaseBusy[i])
|
|
won = false;
|
|
}
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
if (_vasePos[i] != vaseSol[i])
|
|
won = false;
|
|
}
|
|
|
|
if (!won)
|
|
break;
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
room->stopAnim(vaseSegment[i]);
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
room->disableHotzone(Common::String::format("VaseSegment%d", i + 1));
|
|
|
|
room->playAnim("r1220ba0", 500,
|
|
PlayAnimParams::disappear().partial(0, 17), 12206);
|
|
room->playVideo("r1220mb0", 0);
|
|
room->playSFX("r1220ea0");
|
|
room->disableMouse();
|
|
break;
|
|
}
|
|
case 12206:
|
|
showSandals();
|
|
persistent->_creteSandalsState = Persistent::SANDALS_SOLVED;
|
|
room->enableMouse();
|
|
break;
|
|
case 12303:
|
|
case 12304:
|
|
case 12305:
|
|
if (_atlantisBoatPosition[0] == 0
|
|
&& _atlantisBoatPosition[1] == 0
|
|
&& _atlantisBoatPosition[2] == 0) {
|
|
handleEvent(12306);
|
|
}
|
|
break;
|
|
case 12306:
|
|
room->disableMouse();
|
|
hideAtlantisPopupOverlays();
|
|
room->playAnimWithSFX(kAtlantisOpening, "r1210eb0", kAtlantisOpeningZ,
|
|
PlayAnimParams::keepLastFrame().partial(0, 8),
|
|
kAtlantisDoorOpens);
|
|
break;
|
|
case 12402:
|
|
room->enableMouse();
|
|
redrawStrongBox();
|
|
// Fallthrough
|
|
case 12403:
|
|
room->disableMouse();
|
|
room->playAnimWithSpeech("r2230ba0",
|
|
TranscribedSound::make("r2230wb0", "I think those buttons control the symbols"),
|
|
4000,
|
|
PlayAnimParams::keepLastFrame(), 12404,
|
|
kOffsetRightRoom);
|
|
break;
|
|
case 12404:
|
|
case 12405:
|
|
if (persistent->_hintsAreEnabled)
|
|
g_vm->addTimer(12406, 5000);
|
|
// Fallthrough
|
|
case 12407:
|
|
case 12408:
|
|
case 12145:
|
|
room->playAnim("r2230ba0", 4000, PlayAnimParams::disappear().backwards(), -1,
|
|
kOffsetRightRoom);
|
|
room->enableMouse();
|
|
break;
|
|
case 12406:
|
|
if (!room->isMouseEnabled())
|
|
break;
|
|
room->disableMouse();
|
|
room->playAnimWithSpeech("r2230ba0",
|
|
TranscribedSound::make("r2230wc0", "Try to spell my name"),
|
|
4000,
|
|
PlayAnimParams::keepLastFrame(), 12407,
|
|
kOffsetRightRoom);
|
|
break;
|
|
case 12409:
|
|
for (int i = 0; i < 12; i++) {
|
|
int pos = _strongBoxTiles[i].getPosition();
|
|
if (pos == 1 || pos == 2 || pos == 5 || pos == 6) {
|
|
_strongBoxTiles[i].setRotationPhase(1);
|
|
}
|
|
}
|
|
g_vm->addTimer(12410, 250);
|
|
break;
|
|
case 12410:
|
|
for (int i = 0; i < 12; i++) {
|
|
int pos = _strongBoxTiles[i].getPosition();
|
|
if (pos == 1 || pos == 2 || pos == 5 || pos == 6) {
|
|
_strongBoxTiles[i].setRotationPhase(2);
|
|
_strongBoxTiles[i].rotate();
|
|
switch (pos) {
|
|
case 1:
|
|
_strongBoxTiles[i].setPosition(2);
|
|
break;
|
|
case 2:
|
|
_strongBoxTiles[i].setPosition(6);
|
|
break;
|
|
case 5:
|
|
_strongBoxTiles[i].setPosition(1);
|
|
break;
|
|
case 6:
|
|
_strongBoxTiles[i].setPosition(5);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
g_vm->addTimer(12411, 250);
|
|
break;
|
|
case 12411:
|
|
for (int i = 0; i < 12; i++) {
|
|
_strongBoxTiles[i].setRotationPhase(-1);
|
|
}
|
|
redrawStrongBox();
|
|
break;
|
|
case 12414:
|
|
room->playVideo("v4190ma0", 0, 12415);
|
|
break;
|
|
case 12204:
|
|
case 12415:
|
|
room->enableMouse();
|
|
break;
|
|
case kCoinGiven:
|
|
g_vm->getHeroBelt()->placeToInventory(kPotion);
|
|
break;
|
|
case 12124:
|
|
_fadingHades = true;
|
|
_fadingHadesStartTime = g_vm->getCurrentTime();
|
|
break;
|
|
case 12125:
|
|
room->stopAnim("r2035ba0");
|
|
room->playVideo("R2035BE0", 1200, 12127);
|
|
break;
|
|
case 12127:
|
|
g_vm->moveToRoom(kDaedalusRoom);
|
|
break;
|
|
case kSandalsPlaced:
|
|
room->playVideo("r1220bb0", 0, 12204);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void prepareRoom() override {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
Quest quest = persistent->_quest;
|
|
|
|
if (persistent->_creteHadesPusnishesPainAndPanic) {
|
|
room->disableHeroBelt();
|
|
room->disableMouse();
|
|
room->addStaticLayer("r2035pa0", kBackgroundZ); // background
|
|
room->selectFrame("r2035ba0", 1200, 0);
|
|
|
|
// Originally event 12123
|
|
room->playSpeech(TranscribedSound::make(
|
|
"r2035wa0",
|
|
"Seems the only thing I can count on you two for is target practice"), 12124);
|
|
persistent->_creteHadesPusnishesPainAndPanic = false;
|
|
return;
|
|
}
|
|
|
|
room->loadHotZones("Crete.HOT", false);
|
|
room->addStaticLayer("r1010pa0", kBackgroundZ); // background
|
|
g_vm->getHeroBelt()->setColour(HeroBelt::kWarm);
|
|
|
|
if (quest != kMedusaQuest && quest != kRescuePhilQuest) {
|
|
room->playAnimLoop("r2010oe0", 7000, kOffsetRightRoom);
|
|
room->playAnimLoop("r2010tb0", 6500, kOffsetRightRoom);
|
|
}
|
|
room->playAnimLoop("r2010ta0", 7600, kOffsetRightRoom);
|
|
room->playAnimLoop("r1120ba0", 5500);
|
|
room->playAnimLoop("r1160ba0", 5000);
|
|
room->playAnimLoop("r1170ba0", 5000);
|
|
|
|
room->selectFrame(kTavernImage, kTavernImageZ, 0, kOffsetRightRoom);
|
|
room->enableMouse();
|
|
room->setPannable(true);
|
|
room->enableHotzone(kTavernHotzone);
|
|
room->enableHotzone("Argo");
|
|
room->enableHotzone("Hermes");
|
|
room->enableHotzone("Zeus");
|
|
room->enableHotzone("Poseidon");
|
|
room->enableHotzone("MinosPalace");
|
|
if (quest != kMedusaQuest && quest != kRescuePhilQuest) {
|
|
room->enableHotzone("AlchemistStand");
|
|
}
|
|
|
|
room->setUserPanCallback(-1, -1, 12140, 12142);
|
|
|
|
if (quest == kMedusaQuest && !persistent->_creteAlchemistExploded) {
|
|
persistent->_creteAlchemistExploded = true;
|
|
room->disableMouse();
|
|
room->playAnimWithSFX("r1190ba0", "r1190ea0", 1005, PlayAnimParams::disappear(), 12128);
|
|
}
|
|
|
|
if (quest == kRescuePhilQuest || quest == kMedusaQuest) {
|
|
room->selectFrame("r2010op0", 7500, 0, kOffsetRightRoom);
|
|
}
|
|
|
|
if (quest == kMedusaQuest) {
|
|
room->playAnimWithSFX("r2220bb0", "r2220eb0", 4500, PlayAnimParams::loop(), -1, kOffsetRightRoom);
|
|
}
|
|
|
|
showMiniStrongBox();
|
|
|
|
switch (quest) {
|
|
case kCreteQuest:
|
|
_tavernTalks.push_back("r2250xa0");
|
|
_tavernTalks.push_back("r2250xb0");
|
|
_tavernTalks.push_back("r2250xc0");
|
|
_tavernTalks.push_back("r2250xd0");
|
|
_tavernTalks.push_back("r2250xe0");
|
|
_tavernTalks.push_back("r2250xf0");
|
|
_tavernTalks.push_back("r2220xa0");
|
|
_tavernTalks.push_back("r2220xb0");
|
|
_tavernTalks.push_back("r2220xc0");
|
|
_tavernTalks.push_back("r2220xd0");
|
|
_tavernTalks.push_back("r2220xe0");
|
|
_tavernTalks.push_back("r2220xf0");
|
|
break;
|
|
case kTroyQuest:
|
|
_tavernTalks.push_back("r2260xa0");
|
|
_tavernTalks.push_back("r2260xb0");
|
|
_tavernTalks.push_back("r2195xa0");
|
|
_tavernTalks.push_back("r2195xb0");
|
|
_tavernTalks.push_back("r2290xf0");
|
|
_tavernTalks.push_back("r2220xa0");
|
|
_tavernTalks.push_back("r2220xb0");
|
|
_tavernTalks.push_back("r2220xc0");
|
|
_tavernTalks.push_back("r2220xd0");
|
|
_tavernTalks.push_back("r2220xe0");
|
|
_tavernTalks.push_back("r2220xf0");
|
|
break;
|
|
case kMedusaQuest:
|
|
_tavernTalks.push_back("r2270xa0");
|
|
_tavernTalks.push_back("r2270xb0");
|
|
_tavernTalks.push_back("r2290xg0");
|
|
_tavernTalks.push_back("r2290xh0");
|
|
_tavernTalks.push_back("r2290xi0");
|
|
_tavernTalks.push_back("r2290xj0");
|
|
_tavernTalks.push_back("r2290xk0");
|
|
_tavernTalks.push_back("r2290xl0");
|
|
break;
|
|
case kRescuePhilQuest:
|
|
_tavernTalks.push_back("r2280xa0");
|
|
_tavernTalks.push_back("r2280xc0");
|
|
_tavernTalks.push_back("r2280xd0");
|
|
_tavernTalks.push_back("r2290xg0");
|
|
_tavernTalks.push_back("r2290xh0");
|
|
_tavernTalks.push_back("r2290xi0");
|
|
_tavernTalks.push_back("r2290xj0");
|
|
_tavernTalks.push_back("r2290xk0");
|
|
_tavernTalks.push_back("r2290xl0");
|
|
break;
|
|
|
|
// To silence warning
|
|
case kNoQuest:
|
|
case kEndGame:
|
|
case kNumQuests:
|
|
break;
|
|
}
|
|
_tavernTalks.push_back("r2290xa0");
|
|
_tavernTalks.push_back("r2290xb0");
|
|
_tavernTalks.push_back("r2290xc0");
|
|
_tavernTalks.push_back("r2290xd0");
|
|
_tavernTalks.push_back("r2290xe0");
|
|
|
|
int bg1_variant = -1;
|
|
int bg2_variant = -1;
|
|
|
|
bool showOiBoat = false;
|
|
|
|
if (!persistent->_creteShowMerchant && (quest != kMedusaQuest || !persistent->_medisleShowFates)) {
|
|
bg1_variant = g_vm->getRnd().getRandomNumberRng(0, 2);
|
|
bg2_variant = g_vm->getRnd().getRandomNumberRng(0, 2);
|
|
debug("BG variants %d and %d", bg1_variant, bg2_variant);
|
|
}
|
|
|
|
if (randomBool()) {
|
|
showOiBoat = true;
|
|
room->addStaticLayer("r1010oi0", 4000);
|
|
}
|
|
if (randomBool())
|
|
room->addStaticLayer("r1010oj0", 4000);
|
|
if (randomBool())
|
|
room->addStaticLayer("r1010ok0", 4000);
|
|
if (randomBool())
|
|
room->addStaticLayer("r1010ol0", 4000);
|
|
if (randomBool())
|
|
room->addStaticLayer("r1010on0", 4001);
|
|
if (randomBool())
|
|
room->addStaticLayer("r1010oo0", 4000);
|
|
if (randomBool())
|
|
room->addStaticLayer("r1010op0", 4100);
|
|
if (randomBool())
|
|
room->addStaticLayer("r1010or0", 6500);
|
|
|
|
if (quest != kCreteQuest)
|
|
persistent->_creteShowAtlantisBoat = false;
|
|
|
|
if (persistent->_creteShowAtlantisBoat) {
|
|
room->addStaticLayer("r1010od0", 3900);
|
|
room->addStaticLayer("r1010ta0", 3800);
|
|
room->enableHotzone("AtlantisBoat");
|
|
}
|
|
|
|
room->playAnimLoop("r1010om0", 3000);
|
|
|
|
int minotaurPosition = -1;
|
|
int toughGuyPosition = -1;
|
|
int womanSmellPosition = -1;
|
|
if (quest == kCreteQuest && !persistent->_creteShowMerchant && !persistent->_creteShowAtlantisBoat)
|
|
minotaurPosition = g_vm->getRnd().getRandomNumberRng(0, 3);
|
|
|
|
bool showCat = false;
|
|
bool showStatueMan = false;
|
|
bool showOldMan = false;
|
|
bool showBlondBoy = false;
|
|
bool showMotherAndKidSmall = false;
|
|
bool showMotherAndKid = false;
|
|
bool showManSelling = false;
|
|
bool showDrawinWithoutWoman = false;
|
|
bool showWomanDrawing = false;
|
|
bool showWomanGraffiti = false;
|
|
bool showGirlAndNut = false;
|
|
bool showOneManBand = false;
|
|
int ambientComposite = g_vm->getRnd().getRandomNumberRng(1, 8);
|
|
debug("Ambients from Composite %d selected. \n", ambientComposite);
|
|
switch (ambientComposite) {
|
|
case 1:
|
|
showGirlAndNut = true;
|
|
if (quest != kCreteQuest && quest != kTroyQuest) {
|
|
toughGuyPosition = 1;
|
|
break;
|
|
}
|
|
if (minotaurPosition == 1) {
|
|
if (randomBool())
|
|
toughGuyPosition = 0;
|
|
break;
|
|
|
|
}
|
|
if (persistent->_creteShowMerchant) {
|
|
showOneManBand = true;
|
|
showWomanGraffiti = true;
|
|
break;
|
|
}
|
|
if (randomBool()) {
|
|
toughGuyPosition = 0;
|
|
showOneManBand = true;
|
|
showWomanGraffiti = true;
|
|
}
|
|
else
|
|
toughGuyPosition = 1;
|
|
break;
|
|
case 2:
|
|
womanSmellPosition = g_vm->getRnd().getRandomNumberRng(0, 2);
|
|
showWomanDrawing = true;
|
|
showManSelling = true;
|
|
if (quest != kMedusaQuest && quest != kRescuePhilQuest)
|
|
showMotherAndKid = true;
|
|
showBlondBoy = true;
|
|
break;
|
|
case 3:
|
|
if (quest != kRescuePhilQuest && bg1_variant != 0 && bg1_variant != 1)
|
|
showCat = true;
|
|
showOldMan = true;
|
|
if (!persistent->_creteShowMerchant) {
|
|
showManSelling = true;
|
|
toughGuyPosition = 2;
|
|
}
|
|
showWomanGraffiti = true;
|
|
showWomanDrawing = true;
|
|
break;
|
|
case 4:
|
|
if (quest != kRescuePhilQuest && bg1_variant != 0 && bg1_variant != 1)
|
|
showCat = true;
|
|
showWomanDrawing = true;
|
|
toughGuyPosition = 2;
|
|
showOneManBand = true;
|
|
break;
|
|
case 5:
|
|
if (quest != kCreteQuest && quest != kTroyQuest)
|
|
toughGuyPosition = 1;
|
|
else
|
|
toughGuyPosition = g_vm->getRnd().getRandomBit();
|
|
womanSmellPosition = g_vm->getRnd().getRandomBit();
|
|
break;
|
|
case 6:
|
|
showWomanGraffiti = true;
|
|
showWomanDrawing = true;
|
|
if (quest != kCreteQuest && quest != kTroyQuest)
|
|
toughGuyPosition = 1;
|
|
else
|
|
toughGuyPosition = g_vm->getRnd().getRandomBit();
|
|
break;
|
|
case 7:
|
|
womanSmellPosition = g_vm->getRnd().getRandomNumberRng(0, 2);
|
|
if (womanSmellPosition == 2 && (quest != kCreteQuest && quest != kTroyQuest))
|
|
womanSmellPosition = -1;
|
|
if (quest == kMedusaQuest)
|
|
showStatueMan = true;
|
|
showMotherAndKidSmall = true;
|
|
showWomanGraffiti = true;
|
|
break;
|
|
case 8:
|
|
if (quest != kCreteQuest && quest != kTroyQuest) {
|
|
toughGuyPosition = 1;
|
|
showDrawinWithoutWoman = true;
|
|
break;
|
|
}
|
|
|
|
if (!persistent->_creteShowMerchant && randomBool()) {
|
|
toughGuyPosition = 2;
|
|
showBlondBoy = true;
|
|
}
|
|
else
|
|
toughGuyPosition = 1;
|
|
showOldMan = true;
|
|
showDrawinWithoutWoman = true;
|
|
break;
|
|
}
|
|
|
|
int birdsState = g_vm->getRnd().getRandomNumberRng(0, 2);
|
|
int dolphinPosition = -1;
|
|
if (!persistent->_creteShowAtlantisBoat)
|
|
dolphinPosition = g_vm->getRnd().getRandomNumberRng(0, showOiBoat ? 1 : 2);
|
|
if (quest != kMedusaQuest && quest != kRescuePhilQuest)
|
|
_alchemistAmbient = ambient("r2220ba0", "r2220ec0", 5500, 15, 30, AmbientAnim::PAN_RIGHT, kOffsetRightRoom, true);
|
|
|
|
// Disable conflicting images
|
|
if (minotaurPosition == 1
|
|
&& (toughGuyPosition == 1 || toughGuyPosition == 2))
|
|
toughGuyPosition = -1;
|
|
if (minotaurPosition == 1) {
|
|
showWomanGraffiti = false;
|
|
showManSelling = false;
|
|
showOneManBand = false;
|
|
}
|
|
if (persistent->_creteShowMerchant &&
|
|
(toughGuyPosition == 0 || toughGuyPosition == 1))
|
|
toughGuyPosition = -1;
|
|
if (womanSmellPosition == 2)
|
|
showMotherAndKid = false;
|
|
if (persistent->_creteShowMerchant)
|
|
showCat = false;
|
|
if (quest != kCreteQuest && quest != kTroyQuest)
|
|
showOldMan = false;
|
|
|
|
debug("toughGuyPosition = %d, minotaurPosition = %d, dolphinPosition = %d",
|
|
toughGuyPosition, minotaurPosition, dolphinPosition);
|
|
if (showWomanGraffiti)
|
|
ambient("r2370ba0", "r2370ea0", 1700, 15, 30, AmbientAnim::PAN_RIGHT, kOffsetRightRoom);
|
|
switch (toughGuyPosition) {
|
|
case 0:
|
|
ambient("r2340ba0", "r2340ea0", 1400, 15, 25, AmbientAnim::PAN_RIGHT, kOffsetRightRoom);
|
|
break;
|
|
case 1:
|
|
ambient("r2340bb0", "r2340eb0", 1400, 15, 25, AmbientAnim::PAN_RIGHT, kOffsetRightRoom);
|
|
break;
|
|
case 2:
|
|
ambient("r2340be0", "r2340ee0", 1600, 15, 25, AmbientAnim::PAN_RIGHT, kOffsetRightRoom);
|
|
break;
|
|
}
|
|
if (showOneManBand) {
|
|
room->playAnimLoop(kOneManBandAnim, kOneManBandZ, kOffsetRightRoom);
|
|
room->enableHotzone(kOneManBandHotZone);
|
|
}
|
|
if (showGirlAndNut)
|
|
ambient("r2140ba0", "r2140ea0", 1500, 15, 30, AmbientAnim::PAN_RIGHT, kOffsetRightRoom);
|
|
if (showWomanDrawing)
|
|
ambient("r2110ba0", "r2110ea0", 1600, 10, 30, AmbientAnim::PAN_LEFT);
|
|
if (showDrawinWithoutWoman)
|
|
room->addStaticLayer("r2110bb0", 1600);
|
|
if (showManSelling)
|
|
ambient("r2150ba0", "r2150ea0", 1600, 10, 30, AmbientAnim::PAN_RIGHT, kOffsetRightRoom);
|
|
if (showMotherAndKid)
|
|
ambient("r2160ba0", "r2160ea0", 1500, 15, 30, AmbientAnim::PAN_RIGHT, kOffsetRightRoom);
|
|
if (showMotherAndKidSmall)
|
|
ambient("r2160bb0", "", 1500, 15, 30, AmbientAnim::PAN_LEFT);
|
|
if (showBlondBoy)
|
|
ambient("r2350ba0", "r2350ea0", 1500, 15, 30, AmbientAnim::PAN_RIGHT, kOffsetRightRoom);
|
|
if (showOldMan)
|
|
ambient("r2100bb0", "r2100eb0", 1500, 10, 30, AmbientAnim::PAN_RIGHT, kOffsetRightRoom);
|
|
if (showStatueMan)
|
|
ambient("r2050ba0", "r2050ea0", 1500, 10, 30, AmbientAnim::PAN_RIGHT, kOffsetRightRoom);
|
|
if (showCat) {
|
|
room->addStaticLayer("r2010on0", kMerchantStandZ);
|
|
ambient("r2080bb0", "r2080eb0", kMerchantZ, 10, 30, AmbientAnim::PAN_LEFT);
|
|
}
|
|
|
|
if (persistent->_creteShowMerchant) {
|
|
room->addStaticLayer("r2010on0", kMerchantStandZ);
|
|
room->selectFrame(kMerchantAnim, kMerchantZ, 0);
|
|
room->playSFX("G0261mA0");
|
|
if (persistent->_creteShowHorned) {
|
|
room->addStaticLayer(kHorned, 1220);
|
|
room->enableHotzone(kHornedHotzone);
|
|
}
|
|
if (persistent->_creteShowHornless2) {
|
|
room->addStaticLayer(kHornless2, 1190);
|
|
room->setHotzoneEnabled(kHornless2Hotzone,
|
|
persistent->_creteTriedHornless[0]);
|
|
}
|
|
if (persistent->_creteShowHornless1) {
|
|
room->addStaticLayer(kHornless1, 1180);
|
|
room->enableHotzone(kHornless1Hotzone);
|
|
}
|
|
if (persistent->_creteShowHornless3) {
|
|
room->addStaticLayer(kHornless3, 1180);
|
|
room->setHotzoneEnabled(kHornless3Hotzone,
|
|
persistent->_creteTriedHornless[1]);
|
|
}
|
|
if (persistent->_creteShowHornless4) {
|
|
room->addStaticLayer(kHornless4, 1180);
|
|
room->setHotzoneEnabled(kHornless4Hotzone,
|
|
persistent->_creteTriedHornless[2]);
|
|
g_vm->addTimer(kMerchantIdleTimer, 10000, -1);
|
|
}
|
|
}
|
|
|
|
if (birdsState == 0) {
|
|
room->addStaticLayer(kTalusImageWithShip, kTalusZ);
|
|
room->enableHotzone(kTalusHotzone);
|
|
} else
|
|
room->addStaticLayer(kTalusImage, kTalusZ);
|
|
|
|
// TODO: fix this
|
|
switch (minotaurPosition) {
|
|
case 0:
|
|
ambient("r2060bf0", "r2060ee0", 1800, 3, 4, AmbientAnim::PAN_RIGHT, kOffsetRightRoom); // shouldn't be an ambient
|
|
break;
|
|
case 1:
|
|
ambient("r2060bt0", "r2060ei0", 1650, 3, 4, AmbientAnim::PAN_RIGHT, kOffsetRightRoom); // shouldn't be an ambient
|
|
break;
|
|
case 2:
|
|
// ambient("r1110ea0", "", 15, 30); // wrong
|
|
break;
|
|
case 3:
|
|
ambient("r1110ba0", "r1110eb0", 850, 20, 40, AmbientAnim::PAN_RIGHT, kOffsetRightRoom);
|
|
break;
|
|
}
|
|
|
|
switch (womanSmellPosition) {
|
|
case 0:
|
|
ambient("r2380ba0", "r2380ea0", 1550, 15, 30, AmbientAnim::PAN_ANY);
|
|
break;
|
|
case 1:
|
|
ambient("r2380bc0", "r2380ec0", 1550, 15, 30, AmbientAnim::PAN_ANY);
|
|
break;
|
|
case 2:
|
|
ambient("r2380bd0", "r2380ed0", 1550, 15, 30, AmbientAnim::PAN_RIGHT, kOffsetRightRoom);
|
|
break;
|
|
}
|
|
|
|
switch (birdsState) {
|
|
case 0:
|
|
ambient("r1060ba0", "r1060ea0", 4500, 10, 40, AmbientAnim::PAN_ANY);
|
|
break;
|
|
case 1:
|
|
ambient("r1060bb0","r1060eb0", 4500, 5, 40, AmbientAnim::PAN_ANY);
|
|
break;
|
|
case 2:
|
|
ambient("r1060bc0", "r1060ec0", 4500, 5, 40, AmbientAnim::PAN_ANY);
|
|
break;
|
|
}
|
|
|
|
if (dolphinPosition >= 0) {
|
|
Common::String dolphinAnim = Common::String::format(
|
|
"r1150b%c0", 'a' + dolphinPosition);
|
|
Common::String dolphinSound = Common::String::format(
|
|
"r1150e%c0", 'a' + dolphinPosition);
|
|
|
|
ambient(dolphinAnim, dolphinSound, 5500, 5, 20, AmbientAnim::PAN_LEFT);
|
|
}
|
|
|
|
if (bg1_variant >= 0 && bg2_variant >= 0) {
|
|
Common::String bg2 = Common::String::format(
|
|
"r1010o%c1", 'e' + bg2_variant);
|
|
room->addStaticLayer(bg2, 3500);
|
|
|
|
Common::String bg1 = Common::String::format(
|
|
"r1010o%c0", 'e' + bg1_variant);
|
|
room->addStaticLayer(bg1, 1000);
|
|
}
|
|
|
|
room->playMusicLoop("R1010eA0");
|
|
|
|
if (g_vm->getPreviousRoomId() == kMinosPalaceRoom) {
|
|
room->panRightInstant();
|
|
if (persistent->_creteIntroMerchant) {
|
|
room->disableMouse();
|
|
room->panLeftAnim(kIntroMerchantPanFinished);
|
|
_merchantIsBusy = true;
|
|
persistent->_creteIntroMerchant = false;
|
|
}
|
|
|
|
if (persistent->_creteIntroAtlantisBoat) {
|
|
persistent->_creteIntroAtlantisBoat = false;
|
|
room->disableMouse();
|
|
room->playVideo("r1180ba0", 0, 12134, Common::Point(640, 216));
|
|
}
|
|
|
|
}
|
|
|
|
if (quest == kMedusaQuest && persistent->_medisleShowFates) {
|
|
switch (persistent->_creteSandalsState) {
|
|
case Persistent::SANDALS_NOT_SOLVED:
|
|
for (int i = 0; i < 4; i++)
|
|
room->enableHotzone(Common::String::format("VaseSegment%d", i + 1));
|
|
_vasePos[0] = (g_vm->getRnd().getRandomNumberRng(1, 3) + 2) % 4;
|
|
_vasePos[1] = (g_vm->getRnd().getRandomNumberRng(1, 5) + 3) % 6;
|
|
_vasePos[2] = (g_vm->getRnd().getRandomNumberRng(1, 5) + 2) % 6;
|
|
_vasePos[3] = (g_vm->getRnd().getRandomNumberRng(1, 3) + 3) % 4;
|
|
renderVase();
|
|
break;
|
|
case Persistent::SANDALS_SOLVED:
|
|
showSandals();
|
|
break;
|
|
case Persistent::SANDALS_TAKEN:
|
|
room->selectFrame("r1220ba0", 500, 0);
|
|
break;
|
|
}
|
|
}
|
|
|
|
switch (persistent->_quest) {
|
|
case kCreteQuest:
|
|
if (!persistent->_roomVisited[kMinosPalaceRoom]) {
|
|
room->playVideo("r1260ma0", 0);
|
|
break;
|
|
}
|
|
|
|
if (persistent->_creteShowMerchant) {
|
|
room->playVideo("g0261ma0", 0);
|
|
break;
|
|
}
|
|
break;
|
|
case kMedusaQuest:
|
|
if (persistent->_medisleShowFates && persistent->_creteSandalsState == Persistent::SANDALS_NOT_SOLVED)
|
|
room->playVideo("r1220ma0", 0);
|
|
break;
|
|
case kRescuePhilQuest:
|
|
if (persistent->_creteStrongBoxState == Persistent::BOX_CLOSED || persistent->_creteStrongBoxState == Persistent::BOX_OPEN)
|
|
room->playVideo("r2230ma0", 0);
|
|
break;
|
|
// To silence warning
|
|
case kTroyQuest:
|
|
case kNoQuest:
|
|
case kEndGame:
|
|
case kNumQuests:
|
|
break;
|
|
}
|
|
|
|
if (!persistent->_creteSaidHelenPermanentResident && persistent->_quest == kTroyQuest) {
|
|
persistent->_creteSaidHelenPermanentResident = true;
|
|
room->disableMouse();
|
|
room->playVideo("r1250ba0", 0, 12134, Common::Point(0, 216));
|
|
}
|
|
}
|
|
|
|
void frameCallback() override {
|
|
if (_strongBoxPopup && strongBoxIsBusy())
|
|
redrawStrongBox();
|
|
if (_fadingHades) {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
int val = (256 * (g_vm->getCurrentTime() - _fadingHadesStartTime)) / 2000;
|
|
if (val >= 256) {
|
|
_fadingHades = false;
|
|
val = 256;
|
|
handleEvent(12125);
|
|
}
|
|
room->setColorScale("r2035pa0", 256 - val);
|
|
}
|
|
}
|
|
|
|
private:
|
|
void showMiniStrongBox() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
if (persistent->_quest != kRescuePhilQuest)
|
|
return;
|
|
|
|
switch(persistent->_creteStrongBoxState) {
|
|
case Persistent::BOX_CLOSED:
|
|
room->enableHotzone("StrongBoxClosed");
|
|
room->selectFrame("r2010ba0", 5000, 0, kOffsetRightRoom);
|
|
break;
|
|
case Persistent::BOX_OPEN:
|
|
room->enableHotzone("StrongBoxOpen");
|
|
room->selectFrame("r2010ba0", 5000, 1, kOffsetRightRoom);
|
|
break;
|
|
case Persistent::BOX_OPEN_POTION:
|
|
room->enableHotzone("StrongBoxOpenPotion");
|
|
room->selectFrame("r2010ba0", 5000, 2, kOffsetRightRoom);
|
|
break;
|
|
case Persistent::BOX_OPEN_NO_POTION:
|
|
room->enableHotzone("StrongBoxOpenNoPotion");
|
|
room->selectFrame("r2010ba0", 5000, 3, kOffsetRightRoom);
|
|
break;
|
|
}
|
|
}
|
|
|
|
AmbientAnim ambient(const Common::String &anim, const Common::String &sound,
|
|
int zValue, int minint, int maxint,
|
|
AmbientAnim::PanType pan,
|
|
Common::Point offset = Common::Point(0,0),
|
|
bool loop = true) {
|
|
AmbientAnim ret = AmbientAnim(anim, sound, zValue, minint * 1000, maxint * 1000,
|
|
loop ? AmbientAnim::KEEP_LOOP : AmbientAnim::DISAPPEAR,
|
|
offset, pan);
|
|
ret.start();
|
|
return ret;
|
|
}
|
|
|
|
bool randomBool() const {
|
|
return g_vm->getRnd().getRandomBit();
|
|
}
|
|
|
|
void renderAtlantisDisks() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
room->selectFrame(kAtlantisLargeDisk, kAtlantisLargeDiskZ, _atlantisBoatPosition[0]);
|
|
room->selectFrame(kAtlantisMediumDisk, kAtlantisMediumDiskZ, _atlantisBoatPosition[1]);
|
|
room->selectFrame(kAtlantisSmallDisk, kAtlantisSmallDiskZ, _atlantisBoatPosition[2]);
|
|
}
|
|
|
|
void advanceAtlantisDisk(int diskNum) {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
_atlantisBoatPosition[diskNum] = (_atlantisBoatPosition[diskNum] + 1) % 8;
|
|
renderAtlantisDisks();
|
|
room->playSFX(Common::String::format("r1210e%c0", 'e' + diskNum), 12303 + diskNum);
|
|
}
|
|
|
|
void hideAtlantisPopupOverlays() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
room->stopAnim(kAtlantisLargeDisk);
|
|
room->stopAnim(kAtlantisMediumDisk);
|
|
room->stopAnim(kAtlantisSmallDisk);
|
|
room->stopAnim(kAtlantisDiskBackground);
|
|
}
|
|
|
|
void renderVase() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
for(int i = 0; i < 4; i++)
|
|
room->selectFrame(vaseSegment[i], 1000, _vasePos[i]);
|
|
|
|
}
|
|
|
|
void showSandals() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
room->playAnim("r1220ba0", 500, PlayAnimParams::loop().partial(9, 17));
|
|
room->enableHotzone("sandals");
|
|
}
|
|
|
|
void showStrongBox() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
// User already clicked, no need to play that anim
|
|
persistent->_cretePlayedZeusCheckOutThatBox = true;
|
|
room->pushHotZones("Box.Hot");
|
|
room->playSFX("g0082ea0");
|
|
redrawStrongBox();
|
|
_strongBoxPopup = true;
|
|
switch(persistent->_creteStrongBoxState) {
|
|
case Persistent::BOX_CLOSED:
|
|
room->selectFrame("r2230bb0", 1000, 1, kOffsetRightRoom);
|
|
break;
|
|
case Persistent::BOX_OPEN:
|
|
room->selectFrame("r2230bb0", 1000, 3, kOffsetRightRoom);
|
|
break;
|
|
case Persistent::BOX_OPEN_POTION:
|
|
room->selectFrame("r2230bb0", 1000, 3, kOffsetRightRoom);
|
|
room->selectFrame("r2230bf0", 300, -2, kOffsetRightRoom);
|
|
break;
|
|
case Persistent::BOX_OPEN_NO_POTION:
|
|
room->selectFrame("r2230bb0", 1000, 3, kOffsetRightRoom);
|
|
room->selectFrame("r2230bf0", 300, -1, kOffsetRightRoom);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void hideStrongBox() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
room->stopAnim("r2230bb0");
|
|
room->stopAnim("r2230bf0");
|
|
for (int i = 0; i < 12; i++)
|
|
room->stopAnim(LayerId("r2010om0", i, "pos"));
|
|
room->stopAnim(LayerId("r2010om1", 0, "center"));
|
|
for (int i = 0; i < 4; i++) {
|
|
room->stopAnim(LayerId("r2010om1", i, "side"));
|
|
}
|
|
_strongBoxPopup = false;
|
|
}
|
|
|
|
void redrawStrongBox() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
|
|
room->setHotzoneEnabled("Potion", persistent->_creteStrongBoxState == Persistent::BOX_OPEN_POTION);
|
|
room->setHotzoneEnabled("Latch", persistent->_creteStrongBoxState == Persistent::BOX_CLOSED);
|
|
room->setHotzoneEnabled("ButtonN", persistent->_creteStrongBoxState == Persistent::BOX_OPEN);
|
|
room->setHotzoneEnabled("ButtonS", persistent->_creteStrongBoxState == Persistent::BOX_OPEN);
|
|
room->setHotzoneEnabled("ButtonE", persistent->_creteStrongBoxState == Persistent::BOX_OPEN);
|
|
room->setHotzoneEnabled("ButtonW", persistent->_creteStrongBoxState == Persistent::BOX_OPEN);
|
|
room->setHotzoneEnabled("ButtonC", persistent->_creteStrongBoxState == Persistent::BOX_OPEN);
|
|
|
|
switch(persistent->_creteStrongBoxState) {
|
|
case Persistent::BOX_CLOSED:
|
|
break;
|
|
case Persistent::BOX_OPEN:
|
|
room->selectFrame(LayerId("r2010om1", 0, "center"), 400, 0, Common::Point(1060, 308));
|
|
for (int i = 0; i < 4; i++) {
|
|
room->selectFrame(LayerId("r2010om1", i, "side"), 400, 1,
|
|
strongBoxSideDotOffsets[i].get());
|
|
}
|
|
{
|
|
bool wasMoving = strongBoxIsBusy();
|
|
for (int i = 0; i < 12; i++) {
|
|
_strongBoxTiles[i].show();
|
|
}
|
|
if (wasMoving && !strongBoxIsBusy()) {
|
|
strongBoxCheckSolution();
|
|
}
|
|
}
|
|
break;
|
|
case Persistent::BOX_OPEN_POTION:
|
|
case Persistent::BOX_OPEN_NO_POTION:
|
|
room->selectFrame(LayerId("r2010om1", 0, "center"), 400, 0, Common::Point(1060, 308));
|
|
for (int i = 0; i < 4; i++) {
|
|
room->selectFrame(LayerId("r2010om1", i, "side"), 400, 1,
|
|
strongBoxSideDotOffsets[i].get());
|
|
}
|
|
for (int i = 0; i < 12; i++) {
|
|
_strongBoxTiles[i].show();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool strongBoxIsBusy() {
|
|
for (int i = 0; i < 12; i++) {
|
|
if (_strongBoxTiles[i].isMoving()) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void strongBoxCheckSolution() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
bool zOk = false, eOk = false, uOk = false, sOk = false;
|
|
for (int i = 0; i < 12; i++) {
|
|
if (_strongBoxTiles[i].getPosition() == 0
|
|
&& _strongBoxTiles[i].getLetter() == StrongBoxTile::kLetterZ
|
|
&& (_strongBoxTiles[i].getOrientation() == 0
|
|
|| _strongBoxTiles[i].getOrientation() == 180))
|
|
zOk = true;
|
|
if (_strongBoxTiles[i].getPosition() == 1
|
|
&& _strongBoxTiles[i].getLetter() == StrongBoxTile::kLetterE
|
|
&& _strongBoxTiles[i].getOrientation() == 0)
|
|
eOk = true;
|
|
if (_strongBoxTiles[i].getPosition() == 2
|
|
&& _strongBoxTiles[i].getLetter() == StrongBoxTile::kLetterU
|
|
&& _strongBoxTiles[i].getOrientation() == 0)
|
|
uOk = true;
|
|
if (_strongBoxTiles[i].getPosition() == 3
|
|
&& _strongBoxTiles[i].getLetter() == StrongBoxTile::kLetterS
|
|
&& (_strongBoxTiles[i].getOrientation() == 0
|
|
|| _strongBoxTiles[i].getOrientation() == 180))
|
|
sOk = true;
|
|
}
|
|
|
|
if (zOk && eOk && uOk && sOk) {
|
|
persistent->_creteStrongBoxState = Persistent::BOX_OPEN_POTION;
|
|
room->disableMouse();
|
|
room->enableHotzone("Potion");
|
|
room->disableHotzone("ButtonS");
|
|
room->disableHotzone("ButtonN");
|
|
room->disableHotzone("ButtonE");
|
|
room->disableHotzone("ButtonW");
|
|
room->disableHotzone("ButtonC");
|
|
room->playAnimWithSFX("r2230bf0", "r2230ea0", 300,
|
|
PlayAnimParams::keepLastFrame().partial(0, -2),
|
|
12414, kOffsetRightRoom);
|
|
}
|
|
}
|
|
|
|
void strongBoxMoveTiles(int p1, int p2, int p3, int p4) {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
room->playSFX("r2230ee0");
|
|
for (int i = 0; i < 12; i++) {
|
|
int pos = _strongBoxTiles[i].getPosition();
|
|
if (pos == p1)
|
|
_strongBoxTiles[i].moveTo(p2);
|
|
if (pos == p2)
|
|
_strongBoxTiles[i].moveTo(p3);
|
|
if (pos == p3)
|
|
_strongBoxTiles[i].moveTo(p4);
|
|
if (pos == p4)
|
|
_strongBoxTiles[i].moveTo(p1);
|
|
}
|
|
}
|
|
|
|
bool _fadingHades;
|
|
int _fadingHadesStartTime;
|
|
int _tavernCounter;
|
|
int _oneManBandCounter;
|
|
int _atlantisBoatPosition[3];
|
|
bool _merchantIsBusy;
|
|
int _vasePos[4];
|
|
bool _vaseBusy[4];
|
|
bool _strongBoxPopup;
|
|
StrongBoxTile _strongBoxTiles[12];
|
|
Common::Array<Common::String> _tavernTalks;
|
|
AmbientAnim _alchemistAmbient;
|
|
};
|
|
|
|
Common::SharedPtr<Hadesch::Handler> makeCreteHandler() {
|
|
return Common::SharedPtr<Hadesch::Handler>(new CreteHandler());
|
|
}
|
|
|
|
}
|