aboutsummaryrefslogtreecommitdiff
path: root/engines/titanic
diff options
context:
space:
mode:
authorPaul Gilbert2016-08-13 23:43:52 -0400
committerPaul Gilbert2016-08-13 23:43:52 -0400
commitc6c76e7f4cdcdf8b0719cf5bd5f603219a11094f (patch)
tree6c83f87fb2d2d91d9d42957ca8de210956a38de2 /engines/titanic
parent14cdfa3f58455c818691eb94d3a3de5b0dda8696 (diff)
downloadscummvm-rg350-c6c76e7f4cdcdf8b0719cf5bd5f603219a11094f.tar.gz
scummvm-rg350-c6c76e7f4cdcdf8b0719cf5bd5f603219a11094f.tar.bz2
scummvm-rg350-c6c76e7f4cdcdf8b0719cf5bd5f603219a11094f.zip
TITANIC: In-progress implementing CParrot class
Diffstat (limited to 'engines/titanic')
-rw-r--r--engines/titanic/carry/carry.h3
-rw-r--r--engines/titanic/core/game_object.cpp8
-rw-r--r--engines/titanic/core/game_object.h6
-rw-r--r--engines/titanic/core/named_item.h2
-rw-r--r--engines/titanic/core/tree_item.cpp13
-rw-r--r--engines/titanic/core/tree_item.h5
-rw-r--r--engines/titanic/npcs/parrot.cpp313
-rw-r--r--engines/titanic/npcs/parrot.h19
8 files changed, 358 insertions, 11 deletions
diff --git a/engines/titanic/carry/carry.h b/engines/titanic/carry/carry.h
index 72f4024904..19c4f11fed 100644
--- a/engines/titanic/carry/carry.h
+++ b/engines/titanic/carry/carry.h
@@ -48,7 +48,6 @@ protected:
Point _origPos;
CString _fullViewName;
int _fieldDC;
- int _fieldE0;
CString _string3;
CString _string4;
Point _tempPos;
@@ -62,6 +61,8 @@ protected:
bool _enterFrameSet;
int _visibleFrame;
public:
+ int _fieldE0;
+public:
CLASSDEF;
CCarry();
diff --git a/engines/titanic/core/game_object.cpp b/engines/titanic/core/game_object.cpp
index 723f2456f3..9a524e57a9 100644
--- a/engines/titanic/core/game_object.cpp
+++ b/engines/titanic/core/game_object.cpp
@@ -657,10 +657,10 @@ void CGameObject::playClip(uint startFrame, uint endFrame) {
gameManager->playClip(clip, room, room);
}
-void CGameObject::playRandomClip(const char **names, uint flags) {
+void CGameObject::playRandomClip(const char *const *names, uint flags) {
// Count size of array
int count = 0;
- for (const char **p = names; *p; ++p)
+ for (const char *const *p = names; *p; ++p)
++count;
// Play clip
@@ -1206,9 +1206,9 @@ void CGameObject::dragMove(const Point &pt) {
setPosition(Point(pt.x - _bounds.width() / 2, pt.y - _bounds.height() / 2));
}
-bool CGameObject::isObjectDragging() const {
+CGameObject *CGameObject::getDraggingObject() const {
CTreeItem *item = getGameManager()->_dragItem;
- return item ? static_cast<CGameObject *>(item) != nullptr : false;
+ return static_cast<CGameObject *>(item);
}
Point CGameObject::getControid() const {
diff --git a/engines/titanic/core/game_object.h b/engines/titanic/core/game_object.h
index 2dc539f739..b9d819fc25 100644
--- a/engines/titanic/core/game_object.h
+++ b/engines/titanic/core/game_object.h
@@ -358,7 +358,7 @@ protected:
/**
* Play a clip randomly from a passed list of names
*/
- void playRandomClip(const char **names, uint flags);
+ void playRandomClip(const char *const *names, uint flags);
/**
* Return the current view/node/room as a single string
@@ -723,9 +723,9 @@ public:
void dragMove(const Point &pt);
/**
- * Returns true if an item being dragged is a game object
+ * Returns the currently dragging item (if any) if it's a game object
*/
- bool isObjectDragging() const;
+ CGameObject *getDraggingObject() const;
bool compareRoomFlags(int mode, uint flags1, uint flags2);
diff --git a/engines/titanic/core/named_item.h b/engines/titanic/core/named_item.h
index 809cda1156..acd59f344e 100644
--- a/engines/titanic/core/named_item.h
+++ b/engines/titanic/core/named_item.h
@@ -61,7 +61,7 @@ public:
/**
* Compares the name of the item to a passed name
*/
- virtual int compareTo(const CString &name, int maxLen) const;
+ virtual int compareTo(const CString &name, int maxLen = 0) const;
/**
* Find a parent node for the item
diff --git a/engines/titanic/core/tree_item.cpp b/engines/titanic/core/tree_item.cpp
index 6adbbe39fa..a10b8ef19d 100644
--- a/engines/titanic/core/tree_item.cpp
+++ b/engines/titanic/core/tree_item.cpp
@@ -252,6 +252,19 @@ void CTreeItem::detach() {
_priorSibling = _nextSibling = _parent = nullptr;
}
+void CTreeItem::attach(CTreeItem *item) {
+ _nextSibling = item;
+ _priorSibling = item->_priorSibling;
+ _parent = item->_parent;
+
+ if (item->_priorSibling)
+ item->_priorSibling->_nextSibling = this;
+
+ item->_priorSibling = this;
+ if (item->_parent && !item->_parent->_firstChild)
+ item->_parent->_firstChild = this;
+}
+
CNamedItem *CTreeItem::findByName(const CString &name, int maxLen) {
CString nameLower = name;
nameLower.toLowercase();
diff --git a/engines/titanic/core/tree_item.h b/engines/titanic/core/tree_item.h
index db4ba30a44..45ce5164ac 100644
--- a/engines/titanic/core/tree_item.h
+++ b/engines/titanic/core/tree_item.h
@@ -242,6 +242,11 @@ public:
void detach();
/**
+ * Attaches a tree item to a new node
+ */
+ void attach(CTreeItem *item);
+
+ /**
* Finds a tree item by name
*/
CNamedItem *findByName(const CString &name, int maxLen = 0);
diff --git a/engines/titanic/npcs/parrot.cpp b/engines/titanic/npcs/parrot.cpp
index 49e4f4066e..eb3a09ecb2 100644
--- a/engines/titanic/npcs/parrot.cpp
+++ b/engines/titanic/npcs/parrot.cpp
@@ -21,9 +21,31 @@
*/
#include "titanic/npcs/parrot.h"
+#include "titanic/core/project_item.h"
+#include "titanic/carry/carry.h"
+#include "titanic/titanic.h"
namespace Titanic {
+BEGIN_MESSAGE_MAP(CParrot, CTrueTalkNPC)
+ ON_MESSAGE(ActMsg)
+ ON_MESSAGE(MouseButtonDownMsg)
+ ON_MESSAGE(MovieEndMsg)
+ ON_MESSAGE(EnterViewMsg)
+ ON_MESSAGE(TrueTalkTriggerActionMsg)
+ ON_MESSAGE(MouseDragStartMsg)
+ ON_MESSAGE(LeaveViewMsg)
+ ON_MESSAGE(ParrotSpeakMsg)
+ ON_MESSAGE(NPCPlayTalkingAnimationMsg)
+ ON_MESSAGE(NPCPlayIdleAnimationMsg)
+ ON_MESSAGE(FrameMsg)
+ ON_MESSAGE(MovieFrameMsg)
+ ON_MESSAGE(PutParrotBackMsg)
+ ON_MESSAGE(PreEnterViewMsg)
+ ON_MESSAGE(PanningAwayFromParrotMsg)
+ ON_MESSAGE(LeaveRoomMsg)
+END_MESSAGE_MAP()
+
int CParrot::_v1;
int CParrot::_v2;
int CParrot::_v3;
@@ -40,7 +62,7 @@ CParrot::CParrot() : CTrueTalkNPC() {
_field128 = 58;
_field12C = 0;
_field130 = 0;
- _field134 = 0;
+ _field134 = nullptr;
_field138 = 851;
_field13C = 851;
_field140 = 265;
@@ -140,4 +162,293 @@ void CParrot::load(SimpleFile *file) {
CTrueTalkNPC::load(file);
}
+bool CParrot::ActMsg(CActMsg *msg) {
+ if (msg->_action == "PistaccioEaten") {
+ CActMsg actMsg("NutsEaten");
+ actMsg.execute("Ear2");
+ } else if (msg->_action == "Chicken") {
+ // Nothing to do
+ } else if (msg->_action == "CarryParrotLeftView") {
+ if (!_v2) {
+ _v1 = 0;
+ CStatusChangeMsg statusMsg;
+ statusMsg._newStatus = 1;
+ statusMsg.execute("PerchCoreHolder");
+ }
+ } else if (msg->_action == "StartChickenDrag") {
+ if (!_v4) {
+ stopMovie();
+ startTalking(this, 280275, findView());
+ _field12C = 0;
+ }
+ } else if (msg->_action == "EnteringFromTOW" &&
+ (_v4 == 0 || _v4 == 2)) {
+ if (_v2) {
+ _v2 = 2;
+ } else {
+ setVisible(true);
+ CTreeItem *cageBar = getRoot()->findByName("CageBar");
+ detach();
+ attach(cageBar);
+
+ _v4 = 0;
+ CActMsg actMsg1("OpenNow");
+ actMsg1.execute("ParrotCage");
+ CActMsg actMsg2("GainParrot");
+ actMsg2.execute("ParrotLobbyController");
+ }
+ }
+
+ return true;
+}
+
+bool CParrot::MouseButtonDownMsg(CMouseButtonDownMsg *msg) {
+ if (!(_npcFlags & NPCFLAG_2000000) && _field100 <= 0) {
+ CTrueTalkTriggerActionMsg triggerMsg(280250, 280250, 1);
+ triggerMsg.execute(this);
+ }
+
+ return true;
+}
+
+bool CParrot::MovieEndMsg(CMovieEndMsg *msg) {
+ // TODO
+ return true;
+}
+
+bool CParrot::EnterViewMsg(CEnterViewMsg *msg) {
+ static const char *const NAMES[] = {
+ "Talking0", "Talking1", "Talking2", "Talking3", "Talking4",
+ "Talking5", "Talking6", "Talking7", nullptr
+ };
+
+ if (!_v4) {
+ setPosition(Point(_field124, _bounds.top));
+ _field118 = 1;
+ _npcFlags &= ~(NPCFLAG_10000 | NPCFLAG_20000 | NPCFLAG_40000 | NPCFLAG_80000 | NPCFLAG_100000 | NPCFLAG_200000 | NPCFLAG_400000);
+ loadFrame(0);
+ endTalking(this, true, findView());
+
+ if (_field100 > 0) {
+ playRandomClip(NAMES, MOVIE_NOTIFY_OBJECT);
+ } else {
+ startTalking(this, 280258, findView());
+ }
+
+ petSetArea(PET_CONVERSATION);
+ _field12C = 0;
+ _npcFlags |= NPCFLAG_4;
+ }
+
+ return true;
+}
+
+bool CParrot::TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg) {
+ if (_v4) {
+ CViewItem *view = msg->_param2 ? findView() : nullptr;
+ startTalking(this, msg->_action, view);
+ }
+
+ return true;
+}
+
+bool CParrot::MouseDragStartMsg(CMouseDragStartMsg *msg) {
+ if (_field118 && !_v4 && checkPoint(msg->_mousePos, false, true)) {
+ setVisible(false);
+ CRoomItem *room = findRoom();
+
+ moveUnder(room);
+ startTalking(this, 280129);
+ performAction(true);
+
+ CCarry *item = static_cast<CCarry *>(getRoot()->findByName(_string2));
+ if (item) {
+ item->_fieldE0 = 1;
+ CPassOnDragStartMsg passMsg;
+ passMsg._mousePos = msg->_mousePos;
+ passMsg.execute(item);
+ msg->_dragItem = item;
+
+ CActMsg actMsg("LoseParrot");
+ actMsg.execute("ParrotLobbyController");
+ }
+ }
+
+ return true;
+}
+
+bool CParrot::LeaveViewMsg(CLeaveViewMsg *msg) {
+ performAction(true);
+ _npcFlags &= ~NPCFLAG_4;
+
+ return true;
+}
+
+bool CParrot::ParrotSpeakMsg(CParrotSpeakMsg *msg) {
+ // TODO
+ return true;
+}
+
+bool CParrot::NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg) {
+ const char *const NAMES[] = {
+ "Talking0", "Talking1", "Talking2", "Talking3", "Talking4",
+ "Talking5", "Talking6", "Talking7", nullptr
+ };
+
+ if (!(_npcFlags & (NPCFLAG_10000 | NPCFLAG_20000 | NPCFLAG_40000 | NPCFLAG_80000 | NPCFLAG_100000 | NPCFLAG_200000 | NPCFLAG_400000))
+ && _visible && !_v4) {
+ if (!compareViewNameTo("ParrotLobby.Node 1.N"))
+ msg->_names = NAMES;
+ }
+
+ return true;
+}
+
+bool CParrot::NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg) {
+ const char *const NAMES[] = {
+ "Idle0", "Idle1", "Peck At Feet", "Peck At Feet Left"
+ "Peck At Feet Right", nullptr
+ };
+
+ if (!(_npcFlags & (NPCFLAG_10000 | NPCFLAG_20000 | NPCFLAG_40000 | NPCFLAG_80000 | NPCFLAG_100000 | NPCFLAG_200000 | NPCFLAG_400000))
+ && _visible && !_v4 && !compareViewNameTo("ParrotLobby.Node 1.N")) {
+ CGameObject *dragItem = getDraggingObject();
+ if (!dragItem || dragItem->getName() == "Chicken") {
+ if (!_v5 || g_vm->getRandomNumber(3) != 0) {
+ if (g_vm->getRandomNumber(1)) {
+ startTalking(this, 280267, findView());
+ } else {
+ msg->_names = NAMES;
+ }
+ } else {
+ int id = -1;
+ switch (stateGet38()) {
+ case 0:
+ id = 280107;
+ break;
+ case 1:
+ id = 280106;
+ break;
+ case 2:
+ id = 280115;
+ break;
+ case 3:
+ id = 280114;
+ break;
+ case 4:
+ id = 280113;
+ break;
+ case 5:
+ id = 280112;
+ break;
+ case 6:
+ id = 280111;
+ break;
+ case 7:
+ id = 280110;
+ break;
+ case 8:
+ id = 280109;
+ break;
+ case 9:
+ id = 280108;
+ break;
+ case 10:
+ id = 280105;
+ break;
+ case 11:
+ id = 280000;
+ break;
+ default:
+ break;
+ }
+
+ if (id != -1)
+ startTalking(this, id, findView());
+
+ CActMsg actMsg("FlashCore");
+ actMsg.execute("PerchCoreHolder");
+ }
+ }
+ }
+
+ return true;
+}
+
+bool CParrot::FrameMsg(CFrameMsg *msg) {
+ if (compareViewNameTo("ParrotLobby.Node 1.N"))
+ return false;
+ if (_v4)
+ return true;
+
+ Point pt = getMousePos();
+ CGameObject *dragObject = getDraggingObject();
+ int xp = _bounds.left + _bounds.width() / 2;
+//; edi=xp, ebp=dragObject
+ if ((_npcFlags & NPCFLAG_400000) && !hasActiveMovie()) {
+ _field128 = xp - (_field124 + _bounds.width() / 2);
+
+ if (xp < 64) {
+ if (_field134) {
+ CActMsg actMsg("PanAwayFromParrot");
+ actMsg.execute(_field134);
+ }
+
+ _npcFlags &= ~(NPCFLAG_10000 | NPCFLAG_20000 | NPCFLAG_40000
+ | NPCFLAG_80000 | NPCFLAG_100000 | NPCFLAG_200000 | NPCFLAG_400000);
+ return true;
+ }
+ }
+
+ bool chickenFlag = dragObject && dragObject->compareTo("Chicken");
+
+ if (_npcFlags & NPCFLAG_1000000) {
+ if (!chickenFlag || pt.x > 70 || pt.y < 90 || pt.y > 280) {
+ stopMovie();
+ loadFrame(0);
+ setPosition(Point(-90, _bounds.top));
+ }
+ } else {
+ if (!chickenFlag)
+ return false;
+ }
+
+ _field128 = CLIP((int)pt.x, 230, 480);
+ if ((_npcFlags & NPCFLAG_10000) || hasActiveMovie())
+ return true;
+
+ if (_field128 > 64) {
+ _npcFlags |= NPCFLAG_10000 | NPCFLAG_20000;
+
+ // TODO
+ }
+
+ return true;
+}
+
+bool CParrot::MovieFrameMsg(CMovieFrameMsg *msg) {
+ // TODO
+ return true;
+}
+
+bool CParrot::PutParrotBackMsg(CPutParrotBackMsg *msg) {
+ // TODO
+ return true;
+}
+
+bool CParrot::PreEnterViewMsg(CPreEnterViewMsg *msg) {
+ // TODO
+ return true;
+}
+
+bool CParrot::PanningAwayFromParrotMsg(CPanningAwayFromParrotMsg *msg) {
+ // TODO
+ return true;
+}
+
+bool CParrot::LeaveRoomMsg(CLeaveRoomMsg *msg) {
+ // TODO
+ return true;
+}
+
} // End of namespace Titanic
diff --git a/engines/titanic/npcs/parrot.h b/engines/titanic/npcs/parrot.h
index a3c8540f0e..93e0643857 100644
--- a/engines/titanic/npcs/parrot.h
+++ b/engines/titanic/npcs/parrot.h
@@ -28,6 +28,23 @@
namespace Titanic {
class CParrot : public CTrueTalkNPC {
+ DECLARE_MESSAGE_MAP;
+ bool ActMsg(CActMsg *msg);
+ bool MouseButtonDownMsg(CMouseButtonDownMsg *msg);
+ bool MovieEndMsg(CMovieEndMsg *msg);
+ bool EnterViewMsg(CEnterViewMsg *msg);
+ bool TrueTalkTriggerActionMsg(CTrueTalkTriggerActionMsg *msg);
+ bool MouseDragStartMsg(CMouseDragStartMsg *msg);
+ bool LeaveViewMsg(CLeaveViewMsg *msg);
+ bool ParrotSpeakMsg(CParrotSpeakMsg *msg);
+ bool NPCPlayTalkingAnimationMsg(CNPCPlayTalkingAnimationMsg *msg);
+ bool NPCPlayIdleAnimationMsg(CNPCPlayIdleAnimationMsg *msg);
+ bool FrameMsg(CFrameMsg *msg);
+ bool MovieFrameMsg(CMovieFrameMsg *msg);
+ bool PutParrotBackMsg(CPutParrotBackMsg *msg);
+ bool PreEnterViewMsg(CPreEnterViewMsg *msg);
+ bool PanningAwayFromParrotMsg(CPanningAwayFromParrotMsg *msg);
+ bool LeaveRoomMsg(CLeaveRoomMsg *msg);
public:
static int _v1;
static int _v2;
@@ -44,7 +61,7 @@ private:
int _field128;
int _field12C;
int _field130;
- int _field134;
+ CTreeItem *_field134;
int _field138;
int _field13C;
int _field140;