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