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