342 lines
10 KiB
C++
342 lines
10 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Copyright 2020 Google
|
|
*
|
|
*/
|
|
#include "hadesch/hadesch.h"
|
|
#include "hadesch/video.h"
|
|
#include "hadesch/ambient.h"
|
|
|
|
namespace Hadesch {
|
|
|
|
static const char *kBacchusHighlight = "AnimBacchusStatue";
|
|
static const char *kGuardLooking = "AnimGuardLooking";
|
|
static const char *kAnimMinosEating = "AnimMinosEating";
|
|
static const char *kStatues = "AnimStatueZeroPose";
|
|
|
|
enum {
|
|
kMinosBackToIdleEvent = 14003,
|
|
// 14005 is the end of statue animation that we handle as functor instead
|
|
kInstructionMovieCompleted = 14011,
|
|
kMinosHornedStatue = 14012,
|
|
kMinosOtherItem = 14013,
|
|
kMinosToss1 = 14014,
|
|
kMinosToss2 = 14015,
|
|
kMinosToss3 = 14016,
|
|
kMinosToss4 = 14017,
|
|
kMinosStatueTossed = 14018,
|
|
kGuardGruntCleanup = 14020,
|
|
kGuardNagCleanup = 14021,
|
|
kGuardNag = 14022,
|
|
kGuardPeriodic = 1014001,
|
|
kMinosPeriodic = 1014002
|
|
};
|
|
|
|
enum {
|
|
kBacchusZ = 200,
|
|
kStatueOnTheTableZ = 300,
|
|
kMinosZ = 500,
|
|
kInstalledStatueZ = 500,
|
|
kGuardZ = 600,
|
|
kBackgroundZ = 10000
|
|
};
|
|
|
|
class MinosHandler : public Handler {
|
|
public:
|
|
MinosHandler() {
|
|
_guardIsBusy = false;
|
|
_minosIsBusy = false;
|
|
}
|
|
|
|
void handleClick(const Common::String &name) override {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
if (name == "Bacchus") {
|
|
Common::Array<Common::String> videos;
|
|
videos.push_back("SndBacchusStatueA");
|
|
videos.push_back("SndBacchusStatueB");
|
|
videos.push_back("SndBacchusStatueC");
|
|
|
|
room->playStatueSMK(kBacchusStatue,
|
|
kBacchusHighlight,
|
|
kBacchusZ,
|
|
videos, 22, 39);
|
|
return;
|
|
}
|
|
|
|
if (name == "Crete") {
|
|
room->disableMouse();
|
|
g_vm->moveToRoom(kCreteRoom);
|
|
return;
|
|
}
|
|
|
|
if (name == "Daedalus") {
|
|
room->disableMouse();
|
|
g_vm->moveToRoom(kDaedalusRoom);
|
|
return;
|
|
}
|
|
|
|
if (name == "Guard" && !_guardIsBusy) {
|
|
_guardIsBusy = true;
|
|
room->playAnimWithSFX("AnimGuardGrunt",
|
|
"SndGuardGrunt",
|
|
kGuardZ,
|
|
PlayAnimParams::keepLastFrame(),
|
|
kGuardGruntCleanup);
|
|
room->stopAnim(kGuardLooking);
|
|
return;
|
|
}
|
|
|
|
if (name == "Minos") {
|
|
playMinosMovie("MovMinosBeGone", kMinosBackToIdleEvent, Common::Point(202, 229));
|
|
return;
|
|
}
|
|
|
|
if (name == "Table") {
|
|
playMinosMovie("MovMinosHavePiece", kMinosBackToIdleEvent, Common::Point(230, 227));
|
|
return;
|
|
}
|
|
|
|
if (name == "Statue" && !_guardIsBusy) {
|
|
_guardIsBusy = true;
|
|
room->playVideo("MovGuardDontTouch", kGuardZ, 14004, Common::Point(432, 142));
|
|
room->stopAnim(kGuardLooking);
|
|
return;
|
|
}
|
|
}
|
|
|
|
bool handleClickWithItem(const Common::String &name, InventoryItem item) override {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
if (name == "Minos") {
|
|
if (item >= kHornlessStatue1 && item <= kHornedStatue) {
|
|
playMinosMovie("MovMinosPutOnTable", kMinosBackToIdleEvent, Common::Point(218, 227));
|
|
return true;
|
|
}
|
|
|
|
playMinosMovie("MovMinosBeGone", kMinosBackToIdleEvent, Common::Point(202, 229));
|
|
return true;
|
|
}
|
|
|
|
if (name == "Table") {
|
|
static const char *sounds[4] = {
|
|
"R3160eA0",
|
|
"R3160eB0",
|
|
"R3160eC0",
|
|
"R3160eD0",
|
|
};
|
|
room->playSFX(sounds[g_vm->getRnd().getRandomNumberRng(0, 3)]);
|
|
if (item == kHornedStatue) {
|
|
g_vm->getHeroBelt()->removeFromInventory(item);
|
|
// room->selectFrame(kStatues, 0);
|
|
playMinosMovie("MovMinosLoveTheHorns", kMinosHornedStatue, Common::Point(202, 178));
|
|
persistent->_creteDaedalusRoomAvailable = true;
|
|
return true;
|
|
}
|
|
if (item >= kHornlessStatue1 && item <= kHornedStatue) {
|
|
g_vm->getHeroBelt()->removeFromInventory(item);
|
|
static const int mapFrames[] = {
|
|
2, 4, 1, 3
|
|
};
|
|
room->selectFrame(kStatues, kStatueOnTheTableZ, mapFrames[item - kHornlessStatue1]);
|
|
playMinosMovie("MovMinosWhatTrash", kMinosToss1 + item - kHornlessStatue1, Common::Point(202, 225));
|
|
persistent->_creteTriedHornless[item - kHornlessStatue1] = true;
|
|
return true;
|
|
}
|
|
playMinosMovie("MovMinosWhatTrash", kMinosOtherItem, Common::Point(202, 225));
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void handleEvent(int eventId) override {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
|
|
switch (eventId) {
|
|
case kMinosBackToIdleEvent:
|
|
minosBackToIdle();
|
|
break;
|
|
case kMinosHornedStatue:
|
|
room->setLayerEnabled(kStatues, false);
|
|
persistent->_creteShowMerchant = false;
|
|
persistent->_creteHadesPusnishesPainAndPanic = true;
|
|
g_vm->moveToRoom(kCreteRoom);
|
|
break;
|
|
case kMinosOtherItem:
|
|
playMinosMovie("MovMinosBeGone", kMinosBackToIdleEvent, Common::Point(202, 229));
|
|
scheduleNagging();
|
|
break;
|
|
case kMinosToss1:
|
|
room->setLayerEnabled(kStatues, false);
|
|
playMinosMovie("MovMinosToss1", kMinosStatueTossed, Common::Point(0, 191));
|
|
break;
|
|
case kMinosToss2:
|
|
room->setLayerEnabled(kStatues, false);
|
|
playMinosMovie("MovMinosToss2", kMinosStatueTossed, Common::Point(0, 188));
|
|
break;
|
|
case kMinosToss3:
|
|
room->setLayerEnabled(kStatues, false);
|
|
playMinosMovie("MovMinosToss3", kMinosStatueTossed, Common::Point(0, 183));
|
|
break;
|
|
case kMinosToss4:
|
|
room->setLayerEnabled(kStatues, false);
|
|
playMinosMovie("MovMinosToss4", kMinosStatueTossed, Common::Point(0, 191));
|
|
break;
|
|
case kMinosStatueTossed:
|
|
playMinosMovie("MovMinosBeGone", kMinosBackToIdleEvent, Common::Point(202, 229));
|
|
scheduleNagging();
|
|
break;
|
|
|
|
case kGuardGruntCleanup:
|
|
_guardIsBusy = false;
|
|
room->stopAnim("AnimGuardGrunt");
|
|
room->selectFrame(kGuardLooking, kGuardZ, 0);
|
|
break;
|
|
case kGuardPeriodic:
|
|
if (!_guardIsBusy)
|
|
room->playAnimWithSFX(kGuardLooking,
|
|
"SndGuardLooking",
|
|
kGuardZ,
|
|
PlayAnimParams::keepLastFrame());
|
|
g_vm->addTimer(kGuardPeriodic, g_vm->getRnd().getRandomNumberRng(5000, 10000));
|
|
break;
|
|
case kMinosPeriodic:
|
|
if (!_minosIsBusy)
|
|
room->playAnimWithSFX(kAnimMinosEating,
|
|
"SndMinosEating",
|
|
kMinosZ,
|
|
PlayAnimParams::keepLastFrame());
|
|
g_vm->addTimer(kMinosPeriodic, g_vm->getRnd().getRandomNumberRng(5000, 10000));
|
|
break;
|
|
case kInstructionMovieCompleted:
|
|
minosBackToIdle();
|
|
break;
|
|
|
|
case kGuardNagCleanup:
|
|
room->selectFrame(kGuardLooking, kGuardZ, 0);
|
|
_guardIsBusy = false;
|
|
break;
|
|
|
|
case kGuardNag:
|
|
scheduleNagging();
|
|
if (!_guardIsBusy && !_minosIsBusy) {
|
|
_guardIsBusy = true;
|
|
room->playVideo("MovGuardUMustGo", kGuardNagCleanup, kGuardZ, Common::Point(0, 142));
|
|
room->stopAnim(kGuardLooking);
|
|
}
|
|
break;
|
|
|
|
case 14004:
|
|
_guardIsBusy = false;
|
|
room->selectFrame(kGuardLooking, kGuardZ, 0);
|
|
break;
|
|
case 14006:
|
|
_ambients.tick();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void prepareRoom() override {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
Persistent *persistent = g_vm->getPersistent();
|
|
room->loadHotZones("Minos.HOT", false);
|
|
room->addStaticLayer("Background", kBackgroundZ);
|
|
room->playAnimLoop("AnimFountain", 250);
|
|
room->enableHotzone("Bacchus");
|
|
room->enableHotzone("Crete");
|
|
g_vm->getHeroBelt()->setColour(HeroBelt::kWarm);
|
|
|
|
if (persistent->_creteDaedalusRoomAvailable) {
|
|
room->enableHotzone("Statue");
|
|
room->enableHotzone("Daedalus");
|
|
} else {
|
|
room->enableHotzone("Minos");
|
|
room->selectFrame(kAnimMinosEating, kMinosZ, 0);
|
|
g_vm->addTimer(kMinosPeriodic, 10000);
|
|
}
|
|
|
|
for (int i = kHornlessStatue1; i <= kHornedStatue; i++)
|
|
if (persistent->isInInventory((InventoryItem) i))
|
|
room->enableHotzone("Table");
|
|
|
|
room->enableHotzone("Guard");
|
|
room->selectFrame(kGuardLooking, kGuardZ, 0);
|
|
g_vm->addTimer(kGuardPeriodic, 5000);
|
|
|
|
if (!persistent->_creteMinosInstructed) {
|
|
playMinosMovie(
|
|
"MovMinosInstructions", kInstructionMovieCompleted,
|
|
Common::Point(210, 229));
|
|
persistent->_creteMinosInstructed = true;
|
|
persistent->_creteShowMerchant = true;
|
|
persistent->_creteIntroMerchant = true;
|
|
persistent->_creteShowHorned = true;
|
|
persistent->_creteShowHornless1 = true;
|
|
persistent->_creteShowHornless2 = true;
|
|
persistent->_creteShowHornless3 = true;
|
|
persistent->_creteShowHornless4 = true;
|
|
}
|
|
|
|
room->playMusic(persistent->isInInventory(kHornedStatue)
|
|
? "HornedIntroMusic" : "NormalIntroMusic");
|
|
|
|
if (persistent->_creteDaedalusRoomAvailable) {
|
|
room->selectFrame(kStatues, kInstalledStatueZ, 0, Common::Point(37, -110));
|
|
}
|
|
|
|
TextTable miAmb = TextTable(
|
|
Common::SharedPtr<Common::SeekableReadStream>(room->openFile("MiAmb.txt")), 6);
|
|
_ambients.readTableFilePriamSFX(miAmb);
|
|
g_vm->addTimer(14006, 100, -1);
|
|
_ambients.firstFrame();
|
|
}
|
|
|
|
private:
|
|
void scheduleNagging() {
|
|
g_vm->addTimer(kGuardNag, g_vm->getRnd().getRandomNumberRng(5000, 10000));
|
|
}
|
|
|
|
void playMinosMovie(const Common::String &name, int callback,
|
|
Common::Point offset) {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
room->setLayerEnabled(kAnimMinosEating, false);
|
|
room->playVideo(name, kMinosZ, callback, offset);
|
|
room->disableMouse();
|
|
_minosIsBusy = true;
|
|
}
|
|
|
|
void minosBackToIdle() {
|
|
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
|
_minosIsBusy = false;
|
|
room->enableMouse();
|
|
room->selectFrame(kAnimMinosEating, kMinosZ, 0);
|
|
}
|
|
|
|
bool _guardIsBusy;
|
|
bool _minosIsBusy;
|
|
AmbientAnimWeightedSet _ambients;
|
|
};
|
|
|
|
Common::SharedPtr<Hadesch::Handler> makeMinosHandler() {
|
|
return Common::SharedPtr<Hadesch::Handler>(new MinosHandler());
|
|
}
|
|
|
|
}
|