From 8f29f067a41548da7625ebfec43e7ca8f22dfe4a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 27 Aug 2016 22:51:33 -0400 Subject: TITANIC: Implemented more game classes --- engines/titanic/game/season_background.cpp | 103 +++++++++- engines/titanic/game/season_background.h | 13 +- engines/titanic/game/season_barrel.cpp | 27 ++- engines/titanic/game/season_barrel.h | 9 +- engines/titanic/game/service_elevator_window.cpp | 63 ++++++ engines/titanic/game/service_elevator_window.h | 4 + .../titanic/game/transport/service_elevator.cpp | 227 ++++++++++++++++++++- engines/titanic/game/transport/service_elevator.h | 16 +- engines/titanic/messages/service_elevator_door.cpp | 10 + engines/titanic/messages/service_elevator_door.h | 2 + engines/titanic/npcs/mobile.h | 2 +- engines/titanic/npcs/true_talk_npc.h | 10 +- 12 files changed, 447 insertions(+), 39 deletions(-) diff --git a/engines/titanic/game/season_background.cpp b/engines/titanic/game/season_background.cpp index 1c63f3d892..20ad6aca1d 100644 --- a/engines/titanic/game/season_background.cpp +++ b/engines/titanic/game/season_background.cpp @@ -24,28 +24,113 @@ namespace Titanic { +BEGIN_MESSAGE_MAP(CSeasonBackground, CBackground) + ON_MESSAGE(EnterViewMsg) + ON_MESSAGE(ChangeSeasonMsg) + ON_MESSAGE(MovieEndMsg) + ON_MESSAGE(ActMsg) +END_MESSAGE_MAP() + CSeasonBackground::CSeasonBackground() : CBackground(), - _fieldE0(0), _fieldE4(0), _fieldE8(46), _fieldEC(0) { + _seasonNum(SEASON_SUMMER), _flag(false), _defaultFrame(46), _unused(0) { } void CSeasonBackground::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); - file->writeNumberLine(_fieldE0, indent); - file->writeNumberLine(_fieldE4, indent); - file->writeNumberLine(_fieldE8, indent); - file->writeNumberLine(_fieldEC, indent); + file->writeNumberLine(_seasonNum, indent); + file->writeNumberLine(_flag, indent); + file->writeNumberLine(_defaultFrame, indent); + file->writeNumberLine(_unused, indent); CBackground::save(file, indent); } void CSeasonBackground::load(SimpleFile *file) { file->readNumber(); - _fieldE0 = file->readNumber(); - _fieldE4 = file->readNumber(); - _fieldE8 = file->readNumber(); - _fieldEC = file->readNumber(); + _seasonNum = (Season)file->readNumber(); + _flag = file->readNumber(); + _defaultFrame = file->readNumber(); + _unused = file->readNumber(); CBackground::load(file); } +bool CSeasonBackground::EnterViewMsg(CEnterViewMsg *msg) { + loadFrame(_defaultFrame); + return true; +} + +bool CSeasonBackground::ChangeSeasonMsg(CChangeSeasonMsg *msg) { + _seasonNum = (Season)(((int)_seasonNum + 1) % 4); + + switch (_seasonNum) { + case SEASON_SUMMER: + playMovie(0, 45, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + _defaultFrame = 45; + break; + + case SEASON_AUTUMN: + if (_flag) { + playMovie(232, 278, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + _defaultFrame = 278; + } else { + playMovie(45, 91, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + _defaultFrame = 91; + } + break; + + case SEASON_WINTER: + if (_flag) { + playMovie(278, 326, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + _defaultFrame = 326; + } else { + CStatusChangeMsg changeMsg; + changeMsg._newStatus = 0; + changeMsg.execute("PickUpSpeechCentre"); + playMovie(91, 139, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + _defaultFrame = 139; + } + break; + + case SEASON_SPRING: + if (_flag) { + playMovie(326, 417, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + _defaultFrame = 417; + } else { + playMovie(139, 228, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE); + _defaultFrame = 228; + } + break; + + default: + break; + } + + return true; +} + +bool CSeasonBackground::MovieEndMsg(CMovieEndMsg *msg) { + if (msg->_endFrame == _defaultFrame) { + CTurnOn onMsg; + onMsg.execute("SeasonalAdjust"); + } + + if (msg->_endFrame == 91 && !_flag) { + CStatusChangeMsg changeMsg; + changeMsg.execute("PickUpSpeechCentre"); + } + + return true; +} + +bool CSeasonBackground::ActMsg(CActMsg *msg) { + if (msg->_action == "PlayerGetsSpeechCentre") { + loadFrame(278); + _defaultFrame = 278; + _flag = true; + } + + return true; +} + } // End of namespace Titanic diff --git a/engines/titanic/game/season_background.h b/engines/titanic/game/season_background.h index f0fd2cdc63..d30fd7aedc 100644 --- a/engines/titanic/game/season_background.h +++ b/engines/titanic/game/season_background.h @@ -28,11 +28,16 @@ namespace Titanic { class CSeasonBackground : public CBackground { + DECLARE_MESSAGE_MAP; + bool EnterViewMsg(CEnterViewMsg *msg); + bool ChangeSeasonMsg(CChangeSeasonMsg *msg); + bool MovieEndMsg(CMovieEndMsg *msg); + bool ActMsg(CActMsg *msg); public: - int _fieldE0; - int _fieldE4; - int _fieldE8; - int _fieldEC; + Season _seasonNum; + bool _flag; + int _defaultFrame; + int _unused; public: CLASSDEF; CSeasonBackground(); diff --git a/engines/titanic/game/season_barrel.cpp b/engines/titanic/game/season_barrel.cpp index 9594396885..e08cdf323b 100644 --- a/engines/titanic/game/season_barrel.cpp +++ b/engines/titanic/game/season_barrel.cpp @@ -24,19 +24,38 @@ namespace Titanic { +BEGIN_MESSAGE_MAP(CSeasonBarrel, CBackground) + ON_MESSAGE(ChangeSeasonMsg) + ON_MESSAGE(EnterViewMsg) +END_MESSAGE_MAP() + void CSeasonBarrel::save(SimpleFile *file, int indent) { file->writeNumberLine(1, indent); - file->writeNumberLine(_fieldE0, indent); - file->writeNumberLine(_fieldE4, indent); + file->writeNumberLine(_unused, indent); + file->writeNumberLine(_startFrame, indent); CBackground::save(file, indent); } void CSeasonBarrel::load(SimpleFile *file) { file->readNumber(); - _fieldE0 = file->readNumber(); - _fieldE4 = file->readNumber(); + _unused = file->readNumber(); + _startFrame = file->readNumber(); CBackground::load(file); } +bool CSeasonBarrel::ChangeSeasonMsg(CChangeSeasonMsg *msg) { + if (_startFrame >= 28) + _startFrame = 0; + + playMovie(_startFrame, _startFrame + 7, 0); + _startFrame += 7; + return true; +} + +bool CSeasonBarrel::EnterViewMsg(CEnterViewMsg *msg) { + loadFrame(_startFrame); + return true; +} + } // End of namespace Titanic diff --git a/engines/titanic/game/season_barrel.h b/engines/titanic/game/season_barrel.h index f77864599d..6296b6f7b1 100644 --- a/engines/titanic/game/season_barrel.h +++ b/engines/titanic/game/season_barrel.h @@ -28,12 +28,15 @@ namespace Titanic { class CSeasonBarrel : public CBackground { + DECLARE_MESSAGE_MAP; + bool ChangeSeasonMsg(CChangeSeasonMsg *msg); + bool EnterViewMsg(CEnterViewMsg *msg); public: - int _fieldE0; - int _fieldE4; + int _unused; + int _startFrame; public: CLASSDEF; - CSeasonBarrel() : CBackground(), _fieldE0(0), _fieldE4(7) {} + CSeasonBarrel() : CBackground(), _unused(0), _startFrame(7) {} /** * Save the data for the class to file diff --git a/engines/titanic/game/service_elevator_window.cpp b/engines/titanic/game/service_elevator_window.cpp index 95b2735b37..b0cc53abb4 100644 --- a/engines/titanic/game/service_elevator_window.cpp +++ b/engines/titanic/game/service_elevator_window.cpp @@ -21,9 +21,19 @@ */ #include "titanic/game/service_elevator_window.h" +#include "titanic/core/room_item.h" +#include "titanic/npcs/doorbot.h" namespace Titanic { +BEGIN_MESSAGE_MAP(CServiceElevatorWindow, CBackground) + ON_MESSAGE(ServiceElevatorFloorChangeMsg) + ON_MESSAGE(MovieEndMsg) + ON_MESSAGE(EnterViewMsg) +END_MESSAGE_MAP() + +static const int FACTORS[4] = { 0, 20, 100, 0 }; + CServiceElevatorWindow::CServiceElevatorWindow() : CBackground(), _fieldE0(0), _fieldE4(0), _fieldE8(0), _fieldEC(0) { } @@ -48,4 +58,57 @@ void CServiceElevatorWindow::load(SimpleFile *file) { CBackground::load(file); } +bool CServiceElevatorWindow::ServiceElevatorFloorChangeMsg(CServiceElevatorFloorChangeMsg *msg) { + if (getView() == findView()) { + CDoorbot *doorbot = dynamic_cast(findRoom()->findByName("Doorbot")); + int val = (_fieldE8 && doorbot) ? 65 : 15; + CMovieClip *clip = _movieClips.findByName("Going Up"); + + if (!clip) + return true; + + int count = _endFrame - _startFrame; + setMovieFrameRate(1.0 * count / val); + + int startFrame = clip->_startFrame + count * FACTORS[msg->_value1] / 100; + int endFrame = clip->_startFrame + count * FACTORS[msg->_value2] / 100; + + if (_fieldE4) { + playMovie(startFrame, endFrame, MOVIE_NOTIFY_OBJECT); + } else { + playMovie(startFrame, endFrame, 0); + if (_fieldEC) + playClip("Into Space"); + } + } + + _fieldE0 = msg->_value2; + return true; +} + +bool CServiceElevatorWindow::MovieEndMsg(CMovieEndMsg *msg) { + CServiceElevatorMsg elevMsg(5); + elevMsg.execute(findRoom()->findByName("Service Elevator Entity")); + return true; +} + +bool CServiceElevatorWindow::EnterViewMsg(CEnterViewMsg *msg) { + if (_fieldEC) { + playClip("Fade Up"); + playMovie(1, 2, 0); + } else { + CMovieClip *clip = _movieClips.findByName("Going Up"); + + if (clip) { + int frameNum = clip->_startFrame + (clip->_endFrame - clip->_startFrame) + * FACTORS[_fieldE0] / 100; + loadFrame(frameNum); + } else { + loadFrame(0); + } + } + + return true; +} + } // End of namespace Titanic diff --git a/engines/titanic/game/service_elevator_window.h b/engines/titanic/game/service_elevator_window.h index 4233b8405a..88e1663aba 100644 --- a/engines/titanic/game/service_elevator_window.h +++ b/engines/titanic/game/service_elevator_window.h @@ -28,6 +28,10 @@ namespace Titanic { class CServiceElevatorWindow : public CBackground { + DECLARE_MESSAGE_MAP; + bool ServiceElevatorFloorChangeMsg(CServiceElevatorFloorChangeMsg *msg); + bool MovieEndMsg(CMovieEndMsg *msg); + bool EnterViewMsg(CEnterViewMsg *msg); public: int _fieldE0; int _fieldE4; diff --git a/engines/titanic/game/transport/service_elevator.cpp b/engines/titanic/game/transport/service_elevator.cpp index 1ea8d14e36..1980825cb6 100644 --- a/engines/titanic/game/transport/service_elevator.cpp +++ b/engines/titanic/game/transport/service_elevator.cpp @@ -21,15 +21,27 @@ */ #include "titanic/game/transport/service_elevator.h" +#include "titanic/core/room_item.h" +#include "titanic/npcs/doorbot.h" -namespace Titanic { +namespace Titanic { -int CServiceElevator::_v1; +BEGIN_MESSAGE_MAP(CServiceElevator, CTransport) + ON_MESSAGE(BodyInBilgeRoomMsg) + ON_MESSAGE(EnterViewMsg) + ON_MESSAGE(ServiceElevatorMsg) + ON_MESSAGE(TimerMsg) + ON_MESSAGE(ServiceElevatorFloorRequestMsg) + ON_MESSAGE(LeaveRoomMsg) + ON_MESSAGE(OpeningCreditsMsg) +END_MESSAGE_MAP() + +bool CServiceElevator::_v1; int CServiceElevator::_v2; int CServiceElevator::_v3; CServiceElevator::CServiceElevator() : CTransport(), - _fieldF8(0), _fieldFC(0), _field100(0), _field104(0) { + _fieldF8(0), _soundHandle1(0), _timerId(0), _soundHandle2(0) { } void CServiceElevator::save(SimpleFile *file, int indent) { @@ -38,9 +50,9 @@ void CServiceElevator::save(SimpleFile *file, int indent) { file->writeNumberLine(_v2, indent); file->writeNumberLine(_v3, indent); file->writeNumberLine(_fieldF8, indent); - file->writeNumberLine(_fieldFC, indent); - file->writeNumberLine(_field100, indent); - file->writeNumberLine(_field104, indent); + file->writeNumberLine(_soundHandle1, indent); + file->writeNumberLine(_timerId, indent); + file->writeNumberLine(_soundHandle2, indent); CTransport::save(file, indent); } @@ -51,11 +63,208 @@ void CServiceElevator::load(SimpleFile *file) { _v2 = file->readNumber(); _v3 = file->readNumber(); _fieldF8 = file->readNumber(); - _fieldFC = file->readNumber(); - _field100 = file->readNumber(); - _field104 = file->readNumber(); + _soundHandle1 = file->readNumber(); + _timerId = file->readNumber(); + _soundHandle2 = file->readNumber(); CTransport::load(file); } +bool CServiceElevator::BodyInBilgeRoomMsg(CBodyInBilgeRoomMsg *msg) { + _v2 = true; + _string1 = "BilgeRoomWith.Node 2.N"; + return true; +} + +bool CServiceElevator::EnterViewMsg(CEnterViewMsg *msg) { + petShow(); + return true; +} + +bool CServiceElevator::ServiceElevatorMsg(CServiceElevatorMsg *msg) { + switch (msg->_value) { + case 1: + case 2: + case 3: { + switch (msg->_value) { + case 1: + _v3 = 0; + break; + case 2: + _v3 = 1; + break; + case 3: + _v3 = 2; + break; + } + + CServiceElevatorFloorRequestMsg requestMsg; + requestMsg.execute(this); + break; + } + + case 4: + if (!_string1.empty()) { + if (_string1 == "DeepSpace") { + disableMouse(); + _soundHandle1 = playSound("z#413.wav", 50); + _timerId = addTimer(1, 1000, 500); + } else { + changeView(_string1); + } + } + break; + + case 5: + _fieldF8 = false; + _fieldDC = _v3; + loadSound("z#423.wav"); + stopSound(_soundHandle2); + _soundHandle2 = playSound("z#423.wav", 80); + + switch (_fieldDC) { + case 0: + _string1 = "DeepSpace"; + _string2 = "a#2.wav"; + queueSound("z#416.wav", _soundHandle2, 50); + break; + + case 1: + _string1 = _v2 ? "BilgeRoomWith.Node 2.N" : "BilgeRoom.Node 1.N"; + queueSound("z#421.wav", _soundHandle2, 50); + break; + + case 2: + _string1 = _v1 ? "MoonEmbLobby.Node 1.NE" : "EmbLobby.Node 1.NE"; + queueSound("z#411.wav", _soundHandle2, 50); + break; + + default: + break; + } + + enableMouse(); + if (findRoom()->findByName("Doorbot")) + addTimer(3, 3000, 0); + break; + + default: + break; + } + + return true; +} + +bool CServiceElevator::TimerMsg(CTimerMsg *msg) { + CDoorbot *doorbot = dynamic_cast(findRoom()->findByName("Doorbot")); + + switch (msg->_actionVal) { + case 0: + case 1: + if (!isSoundActive(_soundHandle1)) { + stopAnimTimer(_timerId); + if (msg->_actionVal == 0) { + _fieldF8 = true; + CServiceElevatorFloorChangeMsg changeMsg(_fieldDC, _v3); + changeMsg.execute(getRoom()); + _soundHandle2 = playSound("z#424.wav"); + + if (doorbot) { + CActMsg actMsg("DoorbotPlayerPressedTopButton"); + actMsg.execute(doorbot); + } + } else { + enableMouse(); + if (doorbot) { + CActMsg actMsg; + if (_v3 == 0) + actMsg._action = "DoorbotPlayerPressedBottomButton"; + else if (_v3 == 1) + actMsg._action = "DoorbotPlayerPressedMiddleButton"; + + actMsg.execute(doorbot); + } + } + } + break; + + case 3: { + CActMsg actMsg("DoorbotReachedEmbLobby"); + actMsg.execute(doorbot); + break; + } + + default: + break; + } + + return true; +} + +bool CServiceElevator::ServiceElevatorFloorRequestMsg(CServiceElevatorFloorRequestMsg *msg) { + disableMouse(); + CDoorbot *doorbot = dynamic_cast(findRoom()->findByName("Doorbot")); + + if (doorbot && _v3 == 0) { + _soundHandle1 = playSound("z#415.wav", 50); + addTimer(1, 1000, 500); + } else if (doorbot && _v3 == 1) { + _soundHandle1 = playSound("z#417.wav", 50); + addTimer(1, 1000, 500); + } else if (_fieldDC == _v3) { + switch (_v3) { + case 0: + _soundHandle1 = playSound("z#415.wav", 50); + break; + case 1: + _soundHandle1 = playSound("z#420.wav", 50); + break; + case 2: + _soundHandle1 = playSound("z#410.wav", 50); + break; + default: + break; + } + + addTimer(1, 1000, 500); + } else { + switch (_v3) { + case 0: + _soundHandle1 = playSound("z#414.wav", 50); + break; + case 1: + _soundHandle1 = playSound(_fieldDC ? "z#419.wav" : "z#418.wav", 50); + break; + case 2: + _soundHandle1 = playSound("z#414.wav", 50); + break; + default: + break; + } + + addTimer(0, 1000, 500); + } + + return true; +} + +bool CServiceElevator::LeaveRoomMsg(CLeaveRoomMsg *msg) { + CDoorbot *doorbot = dynamic_cast(findRoom()->findByName("Doorbot")); + + if (doorbot) { + CPutBotBackInHisBoxMsg boxMsg(0); + boxMsg.execute("Doorbot"); + doorbot->performAction(false); + enableMouse(); + } + + return true; +} + +bool CServiceElevator::OpeningCreditsMsg(COpeningCreditsMsg *msg) { + _v1 = false; + _string1 = "EmbLobby.Node 1.NE"; + return true; +} + } // End of namespace Titanic diff --git a/engines/titanic/game/transport/service_elevator.h b/engines/titanic/game/transport/service_elevator.h index b2c135021a..5cf1f6f0d5 100644 --- a/engines/titanic/game/transport/service_elevator.h +++ b/engines/titanic/game/transport/service_elevator.h @@ -28,15 +28,23 @@ namespace Titanic { class CServiceElevator : public CTransport { + DECLARE_MESSAGE_MAP; + bool BodyInBilgeRoomMsg(CBodyInBilgeRoomMsg *msg); + bool EnterViewMsg(CEnterViewMsg *msg); + bool ServiceElevatorMsg(CServiceElevatorMsg *msg); + bool TimerMsg(CTimerMsg *msg); + bool ServiceElevatorFloorRequestMsg(CServiceElevatorFloorRequestMsg *msg); + bool LeaveRoomMsg(CLeaveRoomMsg *msg); + bool OpeningCreditsMsg(COpeningCreditsMsg *msg); private: - static int _v1; + static bool _v1; static int _v2; static int _v3; int _fieldF8; - int _fieldFC; - int _field100; - int _field104; + int _soundHandle1; + int _timerId; + int _soundHandle2; public: CLASSDEF; CServiceElevator(); diff --git a/engines/titanic/messages/service_elevator_door.cpp b/engines/titanic/messages/service_elevator_door.cpp index 748790e4aa..7011b1ad44 100644 --- a/engines/titanic/messages/service_elevator_door.cpp +++ b/engines/titanic/messages/service_elevator_door.cpp @@ -24,6 +24,10 @@ namespace Titanic { +BEGIN_MESSAGE_MAP(CServiceElevatorDoor, CDoorAutoSoundEvent) + ON_MESSAGE(PreEnterNodeMsg) +END_MESSAGE_MAP() + CServiceElevatorDoor::CServiceElevatorDoor() : CDoorAutoSoundEvent() { _string1 = "z#31.wav"; _string2 = "z#32.wav"; @@ -45,4 +49,10 @@ void CServiceElevatorDoor::load(SimpleFile *file) { CDoorAutoSoundEvent::load(file); } +bool CServiceElevatorDoor::PreEnterNodeMsg(CPreEnterNodeMsg *msg) { + if (!findRoom()->isEquals("BilgeRoomWith")) + CDoorAutoSoundEvent::PreEnterNodeMsg(msg); + return true; +} + } // End of namespace Titanic diff --git a/engines/titanic/messages/service_elevator_door.h b/engines/titanic/messages/service_elevator_door.h index cc8da0917d..69ad1e15b9 100644 --- a/engines/titanic/messages/service_elevator_door.h +++ b/engines/titanic/messages/service_elevator_door.h @@ -28,6 +28,8 @@ namespace Titanic { class CServiceElevatorDoor : public CDoorAutoSoundEvent { + DECLARE_MESSAGE_MAP; + bool PreEnterNodeMsg(CPreEnterNodeMsg *msg); public: CLASSDEF; CServiceElevatorDoor(); diff --git a/engines/titanic/npcs/mobile.h b/engines/titanic/npcs/mobile.h index 68e74a5afe..2ad939afa6 100644 --- a/engines/titanic/npcs/mobile.h +++ b/engines/titanic/npcs/mobile.h @@ -29,7 +29,7 @@ namespace Titanic { class CMobile : public CCharacter { DECLARE_MESSAGE_MAP; -private: +protected: Point _pos1; int _fieldDC; public: diff --git a/engines/titanic/npcs/true_talk_npc.h b/engines/titanic/npcs/true_talk_npc.h index 2eea9bdf3d..5254eaf9b7 100644 --- a/engines/titanic/npcs/true_talk_npc.h +++ b/engines/titanic/npcs/true_talk_npc.h @@ -65,11 +65,6 @@ protected: int _field104; protected: void processInput(CTextInputMsg *msg, CViewItem *view); - - /** - * Perform an action - */ - void performAction(bool startTalking, CViewItem *view = nullptr); public: int _field100; public: @@ -95,6 +90,11 @@ public: * Start the talker in the given view */ void startTalker(CViewItem *view); + + /** + * Perform an action + */ + void performAction(bool startTalking, CViewItem *view = nullptr); }; } // End of namespace Titanic -- cgit v1.2.3