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 "common/textconsole.h"
24 #include "titanic/true_talk/doorbot_script.h"
25 #include "titanic/true_talk/tt_room_script.h"
26 #include "titanic/true_talk/true_talk_manager.h"
27 #include "titanic/translation.h"
28 #include "titanic/titanic.h"
29 
30 namespace Titanic {
31 
32 static const int STATE_ARRAY_EN[9] = {
33 	11818, 11819, 11820, 11821, 11822, 11823, 11824, 11825, 11826
34 };
35 static const int STATE_ARRAY_DE[9] = {
36 	11831, 11832, 11833, 11834, 11835, 11836, 11837, 11838, 11839
37 };
38 
39 static const RoomDialogueId ROOM_DIALOGUES1_EN[] = {
40 	{ 100, 10523 }, { 101, 10499 }, { 107, 10516 }, { 108, 10500 },
41 	{ 109, 10490 }, { 110, 10504 }, { 111, 10506 }, { 112, 10498 },
42 	{ 113, 10502 }, { 114, 10507 }, { 115, 10497 }, { 116, 10508 },
43 	{ 117, 10505 }, { 118, 10505 }, { 122, 10516 }, { 123, 10383 },
44 	{ 124, 10510 }, { 125, 10511 }, { 126, 10513 }, { 127, 10512 },
45 	{ 128, 10495 }, { 129, 10496 }, { 130, 10491 }, { 131, 10493 },
46 	{ 132, 10492 }, { 0, 0 }
47 };
48 static const RoomDialogueId ROOM_DIALOGUES1_DE[] = {
49 	{ 101, 10375 }, { 107, 10379 }, { 108, 10378 }, { 109, 10364 },
50 	{ 110, 10377 }, { 111, 10383 }, { 112, 10374 }, { 113, 10376 },
51 	{ 114, 10384 }, { 115, 10373 }, { 116, 10385 }, { 117, 10380 },
52 	{ 118, 10380 }, { 122, 10392 }, { 123, 10390 }, { 124, 10386 },
53 	{ 125, 10387 }, { 126, 10389 }, { 127, 10388 }, { 128, 10371 },
54 	{ 129, 10372 }, { 130, 10366 }, { 131, 10368 }, { 132, 10367 },
55 	{ 0, 0 }
56 };
57 
58 static const RoomDialogueId ROOM_DIALOGUES2_EN[] = {
59 	{ 102, 221981 }, { 110, 221948 }, { 111, 221968 }, { 107, 222000 },
60 	{ 101, 221935 }, { 112, 221924 }, { 113, 221942 }, { 116, 221977 },
61 	{ 124, 221987 }, { 125, 221984 }, { 127, 221991 }, { 128, 221916 },
62 	{ 129, 221919 }, { 131, 221912 }, { 132, 221908 }, { 0, 0 }
63 };
64 static const RoomDialogueId ROOM_DIALOGUES2_DE[] = {
65 	{ 102, 221981 }, { 110, 221948 }, { 111, 221968 }, { 107, 222000 },
66 	{ 101, 221935 }, { 112, 221924 }, { 113, 221942 }, { 116, 221977 },
67 	{ 124, 221987 }, { 125, 221984 }, { 127, 221991 }, { 128, 221916 },
68 	{ 129, 221919 }, { 131, 221912 }, { 132, 221909 }, { 0, 0 }
69 };
70 
DoorbotScript(int val1,const char * charClass,int v2,const char * charName,int v3,int val2,int v4,int v5,int v6,int v7)71 DoorbotScript::DoorbotScript(int val1, const char *charClass, int v2,
72 		const char *charName, int v3, int val2, int v4, int v5, int v6, int v7) :
73 		TTnpcScript(val1, charClass, v2, charName, v3, val2, v4, v5, v6, v7) {
74 	_stateIndex = _doorbotState = 0;
75 
76 	loadRanges("Ranges/Doorbot");
77 	loadResponses("Responses/Doorbot");
78 	setupSentences();
79 	_tagMappings.load("TagMap/Doorbot");
80 	_words.load("Words/Doorbot");
81 	_quotes.load("Quotes/Doorbot");
82 	_states.load("States/Doorbot");
83 }
84 
~DoorbotScript()85 DoorbotScript::~DoorbotScript() {
86 	for (int idx = 0; idx < 11; ++idx)
87 		_sentences[idx].clear();
88 }
89 
setupSentences()90 void DoorbotScript::setupSentences() {
91 	for (int idx = 35; idx < 40; ++idx)
92 		CTrueTalkManager::setFlags(idx, 0);
93 	_doorbotState = 1;
94 	_field68 = 0;
95 	_entryCount = 0;
96 	_dialValues[0] = _dialValues[1] = 100;
97 
98 	_mappings.load("Mappings/Doorbot", 4);
99 	_entries.load("Sentences/Doorbot");
100 
101 	static const int SENTENCE_NUMS[11] = {
102 		2, 100, 101, 102, 107, 110, 111, 124, 129, 131, 132
103 	};
104 	for (int idx = 0; idx < 11; ++idx) {
105 		_sentences[idx] = TTsentenceEntries();
106 		_sentences[idx].load(CString::format("Sentences/Doorbot/%d", SENTENCE_NUMS[idx]));
107 	}
108 }
109 
chooseResponse(const TTroomScript * roomScript,const TTsentence * sentence,uint tag)110 int DoorbotScript::chooseResponse(const TTroomScript *roomScript, const TTsentence *sentence, uint tag) {
111 	if (tag == MKTAG('D', 'N', 'A', '1') || tag == MKTAG('H', 'H', 'G', 'Q') ||
112 		tag == MKTAG('A', 'N', 'S', 'W') || tag == MKTAG('S', 'U', 'M', 'S')) {
113 		if (_stateIndex > 8)
114 			_stateIndex = 0;
115 		addResponse(TRANSLATE(STATE_ARRAY_EN[_stateIndex], STATE_ARRAY_DE[_stateIndex]));
116 		applyResponse();
117 
118 		if (_stateIndex == 8)
119 			setState(1);
120 		++_stateIndex;
121 		return 2;
122 	}
123 
124 	if (tag == MKTAG('C', 'H', 'S', 'E') || tag == MKTAG('C', 'M', 'N', 'T') ||
125 			tag == MKTAG('J', 'F', 'O', 'D'))
126 		tag = MKTAG('F', 'O', 'O', 'D');
127 
128 	if (tag == MKTAG('F', 'O', 'O', 'D') && roomScript->_scriptId == 132) {
129 		return setResponse(getDialogueId(220818));
130 	}
131 
132 	if (tag == MKTAG('T', 'R', 'A', 'V')) {
133 		return setResponse(11858 - getRandomBit());
134 	} else if (tag == MKTAG('C', 'S', 'P', 'Y')) {
135 		return setResponse(10405, 3);
136 	} else if (tag == MKTAG('S', 'C', 'I', 'T')) {
137 		return setResponse(10410, 14);
138 	} else if (tag == MKTAG('L', 'I', 'T', 'E')) {
139 		return setResponse(10296, 17);
140 	} else if (tag == MKTAG('D', 'O', 'R', '1')) {
141 		return setResponse(getDialogueId(222034));
142 	} else if (tag == MKTAG('W', 'T', 'H', 'R')) {
143 		return setResponse(getDialogueId(222126));
144 	} else if (tag == MKTAG('N', 'A', 'U', 'T')) {
145 		return setResponse(getDialogueId(222259));
146 	} else if (tag == MKTAG('T', 'R', 'A', '2')) {
147 		return setResponse(getRandomBit() ? TRANSLATE(11860, 11873)
148 			: TRANSLATE(11858, 11871));
149 	} else if (tag == MKTAG('T', 'R', 'A', '3')) {
150 		return setResponse(getRandomBit() ? TRANSLATE(11859, 11872)
151 			: TRANSLATE(11857, 11870));
152 	} else if (tag == MKTAG('B', 'R', 'N', 'D')) {
153 		switch (getRandomNumber(3)) {
154 		case 1:
155 			tag = MKTAG('B', 'R', 'N', '2');
156 			break;
157 		case 2:
158 			tag = MKTAG('B', 'R', 'N', '3');
159 			break;
160 		default:
161 			break;
162 		}
163 	} else if (g_language == Common::DE_DEU && tag == MKTAG('K', 'O', 'H', 'L')) {
164 		return setResponse(getDialogueId(220976));
165 	}
166 
167 	return TTnpcScript::chooseResponse(roomScript, sentence, tag);
168 }
169 
process(const TTroomScript * roomScript,const TTsentence * sentence)170 int DoorbotScript::process(const TTroomScript *roomScript, const TTsentence *sentence) {
171 	int currState;
172 
173 	switch (roomScript->_scriptId) {
174 	case 100:
175 	case 101:
176 	case 102:
177 	case 103:
178 	case 104:
179 	case 106:
180 	case 107:
181 	case 108:
182 	case 109:
183 	case 110:
184 	case 111:
185 	case 113:
186 	case 116:
187 	case 117:
188 	case 118:
189 	case 122:
190 	case 123:
191 	case 124:
192 	case 125:
193 	case 126:
194 	case 127:
195 	case 128:
196 	case 129:
197 	case 130:
198 	case 131:
199 	case 132:
200 		break;
201 
202 	default:
203 		return 2;
204 	}
205 
206 	checkItems(nullptr, nullptr);
207 	if (getState() == 0) {
208 		if (CTrueTalkManager::_v2 > getValue(36)) {
209 			if (getDialRegion(1) == 1 && getRandomBit()) {
210 				setDialRegion(0, getDialRegion(1) ? 0 : 1);
211 			} else {
212 				setDialRegion(1, getDialRegion(1) ? 0 : 1);
213 			}
214 			CTrueTalkManager::setFlags(36, CTrueTalkManager::_v2 + 3 + getRandomNumber(5));
215 
216 			if (getValue(37)) {
217 				CTrueTalkManager::setFlags(37, 0);
218 				setState(0);
219 				return setResponse(getDialogueId(221140));
220 			}
221 		}
222 	}
223 
224 	if (getValue(35) == 0 && roomScript->_scriptId != 100 && sentence->localWord("parrot")) {
225 		CTrueTalkManager::setFlags(35, 1);
226 		setState(0);
227 		return setResponse(getDialogueId(220113));
228 	}
229 
230 	if (sentence->_category == 6 && (sentence->contains("why not") ||
231 				sentence->contains("warum nicht"))) {
232 		return setResponse(11871, 8);
233 	}
234 
235 	currState = getState();
236 	if (currState) {
237 		int sentMode = sentence->_category;
238 		bool flag1 = sentMode == 11 || sentMode == 13;
239 		bool flag2 = sentMode == 12;
240 
241 		switch (currState) {
242 		case 1:
243 			if (flag1)
244 				return setResponse(TRANSLATE(11828, 11841), 2);
245 			if (flag2)
246 				return setResponse(TRANSLATE(11827, 11840), 0);
247 			break;
248 
249 		case 2:
250 			if (flag1)
251 				return setResponse(TRANSLATE(11827, 11840), 0);
252 			break;
253 
254 		case 3:
255 			if (sentMode == 3)
256 				return setResponse(TRANSLATE(10406, 10417), 0);
257 			break;
258 
259 		case 4:
260 			if (flag1)
261 				return setResponse(TRANSLATE(11332, 11345), 0);
262 			if (flag2)
263 				return setResponse(TRANSLATE(11331, 11344), 0);
264 			break;
265 
266 		case 5:
267 			if (g_language == Common::EN_ANY)
268 				return setResponse(11868, 0);
269 			break;
270 
271 		case 6:
272 			return setResponse(TRANSLATE(11872, 11885), 7);
273 
274 		case 7:
275 			return setResponse(TRANSLATE(11869, 11882), 0);
276 
277 		case 8:
278 			return setResponse(TRANSLATE(11870, 11883), 0);
279 
280 		case 12:
281 			if (flag1)
282 				return setResponse(TRANSLATE(11894, 11907), 13);
283 			if (flag2)
284 				return setResponse(TRANSLATE(11893, 11906), 13);
285 			break;
286 
287 		case 13:
288 			return setResponse(TRANSLATE(11895, 11908), 12);
289 
290 		case 15:
291 			if (sentMode == 3 || sentMode == 6)
292 				return setResponse(TRANSLATE(10257, 10260), 0);
293 			break;
294 
295 		case 16: {
296 			TTtreeResult treeResult[32];
297 			if (g_vm->_trueTalkManager->_quotesTree.search(sentence->_normalizedLine.c_str(),
298 					TREE_3, &treeResult[0], 0, nullptr) != -1)
299 				return setResponse(getDialogueId(221380), 0);
300 			break;
301 		}
302 
303 		case 17:
304 			return setResponse(getDialogueId(221126), 0);
305 
306 		case 18:
307 			if (flag1)
308 				return setResponse(getDialogueId(221135), 0);
309 			if (flag2)
310 				return setResponse(getDialogueId(221134), 0);
311 			break;
312 
313 		case 19:
314 			if (flag1) {
315 				if (addRandomResponse(true)) {
316 					setState(10);
317 					return 2;
318 				}
319 			}
320 			if (flag2)
321 				return setResponse(getDialogueId(221966), 0);
322 			break;
323 
324 		case 20:
325 			if (flag1) {
326 				if (addRandomResponse(true)) {
327 					setState(19);
328 					return 2;
329 				}
330 			}
331 			if (flag2 || sentMode == 7 || sentMode == 10) {
332 				return setResponse(getDialogueId(221879), 0);
333 			}
334 			break;
335 
336 		case 21:
337 			if (flag2)
338 				return setResponse(TRANSLATE(10935, 10947), 0);
339 			break;
340 
341 		case 22:
342 			if (flag1) {
343 				if (getRandomBit()) {
344 					return setResponse(TRANSLATE(11211, 11223), 23);
345 				} else {
346 					return setResponse(TRANSLATE(10127, 10128), 0);
347 				}
348 			}
349 			if (flag2)
350 				return setResponse(TRANSLATE(10136, 10137), 0);
351 			break;
352 
353 		case 23:
354 			return setResponse(TRANSLATE(10212, 10213), 0);
355 
356 		case 24:
357 			if (flag1)
358 				return setResponse(TRANSLATE(11151, 11163), 0);
359 			if (flag2)
360 				return setResponse(TRANSLATE(11150, 11162), 0);
361 			break;
362 
363 		case 25:
364 		case 26:
365 			if (flag2) {
366 				if (getRandomBit()) {
367 					return setResponse(TRANSLATE(11211, 11223), 23);
368 				} else {
369 					return setResponse(TRANSLATE(10127, 10128), 0);
370 				}
371 			}
372 			if (flag1)
373 				return setResponse(TRANSLATE(10136, 10137), 0);
374 			break;
375 
376 		case 27:
377 			if (flag1 || sentence->localWord("did") || sentence->contains("did"))
378 				return setResponse(getDialogueId(221175), 28);
379 			break;
380 
381 		case 28:
382 			if (flag1 || sentence->localWord("did") || sentence->contains("did"))
383 				return setResponse(getDialogueId(221176), 29);
384 			break;
385 
386 		case 29:
387 			if (flag1 || sentence->localWord("did") || sentence->contains("did"))
388 				return setResponse(getDialogueId(221177), 30);
389 			break;
390 
391 		case 30:
392 			return setResponse(getDialogueId(221178), 31);
393 
394 		case 31:
395 			if (sentMode == 3 || sentMode == 10)
396 				return setResponse(TRANSLATE(10350, 10353), 0);
397 			break;
398 
399 		case 32:
400 			return setResponse(TRANSLATE(10110, 10111), 0);
401 
402 		case 33:
403 			if (sentence->contains("sieve") || sentence->contains("colander")
404 					|| sentence->contains("vegetable") || sentence->contains("ground")
405 					|| sentence->contains("earth") || sentence->contains("garden")
406 					|| sentence->contains("cheese") || sentence->contains("strainer")
407 					|| sentence->contains("sieb") || sentence->contains("emmenthaler")
408 					|| sentence->contains("gemuese") || sentence->contains("kaese")
409 					|| sentence->contains("erde") || sentence->contains("garten")) {
410 				return setResponse(getDialogueId(221375), 0);
411 			} else if (getRandomNumber(100) > 30) {
412 				return setResponse(getDialogueId(221376), 33);
413 			} else {
414 				return setResponse(getDialogueId(221376), 0);
415 			}
416 			break;
417 
418 		case 34:
419 			if (sentence->localWord("bellbot"))
420 				return setResponse(TRANSLATE(10094, 10095), 0);
421 			if (sentence->localWord("doorbot"))
422 				return setResponse(TRANSLATE(10349, 10352), 0);
423 
424 			if (g_language == Common::EN_ANY) {
425 				if (sentence->localWord("deskbot") || sentence->localWord("titania"))
426 					return setResponse(10148, 0);
427 				if (sentence->localWord("barbot") || sentence->localWord("rowbot")
428 					|| sentence->localWord("liftbot") || sentence->localWord("maitredbot"))
429 					return setResponse(10147, 0);
430 			}
431 			break;
432 
433 		case 35:
434 			return setResponse(TRANSLATE(10811, 10822), 36);
435 
436 		case 36:
437 			if (flag1)
438 				return setResponse(TRANSLATE(10813, 10824), 37);
439 			if (flag2)
440 				return setResponse(TRANSLATE(10812, 10823), 37);
441 			break;
442 
443 		case 37:
444 			if (flag1)
445 				return setResponse(TRANSLATE(10815, 10826), 37);
446 			if (flag2)
447 				return setResponse(TRANSLATE(10814, 10825), 37);
448 			break;
449 
450 		case 38:
451 			if (g_language == Common::EN_ANY)
452 				return setResponse(10848, 39);
453 			break;
454 
455 		case 39:
456 			if (g_language == Common::EN_ANY)
457 				return setResponse(10823, 40);
458 			break;
459 
460 		case 40:
461 			return setResponse(TRANSLATE(10832, 10843), 41);
462 
463 		case 41:
464 			addResponse(TRANSLATE(10833, 10844));
465 			return setResponse(TRANSLATE(10835, 10846), 0);
466 
467 		case 42:
468 			if (sentence->localWord("please"))
469 				return setResponse(TRANSLATE(10840, 10851), 43);
470 			return setResponse(TRANSLATE(10844, 10855), 0);
471 
472 		case 43:
473 		case 45:
474 			return setResponse(TRANSLATE(10844, 10855), 0);
475 
476 		case 44:
477 			if (sentence->localWord("thanks"))
478 				return setResponse(TRANSLATE(10843, 10854), 45);
479 			return setResponse(TRANSLATE(10844, 10855), 0);
480 
481 		case 46:
482 			if (flag1)
483 				return setResponse(getDialogueId(222251), 0);
484 			if (g_language == Common::EN_ANY && flag2)
485 				return setResponse(10713, 0);
486 			break;
487 
488 		default:
489 			break;
490 		}
491 	}
492 
493 	if (currState != 14)
494 		setState(0);
495 
496 	if (getDialRegion(1) != 1 && getRandomNumber(100) > 92)
497 		return setResponse(getDialogueId(221043), 0);
498 
499 	int result = 0;
500 	if (g_language == Common::EN_ANY) {
501 		switch (roomScript->_scriptId) {
502 		case 100:
503 		case 101:
504 		case 102:
505 		case 107:
506 		case 110:
507 		case 111:
508 		case 124:
509 		case 129:
510 		case 131:
511 		case 132:
512 			result = processEntries(&_sentences[roomScript->_scriptId], 0, roomScript, sentence);
513 			break;
514 		default:
515 			break;
516 		}
517 
518 		if (result == 2)
519 			return 2;
520 	}
521 
522 	if (processEntries(&_entries, _entryCount, roomScript, sentence) == 2
523 			|| processEntries(_defaultEntries, 0, roomScript, sentence) == 2
524 			|| defaultProcess(roomScript, sentence))
525 		return 2;
526 
527 	if (g_language == Common::DE_DEU && sentence->contains("42")) {
528 		selectResponse(11831);
529 		applyResponse();
530 		return 2;
531 	}
532 
533 	switch (sentence->_category) {
534 	case 11:
535 		if (getRandomNumber(100) > 90)
536 			return setResponse(TRANSLATE(10839, 10850), 42);
537 		return setResponse(getDialogueId(222415), 0);
538 
539 	case 12:
540 		if (getRandomNumber(100) > 90)
541 			return setResponse(TRANSLATE(10841, 10852), 44);
542 		return setResponse(getDialogueId(222416), 0);
543 
544 	case 13:
545 		return setResponse(getDialogueId(222415), 0);
546 
547 	default:
548 		if (getRandomNumber(100) > 75 && getStateValue())
549 			return setResponse(getDialogueId(221095));
550 
551 		if (processEntries(&_sentences[2], 0, roomScript, sentence) != 2)
552 			return setResponse(getDialogueId(220000));
553 		break;
554 	}
555 
556 	return 2;
557 }
558 
scriptChanged(const TTroomScript * roomScript,uint id)559 ScriptChangedResult DoorbotScript::scriptChanged(const TTroomScript *roomScript, uint id) {
560 	if (id == 3) {
561 		if (roomScript != nullptr  && roomScript->_scriptId != 100) {
562 			if (CTrueTalkManager::_v9 == 101) {
563 				addResponse(getDialogueId(220873));
564 				applyResponse();
565 			} else {
566 				bool flag = false;
567 				if (CTrueTalkManager::_currentNPC) {
568 					CGameObject *obj;
569 					if (CTrueTalkManager::_currentNPC->find("Magazine", &obj, FIND_PET)) {
570 						setResponse(getDialogueId(222248), 46);
571 						flag = true;
572 					}
573 				}
574 
575 				if (!flag) {
576 					if (getRandomNumber(100) > 80 && getStateValue()) {
577 						addResponse(getDialogueId(221095));
578 						applyResponse();
579 						flag = true;
580 					}
581 
582 					if (!flag && (_doorbotState || !fn10(true))) {
583 						addResponse(getDialogueId(220074));
584 						applyResponse();
585 					}
586 				}
587 			}
588 		}
589 
590 		_doorbotState = 0;
591 		resetFlags();
592 		CTrueTalkManager::_v9 = 0;
593 	} else if (id == 4) {
594 		setState(0);
595 		if (getValue(38) == 0) {
596 			addResponse(getDialogueId(220883));
597 			applyResponse();
598 		}
599 
600 		CTrueTalkManager::setFlags(38, 0);
601 		CTrueTalkManager::setFlags(39, 0);
602 	}
603 
604 	if (id >= 220000 && id <= (uint)TRANSLATE(222418, 222430)) {
605 		addResponse(getDialogueId(id));
606 		applyResponse();
607 	} else if (id >= 10000 && id <= (uint)TRANSLATE(11986, 11999)) {
608 		addResponse(id);
609 		applyResponse();
610 	}
611 
612 	return SCR_2;
613 }
614 
handleQuote(const TTroomScript * roomScript,const TTsentence * sentence,uint tag1,uint tag2,uint remainder)615 int DoorbotScript::handleQuote(const TTroomScript *roomScript, const TTsentence *sentence,
616 		uint tag1, uint tag2, uint remainder) {
617 	switch (tag2) {
618 	case MKTAG('A', 'D', 'V', 'T'):
619 	case MKTAG('A', 'R', 'T', 'I'):
620 	case MKTAG('A', 'R', 'T', 'Y'):
621 	case MKTAG('B', 'R', 'N', 'D'):
622 	case MKTAG('C', 'O', 'M', 'D'):
623 	case MKTAG('D', 'N', 'C', 'E'):
624 	case MKTAG('H', 'B', 'B', 'Y'):
625 	case MKTAG('L', 'I', 'T', 'R'):
626 	case MKTAG('M', 'A', 'G', 'S'):
627 	case MKTAG('M', 'C', 'P', 'Y'):
628 	case MKTAG('M', 'I', 'N', 'S'):
629 	case MKTAG('M', 'U', 'S', 'I'):
630 	case MKTAG('N', 'I', 'K', 'E'):
631 	case MKTAG('S', 'F', 'S', 'F'):
632 	case MKTAG('S', 'O', 'A', 'P'):
633 	case MKTAG('S', 'O', 'N', 'G'):
634 	case MKTAG('S', 'P', 'R', 'T'):
635 	case MKTAG('T', 'E', 'A', 'M'):
636 	case MKTAG('T', 'V', 'S', 'H'):
637 	case MKTAG('W', 'W', 'E', 'B'):
638 		tag2 = MKTAG('E', 'N', 'T', 'N');
639 		break;
640 	case MKTAG('A', 'C', 'T', 'R'):
641 	case MKTAG('A', 'C', 'T', 'S'):
642 	case MKTAG('A', 'U', 'T', 'H'):
643 	case MKTAG('B', 'A', 'R', 'K'):
644 	case MKTAG('B', 'A', 'R', 'U'):
645 	case MKTAG('B', 'L', 'F', '1'):
646 	case MKTAG('B', 'L', 'F', '2'):
647 	case MKTAG('B', 'L', 'P', '1'):
648 	case MKTAG('B', 'L', 'P', '2'):
649 	case MKTAG('B', 'L', 'P', '3'):
650 	case MKTAG('B', 'L', 'P', '4'):
651 	case MKTAG('B', 'L', 'T', '1'):
652 	case MKTAG('B', 'L', 'T', '2'):
653 	case MKTAG('B', 'L', 'T', '3'):
654 	case MKTAG('B', 'L', 'T', '4'):
655 	case MKTAG('B', 'L', 'T', '5'):
656 	case MKTAG('B', 'O', 'Y', 'S'):
657 	case MKTAG('D', 'C', 'T', 'R'):
658 	case MKTAG('F', 'A', 'M', 'E'):
659 	case MKTAG('F', 'A', 'S', 'H'):
660 	case MKTAG('G', 'I', 'R', 'L'):
661 	case MKTAG('H', 'E', 'R', 'O'):
662 	case MKTAG('H', 'O', 'S', 'T'):
663 	case MKTAG('K', 'N', 'O', 'B'):
664 	case MKTAG('N', 'H', 'R', 'O'):
665 	case MKTAG('R', 'A', 'C', 'E'):
666 	case MKTAG('S', 'C', 'I', 'T'):
667 	case MKTAG('T', 'D', 'V', 'P'):
668 	case MKTAG('T', 'W', 'A', 'T'):
669 	case MKTAG('W', 'E', 'A', 'T'):
670 		tag2 = MKTAG('P', 'R', 'S', 'N');
671 		break;
672 	case MKTAG('C', 'H', 'S', 'E'):
673 	case MKTAG('C', 'M', 'N', 'T'):
674 	case MKTAG('F', 'I', 'L', 'M'):
675 	case MKTAG('J', 'F', 'O', 'D'):
676 	case MKTAG('L', 'I', 'Q', 'D'):
677 		tag2 = MKTAG('F', 'O', 'O', 'D');
678 		break;
679 	case MKTAG('C', 'R', 'I', 'M'):
680 	case MKTAG('C', 'S', 'P', 'Y'):
681 	case MKTAG('D', 'R', 'U', 'G'):
682 		tag2 = MKTAG('V', 'B', 'A', 'D');
683 		break;
684 	case MKTAG('E', 'A', 'R', 'T'):
685 	case MKTAG('H', 'O', 'M', 'E'):
686 	case MKTAG('N', 'P', 'L', 'C'):
687 	case MKTAG('P', 'L', 'A', 'N'):
688 		tag2 = MKTAG('P', 'L', 'A', 'C');
689 		break;
690 	case MKTAG('F', 'A', 'U', 'N'):
691 	case MKTAG('F', 'I', 'S', 'H'):
692 	case MKTAG('F', 'L', 'O', 'R'):
693 		tag2 = MKTAG('N', 'A', 'T', 'R');
694 		break;
695 	case MKTAG('H', 'H', 'L', 'D'):
696 	case MKTAG('T', 'O', 'Y', 'S'):
697 	case MKTAG('W', 'E', 'A', 'P'):
698 		tag2 = MKTAG('M', 'A', 'C', 'H');
699 		break;
700 	case MKTAG('M', 'L', 'T', 'Y'):
701 	case MKTAG('P', 'G', 'R', 'P'):
702 	case MKTAG('P', 'T', 'I', 'C'):
703 		tag2 = MKTAG('G', 'R', 'U', 'P');
704 		break;
705 	case MKTAG('P', 'K', 'U', 'P'):
706 	case MKTAG('S', 'E', 'X', '1'):
707 	case MKTAG('S', 'W', 'E', 'R'):
708 		tag2 = MKTAG('R', 'U', 'D', 'E');
709 		break;
710 	case MKTAG('P', 'H', 'I', 'L'):
711 	case MKTAG('R', 'C', 'K', 'T'):
712 		tag2 = MKTAG('S', 'C', 'I', 'E');
713 		break;
714 	case MKTAG('T', 'R', 'A', '2'):
715 	case MKTAG('T', 'R', 'A', '3'):
716 		tag2 = MKTAG('T', 'R', 'A', 'V');
717 		break;
718 	default:
719 		break;
720 	}
721 
722 	return TTnpcScript::handleQuote(roomScript, sentence, tag1, tag2, remainder);
723 }
724 
updateState(uint oldId,uint newId,int index)725 int DoorbotScript::updateState(uint oldId, uint newId, int index) {
726 	getValue(38);
727 	bool flag39 = getValue(39) != 0;
728 	CTrueTalkManager::setFlags(38, 0);
729 	CTrueTalkManager::setFlags(39, 0);
730 
731 	if (newId > 220890) {
732 		switch (newId) {
733 		case 221064:
734 			return getValue(1) == 2 ? newId : 221062;
735 		case 221080:
736 			return getValue(1) >= 2 ? newId : 221066;
737 		case 221078:
738 		case 221079:
739 			return getValue(1) >= 3 ? newId : 221065;
740 		case 221081:
741 			return getValue(7) == 0 ? newId : 221070;
742 		case 221251:
743 			CTrueTalkManager::triggerAction(28, 0);
744 			break;
745 		default:
746 			break;
747 		}
748 	}
749 	else if (newId >= 220883) {
750 		CTrueTalkManager::setFlags(38, 1);
751 		CTrueTalkManager::triggerAction(28, 0);
752 	}
753 	else if (newId >= 220076) {
754 		switch (newId) {
755 		case 220078:
756 		case 220080:
757 		case 220081:
758 		case 220082:
759 		case 220083:
760 		case 220084:
761 			if (flag39)
762 				return getRangeValue(221381);
763 			break;
764 		default:
765 			break;
766 		}
767 
768 		CTrueTalkManager::setFlags(39, 1);
769 	}
770 	else if (newId == 220075) {
771 		if (flag39)
772 			return getRangeValue(221381);
773 		CTrueTalkManager::setFlags(39, 1);
774 	}
775 	else if (newId == 220038) {
776 		return 220038;
777 	}
778 
779 	for (uint idx = 0; idx < _states.size(); ++idx) {
780 		TTupdateState &us = _states[idx];
781 		if (us._newId == newId) {
782 			uint bits = us._dialBits;
783 
784 			if (!bits
785 				|| (index == 0 && (bits == 5 || bits == 1))
786 				|| (index == 1 && (bits == 6 || bits == 2))
787 				|| (index == 2 && (bits == 9 || bits == 1))
788 				|| (index == 3 && (bits == 10 || bits == 2))) {
789 				setState(us._newValue);
790 				break;
791 			}
792 		}
793 	}
794 
795 	return newId;
796 }
797 
preResponse(uint id)798 int DoorbotScript::preResponse(uint id) {
799 	uint newId = 0;
800 	if (getDialRegion(0) != 1 && getRandomNumber(100) > 60) {
801 		addResponse(TRANSLATE(11195, 11207));
802 		newId = 222193;
803 	}
804 
805 	return newId;
806 }
807 
getDialsBitset() const808 uint DoorbotScript::getDialsBitset() const {
809 	uint bits = 0;
810 	if (!getDialRegion(1))
811 		bits = 1;
812 	if (!getDialRegion(0))
813 		bits |= 2;
814 
815 	return bits;
816 }
817 
doSentenceEntry(int val1,const int * srcIdP,const TTroomScript * roomScript,const TTsentence * sentence)818 int DoorbotScript::doSentenceEntry(int val1, const int *srcIdP, const TTroomScript *roomScript, const TTsentence *sentence) {
819 	int id2, id = 0;
820 
821 	if (g_language == Common::DE_DEU) {
822 		if (val1 == 4010 || (val1 >= 4012 && val1 <= 4015)) {
823 			return TTnpcScript::doSentenceEntry(val1, srcIdP, roomScript, sentence);
824 		}
825 
826 		if (val1 >= 4009 && val1 <= 4030)
827 			val1 -= 4000;
828 	}
829 
830 	switch (val1) {
831 	case 2:
832 		if (getValue(1) != 1)
833 			return 1;
834 		break;
835 	case 3:
836 		if (getValue(1) != 2)
837 			return 1;
838 		break;
839 	case 4:
840 		if (getValue(1) != 3)
841 			return 1;
842 		break;
843 	case 5:
844 		if (getValue(1) == 3)
845 			return 1;
846 		break;
847 	case 6:
848 		if (getRoom54(132))
849 			return 1;
850 		break;
851 	case 9:
852 		if (sentence->localWord("my") || sentence->contains("my")
853 				|| sentence->contains("mein"))
854 			return true;
855 		id2 = getRoomDialogueId1(roomScript);
856 		if (id2) {
857 			addResponse(id2);
858 			applyResponse();
859 			return 2;
860 		}
861 		break;
862 	case 11:
863 		switch (getValue(1)) {
864 		case 1:
865 			id = 220837;
866 			break;
867 		case 2:
868 			id = 220849;
869 			break;
870 		default:
871 			id = 220858;
872 			break;
873 		}
874 		break;
875 	case 12:
876 		if (getValue(4) != 1)
877 			id = 221157;
878 		break;
879 	case 13:
880 		if (getValue(4) != 2)
881 			id = 221157;
882 		break;
883 	case 14:
884 		if (getValue(4) != 3)
885 			id = 221157;
886 		break;
887 	case 15:
888 		if (getValue(4) != 0)
889 			id = 221157;
890 		break;
891 	case 16:
892 		if (!sentence->localWord("weather"))
893 			return true;
894 		switch (getRandomNumber(4)) {
895 		case 1:
896 			if (getValue(4) != 0)
897 				id = 221354 - getRandomNumber(2) ? -489 : 0;
898 			break;
899 		case 2:
900 			switch (getValue(4)) {
901 			case 0:
902 				id = 220851;
903 				break;
904 			case 1:
905 				id = 221268;
906 				break;
907 			case 2:
908 				id = 221270;
909 				break;
910 			default:
911 				id = 220865;
912 			}
913 			break;
914 		case 3:
915 			id = 221280;
916 			break;
917 		default:
918 			break;
919 		}
920 		break;
921 	case 17:
922 		if (getState())
923 			return 1;
924 		setState(0);
925 		break;
926 	case 18:
927 		if (roomScript->_scriptId == 100) {
928 			CTrueTalkManager::triggerAction(3, 0);
929 			return 2;
930 		}
931 		break;
932 	case 19:
933 		CTrueTalkManager::_v9 = 104;
934 		CTrueTalkManager::triggerAction(4, 0);
935 		break;
936 	case 20:
937 		CTrueTalkManager::triggerAction(28, 0);
938 		break;
939 	case 22:
940 		CTrueTalkManager::triggerAction(29, 1);
941 		break;
942 	case 23:
943 		CTrueTalkManager::triggerAction(29, 2);
944 		break;
945 	case 24:
946 		CTrueTalkManager::triggerAction(29, 3);
947 		break;
948 	case 25:
949 		CTrueTalkManager::triggerAction(29, 4);
950 		break;
951 	case 26:
952 		if (!sentence->localWord("my")) {
953 			if (g_language == Common::EN_ANY && !sentence->contains("my"))
954 				return 1;
955 			if (g_language == Common::DE_DEU && !sentence->contains("mein"))
956 				return 1;
957 		}
958 		break;
959 	case 27:
960 		if (!sentence->localWord("earth")) {
961 			if (g_language == Common::EN_ANY && !sentence->contains("earth"))
962 				return 1;
963 			if (g_language == Common::EN_ANY && !sentence->contains("erde"))
964 				return 1;
965 		}
966 		break;
967 	case 28:
968 		id2 = getRoomDialogueId2(roomScript);
969 		if (id2) {
970 			addResponse(id2);
971 			applyResponse();
972 			return 2;
973 		}
974 		break;
975 	case 29:
976 		if (sentence->localWord("another") || sentence->localWord("more")
977 				|| sentence->localWord("additional") || sentence->contains("another")
978 				|| sentence->contains("more") || sentence->contains("additional")
979 				|| sentence->contains("noch ein") || sentence->contains("einen anderen")
980 				|| sentence->contains("ein anderes") || sentence->contains("eine andere")
981 				|| sentence->contains("zusaetzliche")) {
982 			addResponse(getDialogueId(220058));
983 			applyResponse();
984 			return 2;
985 		}
986 		break;
987 	case 30:
988 		if (!sentence->localWord("because") && !sentence->contains("because")
989 				&& !(g_language == Common::DE_DEU && sentence->contains("well")))
990 			return 1;
991 		break;
992 
993 	case 512:
994 		if (getValue(4) != 1)
995 			id = 221157;
996 		break;
997 	case 513:
998 		if (getValue(4) != 2)
999 			id = 221157;
1000 		break;
1001 	case 514:
1002 		if (getValue(4) != 3)
1003 			id = 221157;
1004 		break;
1005 	case 515:
1006 		if (getValue(4) != 0)
1007 			id = 221157;
1008 		break;
1009 	default:
1010 		break;
1011 	}
1012 
1013 	if (id) {
1014 		addResponse(getDialogueId(id));
1015 		applyResponse();
1016 		return 2;
1017 	} else {
1018 		return 0;
1019 	}
1020 }
1021 
setDialRegion(int dialNum,int region)1022 void DoorbotScript::setDialRegion(int dialNum, int region) {
1023 	TTnpcScript::setDialRegion(dialNum, region);
1024 	if (dialNum == 1 && region != 1) {
1025 		CTrueTalkManager::setFlags(37, dialNum);
1026 	} else {
1027 		addResponse(getDialogueId(221777));
1028 		applyResponse();
1029 	}
1030 }
1031 
randomResponse(uint index)1032 bool DoorbotScript::randomResponse(uint index) {
1033 	static const int DIALOGUE_IDS[] = {
1034 		220133, 220074, 220000, 220008, 220009, 220010, 220011,
1035 		220012, 220013, 220014, 220015, 220016, 221053, 221054,
1036 		221055, 221056, 221057, 221058, 221059, 221060, 221061,
1037 		221173, 221174, 221175, 221176, 221177, 222415, 222416,
1038 		221157, 221165, 221166, 221167, 221168, 221169, 221170,
1039 		221171, 221172, 221158, 221159, 221356, 221364, 221365,
1040 		221366, 221367, 221368, 221369, 221370, 221371, 221357,
1041 		221358, 221359, 221360, 221252, 221019, 221355, 220952,
1042 		220996, 220916, 220924, 220926, 220931, 220948, 220956,
1043 		220965, 220967, 220968, 220980, 220981, 220982, 220983,
1044 		220984, 220988, 220903, 221095, 222202, 222239, 221758,
1045 		221759, 221762, 221763, 221766, 221767, 221768, 0
1046 	};
1047 
1048 	int *dataP = _data.getSlot(index);
1049 	bool flag = false;
1050 	for (const int *idP = DIALOGUE_IDS; *idP && !flag; ++idP) {
1051 		flag = *idP == *dataP;
1052 	}
1053 
1054 	if (flag || (getDialRegion(1) != 1 && getRandomNumber(100) > 33)
1055 			|| getRandomNumber(8) <= index)
1056 		return false;
1057 
1058 	if (getRandomNumber(100) > 40) {
1059 		deleteResponses();
1060 		addResponse(getDialogueId(221242));
1061 		applyResponse();
1062 	} else {
1063 		setResponseFromArray(index, 221245);
1064 	}
1065 
1066 	return true;
1067 }
1068 
setResponse(int dialogueId,int v34)1069 int DoorbotScript::setResponse(int dialogueId, int v34) {
1070 	addResponse(dialogueId);
1071 	applyResponse();
1072 
1073 	if (v34 != -1)
1074 		setState(v34);
1075 	return 2;
1076 }
1077 
getRoomDialogueId1(const TTroomScript * roomScript)1078 int DoorbotScript::getRoomDialogueId1(const TTroomScript *roomScript) {
1079 	const RoomDialogueId *r = TRANSLATE(ROOM_DIALOGUES1_EN, ROOM_DIALOGUES1_DE);
1080 	for (; r->_roomNum; ++r) {
1081 		if (r->_roomNum == roomScript->_scriptId)
1082 			return getDialogueId(r->_dialogueId);
1083 	}
1084 
1085 	return 0;
1086 }
1087 
getRoomDialogueId2(const TTroomScript * roomScript)1088 int DoorbotScript::getRoomDialogueId2(const TTroomScript *roomScript) {
1089 	const RoomDialogueId *r = TRANSLATE(ROOM_DIALOGUES2_EN, ROOM_DIALOGUES2_DE);
1090 	for (; r->_roomNum; ++r) {
1091 		if (r->_roomNum == roomScript->_scriptId)
1092 			return getDialogueId(r->_dialogueId);
1093 	}
1094 
1095 	return 0;
1096 }
1097 
1098 } // End of namespace Titanic
1099