aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/titanic/carry/carry.h4
-rw-r--r--engines/titanic/core/game_object.h32
-rw-r--r--engines/titanic/npcs/succubus.cpp776
-rw-r--r--engines/titanic/npcs/succubus.h80
4 files changed, 739 insertions, 153 deletions
diff --git a/engines/titanic/carry/carry.h b/engines/titanic/carry/carry.h
index 19c4f11fed..fb5519e290 100644
--- a/engines/titanic/carry/carry.h
+++ b/engines/titanic/carry/carry.h
@@ -45,8 +45,6 @@ class CCarry : public CGameObject {
bool PassOnDragStartMsg(CPassOnDragStartMsg *msg);
protected:
CString _string1;
- Point _origPos;
- CString _fullViewName;
int _fieldDC;
CString _string3;
CString _string4;
@@ -62,6 +60,8 @@ protected:
int _visibleFrame;
public:
int _fieldE0;
+ Point _origPos;
+ CString _fullViewName;
public:
CLASSDEF;
CCarry();
diff --git a/engines/titanic/core/game_object.h b/engines/titanic/core/game_object.h
index 849682c1a3..f853a63bbb 100644
--- a/engines/titanic/core/game_object.h
+++ b/engines/titanic/core/game_object.h
@@ -71,7 +71,6 @@ private:
*/
bool clipRect(const Rect &rect1, Rect &rect2) const;
protected:
- Rect _bounds;
double _field34;
double _field38;
double _field3C;
@@ -341,11 +340,6 @@ protected:
bool changeView(const CString &viewName);
/**
- * Get the centre of the game object's bounds
- */
- Point getControid() const;
-
- /**
* Play an arbitrary clip
*/
void playClip(const CString &name, uint flags);
@@ -445,16 +439,6 @@ protected:
uint32 getTickCount();
/**
- * Adds an object to the mail list
- */
- void addMail(int mailId);
-
- /**
- * Sets the mail identifier for an object
- */
- void setMailId(int mailId);
-
- /**
* Returns true if a mail with a specified Id exists
*/
bool mailExists(int id) const;
@@ -544,6 +528,7 @@ protected:
*/
int getNewRandomNumber(int max, int *oldVal = nullptr);
public:
+ Rect _bounds;
bool _isMail;
int _id;
uint _roomFlags;
@@ -627,6 +612,11 @@ public:
void setPosition(const Point &newPos);
/**
+ * Get the centre of the game object's bounds
+ */
+ Point getControid() const;
+
+ /**
* Change the object's status
*/
void playMovie(uint flags);
@@ -697,6 +687,16 @@ public:
int getPriorClass() const;
/**
+ * Adds an object to the mail list
+ */
+ void addMail(int mailId);
+
+ /**
+ * Sets the mail identifier for an object
+ */
+ void setMailId(int mailId);
+
+ /**
* Returns true if there's an attached surface which has a frame
* ready for display
*/
diff --git a/engines/titanic/npcs/succubus.cpp b/engines/titanic/npcs/succubus.cpp
index f66a59cb84..75afb1b273 100644
--- a/engines/titanic/npcs/succubus.cpp
+++ b/engines/titanic/npcs/succubus.cpp
@@ -21,61 +21,78 @@
*/
#include "titanic/npcs/succubus.h"
+#include "titanic/carry/carry.h"
+#include "titanic/carry/chicken.h"
+#include "titanic/core/view_item.h"
+#include "titanic/pet_control/pet_control.h"
+#include "titanic/titanic.h"
namespace Titanic {
-int CSuccUBus::_v0;
+BEGIN_MESSAGE_MAP(CSuccUBus, CTrueTalkNPC)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(SubAcceptCCarryMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(LeaveViewMsg)
+ ON_MESSAGE(PETDeliverMsg)
+ ON_MESSAGE(PETReceiveMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(TrueTalkGetStateValueMsg)
+ ON_MESSAGE(SignalObject)
+ ON_MESSAGE(TurnOn)
+ ON_MESSAGE(TurnOff)
+ ON_MESSAGE(SUBTransition)
+ ON_MESSAGE(SetChevRoomBits)
+ ON_MESSAGE(ActMsg)
+ ON_MESSAGE(MouseDragStartMsg)
+END_MESSAGE_MAP()
+
+bool CSuccUBus::_enabled;
int CSuccUBus::_v1;
int CSuccUBus::_v2;
int CSuccUBus::_v3;
int CSuccUBus::_v4;
CSuccUBus::CSuccUBus() : CTrueTalkNPC() {
- _field108 = -1;
- _field10C = -1;
- _field110 = -1;
- _field114 = -1;
- _field118 = 0x44;
- _field11C = 0xA8;
- _field120 = 0xA8;
- _field124 = 0xF8;
- _field128 = 0;
- _field12C = 0x0E;
- _field130 = 0x0E;
- _field134 = 27;
- _field138 = 40;
- _field13C = 0x44;
+ _startFrame8 = -1;
+ _endFrame8 = -1;
+ _startFrame11 = -1;
+ _endFrame11 = -1;
+ _startFrame3 = 68;
+ _endFrame3 = 168;
+ _startFrame4 = 168;
+ _endFrame4 = 248;
+ _startFrame9 = 0;
+ _endFrame9 = 0x0E;
+ _startFrame10 = 0x0E;
+ _endFrame10 = 27;
+ _startFrame2 = 40;
+ _endFrame2 = 68;
_field140 = 1;
_field144 = 0;
- _field148 = 0;
- _field14C = 0;
+ _startFrame5 = 0;
+ _endFrame5 = 0;
_field150 = 0xE0;
_field154 = 0;
_field158 = 0;
_field15C = 0;
_string2 = "NULL";
- _field16C = 28;
- _field170 = 40;
- _field174 = 82;
- _field178 = 284;
- _field17C = 148;
- _field180 = 339;
+ _startFrame1 = 28;
+ _endFrame1 = 40;
+ _rect1 = Rect(82, 284, 148, 339);
_field184 = 15;
_field188 = 0;
- _field18C = 0;
- _field190 = 0;
- _field194 = 240;
- _field198 = 340;
+ _rect2 = Rect(0, 0, 240, 340);
_field19C = 0;
- _field1A0 = -1;
- _field1A4 = 0;
- _field1A8 = 0;
+ _soundHandle = -1;
+ _isChicken = false;
+ _isFeathers = false;
_field1AC = 0;
_field1B0 = 0;
- _field1B4 = 303;
- _field1B8 = 312;
- _field1BC = 313;
- _field1C0 = 325;
+ _startFrame6 = 303;
+ _endFrame6 = 312;
+ _startFrame7 = 313;
+ _endFrame7 = 325;
_field1C4 = 326;
_field1C8 = 347;
_field1CC = 348;
@@ -87,54 +104,54 @@ CSuccUBus::CSuccUBus() : CTrueTalkNPC() {
void CSuccUBus::save(SimpleFile *file, int indent) {
file->writeNumberLine(1, indent);
- file->writeNumberLine(_v0, indent);
- file->writeNumberLine(_field108, indent);
- file->writeNumberLine(_field10C, indent);
- file->writeNumberLine(_field110, indent);
- file->writeNumberLine(_field114, indent);
- file->writeNumberLine(_field118, indent);
- file->writeNumberLine(_field11C, indent);
- file->writeNumberLine(_field120, indent);
- file->writeNumberLine(_field124, indent);
- file->writeNumberLine(_field128, indent);
- file->writeNumberLine(_field12C, indent);
- file->writeNumberLine(_field130, indent);
- file->writeNumberLine(_field134, indent);
- file->writeNumberLine(_field138, indent);
- file->writeNumberLine(_field13C, indent);
+ file->writeNumberLine(_enabled, indent);
+ file->writeNumberLine(_startFrame8, indent);
+ file->writeNumberLine(_endFrame8, indent);
+ file->writeNumberLine(_startFrame11, indent);
+ file->writeNumberLine(_endFrame11, indent);
+ file->writeNumberLine(_startFrame3, indent);
+ file->writeNumberLine(_endFrame3, indent);
+ file->writeNumberLine(_startFrame4, indent);
+ file->writeNumberLine(_endFrame4, indent);
+ file->writeNumberLine(_startFrame9, indent);
+ file->writeNumberLine(_endFrame9, indent);
+ file->writeNumberLine(_startFrame10, indent);
+ file->writeNumberLine(_endFrame10, indent);
+ file->writeNumberLine(_startFrame2, indent);
+ file->writeNumberLine(_endFrame2, indent);
file->writeNumberLine(_field140, indent);
file->writeNumberLine(_v2, indent);
- file->writeNumberLine(_field148, indent);
- file->writeNumberLine(_field14C, indent);
+ file->writeNumberLine(_startFrame5, indent);
+ file->writeNumberLine(_endFrame5, indent);
file->writeNumberLine(_field150, indent);
file->writeNumberLine(_field154, indent);
file->writeNumberLine(_field158, indent);
file->writeNumberLine(_field15C, indent);
file->writeQuotedLine(_string2, indent);
- file->writeNumberLine(_field16C, indent);
- file->writeNumberLine(_field170, indent);
- file->writeNumberLine(_field174, indent);
- file->writeNumberLine(_field178, indent);
- file->writeNumberLine(_field17C, indent);
- file->writeNumberLine(_field180, indent);
+ file->writeNumberLine(_startFrame1, indent);
+ file->writeNumberLine(_endFrame1, indent);
+ file->writeNumberLine(_rect1.left, indent);
+ file->writeNumberLine(_rect1.top, indent);
+ file->writeNumberLine(_rect1.right, indent);
+ file->writeNumberLine(_rect1.bottom, indent);
file->writeNumberLine(_field184, indent);
file->writeNumberLine(_field188, indent);
- file->writeNumberLine(_field18C, indent);
- file->writeNumberLine(_field190, indent);
- file->writeNumberLine(_field194, indent);
- file->writeNumberLine(_field198, indent);
+ file->writeNumberLine(_rect2.left, indent);
+ file->writeNumberLine(_rect2.top, indent);
+ file->writeNumberLine(_rect2.right, indent);
+ file->writeNumberLine(_rect2.bottom, indent);
file->writeNumberLine(_field19C, indent);
- file->writeNumberLine(_field1A0, indent);
- file->writeNumberLine(_field1A4, indent);
- file->writeNumberLine(_field1A8, indent);
+ file->writeNumberLine(_soundHandle, indent);
+ file->writeNumberLine(_isChicken, indent);
+ file->writeNumberLine(_isFeathers, indent);
file->writeNumberLine(_field1AC, indent);
file->writeNumberLine(_field1B0, indent);
- file->writeNumberLine(_field1B4, indent);
- file->writeNumberLine(_field1B8, indent);
- file->writeNumberLine(_field1BC, indent);
- file->writeNumberLine(_field1C0, indent);
+ file->writeNumberLine(_startFrame6, indent);
+ file->writeNumberLine(_endFrame6, indent);
+ file->writeNumberLine(_startFrame7, indent);
+ file->writeNumberLine(_endFrame7, indent);
file->writeNumberLine(_field1C4, indent);
file->writeNumberLine(_field1C8, indent);
file->writeNumberLine(_field1CC, indent);
@@ -151,54 +168,54 @@ void CSuccUBus::save(SimpleFile *file, int indent) {
void CSuccUBus::load(SimpleFile *file) {
file->readNumber();
- _v0 = file->readNumber();
- _field108 = file->readNumber();
- _field10C = file->readNumber();
- _field110 = file->readNumber();
- _field114 = file->readNumber();
- _field118 = file->readNumber();
- _field11C = file->readNumber();
- _field120 = file->readNumber();
- _field124 = file->readNumber();
- _field128 = file->readNumber();
- _field12C = file->readNumber();
- _field130 = file->readNumber();
- _field134 = file->readNumber();
- _field138 = file->readNumber();
- _field13C = file->readNumber();
+ _enabled = file->readNumber();
+ _startFrame8 = file->readNumber();
+ _endFrame8 = file->readNumber();
+ _startFrame11 = file->readNumber();
+ _endFrame11 = file->readNumber();
+ _startFrame3 = file->readNumber();
+ _endFrame3 = file->readNumber();
+ _startFrame4 = file->readNumber();
+ _endFrame4 = file->readNumber();
+ _startFrame9 = file->readNumber();
+ _endFrame9 = file->readNumber();
+ _startFrame10 = file->readNumber();
+ _endFrame10 = file->readNumber();
+ _startFrame2 = file->readNumber();
+ _endFrame2 = file->readNumber();
_field140 = file->readNumber();
_v2 = file->readNumber();
- _field148 = file->readNumber();
- _field14C = file->readNumber();
+ _startFrame5 = file->readNumber();
+ _endFrame5 = file->readNumber();
_field150 = file->readNumber();
_field154 = file->readNumber();
_field158 = file->readNumber();
_field15C = file->readNumber();
_string2 = file->readString();
- _field16C = file->readNumber();
- _field170 = file->readNumber();
- _field174 = file->readNumber();
- _field178 = file->readNumber();
- _field17C = file->readNumber();
- _field180 = file->readNumber();
+ _startFrame1 = file->readNumber();
+ _endFrame1 = file->readNumber();
+ _rect1.left = file->readNumber();
+ _rect1.top = file->readNumber();
+ _rect1.right = file->readNumber();
+ _rect1.bottom = file->readNumber();
_field184 = file->readNumber();
_field188 = file->readNumber();
- _field18C = file->readNumber();
- _field190 = file->readNumber();
- _field194 = file->readNumber();
- _field198 = file->readNumber();
+ _rect2.left = file->readNumber();
+ _rect2.top = file->readNumber();
+ _rect2.right = file->readNumber();
+ _rect2.bottom = file->readNumber();
_field19C = file->readNumber();
- _field1A0 = file->readNumber();
- _field1A4 = file->readNumber();
- _field1A8 = file->readNumber();
+ _soundHandle = file->readNumber();
+ _isChicken = file->readNumber();
+ _isFeathers = file->readNumber();
_field1AC = file->readNumber();
_field1B0 = file->readNumber();
- _field1B4 = file->readNumber();
- _field1B8 = file->readNumber();
- _field1BC = file->readNumber();
- _field1C0 = file->readNumber();
+ _startFrame6 = file->readNumber();
+ _endFrame6 = file->readNumber();
+ _startFrame7 = file->readNumber();
+ _endFrame7 = file->readNumber();
_field1C4 = file->readNumber();
_field1C8 = file->readNumber();
_field1CC = file->readNumber();
@@ -212,4 +229,559 @@ void CSuccUBus::load(SimpleFile *file) {
CTrueTalkNPC::load(file);
}
+bool CSuccUBus::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (!_field1D8) {
+ Rect tempRect = _rect1;
+ tempRect.translate(_bounds.left, _bounds.top);
+
+ if (!_enabled || (_field188 && tempRect.contains(msg->_mousePos))) {
+ CTurnOn onMsg;
+ onMsg.execute(this);
+ _enabled = true;
+ } else if (getNewRandomNumber(256) < 130) {
+ _enabled = false;
+ CTurnOff offMsg;
+ offMsg.execute(this);
+ } else {
+ switch (getNewRandomNumber(2)) {
+ case 0:
+ startTalking(this, 230055, findView());
+ break;
+ case 1:
+ startTalking(this, 230067, findView());
+ break;
+ case 2:
+ startTalking(this, 230045, findView());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+bool CSuccUBus::SubAcceptCCarryMsg(CSubAcceptCCarryMsg *msg) {
+ if (!msg->_item)
+ return false;
+
+ CPetControl *pet = getPetControl();
+ CCarry *item = dynamic_cast<CCarry *>(msg->_item);
+ Rect tempRect = _rect2;
+ tempRect.translate(_bounds.left, _bounds.top);
+ uint roomFlags = pet ? pet->getRoomFlags() : 0;
+
+ if (!_enabled || !pet || !item || !tempRect.contains(item->getControid())) {
+ item->petAddToInventory();
+ } else if (mailExists(roomFlags)) {
+ petDisplayMessage("The Succ-U-Bus is a Single Entity Delivery Device.");
+ item->petAddToInventory();
+ } else {
+ petContainerRemove(item);
+ pet->phonographAction("");
+
+ CChicken *chicken = dynamic_cast<CChicken *>(item);
+ bool chickenFlag = chicken ? chicken->_string6 != "None" : false;
+
+ item->setVisible(false);
+ if (_startFrame1 >= 0) {
+ playSound("z#23.wav");
+ playMovie(_startFrame1, _endFrame1, 0);
+ }
+
+ if (!chickenFlag) {
+ _field188 = 1;
+ item->addMail(roomFlags);
+ petSetArea(PET_REMOTE);
+ petHighlightGlyph(16);
+ CSUBTransition transMsg;
+ transMsg.execute(this);
+ } else {
+ if (_startFrame2 >= 0) {
+ startTalking(this, 70219, findView());
+ playMovie(_startFrame2, _endFrame2, 0);
+ }
+
+ if (_startFrame3 >= 0) {
+ playMovie(_startFrame3, _endFrame3, MOVIE_NOTIFY_OBJECT);
+ _field158 = 2;
+ }
+
+ CViewItem *view = parseView(chicken->_fullViewName);
+ if (!view)
+ return false;
+
+ item->setPosition(item->_origPos);
+ item->moveUnder(view);
+
+ CSUBTransition transMsg;
+ transMsg.execute(this);
+ }
+ }
+
+ return true;
+}
+
+bool CSuccUBus::EnterViewMsg(CEnterViewMsg *msg) {
+ if (g_vm->getRandomNumber(4) == 0 && compareRoomNameTo("PromenadeDeck")) {
+ CParrotSpeakMsg speakMsg("SuccUBus", "EnterView");
+ speakMsg.execute("PerchedParrot");
+ }
+
+ petSetRemoteTarget();
+ _field144 = nullptr;
+ if (_startFrame8 >= 0)
+ loadFrame(_startFrame8);
+
+ return true;
+}
+
+bool CSuccUBus::LeaveViewMsg(CLeaveViewMsg *msg) {
+ petDisplayMessage(2, "");
+ if (_startFrame8 >= 0)
+ loadFrame(_startFrame8);
+ else if (!_field15C && _startFrame9 >= 0)
+ loadFrame(_startFrame9);
+
+ petClear();
+ if (_soundHandle != -1) {
+ stopSound(_soundHandle, 1);
+ _soundHandle = -1;
+ }
+
+ if (_enabled) {
+ _enabled = false;
+ if (_startFrame10 >= 0)
+ playSound("z#27.wav", 100);
+
+ if (_field15C)
+ setVisible(false);
+ }
+
+ performAction(true, findView());
+ CSUBTransition transMsg;
+ transMsg.execute(this);
+
+ return true;
+}
+
+bool CSuccUBus::PETDeliverMsg(CPETDeliverMsg *msg) {
+ if (_field1D8)
+ return true;
+
+ if (!_enabled) {
+ petDisplayMessage(2, "The Succ-U-Bus is in Standby, or \"Off\" mode at present.");
+ return true;
+ }
+
+ CPetControl *pet = getPetControl();
+ if (!pet)
+ return true;
+
+ CGameObject *mailObject = findMail(pet->getRoomFlags());
+ if (!mailObject) {
+ switch (g_vm->getRandomNumber(2)) {
+ case 0:
+ startTalking(this, 70111, findView());
+ break;
+ case 1:
+ startTalking(this, 70112, findView());
+ break;
+ case 2:
+ startTalking(this, 70113, findView());
+ break;
+ default:
+ break;
+ }
+
+ petDisplayMessage(2, "There is currently nothing in the tray to send.");
+ } else {
+ _field19C = 0;
+
+ CRoomFlags roomFlags = _roomFlags;
+ if (!pet->testRooms5(roomFlags) || getPassengerClass() > 0) {
+ roomFlags = pet->getSpecialRoomFlags("BilgeRoom");
+ _field19C = 1;
+ } else {
+ pet->getMailDest(roomFlags);
+ }
+
+ _isFeathers = mailObject->getName() == "Feathers";
+ _isChicken = mailObject->getName() == "Chicken";
+ _field158 = 0;
+ _field188 = 0;
+ _field1D8 = 1;
+ inc54();
+
+ if (_isFeathers) {
+ _field19C = 0;
+ removeMail(roomFlags, roomFlags);
+ pet->phonographAction("");
+
+ if (_startFrame2 >= 0) {
+ playMovie(_startFrame2, _endFrame2, 0);
+ startTalking(this, 230022, findView());
+ }
+
+ _field158 = 1;
+ if (_startFrame3 >= 0)
+ playMovie(_startFrame3, _endFrame3, 0);
+
+ if (_startFrame4 >= 0) {
+ _field144 = mailObject;
+ playMovie(_startFrame4, _endFrame4, MOVIE_NOTIFY_OBJECT);
+ }
+
+ if (_startFrame5 >= 0) {
+ playMovie(_startFrame5, _endFrame5, 0);
+ }
+ } else {
+ removeMail(pet->getRoomFlags(), roomFlags);
+ pet->phonographAction("");
+
+ if (_startFrame2 >= 0) {
+ playMovie(_startFrame2, _endFrame2, 0);
+ startTalking(this, 230012, findView());
+ }
+
+ if (_startFrame3 >= 0)
+ playMovie(_startFrame3, _endFrame3, MOVIE_NOTIFY_OBJECT);
+ }
+ }
+
+ return true;
+}
+
+bool CSuccUBus::PETReceiveMsg(CPETReceiveMsg *msg) {
+ CPetControl *pet = getPetControl();
+
+ if (_field1D8 || !pet)
+ return true;
+ if (!_enabled) {
+ petDisplayMessage(2, "The Succ-U-Bus is in Standby, or \"Off\" mode at present.");
+ return true;
+ }
+
+ uint petRoomFlags = pet->getRoomFlags();
+ if (mailExists(petRoomFlags)) {
+ switch (g_vm->getRandomNumber(2)) {
+ case 0:
+ startTalking(this, 70080, findView());
+ break;
+ case 1:
+ startTalking(this, 70081, findView());
+ break;
+ case 2:
+ startTalking(this, 70082, findView());
+ break;
+ default:
+ break;
+ }
+ } else {
+ CGameObject *mailObject = findMailByFlags(compareRoomNameTo("Titania")
+ ? 3 : _field140, petRoomFlags);
+ if (!mailObject) {
+ if (g_vm->getRandomNumber(1) == 0) {
+ startTalking(this, 70104, findView());
+ } else {
+ startTalking(this, 70105, findView());
+ }
+
+ playMovie(_startFrame6, _endFrame6, 0);
+ playMovie(_startFrame7, _endFrame7, 0);
+ petDisplayMessage(2, "There is currently nothing to deliver.");
+ } else {
+ startTalking(this, 230004, findView());
+
+ if (_startFrame4 >= 0) {
+ _field158 = 1;
+ _field1D8 = 1;
+ inc54();
+ playMovie(_startFrame4, _endFrame4, MOVIE_NOTIFY_OBJECT);
+ }
+ }
+ }
+
+ return true;
+}
+
+bool CSuccUBus::MovieEndMsg(CMovieEndMsg *msg) {
+ CPetControl *pet = getPetControl();
+ uint petRoomFlags = pet ? pet->getRoomFlags() : 0;
+
+ if (msg->_endFrame == _endFrame10) {
+ if (_startFrame11 >= 0)
+ playSound("z#30.wav", 100);
+
+ if (_field15C) {
+ _field15C = false;
+ setVisible(false);
+ CSignalObject signalMsg;
+ signalMsg._numValue = 1;
+ signalMsg.execute(_string2);
+ }
+ }
+
+ if (msg->_endFrame == _endFrame9) {
+ bool flag = false;
+
+ if (pet && mailExists(petRoomFlags)) {
+ CGameObject *mailObject = _v3 && compareRoomNameTo("Titania") ?
+ findMailByFlags(3, petRoomFlags) :
+ findMailByFlags(_field140, petRoomFlags);
+
+ if (mailObject) {
+ switch (g_vm->getRandomNumber(4)) {
+ case 0:
+ startTalking(this, 70094, findView());
+ break;
+ case 1:
+ startTalking(this, 70095, findView());
+ break;
+ case 2:
+ startTalking(this, 70096, findView());
+ break;
+ case 3:
+ startTalking(this, 70098, findView());
+ break;
+ case 4:
+ startTalking(this, 70099, findView());
+ break;
+ default:
+ break;
+ }
+ flag = true;
+ }
+ }
+
+ if (!_field188 && !flag) {
+ stopSound(_soundHandle);
+ _soundHandle = -1;
+
+ switch (getNewRandomNumber(_v2 ? 7 : 5, &_field1B0)) {
+ case 2:
+ startTalking(this, 230001, findView());
+ break;
+ case 3:
+ startTalking(this, 230002, findView());
+ break;
+ case 4:
+ startTalking(this, 230003, findView());
+ break;
+ case 5:
+ startTalking(this, 230064, findView());
+ break;
+ case 6:
+ startTalking(this, 230062, findView());
+ break;
+ case 7:
+ startTalking(this, 230063, findView());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (msg->_endFrame == _endFrame3) {
+ if (_field158 == 1) {
+ startTalking(this, 230022, findView());
+ } else if (_field158 == 2) {
+ startTalking(this, 230017, findView());
+ } else if (_field19C) {
+ startTalking(this, 230019, findView());
+ _field19C = 0;
+ } else if (_isChicken) {
+ startTalking(this, 230018, findView());
+ _isChicken = false;
+ } else {
+ startTalking(this, 230013, findView());
+ }
+
+ if (_field1D8) {
+ _field1D8 = 0;
+ dec54();
+ }
+
+ CSUBTransition transMsg;
+ transMsg.execute(this);
+ }
+
+ if (msg->_endFrame == _endFrame4) {
+ if (pet && _field144) {
+ _field144->setMailId(petRoomFlags);
+ }
+
+ _field188 = 1;
+ _field144 = 0;
+ if (_field1D8) {
+ _field1D8 = 0;
+ dec54();
+ }
+
+ CSUBTransition transMsg;
+ transMsg.execute(this);
+ }
+
+ return true;
+}
+
+bool CSuccUBus::TrueTalkGetStateValueMsg(CTrueTalkGetStateValueMsg *msg) {
+ if (msg->_stateNum == 1)
+ msg->_stateVal = _enabled;
+
+ return true;
+}
+
+bool CSuccUBus::SignalObject(CSignalObject *msg) {
+ if (msg->_numValue == 1) {
+ _string2 = msg->_strValue;
+ _field15C = 1;
+ setVisible(true);
+ CTurnOn onMsg;
+ onMsg.execute(this);
+ }
+
+ return true;
+}
+
+bool CSuccUBus::TurnOn(CTurnOn *msg) {
+ if (g_vm->getRandomNumber(9) == 0) {
+ CParrotSpeakMsg speakMsg("SuccUBus", "TurnOn");
+ speakMsg.execute("PerchedParrot");
+ }
+
+ CPetControl *pet = getPetControl();
+ if (pet) {
+ if (!_field15C && _startFrame8 >= 0) {
+ playMovie(_startFrame8, _endFrame8, 0);
+ playSound("z#30.wav", 100);
+ }
+
+ if (_startFrame9 >= 0) {
+ playMovie(_startFrame9, _endFrame9, MOVIE_NOTIFY_OBJECT);
+ playSound("z#26.wav", 100);
+ }
+
+ uint petRoomFlags = pet->getRoomFlags();
+ if (mailExists(petRoomFlags) && _endFrame1 >= 0)
+ playMovie(_endFrame1, _endFrame1, 0);
+
+ _enabled = true;
+ CSUBTransition transMsg;
+ transMsg.execute(this);
+
+ endTalking(this, true, findView());
+ petSetArea(PET_REMOTE);
+ petHighlightGlyph(16);
+ }
+
+ return true;
+}
+
+bool CSuccUBus::TurnOff(CTurnOff *msg) {
+ if (_soundHandle != -1) {
+ stopSound(_soundHandle);
+ _soundHandle = -1;
+ }
+
+ if (_startFrame10 >= 0) {
+ playSound("z#27.wav", 100);
+ playMovie(_startFrame10, _endFrame10, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+ }
+
+ if (!_field15C && _startFrame11 >= 0)
+ playMovie(_startFrame11, _endFrame11, MOVIE_NOTIFY_OBJECT | MOVIE_GAMESTATE);
+
+ _enabled = false;
+ performAction(true);
+ CSUBTransition transMsg;
+ transMsg.execute(this);
+
+ return true;
+}
+
+bool CSuccUBus::SUBTransition(CSUBTransition *msg) {
+ CPetControl *pet = getPetControl();
+
+ if (pet) {
+ uint petRoomFlags = pet->getRoomFlags();
+
+ if (_enabled) {
+ CGameObject *mailObject = findMail(petRoomFlags);
+ if (mailObject)
+ pet->phonographAction("Send");
+ else
+ pet->phonographAction("Receive");
+ } else {
+ if (pet->isSuccUBusRoom(petRoomFlags))
+ pet->phonographAction("Record");
+ else
+ pet->phonographAction("");
+ }
+ }
+
+ return true;
+}
+
+bool CSuccUBus::SetChevRoomBits(CSetChevRoomBits *msg) {
+ if (_enabled) {
+ _roomFlags = msg->_value;
+ playSound("z#98.wav", 100);
+ }
+
+ return true;
+}
+
+bool CSuccUBus::ActMsg(CActMsg *msg) {
+ if (msg->_action == "EnableObject")
+ _v3 = 1;
+ else if (msg->_action == "DisableObject")
+ _v3 = 0;
+
+ return true;
+}
+
+bool CSuccUBus::MouseDragStartMsg(CMouseDragStartMsg *msg) {
+ CPetControl *pet = getPetControl();
+ Rect tempRect = _rect1;
+ tempRect.translate(_bounds.left, _bounds.top);
+
+ if (_field1D8 || !_enabled || !_field188 || !tempRect.contains(msg->_mousePos)
+ || !pet)
+ return true;
+
+ uint petRoomFlags = pet->getRoomFlags();
+ CGameObject *mailObject = findMail(petRoomFlags);
+ if (!mailObject)
+ return true;
+
+ petAddToCarryParcel(mailObject);
+ CViewItem *view = getView();
+ if (!view)
+ return true;
+
+ mailObject->moveUnder(view);
+ mailObject->setPosition(Point(msg->_mousePos.x + mailObject->_bounds.width() / 2,
+ msg->_mousePos.y + mailObject->_bounds.height() / 2));
+
+ CVisibleMsg visibleMsg(true);
+ visibleMsg.execute(mailObject);
+ CPassOnDragStartMsg dragMsg;
+ dragMsg._mousePos = msg->_mousePos;
+ dragMsg._value3 = 1;
+ dragMsg.execute(mailObject);
+
+ if (!dragMsg._value4)
+ msg->_dragItem = mailObject;
+
+ loadFrame(_field184);
+ _field188 = 0;
+ CSUBTransition transMsg;
+ transMsg.execute(this);
+
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/npcs/succubus.h b/engines/titanic/npcs/succubus.h
index f6f5a6b9e9..b8e4c316a9 100644
--- a/engines/titanic/npcs/succubus.h
+++ b/engines/titanic/npcs/succubus.h
@@ -24,62 +24,76 @@
#define TITANIC_SUCCUBUS_H
#include "titanic/npcs/true_talk_npc.h"
+#include "titanic/messages/pet_messages.h"
namespace Titanic {
class CSuccUBus : public CTrueTalkNPC {
+ DECLARE_MESSAGE_MAP;
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool SubAcceptCCarryMsg(CSubAcceptCCarryMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
+ bool PETDeliverMsg(CPETDeliverMsg *msg);
+ bool PETReceiveMsg(CPETReceiveMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool TrueTalkGetStateValueMsg(CTrueTalkGetStateValueMsg *msg);
+ bool SignalObject(CSignalObject *msg);
+ bool TurnOn(CTurnOn *msg);
+ bool TurnOff(CTurnOff *msg);
+ bool SUBTransition(CSUBTransition *msg);
+ bool SetChevRoomBits(CSetChevRoomBits *msg);
+ bool ActMsg(CActMsg *msg);
+ bool MouseDragStartMsg(CMouseDragStartMsg *msg);
private:
- static int _v0;
+ static bool _enabled;
static int _v1;
static int _v2;
static int _v3;
static int _v4;
private:
- int _field108;
- int _field10C;
- int _field110;
- int _field114;
- int _field118;
- int _field11C;
- int _field120;
- int _field124;
- int _field128;
- int _field12C;
- int _field130;
- int _field134;
- int _field138;
- int _field13C;
+ int _startFrame8;
+ int _endFrame8;
+ int _startFrame11;
+ int _endFrame11;
+ int _startFrame3;
+ int _endFrame3;
+ int _startFrame4;
+ int _endFrame4;
+ int _startFrame9;
+ int _endFrame9;
+ int _startFrame10;
+ int _endFrame10;
+ int _startFrame2;
+ int _endFrame2;
int _field140;
- int _field144;
- int _field148;
- int _field14C;
+ CGameObject *_field144;
+ int _startFrame5;
+ int _endFrame5;
int _field150;
int _field154;
int _field158;
- int _field15C;
+ bool _field15C;
CString _string2;
- int _field16C;
- int _field170;
- int _field174;
- int _field178;
- int _field17C;
- int _field180;
+ int _startFrame1;
+ int _endFrame1;
+ Rect _rect1;
int _field184;
int _field188;
- int _field18C;
+ Rect _rect2;
int _field190;
int _field194;
int _field198;
int _field19C;
- int _field1A0;
- int _field1A4;
- int _field1A8;
+ int _soundHandle;
+ bool _isChicken;
+ bool _isFeathers;
int _field1AC;
int _field1B0;
- int _field1B4;
- int _field1B8;
- int _field1BC;
- int _field1C0;
+ int _startFrame6;
+ int _endFrame6;
+ int _startFrame7;
+ int _endFrame7;
int _field1C4;
int _field1C8;
int _field1CC;