From 9c11611507f7669c16e955cd64a44f616b8efabe Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 13 Aug 2016 20:08:47 -0400 Subject: TITANIC: Implemented CDoorbot class --- engines/titanic/npcs/doorbot.cpp | 513 ++++++++++++++++++++++++++++++++++- engines/titanic/npcs/doorbot.h | 19 +- engines/titanic/npcs/true_talk_npc.h | 8 +- 3 files changed, 534 insertions(+), 6 deletions(-) (limited to 'engines/titanic/npcs') diff --git a/engines/titanic/npcs/doorbot.cpp b/engines/titanic/npcs/doorbot.cpp index 76db55f92c..8b98e0d0ef 100644 --- a/engines/titanic/npcs/doorbot.cpp +++ b/engines/titanic/npcs/doorbot.cpp @@ -21,15 +21,35 @@ */ #include "titanic/npcs/doorbot.h" +#include "titanic/titanic.h" namespace Titanic { +BEGIN_MESSAGE_MAP(CDoorbot, CTrueTalkNPC) + ON_MESSAGE(MovieEndMsg) + ON_MESSAGE(OnSummonBotMsg) + ON_MESSAGE(TrueTalkTriggerActionMsg) + ON_MESSAGE(DoorbotNeededInHomeMsg) + ON_MESSAGE(DoorbotNeededInElevatorMsg) + ON_MESSAGE(LeaveViewMsg) + ON_MESSAGE(TimerMsg) + ON_MESSAGE(NPCPlayTalkingAnimationMsg) + ON_MESSAGE(NPCPlayIdleAnimationMsg) + ON_MESSAGE(PutBotBackInHisBoxMsg) + ON_MESSAGE(DismissBotMsg) + ON_MESSAGE(MovieFrameMsg) + ON_MESSAGE(TrueTalkNotifySpeechEndedMsg) + ON_MESSAGE(TextInputMsg) + ON_MESSAGE(EnterViewMsg) + ON_MESSAGE(ActMsg) +END_MESSAGE_MAP() + int CDoorbot::_v1; int CDoorbot::_v2; CDoorbot::CDoorbot() : CTrueTalkNPC() { _field108 = 0; - _field10C = 0; + _timerId = 0; _field110 = 0; _field114 = 0; } @@ -40,7 +60,7 @@ void CDoorbot::save(SimpleFile *file, int indent) { file->writeNumberLine(_v2, indent); file->writeNumberLine(_field108, indent); - file->writeNumberLine(_field10C, indent); + file->writeNumberLine(_timerId, indent); file->writeNumberLine(_field110, indent); file->writeNumberLine(_field114, indent); @@ -53,11 +73,498 @@ void CDoorbot::load(SimpleFile *file) { _v2 = file->readNumber(); _field108 = file->readNumber(); - _field10C = file->readNumber(); + _timerId = file->readNumber(); _field110 = file->readNumber(); _field114 = file->readNumber(); CTrueTalkNPC::load(file); } +bool CDoorbot::MovieEndMsg(CMovieEndMsg *msg) { + if (_npcFlags & NPCFLAG_8000000) { + switch (_field108) { + case 3: + startTalking(this, 221482); + _field108 = 4; + break; + + case 6: + if (clipExistsByEnd("Cloak On", msg->_endFrame)) { + petShow(); + setState1C(true); + changeView("ServiceElevator.Node 1.S"); + changeView("ServiceElevator.Node 1.N"); + } + break; + + case 7: + startTalking(this, 221467); + _field108 = 8; + break; + + case 9: + startTalking(this, 221468); + break; + + case 11: + changeView("ServiceElevator.Node 1.S"); + changeView("MoonEmbLobby.Node 1.NE"); + break; + + default: + break; + } + + CTrueTalkNPC::MovieEndMsg(msg); + } else if (_npcFlags & NPCFLAG_100000) { + if (clipExistsByEnd("Cloak Off", msg->_endFrame)) { + _npcFlags = (_npcFlags & ~NPCFLAG_8) | NPCFLAG_4; + endTalking(this, false); + startTalking(this, 221474); + _npcFlags &= ~NPCFLAG_8000000; + _field108 = 0; + } else if (clipExistsByEnd("Cloak On", msg->_endFrame)) { + petShow(); + setState1C(true); + changeView("ServiceElevator.Node 1.S"); + } else { + CTrueTalkNPC::MovieEndMsg(msg); + } + } else if (_npcFlags & NPCFLAG_400000) { + if (clipExistsByEnd("Whizz On Left", msg->_endFrame) + || clipExistsByEnd("Whizz On Right", msg->_endFrame)) { + setPosition(Point((600 - _bounds.width()) / 2 + 18, 42)); + loadFrame(0); + endTalking(this, true); + _npcFlags |= NPCFLAG_4; + petSetArea(PET_CONVERSATION); + } else if (clipExistsByEnd("Whizz Off Left", msg->_endFrame) + || clipExistsByEnd("Whizz Off Right", msg->_endFrame)) { + CPutBotBackInHisBoxMsg boxMsg; + boxMsg.execute(this); + if (_npcFlags & NPCFLAG_4000000) + startAnimTimer("SummonBellbot", 1500); + } else { + CTrueTalkNPC::MovieEndMsg(msg); + } + } else { + CTrueTalkNPC::MovieEndMsg(msg); + } + + return true; +} + +bool CDoorbot::OnSummonBotMsg(COnSummonBotMsg *msg) { + const char *const ROOM_WAVES[8][2] = { + { "EmbLobby", "z#186.wav" }, + { "PromenadeDeck", "z#184.wav" }, + { "Arboretum", "z#188.wav" }, + { "Frozen Arboretum", "z#188.wav" }, + { "Bar", "z#187.wav" }, + { "MusicRoom", "z#185.wav" }, + { "MusicRoomLobby", "z#185.wav" }, + { "1stClassRestaurant", "z#183.wav" }, + }; + + if (msg->_value != -1) { + int idx; + for (idx = 0; idx < 8; ++idx) { + if (compareRoomNameTo(ROOM_WAVES[idx][0])) { + playSound(ROOM_WAVES[idx][1]); + + } + } + if (idx == 8) + playSound("z#146.wav"); + + sleep(2000); + } + + playClip(g_vm->getRandomNumber(1) ? "Whizz On Left" : "Whizz On Right", + MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + movieEvent(); + _npcFlags |= NPCFLAG_400000; + + return true; +} + +bool CDoorbot::TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg) { + switch (msg->_action) { + case 3: + playClip("Cloak On", MOVIE_NOTIFY_OBJECT); + break; + + case 4: + _npcFlags = (_npcFlags & ~NPCFLAG_2) | NPCFLAG_4000000; + playClip("Whizz Off Left", MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + break; + + case 28: { + _npcFlags &= ~(NPCFLAG_2 | NPCFLAG_4); + CDismissBotMsg dismissMsg; + dismissMsg.execute(this); + break; + } + } + + return true; +} + +bool CDoorbot::DoorbotNeededInHomeMsg(CDoorbotNeededInHomeMsg *msg) { + moveToView(); + setPosition(Point(90, 42)); + _npcFlags = NPCFLAG_100000; + + stopMovie(); + playClip("Cloak Off", MOVIE_NOTIFY_OBJECT); + + _npcFlags |= NPCFLAG_8; + return true; +} + +bool CDoorbot::DoorbotNeededInElevatorMsg(CDoorbotNeededInElevatorMsg *msg) { + moveToView("ServiceElevator.Node 1.N"); + setPosition(Point(100, 42)); + + if (_npcFlags & NPCFLAG_8000000) { + _field108 = 7; + _npcFlags |= NPCFLAG_200000; + loadFrame(797); + } else { + _npcFlags = 0; + if (msg->_value) + endTalking(this, true); + } + + return true; +} + +bool CDoorbot::LeaveViewMsg(CLeaveViewMsg *msg) { + if (!(_npcFlags & NPCFLAG_8000000) && (_npcFlags & NPCFLAG_400000)) { + performAction(true); + _npcFlags &= ~NPCFLAG_4; + } + + return true; +} + +bool CDoorbot::TimerMsg(CTimerMsg *msg) { + if (msg->_action == "NPCIdleAnim") { + return CTrueTalkNPC::TimerMsg(msg); + } else if (_npcFlags & NPCFLAG_8000000) { + switch (msg->_actionVal) { + case 0: + startTalking(this, 221475); + break; + + case 1: + startTalking(this, 221476); + break; + + case 2: + startTalking(this, 221477); + break; + + case 3: + playClip("DoubleTake Start", 0); + playClip("DoubleTake End", 0); + playClip("DoubleTake Start", 0); + playClip("DoubleTake End", MOVIE_NOTIFY_OBJECT); + _field108 = 3; + break; + + case 4: + startTalking(this, 221483); + lockInputHandler(); + _field114 = true; + break; + + case 5: + lockInputHandler(); + mouseLockE4(); + _field114 = true; + startTalking(this, 221485); + break; + + case 6: + CMouseButtonDownMsg::generate(); + mouseSaveState(200, 430, 2500); + _timerId = addTimer(7, 2500, 0); + break; + + case 7: + CMouseButtonDownMsg::generate(); + startTalking(this, 221486); + mouseUnlockE4(); + unlockInputHandler(); + _field114 = false; + disableMouse(); + break; + + default: + break; + } + } else if (msg->_action == "SummonBellbot") { + CRoomItem *room = getRoom(); + if (room) { + CSummonBotMsg botMsg; + botMsg._npcName = "Bellbot"; + botMsg.execute(room); + } + + _npcFlags &= ~NPCFLAG_4000000; + } + + return true; +} + +bool CDoorbot::NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg) { + const char *const NAMES1[] = { + "Mutter Aside", "Rub Chin", "Drunken Eye Roll", "Drunken Head Move", + "Look down and mutter", "Look side to side", "Gesture forward and around", + "Arms behind back", "Look down", "Rolling around", "Hold face", + "Touch chin", "Cross hands in front", nullptr + }; + const char *const NAMES2[] = { + "SE Talking 1", "SE Talking 2", "SE Talking 3", "SE Talking 4" + }; + const char *const NAMES3[] = { + "SE Ask For Help", nullptr + }; + + if (msg->_value2 != 2) { + if (_npcFlags & NPCFLAG_200000) { + if (_field108 == 8 || _field110) { + msg->_names = NAMES2; + } else if (_field108 == 9) { + msg->_names = NAMES3; + _field108 = 10; + } + } else if (_npcFlags & (NPCFLAG_100000 | NPCFLAG_400000)) { + msg->_names = NAMES1; + } + } + + return true; +} + +bool CDoorbot::NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg) { + const char *const NAMES[] = { + "Hand swivel", "Prompt Push", "Eye Roll", "Say something", nullptr + }; + + if (!(_npcFlags & (NPCFLAG_100000 | NPCFLAG_200000)) + && (_npcFlags & NPCFLAG_400000)) + msg->_names = NAMES; + + return true; +} + +bool CDoorbot::PutBotBackInHisBoxMsg(CPutBotBackInHisBoxMsg *msg) { + petMoveToHiddenRoom(); + _npcFlags &= ~(NPCFLAG_4 | NPCFLAG_100000 | NPCFLAG_200000 | NPCFLAG_8000000); + if (msg->_value) + performAction(true); + + return true; +} + +bool CDoorbot::DismissBotMsg(CDismissBotMsg *msg) { + if (_npcFlags & NPCFLAG_400000) { + playClip(g_vm->getRandomNumber(1) ? "Whizz Off Left" : "Whizz Off Right", + MOVIE_STOP_PREVIOUS | MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + movieEvent(); + + if (_npcFlags & NPCFLAG_4) { + _npcFlags &= ~NPCFLAG_4; + performAction(true); + } else { + performAction(false); + } + + CActMsg actMsg("DoorbotDismissed"); + actMsg.execute("BotIdleSummons"); + } + + return true; +} + +bool CDoorbot::MovieFrameMsg(CMovieFrameMsg *msg) { + if (clipExistsByStart("Whizz Off Left", msg->_frameNumber) + || clipExistsByStart("Whizz On Left", msg->_frameNumber)) { + setPosition(Point(20, 42)); + } else if (clipExistsByStart("Whizz Off Right", msg->_frameNumber) + || clipExistsByStart("Whizz On Right", msg->_frameNumber)) { + setPosition(Point(620 - _bounds.width(), 42)); + } + + return true; +} + +bool CDoorbot::TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg) { + if (_npcFlags & NPCFLAG_8000000) { + switch (msg->_dialogueId) { + case 10552: + playClip("SE Try Buttons", MOVIE_NOTIFY_OBJECT); + _field108 = 9; + break; + + case 10553: + enableMouse(); + break; + + case 10557: + playClip("SE Move To Right", MOVIE_NOTIFY_OBJECT); + _field108 = 11; + break; + + case 10559: + stopAnimTimer(_timerId); + _timerId = addTimer(0, 2500, 0); + break; + + case 10560: + petShow(); + petSetArea(PET_CONVERSATION); + stopAnimTimer(_timerId); + _timerId = addTimer(1, 1000, 0); + break; + + case 10561: + enableMouse(); + _field108 = 1; + stopAnimTimer(_timerId); + _timerId = addTimer(2, 10000, 0); + break; + + case 10562: + if (_field108 == 1) { + stopAnimTimer(_timerId); + _timerId = addTimer(2, g_vm->getRandomNumber(5000), 0); + } + break; + + case 10563: + case 10564: + disableMouse(); + startTalking(this, 221480); + break; + + case 10565: + startTalking(this, 221481); + break; + + case 10566: + stopAnimTimer(_timerId); + _timerId = 0; + if (_field110 == 2) { + playClip("Cloak On", MOVIE_NOTIFY_OBJECT); + _field108 = 6; + } else { + _timerId = addTimer(3, 2000, 0); + } + break; + + case 10567: { + CActMsg actMsg("BecomeGettable"); + actMsg.execute("Photograph"); + enableMouse(); + stopAnimTimer(_timerId); + _timerId = addTimer(4, 5000, 0); + break; + } + + case 10568: + mouseLockE4(); + mouseSaveState(600, 250, 2500); + _timerId = addTimer(6, 2500, 0); + break; + + case 10569: + if (_field110 != 2) { + stopAnimTimer(_timerId); + _timerId = addTimer(5, 3000, 0); + } + break; + + case 10570: + mouseSaveState(200, 430, 2500); + _timerId = addTimer(7, 3000, 0); + break; + + case 10571: + playClip("Cloak On", MOVIE_NOTIFY_OBJECT); + _field108 = 6; + break; + + default: + break; + } + } + + return true; +} + +bool CDoorbot::TextInputMsg(CTextInputMsg *msg) { + if (!(_npcFlags & NPCFLAG_8000000)) + return CTrueTalkNPC::TextInputMsg(msg); + + if (_field108 == 1) { + stopAnimTimer(_timerId); + _field108 = 2; + _timerId = 0; + + if (msg->_input == "yes" || msg->_input == "yeah" + || msg->_input == "yea" || msg->_input == "yup" + || msg->_input == "yep" || msg->_input == "sure" + || msg->_input == "alright" || msg->_input == "all right" + || msg->_input == "ok") { + startTalking(this, 221479); + } else { + startTalking(this, 221478); + } + } + + return true; +} + +bool CDoorbot::EnterViewMsg(CEnterViewMsg *msg) { + if ((_npcFlags & NPCFLAG_8000000) && _field108 == 7) + playClip("SE Move And Turn", MOVIE_NOTIFY_OBJECT); + + return true; +} + +bool CDoorbot::ActMsg(CActMsg *msg) { + if (msg->_action == "DoorbotPlayerPressedTopButton") { + disableMouse(); + startTalking(this, 221471); + } else if (msg->_action == "DoorbotPlayerPressedMiddleButton") { + startTalking(this, 221470); + } + else if (msg->_action == "DoorbotPlayerPressedBottomButton") { + startTalking(this, 221469); + } else if (msg->_action == "DoorbotReachedEmbLobby") { + startTalking(this, 221472); + } else if (msg->_action == "PlayerPicksUpPhoto") { + _field110 = 1; + if (!_field114 && _field108 == 4) { + stopAnimTimer(_timerId); + _timerId = 0; + _field108 = 5; + startTalking(this, 221484); + } + } else if (msg->_action == "PlayerPutsPhotoInPet") { + _field110 = 2; + if (!_field114 && _field108 == 5) { + stopAnimTimer(_timerId); + _timerId = 0; + startTalking(this, 221486); + disableMouse(); + } + } + + return true; +} + } // End of namespace Titanic diff --git a/engines/titanic/npcs/doorbot.h b/engines/titanic/npcs/doorbot.h index b62026c7d9..9095ebc7e7 100644 --- a/engines/titanic/npcs/doorbot.h +++ b/engines/titanic/npcs/doorbot.h @@ -28,12 +28,29 @@ namespace Titanic { class CDoorbot : public CTrueTalkNPC { + DECLARE_MESSAGE_MAP; + bool MovieEndMsg(CMovieEndMsg *msg); + bool OnSummonBotMsg(COnSummonBotMsg *msg); + bool TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg); + bool DoorbotNeededInHomeMsg(CDoorbotNeededInHomeMsg *msg); + bool DoorbotNeededInElevatorMsg(CDoorbotNeededInElevatorMsg *msg); + bool LeaveViewMsg(CLeaveViewMsg *msg); + bool TimerMsg(CTimerMsg *msg); + bool NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg); + bool NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg); + bool PutBotBackInHisBoxMsg(CPutBotBackInHisBoxMsg *msg); + bool DismissBotMsg(CDismissBotMsg *msg); + bool MovieFrameMsg(CMovieFrameMsg *msg); + bool TrueTalkNotifySpeechEndedMsg(CTrueTalkNotifySpeechEndedMsg *msg); + bool TextInputMsg(CTextInputMsg *msg); + bool EnterViewMsg(CEnterViewMsg *msg); + bool ActMsg(CActMsg *msg); private: static int _v1; static int _v2; private: int _field108; - int _field10C; + int _timerId; int _field110; int _field114; public: diff --git a/engines/titanic/npcs/true_talk_npc.h b/engines/titanic/npcs/true_talk_npc.h index 6a4e65035e..ea6cbb3f84 100644 --- a/engines/titanic/npcs/true_talk_npc.h +++ b/engines/titanic/npcs/true_talk_npc.h @@ -31,8 +31,12 @@ namespace Titanic { enum NpcFlag { NPCFLAG_SPEAKING = 1, NPCFLAG_2 = 2, NPCFLAG_4 = 4, NPCFLAG_8 = 8, - NPCFLAG_10000 = 0x10000, NPCFLAG_20000 = 0x20000, NPCFLAG_40000 = 0x40000, - NPCFLAG_80000 = 0x80000, NPCFLAG_100000 = 0x100000 + NPCFLAG_10000 = 0x10000, NPCFLAG_20000 = 0x20000, + NPCFLAG_40000 = 0x40000, NPCFLAG_80000 = 0x80000, + NPCFLAG_100000 = 0x100000, NPCFLAG_200000 = 0x200000, + NPCFLAG_400000 = 0x400000, NPCFLAG_800000 = 0x800000, + NPCFLAG_1000000 = 0x1000000, NPCFLAG_2000000 = 0x2000000, + NPCFLAG_4000000 = 0x4000000, NPCFLAG_8000000 = 0x8000000 }; class CViewItem; -- cgit v1.2.3