1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "titanic/messages/messages.h"
24 #include "titanic/core/game_object.h"
25 #include "titanic/core/message_target.h"
26 #include "titanic/core/project_item.h"
27 #include "titanic/core/tree_item.h"
28 #include "titanic/main_game_window.h"
29 #include "titanic/messages/mouse_messages.h"
30 #include "titanic/pet_control/pet_control.h"
31 #include "titanic/titanic.h"
32
33 namespace Titanic {
34
CMessage()35 CMessage::CMessage() : CSaveableObject() {
36 }
37
save(SimpleFile * file,int indent)38 void CMessage::save(SimpleFile *file, int indent) {
39 file->writeNumberLine(0, indent);
40 }
41
load(SimpleFile * file)42 void CMessage::load(SimpleFile *file) {
43 file->readNumber();
44 CSaveableObject::load(file);
45 }
46
execute(CTreeItem * target,const ClassDef * classDef,int flags)47 bool CMessage::execute(CTreeItem *target, const ClassDef *classDef, int flags) {
48 // If no target was specified, then there's nothing to do
49 if (!target)
50 return false;
51
52 bool result = false;
53 CTreeItem *item = target;
54 CTreeItem *nextItem = nullptr;
55 do {
56 if (flags & MSGFLAG_SCAN)
57 nextItem = item->scan(target);
58
59 if (!classDef || item->isInstanceOf(classDef)) {
60 bool handled = perform(item);
61
62 if (handled) {
63 result = true;
64 if (flags & MSGFLAG_BREAK_IF_HANDLED)
65 return true;
66 }
67 }
68
69 item = nextItem;
70 } while (nextItem);
71
72 return result;
73 }
74
execute(const CString & target,const ClassDef * classDef,int flags)75 bool CMessage::execute(const CString &target, const ClassDef *classDef, int flags) {
76 // Scan for the target by name
77 CProjectItem *project = g_vm->_window->_project;
78 for (CTreeItem *treeItem = project; treeItem; treeItem = treeItem->scan(project)) {
79 if (!treeItem->getName().compareToIgnoreCase(target))
80 return execute(treeItem, classDef, flags);
81 }
82
83 return false;
84 }
85
findMapEntry(const CTreeItem * treeItem,const ClassDef * classDef)86 const MSGMAP_ENTRY *CMessage::findMapEntry(const CTreeItem *treeItem, const ClassDef *classDef) {
87 // Iterate through the class and any parent classes
88 for (const MSGMAP *msgMap = treeItem->getMessageMap(); msgMap->pFnGetBaseMap;
89 msgMap = msgMap->pFnGetBaseMap()) {
90 // Iterate through the map entries for this class
91 for (const MSGMAP_ENTRY *entry = msgMap->lpEntries;
92 entry->_class != nullptr; ++entry) {
93 // Check if the class or any of it's ancesotrs is handled by this entry
94 for (const ClassDef *entryDef = *entry->_class; entryDef;
95 entryDef = entryDef->_parent) {
96 if (entryDef == classDef)
97 return entry;
98 }
99 }
100 }
101
102 return nullptr;
103 }
104
perform(CTreeItem * treeItem)105 bool CMessage::perform(CTreeItem *treeItem) {
106 const MSGMAP_ENTRY *entry = findMapEntry(treeItem, getType());
107 return entry && (*treeItem.*(entry->_fn))(this);
108 }
109
supports(const CTreeItem * treeItem,ClassDef * classDef)110 bool CMessage::supports(const CTreeItem *treeItem, ClassDef *classDef) {
111 return findMapEntry(treeItem, classDef) != nullptr;
112 }
113
isMouseMsg() const114 bool CMessage::isMouseMsg() const {
115 return dynamic_cast<const CMouseMsg *>(this) != nullptr;
116 }
117
isButtonDownMsg() const118 bool CMessage::isButtonDownMsg() const {
119 return dynamic_cast<const CMouseButtonDownMsg *>(this) != nullptr;
120 }
121
isButtonUpMsg() const122 bool CMessage::isButtonUpMsg() const {
123 return dynamic_cast<const CMouseButtonUpMsg *>(this) != nullptr;
124 }
125
isMouseMoveMsg() const126 bool CMessage::isMouseMoveMsg() const {
127 return dynamic_cast<const CMouseMoveMsg *>(this) != nullptr;
128 }
129
isDoubleClickMsg() const130 bool CMessage::isDoubleClickMsg() const {
131 return dynamic_cast<const CMouseDoubleClickMsg *>(this) != nullptr;
132 }
133
isEnterRoomMsg() const134 bool CMessage::isEnterRoomMsg() const {
135 return dynamic_cast<const CEnterRoomMsg *>(this) != nullptr;
136 }
137
isPreEnterRoomMsg() const138 bool CMessage::isPreEnterRoomMsg() const {
139 return dynamic_cast<const CPreEnterRoomMsg *>(this) != nullptr;
140 }
141
isleaveRoomMsg() const142 bool CMessage::isleaveRoomMsg() const {
143 return dynamic_cast<const CLeaveRoomMsg *>(this) != nullptr;
144 }
145
isEnterNodeMsg() const146 bool CMessage::isEnterNodeMsg() const {
147 return dynamic_cast<const CEnterNodeMsg *>(this) != nullptr;
148 }
149
isPreEnterNodeMsg() const150 bool CMessage::isPreEnterNodeMsg() const {
151 return dynamic_cast<const CPreEnterNodeMsg *>(this) != nullptr;
152 }
153
isLeaveNodeMsg() const154 bool CMessage::isLeaveNodeMsg() const {
155 return dynamic_cast<const CLeaveNodeMsg *>(this) != nullptr;
156 }
157
isEnterViewMsg() const158 bool CMessage::isEnterViewMsg() const {
159 return dynamic_cast<const CEnterViewMsg *>(this) != nullptr;
160 }
161
isPreEnterViewMsg() const162 bool CMessage::isPreEnterViewMsg() const {
163 return dynamic_cast<const CPreEnterViewMsg *>(this) != nullptr;
164 }
165
isLeaveViewMsg() const166 bool CMessage::isLeaveViewMsg() const {
167 return dynamic_cast<const CLeaveViewMsg *>(this) != nullptr;
168 }
169
170 /*------------------------------------------------------------------------*/
171
CShowTextMsg()172 CShowTextMsg::CShowTextMsg() : CMessage(), _message("NO TEXT INCLUDED!!!") {
173 }
174
CShowTextMsg(const CString & msg)175 CShowTextMsg::CShowTextMsg(const CString &msg) : CMessage(), _message(msg) {
176 }
177
CShowTextMsg(StringId stringId)178 CShowTextMsg::CShowTextMsg(StringId stringId) : CMessage() {
179 _message = g_vm->_strings[stringId];
180 }
181
182 /*------------------------------------------------------------------------*/
183
getMovement(Common::KeyCode keycode)184 Movement CMovementMsg::getMovement(Common::KeyCode keycode) {
185 switch (keycode) {
186 case Common::KEYCODE_LEFT:
187 case Common::KEYCODE_KP4:
188 return TURN_LEFT;
189 case Common::KEYCODE_RIGHT:
190 case Common::KEYCODE_KP6:
191 return TURN_RIGHT;
192 case Common::KEYCODE_UP:
193 case Common::KEYCODE_KP8:
194 return MOVE_FORWARDS;
195 case Common::KEYCODE_DOWN:
196 case Common::KEYCODE_KP2:
197 return MOVE_BACKWARDS;
198 default:
199 return MOVE_NONE;
200 }
201 }
202
203 } // End of namespace Titanic
204