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 /*
24  * This code is based on original Mortville Manor DOS source code
25  * Copyright (c) 1987-1989 Lankhor
26  */
27 
28 #include "mortevielle/mortevielle.h"
29 #include "mortevielle/dialogs.h"
30 #include "mortevielle/menu.h"
31 #include "mortevielle/mouse.h"
32 #include "mortevielle/outtext.h"
33 
34 #include "common/scummsys.h"
35 
36 namespace Mortevielle {
37 
38 /**
39  * Engine function - Move
40  * @remarks	Originally called 'taller'
41  */
fctMove()42 void MortevielleEngine::fctMove() {
43 	int oldMenu = (_menu->_moveMenu[6]._menuId << 8) | _menu->_moveMenu[6]._actionId;
44 	if ((_coreVar._currPlace == ROOM26) && (_currAction == oldMenu)) {
45 		_coreVar._currPlace = LANDING;
46 		_caff = _coreVar._currPlace;
47 		drawPictureWithText();
48 		handleDescriptionText(2, _coreVar._currPlace);
49 	}
50 	if ((_coreVar._currPlace == LANDING) && (_currAction == oldMenu)) {
51 		if (!_syn)
52 			displayTextInVerbBar(getEngineString(S_GO_TO));
53 		displayStatusArrow();
54 
55 		if (_keyPressedEsc)
56 			_destinationOk = false;
57 
58 		if ((_anyone) || (_keyPressedEsc))
59 			return;
60 
61 		setCoordinates(1);
62 
63 		if (_num == 0)
64 			return;
65 
66 		if (_num == 1) {
67 			_coreVar._currPlace = OWN_ROOM;
68 			_menu->setDestinationText(OWN_ROOM);
69 		} else if (_num == 7) {
70 			_coreVar._currPlace = ATTIC;
71 			_menu->setDestinationText(ATTIC);
72 		} else if (_num != 6)
73 			_coreVar._currPlace = ROOM26;
74 
75 		if ((_num > 1) && (_num < 6))
76 			_roomDoorId = _num - 1;
77 		else if (_num > 7)
78 			_roomDoorId = _num - 3;
79 
80 		if (_num != 6)
81 			prepareDisplayText();
82 		else
83 			showMoveMenuAlert();
84 		return;
85 	}
86 	exitRoom();
87 	int menuChoice = 1;
88 	oldMenu = (_menu->_moveMenu[menuChoice]._menuId << 8) | _menu->_moveMenu[menuChoice]._actionId;
89 	while (oldMenu != _currAction) {
90 		++menuChoice;
91 		oldMenu = (_menu->_moveMenu[menuChoice]._menuId << 8) | _menu->_moveMenu[menuChoice]._actionId;
92 	}
93 
94 	switch (_coreVar._currPlace) {
95 	case MOUNTAIN:
96 		if (menuChoice == 1)
97 			gotoManorFront();
98 		else if (menuChoice == 2)
99 			checkManorDistance();
100 		_menu->setDestinationText(_coreVar._currPlace);
101 		return;
102 	case INSIDE_WELL:
103 		if (menuChoice == 1)
104 			floodedInWell();
105 		else if (menuChoice == 2)
106 			gotoManorBack();
107 		_menu->setDestinationText(_coreVar._currPlace);
108 		return;
109 	case BUREAU:
110 		if (menuChoice == 1)
111 			menuChoice = 6;
112 		break;
113 	case KITCHEN:
114 		if (menuChoice == 2)
115 			menuChoice = 6;
116 		else if (menuChoice == 5)
117 			menuChoice = 16;
118 		break;
119 	case CELLAR:
120 		if (menuChoice == 3)
121 			menuChoice = 6;
122 		break;
123 	case LANDING:
124 	case ROOM26:
125 		if (menuChoice == 4)
126 			menuChoice = 6;
127 		break;
128 	default:
129 		break;
130 	}
131 
132 	if ((_coreVar._currPlace > MOUNTAIN) && (_coreVar._currPlace != ROOM26))
133 		menuChoice += 10;
134 
135 	if ((_coreVar._currPlace == CHAPEL) && (menuChoice == 13))
136 		menuChoice = 16;
137 	else if (_coreVar._currPlace == MANOR_FRONT) {
138 		if (menuChoice == 12)
139 			menuChoice = 16;
140 		else if (menuChoice > 13)
141 			menuChoice = 15;
142 	} else if ((_coreVar._currPlace == MANOR_BACK) && (menuChoice > 14))
143 		menuChoice = 15;
144 	else if ((_coreVar._currPlace == WELL) && (menuChoice > 13) && (menuChoice != 17))
145 		menuChoice = 15;
146 
147 	switch (menuChoice) {
148 	case 1:
149 		_coreVar._currPlace = BUREAU;
150 		break;
151 	case 2:
152 		_coreVar._currPlace = KITCHEN;
153 		break;
154 	case 3:
155 		_coreVar._currPlace = CELLAR;
156 		break;
157 	case 4:
158 		_coreVar._currPlace = LANDING;
159 		break;
160 	case 5:
161 	case 12:
162 		gotoManorFront();
163 		break;
164 	case 6:
165 	case 11:
166 		gotoDiningRoom();
167 		break;
168 	case 13:
169 		_coreVar._currPlace = CHAPEL;
170 		break;
171 	case 14:
172 		_coreVar._currPlace = WELL;
173 		break;
174 	case 15:
175 		checkManorDistance();
176 		break;
177 	case 16:
178 		gotoManorBack();
179 		break;
180 	case 17:
181 		if ((_coreVar._wellObjectId != 120) && (_coreVar._wellObjectId != 140))
182 			_crep = 997;
183 		else if (_coreVar._wellObjectId == 120)
184 			_crep = 181;
185 		else if (_coreVar._faithScore > 80) {
186 			_crep = 1505;
187 			loseGame();
188 		} else {
189 			_coreVar._currPlace = INSIDE_WELL;
190 			prepareDisplayText();
191 		}
192 		break;
193 	default:
194 		break;
195 	}
196 
197 	if ((menuChoice < 5) || (menuChoice == 13) || (menuChoice == 14))
198 		prepareDisplayText();
199 	resetRoomVariables(_coreVar._currPlace);
200 	_menu->setDestinationText(_coreVar._currPlace);
201 }
202 
203 /**
204  * Engine function - Take
205  * @remarks	Originally called 'tprendre'
206  */
fctTake()207 void MortevielleEngine::fctTake() {
208 	if (_caff > 99) {
209 		int cx = _caff;
210 		putInHand(cx);
211 		if (_crep != 139) {
212 			if (_currBitIndex > 0)
213 				_coreVar._faithScore += 3;
214 			if (_obpart) {
215 				switch (_coreVar._currPlace) {
216 				case PURPLE_ROOM:
217 					_coreVar._purpleRoomObjectId = 0;
218 					break;
219 				case ATTIC:
220 					if (_coreVar._atticBallHoleObjectId == _caff)
221 						_coreVar._atticBallHoleObjectId = 0;
222 					if (_coreVar._atticRodHoleObjectId == _caff)
223 						_coreVar._atticRodHoleObjectId = 0;
224 					break;
225 				case CELLAR:
226 					_coreVar._cellarObjectId = 0;
227 					break;
228 				case CRYPT:
229 					_coreVar._cryptObjectId = 0;
230 					break;
231 				case SECRET_PASSAGE:
232 					_coreVar._secretPassageObjectId = 0;
233 					break;
234 				case WELL:
235 					_coreVar._wellObjectId = 0;
236 					break;
237 				default:
238 					break;
239 				}
240 				_menu->unsetSearchMenu();
241 				_obpart = false;
242 				prepareDisplayText();
243 			} else {
244 				_tabdon[kAcha + ((_curSearchObjId - 1) * 10) + _searchCount - 1] = 0;
245 				prepareNextObject();
246 				++_takeObjCount;
247 				if (_takeObjCount > 6) {
248 					_coreVar._faithScore += 2;
249 					_takeObjCount = 0;
250 				}
251 			}
252 		}
253 		return;
254 	}
255 	if (!_syn)
256 		displayTextInVerbBar(getEngineString(S_TAKE));
257 	displayStatusArrow();
258 	if ((_anyone) || (_keyPressedEsc))
259 		return;
260 	if (_caff == 3) {
261 		setCoordinates(2);
262 		if (_num == 1) {
263 			_crep = 152;
264 			return;
265 		}
266 	}
267 	setCoordinates(5);
268 	if ((_num == 0) || ((_num == 1) && (_coreVar._currPlace == CRYPT))) {
269 		setCoordinates(8);
270 		if (_num != 0) {
271 			if (_currBitIndex > 0)
272 				_coreVar._faithScore += 3;
273 			_crep = 997;
274 
275 			switch (_coreVar._currPlace) {
276 			case PURPLE_ROOM:
277 				if (_coreVar._purpleRoomObjectId != 0)
278 					putInHand(_coreVar._purpleRoomObjectId);
279 				break;
280 			case ATTIC:
281 				if ((_num == 1) && (_coreVar._atticBallHoleObjectId != 0)) {
282 					putInHand(_coreVar._atticBallHoleObjectId);
283 					if ((_crep != 997) && (_crep != 139))
284 						displayAnimFrame(2, 7);
285 				} else if ((_num == 2) && (_coreVar._atticRodHoleObjectId != 0)) {
286 					putInHand(_coreVar._atticRodHoleObjectId);
287 					if ((_crep != 997) && (_crep != 139))
288 						displayAnimFrame(2, 6);
289 				}
290 				break;
291 			case CELLAR:
292 				if (_coreVar._cellarObjectId != 0) {
293 					putInHand(_coreVar._cellarObjectId);
294 					if ((_crep != 997) && (_crep != 139))
295 						displayAnimFrame(2, 2);
296 				}
297 				break;
298 			case CRYPT:
299 				if (_coreVar._cryptObjectId != 0)
300 					putInHand(_coreVar._cryptObjectId);
301 				break;
302 			case SECRET_PASSAGE:
303 				if (_coreVar._secretPassageObjectId != 0) {
304 					putInHand(_coreVar._secretPassageObjectId);
305 					if ((_crep != 997) && (_crep != 139)) {
306 						_crep = 182;
307 						displayAnimFrame(2, 1);
308 					}
309 				}
310 				break;
311 			case WELL:
312 				if (_coreVar._wellObjectId != 0) {
313 					putInHand(_coreVar._wellObjectId);
314 					if ((_crep != 997) && (_crep != 139))
315 						displayAnimFrame(2, 1);
316 				}
317 				break;
318 			default:
319 				break;
320 			}
321 
322 			if ((_crep != 997) && (_crep != 182) && (_crep != 139))
323 				_crep = 999;
324 		}
325 	} else {
326 		if ( ((_coreVar._currPlace == OWN_ROOM)  && (_num == 3))
327 		  || ((_coreVar._currPlace == GREEN_ROOM)  && (_num == 4))
328 		  || ((_coreVar._currPlace == PURPLE_ROOM)  && (_num == 1))
329 		  || ((_coreVar._currPlace == DARKBLUE_ROOM)  && (_num == 3))
330 		  || ((_coreVar._currPlace == BLUE_ROOM)  && (_num == 6))
331 		  || ((_coreVar._currPlace == RED_ROOM)  && (_num == 2))
332 		  || ((_coreVar._currPlace == BATHROOM)  && (_num == 6))
333 		  || ((_coreVar._currPlace == GREEN_ROOM2)  && (_num == 4))
334 		  || ((_coreVar._currPlace == JULIA_ROOM) && (_num == 4))
335 		  || ((_coreVar._currPlace == DINING_ROOM) && (_num > 2))
336 		  || ((_coreVar._currPlace == BUREAU) && (_num == 7))
337 		  || ((_coreVar._currPlace == KITCHEN) && (_num == 6))
338 		  || ((_coreVar._currPlace == ATTIC) && (_num > 4))
339 		  || ((_coreVar._currPlace > ATTIC) && (_coreVar._currPlace != INSIDE_WELL)) )
340 		  _crep = 997;
341 		else if (_coreVar._currPlace == INSIDE_WELL) {
342 			_crep = 1504;
343 			loseGame();
344 		} else
345 			_crep = 120;
346 	}
347 }
348 /**
349  * Engine function - Inventory / Take
350  * @remarks	Originally called 'tsprendre'
351  */
fctInventoryTake()352 void MortevielleEngine::fctInventoryTake() {
353 	int inventIndex = 0;
354 	int oldMenu = 0;
355 	do {
356 		++inventIndex;
357 		oldMenu = (_menu->_inventoryMenu[inventIndex]._menuId << 8) | _menu->_inventoryMenu[inventIndex]._actionId;
358 	} while (oldMenu != _currAction);
359 	int cz = 0;
360 	int cy = 0;
361 	do {
362 		++cy;
363 		if (_coreVar._inventory[cy] != 0)
364 			++cz;
365 	} while (cz != inventIndex);
366 	cz = _coreVar._inventory[cy];
367 	_coreVar._inventory[cy] = 0;
368 	_menu->setInventoryText();
369 	putInHand(cz);
370 	_crep = 998;
371 	clearDescriptionBar();
372 }
373 
374 /**
375  * Engine function - Lift
376  * @remarks	Originally called 'tsoulever'
377  */
fctLift()378 void MortevielleEngine::fctLift() {
379 	if (!_syn)
380 		displayTextInVerbBar(getEngineString(S_LIFT));
381 	displayStatusArrow();
382 	if ((_anyone) || (_keyPressedEsc))
383 		return;
384 	setCoordinates(3);
385 	if (_num == 0) {
386 		setCoordinates(8);
387 		if (_num != 0) {
388 			if (_currBitIndex > 0)
389 				++_coreVar._faithScore;
390 			_crep = 997;
391 			if ((_coreVar._currPlace == PURPLE_ROOM) && (_coreVar._purpleRoomObjectId != 0))
392 				displayLookScreen(_coreVar._purpleRoomObjectId);
393 		}
394 		return;
395 	}
396 	if (_currBitIndex > 0)
397 		++_coreVar._faithScore;
398 	int tmpPlace = _coreVar._currPlace;
399 	if (_coreVar._currPlace == CRYPT)
400 		tmpPlace = 14;
401 	else if (_coreVar._currPlace == MOUNTAIN)
402 		tmpPlace = 15;
403 	_crep = _tabdon[kAsoul + (tmpPlace << 3) + (_num - 1)];
404 	if (_crep == 255)
405 		_crep = 997;
406 }
407 
408 /**
409  * Engine function - Read
410  * @remarks	Originally called 'tlire'
411  */
fctRead()412 void MortevielleEngine::fctRead() {
413 	if (_caff > 99)
414 		getReadDescription(_caff);
415 	else {
416 		if (!_syn)
417 			displayTextInVerbBar(getEngineString(S_READ));
418 		displayStatusArrow();
419 		if (!(_anyone) && !(_keyPressedEsc)) {
420 			setCoordinates(4);
421 			if (_num != 0)
422 				_crep = 107;
423 		}
424 	}
425 }
426 
427 /**
428  * Engine function - Self / Read
429  * @remarks	Originally called 'tslire'
430  */
fctSelfRead()431 void MortevielleEngine::fctSelfRead() {
432 	if (_coreVar._selectedObjectId == 0)
433 		_crep = 186;
434 	else
435 		getReadDescription(_coreVar._selectedObjectId);
436 }
437 
438 /**
439  * Engine function - Look
440  * @remarks	Originally called 'tregarder'
441  */
fctLook()442 void MortevielleEngine::fctLook() {
443 	if (_caff > 99) {
444 		_crep = 103;
445 		return;
446 	}
447 	if (!_syn)
448 		displayTextInVerbBar(getEngineString(S_LOOK));
449 	displayStatusArrow();
450 	if ((_anyone) || (_keyPressedEsc))
451 		return;
452 	setCoordinates(5);
453 	if (_num == 0) {
454 		setCoordinates(8);
455 		_crep = 131;
456 		if (_num != 0) {
457 			if (_coreVar._currPlace == ATTIC) {
458 				if (_num == 1) {
459 					_crep = 164;
460 					if (_coreVar._atticRodHoleObjectId != 0)
461 						displayLookScreen(_coreVar._atticRodHoleObjectId);
462 					else if (_coreVar._atticBallHoleObjectId != 0)
463 						displayLookScreen(_coreVar._atticBallHoleObjectId);
464 				} else {
465 					_crep = 193;
466 					if (_coreVar._atticRodHoleObjectId != 0)
467 						displayLookScreen(_coreVar._atticRodHoleObjectId);
468 				}
469 			}
470 			if (_coreVar._currPlace == CELLAR) {
471 				_crep = 164;
472 				if (_coreVar._cellarObjectId != 0)
473 					displayLookScreen(_coreVar._cellarObjectId);
474 			}
475 			if (_coreVar._currPlace == SECRET_PASSAGE) {
476 				_crep = 174;
477 				if (_coreVar._secretPassageObjectId != 0)
478 					displayLookScreen(_coreVar._secretPassageObjectId);
479 			}
480 			if (_coreVar._currPlace == WELL) {
481 				_crep = 131;
482 				if (_coreVar._wellObjectId != 0)
483 					displayLookScreen(_coreVar._wellObjectId);
484 			}
485 		}
486 		return;
487 	}
488 
489 	int cx = _coreVar._currPlace;
490 	switch (_coreVar._currPlace) {
491 	case CHAPEL:
492 		cx = 17;
493 		break;
494 	case MANOR_BACK:
495 	case INSIDE_WELL:
496 	case WELL:
497 		cx -= 4;
498 		break;
499 	case ROOM26:
500 		cx = 21;
501 		break;
502 	default:
503 		break;
504 	}
505 
506 	_crep = _tabdon[kArega + (cx * 7) + _num - 1];
507 	if ((_coreVar._currPlace == ATTIC) && (_num == 8))
508 		_crep = 126;
509 	if (_coreVar._currPlace == MOUNTAIN)
510 		_crep = 103;
511 	if (_crep == 255)
512 		_crep = 131;
513 	if ((_coreVar._currPlace == GREEN_ROOM) && (_num == 1))
514 		displayLookScreen(144);
515 	if ((_coreVar._currPlace == BLUE_ROOM) && (_num == 3))
516 		displayLookScreen(147);
517 	if ((_coreVar._currPlace == GREEN_ROOM2) && (_num == 3))
518 		displayLookScreen(149);
519 	if ((_coreVar._currPlace == JULIA_ROOM) && (_num == 2))
520 		displayLookScreen(30);
521 	if ((_coreVar._currPlace == DINING_ROOM) && (_num == 3))
522 		displayLookScreen(31);
523 }
524 
525 /**
526  * Engine function - Self / Look
527  * @remarks	Originally called 'tsregarder'
528  */
fctSelftLook()529 void MortevielleEngine::fctSelftLook() {
530 	if (_coreVar._selectedObjectId != 0)
531 		displayLookScreen(_coreVar._selectedObjectId);
532 	else
533 		_crep = 186;
534 }
535 
536 /**
537  * Engine function - Search
538  * @remarks	Originally called 'tfouiller'
539  */
fctSearch()540 void MortevielleEngine::fctSearch() {
541 	static const byte answerArr[14] = {123, 104, 123, 131, 131, 123, 104, 131, 123, 123, 106, 123, 123, 107};
542 
543 	if (_caff > 99) {
544 		getSearchDescription(_caff);
545 		return;
546 	}
547 
548 	if (!_syn)
549 		displayTextInVerbBar(getEngineString(S_SEARCH));
550 
551 	displayStatusArrow();
552 	if (_anyone || _keyPressedEsc)
553 		return;
554 
555 	if (_coreVar._currPlace == INSIDE_WELL) {
556 		_crep = 1504;
557 		loseGame();
558 		return;
559 	}
560 
561 	setCoordinates(6);
562 	if (_num == 0) {
563 		setCoordinates(7);
564 		if (_num != 0) {
565 			int i;
566 			for (i = 1; i <= 6; i++) {
567 				if (_num == _openObjects[i])
568 					break;
569 			}
570 
571 			if (i <= 6) {
572 				if (_currBitIndex > 0)
573 					_coreVar._faithScore += 3;
574 
575 				_curSearchObjId = getFirstObject();
576 				if (_curSearchObjId != 0) {
577 					_searchCount = 0;
578 					_is = 0;
579 					_heroSearching = true;
580 					_menu->setSearchMenu();
581 					prepareNextObject();
582 				} else
583 					_crep = 997;
584 			} else
585 				_crep = 187;
586 		} else {
587 			setCoordinates(8);
588 			_crep = 997;
589 			if (_num != 0) {
590 				if (_currBitIndex > 0)
591 					_coreVar._faithScore += 3;
592 				if ((_coreVar._currPlace != WELL) && (_coreVar._currPlace != SECRET_PASSAGE) && (_coreVar._currPlace != ATTIC)) {
593 					if (_coreVar._currPlace == PURPLE_ROOM) {
594 						_crep = 123;
595 						if (_coreVar._purpleRoomObjectId != 0)
596 							displayLookScreen(_coreVar._purpleRoomObjectId);
597 					}
598 					if (_coreVar._currPlace == CRYPT) {
599 						_crep = 123;
600 						if (_coreVar._cryptObjectId != 0)
601 							displayLookScreen(_coreVar._cryptObjectId);
602 					}
603 				}
604 			}
605 		}
606 	} else {
607 		if (_currBitIndex > 0)
608 			_coreVar._faithScore += 3;
609 		_crep = 997;
610 		if (_coreVar._currPlace < CELLAR)
611 			_crep = answerArr[_coreVar._currPlace];
612 
613 		if ((_coreVar._currPlace == TOILETS) && (_num == 2))
614 			_crep = 162;
615 
616 		if (_coreVar._currPlace == KITCHEN) {
617 			if ((_num == 3) || (_num == 4))
618 				_crep = 162;
619 			else if (_num == 5)
620 				_crep = 159;
621 		}
622 
623 		if (_coreVar._currPlace == MOUNTAIN)
624 			_crep = 104;
625 		else if (_coreVar._currPlace == CRYPT)
626 			_crep = 155;
627 	}
628 }
629 
630 /**
631  * Engine function - Self / Search
632  * @remarks	Originally called 'tsfouiller'
633  */
fctSelfSearch()634 void MortevielleEngine::fctSelfSearch() {
635 	if (_coreVar._selectedObjectId != 0)
636 		getSearchDescription(_coreVar._selectedObjectId);
637 	else
638 		_crep = 186;
639 }
640 
641 /**
642  * Engine function - Open
643  * @remarks	Originally called 'touvrir'
644  */
fctOpen()645 void MortevielleEngine::fctOpen() {
646 	if (!_syn)
647 		displayTextInVerbBar(getEngineString(S_OPEN));
648 
649 	if (_caff == ROOM26) {
650 		if (_roomDoorId != OWN_ROOM) {
651 			_currAction = _menu->_opcodeEnter;
652 			_syn = true;
653 		} else
654 			_crep = 997;
655 		return;
656 	}
657 
658 	if (_caff == LANDING) {
659 		showMoveMenuAlert();
660 		return;
661 	}
662 
663 	displayStatusArrow();
664 	if ((_anyone) || (_keyPressedEsc))
665 		return;
666 
667 	setCoordinates(7);
668 	if (_num != 0) {
669 		if (_currBitIndex > 0)
670 			_coreVar._faithScore += 2;
671 		++_openObjCount;
672 		int i;
673 		for (i = 1; (i <= 6); i++) {
674 			if ((_openObjects[i] == 0) || (_openObjects[i] == _num))
675 				break;
676 		}
677 
678 		if (i > 6) {
679 			warning("Unexpected action: Too many open objects");
680 			return;
681 		}
682 
683 		if (_openObjects[i] == _num)
684 			// display "Already Opened"
685 			_crep = 18;
686 		else {
687 			if (!( ((_num == 3) && ((_coreVar._currPlace == OWN_ROOM)
688 				                 || (_coreVar._currPlace == JULIA_ROOM)
689 								 || (_coreVar._currPlace == BLUE_ROOM)
690 								 || (_coreVar._currPlace == BATHROOM)))
691 			    || ((_num == 4) && ((_coreVar._currPlace == GREEN_ROOM)
692 				                 || (_coreVar._currPlace == PURPLE_ROOM)
693 								 || (_coreVar._currPlace == RED_ROOM)))
694 				|| ((_coreVar._currPlace == DARKBLUE_ROOM) && (_num == 5))
695 				|| ((_num == 6) && ((_coreVar._currPlace == BATHROOM)
696 				                 || (_coreVar._currPlace == DINING_ROOM)
697 								 || (_coreVar._currPlace == GREEN_ROOM2)
698 								 || (_coreVar._currPlace == ATTIC)))
699 				|| ((_coreVar._currPlace == GREEN_ROOM2) && (_num == 2))
700 				|| ((_coreVar._currPlace == KITCHEN) && (_num == 7))) ) {
701 				if ( ((_coreVar._currPlace > DINING_ROOM) && (_coreVar._currPlace < CELLAR))
702 				  || ((_coreVar._currPlace > RED_ROOM) && (_coreVar._currPlace < DINING_ROOM))
703 				  || (_coreVar._currPlace == OWN_ROOM)
704 				  || (_coreVar._currPlace == PURPLE_ROOM)
705 				  || (_coreVar._currPlace == BLUE_ROOM)) {
706 					if (getRandomNumber(1, 4) == 3)
707 						_soundManager->startSpeech(7, 9, 1);
708 				}
709 				_openObjects[i] = _num;
710 				displayAnimFrame(1, _num);
711 				_soundManager->waitSpeech();
712 			}
713 			int tmpPlace = _coreVar._currPlace;
714 			if (_coreVar._currPlace == CRYPT)
715 				tmpPlace = CELLAR;
716 			_crep = _tabdon[kAouvr + (tmpPlace * 7) + _num - 1];
717 			if (_crep == 254)
718 				_crep = 999;
719 		}
720 	}
721 }
722 
723 /**
724  * Engine function - Place
725  * @remarks	Originally called 'tmettre'
726  */
fctPlace()727 void MortevielleEngine::fctPlace() {
728 	if (_coreVar._selectedObjectId == 0) {
729 		_crep = 186;
730 		return;
731 	}
732 
733 	if (!_syn)
734 		displayTextInVerbBar(getEngineString(S_PUT));
735 
736 	displayStatusArrow();
737 	if (_keyPressedEsc)
738 		_crep = 998;
739 
740 	if ((_anyone) || (_keyPressedEsc))
741 		return;
742 
743 	setCoordinates(8);
744 	if (_num != 0) {
745 		_crep = 999;
746 		if (_caff == ATTIC) {
747 			if (_num == 1) {
748 				if (_coreVar._atticBallHoleObjectId != 0) {
749 					_crep = 188;
750 				} else {
751 					_coreVar._atticBallHoleObjectId = _coreVar._selectedObjectId;
752 					if (_coreVar._selectedObjectId == 141)
753 						displayAnimFrame(1, 7);
754 				}
755 			} else if (_coreVar._atticRodHoleObjectId != 0) {
756 				_crep = 188;
757 			} else {
758 				_coreVar._atticRodHoleObjectId = _coreVar._selectedObjectId;
759 				if (_coreVar._selectedObjectId == 159)
760 					displayAnimFrame(1, 6);
761 			}
762 		}
763 
764 		if (_caff == CELLAR) {
765 			if (_coreVar._cellarObjectId != 0) {
766 				_crep = 188;
767 			} else {
768 				_coreVar._cellarObjectId = _coreVar._selectedObjectId;
769 				if (_coreVar._selectedObjectId == 151) {
770 					// Open hidden passage
771 					displayAnimFrame(1, 2);
772 					displayAnimFrame(1, 1);
773 					handleDescriptionText(2, 165);
774 					displayEmptyHand();
775 					_soundManager->startSpeech(6, -9, 1);
776 
777 					// Do you want to enter the hidden passage?
778 					int answer = _dialogManager->show(getEngineString(S_YES_NO));
779 					if (answer == 1) {
780 						Common::String alertTxt = getString(582);
781 						_dialogManager->show(alertTxt);
782 
783 						bool enterPassageFl = _dialogManager->showKnowledgeCheck();
784 						_mouse->hideMouse();
785 						clearScreen();
786 						drawRightFrame();
787 						clearDescriptionBar();
788 						clearVerbBar();
789 						_mouse->showMouse();
790 						prepareRoom();
791 						drawClock();
792 						if (_currBitIndex != 0)
793 							showPeoplePresent(_currBitIndex);
794 						else
795 							displayAloneText();
796 
797 						_menu->displayMenu();
798 						if (enterPassageFl) {
799 							_coreVar._currPlace = SECRET_PASSAGE;
800 							_menu->setDestinationText(SECRET_PASSAGE);
801 						} else {
802 							_menu->setDestinationText(_coreVar._currPlace);
803 							setPal(14);
804 							drawPicture();
805 							displayAnimFrame(1, 2);
806 							displayAnimFrame(1, 1);
807 							alertTxt = getString(577);
808 							_dialogManager->show(alertTxt);
809 							displayAnimFrame(2, 1);
810 							_crep = 166;
811 						}
812 						prepareDisplayText();
813 					} else {
814 						displayAnimFrame(2, 1);
815 						_crep = 166;
816 					}
817 					return;
818 				}
819 			}
820 		}
821 
822 		if (_caff == CRYPT) {
823 			if (_coreVar._cryptObjectId == 0)
824 				_coreVar._cryptObjectId = _coreVar._selectedObjectId;
825 			else
826 				_crep = 188;
827 		}
828 
829 		if (_caff == SECRET_PASSAGE) {
830 			if (_coreVar._secretPassageObjectId != 0) {
831 				_crep = 188;
832 			} else if (_coreVar._selectedObjectId == 143) {
833 				_coreVar._secretPassageObjectId = 143;
834 				displayAnimFrame(1, 1);
835 			} else {
836 				_crep = 1512;
837 				loseGame();
838 			}
839 		}
840 
841 		if (_caff == WELL) {
842 			if (_coreVar._wellObjectId != 0) {
843 				_crep = 188;
844 			} else if ((_coreVar._selectedObjectId == 140) || (_coreVar._selectedObjectId == 120)) {
845 				_coreVar._wellObjectId = _coreVar._selectedObjectId;
846 				displayAnimFrame(1, 1);
847 			} else {
848 				_crep = 185;
849 			}
850 		}
851 
852 		if (_crep != 188)
853 			displayEmptyHand();
854 	}
855 }
856 
857 /**
858  * Engine function - Turn
859  * @remarks	Originally called 'ttourner'
860  */
fctTurn()861 void MortevielleEngine::fctTurn() {
862 	if (_caff > 99) {
863 		_crep = 149;
864 		return;
865 	}
866 	if (!_syn)
867 		displayTextInVerbBar(getEngineString(S_TURN));
868 	displayStatusArrow();
869 	if ((_anyone) || (_keyPressedEsc))
870 		return;
871 	setCoordinates(9);
872 	if (_num != 0) {
873 		_crep = 997;
874 		if ((_coreVar._currPlace == ATTIC) && (_coreVar._atticRodHoleObjectId == 159) && (_coreVar._atticBallHoleObjectId == 141)) {
875 			handleDescriptionText(2, 167);
876 			_soundManager->startSpeech(7, 9, 1);
877 			int answer = _dialogManager->show(getEngineString(S_YES_NO));
878 			if (answer == 1)
879 				_endGame = true;
880 			else
881 				_crep = 168;
882 		}
883 		if ((_coreVar._currPlace == SECRET_PASSAGE) && (_coreVar._secretPassageObjectId == 143)) {
884 			handleDescriptionText(2, 175);
885 			clearVerbBar();
886 			_soundManager->startSpeech(6, -9, 1);
887 			int answer = _dialogManager->show(getEngineString(S_YES_NO));
888 			if (answer == 1) {
889 				_coreVar._currPlace = CRYPT;
890 				prepareDisplayText();
891 			} else
892 				_crep = 176;
893 		}
894 	}
895 }
896 
897 /**
898  * Engine function - Hide Self
899  * @remarks	Originally called 'tcacher'
900  */
fctSelfHide()901 void MortevielleEngine::fctSelfHide() {
902 	if (!_syn)
903 		displayTextInVerbBar(getEngineString(S_HIDE_SELF));
904 	displayStatusArrow();
905 	if (!(_anyone) && !(_keyPressedEsc)) {
906 		setCoordinates(10);
907 		if (_num == 0)
908 			_hiddenHero = false;
909 		else {
910 			_hiddenHero = true;
911 			_crep = 999;
912 		}
913 	}
914 }
915 
916 /**
917  * Engine function - Attach
918  * @remarks	Originally called 'tattacher'
919  */
fctAttach()920 void MortevielleEngine::fctAttach() {
921 	if (_coreVar._selectedObjectId == 0)
922 		_crep = 186;
923 	else {
924 		if (!_syn)
925 			displayTextInVerbBar(getEngineString(S_TIE));
926 		displayStatusArrow();
927 		if (!(_anyone) && !(_keyPressedEsc)) {
928 			setCoordinates(8);
929 			_crep = 997;
930 			if ((_num != 0) && (_coreVar._currPlace == WELL)) {
931 				_crep = 999;
932 				if ((_coreVar._selectedObjectId == 120) || (_coreVar._selectedObjectId == 140)) {
933 					_coreVar._wellObjectId = _coreVar._selectedObjectId;
934 					displayAnimFrame(1, 1);
935 				} else
936 					_crep = 185;
937 				displayEmptyHand();
938 			}
939 		}
940 	}
941 }
942 
943 /**
944  * Engine function - Close
945  * @remarks	Originally called 'tfermer'
946  */
fctClose()947 void MortevielleEngine::fctClose() {
948 	if (!_syn)
949 		displayTextInVerbBar(getEngineString(S_CLOSE));
950 
951 	if (_caff < ROOM26) {
952 		displayStatusArrow();
953 		if (_keyPressedEsc)
954 			_crep = 998;
955 		if ((_anyone) || (_keyPressedEsc))
956 			return;
957 		setCoordinates(7);
958 		if (_num != 0) {
959 			int i;
960 			for (i = 1; i <= 6; ++i) {
961 				if (_num == _openObjects[i])
962 					break;
963 			}
964 
965 			if (i <= 6) {
966 				displayAnimFrame(2, _num);
967 				_crep = 998;
968 				_openObjects[i] = 0;
969 				--_openObjCount;
970 				if (_openObjCount < 0)
971 					_openObjCount = 0;
972 				int objId = getFirstObject();
973 				if (_curSearchObjId == objId)
974 					_curSearchObjId = 0;
975 			} else {
976 				_crep = 187;
977 			}
978 		}
979 	}
980 	if (_caff == ROOM26)
981 		_crep = 999;
982 }
983 
984 /**
985  * Engine function - Knock
986  * @remarks	Originally called 'tfrapper'
987  */
fctKnock()988 void MortevielleEngine::fctKnock() {
989 	if (!_syn)
990 		displayTextInVerbBar(getEngineString(S_HIT));
991 
992 	if (_coreVar._currPlace == LANDING) {
993 		_dialogManager->show(getEngineString(S_BEFORE_USE_DEP_MENU));
994 		return;
995 	}
996 
997 	if (_coreVar._currPlace < DOOR) {
998 		displayStatusArrow();
999 		if (!(_anyone) && !(_keyPressedEsc)) {
1000 			if ((_coreVar._currPlace < MOUNTAIN) && (_coreVar._currPlace != LANDING))
1001 				_crep = 133;
1002 			else
1003 				_crep = 997;
1004 		}
1005 
1006 		return;
1007 	}
1008 
1009 	if (_coreVar._currPlace == ROOM26) {
1010 		int rand = (getRandomNumber(0, 8)) - 4;
1011 		_soundManager->startSpeech(11, rand, 1);
1012 		int pres = getPresenceStats(rand, _coreVar._faithScore, _roomDoorId);
1013 		if (_roomDoorId != OWN_ROOM) {
1014 			if (pres != -500) {
1015 				if (rand > pres)
1016 					_crep = 190;
1017 				else {
1018 					setPresenceFlags(_roomDoorId);
1019 					getKnockAnswer();
1020 				}
1021 			} else
1022 				getKnockAnswer();
1023 		}
1024 
1025 		if (_roomDoorId == GREEN_ROOM2)
1026 			_crep = 190;
1027 	}
1028 }
1029 
1030 /**
1031  * Engine function - Self / Put
1032  * @remarks	Originally called 'tposer'
1033  */
fctSelfPut()1034 void MortevielleEngine::fctSelfPut() {
1035 	if (!_syn)
1036 		displayTextInVerbBar(getEngineString(S_POSE));
1037 	if (_coreVar._selectedObjectId == 0)
1038 		_crep = 186;
1039 	else {
1040 		if (_caff > 99) {
1041 			_crep = 999;
1042 			putObject();
1043 			if (_crep != 192)
1044 				displayEmptyHand();
1045 			return;
1046 		}
1047 		displayStatusArrow();
1048 		if ((_anyone) || (_keyPressedEsc))
1049 			return;
1050 		setCoordinates(7);
1051 		_crep = 124;
1052 		if (_num != 0) {
1053 			int objId = getFirstObject();
1054 			if (objId == 0)
1055 				_crep = 997;
1056 			else {
1057 				int i;
1058 				for (i = 1; i <= 6; i++) {
1059 					if (_num == _openObjects[i])
1060 						break;
1061 				}
1062 
1063 				if (i <= 6) {
1064 					_curSearchObjId = objId;
1065 					_crep = 999;
1066 				} else
1067 					_crep = 187;
1068 			}
1069 		} else {
1070 			setCoordinates(8);
1071 			if (_num != 0) {
1072 				_crep = 998;
1073 				if (_caff == PURPLE_ROOM) {
1074 					if (_coreVar._purpleRoomObjectId != 0)
1075 						_crep = 188;
1076 					else
1077 						_coreVar._purpleRoomObjectId = _coreVar._selectedObjectId;
1078 				}
1079 
1080 				if (_caff == ATTIC) {
1081 					if (_num == 1) {
1082 						if (_coreVar._atticBallHoleObjectId != 0)
1083 							_crep = 188;
1084 						else {
1085 							_coreVar._atticBallHoleObjectId = _coreVar._selectedObjectId;
1086 							displayAnimFrame(1, 7);
1087 						}
1088 					} else if (_coreVar._atticRodHoleObjectId != 0) {
1089 						_crep = 188;
1090 					} else {
1091 						_coreVar._atticRodHoleObjectId = _coreVar._selectedObjectId;
1092 						displayAnimFrame(1, 6);
1093 					}
1094 				}
1095 
1096 				if (_caff == CRYPT) {
1097 					if (_coreVar._cryptObjectId != 0)
1098 						_crep = 188;
1099 					else
1100 						_coreVar._cryptObjectId = _coreVar._selectedObjectId;
1101 				}
1102 
1103 				if (_caff == WELL)
1104 					_crep = 185;
1105 				if ((_caff == CELLAR) || (_caff == SECRET_PASSAGE))
1106 					_crep = 124;
1107 			} else {
1108 				_crep = 124;
1109 				if (_caff == WELL) {
1110 					setCoordinates(5);
1111 					if (_num != 0)
1112 						_crep = 185;
1113 				}
1114 			}
1115 		}
1116 		if (_caff == INSIDE_WELL)
1117 			_crep = 185;
1118 		if ((_crep == 999) || (_crep == 185) || (_crep == 998)) {
1119 			if (_crep == 999)
1120 				putObject();
1121 			if (_crep != 192)
1122 				displayEmptyHand();
1123 		}
1124 	}
1125 }
1126 
1127 /**
1128  * Engine function - Listen
1129  * @remarks	Originally called 'tecouter'
1130  */
fctListen()1131 void MortevielleEngine::fctListen() {
1132 	if (_coreVar._currPlace != ROOM26)
1133 		_crep = 101;
1134 	else {
1135 		if (_currBitIndex != 0)
1136 			++_coreVar._faithScore;
1137 		int rand;
1138 		int pres = getPresenceStats(rand, _coreVar._faithScore, _roomDoorId);
1139 		if (_roomDoorId != OWN_ROOM) {
1140 			if (pres != -500) {
1141 				if (rand > pres)
1142 					_crep = 101;
1143 				else {
1144 					setPresenceFlags(_roomDoorId);
1145 					int day, hour, minute;
1146 					updateHour(day, hour, minute);
1147 					rand = getRandomNumber(1, 100);
1148 					if ((hour >= 0) && (hour < 8)) {
1149 						if (rand > 30)
1150 							_crep = 101;
1151 						else
1152 							_crep = 178;
1153 					} else if (rand > 70)
1154 						_crep = 101;
1155 					else
1156 						_crep = 178;
1157 				}
1158 			} else
1159 				_crep = 178;
1160 		}
1161 	}
1162 }
1163 
1164 /**
1165  * Engine function - Eat
1166  * @remarks	Originally called 'tmanger'
1167  */
fctEat()1168 void MortevielleEngine::fctEat() {
1169 	if ((_coreVar._currPlace > LANDING) && (_coreVar._currPlace < ROOM26)) {
1170 		_crep = 148;
1171 	} else {
1172 		exitRoom();
1173 		_coreVar._currPlace = DINING_ROOM;
1174 		_caff = DINING_ROOM;
1175 		resetRoomVariables(_coreVar._currPlace);
1176 		_menu->setDestinationText(_coreVar._currPlace);
1177 
1178 		int day, hour, minute;
1179 		updateHour(day, hour, minute);
1180 		if ((hour == 12) || (hour == 13) || (hour == 19)) {
1181 			_coreVar._faithScore -= (_coreVar._faithScore / 7);
1182 			if (hour == 12) {
1183 				if (minute == 0)
1184 					hour = 4;
1185 				else
1186 					hour = 3;
1187 			}
1188 
1189 			if ((hour == 13) || (hour == 19)) {
1190 				if (minute == 0)
1191 					hour = 2;
1192 				else
1193 					hour = 1;
1194 			}
1195 
1196 			_currentHourCount += hour;
1197 			_crep = 135;
1198 			prepareRoom();
1199 		} else {
1200 			_crep = 134;
1201 		}
1202 	}
1203 }
1204 
1205 /**
1206  * Engine function - Enter
1207  * @remarks	Originally called 'tentrer'
1208  */
fctEnter()1209 void MortevielleEngine::fctEnter() {
1210 	if ((_coreVar._currPlace == MANOR_FRONT) || (_coreVar._currPlace == MANOR_BACK)) {
1211 		gotoDiningRoom();
1212 		_menu->setDestinationText(_coreVar._currPlace);
1213 	} else if (_coreVar._currPlace == LANDING)
1214 		showMoveMenuAlert();
1215 	else if (_roomDoorId == OWN_ROOM)
1216 		_crep = 997;
1217 	else if ((_roomDoorId == JULIA_ROOM) && (_coreVar._selectedObjectId != 136)) {
1218 		_crep = 189;
1219 		_coreVar._availableQuestion[8] = '*';
1220 	} else {
1221 		int pres = 0;
1222 		if (!_outsideOnlyFl)
1223 			pres = getPresence(_roomDoorId);
1224 		if (pres != 0) {
1225 			if ((_roomDoorId == TOILETS) || (_roomDoorId == BATHROOM))
1226 				_crep = 179;
1227 			else {
1228 				int randVal = (getRandomNumber(0, 10)) - 5;
1229 				_soundManager->startSpeech(7, randVal, 1);
1230 				displayAnimFrame(1, 1);
1231 				_soundManager->waitSpeech();
1232 
1233 				int charIndex = convertBitIndexToCharacterIndex(pres);
1234 				++_coreVar._faithScore;
1235 				_coreVar._currPlace = LANDING;
1236 				_currMenu = MENU_DISCUSS;
1237 				_currAction = (_menu->_discussMenu[charIndex]._menuId << 8) | _menu->_discussMenu[charIndex]._actionId;
1238 				_syn = true;
1239 				if (_roomDoorId == JULIA_ROOM) {
1240 					_col = true;
1241 					_caff = 70;
1242 					drawPictureWithText();
1243 					handleDescriptionText(2, _caff);
1244 				} else
1245 					_col = false;
1246 				resetRoomVariables(_roomDoorId);
1247 				_roomDoorId = OWN_ROOM;
1248 			}
1249 		} else {
1250 			int randVal = (getRandomNumber(0, 10)) - 5;
1251 			_soundManager->startSpeech(7, randVal, 1);
1252 			displayAnimFrame(1, 1);
1253 			_soundManager->waitSpeech();
1254 
1255 			_coreVar._currPlace = _roomDoorId;
1256 			prepareDisplayText();
1257 			resetRoomVariables(_coreVar._currPlace);
1258 			_menu->setDestinationText(_coreVar._currPlace);
1259 			_roomDoorId = OWN_ROOM;
1260 			_savedBitIndex = 0;
1261 			_currBitIndex = 0;
1262 		}
1263 	}
1264 }
1265 
1266 /**
1267  * Engine function - Sleep
1268  * @remarks	Originally called 'tdormir'
1269  */
fctSleep()1270 void MortevielleEngine::fctSleep() {
1271 	if ((_coreVar._currPlace > LANDING) && (_coreVar._currPlace < ROOM26)) {
1272 		_crep = 148;
1273 		return;
1274 	}
1275 	if (_coreVar._currPlace != OWN_ROOM) {
1276 		exitRoom();
1277 		_coreVar._currPlace = OWN_ROOM;
1278 		prepareDisplayText();
1279 		drawPictureWithText();
1280 		resetRoomVariables(_coreVar._currPlace);
1281 		_menu->setDestinationText(_coreVar._currPlace);
1282 	}
1283 	clearVerbBar();
1284 	clearDescriptionBar();
1285 	prepareScreenType2();
1286 	displayTextBlock(getEngineString(S_WANT_TO_WAKE_UP));
1287 	int day, hour, minute;
1288 	updateHour(day, hour, minute);
1289 
1290 	int answer;
1291 	do {
1292 		if (hour < 8) {
1293 			_coreVar._faithScore -= (_coreVar._faithScore / 20);
1294 			int z = (7 - hour) * 2;
1295 			if (minute == 30)
1296 				--z;
1297 			_currentHourCount += z;
1298 			hour = 7;
1299 		}
1300 		_currentHourCount += 2;
1301 		++hour;
1302 		if (hour > 23)
1303 			hour = 0;
1304 		prepareRoom();
1305 		answer = _dialogManager->show(getEngineString(S_YES_NO));
1306 		_anyone = false;
1307 	} while (answer != 1);
1308 	_crep = 998;
1309 	_num = 0;
1310 }
1311 
1312 /**
1313  * Engine function - Force
1314  * @remarks	Originally called 'tdefoncer'
1315  */
fctForce()1316 void MortevielleEngine::fctForce() {
1317 	if (!_syn)
1318 		displayTextInVerbBar(getEngineString(S_SMASH));
1319 	if (_caff < DOOR)
1320 		displayStatusArrow();
1321 
1322 	if ((!_anyone) && (!_keyPressedEsc)) {
1323 		if (_coreVar._currPlace != ROOM26)
1324 			_crep = 997;
1325 		else {
1326 			_crep = 143;
1327 			_coreVar._faithScore += 2;
1328 		}
1329 	}
1330 }
1331 
1332 /**
1333  * Engine function - Leave
1334  * @remarks	Originally called 'tsortir'
1335  */
fctLeave()1336 void MortevielleEngine::fctLeave() {
1337 	exitRoom();
1338 	_crep = 0;
1339 	if ((_coreVar._currPlace == MOUNTAIN) || (_coreVar._currPlace == MANOR_FRONT) || (_coreVar._currPlace == MANOR_BACK) || (_coreVar._currPlace == WELL))
1340 		_crep = 997;
1341 	else {
1342 		int nextPlace = OWN_ROOM;
1343 
1344 		if ((_coreVar._currPlace < CRYPT) || (_coreVar._currPlace == ROOM26))
1345 			nextPlace = DINING_ROOM;
1346 		else if ((_coreVar._currPlace == DINING_ROOM) || (_coreVar._currPlace == CHAPEL))
1347 			nextPlace = MANOR_FRONT;
1348 		else if ((_coreVar._currPlace < DINING_ROOM) || (_coreVar._currPlace == ATTIC))
1349 			nextPlace = LANDING;
1350 		else if (_coreVar._currPlace == CRYPT) {
1351 			nextPlace = SECRET_PASSAGE;
1352 			_crep = 176;
1353 		} else if (_coreVar._currPlace == SECRET_PASSAGE)
1354 			nextPlace = checkLeaveSecretPassage();
1355 		else if (_coreVar._currPlace == INSIDE_WELL)
1356 			nextPlace = WELL;
1357 
1358 		if (_crep != 997)
1359 			_coreVar._currPlace = nextPlace;
1360 
1361 		_caff = nextPlace;
1362 		if (_crep == 0)
1363 			_crep = nextPlace;
1364 		resetRoomVariables(nextPlace);
1365 		_menu->setDestinationText(nextPlace);
1366 	}
1367 }
1368 
1369 /**
1370  * Engine function - Wait
1371  * @remarks	Originally called 'tattendre'
1372  */
fctWait()1373 void MortevielleEngine::fctWait() {
1374 	_savedBitIndex = 0;
1375 	clearVerbBar();
1376 
1377 	int answer;
1378 	do {
1379 		++_currentHourCount;
1380 		prepareRoom();
1381 		if (!_outsideOnlyFl)
1382 			getPresence(_coreVar._currPlace);
1383 		if ((_currBitIndex != 0) && (_savedBitIndex == 0)) {
1384 			_crep = 998;
1385 			if ((_coreVar._currPlace == ATTIC) || (_coreVar._currPlace == CELLAR))
1386 				initCaveOrCellar();
1387 			if ((_coreVar._currPlace > OWN_ROOM) && (_coreVar._currPlace < DINING_ROOM))
1388 				_anyone = true;
1389 			_savedBitIndex = _currBitIndex;
1390 			if (!_anyone)
1391 				prepareRoom();
1392 			return;
1393 		}
1394 		handleDescriptionText(2, 102);
1395 		answer = _dialogManager->show(getEngineString(S_YES_NO));
1396 	} while (answer != 2);
1397 	_crep = 998;
1398 	if (!_anyone)
1399 		prepareRoom();
1400 }
1401 
1402 /**
1403  * Engine function - Sound
1404  * @remarks	Originally called 'tsonder'
1405  */
fctSound()1406 void MortevielleEngine::fctSound() {
1407 	if (!_syn)
1408 		displayTextInVerbBar(getEngineString(S_PROBE2));
1409 	if (_caff < 27) {
1410 		displayStatusArrow();
1411 		if (!(_anyone) && (!_keyPressedEsc))
1412 			_crep = 145;
1413 		_num = 0;
1414 	}
1415 }
1416 
1417 /**
1418  * Engine function - Discuss
1419  * @remarks	Originally called 'tparler'
1420  */
fctDiscuss()1421 void MortevielleEngine::fctDiscuss() {
1422 	bool questionAsked[47];
1423 	int cy, cx;
1424 	int x, y;
1425 	Common::String lib[47];
1426 
1427 	int choice;
1428 	int displId;
1429 
1430 	endSearch();
1431 	if (_col)
1432 		displId = 128;
1433 	else {
1434 		cx = 0;
1435 		int oldMenu;
1436 		do {
1437 			++cx;
1438 			oldMenu = (_menu->_discussMenu[cx]._menuId << 8) | _menu->_discussMenu[cx]._actionId;
1439 		} while (oldMenu != _currAction);
1440 		_caff = 69 + cx;
1441 		drawPictureWithText();
1442 		handleDescriptionText(2, _caff);
1443 		displId = _caff + 60;
1444 	}
1445 	testKey(false);
1446 	menuUp();
1447 	_mouse->hideMouse();
1448 	clearScreen();
1449 	drawDiscussionBox();
1450 	startDialog(displId);
1451 	clearScreen();
1452 	for (int ix = 1; ix <= 46; ++ix)
1453 		questionAsked[ix] = false;
1454 	for (int ix = 1; ix <= 45; ++ix) {
1455 		lib[ix] = getString(ix + kQuestionStringIndex);
1456 		for (int i = lib[ix].size(); i <= 40; ++i)
1457 			lib[ix] = lib[ix] + ' ';
1458 	}
1459 	lib[46] = lib[45];
1460 	lib[45] = ' ';
1461 	_mouse->showMouse();
1462 	do {
1463 		choice = 0;
1464 		int posX = 0;
1465 		int posY = 0;
1466 		for (int icm = 1; icm < 43; icm++) {
1467 			_screenSurface->putxy(posX, posY);
1468 			if (_coreVar._availableQuestion[icm] == '*') {
1469 				// If question already asked, write it in reverse video
1470 				if (questionAsked[icm])
1471 					displayQuestionText(lib[icm], 1);
1472 				else
1473 					displayQuestionText(lib[icm], 0);
1474 			}
1475 
1476 			if (icm == 23)  {
1477 				posY = 0;
1478 				posX = 320;
1479 			} else
1480 				posY += 8;
1481 		}
1482 		_screenSurface->putxy(320, 176);
1483 		displayQuestionText(lib[46], 0);
1484 		char retKey = '\0';
1485 		bool click;
1486 		do {
1487 			bool dummyFl;
1488 			_mouse->moveMouse(dummyFl, retKey);
1489 			if (shouldQuit())
1490 				return;
1491 
1492 			_mouse->getMousePosition(x, y, click);
1493 			x *= (3 - kResolutionScaler);
1494 			if (x > 319)
1495 				cx = 41;
1496 			else
1497 				cx = 1;
1498 			cy = ((uint)y >> 3) + 1;      // 0-199 => 1-25
1499 			if ((cy > 23) || ((cx == 41) && ((cy >= 20) && (cy <= 22)))) {
1500 				if (choice != 0) {
1501 					posY = ((choice - 1) % 23) << 3;
1502 					if (choice > 23)
1503 						posX = 320;
1504 					else
1505 						posX = 0;
1506 					_screenSurface->putxy(posX, posY);
1507 					if (questionAsked[choice])
1508 						displayQuestionText(lib[choice], 0);
1509 					else
1510 						displayQuestionText(lib[choice], 1);
1511 					questionAsked[choice] = !questionAsked[choice];
1512 					choice = 0;
1513 				}
1514 			} else {
1515 				int ix = cy;
1516 				if (cx == 41)
1517 					ix += 23;
1518 				if (ix != choice) {
1519 					if (choice != 0) {
1520 						posY = ((choice - 1) % 23) << 3;
1521 						if (choice > 23)
1522 							posX = 320;
1523 						else
1524 							posX = 0;
1525 						_screenSurface->putxy(posX, posY);
1526 						if (questionAsked[choice])
1527 							displayQuestionText(lib[choice], 0);
1528 						else
1529 							displayQuestionText(lib[choice], 1);
1530 						questionAsked[choice] = ! questionAsked[choice];
1531 					}
1532 					if ((ix == 46) || (_coreVar._availableQuestion[ix] == '*')) {
1533 						posY = ((ix - 1) % 23) << 3;
1534 						if (ix > 23)
1535 							posX = 320;
1536 						else
1537 							posX = 0;
1538 						_screenSurface->putxy(posX, posY);
1539 						if (questionAsked[ix])
1540 							displayQuestionText(lib[ix], 0);
1541 						else
1542 							displayQuestionText(lib[ix], 1);
1543 						questionAsked[ix] = ! questionAsked[ix];
1544 						choice = ix;
1545 					} else
1546 						choice = 0;
1547 				}
1548 			}
1549 		} while (!((retKey == '\15') || (((click != 0) || getMouseClick()) && (choice != 0))));
1550 		setMouseClick(false);
1551 
1552 		// If choice is not "End of Conversation"
1553 		if (choice != 46) {
1554 			int ix = choice - 1;
1555 			if (_col) {
1556 				_col = false;
1557 				_coreVar._currPlace = 15;
1558 				int maxRandVal;
1559 				if (_openObjCount > 0)
1560 					maxRandVal = 8;
1561 				else
1562 					maxRandVal = 4;
1563 				if (getRandomNumber(1, maxRandVal) == 2)
1564 					displId = 129;
1565 				else {
1566 					displId = 138;
1567 					_coreVar._faithScore += (3 * (_coreVar._faithScore / 10));
1568 				}
1569 			} else if (_charAnswerCount[_caff - 69] < _charAnswerMax[_caff - 69]) {
1570 				displId = _tabdon[kArep + (ix << 3) + (_caff - 70)];
1571 				_coreVar._faithScore += _tabdon[kArcf + ix];
1572 				++_charAnswerCount[_caff - 69];
1573 			} else {
1574 				_coreVar._faithScore += 3;
1575 				displId = 139;
1576 			}
1577 			_mouse->hideMouse();
1578 			clearScreen();
1579 			drawDiscussionBox();
1580 			startDialog(displId);
1581 			_mouse->showMouse();
1582 			if ((displId == 84) || (displId == 86)) {
1583 				_coreVar._pctHintFound[5] = '*';
1584 				_coreVar._availableQuestion[7] = '*';
1585 			}
1586 			if ((displId == 106) || (displId == 108) || (displId == 94)) {
1587 				for (int indx = 29; indx <= 31; ++indx)
1588 					_coreVar._availableQuestion[indx] = '*';
1589 				_coreVar._pctHintFound[7] = '*';
1590 			}
1591 			if (displId == 70) {
1592 				_coreVar._pctHintFound[8] = '*';
1593 				_coreVar._availableQuestion[32] = '*';
1594 			}
1595 			_mouse->hideMouse();
1596 			clearScreen();
1597 			_mouse->showMouse();
1598 		}
1599 	} while ((choice != 46) && (displId != 138));
1600 	if (_col) {
1601 		_coreVar._faithScore += (3 * (_coreVar._faithScore / 10));
1602 		_mouse->hideMouse();
1603 		clearScreen();
1604 		drawDiscussionBox();
1605 		startDialog(138);
1606 		_mouse->showMouse();
1607 		_col = false;
1608 		_coreVar._currPlace = LANDING;
1609 	}
1610 	_controlMenu = 0;
1611 	_mouse->hideMouse();
1612 	clearScreen();
1613 	drawRightFrame();
1614 	_mouse->showMouse();
1615 	showPeoplePresent(_currBitIndex);
1616 	prepareRoom();
1617 	drawClock();
1618 	prepareDisplayText();
1619 	/* chech;*/
1620 	_menu->setDestinationText(_coreVar._currPlace);
1621 	clearVerbBar();
1622 }
1623 
1624 /**
1625  * Engine function - Smell
1626  * @remarks	Originally called 'tsentir'
1627  */
fctSmell()1628 void MortevielleEngine::fctSmell() {
1629 	_crep = 119;
1630 	if (_caff < ROOM26) {
1631 		if (!_syn)
1632 			displayTextInVerbBar(getEngineString(S_SMELL));
1633 		displayStatusArrow();
1634 		if (!(_anyone) && !(_keyPressedEsc))
1635 			if (_caff == CRYPT)
1636 				_crep = 153;
1637 	} else if (_caff == 123)
1638 		_crep = 110;
1639 	_num = 0;
1640 }
1641 
1642 /**
1643  * Engine function - Scratch
1644  * @remarks	Originally called 'tgratter'
1645  */
fctScratch()1646 void MortevielleEngine::fctScratch() {
1647 	_crep = 155;
1648 	if (_caff < 27) {
1649 		if (!_syn)
1650 			displayTextInVerbBar(getEngineString(S_SCRATCH));
1651 		displayStatusArrow();
1652 	}
1653 	_num = 0;
1654 }
1655 
1656 /**
1657  * The game is over
1658  * @remarks	Originally called 'tmaj1'
1659  */
endGame()1660 void MortevielleEngine::endGame() {
1661 	_quitGame = true;
1662 	displayNarrativePicture(13, 152);
1663 	displayEmptyHand();
1664 	clearUpperLeftPart();
1665 	clearDescriptionBar();
1666 	clearVerbBar();
1667 	handleDescriptionText(9, 1509);
1668 	testKey(false);
1669 	_mouse->hideMouse();
1670 	_caff = 70;
1671 	_text->taffich();
1672 	clearScreen();
1673 	drawDiscussionBox();
1674 	startDialog(141);
1675 	_mouse->showMouse();
1676 	clearUpperLeftPart();
1677 	handleDescriptionText(9, 1509);
1678 	handleDescriptionText(2, 142);
1679 	testKey(false);
1680 	_caff = 32;
1681 	drawPictureWithText();
1682 	handleDescriptionText(6, 34);
1683 	handleDescriptionText(2, 35);
1684 	startMusicOrSpeech(0);
1685 	testKey(false);
1686 	displayInterScreenMessage(2036);
1687 	testKey(false);
1688 	resetVariables();
1689 }
1690 
1691 /**
1692  * You lost!
1693  * @remarks	Originally called 'tencore'
1694  */
askRestart()1695 void MortevielleEngine::askRestart() {
1696 	clearDescriptionBar();
1697 	startMusicOrSpeech(0);
1698 	testKey(false);
1699 	displayEmptyHand();
1700 	resetVariables();
1701 	initGame();
1702 	_currHour = 10;
1703 	_currHalfHour = 0;
1704 	_currDay = 0;
1705 	_minute = 0;
1706 	_hour = 10;
1707 	_day = 0;
1708 	handleDescriptionText(2, 180);
1709 
1710 	int answer = _dialogManager->show(getEngineString(S_YES_NO));
1711 	_quitGame = (answer != 1);
1712 }
1713 
1714 } // End of namespace Mortevielle
1715