Initial commit
This commit is contained in:
362
engines/hadesch/rooms/argo.cpp
Normal file
362
engines/hadesch/rooms/argo.cpp
Normal file
@@ -0,0 +1,362 @@
|
||||
/* 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"
|
||||
|
||||
namespace Hadesch {
|
||||
|
||||
static const char *kIslandNames = "islandnames";
|
||||
static const char *kMastHeadAnim = "mastheadanim";
|
||||
|
||||
enum {
|
||||
kSkyZ = 10200,
|
||||
kCloudsZ = 10100,
|
||||
kWavesRightZ = 10050,
|
||||
kWavesLeftZ = 10050,
|
||||
kBackgroundZ = 10000,
|
||||
kFlagsZ = 9000,
|
||||
kMastHeadZ = 8000,
|
||||
kChessPieceZ = 701,
|
||||
kIslandNamesZ = 601
|
||||
};
|
||||
|
||||
static const struct island {
|
||||
const char *hotname;
|
||||
const char *mouseoverAnim;
|
||||
TranscribedSound nameSound;
|
||||
const char *sfxSound;
|
||||
RoomId roomId;
|
||||
int zValue;
|
||||
} islands[] = {
|
||||
{"Phils", "a1030bh0", {"a1030nf0", _hs("Phil's") }, "a1030ef0", kWallOfFameRoom, 901},
|
||||
{"Medusa", "a1030bf0", {"a1030nc0", _hs("Medusa Isle")}, "a1030ed0", kMedIsleRoom, 901},
|
||||
{"Troy", "a1030bd0", {"a1030na0", _hs("Troy")}, "a1030eb0", kTroyRoom, 901},
|
||||
{"Seriphos", "a1030be0", {"a1030nd0", _hs("Seriphos")}, "a1030ec0", kSeriphosRoom, 801},
|
||||
{"Crete", "a1030bc0", {"a1030nb0", _hs("Crete")}, "a1030ea0", kCreteRoom, 801},
|
||||
{"Volcano", "a1030bg0", {"a1030ne0", _hs("Volcano island")}, "a1030ee0", kVolcanoRoom, 801},
|
||||
};
|
||||
|
||||
static const int nislands = ARRAYSIZE(islands);
|
||||
|
||||
static const TranscribedSound intros[] = {
|
||||
{ "a1150na0", _hs("Aye, welcome onboard ladie") },
|
||||
{ "a1150nb0", _hs("So, are you hero yet?") },
|
||||
{ "a1150nc0", _hs("So, are you heroine yet?") },
|
||||
{ "a1150nd0", _hs("So, made it back, you did? Frankly, I'm surprised") },
|
||||
{ "a1150ne0", _hs("Glad I'm, you're still alive. I hate sailing alone") },
|
||||
{ "a1150nf0", _hs("So where will we be headed now?") }
|
||||
};
|
||||
|
||||
static const TranscribedSound defaultOutros[] = {
|
||||
{ "a1170na0", _hs("Heave anchor") },
|
||||
{ "a1170nb0", _hs("Hurry, hoist the main") },
|
||||
{ "a1170nc0", _hs("All hands on deck. Man the sails") },
|
||||
{ "a1170nd0", _hs("Pull her to starboard and bring her around") },
|
||||
{ "a1170ne0", _hs("Pull back on that rudder. Hold her steady") }
|
||||
};
|
||||
|
||||
enum {
|
||||
kPlayIntro2 = 27001,
|
||||
kPlayIntro3 = 27002,
|
||||
kReturnToIdleEvent = 27003,
|
||||
kIdleEvent = 27008,
|
||||
kOutroFinished = 27009,
|
||||
kOutroFinishedCounter = 1027001,
|
||||
kMastSoundFinished = 1027002
|
||||
};
|
||||
|
||||
static const TranscribedSound
|
||||
getOutroName(RoomId dest) {
|
||||
Persistent *persistent = g_vm->getPersistent();
|
||||
Quest quest = persistent->_quest;
|
||||
|
||||
switch (dest) {
|
||||
case kWallOfFameRoom:
|
||||
if (!persistent->_argoSailedInQuest[dest][quest])
|
||||
return TranscribedSound::make("philsfirst", "That'd be where the grand heroes and heroines of the world go to train");
|
||||
break;
|
||||
case kSeriphosRoom:
|
||||
if ((quest == kTroyQuest || quest == kCreteQuest) && !persistent->_argoSailedInQuest[dest][quest])
|
||||
return TranscribedSound::make("seriphoscretetroy", "This place be ruled by the evil tyrant king Polydectes");
|
||||
if (quest == kMedusaQuest && !persistent->_argoSailedInQuest[dest][quest])
|
||||
return TranscribedSound::make("seriphosperseus", "Arr, Perseus be in trouble deep. Could use a hand");
|
||||
break;
|
||||
case kMedIsleRoom:
|
||||
if (quest == kMedusaQuest && !persistent->_argoSailedInQuest[dest][quest])
|
||||
return TranscribedSound::make("medusabeware", "Beware of Medusa. She be one scary looking lady. All her mirrors be made of shatter-proof glass");
|
||||
break;
|
||||
case kTroyRoom:
|
||||
if (!persistent->isRoomVisited(kTroyRoom))
|
||||
return TranscribedSound::make("troytenyears", "For ten years now trojan and greek soldiers have been fighting that trojan war. Talk about job security");
|
||||
if (quest == kTroyQuest && !persistent->_argoSailedInQuest[dest][quest])
|
||||
return TranscribedSound::make("troyregards", "Send me regards to Odysseus");
|
||||
if (quest > kTroyQuest && !persistent->_argoSaidTroyFinally) {
|
||||
persistent->_argoSaidTroyFinally = true;
|
||||
return TranscribedSound::make("troyfinally", "Finally, the trojan war be over and Helen be back with Menelaus. Now those two can fight without an interruption");
|
||||
}
|
||||
break;
|
||||
case kCreteRoom:
|
||||
if (!persistent->isRoomVisited(kCreteRoom))
|
||||
return TranscribedSound::make("cretedaedalus", "This be where Daedalus, the inventor, lives");
|
||||
|
||||
if (quest != kCreteQuest && !persistent->_argoSaidCretePort)
|
||||
return TranscribedSound::make("creteport", "Crete, the famous international port of trade");
|
||||
break;
|
||||
case kVolcanoRoom:
|
||||
if (!persistent->isRoomVisited(kVolcanoRoom))
|
||||
return TranscribedSound::make("volcanotopfirst", "Know this: should you go down there, you may not come back");
|
||||
|
||||
if (quest == kRescuePhilQuest && !!persistent->_argoSailedInQuest[dest][quest])
|
||||
return TranscribedSound::make("volcanotopyoufirst", "Hah, many are monsters down there. Very dangerous. You go first");
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
int rnd = g_vm->getRnd().getRandomNumberRng(0, ARRAYSIZE(defaultOutros) - 1);
|
||||
debug("rnd = %d", rnd);
|
||||
return defaultOutros[rnd];
|
||||
}
|
||||
|
||||
class ArgoHandler : public Handler {
|
||||
public:
|
||||
ArgoHandler() {
|
||||
_prevId = kInvalidRoom;
|
||||
_destination = kInvalidRoom;
|
||||
_mastHeadIsBusy = false;
|
||||
}
|
||||
void handleClick(const Common::String &name) override {
|
||||
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
||||
_destination = kInvalidRoom;
|
||||
for (unsigned i = 0; i < nislands; i++) {
|
||||
if (name == islands[i].hotname) {
|
||||
_destination = islands[i].roomId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_destination != kInvalidRoom) {
|
||||
Persistent *persistent = g_vm->getPersistent();
|
||||
room->disableMouse();
|
||||
room->stopAnim("idlesound");
|
||||
if (_destination == _prevId) {
|
||||
playMastSound(TranscribedSound::make(
|
||||
"currentlocation",
|
||||
"Here be your current location, matie."),
|
||||
kOutroFinished);
|
||||
return;
|
||||
}
|
||||
|
||||
_outroCounter = 4;
|
||||
_cloudsMoving = true;
|
||||
_cloudsMoveStart = g_vm->getCurrentTime();
|
||||
playMastSound(getOutroName(_destination), kOutroFinishedCounter);
|
||||
room->playAnimWithSFX("wavesleft", "wavesleftSFX", kWavesLeftZ,
|
||||
PlayAnimParams::disappear(),
|
||||
kOutroFinishedCounter);
|
||||
room->playAnimWithSFX("wavesright", "wavesrightSFX", kWavesRightZ,
|
||||
PlayAnimParams::disappear(),
|
||||
kOutroFinishedCounter);
|
||||
room->playSFX("A1030eG0", kOutroFinishedCounter);
|
||||
persistent->_argoSailedInQuest[_destination][persistent->_quest] = true;
|
||||
}
|
||||
}
|
||||
void handleEvent(int eventId) override {
|
||||
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
||||
switch (eventId) {
|
||||
case kPlayIntro2:
|
||||
playMastSound(TranscribedSound::make("intro2", "Navigate by clicking on the island you want to go to"), kPlayIntro3);
|
||||
break;
|
||||
case kPlayIntro3:
|
||||
playMastSound(TranscribedSound::make(
|
||||
"intro3",
|
||||
"The map shall always show the location of the Argo in relation to the other islands in the region"),
|
||||
kReturnToIdleEvent);
|
||||
break;
|
||||
case kReturnToIdleEvent:
|
||||
_mastHeadIsBusy = false;
|
||||
room->enableMouse();
|
||||
break;
|
||||
case kOutroFinishedCounter:
|
||||
if (--_outroCounter > 0)
|
||||
break;
|
||||
// Fallthrough
|
||||
case kOutroFinished:
|
||||
room->selectFrame(kMastHeadAnim, kMastHeadZ, 0);
|
||||
g_vm->moveToRoom(_destination);
|
||||
break;
|
||||
case kIdleEvent:
|
||||
g_vm->addTimer(kIdleEvent, 30000);
|
||||
if (_mastHeadIsBusy)
|
||||
break;
|
||||
playMastSound(TranscribedSound::make("idlesound", "And what course lies ahead for you, matie?"), kMastSoundFinished);
|
||||
room->selectFrame(kMastHeadAnim, kMastHeadZ, 1);
|
||||
break;
|
||||
case 27301:
|
||||
room->playAnimWithSpeech(kMastHeadAnim, _mastSound, kMastHeadZ,
|
||||
PlayAnimParams::keepLastFrame().partial(8, 21), 27303);
|
||||
break;
|
||||
// 27302 was for event chaining and frame keeping
|
||||
case 27303:
|
||||
room->playAnim(kMastHeadAnim, kMastHeadZ,
|
||||
PlayAnimParams::keepLastFrame().partial(8, 0), _mastHeadEndEvent);
|
||||
break;
|
||||
case kMastSoundFinished:
|
||||
_mastHeadIsBusy = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
void handleMouseOver(const Common::String &name) override {
|
||||
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
||||
for (unsigned i = 0; i < nislands; i++) {
|
||||
if (name == islands[i].hotname) {
|
||||
room->selectFrame(kIslandNames, kIslandNamesZ, i);
|
||||
room->playAnimKeepLastFrame(islands[i].mouseoverAnim, islands[i].zValue);
|
||||
playMastSound(islands[i].nameSound);
|
||||
room->playSFXLoop(islands[i].sfxSound);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handleMouseOut(const Common::String &name) override {
|
||||
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
||||
for (unsigned i = 0; i < nislands; i++)
|
||||
if (name == islands[i].hotname) {
|
||||
if (_destination != islands[i].roomId) {
|
||||
room->stopAnim(kIslandNames);
|
||||
room->stopAnim(islands[i].mouseoverAnim);
|
||||
}
|
||||
room->stopAnim(islands[i].nameSound.soundName);
|
||||
room->stopAnim(islands[i].sfxSound);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void prepareRoom() override {
|
||||
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
||||
Persistent *persistent = g_vm->getPersistent();
|
||||
_prevId = g_vm->getPreviousRoomId();
|
||||
room->loadHotZones("argo.HOT");
|
||||
room->addStaticLayer("background", kBackgroundZ);
|
||||
Common::String sky;
|
||||
int chesspiece;
|
||||
Common::String bgsound;
|
||||
|
||||
switch (_prevId) {
|
||||
default:
|
||||
sky = "bluesky";
|
||||
chesspiece = 0;
|
||||
bgsound = "a1180ea0";
|
||||
break;
|
||||
case kSeriphosRoom:
|
||||
sky = "pinksky";
|
||||
chesspiece = 3;
|
||||
bgsound = "A1070eA0";
|
||||
break;
|
||||
case kMedIsleRoom:
|
||||
sky = "mauvesky";
|
||||
chesspiece = 1;
|
||||
bgsound = "a1210ea0";
|
||||
break;
|
||||
case kTroyRoom:
|
||||
sky = "goldsky";
|
||||
chesspiece = 2;
|
||||
bgsound = "a1190eb0";
|
||||
break;
|
||||
case kCreteRoom:
|
||||
sky = "bluesky";
|
||||
chesspiece = 4;
|
||||
bgsound = "a1180ea0";
|
||||
break;
|
||||
case kVolcanoRoom:
|
||||
sky = "pinksky";
|
||||
chesspiece = 5;
|
||||
bgsound = "a1210ea0";
|
||||
break;
|
||||
}
|
||||
room->addStaticLayer(sky, kSkyZ);
|
||||
room->playMusicLoop(bgsound);
|
||||
|
||||
room->selectFrame("chesspiece", kChessPieceZ, chesspiece);
|
||||
|
||||
room->disableMouse();
|
||||
// Originally event 4015
|
||||
if (!persistent->isRoomVisited(kArgoRoom))
|
||||
playMastSound(TranscribedSound::make(
|
||||
"intro1",
|
||||
"Sharpen up now, matie. You'll be on the Argo now. It's a hero of ships. It used to belong to Jason and his crew, the argonauts. And now it'll be here for you"),
|
||||
kPlayIntro2);
|
||||
else {
|
||||
int rnd = g_vm->getRnd().getRandomNumberRng(0, ARRAYSIZE(intros) - 1);
|
||||
debug("rnd = %d", rnd);
|
||||
if (rnd == 1 || rnd == 2)
|
||||
rnd = persistent->_gender == kFemale ? 2 : 1;
|
||||
playMastSound(intros[rnd], kReturnToIdleEvent);
|
||||
}
|
||||
|
||||
room->playAnimWithSFX("flags", "flagsSFX", kFlagsZ, PlayAnimParams::loop());
|
||||
g_vm->addTimer(kIdleEvent, 30000);
|
||||
g_vm->getHeroBelt()->setColour(HeroBelt::kCool);
|
||||
room->playMusic("intromusic");
|
||||
_cloudsMoving = false;
|
||||
cloudMove(0);
|
||||
}
|
||||
|
||||
void frameCallback() override {
|
||||
if (_cloudsMoving) {
|
||||
cloudMove(g_vm->getCurrentTime() - _cloudsMoveStart);
|
||||
}
|
||||
}
|
||||
|
||||
void cloudMove(int cloudMoveTime) {
|
||||
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
||||
double div = cloudMoveTime / 15000.0;
|
||||
room->selectFrame("cloudright", kCloudsZ, 0, Common::Point(450, 0) + Common::Point(650, -50) * div);
|
||||
room->selectFrame("cloudmiddle", kCloudsZ, 1, Common::Point(220, 0) + Common::Point(220, -50) * div);
|
||||
room->selectFrame("cloudleft", kCloudsZ, 2, Common::Point(0, 0) + Common::Point(-200, -50) * div);
|
||||
}
|
||||
|
||||
private:
|
||||
void playMastSound(const TranscribedSound &sound, int event = kMastSoundFinished) {
|
||||
Common::SharedPtr<VideoRoom> room = g_vm->getVideoRoom();
|
||||
_mastSound = sound;
|
||||
_mastHeadEndEvent = event;
|
||||
_mastHeadIsBusy = true;
|
||||
room->playAnim(kMastHeadAnim, kMastHeadZ, PlayAnimParams::keepLastFrame().partial(1, 8), 27301);
|
||||
}
|
||||
|
||||
RoomId _prevId;
|
||||
RoomId _destination;
|
||||
int _outroCounter;
|
||||
int _cloudsMoveStart;
|
||||
bool _cloudsMoving;
|
||||
int _mastHeadEndEvent;
|
||||
bool _mastHeadIsBusy;
|
||||
TranscribedSound _mastSound;
|
||||
};
|
||||
|
||||
Common::SharedPtr<Hadesch::Handler> makeArgoHandler() {
|
||||
return Common::SharedPtr<Hadesch::Handler>(new ArgoHandler());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user