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/true_talk/tt_concept.h"
24 #include "titanic/true_talk/script_handler.h"
25 #include "titanic/true_talk/tt_script_base.h"
26 #include "titanic/true_talk/tt_word.h"
27 #include "titanic/titanic.h"
28
29 namespace Titanic {
30
TTconcept()31 TTconcept::TTconcept() : _string1(" "), _string2(" "),
32 _nextP(nullptr), _scriptP(nullptr), _wordP(nullptr), _word2P(nullptr), _status(SS_VALID),
33 _scriptType(ST_UNKNOWN_SCRIPT), _field14(0), _field1C(0), _field20(0), _field30(0), _field34(0) {
34 if (setStatus())
35 setScriptType(ST_UNKNOWN_SCRIPT);
36 else
37 reset();
38 }
39
TTconcept(TTscriptBase * script,ScriptType scriptType)40 TTconcept::TTconcept(TTscriptBase *script, ScriptType scriptType) :
41 _string1(" "), _string2(" "), _nextP(nullptr), _wordP(nullptr), _word2P(nullptr), _scriptP(nullptr),
42 _status(SS_VALID), _scriptType(ST_UNKNOWN_SCRIPT), _field14(0), _field1C(0), _field20(0), _field30(0),
43 _field34(0) {
44 if (!script->getStatus()) {
45 setScriptType(scriptType);
46 _scriptP = script;
47
48 if (scriptType == ST_UNKNOWN_SCRIPT && script->_id == 1)
49 _scriptType = ST_ROOM_SCRIPT;
50 }
51
52 if (_status)
53 reset();
54 }
55
TTconcept(TTword * word,ScriptType scriptType)56 TTconcept::TTconcept(TTword *word, ScriptType scriptType) :
57 _string1(" "), _string2(" "), _nextP(nullptr), _wordP(nullptr), _word2P(nullptr), _scriptP(nullptr),
58 _status(SS_VALID), _scriptType(ST_UNKNOWN_SCRIPT), _field14(0), _field1C(0), _field20(0),
59 _field30(0), _field34(0), _flag(false) {
60 if (!word || !setStatus() || word->getStatus()) {
61 _status = SS_5;
62 } else {
63 _status = initializeWordRef(word);
64 if (!_status)
65 setScriptType(scriptType);
66 }
67
68 if (_status)
69 reset();
70 }
71
TTconcept(TTconcept & src)72 TTconcept::TTconcept(TTconcept &src) :
73 _string1(src._string1), _string2(src._string2), _nextP(nullptr),
74 _wordP(nullptr), _word2P(nullptr), _scriptP(nullptr), _status(SS_VALID),
75 _scriptType(ST_UNKNOWN_SCRIPT), _field14(0), _field1C(0), _field20(0),
76 _field30(0), _field34(0), _flag(false) {
77 if (src.getStatus()) {
78 _status = SS_5;
79 } else {
80 if (setStatus()) {
81 _status = SS_VALID;
82 _scriptP = src._scriptP;
83
84 if (src._wordP) {
85 _status = initializeWordRef(src._wordP);
86 initialize(src);
87 }
88 }
89 }
90
91 if (_status)
92 reset();
93 }
94
~TTconcept()95 TTconcept::~TTconcept() {
96 if (_word2P) {
97 _word2P->deleteSiblings();
98 delete _word2P;
99 }
100 delete _wordP;
101
102 if (_flag)
103 g_vm->_exeResources._owner->setParserConcept(this, nullptr);
104 }
105
deleteSiblings()106 void TTconcept::deleteSiblings() {
107 for (TTconcept *currP = _nextP, *nextP; currP; currP = nextP) {
108 nextP = currP->_nextP;
109 delete currP;
110 }
111
112 _nextP = nullptr;
113 }
114
setStatus()115 bool TTconcept::setStatus() {
116 if (_string1.isValid() && _string2.isValid()) {
117 _status = SS_VALID;
118 return true;
119 } else {
120 _status = SS_11;
121 return false;
122 }
123 }
124
setScriptType(ScriptType scriptType)125 void TTconcept::setScriptType(ScriptType scriptType) {
126 _nextP = nullptr;
127 _field14 = 0;
128 _scriptType = scriptType;
129 _field1C = -1;
130 _field20 = 0;
131 _word2P = nullptr;
132 _field30 = 0;
133 _field34 = 0;
134 _flag = false;
135 _status = 0;
136 }
137
initializeWordRef(TTword * word)138 int TTconcept::initializeWordRef(TTword *word) {
139 delete _wordP;
140 _wordP = word->copy();
141 return 0;
142 }
143
reset()144 void TTconcept::reset() {
145 delete _wordP;
146 _wordP = nullptr;
147 _scriptP = nullptr;
148
149 int oldStatus = _status;
150 setScriptType(ST_UNKNOWN_SCRIPT);
151 _status = oldStatus;
152 }
153
compareTo(const char * str) const154 bool TTconcept::compareTo(const char *str) const {
155 return _wordP != nullptr &&
156 _wordP->compareTo(str);
157 }
158
compareTo(TTword * word) const159 bool TTconcept::compareTo(TTword *word) const {
160 if (_wordP && _wordP->compareTo(word->_text))
161 return true;
162
163 if (_scriptP && _scriptP->getId() == 1 && word->comparePronounTo(1))
164 return true;
165
166 return false;
167 }
168
initialize(TTconcept & src)169 void TTconcept::initialize(TTconcept &src) {
170 _nextP = src._nextP;
171 _field14 = src._field14;
172 _scriptType = src._scriptType;
173 _field1C = src._field1C;
174 _field20 = src._field20;
175
176 if (src._word2P) {
177 _word2P = src._word2P->copyWords();
178 if (src._word2P->getChainStatus())
179 _status = 11;
180 } else {
181 _word2P = nullptr;
182 }
183
184 _field30 = src._field30;
185 _field34 = src._field34;
186
187 if (src._flag) {
188 g_vm->_exeResources._owner->setParserConcept(this, &src);
189 src.setFlag(true);
190 _flag = true;
191 }
192
193 _status = src._status;
194 }
195
copyFrom(TTconcept * src)196 void TTconcept::copyFrom(TTconcept *src) {
197 if (this != src) {
198 if (src->getStatus()) {
199 _status = SS_5;
200 } else {
201 _string1 = src->_string1;
202 _string2 = src->_string2;
203
204 if (setStatus()) {
205 _scriptP = src->_scriptP;
206 if (src->_wordP) {
207 _status = initializeWordRef(src->_wordP);
208 initialize(*src);
209 } else {
210 _wordP = nullptr;
211 initialize(*src);
212 }
213 }
214 }
215 }
216
217 if (_status)
218 reset();
219 }
220
setOwner(TTconcept * src)221 int TTconcept::setOwner(TTconcept *src) {
222 if (src->_wordP) {
223 TTword *newWord = src->_wordP->copy();
224 return setOwner(newWord, 1);
225 }
226
227 return 0;
228 }
229
setOwner(TTword * src,bool dontDup)230 int TTconcept::setOwner(TTword *src, bool dontDup) {
231 TTword *word = dontDup ? src : src->copy();
232
233 if (word) {
234 if (!_word2P) {
235 _word2P = word;
236 } else {
237 // Add word to end of word list
238 TTword *tailP = _word2P;
239 while (tailP->_nextP)
240 tailP = tailP->_nextP;
241
242 tailP->_nextP = word;
243 }
244 }
245
246 return 0;
247 }
248
checkWordId1() const249 bool TTconcept::checkWordId1() const {
250 return (_wordP && (_wordP->_id == 200 || _wordP->_id == 201 ||
251 _wordP->_id == 602 || _wordP->_id == 607)) ||
252 (_scriptP && _scriptP->_id <= 2);
253 }
254
checkWordId2() const255 bool TTconcept::checkWordId2() const {
256 return (_wordP && _wordP->_id == 204) || (_scriptP && _scriptP->getId() == 3);
257 }
258
checkWordId3() const259 bool TTconcept::checkWordId3() const {
260 return isWordClass(WC_ABSTRACT) || isWordClass(WC_ADJECTIVE) ||
261 (isWordClass(WC_ADVERB) && getTheWordId() != 910);
262 }
263
checkWordClass() const264 bool TTconcept::checkWordClass() const {
265 return _scriptP || (_wordP && (_wordP->_wordClass == WC_THING || _wordP->_wordClass == WC_PRONOUN));
266 }
267
getText()268 const TTstring TTconcept::getText() {
269 if (_scriptP)
270 return _scriptP->getText();
271 else if (_wordP)
272 return _wordP->getText();
273 else
274 return TTstring();
275 }
276
findByWordId(int id)277 TTconcept *TTconcept::findByWordId(int id) {
278 for (TTconcept *conceptP = this; conceptP; conceptP = conceptP->_nextP) {
279 if (conceptP->_wordP && conceptP->_wordP->_id == id)
280 return conceptP;
281 }
282
283 return nullptr;
284 }
285
findByWordClass(WordClass wordClass)286 TTconcept *TTconcept::findByWordClass(WordClass wordClass) {
287 for (TTconcept *conceptP = this; conceptP; conceptP = conceptP->_nextP) {
288 if (conceptP->_wordP && conceptP->_wordP->_wordClass == wordClass)
289 return conceptP;
290 }
291
292 return nullptr;
293 }
294
findBy20(int val)295 TTconcept *TTconcept::findBy20(int val) {
296 for (TTconcept *conceptP = this; conceptP; conceptP = conceptP->_nextP) {
297 if (conceptP->_field20 == val)
298 return conceptP;
299 }
300
301 return nullptr;
302 }
303
isTheWordId(int id) const304 bool TTconcept::isTheWordId(int id) const {
305 return _wordP && _wordP->_id == id;
306 }
307
getTheWordId() const308 int TTconcept::getTheWordId() const {
309 return _wordP ? _wordP->_id : 0;
310 }
311
isWordId(const TTconcept * concept,int id)312 bool isWordId(const TTconcept *concept, int id) {
313 return concept ? concept->isTheWordId(id) : 0;
314 }
315
getWordId(const TTconcept * concept)316 int getWordId(const TTconcept *concept) {
317 return concept ? concept->getTheWordId() : 0;
318 }
319
320 } // End of namespace Titanic
321