1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "common/system.h"
24 #include "graphics/palette.h"
25 #include "graphics/cursorman.h"
26 
27 #include "supernova/screen.h"
28 #include "supernova/supernova.h"
29 #include "supernova/supernova1/state.h"
30 #include "supernova/supernova1/stringid.h"
31 
32 namespace Supernova {
33 
Room1()34 Room1::Room1() {
35 	_dialogsX[0] = kStringDialogX1;
36 	_dialogsX[1] = kStringDialogX2;
37 	_dialogsX[2] = kStringDialogX3;
38 }
39 
Intro(SupernovaEngine * vm,GameManager1 * gm)40 Intro::Intro(SupernovaEngine *vm, GameManager1 *gm) {
41 	_vm = vm;
42 	_gm = gm;
43 
44 	_fileNumber = -1;
45 	_id = INTRO1;
46 	_shown[0] = kShownFalse;
47 
48 	_objectState[0] =
49 	Object(_id, kStringKeycard, kStringKeycardDescription, KEYCARD,
50 		   TAKE | CARRIED | COMBINABLE, 255, 255, 0, NULLROOM, 0);
51 	_objectState[1] =
52 	Object(_id, kStringKnife, kStringKnifeDescription, KNIFE,
53 		   TAKE | CARRIED | COMBINABLE, 255, 255, 0, NULLROOM, 0);
54 	_objectState[2] =
55 	Object(_id, kStringWatch, kStringDefaultDescription, WATCH,
56 		   TAKE | COMBINABLE | CARRIED, 255, 255, 8, NULLROOM, 0);
57 	_objectState[3] =
58 	Object(_id, kStringDiscman, kStringDiscmanDescription, DISCMAN,
59 		   TAKE | COMBINABLE, 255, 255, 0, NULLROOM, 0);
60 	_objectState[4] =
61 	Object(_id, kStringInventoryMoney, kStringDefaultDescription, MONEY,
62 		   TAKE | COMBINABLE, 255, 255, 0);
63 
64 	_shouldExit = false;
65 
66 	_introText =
67 		_vm->getGameString(kStringIntro1) + '\1' +
68 		_vm->getGameString(kStringIntro2) + '\1' +
69 		_vm->getGameString(kStringIntro3) + '\1' +
70 		_vm->getGameString(kStringIntro4) + '\1' +
71 		_vm->getGameString(kStringIntro5) + '\1' +
72 		_vm->getGameString(kStringIntro6) + '\1' +
73 		_vm->getGameString(kStringIntro7) + '\1' +
74 		_vm->getGameString(kStringIntro8) + '\1' +
75 		_vm->getGameString(kStringIntro9) + '\1' +
76 		_vm->getGameString(kStringIntro10) + '\1' +
77 		_vm->getGameString(kStringIntro11) + '\1' +
78 		_vm->getGameString(kStringIntro12) + '\1' +
79 		_vm->getGameString(kStringIntro13) + '\1';
80 }
81 
onEntrance()82 void Intro::onEntrance() {
83 	_gm->_guiEnabled = false;
84 	_vm->_allowSaveGame = false;
85 	_vm->_allowLoadGame = false;
86 	titleScreen();
87 	cutscene();
88 	leaveCutscene();
89 }
90 
titleScreen()91 void Intro::titleScreen() {
92 	// Newspaper
93 	CursorMan.showMouse(false);
94 	_vm->_screen->setViewportBrightness(0);
95 	_vm->_screen->setGuiBrightness(0);
96 	_vm->paletteBrightness();
97 	_vm->setCurrentImage(1);
98 	_vm->renderImage(0);
99 	_vm->paletteFadeIn();
100 	_gm->getInput();
101 	_vm->paletteFadeOut();
102 
103 	// Title Screen
104 	_vm->setCurrentImage(31);
105 	_vm->renderImage(0);
106 	_vm->paletteFadeIn();
107 	_gm->wait(1);
108 	_vm->playSound(kAudioVoiceSupernova);
109 	while (_vm->_sound->isPlaying())
110 		_gm->wait(1);
111 	titleFadeIn();
112 	_vm->renderText(kStringTitleVersion, 295, 190, kColorWhite44);
113 	const Common::String& title1 = _vm->getGameString(kStringTitle1);
114 	const Common::String& title2 = _vm->getGameString(kStringTitle2);
115 	const Common::String& title3 = _vm->getGameString(kStringTitle3);
116 	_vm->_screen->renderText(title1, 78 - Screen::textWidth(title1) / 2, 120, kColorLightBlue);
117 	_vm->_screen->renderText(title2, 78 - Screen::textWidth(title2) / 2, 132, kColorWhite99);
118 	_vm->_screen->renderText(title3, 78 - Screen::textWidth(title3) / 2, 142, kColorWhite99);
119 	_gm->wait(1);
120 	CursorMan.showMouse(true);
121 	_vm->playSound(kMusicIntro);
122 
123 	Marquee marquee(_vm->_screen, Marquee::kMarqueeIntro, _introText.c_str());
124 	while (!_vm->shouldQuit()) {
125 		_gm->updateEvents();
126 		marquee.renderCharacter();
127 		if (_gm->_mouseClicked || _gm->_keyPressed)
128 			break;
129 		g_system->updateScreen();
130 		g_system->delayMillis(_vm->_delay);
131 	}
132 	_vm->playSound(kAudioVoiceYeah);
133 	while (_vm->_sound->isPlaying() && !_vm->shouldQuit())
134 		_gm->wait(1);
135 	_vm->paletteFadeOut();
136 }
137 
titleFadeIn()138 void Intro::titleFadeIn() {
139 	byte titlePaletteColor[] = {0xfe, 0xeb};
140 	byte titleNewColor[2][3] = {{255, 255, 255}, {199, 21, 21}};
141 	byte newColors[2][3];
142 
143 	for (int brightness = 1; brightness <= 40; ++brightness) {
144 		for (int colorIndex = 0; colorIndex < 2; ++colorIndex) {
145 			for (int i = 0; i < 3; ++i) {
146 				newColors[colorIndex][i] = (titleNewColor[colorIndex][i] * brightness) / 40;
147 			}
148 		}
149 
150 		_vm->_system->getPaletteManager()->setPalette(newColors[0], titlePaletteColor[0], 1);
151 		_vm->_system->getPaletteManager()->setPalette(newColors[1], titlePaletteColor[1], 1);
152 		_vm->_system->updateScreen();
153 		_vm->_system->delayMillis(_vm->_delay);
154 	}
155 }
156 
animate(int section1,int section2,int duration)157 bool Intro::animate(int section1, int section2, int duration) {
158 	Common::KeyCode key = Common::KEYCODE_INVALID;
159 	while (duration) {
160 		_vm->renderImage(section1);
161 		if (_gm->waitOnInput(2, key))
162 			return key != Common::KEYCODE_ESCAPE;
163 		_vm->renderImage(section2);
164 		if (_gm->waitOnInput(2, key))
165 			return key != Common::KEYCODE_ESCAPE;
166 		--duration;
167 	}
168 	return true;
169 }
170 
animate(int section1,int section2,int duration,MessagePosition position,int textId)171 bool Intro::animate(int section1, int section2, int duration,
172 					MessagePosition position, int textId) {
173 	Common::KeyCode key = Common::KEYCODE_INVALID;
174 	const Common::String& text = _vm->getGameString(textId);
175 	_vm->renderMessage(text, position);
176 	int delay = (MIN(text.size(), (uint)512) + 20) * (10 - duration) * _vm->_textSpeed / 400;
177 	while (delay) {
178 		if (section1)
179 			_vm->renderImage(section1);
180 		if (_gm->waitOnInput(2, key)) {
181 			_vm->removeMessage();
182 			return key != Common::KEYCODE_ESCAPE;
183 		}
184 		if (section2)
185 			_vm->renderImage(section2);
186 		if (_gm->waitOnInput(2, key)) {
187 			_vm->removeMessage();
188 			return key != Common::KEYCODE_ESCAPE;
189 		}
190 		--delay;
191 	}
192 	_vm->removeMessage();
193 	return true;
194 }
195 
animate(int section1,int section2,int section3,int section4,int duration,MessagePosition position,int textId)196 bool Intro::animate(int section1, int section2, int section3, int section4,
197 					int duration, MessagePosition position, int textId) {
198 	Common::KeyCode key = Common::KEYCODE_INVALID;
199 	const Common::String& text = _vm->getGameString(textId);
200 	_vm->renderMessage(text, position);
201 	if (duration == 0)
202 		duration = (MIN(text.size(), (uint)512) + 20) * _vm->_textSpeed / 40;
203 
204 	while(duration) {
205 		_vm->renderImage(section1);
206 		_vm->renderImage(section3);
207 		if (_gm->waitOnInput(2, key)) {
208 			_vm->removeMessage();
209 			return key != Common::KEYCODE_ESCAPE;
210 		}
211 		_vm->renderImage(section2);
212 		_vm->renderImage(section4);
213 		if (_gm->waitOnInput(2, key)) {
214 			_vm->removeMessage();
215 			return key != Common::KEYCODE_ESCAPE;
216 		}
217 		duration--;
218 	}
219 	_vm->removeMessage();
220 	return true;
221 }
222 
cutscene()223 void Intro::cutscene() {
224 #define exitOnEscape(X) do { \
225 	Common::KeyCode key = Common::KEYCODE_INVALID; \
226 	if ((_gm->waitOnInput(X, key) && key == Common::KEYCODE_ESCAPE) || _vm->shouldQuit()) { \
227 		CursorMan.showMouse(true); \
228 		return; \
229 	} \
230 } while (0);
231 
232 	_vm->_system->fillScreen(kColorBlack);
233 	_vm->setCurrentImage(31);
234 	_vm->_screen->setGuiBrightness(255);
235 	_vm->paletteBrightness();
236 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene1))
237 		return;
238 	_vm->_screen->setGuiBrightness(0);
239 	_vm->paletteBrightness();
240 	exitOnEscape(1);
241 
242 	_vm->setCurrentImage(9);
243 	_vm->renderImage(0);
244 	_vm->renderImage(1);
245 	_vm->renderImage(9);
246 	_vm->paletteFadeIn();
247 	if (!animate(11, 10, 6, kMessageRight, kStringIntroCutscene2))
248 		return;
249 	_vm->renderImage(3);
250 	exitOnEscape(4);
251 	_vm->renderImage(4);
252 	if (!animate(11, 10, 3)) {// test duration
253 		_vm->removeMessage();
254 		return;
255 	}
256 	_vm->removeMessage();
257 	if (!animate(5, 4, 0, kMessageLeft, kStringIntroCutscene3))
258 		return;
259 	_vm->renderImage(3);
260 	exitOnEscape(3);
261 	_vm->renderImage(2);
262 	exitOnEscape(3);
263 	_vm->renderImage(7);
264 	exitOnEscape(6);
265 	_vm->renderImage(6);
266 	exitOnEscape(6);
267 	if (!animate(0, 0, 0, kMessageLeft, kStringIntroCutscene4))
268 		return;
269 	_vm->renderMessage(kStringIntroCutscene5, kMessageLeft);
270 	exitOnEscape(28);
271 	_vm->removeMessage();
272 	_vm->renderMessage(kStringIntroCutscene6, kMessageLeft);
273 	exitOnEscape(28);
274 	_vm->removeMessage();
275 
276 	int textCounting[4] =
277 	{kStringIntroCutscene7, kStringIntroCutscene8, kStringIntroCutscene9, kStringIntroCutscene10};
278 	_vm->setCurrentImage(31);
279 	_vm->renderImage(0);
280 	_vm->paletteBrightness();
281 	for (int i = 0; i < 4; ++i){
282 		_vm->renderMessage(textCounting[i], kMessageLeft);
283 		for (int j = 0; j < 28; ++j) {
284 			_vm->renderImage((j % 3) + 1);
285 			Common::KeyCode key = Common::KEYCODE_INVALID;
286 			if (_gm->waitOnInput(1, key)) {
287 				if (key == Common::KEYCODE_ESCAPE)
288 					return;
289 				break;
290 			}
291 		}
292 		_vm->removeMessage();
293 	}
294 	_vm->renderMessage(kStringIntroCutscene11, kMessageLeft);
295 	_vm->renderImage(6);
296 	exitOnEscape(3);
297 	_vm->renderImage(3);
298 	exitOnEscape(3);
299 	_vm->renderImage(4);
300 	exitOnEscape(3);
301 	_vm->renderImage(5);
302 	exitOnEscape(3);
303 	_vm->renderImage(_gm->invertSection(5));
304 	exitOnEscape(18);
305 	_vm->removeMessage();
306 
307 	_vm->setCurrentImage(9);
308 	_vm->renderImage(0);
309 	_vm->renderImage(1);
310 	_vm->renderImage(9);
311 	_vm->paletteBrightness();
312 	_vm->renderBox(0, 138, 320, 62, kColorBlack);
313 	_vm->paletteBrightness();
314 	if (!animate(11, 10, 0, kMessageRight, kStringIntroCutscene12))
315 		return;
316 	_vm->renderImage(3);
317 	exitOnEscape(3);
318 	_vm->renderImage(4);
319 	if (!animate(5, 4, 0, kMessageLeft, kStringIntroCutscene13))
320 		return;
321 	if (!animate(0, 0, 0, kMessageCenter, kStringIntroCutscene14))
322 		return;
323 	_vm->renderImage(12);
324 	exitOnEscape(2);
325 	_vm->renderImage(13);
326 	exitOnEscape(2);
327 	_vm->renderImage(14);
328 	if (!animate(19, 20, 0, kMessageRight, kStringIntroCutscene15))
329 		return;
330 	if (!animate(0, 0, 0, kMessageCenter, kStringIntroCutscene16))
331 		return;
332 	exitOnEscape(20);
333 	if (!animate(0, 0, 0, kMessageCenter, kStringIntroCutscene17))
334 		return;
335 	if (!animate(19, 20, 0, kMessageRight, kStringIntroCutscene18))
336 		return;
337 	if (!animate(0, 0, 0, kMessageCenter, kStringIntroCutscene19))
338 		return;
339 	_vm->renderImage(16);
340 	exitOnEscape(3);
341 	_vm->renderImage(17);
342 	if (!animate(19, 20, 18, 17, 0, kMessageRight, kStringIntroCutscene20))
343 		return;
344 	if (!animate(19, 20, 18, 17, 0, kMessageRight, kStringIntroCutscene21))
345 		return;
346 	if (!animate(5, 4, 0, kMessageLeft, kStringIntroCutscene3))
347 		return;
348 	_vm->renderImage(3);
349 	exitOnEscape(3);
350 	_vm->renderImage(2);
351 	exitOnEscape(3);
352 	_vm->renderImage(8);
353 	exitOnEscape(6);
354 	_vm->renderImage(6);
355 	_vm->playSound(kAudioSiren);
356 
357 	exitOnEscape(6);
358 	_vm->renderImage(3);
359 	exitOnEscape(3);
360 	_vm->renderImage(4);
361 	_vm->renderImage(16);
362 	exitOnEscape(3);
363 	_vm->renderImage(15);
364 	if (!animate(19, 20, 0, kMessageRight, kStringIntroCutscene22))
365 		return;
366 	if (!animate(19, 20, 0, kMessageRight, kStringIntroCutscene23))
367 		return;
368 	exitOnEscape(10);
369 	_vm->renderImage(13);
370 	exitOnEscape(2);
371 	_vm->renderImage(12);
372 	exitOnEscape(2);
373 	_vm->renderImage(9);
374 	if (!animate(11, 10, 0, kMessageRight, kStringIntroCutscene24))
375 		return;
376 	if (!animate(5, 4, 0, kMessageLeft, kStringIntroCutscene3))
377 		return;
378 	_vm->paletteFadeOut();
379 
380 	while (_vm->_sound->isPlaying())
381 		exitOnEscape(1);
382 
383 	_vm->_system->fillScreen(kColorBlack);
384 	_vm->_screen->setGuiBrightness(255);
385 	_vm->paletteBrightness();
386 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene25))
387 		return;
388 	_vm->_screen->setGuiBrightness(5);
389 	_vm->paletteBrightness();
390 
391 	_vm->setCurrentImage(31);
392 	_vm->renderImage(0);
393 	_vm->paletteFadeIn();
394 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene26))
395 		return;
396 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene27))
397 		return;
398 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene28))
399 		return;
400 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene29))
401 		return;
402 	exitOnEscape(54);
403 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene30))
404 		return;
405 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene31))
406 		return;
407 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene32))
408 		return;
409 
410 	CursorMan.showMouse(false);
411 	_vm->_screen->setViewportBrightness(0);
412 	_vm->paletteBrightness();
413 	exitOnEscape(10);
414 	_vm->playSound(kAudioSnoring);
415 	while (_vm->_sound->isPlaying())
416 		_gm->wait(1);
417 	exitOnEscape(10);
418 	_vm->playSound(kAudioSnoring);
419 	while (_vm->_sound->isPlaying())
420 		_gm->wait(1);
421 	exitOnEscape(10);
422 	_vm->playSound(kAudioSnoring);
423 	while (_vm->_sound->isPlaying())
424 		_gm->wait(1);
425 	exitOnEscape(30);
426 	CursorMan.showMouse(true);
427 
428 	_vm->setCurrentImage(22);
429 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene33))
430 		return;
431 	exitOnEscape(18);
432 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene34))
433 		return;
434 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene35))
435 		return;
436 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene36))
437 		return;
438 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene37))
439 		return;
440 	exitOnEscape(18);
441 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene38))
442 		return;
443 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene39))
444 		return;
445 	exitOnEscape(18);
446 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene40))
447 		return;
448 	if (!animate(0, 0, 0, kMessageNormal, kStringIntroCutscene41))
449 		return;
450 	exitOnEscape(36);
451 	animate(0, 0, 0, kMessageNormal, kStringIntroCutscene42);
452 	_vm->removeMessage();
453 
454 #undef exitOnEscape
455 }
456 
leaveCutscene()457 void Intro::leaveCutscene() {
458 	_vm->_screen->setViewportBrightness(255);
459 	_vm->removeMessage();
460 	_gm->changeRoom(CABIN_R3);
461 	_gm->_guiEnabled = true;
462 	_vm->_allowSaveGame = true;
463 	_vm->_allowLoadGame = true;
464 }
465 
ShipCorridor(SupernovaEngine * vm,GameManager1 * gm)466 ShipCorridor::ShipCorridor(SupernovaEngine *vm, GameManager1 *gm) {
467 	_vm = vm;
468 	_gm = gm;
469 
470 	_fileNumber = 17;
471 	_id = CORRIDOR_ROOM;
472 	_shown[0] = kShownTrue;
473 	_shown[4] = kShownTrue;
474 
475 	_objectState[0] = Object(_id, kStringHatch, kStringDefaultDescription, HATCH1, OPENABLE | EXIT, 0, 6, 1, CABIN_L1, 15);
476 	_objectState[1] = Object(_id, kStringHatch, kStringDefaultDescription, NULLOBJECT, OPENABLE | EXIT, 1, 7, 2, CABIN_L2, 10);
477 	_objectState[2] = Object(_id, kStringHatch, kStringDefaultDescription, NULLOBJECT, OPENABLE | EXIT, 2, 8, 3, CABIN_L3, 5);
478 	_objectState[3] = Object(_id, kStringHatch, kStringDefaultDescription, NULLOBJECT, OPENABLE | EXIT, 5, 11, 6, CABIN_R1, 19);
479 	_objectState[4] = Object(_id, kStringHatch, kStringDefaultDescription, NULLOBJECT, OPENABLE | EXIT, 4, 10, 5, CABIN_R2, 14);
480 	_objectState[5] = Object(_id, kStringHatch, kStringDefaultDescription, NULLOBJECT, OPENABLE | EXIT | OPENED, 9, 3, 4, CABIN_R3, 9);
481 	_objectState[6] = Object(_id, kStringHatch, kStringDefaultDescription, NULLOBJECT, OPENABLE | CLOSED | EXIT, 12, 12, 0, AIRLOCK, 2);
482 	_objectState[7] = Object(_id, kStringButton, kStringHatchButtonDescription, BUTTON, PRESS, 13, 13, 0, NULLROOM, 0);
483 	_objectState[8] = Object(_id, kStringLadder, kStringDefaultDescription, NULLOBJECT, NULLTYPE, 14, 14, 0, NULLROOM, 0);
484 	_objectState[9] = Object(_id, kStringExit, kStringDefaultDescription, NULLOBJECT, EXIT, 15, 15, 0, HALL, 22);
485 }
486 
interact(Action verb,Object & obj1,Object & obj2)487 bool ShipCorridor::interact(Action verb, Object &obj1, Object &obj2) {
488 	if ((verb == ACTION_PRESS) && (obj1._id == BUTTON)) {
489 		if (_objectState[6].hasProperty(OPENED)) {
490 			_vm->playSound(kAudioSlideDoor);
491 			_objectState[6].disableProperty(OPENED);
492 			_vm->renderImage(8);
493 			setSectionVisible(9, false);
494 			_gm->wait(2);
495 			_vm->renderImage(7);
496 			setSectionVisible(8, false);
497 			_gm->wait(2);
498 			_vm->renderImage(_gm->invertSection(7));
499 		} else {
500 			_vm->playSound(kAudioSlideDoor);
501 			_objectState[6].setProperty(OPENED);
502 			_vm->renderImage(7);
503 			_gm->wait(2);
504 			_vm->renderImage(8);
505 			setSectionVisible(7, false);
506 			_gm->wait(2);
507 			_vm->renderImage(9);
508 			setSectionVisible(8, false);
509 		}
510 		return true;
511 	}
512 	return false;
513 }
514 
ShipHall(SupernovaEngine * vm,GameManager1 * gm)515 ShipHall::ShipHall(SupernovaEngine *vm, GameManager1 *gm) {
516 	_vm = vm;
517 	_gm = gm;
518 
519 	_fileNumber = 15;
520 	_id = HALL;
521 	_shown[0] = kShownTrue;
522 
523 	_objectState[0] = Object(_id, kStringHatch, kStringCockpitHatchDescription, NULLOBJECT, OPENABLE | EXIT, 4, 5, 1, COCKPIT, 10);
524 	_objectState[1] = Object(_id, kStringHatch, kStringKitchenHatchDescription, KITCHEN_HATCH, OPENABLE | EXIT, 0, 0, 0, NULLROOM, 1);
525 	_objectState[2] = Object(_id, kStringHatch, kStringStasisHatchDescription, NULLOBJECT, OPENABLE | CLOSED | EXIT, 1, 1, 2, SLEEP, 8);
526 	_objectState[3] = Object(_id, kStringSlot, kStringSlotDescription, SLEEP_SLOT, COMBINABLE, 2, 2, 0, NULLROOM, 0);
527 	_objectState[4] = Object(_id, kStringLadder, kStringDefaultDescription, NULLOBJECT, NULLTYPE, 3, SLEEP, 0, NULLROOM, 0);
528 	_objectState[5] = Object(_id, kStringCorridor, kStringDefaultDescription, NULLOBJECT, EXIT, 6, 6, 0, CORRIDOR_ROOM, 19);
529 }
530 
interact(Action verb,Object & obj1,Object & obj2)531 bool ShipHall::interact(Action verb, Object &obj1, Object &obj2) {
532 	if ((verb == ACTION_OPEN) && (obj1._id == KITCHEN_HATCH)) {
533 		_vm->renderMessage(kStringShipHall1);
534 	} else if ((verb == ACTION_USE) && Object::combine(obj1,obj2,KEYCARD2,SLEEP_SLOT)) {
535 		if (_objectState[2].hasProperty(OPENED)) {
536 			_objectState[2].disableProperty(OPENED);
537 			_vm->renderImage(3);
538 			setSectionVisible(4, false);
539 			_gm->wait(2);
540 			_vm->renderImage(2);
541 			setSectionVisible(3, false);
542 			_gm->wait(2);
543 			_vm->renderImage(_gm->invertSection(2));
544 		} else {
545 			_objectState[2].setProperty(OPENED);
546 			_vm->renderImage(2);
547 			_gm->wait(2);
548 			_vm->renderImage(3);
549 			setSectionVisible(2, false);
550 			_gm->wait(2);
551 			_vm->renderImage(4);
552 			setSectionVisible(3, false);
553 			_gm->great(1);
554 		}
555 	} else {
556 		return false;
557 	}
558 
559 	return true;
560 }
561 
ShipSleepCabin(SupernovaEngine * vm,GameManager1 * gm)562 ShipSleepCabin::ShipSleepCabin(SupernovaEngine *vm, GameManager1 *gm) {
563 	_vm = vm;
564 	_gm = gm;
565 
566 	_fileNumber = 33;
567 	_id = SLEEP;
568 	_shown[0] = kShownTrue;
569 	_color = kColorBlack;
570 
571 	_objectState[0] = Object(_id, kStringHatch, kStringStasisHatchDescription2, CABINS, NULLTYPE, 0, 0, 0, NULLROOM, 0);
572 	_objectState[1] = Object(_id, kStringHatch, kStringStasisHatchDescription2, CABIN, NULLTYPE, 1, 1, 0, NULLROOM, 0);
573 	_objectState[2] = Object(_id, kStringComputer, kStringDefaultDescription, COMPUTER, NULLTYPE, 2, 2, 0, NULLROOM, 0);
574 	_objectState[3] = Object(_id, kStringExit, kStringDefaultDescription, NULLOBJECT, EXIT, 255, 255, 0, HALL, 22);
575 }
576 
interact(Action verb,Object & obj1,Object & obj2)577 bool ShipSleepCabin::interact(Action verb, Object &obj1, Object &obj2) {
578 	Room *room;
579 	Common::String input;
580 
581 	if (((verb == ACTION_LOOK) || (verb == ACTION_USE)) && (obj1._id == COMPUTER)) {
582 		_gm->_guiEnabled = false;
583 		setSectionVisible(4, false);
584 		g_system->fillScreen(kColorDarkBlue);
585 		if (_gm->_state._arrivalDaysLeft == 0) {
586 			// Destination reached
587 			_vm->renderText(kStringShipSleepCabin1, 60, 95, kColorWhite99);
588 			_gm->getInput();
589 		} else if (_gm->_state._powerOff) {
590 			// Energy depleted
591 			_vm->renderText(kStringShipSleepCabin2, 60, 95, kColorWhite99);
592 			// Artificial coma interrupted
593 			_vm->renderText(kStringShipSleepCabin3, 60, 115, kColorWhite99);
594 			_gm->getInput();
595 		} else if (isSectionVisible(5)) {
596 			// Sleep duration in days
597 			_vm->renderText(kStringShipSleepCabin4, 30, 85, kColorWhite99);
598 			_vm->renderText(Common::String::format("%d",_gm->_state._timeSleep).c_str(),
599 							150, 85, kColorWhite99);
600 			_vm->renderText(kStringShipSleepCabin5, 30, 105, kColorWhite99);
601 			_gm->getInput();
602 		} else {
603 			_vm->renderText(kStringShipSleepCabin6, 100, 85, kColorWhite99);
604 			_gm->edit(input, 100, 105, 30);
605 
606 			input.toUppercase();
607 			if (_gm->_key.keycode != Common::KEYCODE_ESCAPE) {
608 				if (input == _vm->getGameString(kStringComputerPassword)) {
609 					_gm->great(6);
610 					g_system->fillScreen(kColorDarkBlue);
611 					_vm->renderText(kStringShipSleepCabin7, 30, 85, kColorWhite99);
612 					uint daysSleep = 0;
613 					do {
614 						input.clear();
615 						_vm->renderBox(150, 85, 150, 8, kColorDarkBlue);
616 						_gm->edit(input, 150, 85, 10);
617 
618 						if (_gm->_key.keycode == Common::KEYCODE_ESCAPE) {
619 							break;
620 						} else {
621 							daysSleep = input.asUint64();
622 							for (uint i = 0; i < input.size(); i++) {
623 								if (!Common::isDigit(input[i])) {
624 									daysSleep = 0;
625 									break;
626 								}
627 							}
628 						}
629 						if (daysSleep != 0) {
630 							_gm->_state._timeSleep = daysSleep;
631 							_vm->renderText(kStringShipSleepCabin8, 30, 105, kColorWhite99);
632 							_gm->wait(18);
633 							setSectionVisible(5, true);
634 						}
635 					} while (daysSleep == 0);
636 				} else {
637 					_vm->renderText(kStringShipSleepCabin9, 100, 125, kColorLightRed);
638 					_gm->wait(18);
639 				}
640 			}
641 		}
642 
643 		_gm->_guiEnabled = true;
644 		input.clear();
645 	} else if (((verb == ACTION_WALK) || (verb == ACTION_USE)) &&
646 			   ((obj1._id == CABINS) || (obj1._id == CABIN))) {
647 		room = _gm->_rooms[AIRLOCK];
648 		if (!(obj1._id == CABIN) || !isSectionVisible(5)) {
649 			_vm->renderMessage(kStringShipSleepCabin10);
650 		} else if (room->getObject(5)->hasProperty(WORN)) {
651 			_vm->renderMessage(kStringShipSleepCabin11);
652 		} else {
653 			_vm->paletteFadeOut();
654 			_vm->renderImage(_gm->invertSection(5));
655 			_vm->renderImage(_gm->invertSection(4));
656 			room = _gm->_rooms[GENERATOR];
657 			int32 *energyDaysLeft;
658 			if (room->isSectionVisible(9)) {
659 				energyDaysLeft = &_gm->_state._landingModuleEnergyDaysLeft;
660 			} else {
661 				energyDaysLeft = &_gm->_state._shipEnergyDaysLeft;
662 			}
663 			if (_gm->_state._timeSleep > _gm->_state._arrivalDaysLeft) {
664 				_gm->_state._timeSleep = _gm->_state._arrivalDaysLeft;
665 			}
666 			if (_gm->_state._timeSleep >= *energyDaysLeft) {
667 				_gm->_state._timeSleep = *energyDaysLeft;
668 				if (room->isSectionVisible(9)) {
669 					room = _gm->_rooms[LANDINGMODULE]; // Monitors off
670 					room->setSectionVisible(2, false);
671 					room->setSectionVisible(7, false);
672 					room->setSectionVisible(8, false);
673 					room->setSectionVisible(9, false);
674 					room->setSectionVisible(10, false);
675 				}
676 			}
677 			if (_gm->_state._timeSleep == _gm->_state._arrivalDaysLeft) {
678 				_vm->renderImage(3);
679 				room = _gm->_rooms[COCKPIT];
680 				room->setSectionVisible(23, true);
681 				room = _gm->_rooms[CABIN_R2];
682 				room->setSectionVisible(5, false);
683 				room->setSectionVisible(6, true);
684 				room->getObject(2)->_click = 10;
685 				room = _gm->_rooms[HOLD];
686 				room->setSectionVisible(0, false);
687 				room->setSectionVisible(1, true);
688 				room->getObject(1)->_click = 255;
689 				room->getObject(3)->_click = 255;
690 				room = _gm->_rooms[GENERATOR];
691 				room->setSectionVisible(6, false);
692 				room->setSectionVisible(7, true);
693 				room->getObject(1)->_click = 14;
694 				if (room->isSectionVisible(1)) {
695 					room->setSectionVisible(10, true);
696 				}
697 				if (room->isSectionVisible(12)) {
698 					room->setSectionVisible(12, false);
699 					room->setSectionVisible(11, true);
700 				}
701 			}
702 			_gm->_state._arrivalDaysLeft -= _gm->_state._timeSleep;
703 			*energyDaysLeft -= _gm->_state._timeSleep;
704 			_gm->_time = ticksToMsec(786520); // 12pm
705 			_gm->_state._alarmOn = (_gm->_state._timeAlarm > _gm->_time);
706 			if (*energyDaysLeft == 0) {
707 				_gm->turnOff();
708 				room = _gm->_rooms[GENERATOR];
709 				room->setSectionVisible(4, room->isSectionVisible(2));
710 			}
711 			if (_gm->_state._arrivalDaysLeft == 0) {
712 				_gm->saveTime();
713 				if (!_vm->saveGame(kSleepAutosaveSlot, "Sleep autosave"))
714 					_vm->errorTempSave(true);
715 				_gm->_state._dream = true;
716 				_gm->loadTime();
717 			}
718 			_gm->wait(18);
719 			_vm->paletteFadeIn();
720 			if (_gm->_state._arrivalDaysLeft == 0) {
721 				_vm->playSound(kAudioCrash);
722 				_gm->screenShake();
723 				_gm->wait(18);
724 				_vm->renderMessage(kStringShipSleepCabin12);
725 			}
726 		}
727 	} else {
728 		return false;
729 	}
730 
731 	return true;
732 }
733 
animation()734 void ShipSleepCabin::animation() {
735 	if (_gm->_state._powerOff && _gm->_state._arrivalDaysLeft) {
736 		if (_gm->_guiEnabled) {
737 			if (isSectionVisible(1)) {
738 				_vm->renderImage(2);
739 				setSectionVisible(1, false);
740 			} else {
741 				_vm->renderImage(1);
742 				setSectionVisible(2, false);
743 			}
744 		} else {
745 			if (_color == kColorLightRed) {
746 				_color = kColorDarkBlue;
747 			} else {
748 				_color = kColorLightRed;
749 			}
750 
751 			_vm->renderText(kStringShipSleepCabin13, 60, 75, _color);
752 		}
753 	} else if (isSectionVisible(5) && _gm->_guiEnabled) {
754 		if (isSectionVisible(4))
755 			_vm->renderImage(_gm->invertSection(4));
756 		else
757 			_vm->renderImage(4);
758 	}
759 
760 	_gm->setAnimationTimer(6);
761 }
onEntrance()762 void ShipSleepCabin::onEntrance() {
763 	if (_gm->_state._dream && (_gm->_rooms[CAVE]->getObject(1)->_exitRoom == MEETUP3)) {
764 		_vm->renderMessage(kStringShipSleepCabin14);
765 		_gm->wait(_gm->_messageDuration, true);
766 		_vm->removeMessage();
767 		_vm->renderMessage(kStringShipSleepCabin15);
768 		_gm->wait(_gm->_messageDuration, true);
769 		_vm->removeMessage();
770 		_vm->renderMessage(kStringShipSleepCabin16);
771 		_gm->_state._dream = false;
772 	}
773 }
774 
ShipCockpit(SupernovaEngine * vm,GameManager1 * gm)775 ShipCockpit::ShipCockpit(SupernovaEngine *vm, GameManager1 *gm) {
776 	_vm = vm;
777 	_gm = gm;
778 
779 	_fileNumber = 9;
780 	_id = COCKPIT;
781 	_shown[0] = kShownTrue;
782 	_color = kColorBlack;
783 
784 	_objectState[0] = Object(_id, kStringInstruments, kStringInstrumentsDescription1, INSTRUMENTS, NULLTYPE, 2, 2, 0, NULLROOM, 0);
785 	_objectState[1] = Object(_id, kStringMonitor, kStringDefaultDescription, MONITOR, NULLTYPE, 0, 0, 0, NULLROOM, 0);
786 	_objectState[2] = Object(_id, kStringMonitor, kStringMonitorDescription, NULLOBJECT, TAKE, 1, 0, 0, NULLROOM, 0);
787 	_objectState[3] = Object(_id, kStringExit, kStringDefaultDescription, NULLOBJECT, EXIT, 255, 255, 0, HALL, 22);
788 }
789 
interact(Action verb,Object & obj1,Object & obj2)790 bool ShipCockpit::interact(Action verb, Object &obj1, Object &obj2) {
791 	// TODO: distance and remaining time not accurate
792 
793 	if ((verb == ACTION_LOOK) && (obj1._id == MONITOR)) {
794 		char c[2] = {0, 0};
795 		_gm->_guiEnabled = false;
796 		_vm->renderBox(0, 0, 320, 200, kColorBlack);
797 		_vm->renderText(kStringShipCockpit1, 50, 50, kColorLightYellow);
798 		if (_gm->_state._arrivalDaysLeft)
799 			_vm->renderText(kStringShipCockpit2);
800 		else
801 			_vm->renderText(kStringShipCockpit3);
802 		_vm->renderText(kStringShipCockpit4, 50, 70, kColorLightYellow);
803 		_vm->renderText(kStringShipCockpit5, 50, 90, kColorLightYellow);
804 		_vm->renderText(Common::String::format("%d", _gm->_state._arrivalDaysLeft / 400).c_str());
805 		_vm->renderText(",");
806 		c[0] = (_gm->_state._arrivalDaysLeft / 40) % 10 + '0';
807 		_vm->renderText(c);
808 		c[0] = (_gm->_state._arrivalDaysLeft / 4) % 10 + '0';
809 		_vm->renderText(c);
810 		_vm->renderText(kStringShipCockpit6);
811 		_vm->renderText(kStringShipCockpit7, 50, 110, kColorLightYellow);
812 		_vm->renderText(Common::String::format("%d", _gm->_state._arrivalDaysLeft).c_str(),
813 						50, 120, kColorLightYellow);
814 		_vm->renderText(kStringShipCockpit8);
815 
816 		_gm->getInput();
817 		_gm->_guiEnabled = true;
818 	} else if ((verb == ACTION_USE) && (obj1._id == INSTRUMENTS))
819 		_vm->renderMessage(kStringShipCockpit9);
820 	else
821 		return false;
822 
823 	return true;
824 }
animation()825 void ShipCockpit::animation() {
826 	if (!_gm->_guiEnabled) {
827 		if (_color) {
828 			_color = kColorBlack;
829 			_gm->setAnimationTimer(5);
830 		} else {
831 			_color = kColorLightYellow;
832 			_gm->setAnimationTimer(10);
833 		}
834 		_vm->renderText(kStringShipCockpit10, 50, 145, _color);
835 	} else if (isSectionVisible(21)) {
836 		_vm->renderImage(_gm->invertSection(21));
837 		_gm->setAnimationTimer(5);
838 	} else {
839 		_vm->renderImage(21);
840 		_gm->setAnimationTimer(10);
841 	}
842 
843 	if (_gm->_state._powerOff) {
844 		if (!_gm->_guiEnabled) {
845 			_vm->renderText(kStringShipCockpit11, 97, 165, _color);
846 			_vm->renderText(kStringShipCockpit12, 97, 175, _color);
847 		} else if (isSectionVisible(21))
848 			_vm->renderImage(22);
849 		else
850 			_vm->renderImage(_gm->invertSection(22));
851 	}
852 }
853 
onEntrance()854 void ShipCockpit::onEntrance() {
855 	if (!hasSeen())
856 		_vm->renderMessage(kStringShipCockpit13);
857 	setRoomSeen(true);
858 }
859 
ShipCabinL1(SupernovaEngine * vm,GameManager1 * gm)860 ShipCabinL1::ShipCabinL1(SupernovaEngine *vm, GameManager1 *gm) {
861 	_vm = vm;
862 	_gm = gm;
863 
864 	_fileNumber = 21;
865 	_id = CABIN_L1;
866 	_shown[0] = kShownTrue;
867 	_shown[1] = kShownTrue;
868 	_shown[2] = kShownTrue;
869 	_shown[3] = kShownTrue;
870 	_shown[4] = kShownTrue;
871 	_shown[5] = kShownTrue;
872 
873 	_objectState[0] = Object(_id, kStringImage, kStringGenericDescription1, NULLOBJECT, UNNECESSARY, 5, 5, 0, NULLROOM, 0);
874 	_objectState[1] = Object(_id, kStringImage, kStringGenericDescription2, NULLOBJECT, UNNECESSARY, 6, 6, 0, NULLROOM, 0);
875 	_objectState[2] = Object(_id, kStringImage, kStringGenericDescription3, NULLOBJECT, UNNECESSARY, 7, 7, 0, NULLROOM, 0);
876 	_objectState[3] = Object(_id, kStringMagnete, kStringMagneteDescription, NULLOBJECT, UNNECESSARY, 8, 8, 0, NULLROOM, 0);
877 	_objectState[4] = Object(_id, kStringImage, kStringGenericDescription4, NULLOBJECT, UNNECESSARY, 9, 9, 0);
878 	_objectState[5] = Object(_id, kStringPen, kStringPenDescription, PEN, TAKE | COMBINABLE, 10, 10, 5 | kSectionInvert);
879 	_objectState[6] = Object(_id, kStringHatch, kStringDefaultDescription, NULLOBJECT, OPENABLE | OPENED | EXIT, 3, 3, 24 | kSectionInvert, CORRIDOR_ROOM, 9);
880 	_objectState[7] = Object(_id, kStringSlot, kStringSlotDescription, NULLOBJECT, COMBINABLE, 0, 0, 0);
881 	_objectState[8] = Object(_id, kStringShelf, kStringDefaultDescription, NULLOBJECT, OPENABLE | CLOSED, 1, 1, 0);
882 	_objectState[9] = Object(_id, kStringCompartment, kStringDefaultDescription, NULLOBJECT, OPENABLE | CLOSED, 2, 2, 0);
883 	_objectState[10] = Object(_id, kStringSocket, kStringDefaultDescription, SOCKET, COMBINABLE, 4, 4, 0);
884 	_objectState[11] = Object(_id, kStringToilet, kStringDefaultDescription, BATHROOM_DOOR, EXIT, 255, 255, 0, BATHROOM, 22);
885 }
886 
ShipCabinL2(SupernovaEngine * vm,GameManager1 * gm)887 ShipCabinL2::ShipCabinL2(SupernovaEngine *vm, GameManager1 *gm) {
888 	_vm = vm;
889 	_gm = gm;
890 
891 	_fileNumber = 21;
892 	_id = CABIN_L2;
893 	_shown[0] = kShownTrue;
894 	_shown[16] = kShownTrue;
895 
896 	_objectState[0] = Object(_id, kStringSlot,kStringSlotDescription,SLOT_KL1,COMBINABLE,31,31,0);
897 	_objectState[1] = Object(_id, kStringSlot,kStringSlotDescription,SLOT_KL2,COMBINABLE,32,32,0);
898 	_objectState[2] = Object(_id, kStringSlot,kStringSlotDescription,SLOT_KL3,COMBINABLE,33,33,0);
899 	_objectState[3] = Object(_id, kStringSlot,kStringSlotDescription,SLOT_KL4,COMBINABLE,45,45,0);
900 	_objectState[4] = Object(_id, kStringShelf,kStringDefaultDescription,SHELF_L1,OPENABLE | CLOSED,25,26,17);
901 	_objectState[5] = Object(_id, kStringPistol,kStringPistolDescription,PISTOL,TAKE,39,39,20);
902 	_objectState[6] = Object(_id, kStringCompartment,kStringDefaultDescription,SHELF_L2,OPENABLE | CLOSED,27,28,18);
903 	_objectState[7] = Object(_id, kStringBooks,kStringBooksDescription,NULLOBJECT,UNNECESSARY,40,40,0);
904 	_objectState[8] = Object(_id, kStringCompartment,kStringDefaultDescription,SHELF_L3,OPENABLE | CLOSED,29,30,19);
905 	_objectState[9] = Object(_id, kStringSpool,kStringSpoolDescription, SPOOL,TAKE | COMBINABLE,41,41,21);
906 	_objectState[10] = Object(_id, kStringCompartment,kStringDefaultDescription,SHELF_L4,OPENABLE | CLOSED,43,44,22);
907 	_objectState[11] = Object(_id, kStringBook,kStringDefaultDescription,BOOK2,TAKE,46,46,23);
908 	_objectState[12] = Object(_id, kStringUnderwear,kStringUnderwearDescription,NULLOBJECT,UNNECESSARY,34,34,0);
909 	_objectState[13] = Object(_id, kStringUnderwear,kStringUnderwearDescription,NULLOBJECT,UNNECESSARY,35,35,0);
910 	_objectState[14] = Object(_id, kStringClothes,kStringDefaultDescription,NULLOBJECT,UNNECESSARY,36,36,0);
911 	_objectState[15] = Object(_id, kStringJunk,kStringJunkDescription,NULLOBJECT,UNNECESSARY,37,37,0);
912 	_objectState[16] = Object(_id, kStringJunk,kStringJunkDescription,NULLOBJECT,UNNECESSARY,38,38,0);
913 	_objectState[17] = Object(_id, kStringMagnete,kStringMagneteDescription,NULLOBJECT,UNNECESSARY,23,23,0);
914 	_objectState[18] = Object(_id, kStringToilet,kStringDefaultDescription,BATHROOM_DOOR,EXIT,255,255,0,BATHROOM,22);
915 	_objectState[19] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | OPENED | EXIT,3,3,24 | kSectionInvert,CORRIDOR_ROOM,9);
916 	_objectState[20] = Object(_id, kStringSlot,kStringSlotDescription,NULLOBJECT,COMBINABLE,0,0,0);
917 	_objectState[21] = Object(_id, kStringShelf,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,1,1,0);
918 	_objectState[22] = Object(_id, kStringCompartment,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,2,2,0);
919 	_objectState[23] = Object(_id, kStringSocket,kStringDefaultDescription,SOCKET,COMBINABLE,4,4,0);
920 	_objectState[24] = Object(_id, kStringFolders,kStringFoldersDescription,NULLOBJECT,UNNECESSARY,49,49,0);
921 }
922 
interact(Action verb,Object & obj1,Object & obj2)923 bool ShipCabinL2::interact(Action verb, Object &obj1, Object &obj2) {
924 	if ((verb == ACTION_USE) && Object::combine(obj1, obj2, SLOT_KL1, KEYCARD2)) {
925 		_gm->openLocker(this, getObject(4), getObject(0), 17);
926 		if (getObject(5)->_click == 255)
927 			_vm->renderImage(20); // Remove Pistol
928 		_gm->great(2);
929 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, SLOT_KL2, KEYCARD2)) {
930 		_gm->openLocker(this, getObject(6), getObject(1), 18);
931 		_gm->great(2);
932 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, SLOT_KL3, KEYCARD2)) {
933 		_gm->openLocker(this, getObject(8), getObject(2), 19);
934 		if (getObject(9)->_click == 255)
935 			_vm->renderImage(21); // Remove cable spool
936 		_gm->great(2);
937 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, SLOT_KL4, KEYCARD2)) {
938 		_gm->openLocker(this, getObject(10), getObject(3), 22);
939 		if (getObject(11)->_click == 255)
940 			_vm->renderImage(23); // Remove book
941 		_gm->great(2);
942 	} else if ((verb == ACTION_CLOSE) && (obj1._id == SHELF_L1)) {
943 		_gm->closeLocker(this, getObject(4), getObject(0), 17);
944 		setSectionVisible(20, false);
945 	} else if ((verb == ACTION_CLOSE) && (obj1._id == SHELF_L2))
946 		_gm->closeLocker(this, getObject(6), getObject(1), 18);
947 	else if ((verb == ACTION_CLOSE) && (obj1._id == SHELF_L3)) {
948 		_gm->closeLocker(this, getObject(8), getObject(2), 19);
949 		setSectionVisible(21, false);
950 	} else if ((verb == ACTION_CLOSE) && (obj1._id == SHELF_L4)) {
951 		_gm->closeLocker(this, getObject(10), getObject(3), 22);
952 		setSectionVisible(23, false);
953 	} else if ((verb == ACTION_TAKE) && (obj1._id == SPOOL) && !obj1.hasProperty(CARRIED)) {
954 		getObject(8)->_click = 42;  // empty shelf
955 		return false;
956 	} else if ((verb == ACTION_TAKE) && (obj1._id == BOOK2) && !obj1.hasProperty(CARRIED)) {
957 		getObject(10)->_click = 47;  // empty shelf
958 		return false;
959 	} else
960 		return false;
961 
962 	return true;
963 }
964 
ShipCabinL3(SupernovaEngine * vm,GameManager1 * gm)965 ShipCabinL3::ShipCabinL3(SupernovaEngine *vm, GameManager1 *gm) {
966 	_vm = vm;
967 	_gm = gm;
968 
969 	_fileNumber = 21;
970 	_id = CABIN_L3;
971 	_shown[0] = kShownTrue;
972 	_shown[6] = kShownTrue;
973 	_shown[7] = kShownTrue;
974 	_shown[8] = kShownTrue;
975 	_shown[9] = kShownTrue;
976 	_shown[12] = kShownTrue;
977 
978 	_objectState[0] = Object(_id, kStringPoster,kStringPosterDescription1,NULLOBJECT,UNNECESSARY,11,11,0);
979 	_objectState[1] = Object(_id, kStringPoster,kStringPosterDescription2,NULLOBJECT,UNNECESSARY,12,12,0);
980 	_objectState[2] = Object(_id, kStringSpeaker,kStringDefaultDescription,NULLOBJECT,NULLTYPE,13,13,0);
981 	_objectState[3] = Object(_id, kStringMagnete,kStringMagneteDescription,NULLOBJECT,UNNECESSARY,14,14,0);
982 	_objectState[4] = Object(_id, kStringRecord,kStringRecordDescription,RECORD,TAKE | COMBINABLE,15,15,8 | kSectionInvert);
983 	_objectState[5] = Object(_id, kStringRecordStand,kStringRecordStandDescription,NULLOBJECT,UNNECESSARY,16,16,0);
984 	_objectState[6] = Object(_id, kStringButton,kStringDefaultDescription,TURNTABLE_BUTTON,PRESS,22,22,0);
985 	_objectState[7] = Object(_id, kStringTurntable,kStringTurntableDescription,TURNTABLE,UNNECESSARY | COMBINABLE,17,17,0);
986 	_objectState[8] = Object(_id, kStringWire,kStringDefaultDescription,WIRE,COMBINABLE,18,18,0);
987 	_objectState[9] = Object(_id, kStringWire,kStringDefaultDescription,WIRE2,COMBINABLE,19,19,0);
988 	_objectState[10] = Object(_id, kStringPlug,kStringDefaultDescription,PLUG,COMBINABLE,20,20,0);
989 	_objectState[11] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | OPENED | EXIT,3,3,24 | kSectionInvert,CORRIDOR_ROOM,9);
990 	_objectState[12] = Object(_id, kStringSlot,kStringSlotDescription,NULLOBJECT,COMBINABLE,0,0,0);
991 	_objectState[13] = Object(_id, kStringShelf,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,1,1,0);
992 	_objectState[14] = Object(_id, kStringCompartment,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,2,2,0);
993 	_objectState[15] = Object(_id, kStringSocket,kStringDefaultDescription,SOCKET,COMBINABLE,4,4,0);
994 	_objectState[16] = Object(_id, kStringToilet,kStringDefaultDescription,BATHROOM_DOOR,EXIT,255,255,0,BATHROOM,22);
995 }
996 
interact(Action verb,Object & obj1,Object & obj2)997 bool ShipCabinL3::interact(Action verb, Object &obj1, Object &obj2) {
998 	Room *r;
999 
1000 	if ((verb == ACTION_USE) && Object::combine(obj1, obj2, RECORD, TURNTABLE)) {
1001 		if (!_gm->_guiEnabled || isSectionVisible(15))
1002 			_vm->renderMessage(kStringShipCabinL3_1);
1003 		else {
1004 			if (!getObject(4)->hasProperty(CARRIED))
1005 				_vm->renderImage(_gm->invertSection(8));
1006 			else
1007 				_gm->_inventory.remove(*getObject(4));
1008 			_vm->renderImage(15);
1009 			getObject(4)->_click = 48;
1010 		}
1011 	} else if ((verb == ACTION_PRESS) && (obj1._id == TURNTABLE_BUTTON)) {
1012 		if (!isSectionVisible(15)) {
1013 			_vm->renderMessage(kStringShipCabinL3_2);
1014 		} else if (!isSectionVisible(10) && !isSectionVisible(11) && isSectionVisible(12)) {
1015 			_vm->renderImage(14);
1016 			setSectionVisible(15, false);
1017 			for (int i = 3; i; i--) {
1018 				_vm->playSound(kAudioTurntable);
1019 				while (_vm->_sound->isPlaying()) {
1020 					if (isSectionVisible(13)) {
1021 						_vm->renderImage(14);
1022 						setSectionVisible(13, false);
1023 					} else {
1024 						_vm->renderImage(13);
1025 						setSectionVisible(14, false);
1026 					}
1027 					_gm->wait(3);
1028 				}
1029 			}
1030 
1031 			_vm->renderImage(15);
1032 			setSectionVisible(14, false);
1033 			setSectionVisible(13, false);
1034 			_vm->renderMessage(kStringShipCabinL3_3);
1035 		}
1036 	} else if ((verb == ACTION_TAKE) && (obj1._id == RECORD) && (obj1._click != 15)) {
1037 		_vm->renderImage(9);
1038 		setSectionVisible(13, false);
1039 		setSectionVisible(14, false);
1040 		setSectionVisible(15, false);
1041 		obj1._section = 0;
1042 		_gm->takeObject(obj1);
1043 	} else if ((verb == ACTION_PULL) && (obj1._id == PLUG)) {
1044 		_vm->renderImage(10);
1045 		setSectionVisible(7, false);
1046 		obj1._click = 21;
1047 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, PLUG, SOCKET)) {
1048 		_vm->renderImage(7);
1049 		setSectionVisible(10, false);
1050 		getObject(10)->_click = 20;
1051 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, KNIFE, WIRE2))
1052 		_vm->renderMessage(kStringShipCabinL3_4); // cutting near plug
1053 	else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, KNIFE, WIRE)) {
1054 		r = _gm->_rooms[AIRLOCK];
1055 		if (!isSectionVisible(10) && !r->getObject(5)->hasProperty(WORN)) {
1056 			_vm->renderImage(25);
1057 			_gm->shock();
1058 		}
1059 		_vm->renderImage(11);
1060 		_vm->renderImage(26);
1061 		setSectionVisible(12, false);
1062 	} else if ((verb == ACTION_TAKE) && ((obj1._id == WIRE) || (obj1._id == WIRE2) || (obj1._id == PLUG))) {
1063 		if (isSectionVisible(10) && isSectionVisible(11)) {
1064 			_vm->renderImage(_gm->invertSection(10));
1065 			_vm->renderImage(_gm->invertSection(11));
1066 			getObject(8)->_name = kStringWireAndPlug;
1067 			_gm->takeObject(*getObject(8));
1068 			getObject(9)->_click = 255;
1069 			getObject(10)->_click = 255;
1070 		} else
1071 			_vm->renderMessage(kStringShipCabinL3_5);
1072 	} else
1073 		return false;
1074 
1075 	return true;
1076 }
1077 
ShipCabinR1(SupernovaEngine * vm,GameManager1 * gm)1078 ShipCabinR1::ShipCabinR1(SupernovaEngine *vm, GameManager1 *gm) {
1079 	_vm = vm;
1080 	_gm = gm;
1081 
1082 	_fileNumber = 22;
1083 	_id = CABIN_R1;
1084 	_shown[0] = kShownTrue;
1085 	_shown[1] = kShownTrue;
1086 	_shown[2] = kShownTrue;
1087 
1088 	_objectState[0] = Object(_id, kStringImage,kStringImageDescription1,NULLOBJECT,UNNECESSARY,5,5,0);
1089 	_objectState[1] = Object(_id, kStringDrawingInstruments,kStringDrawingInstrumentsDescription,NULLOBJECT,UNNECESSARY,6,6,0);
1090 	_objectState[2] = Object(_id, kStringMagnete,kStringMagneteDescription,NULLOBJECT,UNNECESSARY,7,7,0);
1091 	_objectState[3] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | OPENED | EXIT,3,3,15 | kSectionInvert,CORRIDOR_ROOM,5);
1092 	_objectState[4] = Object(_id, kStringSlot,kStringSlotDescription,NULLOBJECT,COMBINABLE,0,0,0);
1093 	_objectState[5] = Object(_id, kStringShelf,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,1,1,0);
1094 	_objectState[6] = Object(_id, kStringCompartment,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,2,2,0);
1095 	_objectState[7] = Object(_id, kStringSocket,kStringDefaultDescription,SOCKET,COMBINABLE,4,4,0);
1096 	_objectState[8] = Object(_id, kStringToilet,kStringDefaultDescription,BATHROOM_DOOR,EXIT,255,255,0,BATHROOM,22);
1097 }
1098 
ShipCabinR2(SupernovaEngine * vm,GameManager1 * gm)1099 ShipCabinR2::ShipCabinR2(SupernovaEngine *vm, GameManager1 *gm) {
1100 	_vm = vm;
1101 	_gm = gm;
1102 
1103 	_fileNumber = 22;
1104 	_id = CABIN_R2;
1105 	_shown[0] = kShownTrue;
1106 	_shown[3] = kShownTrue;
1107 	_shown[4] = kShownTrue;
1108 	_shown[5] = kShownTrue;
1109 
1110 	_objectState[0] = Object(_id, kStringChessGame,kStringChessGameDescription1,NULLOBJECT,UNNECESSARY,11,11,0);
1111 	_objectState[1] = Object(_id, kStringTennisRacket,kStringTennisRacketDescription,NULLOBJECT,UNNECESSARY,8,8,0);
1112 	_objectState[2] = Object(_id, kStringTennisBall,kStringGenericDescription2,NULLOBJECT,UNNECESSARY,9,9,0);
1113 	_objectState[3] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | OPENED | EXIT,3,3,15 | kSectionInvert,CORRIDOR_ROOM,5);
1114 	_objectState[4] = Object(_id, kStringSlot,kStringSlotDescription,NULLOBJECT,COMBINABLE,0,0,0);
1115 	_objectState[5] = Object(_id, kStringShelf,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,1,1,0);
1116 	_objectState[6] = Object(_id, kStringCompartment,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,2,2,0);
1117 	_objectState[7] = Object(_id, kStringSocket,kStringDefaultDescription,SOCKET,COMBINABLE,4,4,0);
1118 	_objectState[8] = Object(_id, kStringToilet,kStringDefaultDescription,BATHROOM_DOOR,EXIT,255,255,0,BATHROOM,22);
1119 }
1120 
ShipCabinR3(SupernovaEngine * vm,GameManager1 * gm)1121 ShipCabinR3::ShipCabinR3(SupernovaEngine *vm, GameManager1 *gm) {
1122 	_vm = vm;
1123 	_gm = gm;
1124 
1125 	_fileNumber = 22;
1126 	_id = CABIN_R3;
1127 	_shown[0] = kShownTrue;
1128 	_shown[7] = kShownTrue;
1129 	_shown[8] = kShownTrue;
1130 	_shown[15] = kShownTrue;
1131 
1132 	_objectState[0] = Object(_id, kStringChessGame,kStringChessGameDescription2,CHESS,TAKE | COMBINABLE,12,12,7 | kSectionInvert);
1133 	_objectState[1] = Object(_id, kStringBed,kStringBedDescription,NULLOBJECT,NULLTYPE,13,13,0);
1134 	_objectState[2] = Object(_id, kStringSlot,kStringSlotDescription,SLOT_K1,COMBINABLE,27,27,0);
1135 	_objectState[3] = Object(_id, kStringSlot,kStringSlotDescription,SLOT_K2,COMBINABLE,28,28,0);
1136 	_objectState[4] = Object(_id, kStringSlot,kStringSlotDescription,SLOT_K3,COMBINABLE,29,29,0);
1137 	_objectState[5] = Object(_id, kStringSlot,kStringSlotDescription,SLOT_K4,COMBINABLE,30,30,0);
1138 	_objectState[6] = Object(_id, kStringCompartment,kStringCompartmentDescription,SHELF1,OPENABLE | CLOSED,14,18,9);
1139 	_objectState[7] = Object(_id, kStringAlbums,kStringAlbumsDescription,NULLOBJECT,UNNECESSARY,14,14,0);
1140 	_objectState[8] = Object(_id, kStringCompartment,kStringCompartmentDescription,SHELF2,OPENABLE | CLOSED,15,19,10);
1141 	_objectState[9] = Object(_id, kStringRope,kStringRopeDescription,ROPE,TAKE | COMBINABLE,15,15,12);
1142 	_objectState[10] = Object(_id, kStringShelf,kStringShelfDescription,SHELF3,OPENABLE | CLOSED,16,17,11);
1143 	_objectState[11] = Object(_id, kStringJunk,kStringJunkDescription,NULLOBJECT,UNNECESSARY,20,20,0);
1144 	_objectState[12] = Object(_id, kStringClothes,kStringClothesDescription,NULLOBJECT,UNNECESSARY,21,21,0);
1145 	_objectState[13] = Object(_id, kStringUnderwear,kStringDefaultDescription,NULLOBJECT,UNNECESSARY,22,22,0);
1146 	_objectState[14] = Object(_id, kStringSocks,kStringDefaultDescription,NULLOBJECT,UNNECESSARY,23,23,0);
1147 	_objectState[15] = Object(_id, kStringCompartment,kStringCompartmentDescription,SHELF4,OPENABLE | CLOSED,24,25,13);
1148 	_objectState[16] = Object(_id, kStringBook,kStringBookHitchhiker,BOOK,TAKE,26,26,14);
1149 	_objectState[17] = Object(_id, kStringDiscman,kStringDiscmanDescription,DISCMAN,TAKE | COMBINABLE,33,33,16);
1150 	_objectState[18] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | EXIT,3,3,15 | kSectionInvert,CORRIDOR_ROOM,5);
1151 	_objectState[19] = Object(_id, kStringSlot,kStringSlotDescription,NULLOBJECT,COMBINABLE,0,0,0);
1152 	_objectState[20] = Object(_id, kStringShelf,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,1,1,0);
1153 	_objectState[21] = Object(_id, kStringCompartment,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,2,2,0);
1154 	_objectState[22] = Object(_id, kStringSocket,kStringDefaultDescription,SOCKET,COMBINABLE,4,4,0);
1155 	_objectState[23] = Object(_id, kStringToilet,kStringDefaultDescription,BATHROOM_DOOR,EXIT,255,255,0,BATHROOM,22);
1156 }
1157 
interact(Action verb,Object & obj1,Object & obj2)1158 bool ShipCabinR3::interact(Action verb, Object &obj1, Object &obj2) {
1159 	if ((verb == ACTION_USE) && Object::combine(obj1, obj2, SLOT_K1, KEYCARD))
1160 		_gm->openLocker(this, getObject(6), getObject(2), 9);
1161 	else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, SLOT_K2, KEYCARD)) {
1162 		_gm->openLocker(this, getObject(8), getObject(3), 10);
1163 		if (getObject(9)->_click == 255)
1164 			_vm->renderImage(12); // Remove rope
1165 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, SLOT_K3, KEYCARD)) {
1166 		_gm->openLocker(this, getObject(10), getObject(4), 11);
1167 		if (getObject(17)->_click == 255)
1168 			_vm->renderImage(16); // Remove Discman
1169 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, SLOT_K4, KEYCARD)) {
1170 		_gm->openLocker(this, getObject(15), getObject(5), 13);
1171 		if (getObject(16)->_click == 255)
1172 			_vm->renderImage(14); // Remove Book
1173 	} else if ((verb == ACTION_CLOSE) && (obj1._id == SHELF1))
1174 		_gm->closeLocker(this, getObject(6), getObject(2), 9);
1175 	else if ((verb == ACTION_CLOSE) && (obj1._id == SHELF2)) {
1176 		setSectionVisible(12, false);
1177 		_gm->closeLocker(this, getObject(8), getObject(3), 10);
1178 	} else if ((verb == ACTION_CLOSE) && (obj1._id == SHELF3)) {
1179 		setSectionVisible(16, false);
1180 		_gm->closeLocker(this, getObject(10), getObject(4), 11);
1181 	} else if ((verb == ACTION_CLOSE) && (obj1._id == SHELF4)) {
1182 		setSectionVisible(14, false);
1183 		setSectionVisible(14, false);
1184 		_gm->closeLocker(this, getObject(15), getObject(5), 13);
1185 	} else if ((verb == ACTION_TAKE) && (obj1._id == DISCMAN) && !_gm->_rooms[0]->getObject(3)->hasProperty(CARRIED)) {
1186 		getObject(10)->_click = 34; // Locker empty
1187 		obj1._click = 255;
1188 		_gm->takeObject(*_gm->_rooms[0]->getObject(3));
1189 		_vm->renderImage(16);
1190 	} else if ((verb == ACTION_TAKE) && (obj1._id == ROPE) && obj1.hasProperty(CARRIED)) {
1191 		getObject(8)->_click = 31; // Shelf empty
1192 		return false;
1193 	} else if ((verb == ACTION_TAKE) && (obj1._id == BOOK) && !obj1.hasProperty(CARRIED)) {
1194 		getObject(15)->_click = 32; // Shelf empty
1195 		return false;
1196 	} else
1197 		return false;
1198 
1199 	return true;
1200 }
1201 
onEntrance()1202 void ShipCabinR3::onEntrance() {
1203 	for (int i = 0; i < 3; ++i)
1204 		_gm->_inventory.add(*_gm->_rooms[INTRO1]->getObject(i));
1205 
1206 	setRoomSeen(true);
1207 }
1208 
ShipCabinBathroom(SupernovaEngine * vm,GameManager1 * gm)1209 ShipCabinBathroom::ShipCabinBathroom(SupernovaEngine *vm, GameManager1 *gm) {
1210 	_vm = vm;
1211 	_gm = gm;
1212 
1213 	_fileNumber = 23;
1214 	_id = BATHROOM;
1215 	_shown[0] = kShownTrue;
1216 
1217 	_objectState[0] = Object(_id, kStringBathroom,kStringBathroomDescription,TOILET,NULLTYPE,0,0,0);
1218 	_objectState[1] = Object(_id, kStringShower,kStringDefaultDescription,SHOWER,NULLTYPE,1,1,0);
1219 	_objectState[2] = Object(_id, kStringExit,kStringDefaultDescription,BATHROOM_EXIT,EXIT,255,255,0,CABIN_R3,2);
1220 }
1221 
ShipAirlock(SupernovaEngine * vm,GameManager1 * gm)1222 ShipAirlock::ShipAirlock(SupernovaEngine *vm, GameManager1 *gm) {
1223 	_vm = vm;
1224 	_gm = gm;
1225 
1226 	_fileNumber = 34;
1227 	_id = AIRLOCK;
1228 	_shown[0] = kShownTrue;
1229 	_shown[6] = kShownTrue;
1230 
1231 	_objectState[0] = Object(_id, kStringHatch,kStringHatchDescription1,NULLOBJECT,EXIT | OPENABLE | OPENED | CLOSED,0,0,0,CORRIDOR_ROOM,10);
1232 	_objectState[1] = Object(_id, kStringHatch,kStringHatchDescription2,NULLOBJECT,EXIT | OPENABLE | CLOSED,1,1,0,HOLD,14);
1233 	_objectState[2] = Object(_id, kStringButton,kStringDefaultDescription,BUTTON1,PRESS,2,2,0);
1234 	_objectState[3] = Object(_id, kStringButton,kStringDefaultDescription,BUTTON2,PRESS,3,3,0);
1235 	_objectState[4] = Object(_id, kStringHelmet,kStringHelmetDescription,HELMET,TAKE,4,4,7);
1236 	_objectState[5] = Object(_id, kStringSuit,kStringSuitDescription,SUIT,TAKE,5,5,8);
1237 	_objectState[6] = Object(_id, kStringLifeSupport,kStringLifeSupportDescription,LIFESUPPORT,TAKE,6,6,9);
1238 }
1239 
interact(Action verb,Object & obj1,Object & obj2)1240 bool ShipAirlock::interact(Action verb, Object &obj1, Object &obj2) {
1241 	Room *r;
1242 
1243 	if ((verb == ACTION_PRESS) && (obj1._id == BUTTON1)) {
1244 		if (!getObject(1)->hasProperty(OPENED)) {
1245 			_vm->renderImage(10);
1246 			_vm->playSound(kAudioSlideDoor);
1247 			if (getObject(0)->hasProperty(OPENED)) {
1248 				getObject(0)->disableProperty(OPENED);
1249 				_vm->renderImage(1);
1250 				_gm->wait(2);
1251 				_vm->renderImage(2);
1252 				setSectionVisible(1, false);
1253 				_gm->wait(2);
1254 				_vm->renderImage(3);
1255 				setSectionVisible(2, false);
1256 			} else {
1257 				getObject(0)->setProperty(OPENED);
1258 				_vm->renderImage(2);
1259 				setSectionVisible(3, false);
1260 				_gm->wait(2);
1261 				_vm->renderImage(1);
1262 				setSectionVisible(2, false);
1263 				_gm->wait(2);
1264 				_vm->renderImage(_gm->invertSection(1));
1265 			}
1266 			_vm->renderImage(_gm->invertSection(10));
1267 		}
1268 	} else if ((verb == ACTION_PRESS) && (obj1._id == BUTTON2)) {
1269 		if (!getObject(0)->hasProperty(OPENED)) {
1270 			_vm->renderImage(11);
1271 			if (getObject(1)->hasProperty(OPENED)) {
1272 				_vm->playSound(kAudioSlideDoor);
1273 				getObject(1)->disableProperty(OPENED);
1274 				_vm->renderImage(4);
1275 				_gm->wait(2);
1276 				_vm->renderImage(5);
1277 				setSectionVisible(4, false);
1278 				_gm->wait(2);
1279 				_vm->renderImage(6);
1280 				setSectionVisible(5, false);
1281 				_vm->renderImage(16);
1282 				setSectionVisible(17, false);
1283 				_gm->wait(3);
1284 				_vm->renderImage(15);
1285 				setSectionVisible(16, false);
1286 				_gm->wait(3);
1287 				_vm->renderImage(14);
1288 				setSectionVisible(15, false);
1289 				_gm->wait(3);
1290 				_vm->renderImage(13);
1291 				setSectionVisible(14, false);
1292 				_gm->wait(3);
1293 				_vm->renderImage(12);
1294 				setSectionVisible(13, false);
1295 				_gm->wait(3);
1296 				_vm->renderImage(_gm->invertSection(12));
1297 			} else {
1298 				getObject(1)->setProperty(OPENED);
1299 				_vm->renderImage(12);
1300 				_gm->wait(3);
1301 				_vm->renderImage(13);
1302 				setSectionVisible(12, false);
1303 				_gm->wait(3);
1304 				_vm->renderImage(14);
1305 				setSectionVisible(13, false);
1306 				_gm->wait(3);
1307 				_vm->renderImage(15);
1308 				setSectionVisible(14, false);
1309 				_gm->wait(3);
1310 				_vm->renderImage(16);
1311 				setSectionVisible(15, false);
1312 				_gm->wait(3);
1313 				_vm->renderImage(17);
1314 				setSectionVisible(16, false);
1315 				_vm->playSound(kAudioSlideDoor);
1316 				_vm->renderImage(5);
1317 				setSectionVisible(6, false);
1318 				_gm->wait(2);
1319 				_vm->renderImage(4);
1320 				setSectionVisible(5, false);
1321 				_gm->wait(2);
1322 				_vm->renderImage(_gm->invertSection(4));
1323 				r = _gm->_rooms[AIRLOCK];
1324 				if (!r->getObject(4)->hasProperty(WORN) ||
1325 					!r->getObject(5)->hasProperty(WORN) ||
1326 					!r->getObject(6)->hasProperty(WORN)) {
1327 					_gm->dead(kStringShipAirlock1);
1328 					return true;
1329 				}
1330 			}
1331 			_vm->renderImage(_gm->invertSection(11));
1332 		}
1333 	} else if ((verb == ACTION_LOOK) && (obj1._id == MANOMETER))
1334 		_vm->renderMessage(getObject(1)->hasProperty(OPENED) ? kStringShipAirlock2 : kStringShipAirlock3);
1335 	else
1336 		return false;
1337 
1338 	return true;
1339 }
1340 
onEntrance()1341 void ShipAirlock::onEntrance() {
1342 	if (!isSectionVisible(kMaxSection - 1)) {
1343 		_vm->renderMessage(kStringShipAirlock4);
1344 		setSectionVisible(kMaxSection -1, kShownTrue);
1345 	}
1346 	if (_vm->_improved && isSectionVisible(kMaxSection - 2)) {
1347 		if (_objectState[0].hasProperty(OPENED)) {
1348 			_objectState[4].setProperty(WORN);
1349 			_objectState[5].setProperty(WORN);
1350 			_objectState[6].setProperty(WORN);
1351 			interact(ACTION_PRESS, _objectState[2], _gm->_nullObject);
1352 			interact(ACTION_PRESS, _objectState[3], _gm->_nullObject);
1353 		} else {
1354 			_objectState[4].disableProperty(WORN);
1355 			_objectState[5].disableProperty(WORN);
1356 			_objectState[6].disableProperty(WORN);
1357 			interact(ACTION_PRESS, _objectState[3], _gm->_nullObject);
1358 			interact(ACTION_PRESS, _objectState[2], _gm->_nullObject);
1359 		}
1360 	}
1361 
1362 }
1363 
ShipHold(SupernovaEngine * vm,GameManager1 * gm)1364 ShipHold::ShipHold(SupernovaEngine *vm, GameManager1 *gm) {
1365 	_vm = vm;
1366 	_gm = gm;
1367 
1368 	_fileNumber = 24;
1369 	_id = HOLD;
1370 	_shown[0] = kShownTrue;
1371 
1372 	_objectState[0] = Object(_id, kNoString,kStringDefaultDescription,HOLD_WIRE,COMBINABLE,255,255,0);
1373 	_objectState[1] = Object(_id, kStringScrap,kStringScrapDescription1,SCRAP_LK,NULLTYPE,4,4,0);
1374 	_objectState[2] = Object(_id, kStringTerminalStrip,kStringDefaultDescription,TERMINALSTRIP,COMBINABLE,255,255,0);
1375 	_objectState[3] = Object(_id, kStringScrap,kStringScrapDescription2,NULLOBJECT,NULLTYPE,5,5,0);
1376 	_objectState[4] = Object(_id, kStringReactor,kStringReactorDescription,NULLOBJECT,NULLTYPE,6,6,0);
1377 	_objectState[5] = Object(_id, kStringNozzle,kStringDefaultDescription,NULLOBJECT,NULLTYPE,7,7,0);
1378 	_objectState[6] = Object(_id, kStringPumpkin,kStringPumpkinDescription,NULLOBJECT,NULLTYPE,8,8,0);
1379 	_objectState[7] = Object(_id, kStringHatch,kStringDefaultDescription,LANDINGMOD_OUTERHATCH,EXIT | OPENABLE,1,2,2,LANDINGMODULE,6);
1380 	_objectState[8] = Object(_id, kStringLandingModule,kStringLandingModuleDescription,NULLOBJECT,NULLTYPE,0,0,0);
1381 	_objectState[9] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,255,255,0,AIRLOCK,22);
1382 	_objectState[10] = Object(_id, kStringHatch,kStringHatchDescription3,OUTERHATCH_TOP,EXIT | OPENABLE | OPENED,3,3,0,GENERATOR,8);
1383 	_objectState[11] = Object(_id, kStringGenerator,kStringGeneratorDescription,GENERATOR_TOP,EXIT,12,12,0,GENERATOR,8);
1384 }
1385 
interact(Action verb,Object & obj1,Object & obj2)1386 bool ShipHold::interact(Action verb, Object &obj1, Object &obj2) {
1387 	Room *room;
1388 
1389 	if ((verb == ACTION_LOOK) && (obj1._id == SCRAP_LK) && (obj1._description != kStringScrapDescription3)) {
1390 		_vm->renderMessage(obj1._description);
1391 		obj1._description = kStringScrapDescription3;
1392 		_gm->takeObject(*getObject(2));
1393 	} else if (((verb == ACTION_OPEN) || (verb == ACTION_CLOSE)) && (obj1._id == OUTERHATCH_TOP))
1394 		_vm->renderMessage(kStringShipHold1);
1395 	else if ((verb == ACTION_CLOSE) && (obj1._id == LANDINGMOD_HATCH) && (isSectionVisible(4) || isSectionVisible(6)))
1396 		_vm->renderMessage(kStringCable1);
1397 	else if (((verb == ACTION_TAKE) && (obj1._id == HOLD_WIRE)) ||
1398 			 ((verb == ACTION_USE) && Object::combine(obj1, obj2, HOLD_WIRE, LANDINGMOD_HATCH)))
1399 		_vm->renderMessage(kStringCable2);
1400 	else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, TERMINALSTRIP, HOLD_WIRE)) {
1401 		getObject(0)->_name = kStringWireAndClip;
1402 		_gm->_inventory.remove(*getObject(2));
1403 		_gm->_state._terminalStripConnected = true;
1404 		_gm->_state._terminalStripWire = true;
1405 		_vm->renderMessage(kStringOk);
1406 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, HOLD_WIRE, SPOOL)) {
1407 		if (!_gm->_state._terminalStripConnected)
1408 			_vm->renderMessage(kStringCable3);
1409 		else {
1410 			_vm->renderImage(5);
1411 			getObject(0)->_name = kStringWireAndPlug2;
1412 			getObject(0)->_click = 10;
1413 			room = _gm->_rooms[CABIN_L2];
1414 			_gm->_inventory.remove(*getObject(9));
1415 		}
1416 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, HOLD_WIRE, GENERATOR_TOP)) {
1417 		if (isSectionVisible(5)) {
1418 			room = _gm->_rooms[GENERATOR];
1419 			room->getObject(0)->_click = 15;
1420 			room->getObject(1)->_click = 13;
1421 			room->setSectionVisible(6, true);
1422 			room->setSectionVisible(8, true);
1423 			_vm->renderImage(_gm->invertSection(5));
1424 			_vm->renderImage(6);
1425 			setSectionVisible(4, false);
1426 			getObject(0)->_click = 11;
1427 		} else
1428 			_vm->renderMessage(kStringCable4);
1429 	} else
1430 		return false;
1431 
1432 	return true;
1433 }
1434 
onEntrance()1435 void ShipHold::onEntrance() {
1436 	if (!hasSeen())
1437 		_vm->renderMessage(kStringShipHold2);
1438 	_gm->_rooms[AIRLOCK]->setSectionVisible(kMaxSection - 2, kShownTrue);
1439 	setRoomSeen(true);
1440 	_gm->_rooms[COCKPIT]->setRoomSeen(true);
1441 }
1442 
ShipLandingModule(SupernovaEngine * vm,GameManager1 * gm)1443 ShipLandingModule::ShipLandingModule(SupernovaEngine *vm, GameManager1 *gm) {
1444 	_vm = vm;
1445 	_gm = gm;
1446 
1447 	_fileNumber = 25;
1448 	_id = LANDINGMODULE;
1449 	_shown[0] = kShownTrue;
1450 
1451 	_objectState[0] = Object(_id, kStringSocket,kStringDefaultDescription,LANDINGMOD_SOCKET,COMBINABLE,1,1,0);
1452 	_objectState[1] = Object(_id, kStringButton,kSafetyButtonDescription,LANDINGMOD_BUTTON,PRESS | COMBINABLE,2,2,0);
1453 	_objectState[2] = Object(_id, kStringMonitor,kStringDefaultDescription,LANDINGMOD_MONITOR,NULLTYPE,3,3,0);
1454 	_objectState[3] = Object(_id, kStringKeyboard,kStringDefaultDescription,KEYBOARD,NULLTYPE,4,4,0);
1455 	_objectState[4] = Object(_id, kNoString,kStringDefaultDescription,LANDINGMOD_WIRE,COMBINABLE,255,255,0);
1456 	_objectState[5] = Object(_id, kStringHatch,kStringDefaultDescription,LANDINGMOD_HATCH,EXIT | OPENABLE | OPENED | COMBINABLE, 0,0,1 | kSectionInvert,HOLD,10);
1457 }
1458 
interact(Action verb,Object & obj1,Object & obj2)1459 bool ShipLandingModule::interact(Action verb, Object &obj1, Object &obj2) {
1460 	if ((verb == ACTION_PRESS) && (obj1._id == LANDINGMOD_BUTTON))
1461 		_vm->renderMessage(obj1._description);
1462 	else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, PEN, LANDINGMOD_BUTTON)) {
1463 		if (_gm->_state._landingModuleEnergyDaysLeft) {
1464 			Room *r = _gm->_rooms[GENERATOR];
1465 			if (isSectionVisible(7)) {
1466 				_vm->renderImage(_gm->invertSection(9));
1467 				_vm->renderImage(_gm->invertSection(2));
1468 				_vm->renderImage(_gm->invertSection(8));
1469 				_vm->renderImage(_gm->invertSection(7));
1470 				_vm->renderImage(_gm->invertSection(10));
1471 				if (r->isSectionVisible(9))
1472 					_gm->_state._powerOff = true;
1473 				_gm->roomBrightness();
1474 			} else {
1475 				_vm->renderImage(7);
1476 				if (r->isSectionVisible(9))
1477 					_gm->_state._powerOff = false;
1478 				_gm->roomBrightness();
1479 				r = _gm->_rooms[SLEEP];
1480 				r->setSectionVisible(1, false);
1481 				r->setSectionVisible(2, false);
1482 				_gm->wait(2);
1483 				_vm->renderImage(2);
1484 				_gm->wait(3);
1485 				_vm->renderImage(8);
1486 				_gm->wait(2);
1487 				_vm->renderImage(9);
1488 				_gm->wait(1);
1489 				_vm->renderImage(10);
1490 			}
1491 		}
1492 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, KNIFE, LANDINGMOD_BUTTON))
1493 		_vm->renderMessage(kStringShipHold3);
1494 	else if ((verb == ACTION_LOOK) && (obj1._id == LANDINGMOD_MONITOR) && isSectionVisible(7))
1495 		_vm->renderMessage(kStringShipHold4);
1496 	else if ((verb == ACTION_USE) && (obj1._id == KEYBOARD))
1497 		_vm->renderMessage(kStringShipHold5);
1498 	else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, WIRE, LANDINGMOD_SOCKET)) {
1499 		Room *r = _gm->_rooms[CABIN_L3];
1500 		_gm->_inventory.remove(*r->getObject(8));
1501 		getObject(4)->_name = r->getObject(8)->_name;
1502 		_vm->renderImage(4);
1503 		if (_gm->_state._cableConnected) {
1504 			_vm->renderImage(5);
1505 			getObject(4)->_click = 6;
1506 		} else {
1507 			getObject(4)->_click = 5;
1508 			if (_gm->_state._terminalStripWire)
1509 				_vm->renderImage(11);
1510 		}
1511 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, SPOOL, LANDINGMOD_SOCKET))
1512 		_vm->renderMessage(kStringShipHold8);
1513 	else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, LANDINGMOD_WIRE, TERMINALSTRIP)) {
1514 		_vm->renderImage(11);
1515 		getObject(4)->_name = kStringWireAndClip;
1516 		Room *r = _gm->_rooms[HOLD];
1517 		_gm->_inventory.remove(*r->getObject(2));
1518 		_gm->_state._terminalStripConnected = true;
1519 		_gm->_state._terminalStripWire = true;
1520 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, LANDINGMOD_WIRE, SPOOL)) {
1521 		if (!_gm->_state._terminalStripConnected)
1522 			_vm->renderMessage(kStringCable3);
1523 		else {
1524 			_vm->renderImage(5);
1525 			getObject(4)->_name = kStringWireAndPlug2;
1526 			getObject(4)->_click = 6;
1527 			_gm->_inventory.remove(*_gm->_rooms[CABIN_L2]->getObject(9));
1528 		}
1529 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, LANDINGMOD_WIRE, LANDINGMOD_HATCH)) {
1530 		if (getObject(5)->hasProperty(OPENED)) {
1531 			Room *r = _gm->_rooms[HOLD];
1532 			if (isSectionVisible(5)) {
1533 				r->setSectionVisible(5, true);
1534 				r->getObject(0)->_click = 10;
1535 			} else
1536 				r->getObject(0)->_click = 9;
1537 
1538 			r->setSectionVisible(4, true);
1539 			r->getObject(0)->_name = getObject(4)->_name;
1540 			_vm->renderImage(_gm->invertSection(5));
1541 			_vm->renderImage(_gm->invertSection(4));
1542 			setSectionVisible(11, false);
1543 			_vm->renderImage(6);
1544 			getObject(4)->_click = 7;
1545 		} else
1546 			_vm->renderMessage(kStringShipHold6);
1547 	} else if ((verb == ACTION_CLOSE) && (obj1._id == LANDINGMOD_HATCH) && isSectionVisible(6))
1548 		_vm->renderMessage(kStringCable1);
1549 	else if (((verb == ACTION_TAKE) || (verb == ACTION_PULL)) && (obj1._id == LANDINGMOD_WIRE))
1550 		_vm->renderMessage(kStringCable2);
1551 	else
1552 		return false;
1553 
1554 	return true;
1555 }
1556 
ShipGenerator(SupernovaEngine * vm,GameManager1 * gm)1557 ShipGenerator::ShipGenerator(SupernovaEngine *vm, GameManager1 *gm) {
1558 	_vm = vm;
1559 	_gm = gm;
1560 
1561 	_fileNumber = 18;
1562 	_id = GENERATOR;
1563 	_shown[0] = kShownTrue;
1564 	_shown[5] = kShownTrue;
1565 
1566 	_objectState[0] = Object(_id, kStringGeneratorWire,kStringDefaultDescription,GENERATOR_WIRE,COMBINABLE,255,255,0);
1567 	_objectState[1] = Object(_id, kStringEmptySpool,kStringDefaultDescription,NULLOBJECT,UNNECESSARY,255,255,0);
1568 	_objectState[2] = Object(_id, kStringKeycard2,kStringKeycard2Description,KEYCARD2,COMBINABLE | TAKE,12,12,5 | kSectionInvert);
1569 	_objectState[3] = Object(_id, kStringRope,kStringDefaultDescription,GENERATOR_ROPE,COMBINABLE,255,255,0);
1570 	_objectState[4] = Object(_id, kStringHatch,kStringHatchDescription3,OUTERHATCH,EXIT | OPENABLE,1,2,1,OUTSIDE,22);
1571 	_objectState[5] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,OPENABLE | CLOSED,3,3,0);
1572 	_objectState[6] = Object(_id, kStringSlot,kStringSlotDescription,NULLOBJECT,COMBINABLE,4,4,0);
1573 	_objectState[7] = Object(_id, kStringTrap,kStringDefaultDescription,TRAP,OPENABLE,5,6,2);
1574 	_objectState[8] = Object(_id, kStringWire,kStringDefaultDescription,NULLOBJECT,NULLTYPE,7,7,0);
1575 	_objectState[9] = Object(_id, kStringVoltmeter,kStringDefaultDescription,VOLTMETER,NULLTYPE,9,9,0,NULLROOM,0);
1576 	_objectState[10] = Object(_id, kStringClip,kStringDefaultDescription,CLIP,COMBINABLE,8,8,0);
1577 	_objectState[11] = Object(_id, kStringWire,kStringWireDescription,SHORT_WIRE,COMBINABLE,10,10,0);
1578 	_objectState[12] = Object(_id, kStringLadder,kStringDefaultDescription,LADDER,EXIT,0,0,0,HOLD,1);
1579 }
1580 
interact(Action verb,Object & obj1,Object & obj2)1581 bool ShipGenerator::interact(Action verb, Object &obj1, Object &obj2) {
1582 	if ((verb == ACTION_OPEN) && (obj1._id == OUTERHATCH)) {
1583 		if (obj1.hasProperty(OPENED))
1584 			return false;
1585 		_vm->playSound(kAudioSlideDoor);
1586 		_vm->renderImage(1);
1587 		if (isSectionVisible(7))
1588 			_vm->renderImage(10);
1589 		if (isSectionVisible(13))
1590 			_vm->renderImage(13);
1591 		_gm->_rooms[HOLD]->setSectionVisible(3, true);
1592 		obj1.setProperty(OPENED);
1593 		obj1._click = 2;
1594 		_vm->playSound(kAudioDoorOpen);
1595 	} else if ((verb == ACTION_CLOSE) && (obj1._id == OUTERHATCH)) {
1596 		if (!obj1.hasProperty(OPENED))
1597 			return false;
1598 		if (isSectionVisible(11) || isSectionVisible(12))
1599 			_vm->renderMessage(kStringShipHold7);
1600 		else {
1601 			_vm->playSound(kAudioSlideDoor);
1602 			_vm->renderImage(_gm->invertSection(1));
1603 			setSectionVisible(10, false);
1604 			if (isSectionVisible(13))
1605 				_vm->renderImage(13);
1606 			_gm->_rooms[HOLD]->setSectionVisible(3, false);
1607 			obj1.disableProperty(OPENED);
1608 			obj1._click = 1;
1609 			_vm->playSound(kAudioDoorClose);
1610 		}
1611 	} else if ((verb == ACTION_WALK) && (obj1._id == OUTERHATCH) &&
1612 			   isSectionVisible(7)) {
1613 		if (!obj1.hasProperty(OPENED))
1614 			_vm->renderMessage(kStringShipHold9);
1615 		else if (!isSectionVisible(11))
1616 			_vm->renderMessage(kStringShipHold10);
1617 		else {
1618 			obj1._exitRoom = ROCKS;
1619 			return false;
1620 		}
1621 	} else if ((verb == ACTION_TAKE) && (obj1._id == GENERATOR_WIRE))
1622 		_vm->renderMessage(kStringCable2);
1623 	else if ((verb == ACTION_PULL) && (obj1._id == SHORT_WIRE) &&
1624 			 (obj1._click != 11)) {
1625 		_vm->renderImage(3);
1626 		_vm->renderImage(4);
1627 		obj1._click = 11;
1628 		_gm->turnOff();
1629 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, SHORT_WIRE, CLIP) &&
1630 			   (getObject(11)->_click == 11) && !isSectionVisible(9)) {
1631 		_vm->renderImage(2);
1632 		setSectionVisible(3, false);
1633 		setSectionVisible(4, false);
1634 		getObject(11)->_click = 10;
1635 		if (_gm->_state._shipEnergyDaysLeft)
1636 			_gm->turnOn();
1637 		else
1638 			_vm->renderImage(4);
1639 	} else if ((verb == ACTION_OPEN) && (obj1._id == TRAP)) {
1640 		_vm->playSound(kAudioSlideDoor);
1641 		_vm->renderImage(2);
1642 		if (getObject(11)->_click == 11)
1643 			_vm->renderImage(3);
1644 		if (_gm->_state._powerOff)
1645 			_vm->renderImage(4);
1646 		obj1.setProperty(OPENED);
1647 		obj1._click = 6;
1648 
1649 		obj1._click2 = 5;
1650 		_vm->playSound(kAudioDoorOpen);
1651 	} else if ((verb == ACTION_CLOSE) && (obj1._id == TRAP)) {
1652 		if (isSectionVisible(9))
1653 			_vm->renderMessage(kStringCable1);
1654 		else {
1655 			setSectionVisible(3, false);
1656 			return false;
1657 		}
1658 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, GENERATOR_WIRE, CLIP) &&
1659 			   isSectionVisible(3) && (getObject(0)->_click != 16)) {
1660 		_vm->renderImage(_gm->invertSection(8));
1661 		_vm->renderImage(2);
1662 		setSectionVisible(4, false);
1663 		_vm->renderImage(3);
1664 		_vm->renderImage(9);
1665 		getObject(0)->_click = 16;
1666 		Room *r = _gm->_rooms[LANDINGMODULE];
1667 		if (_gm->_state._landingModuleEnergyDaysLeft && r->isSectionVisible(7))
1668 			_gm->turnOn();
1669 		else
1670 			_vm->renderImage(4);
1671 		_gm->_rooms[HOLD]->setSectionVisible(7, true);
1672 		_gm->great(3);
1673 	} else if ((verb == ACTION_PULL) && (obj1._id == GENERATOR_WIRE) && (obj1._click == 16)) {
1674 		_vm->renderImage(_gm->invertSection(9));
1675 		_vm->renderImage(2);
1676 		_vm->renderImage(3);
1677 		_vm->renderImage(4);
1678 		_vm->renderImage(8);
1679 		obj1._click = 15;
1680 		_gm->turnOff();
1681 		_gm->_rooms[HOLD]->setSectionVisible(7, false);
1682 	} else if ((verb == ACTION_USE) &&
1683 			   (Object::combine(obj1, obj2, WIRE, CLIP) ||
1684 				Object::combine(obj1, obj2, SPOOL, CLIP)) &&
1685 			   isSectionVisible(3)) {
1686 		_vm->renderMessage(kStringShipHold11);
1687 	} else if ((verb == ACTION_LOOK) && (obj1._id == VOLTMETER)) {
1688 		if (_gm->_state._powerOff)
1689 			_vm->renderMessage(kStringShipHold12);
1690 		else
1691 			_vm->renderMessage(kStringShipHold13);
1692 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, LADDER, ROPE)) {
1693 		_vm->renderImage(13);
1694 		Room *r = _gm->_rooms[CABIN_R3];
1695 		_gm->_inventory.remove(*r->getObject(9));
1696 		getObject(3)->_click = 18;
1697 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, OUTERHATCH, GENERATOR_ROPE)) {
1698 		if (!isSectionVisible(1))
1699 			_vm->renderMessage(kStringShipHold14);
1700 		else {
1701 			_vm->renderImage(_gm->invertSection(13));
1702 			_vm->renderImage(1);
1703 			if (isSectionVisible(7)) {
1704 				_vm->renderImage(10);
1705 				_vm->renderImage(11);
1706 			} else
1707 				_vm->renderImage(12);
1708 
1709 			Room *r = _gm->_rooms[OUTSIDE];
1710 			r->setSectionVisible(1, true);
1711 			r->getObject(1)->_click = 1;
1712 			getObject(3)->_click = 17;
1713 		}
1714 	} else if ((verb == ACTION_TAKE) && (obj1._id == GENERATOR_ROPE))
1715 		_vm->renderMessage(kStringShipHold15);
1716 	else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, OUTERHATCH, GENERATOR_WIRE) && isSectionVisible(1))
1717 		_vm->renderMessage(kStringShipHold16);
1718 	else
1719 		return false;
1720 
1721 	return true;
1722 }
1723 
ShipOuterSpace(SupernovaEngine * vm,GameManager1 * gm)1724 ShipOuterSpace::ShipOuterSpace(SupernovaEngine *vm, GameManager1 *gm) {
1725 	_vm = vm;
1726 	_gm = gm;
1727 
1728 	_fileNumber = 4;
1729 	_id = OUTSIDE;
1730 	_shown[0] = kShownTrue;
1731 
1732 	_objectState[0] = Object(_id, kStringHatch,kStringDefaultDescription,NULLOBJECT,EXIT,0,0,0,GENERATOR,3);
1733 	_objectState[1] = Object(_id, kStringRope,kStringDefaultDescription,NULLOBJECT,UNNECESSARY,255,255,0);
1734 }
1735 
1736 
1737 // Arsano
ArsanoRocks(SupernovaEngine * vm,GameManager1 * gm)1738 ArsanoRocks::ArsanoRocks(SupernovaEngine *vm, GameManager1 *gm) {
1739 	_vm = vm;
1740 	_gm = gm;
1741 
1742 	_fileNumber = 12;
1743 	_id = OUTSIDE;
1744 	_shown[0] = kShownTrue;
1745 
1746 	_objectState[0] = Object(_id, kStringRope,kStringDefaultDescription,NULLOBJECT,UNNECESSARY | EXIT,0,0,0,GENERATOR,12);
1747 	_objectState[1] = Object(_id, kStringStone,kStringDefaultDescription,STONE,NULLTYPE,1,1,0);
1748 	_objectState[2] = Object(_id, kStringStone,kStringDefaultDescription,NULLOBJECT,NULLTYPE,2,2,0);
1749 	_objectState[3] = Object(_id, kStringCaveOpening,kStringCaveOpeningDescription,NULLOBJECT,NULLTYPE,255,255,0,CAVE,1);
1750 }
1751 
onEntrance()1752 void ArsanoRocks::onEntrance() {
1753 	_gm->great(8);
1754 }
1755 
interact(Action verb,Object & obj1,Object & obj2)1756 bool ArsanoRocks::interact(Action verb, Object &obj1, Object &obj2) {
1757 	if (((verb == ACTION_PULL) || (verb == ACTION_PRESS)) &&
1758 		(obj1._id == STONE) && !isSectionVisible(3)) {
1759 		_vm->renderImage(1);
1760 		_gm->wait(2);
1761 		_vm->renderImage(2);
1762 		_gm->wait(2);
1763 		_vm->renderImage(3);
1764 		_vm->playSound(kAudioRocks);
1765 		obj1._click = 3;
1766 		getObject(3)->_click = 4;
1767 		getObject(3)->setProperty(EXIT);
1768 		return true;
1769 	}
1770 	return false;
1771 }
1772 
ArsanoCave(SupernovaEngine * vm,GameManager1 * gm)1773 ArsanoCave::ArsanoCave(SupernovaEngine *vm, GameManager1 *gm) {
1774 	_vm = vm;
1775 	_gm = gm;
1776 
1777 	_fileNumber = 12;
1778 	_id = CAVE;
1779 
1780 	_objectState[0] = Object(_id, kStringExit,kStringExitDescription,NULLOBJECT,EXIT,255,255,0,ROCKS,22);
1781 	_objectState[1] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,255,255,0,MEETUP,2);
1782 }
1783 
ArsanoMeetup(SupernovaEngine * vm,GameManager1 * gm)1784 ArsanoMeetup::ArsanoMeetup(SupernovaEngine *vm, GameManager1 *gm) {
1785 	_vm = vm;
1786 	_gm = gm;
1787 
1788 	_fileNumber = 37;
1789 	_id = MEETUP;
1790 	_shown[0] = kShownTrue;
1791 	_sign = 0;
1792 	_beacon = 0;
1793 
1794 	_objectState[0] = Object(_id, kStringCave,kStringDefaultDescription,NULLOBJECT,EXIT,255,255,0,CAVE,22);
1795 	_objectState[1] = Object(_id, kStringSign,kStringSignDescription,MEETUP_SIGN,NULLTYPE,0,0,0);
1796 	_objectState[2] = Object(_id, kStringEntrance,kStringDefaultDescription,DOOR,EXIT,1,1,0,ENTRANCE,7);
1797 	_objectState[3] = Object(_id, kStringStar,kStringDefaultDescription,STAR,NULLTYPE,2,2,0);
1798 	_objectState[4] = Object(_id, kStringSpaceshift,kStringDefaultDescription,SPACESHIPS,COMBINABLE,3,3,0);
1799 	_objectState[5] = Object(_id, kStringSpaceshift,kStringDefaultDescription,SPACESHIP,COMBINABLE,4,4,0);
1800 }
1801 
onEntrance()1802 void ArsanoMeetup::onEntrance() {
1803 	if (isSectionVisible(7)) {
1804 		_gm->wait(3);
1805 		_vm->renderImage(6);
1806 		setSectionVisible(7, false);
1807 		_gm->wait(3);
1808 		_vm->renderImage(_gm->invertSection(6));
1809 	}
1810 	if (!(_gm->_state._greatFlag & 0x8000)) {
1811 		_vm->playSound(kAudioFoundLocation);
1812 		_gm->_state._greatFlag |= 0x8000;
1813 	}
1814 }
1815 
animation()1816 void ArsanoMeetup::animation() {
1817 	_vm->renderImage(_gm->invertSection(1) + _beacon);
1818 	_beacon = (_beacon + 1) % 5;
1819 	_vm->renderImage(_beacon + 1);
1820 	_vm->renderImage(_beacon + 8);
1821 	if (isSectionVisible(_sign + 13))
1822 		_vm->renderImage(_gm->invertSection(13) + _sign);
1823 	else
1824 		_vm->renderImage(13 + _sign);
1825 
1826 	_sign = (_sign + 1) % 14;
1827 	_gm->setAnimationTimer(3);
1828 }
1829 
interact(Action verb,Object & obj1,Object & obj2)1830 bool ArsanoMeetup::interact(Action verb, Object &obj1, Object &obj2) {
1831 	if ((verb == ACTION_WALK) &&
1832 		((obj1._id == SPACESHIPS) ||
1833 		 ((obj1._id == SPACESHIP) && !obj1.hasProperty(OPENED)))) {
1834 		_vm->renderMessage(kStringArsanoMeetup1);
1835 	} else if ((verb == ACTION_WALK) && (obj1._id == SPACESHIP))
1836 		_gm->changeRoom(GLIDER);
1837 	else if ((verb == ACTION_WALK) && (obj1._id == STAR))
1838 		_vm->renderMessage(kStringArsanoMeetup2);
1839 	else if ((verb == ACTION_LOOK) && (obj1._id == STAR)) {
1840 		_vm->setCurrentImage(26);
1841 		_vm->renderImage(0);
1842 		_vm->paletteBrightness();
1843 		_gm->animationOff();
1844 		_gm->getInput();
1845 		_gm->animationOn();
1846 		g_system->fillScreen(kColorBlack);
1847 		_vm->renderRoom(*this);
1848 		_vm->paletteBrightness();
1849 	} else if ((verb == ACTION_WALK) && (obj1._id == DOOR)) {
1850 		_vm->renderImage(6);
1851 		_gm->wait(3);
1852 		_vm->renderImage(7);
1853 		setSectionVisible(6, false);
1854 		_gm->wait(3);
1855 
1856 		return false;
1857 	} else if ((verb == ACTION_LOOK) && (obj1._id == MEETUP_SIGN) && _gm->_state._language) {
1858 		if (_gm->_state._language == 2)
1859 			_vm->renderMessage(kStringArsanoMeetup3);
1860 
1861 		obj1._description = kStringSignDescription2;
1862 		if (_gm->_state._language == 1)
1863 			return false;
1864 
1865 		_gm->_state._language = 1;
1866 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, KEYCARD_R, SPACESHIP)) {
1867 		getObject(5)->setProperty(OPENED);
1868 		_gm->changeRoom(GLIDER);
1869 	} else
1870 		return false;
1871 
1872 	return true;
1873 }
1874 
ArsanoEntrance(SupernovaEngine * vm,GameManager1 * gm)1875 ArsanoEntrance::ArsanoEntrance(SupernovaEngine *vm, GameManager1 *gm) {
1876 	_vm = vm;
1877 	_gm = gm;
1878 
1879 	_fileNumber = 10;
1880 	_id = ENTRANCE;
1881 	_shown[0] = kShownTrue;
1882 
1883 	_objectState[0] = Object(_id, kStringPorter,kStringPorterDescription,PORTER,TALK,0,0,0);
1884 	_objectState[1] = Object(_id, kStringDoor,kStringDefaultDescription,NULLOBJECT,EXIT | OPENABLE | CLOSED,1,1,0,NULLROOM,5);
1885 	_objectState[2] = Object(_id, kStringSign,kStringSignDescription,KITCHEN_SIGN,NULLTYPE,2,2,0);
1886 	_objectState[3] = Object(_id, kStringChewingGum,kStringDefaultDescription,SCHNUCK,TAKE,255,255,10+kSectionInvert);
1887 	_objectState[4] = Object(_id, kStringGummyBears,kStringDefaultDescription,SCHNUCK,TAKE,255,255,11+kSectionInvert);
1888 	_objectState[5] = Object(_id, kStringChocolateBall,kStringDefaultDescription,SCHNUCK,TAKE,255,255,12+kSectionInvert);
1889 	_objectState[6] = Object(_id, kStringEgg,kStringDefaultDescription,EGG,TAKE,255,255,13+kSectionInvert);
1890 	_objectState[7] = Object(_id, kStringLiquorice,kStringDefaultDescription,SCHNUCK,TAKE,255,255,14+kSectionInvert);
1891 	_objectState[8] = Object(_id, kStringPill,kStringPillDescription,PILL,TAKE,255,255,0);
1892 	_objectState[9] = Object(_id, kStringSlot,kStringDefaultDescription,CAR_SLOT,COMBINABLE,6,6,0);
1893 	_objectState[10] = Object(_id, kStringVendingMachine,kStringVendingMachineDescription,NULLOBJECT,NULLTYPE,5,5,0);
1894 	_objectState[11] = Object(_id, kStringToilet,kStringToiletDescription,ARSANO_BATHROOM,NULLTYPE,255,255,0);
1895 	_objectState[12] = Object(_id, kStringButton,kStringDefaultDescription,BATHROOM_BUTTON,PRESS,3,3,0);
1896 	_objectState[13] = Object(_id, kStringSign,kStringSignDescription,BATHROOM_SIGN,NULLTYPE,4,4,0);
1897 	_objectState[14] = Object(_id, kStringStaircase,kStringDefaultDescription,STAIRCASE,EXIT,8,8,0,REST,3);
1898 	_objectState[15] = Object(_id, kStringExit,kStringDefaultDescription,MEETUP_EXIT,EXIT,255,255,0,MEETUP,22);
1899 	_objectState[16] = Object(_id, kStringCoins,kStringCoinsDescription,COINS,TAKE|COMBINABLE,255,255,0);
1900 	_objectState[17] = Object(_id, kStringTabletPackage,kStringTabletPackageDescription,PILL_HULL,TAKE,255,255,0);
1901 
1902 	_dialog1[0] = kStringArsanoDialog7;
1903 	_dialog1[1] = kStringArsanoDialog1;
1904 	_dialog1[2] = kStringArsanoDialog8;
1905 	_dialog1[3] = kStringArsanoDialog9;
1906 	_dialog1[4] = kStringDialogSeparator;
1907 
1908 	_dialog2[0] = kStringArsanoDialog1;
1909 	_dialog2[1] = kStringArsanoDialog2;
1910 	_dialog2[2] = kStringArsanoDialog3;
1911 	_dialog2[3] = kStringArsanoDialog4;
1912 	_dialog2[4] = kStringDialogSeparator;
1913 
1914 	_dialog3[0] = kStringArsanoDialog5;
1915 	_dialog3[1] = kStringArsanoDialog6;
1916 
1917 	_eyewitness = 5;
1918 }
1919 
animation()1920 void ArsanoEntrance::animation() {
1921 	if (!_vm->_screen->isMessageShown() && isSectionVisible(kMaxSection - 5)) {
1922 		_gm->animationOff(); // to avoid recursive call
1923 		_vm->playSound(kAudioSlideDoor);
1924 		_vm->renderImage(8);
1925 		setSectionVisible(9, false);
1926 		_gm->wait(2);
1927 		_vm->renderImage(7);
1928 		setSectionVisible(8, false);
1929 		_gm->wait(2);
1930 		_vm->renderImage(6);
1931 		setSectionVisible(7, false);
1932 		_gm->wait(2);
1933 		_vm->renderImage(5);
1934 		setSectionVisible(6, false);
1935 		_gm->wait(2);
1936 		_vm->renderImage(_gm->invertSection(5));
1937 		getObject(11)->_click = 255;
1938 		setSectionVisible(kMaxSection - 5, false);
1939 		_gm->animationOn();
1940 	}
1941 	if (isSectionVisible(2))
1942 		_vm->renderImage(_gm->invertSection(2));
1943 	else if (_eyewitness)
1944 		--_eyewitness;
1945 	else {
1946 		_eyewitness = 20;
1947 		_vm->renderImage(2);
1948 	}
1949 
1950 	_gm->setAnimationTimer(4);
1951 }
1952 
interact(Action verb,Object & obj1,Object & obj2)1953 bool ArsanoEntrance::interact(Action verb, Object &obj1, Object &obj2) {
1954 	static byte row1[6] = {1, 1, 1, 1, 1, 0};
1955 	static byte row2[6] = {1, 1, 1, 1, 1, 0};
1956 	static byte row3[6] = {1, 1, 0, 0, 0, 0};
1957 
1958 	if ((verb == ACTION_TALK) && (obj1._id == PORTER)) {
1959 		if (_gm->_rooms[AIRLOCK]->getObject(4)->hasProperty(WORN))
1960 			_vm->renderMessage(kStringArsanoEntrance1);
1961 		else {
1962 			if (_gm->_state._language) {
1963 				int e;
1964 				do {
1965 					if (_gm->_state._shoes == 1) {
1966 						_dialog2[2] = kStringArsanoEntrance2;
1967 						addSentence(2, 2);
1968 					} else if (_gm->_state._shoes > 1)
1969 						removeSentence(2, 2);
1970 
1971 					switch (e = _gm->dialog(5, row2, _dialog2, 2)) {
1972 					case 0:
1973 						_gm->reply(kStringArsanoEntrance3, 1, _gm->invertSection(1));
1974 						_gm->reply(kStringArsanoEntrance4, 1, _gm->invertSection(1));
1975 						_gm->reply(kStringArsanoEntrance5, 1, _gm->invertSection(1));
1976 						removeSentence(1, 1);
1977 						break;
1978 					case 1:
1979 						_gm->reply(kStringArsanoEntrance6, 1, _gm->invertSection(1));
1980 						addSentence(1, 2);
1981 						break;
1982 					case 2:
1983 						if (_gm->_state._shoes == 1) {
1984 							_gm->reply(kStringArsanoEntrance7, 1, _gm->invertSection(1));
1985 							_gm->_state._shoes = 2;
1986 						} else {
1987 							_gm->reply(kStringArsanoEntrance8, 1, _gm->invertSection(1));
1988 							_gm->_state._shoes = 1;
1989 						}
1990 						break;
1991 					case 3:
1992 						_gm->reply(kStringArsanoEntrance9, 1, _gm->invertSection(1));
1993 						break;
1994 					default:
1995 						break;
1996 					}
1997 				} while (e != 4);
1998 			} else if (_gm->dialog(5, row2, _dialog2, 0) != 4)
1999 				_gm->reply(kStringArsanoEntrance10, 1, _gm->invertSection(1));
2000 		}
2001 	} else if ((verb == ACTION_WALK) && (obj1._id == STAIRCASE) && (_gm->_state._shoes != 3)) {
2002 		_vm->renderImage(3);
2003 		_gm->wait(2);
2004 		_vm->renderImage(4);
2005 		setSectionVisible(3, false);
2006 		if (_gm->_rooms[AIRLOCK]->getObject(4)->hasProperty(WORN))
2007 			_gm->reply(kStringDialogSeparator, 1, _gm->invertSection(1));
2008 		else if (_gm->_state._language)
2009 			_gm->reply(kStringArsanoEntrance11, 1, _gm->invertSection(1));
2010 		else
2011 			_gm->reply(kStringArsanoEntrance12, 1, _gm->invertSection(1));
2012 		_vm->renderImage(3);
2013 		setSectionVisible(4, false);
2014 		_gm->wait(2);
2015 		_vm->renderImage(_gm->invertSection(3));
2016 		if (!_gm->_rooms[AIRLOCK]->getObject(4)->hasProperty(WORN)) {
2017 			if (_gm->_state._language) {
2018 				if (_gm->_state._shoes)
2019 					_gm->reply(kStringArsanoEntrance13, 1, _gm->invertSection(1));
2020 				else
2021 					_gm->reply(kStringArsanoEntrance14, 1, _gm->invertSection(1));
2022 				int e = 0;
2023 				while ((e < 3) && (!allSentencesRemoved(4, 1))) {
2024 					switch (e = _gm->dialog(5, row1, _dialog1, 1)) {
2025 					case 0:
2026 						_gm->reply(kStringArsanoEntrance15, 1, 1 + kSectionInvert);
2027 						break;
2028 					case 1:
2029 						_gm->reply(kStringArsanoEntrance3, 1, 1 + kSectionInvert);
2030 						_gm->reply(kStringArsanoEntrance4, 1, 1 + kSectionInvert);
2031 						_gm->reply(kStringArsanoEntrance5, 1, 1 + kSectionInvert);
2032 						removeSentence(0, 2);
2033 						break;
2034 					case 2:
2035 						_gm->reply(kStringArsanoEntrance7, 1, 1 + kSectionInvert);
2036 						_gm->_state._shoes = 2;
2037 						break;
2038 					case 3:
2039 						_vm->renderImage(3);
2040 						_gm->wait(2);
2041 						_vm->renderImage(4);
2042 						setSectionVisible(3, false);
2043 						_gm->reply(kStringArsanoEntrance16, 1, 1 + kSectionInvert);
2044 						_vm->renderImage(3);
2045 						setSectionVisible(4, false);
2046 						_gm->wait(2);
2047 						_vm->renderImage(_gm->invertSection(3));
2048 						break;
2049 					default:
2050 						break;
2051 					}
2052 					removeSentence(0, 1);
2053 				}
2054 			} else {
2055 				_gm->dialog(2, row3, _dialog3, 0);
2056 				_gm->reply(kStringArsanoEntrance10, 1, 1 + kSectionInvert);
2057 			}
2058 		}
2059 	} else if ((verb == ACTION_PRESS) && (obj1._id == BATHROOM_BUTTON)) {
2060 		_vm->playSound(kAudioSlideDoor);
2061 		_vm->renderImage(5);
2062 		_gm->wait(2);
2063 		_vm->renderImage(6);
2064 		setSectionVisible(5, false);
2065 		_gm->wait(2);
2066 		_vm->renderImage(7);
2067 		setSectionVisible(6, false);
2068 		_gm->wait(2);
2069 		_vm->renderImage(8);
2070 		setSectionVisible(7, false);
2071 		_gm->wait(2);
2072 		_vm->renderImage(9);
2073 		setSectionVisible(8, false);
2074 		getObject(11)->_click = 9;
2075 	} else if ((verb == ACTION_WALK) && (obj1._id == ARSANO_BATHROOM)) {
2076 		if (_gm->_state._coins) {
2077 			if (_gm->_state._shoes == 2) {
2078 				_vm->renderMessage(kStringArsanoEntrance17);
2079 				_gm->_state._shoes = 3;
2080 				removeSentence(2, 2);
2081 				removeSentence(3, 2);
2082 			} else if (_gm->_state._shoes == 3) {
2083 				_vm->renderMessage(kStringArsanoEntrance18);
2084 				_gm->_state._shoes = 2;
2085 			} else
2086 				_vm->renderMessage(kStringArsanoEntrance19);
2087 		} else {
2088 			if (_gm->_rooms[AIRLOCK]->getObject(5)->hasProperty(WORN))
2089 				_vm->renderMessage(kStringArsanoEntrance20);
2090 			else {
2091 				_vm->renderMessage(kStringArsanoEntrance21);
2092 				_gm->wait(_gm->_messageDuration, true);
2093 				_vm->removeMessage();
2094 				_vm->renderMessage(kStringArsanoEntrance22);
2095 				_gm->takeObject(*getObject(16));
2096 				_gm->_state._coins = 5;
2097 			}
2098 		}
2099 		// This shown object is an abuse in the original engine as it's not a real shown variable
2100 		// It's an internal (boolean) status
2101 		_shown[kMaxSection - 5] = kShownTrue;
2102 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, COINS, CAR_SLOT)) {
2103 		if ((_gm->_state._coins < 5) && (getObject(7 - _gm->_state._coins)->_click == 7))
2104 			_vm->renderMessage(kStringArsanoEntrance23);
2105 		else {
2106 			_vm->renderImage(15 - _gm->_state._coins);
2107 			getObject(8 - _gm->_state._coins)->_click = 7;
2108 			--_gm->_state._coins;
2109 			if (_gm->_state._coins == 1)
2110 				getObject(16)->_name = kStringCoin;
2111 
2112 			if (_gm->_state._coins == 0) {
2113 				_gm->_inventory.remove(*getObject(16));
2114 				_gm->_state._coins = 255;
2115 			}
2116 		}
2117 	} else if ((verb == ACTION_LOOK) && (obj1._id == KITCHEN_SIGN) && _gm->_state._language) {
2118 		if (_gm->_state._language == 2)
2119 			_vm->renderMessage(kStringArsanoEntrance24);
2120 		obj1._description = kStringDoorDescription5;
2121 		if (_gm->_state._language == 1)
2122 			return false;
2123 		_gm->_state._language = 1;
2124 	} else if ((verb == ACTION_LOOK) && (obj1._id == BATHROOM_SIGN) && _gm->_state._language) {
2125 		if (_gm->_state._language == 2)
2126 			_vm->renderMessage(kStringArsanoEntrance25);
2127 		obj1._description = kStringDoorDescription6;
2128 		if (_gm->_state._language == 1)
2129 			return false;
2130 		_gm->_state._language = 1;
2131 	} else if ((verb == ACTION_WALK) && (obj1._id == MEETUP_EXIT)) {
2132 		if (!((_gm->_rooms[AIRLOCK]->getObject(4)->hasProperty(WORN)) &&
2133 			  (_gm->_rooms[AIRLOCK]->getObject(5)->hasProperty(WORN)) &&
2134 			  (_gm->_rooms[AIRLOCK]->getObject(6)->hasProperty(WORN)))) {
2135 			_vm->renderMessage(kStringArsanoEntrance26);
2136 			_gm->_rooms[AIRLOCK]->getObject(4)->setProperty(WORN);
2137 			_gm->_rooms[AIRLOCK]->getObject(5)->setProperty(WORN);
2138 			_gm->_rooms[AIRLOCK]->getObject(6)->setProperty(WORN);
2139 			_gm->wait(_gm->_messageDuration, true);
2140 			_vm->removeMessage();
2141 		}
2142 		return false;
2143 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, KNIFE, PORTER))
2144 		_vm->renderMessage(kStringArsanoEntrance27);
2145 	else
2146 		return false;
2147 
2148 	return true;
2149 }
2150 
ArsanoRemaining(SupernovaEngine * vm,GameManager1 * gm)2151 ArsanoRemaining::ArsanoRemaining(SupernovaEngine *vm, GameManager1 *gm) {
2152 	_vm = vm;
2153 	_gm = gm;
2154 
2155 	_fileNumber = 28;
2156 	_id = REST;
2157 	_shown[0] = kShownTrue;
2158 
2159 	_objectState[0] = Object(_id, kStringStaircase,kStringDefaultDescription,NULLOBJECT,EXIT,0,0,0,ENTRANCE,17);
2160 	_objectState[1] = Object(_id, kStringChair,kStringDefaultDescription,NULLOBJECT,EXIT,1,1,0,ROGER,2);
2161 	_objectState[2] = Object(_id, kStringShoes,kStringShoesDescription,NULLOBJECT,NULLTYPE,2,2,0);
2162 
2163 	_chewing = kShownTrue;
2164 	_i = 0;
2165 }
2166 
animation()2167 void ArsanoRemaining::animation() {
2168 	switch (_i) {
2169 	case  0:
2170 		_vm->renderImage(1);
2171 		_vm->renderImage(_gm->invertSection(4));
2172 		break;
2173 	case  1:
2174 		_vm->renderImage(_gm->invertSection(1));
2175 		_vm->renderImage(4);
2176 		break;
2177 	case  2:
2178 		_vm->renderImage(2);
2179 		_vm->renderImage(_gm->invertSection(4));
2180 		break;
2181 
2182 	case  3:
2183 		_vm->renderImage(7); // Dragon
2184 		_vm->renderImage(_gm->invertSection(2));
2185 		_vm->renderImage(4);
2186 		break;
2187 	case  4:
2188 		_vm->renderImage(8);
2189 		setSectionVisible(7, false);
2190 		_vm->renderImage(2);
2191 		_vm->renderImage(_gm->invertSection(4));
2192 		break;
2193 	case  5:
2194 		_vm->renderImage(_gm->invertSection(8));
2195 		_vm->renderImage(_gm->invertSection(2));
2196 		break;
2197 	case  6:
2198 		_vm->renderImage(3);
2199 		_vm->renderImage(2);
2200 		break;
2201 	case  7:
2202 		_vm->renderImage(_gm->invertSection(3));
2203 		_vm->renderImage(_gm->invertSection(2));
2204 		break;
2205 	case  8:
2206 		_vm->renderImage(3);
2207 		break;
2208 	case  9:
2209 		_vm->renderImage(14); // Card Player 1
2210 		_vm->renderImage(4);
2211 		_vm->renderImage(_gm->invertSection(3));
2212 		break;
2213 	case 10:
2214 		_vm->renderImage(15);
2215 		_vm->renderImage(14);
2216 		_vm->renderImage(_gm->invertSection(4));
2217 		_vm->renderImage(3);
2218 		break;
2219 	case 11:
2220 		_vm->renderImage(16);
2221 		setSectionVisible(15, false);
2222 		_vm->renderImage(4);
2223 		_vm->renderImage(_gm->invertSection(3));
2224 		break;
2225 	case 12:
2226 		_vm->renderImage(17);
2227 		setSectionVisible(16, false);
2228 		_vm->renderImage(_gm->invertSection(4));
2229 		_vm->renderImage(3);
2230 		break;
2231 	case 13:
2232 		_vm->renderImage(_gm->invertSection(17));
2233 		_vm->renderImage(4);
2234 		_vm->renderImage(_gm->invertSection(3));
2235 		break;
2236 	case 14:
2237 		_vm->renderImage(_gm->invertSection(4));
2238 		break;
2239 	case 15:
2240 		_vm->renderImage(6);
2241 		break;
2242 	case 16:
2243 		_vm->renderImage(18); // Card Player 2
2244 		_vm->renderImage(5);
2245 		break;
2246 	case 17:
2247 		_vm->renderImage(19);
2248 		setSectionVisible(18, false);
2249 		_vm->renderImage(_gm->invertSection(5));
2250 		break;
2251 	case 18:
2252 		_vm->renderImage(20);
2253 		setSectionVisible(19, false);
2254 		_vm->renderImage(5);
2255 		break;
2256 	case 19:
2257 		_vm->renderImage(21);
2258 		setSectionVisible(20, false);
2259 		_vm->renderImage(_gm->invertSection(5));
2260 		break;
2261 	case 20:
2262 		_vm->renderImage(_gm->invertSection(21));
2263 		_vm->renderImage(5);
2264 		break;
2265 	case 21:
2266 		_vm->renderImage(_gm->invertSection(5));
2267 		break;
2268 	case 22:
2269 		_vm->renderImage(5);
2270 		break;
2271 	case 23:
2272 		_vm->renderImage(10);
2273 		_chewing = false;
2274 		_vm->renderImage(_gm->invertSection(5));
2275 		break;
2276 	case 24:
2277 		_vm->renderImage(11);
2278 		setSectionVisible(10, false);
2279 		break;
2280 	case 25:
2281 		_vm->renderImage(12);
2282 		setSectionVisible(11, false);
2283 		break;
2284 	case 26:
2285 		_vm->renderImage(13);
2286 		setSectionVisible(12, false);
2287 		break;
2288 	case 27:
2289 		_vm->renderImage(12);
2290 		setSectionVisible(13, false);
2291 		break;
2292 	case 28:
2293 		_vm->renderImage(11);
2294 		setSectionVisible(12, false);
2295 		break;
2296 	case 29:
2297 		_vm->renderImage(10);
2298 		setSectionVisible(11, false);
2299 		break;
2300 	case 30:
2301 		_vm->renderImage(_gm->invertSection(10));
2302 		_chewing = true;
2303 		break;
2304 	case 31:
2305 		_vm->renderImage(22); // Card Player 3
2306 		break;
2307 	case 32:
2308 		_vm->renderImage(_gm->invertSection(22));
2309 		break;
2310 	case 33:
2311 		_vm->renderImage(_gm->invertSection(6));
2312 		break;
2313 	case 34:
2314 		_vm->renderImage(4);
2315 		break;
2316 	default:
2317 		break;
2318 	}
2319 
2320 	_i = (_i + 1) % 35;
2321 	if (_chewing) {
2322 		if (isSectionVisible(9))
2323 			_vm->renderImage(_gm->invertSection(9));
2324 		else
2325 			_vm->renderImage(9);
2326 	}
2327 	_gm->setAnimationTimer(3);
2328 }
2329 
ArsanoRoger(SupernovaEngine * vm,GameManager1 * gm)2330 ArsanoRoger::ArsanoRoger(SupernovaEngine *vm, GameManager1 *gm) {
2331 	_vm = vm;
2332 	_gm = gm;
2333 
2334 	_fileNumber = 29;
2335 	_id = ROGER;
2336 	_shown[0] = kShownTrue;
2337 
2338 	_objectState[0] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,255,255,0,REST,19);
2339 	_objectState[1] = Object(_id, kStringFrogFace,kStringDefaultDescription,ROGER_W,TALK,0,0,0);
2340 	_objectState[2] = Object(_id, kStringScrible,kStringScribleDescription,NULLOBJECT,NULLTYPE,3,3,0);
2341 	_objectState[3] = Object(_id, kStringWallet,kStringDefaultDescription,WALLET,TAKE,1,1,4);
2342 	_objectState[4] = Object(_id, kStringMenu,kStringMenuDescription,NULLOBJECT,UNNECESSARY,2,2,0);
2343 	_objectState[5] = Object(_id, kStringCup,kStringCupDescription,CUP,UNNECESSARY,4,4,0);
2344 	_objectState[6] = Object(_id, kStringChessGame,kStringDefaultDescription,NULLOBJECT,UNNECESSARY,255,255,0);
2345 	_objectState[7] = Object(_id, kStringBill,kStringBillDescription,NULLOBJECT,TAKE|COMBINABLE,255,255,0);
2346 	_objectState[8] = Object(_id, kStringKeycard3,kStringDefaultDescription,KEYCARD_R,TAKE|COMBINABLE,255,255,0);
2347 
2348 	_dialog1[0] = kStringDialogArsanoRoger1;
2349 	_dialog1[1] = kStringDialogArsanoRoger2;
2350 	_dialog1[2] = kStringDialogArsanoRoger3;
2351 	_dialog1[3] = kStringDialogSeparator;
2352 
2353 	_eyewitness = 5;
2354 	_hands = 0;
2355 }
2356 
onEntrance()2357 void ArsanoRoger::onEntrance() {
2358 	if (!sentenceRemoved(0, 2)) {
2359 		_gm->say(kStringArsanoRoger1);
2360 		_gm->reply(kStringArsanoRoger2, 2, 2 + kSectionInvert);
2361 		removeSentence(0, 2);
2362 	}
2363 }
2364 
animation()2365 void ArsanoRoger::animation() {
2366 	if (isSectionVisible(1))
2367 		_vm->renderImage(_gm->invertSection(1));
2368 	else if (isSectionVisible(10)) {
2369 		_vm->renderImage(12);
2370 		setSectionVisible(10, false);
2371 		setSectionVisible(12, false);
2372 	} else if (_eyewitness) {
2373 		--_eyewitness;
2374 	} else {
2375 		_eyewitness = 20;
2376 		if (isSectionVisible(3))
2377 			_vm->renderImage(10);
2378 		else
2379 			_vm->renderImage(1);
2380 	}
2381 
2382 	if (isSectionVisible(3)) {
2383 		setSectionVisible(5 + _hands, false);
2384 		_hands = (_hands + 1) % 5;
2385 		_vm->renderImage(5 + _hands);
2386 	}
2387 	_gm->setAnimationTimer(4);
2388 }
2389 
interact(Action verb,Object & obj1,Object & obj2)2390 bool ArsanoRoger::interact(Action verb, Object &obj1, Object &obj2) {
2391 	static byte row1[6] = {1, 1, 1, 1, 0, 0};
2392 
2393 	if ((verb == ACTION_TAKE) && (obj1._id == WALLET)) {
2394 		if (isSectionVisible(3)) {
2395 			_gm->great(0);
2396 			return false;
2397 		}
2398 		_gm->reply(kStringArsanoRoger3, 2, 2 + kSectionInvert);
2399 	} else if ((verb == ACTION_USE) && (obj1._id == CUP))
2400 		_vm->renderMessage(kStringArsanoRoger4);
2401 	else if ((verb == ACTION_TALK) && (obj1._id == ROGER_W)) {
2402 		if (isSectionVisible(3))
2403 			_vm->renderMessage(kStringArsanoRoger5);
2404 		else {
2405 			switch (_gm->dialog(4, row1, _dialog1, 1)) {
2406 			case 0:
2407 				_gm->reply(kStringArsanoRoger6, 2, 2 + kSectionInvert);
2408 				_gm->reply(kStringArsanoRoger7, 2, 2 + kSectionInvert);
2409 				break;
2410 			case 1:
2411 				_gm->reply(kStringArsanoRoger8, 2, 2 + kSectionInvert);
2412 				_gm->reply(kStringArsanoRoger9, 2, 2 + kSectionInvert);
2413 				_gm->say(kStringArsanoRoger10);
2414 				break;
2415 			case 2:
2416 				_gm->reply(kStringArsanoRoger11, 2, 2 + kSectionInvert);
2417 				_gm->say(kStringArsanoRoger12);
2418 				_gm->reply(kStringArsanoRoger13, 2, 2 + kSectionInvert);
2419 				_gm->say(kStringArsanoRoger14);
2420 				_gm->reply(kStringArsanoRoger15, 2, 2 + kSectionInvert);
2421 				_gm->reply(kStringArsanoRoger16, 2, 2 + kSectionInvert);
2422 				_gm->say(kStringArsanoRoger17);
2423 				_gm->say(kStringArsanoRoger18);
2424 				_gm->reply(kStringArsanoRoger19, 2, 2 + kSectionInvert);
2425 				_gm->say(kStringArsanoRoger20);
2426 				_gm->say(kStringArsanoRoger21);
2427 				_gm->reply(kStringArsanoRoger22, 2, 2 + kSectionInvert);
2428 				_gm->say(kStringArsanoRoger23);
2429 				_gm->reply(kStringArsanoRoger24, 2, 2 + kSectionInvert);
2430 				_gm->reply(kStringArsanoRoger25, 2, 2 + kSectionInvert);
2431 				_gm->say(kStringArsanoRoger26);
2432 				_gm->reply(kStringArsanoRoger27, 2, 2 + kSectionInvert);
2433 				_gm->reply(kStringArsanoRoger28, 2, 2 + kSectionInvert);
2434 				_gm->say(kStringArsanoRoger29);
2435 				_gm->reply(kStringArsanoRoger30, 2, 2 + kSectionInvert);
2436 				_gm->reply(kStringArsanoRoger31, 2, 2 + kSectionInvert);
2437 				_gm->say(kStringArsanoRoger32);
2438 				_gm->reply(kStringArsanoRoger33, 2, 2 + kSectionInvert);
2439 				_gm->say(kStringArsanoRoger34);
2440 				_gm->reply(kStringArsanoRoger35, 2, 2 + kSectionInvert);
2441 				break;
2442 			default:
2443 				break;
2444 			}
2445 		}
2446 	} else if (((verb == ACTION_USE) && Object::combine(obj1, obj2, CHESS, ROGER_W)) ||
2447 			   ((verb == ACTION_GIVE) && (obj1._id == CHESS) && (obj2._id == ROGER_W))) {
2448 		_vm->renderImage(11);
2449 		_gm->great(0);
2450 		_gm->say(kStringArsanoRoger36);
2451 		_gm->reply(kStringArsanoRoger37, 2, 2 + kSectionInvert);
2452 		_gm->say(kStringArsanoRoger38);
2453 		_vm->paletteFadeOut();
2454 		_gm->_inventory.remove(*_gm->_rooms[CABIN_R3]->getObject(0)); // Chess board
2455 		g_system->fillScreen(kColorBlack);
2456 		_vm->_screen->setGuiBrightness(255);
2457 		_vm->paletteBrightness();
2458 		_vm->renderMessage(kStringArsanoRoger39);
2459 		_gm->wait(_gm->_messageDuration, true);
2460 		_vm->removeMessage();
2461 		_vm->_screen->setGuiBrightness(0);
2462 		_vm->paletteBrightness();
2463 		_gm->_time += ticksToMsec(125000); // 2 hours
2464 		_gm->_state._alarmOn = (_gm->_state._timeAlarm > _gm->_time);
2465 		_gm->_state._eventTime = _gm->_time + ticksToMsec(4000);
2466 		_gm->_state._eventCallback = kSupernovaFn;
2467 		setSectionVisible(11, false);
2468 		setSectionVisible(1, false);
2469 		_vm->renderRoom(*this);
2470 		_vm->renderImage(3);
2471 		getObject(3)->_click = 5;
2472 		getObject(5)->_click = 6;
2473 		getObject(6)->_click = 7;
2474 		_vm->paletteFadeIn();
2475 		_vm->renderMessage(kStringArsanoRoger40);
2476 		_gm->wait(_gm->_messageDuration, true);
2477 		_vm->removeMessage();
2478 	} else
2479 		return false;
2480 
2481 	return true;
2482 }
2483 
ArsanoGlider(SupernovaEngine * vm,GameManager1 * gm)2484 ArsanoGlider::ArsanoGlider(SupernovaEngine *vm, GameManager1 *gm) {
2485 	_vm = vm;
2486 	_gm = gm;
2487 
2488 	_fileNumber = 19;
2489 	_id = GLIDER;
2490 	_shown[0] = kShownTrue;
2491 	_sinus = 0;
2492 
2493 	_objectState[0] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,255,255,0,MEETUP,15);
2494 	_objectState[1] = Object(_id, kStringButton,kStringDefaultDescription,GLIDER_BUTTON1,PRESS,0,0,0);
2495 	_objectState[2] = Object(_id, kStringButton,kStringDefaultDescription,GLIDER_BUTTON2,PRESS,1,1,0);
2496 	_objectState[3] = Object(_id, kStringButton,kStringDefaultDescription,GLIDER_BUTTON3,PRESS,2,2,0);
2497 	_objectState[4] = Object(_id, kStringButton,kStringDefaultDescription,GLIDER_BUTTON4,PRESS,3,3,0);
2498 	_objectState[5] = Object(_id, kStringKeycard,kStringDefaultDescription,GLIDER_KEYCARD,TAKE|COMBINABLE,255,255,0);
2499 	_objectState[6] = Object(_id, kStringSlot,kStringDefaultDescription,GLIDER_SLOT,COMBINABLE,4,4,0);
2500 	_objectState[7] = Object(_id, kStringCompartment,kStringDefaultDescription,NULLOBJECT,OPENABLE,5,6,6);
2501 	_objectState[8] = Object(_id, kStringKeyboard,kStringDefaultDescription,GLIDER_BUTTONS,NULLTYPE,7,7,0);
2502 	_objectState[9] = Object(_id, kStringAnnouncement,kStringAnnouncementDescription,GLIDER_DISPLAY,NULLTYPE,8,8,0);
2503 	_objectState[10] = Object(_id, kStringInstruments,kStringAnnouncementDescription,GLIDER_INSTRUMENTS,NULLTYPE,9,9,0);
2504 }
2505 
animation()2506 void ArsanoGlider::animation() {
2507 	if (isSectionVisible(8)) {
2508 		setSectionVisible(24 + _sinus, false);
2509 		_sinus = (_sinus + 1) % 14;
2510 		_vm->renderImage(24 + _sinus);
2511 	} else if (isSectionVisible(24 + _sinus))
2512 		_vm->renderImage(_gm->invertSection(24 + _sinus));
2513 
2514 	_gm->setAnimationTimer(2);
2515 }
2516 
interact(Action verb,Object & obj1,Object & obj2)2517 bool ArsanoGlider::interact(Action verb, Object &obj1, Object &obj2) {
2518 	static char l, r;
2519 	if ((verb == ACTION_USE) && Object::combine(obj1, obj2, KEYCARD_R, GLIDER_SLOT)) {
2520 		_vm->renderImage(5);
2521 		_gm->wait(7);
2522 		_vm->renderImage(8);
2523 		getObject(5)->_click = 10;
2524 		_gm->_inventory.remove(*_gm->_rooms[ROGER]->getObject(8));
2525 	} else if (((verb == ACTION_TAKE) || (verb == ACTION_PULL)) &&
2526 			   (obj1._id == GLIDER_KEYCARD)) {
2527 		_vm->renderImage(_gm->invertSection(5));
2528 		_vm->renderImage(_gm->invertSection(8));
2529 		getObject(5)->_click = 255;
2530 		_gm->takeObject(*_gm->_rooms[ROGER]->getObject(8));
2531 		for (int i = 9; i <= 22; i++)
2532 			_vm->renderImage(_gm->invertSection(i));
2533 		l = r = 0;
2534 	} else if ((verb == ACTION_PRESS) &&
2535 			   (obj1._id >= GLIDER_BUTTON1) && (obj1._id <= GLIDER_BUTTON4)) {
2536 		int i = obj1._id - GLIDER_BUTTON1 + 1;
2537 		_vm->renderImage(i);
2538 		if (isSectionVisible(8)) {
2539 			l = 0;
2540 			r = 0;
2541 			for (int j = 1; j < 8; j++) {
2542 				if (isSectionVisible(j + 8))
2543 					l = j;
2544 				if (isSectionVisible(j + 15))
2545 					r = j;
2546 			}
2547 			switch (i) {
2548 			case 1:
2549 				if (l < 7) {
2550 					l++;
2551 					_vm->renderImage(l + 8);
2552 				}
2553 				break;
2554 			case 3:
2555 				if (r < 7) {
2556 					r++;
2557 					_vm->renderImage(r + 15);
2558 				}
2559 				break;
2560 			case 2:
2561 				if (l) {
2562 					_vm->renderImage(_gm->invertSection(l + 8));
2563 					l--;
2564 				}
2565 				break;
2566 			case 4:
2567 				if (r) {
2568 					_vm->renderImage(_gm->invertSection(r + 15));
2569 					r--;
2570 				}
2571 				break;
2572 			default:
2573 				break;
2574 			}
2575 		}
2576 		_gm->wait(4);
2577 		_vm->renderImage(_gm->invertSection(i));
2578 	} else if ((verb == ACTION_USE) && (obj1._id == GLIDER_BUTTONS))
2579 		_vm->renderMessage(kStringArsanoGlider1);
2580 	else
2581 		return false;
2582 
2583 	return true;
2584 }
2585 
ArsanoMeetup2(SupernovaEngine * vm,GameManager1 * gm)2586 ArsanoMeetup2::ArsanoMeetup2(SupernovaEngine *vm, GameManager1 *gm) {
2587 	_vm = vm;
2588 	_gm = gm;
2589 
2590 	_fileNumber = 38;
2591 	_id = MEETUP2;
2592 	_shown[0] = kShownTrue;
2593 
2594 	_objectState[0] = Object(_id, kStringRoger, kStringDefaultDescription, ROGER_W, TALK, 255, 255, 0);
2595 	_objectState[1] = Object(_id, kStringSpaceshift, kStringDefaultDescription, SPACESHIP, COMBINABLE, 255, 255, 0);
2596 	_objectState[2] = Object(_id, kStringCave, kStringDefaultDescription, NULLOBJECT, EXIT, 255, 255, 0, CAVE, 22);
2597 
2598 	_dialog1[0] = kStringDialogArsanoMeetup2_1;
2599 	_dialog1[1] = kStringDialogArsanoMeetup2_2;
2600 	_dialog2[0] = kStringDialogArsanoMeetup2_3;
2601 	_dialog2[1] = kStringDialogArsanoMeetup2_4;
2602 	_dialog3[0] = kStringDialogArsanoMeetup2_5;
2603 	_dialog3[1] = kStringDialogArsanoMeetup2_6;
2604 	_dialog3[2] = kStringDialogArsanoMeetup2_7;
2605 	_dialog3[3] = kStringDialogArsanoMeetup2_8;
2606 	_dialog4[0] = kStringDialogArsanoMeetup2_9;
2607 	_dialog4[1] = kStringDialogArsanoMeetup2_10;
2608 	_dialog4[2] = kStringDialogArsanoMeetup2_11;
2609 }
2610 
onEntrance()2611 void ArsanoMeetup2::onEntrance() {
2612 	if (sentenceRemoved(0, 1)) {
2613 		if (sentenceRemoved(1, 1))
2614 			_vm->renderMessage(kStringArsanoMeetup2_2); // All spaceships have left the planet, except one ...
2615 		else
2616 			shipStart();
2617 	} else if (sentenceRemoved(1, 1))
2618 		_vm->renderMessage(kStringArsanoMeetup2_1); // All spaceships have left the planet
2619 
2620 	addAllSentences(1);
2621 }
2622 
interact(Action verb,Object & obj1,Object & obj2)2623 bool ArsanoMeetup2::interact(Action verb, Object &obj1, Object &obj2) {
2624 	static byte row1[6] = {1, 1, 0, 0, 0, 0};
2625 	static byte row2[6] = {1, 1, 0, 0, 0, 0};
2626 	static byte row3[6] = {1, 1, 1, 1, 0, 0};
2627 	static byte row4[6] = {2, 1, 0, 0, 0, 0};
2628 
2629 	if (((verb == ACTION_WALK) &&
2630 			((obj1._id == SPACESHIP) || (obj1._id == ROGER_W))) ||
2631 			((verb == ACTION_TALK) && (obj1._id == ROGER_W))) {
2632 		_gm->changeRoom(INTRO1);
2633 		_vm->setCurrentImage(30);
2634 		_vm->renderImage(0);
2635 		_vm->paletteBrightness();
2636 		bool found;
2637 		if (sentenceRemoved(0, 2) || sentenceRemoved(1, 2)) {
2638 			_gm->reply(kStringArsanoMeetup2_3, 1, 1 + kSectionInvert);
2639 			found = !_gm->dialog(2, row4, _dialog4, 0);
2640 			if (!(found))
2641 				_gm->reply(kStringArsanoMeetup2_4, 1, 1 + kSectionInvert);
2642 		} else {
2643 			_gm->reply(kStringArsanoMeetup2_5, 1, 1 + kSectionInvert);
2644 			_gm->reply(kStringArsanoMeetup2_6, 1, 1 + kSectionInvert);
2645 			found = !_gm->dialog(2, row1, _dialog1, 0);
2646 			removeSentence(0, 2);
2647 		}
2648 		if (found) {
2649 			_gm->_inventory.remove(*_gm->_rooms[ROGER]->getObject(3));
2650 			_gm->_inventory.remove(*_gm->_rooms[ROGER]->getObject(7));
2651 			_gm->_inventory.remove(*_gm->_rooms[ROGER]->getObject(8));
2652 			_gm->reply(kStringArsanoMeetup2_7, 1, 1 + kSectionInvert);
2653 			_gm->reply(kStringArsanoMeetup2_8, 1, 1 + kSectionInvert);
2654 			bool flight = _gm->dialog(2, row2, _dialog2, 0);
2655 			if (flight) {
2656 				_gm->reply(kStringArsanoMeetup2_9, 1, 1 + kSectionInvert);
2657 				_gm->dialog(4, row3, _dialog3, 0);
2658 				_gm->reply(kStringArsanoMeetup2_10, 1, 1 + kSectionInvert);
2659 			} else
2660 				_gm->reply(kStringArsanoMeetup2_11, 1, 1 + kSectionInvert);
2661 
2662 			_gm->changeRoom(MEETUP2);
2663 			_gm->_rooms[MEETUP2]->setSectionVisible(12, false);
2664 			_gm->_rooms[MEETUP2]->getObject(0)->_click = 255;
2665 			_gm->_rooms[MEETUP2]->getObject(1)->_click = 255;
2666 			_vm->renderRoom(*this);
2667 			_vm->paletteBrightness();
2668 			shipStart();
2669 			if (flight) {
2670 				_vm->setCurrentImage(13);
2671 				_vm->renderImage(0);
2672 				_vm->paletteBrightness();
2673 				_gm->wait(36);
2674 				for (int i = 1; i <= 13; i++) {
2675 					if (i > 1)
2676 						_vm->renderImage(_gm->invertSection(i - 1));
2677 					_vm->renderImage(i);
2678 					_gm->wait(2);
2679 				}
2680 				_vm->renderImage(_gm->invertSection(13));
2681 				_gm->wait(20);
2682 				_vm->setCurrentImage(14);
2683 				_vm->renderImage(0);
2684 				_vm->paletteBrightness();
2685 				_gm->wait(36);
2686 				for (int i = 1; i <= 13; i++) {
2687 					if (i > 1)
2688 						_vm->renderImage(_gm->invertSection(i - 1));
2689 					_vm->renderImage(i);
2690 					_gm->wait(2);
2691 				}
2692 				_vm->renderImage(_gm->invertSection(13));
2693 				_gm->wait(9);
2694 				_vm->playSound(kAudioCrash);
2695 				for (int i = 14; i <= 19; i++) {
2696 					_vm->renderImage(i);
2697 					_gm->wait(3);
2698 				}
2699 				_vm->paletteFadeOut();
2700 				_vm->setCurrentImage(11);
2701 				_vm->renderImage(0);
2702 				_vm->paletteFadeIn();
2703 				_gm->wait(18);
2704 				_vm->renderMessage(kStringArsanoMeetup2_12);
2705 				_gm->great(0);
2706 				_gm->wait(_gm->_messageDuration, true);
2707 				_vm->removeMessage();
2708 				_vm->paletteFadeOut();
2709 				g_system->fillScreen(kColorBlack);
2710 				_gm->_state._dream = false;
2711 				if (!_vm->loadGame(kSleepAutosaveSlot))
2712 					_vm->errorTempSave(false);
2713 				_gm->loadTime();
2714 				_gm->_rooms[CAVE]->getObject(1)->_exitRoom = MEETUP3;
2715 				_gm->_state._dream = true;
2716 			}
2717 		} else {
2718 			_gm->changeRoom(MEETUP2);
2719 			_vm->renderRoom(*this);
2720 		}
2721 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, KEYCARD_R, SPACESHIP))
2722 		_vm->renderMessage(kStringArsanoMeetup2_13);
2723 	else
2724 		return false;
2725 
2726 	return true;
2727 }
2728 
shipStart()2729 void ArsanoMeetup2::shipStart() {
2730 	_gm->wait(12);
2731 	for (int i = 2; i <= 11; ++i) {
2732 		if (i >= 9)
2733 			_vm->renderImage(i - 1 + kSectionInvert);
2734 		else
2735 			setSectionVisible(i - 1, false);
2736 		_vm->renderImage(i);
2737 		_gm->wait(2);
2738 	}
2739 	_vm->renderImage(11 + kSectionInvert);
2740 }
2741 
ArsanoMeetup3(SupernovaEngine * vm,GameManager1 * gm)2742 ArsanoMeetup3::ArsanoMeetup3(SupernovaEngine *vm, GameManager1 *gm) {
2743 	_vm = vm;
2744 	_gm = gm;
2745 
2746 	_fileNumber = 39;
2747 	_id = MEETUP3;
2748 	_shown[0] = kShownTrue;
2749 
2750 	_objectState[0] = Object(_id, kStringUfo,kStringUfoDescription,UFO,EXIT,0,0,0,NULLROOM,3);
2751 	_objectState[1] = Object(_id, kStringStar,kStringDefaultDescription,STAR,NULLTYPE,1,1,0);
2752 	_objectState[2] = Object(_id, kStringCave,kStringDefaultDescription,NULLOBJECT,EXIT,255,255,0,CAVE,22);
2753 
2754 	_dialog2[0] = kStringArsanoDialog1;
2755 	_dialog2[1] = kStringDialogArsanoMeetup3_1;
2756 	_dialog2[2] = kStringDialogArsanoMeetup3_2;
2757 	_dialog2[3] = kStringDialogArsanoMeetup3_3;
2758 	_dialog3[0] = kStringDialogArsanoMeetup3_4;
2759 	_dialog3[1] = kStringDialogArsanoMeetup3_5;
2760 }
2761 
interact(Action verb,Object & obj1,Object & obj2)2762 bool ArsanoMeetup3::interact(Action verb, Object &obj1, Object &obj2) {
2763 	byte row2[6] = {1, 1, 1, 1, 0, 0};
2764 	byte row3[6] = {1, 1, 0, 0, 0, 0};
2765 	byte rowsX[6] = {1, 1, 1, 0, 0, 0};
2766 
2767 	if ((verb == ACTION_WALK) && (obj1._id == STAR))
2768 		_vm->renderMessage(kStringArsanoMeetup2);
2769 	else if ((verb == ACTION_LOOK) && (obj1._id == STAR)) {
2770 		_vm->setCurrentImage(26);
2771 		_vm->renderImage(0);
2772 		_vm->paletteBrightness();
2773 		_gm->getInput();
2774 		g_system->fillScreen(kColorBlack);
2775 		_vm->renderRoom(*this);
2776 	} else if ((verb == ACTION_WALK) && (obj1._id == UFO)) {
2777 		g_system->fillScreen(kColorBlack);
2778 		_vm->setCurrentImage(36);
2779 		_vm->renderImage(0);
2780 		_vm->paletteBrightness();
2781 		_gm->dialog(3, rowsX, _dialogsX, 0);
2782 		_vm->renderImage(1);
2783 		_gm->wait(3);
2784 		_vm->renderImage(2);
2785 		_gm->wait(3);
2786 		_vm->renderImage(3);
2787 		_gm->wait(6);
2788 		_vm->renderImage(4);
2789 		_vm->playSound(kAudioGunShot);
2790 
2791 		while (_vm->_sound->isPlaying())
2792 			_gm->wait(1);
2793 
2794 		_vm->renderImage(5);
2795 		_gm->wait(3);
2796 		_vm->renderImage(4);
2797 		_vm->playSound(kAudioGunShot);
2798 
2799 		while (_vm->_sound->isPlaying())
2800 			_gm->wait(1);
2801 
2802 		_vm->renderImage(5);
2803 		_vm->paletteFadeOut();
2804 		_gm->wait(12);
2805 		_vm->setCurrentImage(0);
2806 		_vm->renderImage(0);
2807 		_vm->paletteFadeIn();
2808 		_gm->wait(18);
2809 		_gm->reply(kStringArsanoMeetup3_1, 2, 2 + kSectionInvert);
2810 		_gm->wait(10);
2811 		_gm->reply(kStringArsanoMeetup3_2, 1, 1 + kSectionInvert);
2812 
2813 		do {
2814 			int i = _gm->dialog(4, row2, _dialog2, 2);
2815 			switch (i) {
2816 			case 0:
2817 				_gm->reply(kStringArsanoMeetup3_3, 1, 1 + kSectionInvert);
2818 				_gm->reply(kStringArsanoMeetup3_4, 1, 1 + kSectionInvert);
2819 				break;
2820 			case 1:
2821 				_gm->reply(kStringArsanoMeetup3_5, 2, 2 + kSectionInvert);
2822 				_gm->say(kStringArsanoMeetup3_6);
2823 				_gm->reply(kStringArsanoMeetup3_7, 2, 2 + kSectionInvert);
2824 				_gm->reply(kStringArsanoMeetup3_8, 2, 2 + kSectionInvert);
2825 				_gm->reply(kStringArsanoMeetup3_9, 2, 2 + kSectionInvert);
2826 				_gm->reply(kStringArsanoMeetup3_10, 2, 2 + kSectionInvert);
2827 				_gm->reply(kStringArsanoMeetup3_11, 2, 2 + kSectionInvert);
2828 				if (_gm->dialog(2, row3, _dialog3, 0)) {
2829 					_gm->reply(kStringArsanoMeetup3_12, 2, 2 + kSectionInvert);
2830 					_gm->say(kStringArsanoMeetup3_13);
2831 				}
2832 				_gm->reply(kStringArsanoMeetup3_14, 2, 2 + kSectionInvert);
2833 				_gm->reply(kStringArsanoMeetup3_15, 2, 2 + kSectionInvert);
2834 				_gm->reply(kStringArsanoMeetup3_16, 2, 2 + kSectionInvert);
2835 				_gm->reply(kStringArsanoMeetup3_17, 2, 2 + kSectionInvert);
2836 				if (_gm->dialog(2, row3, _dialog3, 0)) {
2837 					_gm->reply(kStringArsanoMeetup3_12, 2, 2 + kSectionInvert);
2838 					_gm->say(kStringArsanoMeetup3_13);
2839 				}
2840 				_gm->reply(kStringArsanoMeetup3_18, 2, 2 + kSectionInvert);
2841 				break;
2842 			case 2:
2843 				_gm->reply(kStringArsanoMeetup3_19, 2, 2 + kSectionInvert);
2844 				_gm->reply(kStringArsanoMeetup3_20, 2, 2 + kSectionInvert);
2845 				break;
2846 			case 3:
2847 				_gm->reply(kStringArsanoMeetup3_21, 1, 1 + kSectionInvert);
2848 				_gm->reply(kStringArsanoMeetup3_22, 1, 1 + kSectionInvert);
2849 				_gm->say(kStringArsanoMeetup3_23);
2850 				_gm->reply(kStringArsanoMeetup3_24, 1, 1 + kSectionInvert);
2851 				_gm->reply(kStringArsanoMeetup3_25, 1, 1 + kSectionInvert);
2852 				break;
2853 			default:
2854 				break;
2855 			}
2856 			removeSentence(2, 2);
2857 		} while (!allSentencesRemoved(4, 2));
2858 		_gm->say(kStringArsanoMeetup3_26);
2859 		_gm->reply(kStringArsanoMeetup3_27, 1, 1 + kSectionInvert);
2860 		_gm->reply(kStringArsanoMeetup3_28, 1, 1 + kSectionInvert);
2861 		_vm->paletteFadeOut();
2862 		// Remove all objects from the inventory except the Knife, Watch and Discman
2863 		bool has_knife = _gm->_rooms[INTRO1]->getObject(1)->hasProperty(CARRIED);
2864 		bool has_watch = _gm->_rooms[INTRO1]->getObject(2)->hasProperty(CARRIED);
2865 		bool has_discman = _gm->_rooms[INTRO1]->getObject(3)->hasProperty(CARRIED);
2866 		_gm->_inventory.clear();
2867 		_gm->_inventoryScroll = 0;
2868 		if (has_knife)
2869 			_gm->_inventory.add(*_gm->_rooms[INTRO1]->getObject(1));
2870 		if (has_watch)
2871 			_gm->_inventory.add(*_gm->_rooms[INTRO1]->getObject(2));
2872 		if (has_discman)
2873 			_gm->_inventory.add(*_gm->_rooms[INTRO1]->getObject(3));
2874 		_gm->changeRoom(CELL);
2875 		_gm->_state._dream = true;
2876 	} else
2877 		return false;
2878 
2879 	return true;
2880 }
2881 
2882 // Axacuss
AxacussCell(SupernovaEngine * vm,GameManager1 * gm)2883 AxacussCell::AxacussCell(SupernovaEngine *vm, GameManager1 *gm) {
2884 	_vm = vm;
2885 	_gm = gm;
2886 
2887 	_fileNumber = 43;
2888 	_id = CELL;
2889 	_shown[0] = kShownTrue;
2890 	_shown[1] = kShownTrue;
2891 	_shown[31] = kShownTrue;
2892 
2893 	_objectState[0] = Object(_id, kStringButton,kStringDefaultDescription,CELL_BUTTON,PRESS,1,1,0);
2894 	_objectState[1] = Object(_id, kStringDoor,kStringDefaultDescription,CELL_DOOR,EXIT|OPENABLE|CLOSED,0,0,31+kSectionInvert,CORRIDOR4,1);
2895 	_objectState[2] = Object(_id, kStringTray,kStringTrayDescription,TRAY,UNNECESSARY,255,255,0);
2896 	_objectState[3] = Object(_id, kStringLamp,kStringLampDescription,NULLOBJECT,COMBINABLE,3,3,0);
2897 	_objectState[4] = Object(_id, kStringEyes,kStringEyesDescription,NULLOBJECT,NULLTYPE,4,4,0);
2898 	_objectState[5] = Object(_id, kStringWire,kStringDefaultDescription,CELL_WIRE,COMBINABLE|TAKE,6,6,0);
2899 	_objectState[6] = Object(_id, kStringSocket,kStringSocketDescription,SOCKET,COMBINABLE,5,5,0);
2900 	_objectState[7] = Object(_id, kStringMetalBlock,kStringMetalBlockDescription,MAGNET,TAKE|COMBINABLE,255,255,30);
2901 	_objectState[8] = Object(_id, kStringRobot,kStringRobotDescription,NULLOBJECT,NULLTYPE,255,255,0);
2902 	_objectState[9] = Object(_id, kStringTable,kStringTableDescription,CELL_TABLE,COMBINABLE,2,2,0);
2903 }
2904 
onEntrance()2905 void AxacussCell::onEntrance() {
2906 	if (_gm->_state._dream) {
2907 		_vm->renderMessage(kStringAxacussCell_1);
2908 		_gm->_time = ticksToMsec(500000);
2909 		_gm->_state._alarmOn = (_gm->_state._timeAlarm > _gm->_time);
2910 		_gm->_state._powerOff = false;
2911 		_gm->_state._dream = false;
2912 	}
2913 }
2914 
animation()2915 void AxacussCell::animation() {
2916 	++_gm->_state._timeRobot;
2917 
2918 	if (_gm->_state._timeRobot == 299) {
2919 		_vm->renderImage(_gm->invertSection(31));
2920 		_vm->renderImage(28);
2921 		getObject(0)->_click = 255;
2922 		getObject(1)->resetProperty(EXIT | OPENABLE | OPENED | CLOSED);
2923 	} else if ((_gm->_state._timeRobot >= 301) && (_gm->_state._timeRobot <= 320)) {
2924 		_vm->renderImage(_gm->invertSection(329 - _gm->_state._timeRobot));
2925 		_vm->renderImage(328 - _gm->_state._timeRobot);
2926 	} else if (_gm->_state._timeRobot == 321) {
2927 		_vm->renderImage(31);
2928 		setSectionVisible(8, false);
2929 		getObject(0)->_click = 1;
2930 		getObject(1)->resetProperty(EXIT | OPENABLE | CLOSED);
2931 	}
2932 
2933 	if (_gm->_state._timeRobot == 599) {
2934 		_vm->renderImage(_gm->invertSection(31));
2935 		_vm->renderImage(8);
2936 		getObject(0)->_click = 255;
2937 		getObject(1)->resetProperty(EXIT | OPENABLE | OPENED | CLOSED);
2938 	} else if ((_gm->_state._timeRobot >= 601) && (_gm->_state._timeRobot <= 620)) {
2939 		_vm->renderImage(_gm->_state._timeRobot - 593 + kSectionInvert);
2940 		_vm->renderImage(_gm->_state._timeRobot - 592);
2941 	} else if (_gm->_state._timeRobot == 621) {
2942 		_vm->renderImage(31);
2943 		setSectionVisible(28, false);
2944 		getObject(0)->_click = 1;
2945 		getObject(1)->resetProperty(EXIT | OPENABLE | CLOSED);
2946 	} else if (_gm->_state._timeRobot == 700)
2947 		_gm->_state._timeRobot = 0;
2948 	else if (_gm->_state._timeRobot == 10002) {
2949 		_vm->renderImage(18 + kSectionInvert);
2950 		_vm->renderImage(29);
2951 		_vm->renderImage(7);
2952 		getObject(2)->_click = 13;
2953 	} else if (_gm->_state._timeRobot == 10003) {
2954 		setSectionVisible(29, false);
2955 		_vm->renderImage(30);
2956 		getObject(8)->_click = 12;
2957 		getObject(7)->_click = 14;
2958 		_vm->playSound(kAudioRobotBreaks);
2959 	} else if (_gm->_state._timeRobot == 10010)
2960 		--_gm->_state._timeRobot;
2961 
2962 	if (_gm->_state._timeRobot == 312) {
2963 		_vm->renderImage(7);
2964 		getObject(2)->_click = 13;
2965 	} else if (_gm->_state._timeRobot == 610) {
2966 		setSectionVisible(7, false);
2967 		getObject(2)->_click = 255;
2968 	}
2969 
2970 	if ((isSectionVisible(6)) &&
2971 		((_gm->_state._timeRobot == 310) || (_gm->_state._timeRobot == 610))) {
2972 		_vm->playSound(kAudioRobotShock);
2973 		_gm->_state._timeRobot = 10000;
2974 	}
2975 
2976 	_gm->setAnimationTimer(3);
2977 }
2978 
interact(Action verb,Object & obj1,Object & obj2)2979 bool AxacussCell::interact(Action verb, Object &obj1, Object &obj2) {
2980 	if ((verb == ACTION_PRESS) && (obj1._id == CELL_BUTTON))
2981 		_vm->renderMessage(kStringAxacussCell_2);
2982 	else if ((verb == ACTION_PULL) && (obj1._id == CELL_WIRE) &&
2983 			 !isSectionVisible(2) &&
2984 			 !isSectionVisible(3) &&
2985 			 !isSectionVisible(5)) {
2986 		if (isSectionVisible(1)) {
2987 			_vm->renderImage(_gm->invertSection(1));
2988 			_vm->renderImage(2);
2989 			getObject(5)->_click = 7;
2990 		} else if (isSectionVisible(4)) {
2991 			_vm->renderImage(_gm->invertSection(4));
2992 			_vm->renderImage(3);
2993 			getObject(5)->_click = 8;
2994 		} else if (isSectionVisible(6)) {
2995 			_vm->renderImage(_gm->invertSection(6));
2996 			_vm->renderImage(5);
2997 			getObject(5)->_click = 10;
2998 		}
2999 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, CELL_WIRE, SOCKET) &&
3000 			   !isSectionVisible(1) && !isSectionVisible(4) && !isSectionVisible(6)) {
3001 		if (isSectionVisible(2)) {
3002 			_vm->renderImage(_gm->invertSection(2));
3003 			_vm->renderImage(1);
3004 			getObject(5)->_click = 6;
3005 		} else if (isSectionVisible(3)) {
3006 			_vm->renderImage(_gm->invertSection(3));
3007 			_vm->renderImage(4);
3008 			getObject(5)->_click = 9;
3009 		} else if (isSectionVisible(5)) {
3010 			_vm->renderImage(_gm->invertSection(5));
3011 			_vm->renderImage(6);
3012 			getObject(5)->_click = 11;
3013 		} else {
3014 			_gm->_inventory.remove(*getObject(5));
3015 			_vm->renderImage(4);
3016 			getObject(5)->_click = 9;
3017 		}
3018 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, CELL_WIRE, KNIFE) &&
3019 			   ((isSectionVisible(1)) || (isSectionVisible(2)))) {
3020 		if (isSectionVisible(1))
3021 			_gm->shock();
3022 		else {
3023 			_vm->renderImage(_gm->invertSection(2));
3024 			_vm->renderImage(3);
3025 			getObject(5)->_click = 8;
3026 		}
3027 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, CELL_WIRE, CELL_TABLE) &&
3028 			   !isSectionVisible(1) &&
3029 			   !isSectionVisible(2) &&
3030 			   !isSectionVisible(5) &&
3031 			   !isSectionVisible(6)) {
3032 		if (isSectionVisible(3)) {
3033 			_vm->renderImage(_gm->invertSection(3));
3034 			_vm->renderImage(5);
3035 			getObject(5)->_click = 10;
3036 		} else if (isSectionVisible(4)) {
3037 			_vm->renderImage(_gm->invertSection(4));
3038 			_vm->renderImage(6);
3039 			_gm->shock();
3040 		} else {
3041 			_gm->_inventory.remove(*getObject(5));
3042 			_vm->renderImage(5);
3043 			getObject(5)->_click = 10;
3044 		}
3045 	} else if ((verb == ACTION_TAKE) && (obj1._id == CELL_WIRE) && !(obj1.hasProperty(CARRIED))) {
3046 		if (isSectionVisible(3)) {
3047 			_vm->renderImage(_gm->invertSection(3));
3048 			_gm->takeObject(obj1);
3049 		} else if (isSectionVisible(5)) {
3050 			_vm->renderImage(_gm->invertSection(5));
3051 			_gm->takeObject(obj1);
3052 		} else
3053 			_vm->renderMessage(kStringAxacussCell_3);
3054 	} else if ((verb == ACTION_WALK) && (obj1._id == CELL_DOOR) && (obj1.hasProperty(OPENED))) {
3055 		if (isSectionVisible(30) || isSectionVisible(29))
3056 			return false;
3057 		_vm->playSound(kAudioGunShot);
3058 
3059 		while (_vm->_sound->isPlaying())
3060 			_gm->wait(1);
3061 
3062 		_vm->playSound(kAudioGunShot);
3063 		_vm->playSound(kAudioGunShot);
3064 		_gm->dead(kStringAxacussCell_4);
3065 	} else if ((verb == ACTION_USE) && (obj1._id == TRAY))
3066 		_vm->renderMessage(kStringAxacussCell_5);
3067 	else if ((verb == ACTION_TAKE) && (obj1._id == MAGNET)) {
3068 		if (isSectionVisible(6))
3069 			_gm->shock();
3070 		_gm->takeObject(obj1);
3071 		_vm->renderMessage(kStringOk);
3072 	} else
3073 		return false;
3074 
3075 	return true;
3076 }
3077 
AxacussCorridor1(SupernovaEngine * vm,GameManager1 * gm)3078 AxacussCorridor1::AxacussCorridor1(SupernovaEngine *vm, GameManager1 *gm) {
3079 	_vm = vm;
3080 	_gm = gm;
3081 
3082 	_fileNumber = 16;
3083 	_id = CORRIDOR1;
3084 	_shown[0] = kShownTrue;
3085 	_shown[3] = kShownTrue;
3086 	_shown[4] = kShownTrue;
3087 	_shown[5] = kShownTrue;
3088 	_shown[13] = kShownTrue;
3089 	_shown[21] = kShownTrue;
3090 	_shown[23] = kShownTrue;
3091 	_shown[25] = kShownTrue;
3092 
3093 	_objectState[0] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,2,2,0,GUARD3,2);
3094 	_objectState[1] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,3,3,0,CORRIDOR2,22);
3095 }
3096 
onEntrance()3097 void AxacussCorridor1::onEntrance() {
3098 	_gm->corridorOnEntrance();
3099 }
3100 
3101 
AxacussCorridor2(SupernovaEngine * vm,GameManager1 * gm)3102 AxacussCorridor2::AxacussCorridor2(SupernovaEngine *vm, GameManager1 *gm) {
3103 	_vm = vm;
3104 	_gm = gm;
3105 
3106 	_fileNumber = 16;
3107 	_id = CORRIDOR2;
3108 	_shown[0] = kShownTrue;
3109 	_shown[2] = kShownTrue;
3110 	_shown[3] = kShownTrue;
3111 	_shown[4] = kShownTrue;
3112 	_shown[5] = kShownTrue;
3113 	_shown[17] = kShownTrue;
3114 	_shown[21] = kShownTrue;
3115 	_shown[24] = kShownTrue;
3116 
3117 	_objectState[0] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,2,2,0,CORRIDOR1,2);
3118 	_objectState[1] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,3,3,0,CORRIDOR3,22);
3119 	_objectState[2] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,1,1,0,CORRIDOR4,14);
3120 }
3121 
onEntrance()3122 void AxacussCorridor2::onEntrance() {
3123 	_gm->corridorOnEntrance();
3124 }
3125 
AxacussCorridor3(SupernovaEngine * vm,GameManager1 * gm)3126 AxacussCorridor3::AxacussCorridor3(SupernovaEngine *vm, GameManager1 *gm) {
3127 	_vm = vm;
3128 	_gm = gm;
3129 
3130 	_fileNumber = 16;
3131 	_id = CORRIDOR3;
3132 	_shown[0] = kShownTrue;
3133 	_shown[3] = kShownTrue;
3134 	_shown[5] = kShownTrue;
3135 	_shown[19] = kShownTrue;
3136 	_shown[23] = kShownTrue;
3137 
3138 	_objectState[0] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,2,2,0,CORRIDOR2,2);
3139 }
3140 
onEntrance()3141 void AxacussCorridor3::onEntrance() {
3142 	_gm->corridorOnEntrance();
3143 }
3144 
onEntrance()3145 void AxacussCorridor4::onEntrance() {
3146 	_gm->great(4);
3147 	if (_gm->_state._corridorSearch || _gm->_rooms[GUARD]->isSectionVisible(1))
3148 		_gm->busted(0);
3149 }
3150 
AxacussCorridor4(SupernovaEngine * vm,GameManager1 * gm)3151 AxacussCorridor4::AxacussCorridor4(SupernovaEngine *vm, GameManager1 *gm) {
3152 	_vm = vm;
3153 	_gm = gm;
3154 
3155 	_fileNumber = 16;
3156 	_id = CORRIDOR4;
3157 	_shown[0] = kShownTrue;
3158 	_shown[1] = kShownTrue;
3159 	_shown[2] = kShownTrue;
3160 	_shown[8] = kShownTrue;
3161 	_shown[9] = kShownTrue;
3162 	_shown[11] = kShownTrue;
3163 	_shown[15] = kShownTrue;
3164 	_shown[18] = kShownTrue;
3165 	_shown[20] = kShownTrue;
3166 	_shown[26] = kShownTrue;
3167 
3168 	_objectState[0] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,0,0,0,CORRIDOR2,10);
3169 	_objectState[1] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,1,1,0,GUARD,14);
3170 	_objectState[2] = Object(_id, kStringCellDoor,kStringCellDoorDescription,DOOR,EXIT|OPENABLE|OPENED|CLOSED,7,7,0,CELL,16);
3171 	_objectState[3] = Object(_id, kStringLaptop,kStringDefaultDescription,NEWSPAPER,TAKE,6,6,8);
3172 	_objectState[4] = Object(_id, kStringWristwatch,kStringDefaultDescription,WATCH,TAKE|COMBINABLE,255,255,8);
3173 	_objectState[5] = Object(_id, kStringTable,kStringDefaultDescription,TABLE,COMBINABLE,5,5,0);
3174 }
3175 
animation()3176 void AxacussCorridor4::animation() {
3177 }
3178 
interact(Action verb,Object & obj1,Object & obj2)3179 bool AxacussCorridor4::interact(Action verb, Object &obj1, Object &obj2) {
3180 	if ((verb == ACTION_TAKE) && (obj1._id == NEWSPAPER)) {
3181 		setSectionVisible(9, false);
3182 		_gm->takeObject(obj1);
3183 		if (isSectionVisible(29))
3184 			_vm->renderImage(29);
3185 	} else if (((verb == ACTION_USE) && Object::combine(obj1, obj2, TABLE, WATCH)) ||
3186 			   ((verb == ACTION_GIVE) && (obj1._id == WATCH) && (obj2._id == TABLE))) {
3187 		if (obj1._id == WATCH)
3188 			_gm->_inventory.remove(obj1);
3189 		else
3190 			_gm->_inventory.remove(obj2);
3191 
3192 		_vm->renderImage(29);
3193 		getObject(4)->_click = 8;
3194 	} else if ((verb == ACTION_TAKE) && (obj1._id == WATCH) && !obj1.hasProperty(CARRIED)) {
3195 		setSectionVisible(29, false);
3196 		getObject(4)->_click = 255;
3197 		_gm->takeObject(*_gm->_rooms[INTRO1]->getObject(2));
3198 		if (isSectionVisible(9))
3199 			_vm->renderImage(9);
3200 	} else
3201 		return false;
3202 
3203 	return true;
3204 }
3205 
AxacussCorridor5(SupernovaEngine * vm,GameManager1 * gm)3206 AxacussCorridor5::AxacussCorridor5(SupernovaEngine *vm, GameManager1 *gm) {
3207 	_vm = vm;
3208 	_gm = gm;
3209 
3210 	_fileNumber = 16;
3211 	_id = CORRIDOR5;
3212 	_shown[0] = kShownTrue;
3213 	_shown[3] = kShownTrue;
3214 	_shown[4] = kShownTrue;
3215 	_shown[5] = kShownTrue;
3216 	_shown[12] = kShownTrue;
3217 	_shown[22] = kShownTrue;
3218 	_shown[23] = kShownTrue;
3219 	_shown[24] = kShownTrue;
3220 
3221 	_objectState[0] = Object(_id, kStringExit,kStringDefaultDescription,DOOR,EXIT,2,2,0,NULLROOM,2);
3222 	_objectState[1] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,3,3,0,CORRIDOR6,22);
3223 
3224 	_dialog1[0] = kStringDialogAxacussCorridor5_1;
3225 	_dialog1[1] = kStringDialogAxacussCorridor5_2;
3226 	_dialog2[0] = kStringDialogAxacussCorridor5_3;
3227 	_dialog2[1] = kStringDialogAxacussCorridor5_4;
3228 	_dialog3[0] = kStringDialogAxacussCorridor5_5;
3229 	_dialog3[1] = kStringDialogAxacussCorridor5_6;
3230 	_dialog3[2] = kStringDialogAxacussCorridor5_7;
3231 	_dialog3[3] = kStringDialogAxacussCorridor5_7;
3232 
3233 	_rows[0] = 1;
3234 	_rows[1] = 1;
3235 	_rows[2] = 1;
3236 	_rows[3] = 1;
3237 	_rows[4] = 0;
3238 	_rows[5] = 0;
3239 }
3240 
onEntrance()3241 void AxacussCorridor5::onEntrance() {
3242 	_gm->corridorOnEntrance();
3243 }
3244 
handleMoneyDialog()3245 bool AxacussCorridor5::handleMoneyDialog() {
3246 	if (_gm->dialog(2, _rows, _dialog2, 0) == 0) {
3247 		_gm->reply(kStringAxacussCorridor5_5, 1, 1 + kSectionInvert);
3248 		addAllSentences(2);
3249 		if (_gm->_state._money == 0) {
3250 			removeSentence(2, 2);
3251 			removeSentence(3, 2);
3252 		} else {
3253 			Common::String string = _vm->getGameString(kStringDialogAxacussCorridor5_7);
3254 			_vm->setGameString(kStringPlaceholder1, Common::String::format(string.c_str(), _gm->_state._money - 200));
3255 			_vm->setGameString(kStringPlaceholder2, Common::String::format(string.c_str(), _gm->_state._money));
3256 			_dialog3[2] = kStringPlaceholder1;
3257 			_dialog3[3] = kStringPlaceholder2;
3258 		}
3259 		switch (_gm->dialog(4, _rows, _dialog3, 2)) {
3260 		case 1:
3261 			_gm->wait(3);
3262 			_vm->renderImage(1);
3263 			_vm->playSound(kAudioVoiceHalt);
3264 			_vm->renderImage(_gm->invertSection(1));
3265 			_gm->wait(5);
3266 			_vm->renderImage(2);
3267 			_gm->wait(2);
3268 			_gm->shot(3, _gm->invertSection(3));
3269 			break;
3270 		case 2:
3271 			if (_gm->_state._money > 1100) {
3272 				stopInteract(_gm->_state._money - 200);
3273 				return true;
3274 			}
3275 			_gm->reply(kStringAxacussCorridor5_6, 1, 1 + kSectionInvert);
3276 			break;
3277 		case 3:
3278 			if (_gm->_state._money >= 900) {
3279 				stopInteract(_gm->_state._money);
3280 				return true;
3281 			}
3282 			_gm->reply(kStringAxacussCorridor5_6, 1, 1 + kSectionInvert);
3283 			break;
3284 		default:
3285 			break;
3286 		}
3287 	}
3288 	return false;
3289 }
3290 
stopInteract(int sum)3291 void AxacussCorridor5::stopInteract(int sum) {
3292 	_gm->reply(kStringAxacussCorridor5_7, 1, 1 + kSectionInvert);
3293 	_gm->great(0);
3294 	_gm->changeRoom(ELEVATOR);
3295 	_gm->takeMoney(-sum);
3296 }
3297 
interact(Action verb,Object & obj1,Object & obj2)3298 bool AxacussCorridor5::interact(Action verb, Object &obj1, Object &obj2) {
3299 	if ((verb == ACTION_WALK) && (obj1._id == DOOR)) {
3300 		g_system->fillScreen(kColorBlack);
3301 		_vm->setCurrentImage(41);
3302 		_vm->renderImage(0);
3303 		_vm->paletteBrightness();
3304 		if (_gm->_guiEnabled) {
3305 			_gm->reply(kStringAxacussCorridor5_1, 1, 1 + kSectionInvert);
3306 			if (handleMoneyDialog())
3307 				return true;
3308 		} else {
3309 			_gm->_guiEnabled = true;
3310 			_gm->reply(kStringAxacussCorridor5_2, 1, 1 + kSectionInvert);
3311 			if (_gm->dialog(2, _rows, _dialog1, 0))
3312 				_gm->reply(kStringAxacussCorridor5_3, 1, 1 + kSectionInvert);
3313 			else {
3314 				_gm->reply(kStringAxacussCorridor5_4, 1, 1 + kSectionInvert);
3315 				if (handleMoneyDialog())
3316 					return true;
3317 			}
3318 		}
3319 		g_system->fillScreen(kColorBlack);
3320 		return true;
3321 	}
3322 	return false;
3323 }
3324 
AxacussCorridor6(SupernovaEngine * vm,GameManager1 * gm)3325 AxacussCorridor6::AxacussCorridor6(SupernovaEngine *vm, GameManager1 *gm) {
3326 	_vm = vm;
3327 	_gm = gm;
3328 
3329 	_fileNumber = 16;
3330 	_id = CORRIDOR6;
3331 	_shown[0] = kShownTrue;
3332 	_shown[3] = kShownTrue;
3333 	_shown[4] = kShownTrue;
3334 	_shown[5] = kShownTrue;
3335 	_shown[6] = kShownTrue;
3336 	_shown[22] = kShownTrue;
3337 	_shown[24] = kShownTrue;
3338 	_shown[25] = kShownTrue;
3339 
3340 	_objectState[0] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,2,2,0,CORRIDOR5,2);
3341 	_objectState[1] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,3,3,0,CORRIDOR7,22);
3342 	_objectState[2] = Object(_id, kStringDoor,kStringDefaultDescription,DOOR,OPENABLE|CLOSED,255,255,0,CORRIDOR8,13);
3343 }
3344 
onEntrance()3345 void AxacussCorridor6::onEntrance() {
3346 	_gm->corridorOnEntrance();
3347 }
3348 
interact(Action verb,Object & obj1,Object & obj2)3349 bool AxacussCorridor6::interact(Action verb, Object &obj1, Object &obj2) {
3350 	if ((verb == ACTION_CLOSE) && (obj1._id == DOOR) &&
3351 			(obj1.hasProperty(OPENED))) {
3352 		_vm->renderImage(6);
3353 		setSectionVisible(7, false);
3354 		obj1.resetProperty(EXIT | OPENABLE | CLOSED);
3355 		_gm->_rooms[CORRIDOR8]->setSectionVisible(27, false);
3356 		_gm->_rooms[CORRIDOR8]->setSectionVisible(28, true);
3357 		_gm->_rooms[CORRIDOR8]->getObject(0)->disableProperty(OPENED);
3358 		_vm->playSound(kAudioDoorClose);
3359 	} else
3360 		return false;
3361 
3362 	return true;
3363 }
3364 
AxacussCorridor7(SupernovaEngine * vm,GameManager1 * gm)3365 AxacussCorridor7::AxacussCorridor7(SupernovaEngine *vm, GameManager1 *gm) {
3366 	_vm = vm;
3367 	_gm = gm;
3368 
3369 	_fileNumber = 16;
3370 	_id = CORRIDOR7;
3371 	_shown[0] = kShownTrue;
3372 	_shown[3] = kShownTrue;
3373 	_shown[4] = kShownTrue;
3374 	_shown[5] = kShownTrue;
3375 	_shown[10] = kShownTrue;
3376 	_shown[21] = kShownTrue;
3377 	_shown[24] = kShownTrue;
3378 	_shown[25] = kShownTrue;
3379 
3380 	_objectState[0] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,2,2,0,CORRIDOR6,2);
3381 	_objectState[1] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,3,3,0,GUARD,22);
3382 }
3383 
onEntrance()3384 void AxacussCorridor7::onEntrance() {
3385 	_gm->corridorOnEntrance();
3386 }
3387 
AxacussCorridor8(SupernovaEngine * vm,GameManager1 * gm)3388 AxacussCorridor8::AxacussCorridor8(SupernovaEngine *vm, GameManager1 *gm) {
3389 	_vm = vm;
3390 	_gm = gm;
3391 
3392 	_fileNumber = 16;
3393 	_id = CORRIDOR8;
3394 	_shown[0] = kShownTrue;
3395 	_shown[1] = kShownTrue;
3396 	_shown[4] = kShownTrue;
3397 	_shown[15] = kShownTrue;
3398 	_shown[20] = kShownTrue;
3399 	_shown[22] = kShownTrue;
3400 	_shown[28] = kShownTrue;
3401 
3402 	_objectState[0] = Object(_id, kStringDoor,kStringDefaultDescription,DOOR,EXIT|OPENABLE,0,0,0,CORRIDOR6,10);
3403 	_objectState[1] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,3,3,0,BCORRIDOR,22);
3404 }
3405 
onEntrance()3406 void AxacussCorridor8::onEntrance() {
3407 	_gm->corridorOnEntrance();
3408 }
3409 
interact(Action verb,Object & obj1,Object & obj2)3410 bool AxacussCorridor8::interact(Action verb, Object &obj1, Object &obj2) {
3411 	if ((verb == ACTION_OPEN) && (obj1._id == DOOR) && !obj1.hasProperty(OPENED)) {
3412 		_vm->renderImage(27);
3413 		setSectionVisible(28, false);
3414 		obj1.setProperty(OPENED);
3415 		_gm->_rooms[CORRIDOR6]->setSectionVisible(6, false);
3416 		_gm->_rooms[CORRIDOR6]->setSectionVisible(7, true);
3417 		_gm->_rooms[CORRIDOR6]->getObject(2)->resetProperty(EXIT | OPENED | OPENABLE);
3418 		_gm->_rooms[CORRIDOR6]->getObject(2)->_click = 4;
3419 		_vm->playSound(kAudioDoorOpen);
3420 	} else if ((verb == ACTION_CLOSE) && (obj1._id == DOOR) && (obj1._type & OPENED)) {
3421 		_vm->renderImage(28);
3422 		setSectionVisible(27, false);
3423 		obj1.disableProperty(OPENED);
3424 		_gm->_rooms[CORRIDOR6]->setSectionVisible(6, true);
3425 		_gm->_rooms[CORRIDOR6]->setSectionVisible(7, false);
3426 		_gm->_rooms[CORRIDOR6]->getObject(2)->resetProperty(EXIT | CLOSED | OPENABLE);
3427 		_vm->playSound(kAudioDoorClose);
3428 	} else
3429 		return false;
3430 
3431 	return true;
3432 }
3433 
AxacussCorridor9(SupernovaEngine * vm,GameManager1 * gm)3434 AxacussCorridor9::AxacussCorridor9(SupernovaEngine *vm, GameManager1 *gm) {
3435 	_vm = vm;
3436 	_gm = gm;
3437 
3438 	_fileNumber = 16;
3439 	_id = CORRIDOR9;
3440 	_shown[0] = kShownTrue;
3441 	_shown[1] = kShownTrue;
3442 	_shown[3] = kShownTrue;
3443 	_shown[14] = kShownTrue;
3444 	_shown[19] = kShownTrue;
3445 	_shown[23] = kShownTrue;
3446 	_shown[28] = kShownTrue;
3447 
3448 	_objectState[0] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,2,2,0,BCORRIDOR,2);
3449 	_objectState[1] = Object(_id, kStringDoor,kStringDefaultDescription,DOOR,EXIT|OPENABLE,0,0,0,GUARD,10);
3450 }
3451 
onEntrance()3452 void AxacussCorridor9::onEntrance() {
3453 	_gm->corridorOnEntrance();
3454 }
3455 
interact(Action verb,Object & obj1,Object & obj2)3456 bool AxacussCorridor9::interact(Action verb, Object &obj1, Object &obj2) {
3457 	if ((verb == ACTION_CLOSE) && (obj1._id == DOOR) && (obj1.hasProperty(OPENED))) {
3458 		_vm->renderImage(28);
3459 		setSectionVisible(27, false);
3460 		obj1.disableProperty(OPENED);
3461 		_gm->_rooms[GUARD]->setSectionVisible(6, false);
3462 		_gm->_rooms[GUARD]->getObject(2)->disableProperty(OPENED);
3463 		_vm->playSound(kAudioDoorClose);
3464 	} else if ((verb == ACTION_OPEN) && (obj1._id == DOOR) && !obj1.hasProperty(OPENED)) {
3465 		_vm->renderImage(27);
3466 		setSectionVisible(28, false);
3467 		obj1.setProperty(OPENED);
3468 		_gm->_rooms[GUARD]->setSectionVisible(6, true);
3469 		_gm->_rooms[GUARD]->getObject(2)->setProperty(OPENED);
3470 		_vm->playSound(kAudioDoorOpen);
3471 		if (!_gm->_rooms[GUARD]->isSectionVisible(1))
3472 			_gm->busted(0);
3473 	} else
3474 		return false;
3475 
3476 	return true;
3477 }
3478 
AxacussBcorridor(SupernovaEngine * vm,GameManager1 * gm)3479 AxacussBcorridor::AxacussBcorridor(SupernovaEngine *vm, GameManager1 *gm) {
3480 	_vm = vm;
3481 	_gm = gm;
3482 
3483 	_fileNumber = 6;
3484 	_id = BCORRIDOR;
3485 	_shown[0] = kShownTrue;
3486 	_shown[3] = kShownTrue;
3487 
3488 	_objectState[0] = Object(_id, kStringPillar,kStringDefaultDescription,PILLAR1,NULLTYPE,4,4,0);
3489 	_objectState[1] = Object(_id, kStringPillar,kStringDefaultDescription,PILLAR2,NULLTYPE,5,5,0);
3490 	_objectState[2] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,6,6,0,CORRIDOR8,2);
3491 	_objectState[3] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,7,7,0,CORRIDOR9,22);
3492 	_objectState[4] = Object(_id, kStringDoor,kStringDoorDescription1,DOOR1,EXIT|OPENABLE|CLOSED|OCCUPIED,0,0,1,OFFICE_L1,6);
3493 	_objectState[5] = Object(_id, kStringDoor,kStringDoorDescription2,DOOR2,EXIT|OPENABLE|CLOSED|OCCUPIED,1,1,2,OFFICE_L2,16);
3494 	_objectState[6] = Object(_id, kStringDoor,kStringDoorDescription3,DOOR3,EXIT|OPENABLE|OPENED,2,2,3,OFFICE_R1,8);
3495 	_objectState[7] = Object(_id, kStringDoor,kStringDoorDescription4,DOOR4,EXIT|OPENABLE|CLOSED|OCCUPIED,3,3,4,OFFICE_R2,18);
3496 }
3497 
onEntrance()3498 void AxacussBcorridor::onEntrance() {
3499 	if (_gm->_state._corridorSearch)
3500 		_gm->busted(0);
3501 	else if (isSectionVisible(7))
3502 		_gm->busted(-1);
3503 }
3504 
interact(Action verb,Object & obj1,Object & obj2)3505 bool AxacussBcorridor::interact(Action verb, Object &obj1, Object &obj2) {
3506 	if (obj1.hasProperty(EXIT) ||
3507 		((verb == ACTION_USE) && obj1.hasProperty(COMBINABLE) && obj2.hasProperty(EXIT))) {
3508 		_gm->_state._playerHidden = false;
3509 	}
3510 
3511 	if ((verb == ACTION_CLOSE) && (obj1._id >= DOOR1) && (obj1._id <= DOOR4) && obj1.hasProperty(OPENED)) {
3512 		_vm->renderImage(_gm->invertSection(obj1._id - DOOR1 + 1));
3513 		_vm->playSound(kAudioDoorClose);
3514 		obj1.disableProperty(OPENED);
3515 		obj1.setProperty(CLOSED);
3516 		if (obj1.hasProperty(OCCUPIED)) {
3517 			_gm->_state._destination = 255;
3518 			obj1.disableProperty(OCCUPIED);
3519 			obj1.setProperty(CAUGHT);
3520 			if (!_gm->_rooms[OFFICE_L1 + obj1._id - DOOR1]->isSectionVisible(4))
3521 				_gm->search(180);
3522 			else
3523 				_gm->_state._eventTime = kMaxTimerValue;
3524 		}
3525 	} else if (((verb == ACTION_WALK) || ((verb == ACTION_OPEN) && !obj1.hasProperty(OPENED))) &&
3526 			   (obj1._id >= DOOR1) && (obj1._id <= DOOR4) &&
3527 			   obj1.hasProperty(OCCUPIED)) {
3528 		_vm->renderMessage(kStringDontEnter);
3529 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, MASTERKEYCARD, DOOR1) &&
3530 			   !getObject(4)->hasProperty(OPENED)) {
3531 		if (getObject(4)->hasProperty(OCCUPIED))
3532 			_vm->renderMessage(kStringDontEnter);
3533 		else {
3534 			_vm->renderImage(1);
3535 			_vm->playSound(kAudioDoorOpen);
3536 			if (getObject(4)->hasProperty(CAUGHT)) {
3537 				_gm->busted(11);
3538 				return true;
3539 			}
3540 			getObject(4)->resetProperty(EXIT | OPENABLE | OPENED);
3541 		}
3542 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, MASTERKEYCARD, DOOR2) && !getObject(5)->hasProperty(OPENED)) {
3543 		if (getObject(5)->hasProperty(OCCUPIED))
3544 			_vm->renderMessage(kStringDontEnter);
3545 		else {
3546 			_vm->renderImage(2);
3547 			_vm->playSound(kAudioDoorOpen);
3548 			if (getObject(5)->hasProperty(CAUGHT)) {
3549 				_gm->busted(16);
3550 				return true;
3551 			}
3552 			getObject(5)->resetProperty(EXIT | OPENABLE | OPENED);
3553 		}
3554 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, MASTERKEYCARD, DOOR3) && !getObject(6)->hasProperty(OPENED)) {
3555 		if (getObject(6)->hasProperty(OCCUPIED))
3556 			_vm->renderMessage(kStringDontEnter);
3557 		else {
3558 			_vm->renderImage(3);
3559 			_vm->playSound(kAudioDoorOpen);
3560 			if (getObject(6)->hasProperty(CAUGHT)) {
3561 				_gm->busted(15);
3562 				return true;
3563 			}
3564 			getObject(6)->resetProperty(EXIT | OPENABLE | OPENED);
3565 		}
3566 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, MASTERKEYCARD, DOOR4) && !getObject(7)->hasProperty(OPENED)) {
3567 		if (getObject(7)->hasProperty(OCCUPIED)) {
3568 			_vm->renderMessage(kStringDontEnter);
3569 		} else {
3570 			_vm->renderImage(4);
3571 			_vm->playSound(kAudioDoorOpen);
3572 			if (getObject(7)->hasProperty(CAUGHT)) {
3573 				_gm->busted(20);
3574 				return true;
3575 			}
3576 			getObject(7)->resetProperty(EXIT | OPENABLE | OPENED);
3577 		}
3578 	} else if ((verb == ACTION_LOOK) && (obj1._id >= DOOR1) && (obj1._id <= DOOR4)) {
3579 		_gm->_state._nameSeen[obj1._id - DOOR1] = true;
3580 		return false;
3581 	} else if ((verb == ACTION_WALK) && ((obj1._id == PILLAR1) || (obj1._id == PILLAR2))) {
3582 		_vm->renderMessage(kStringAxacussBcorridor_1);
3583 		_gm->_state._playerHidden = true;
3584 	} else
3585 		return false;
3586 
3587 	return true;
3588 }
3589 
AxacussIntersection(SupernovaEngine * vm,GameManager1 * gm)3590 AxacussIntersection::AxacussIntersection(SupernovaEngine *vm, GameManager1 *gm) {
3591 	_vm = vm;
3592 	_gm = gm;
3593 
3594 	_fileNumber = 40;
3595 	_id = GUARD;
3596 	_shown[0] = kShownTrue;
3597 
3598 	_objectState[0] = Object(_id, kStringExit, kStringDefaultDescription, NULLOBJECT, EXIT, 255, 255, 0, CORRIDOR4, 21);
3599 	_objectState[1] = Object(_id, kStringCorridor, kStringDefaultDescription, NULLOBJECT, EXIT, 3, 3, 0, CORRIDOR7, 5);
3600 	_objectState[2] = Object(_id, kStringDoor, kStringDefaultDescription, DOOR, EXIT | OPENABLE, 1, 1, 6, CORRIDOR9, 3);
3601 	_objectState[3] = Object(_id, kStringAxacussan, kStringAxacussanDescription, GUARDIAN, TALK, 0, 0, 0);
3602 	_objectState[4] = Object(_id, kStringImage, kStringImageDescription2, NULLOBJECT, NULLTYPE, 2, 2, 0);
3603 	_objectState[5] = Object(_id, kStringMastercard, kStringMastercardDescription, MASTERKEYCARD, TAKE | COMBINABLE, 255, 255, 1);
3604 }
3605 
interact(Action verb,Object & obj1,Object & obj2)3606 bool AxacussIntersection::interact(Action verb, Object &obj1, Object &obj2) {
3607 	byte rowsX[6] = {1, 1, 1, 0, 0, 0};
3608 
3609 	if (((verb == ACTION_WALK) || (verb == ACTION_OPEN)) && (obj1._id == DOOR) && !isSectionVisible(1))
3610 		_gm->guardShot();
3611 	else if ((verb == ACTION_OPEN) && (obj1._id == DOOR) && !obj1.hasProperty(OPENED)) {
3612 		_gm->_rooms[CORRIDOR9]->setSectionVisible(27, true);
3613 		_gm->_rooms[CORRIDOR9]->setSectionVisible(28, false);
3614 		_gm->_rooms[CORRIDOR9]->getObject(1)->setProperty(OPENED);
3615 		return false;
3616 	} else if ((verb == ACTION_CLOSE) && (obj1._id == DOOR) && obj1.hasProperty(OPENED)) {
3617 		_gm->_rooms[CORRIDOR9]->setSectionVisible(27, false);
3618 		_gm->_rooms[CORRIDOR9]->setSectionVisible(28, true);
3619 		_gm->_rooms[CORRIDOR9]->getObject(1)->disableProperty(OPENED);
3620 		return false;
3621 	} else if ((verb == ACTION_TALK) && (obj1._id == GUARDIAN)) {
3622 		_gm->dialog(3, rowsX, _dialogsX, 0);
3623 		_gm->guardShot();
3624 	} else if ((verb == ACTION_TAKE) && (obj1._id == MASTERKEYCARD)) {
3625 		_gm->great(0);
3626 		setSectionVisible(7, false);
3627 		return false;
3628 	} else if ((verb == ACTION_USE) && (Object::combine(obj1, obj2, MAGNET, GUARDIAN) || Object::combine(obj1, obj2, KNIFE, GUARDIAN)))
3629 		_vm->renderMessage(kStringArsanoEntrance27);
3630 	else
3631 		return false;
3632 
3633 	return true;
3634 }
3635 
AxacussExit(SupernovaEngine * vm,GameManager1 * gm)3636 AxacussExit::AxacussExit(SupernovaEngine *vm, GameManager1 *gm) {
3637 	_vm = vm;
3638 	_gm = gm;
3639 
3640 	_fileNumber = 42;
3641 	_id = GUARD3;
3642 	_shown[0] = kShownTrue;
3643 
3644 	_objectState[0] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,255,255,0,CORRIDOR1,22);
3645 	_objectState[1] = Object(_id, kStringDoor,kStringDefaultDescription,NULLOBJECT,EXIT|OPENABLE|CLOSED,0,0,0,NULLROOM,20);
3646 	_objectState[2] = Object(_id, kStringDoor,kStringDefaultDescription,NULLOBJECT,EXIT|OPENABLE|CLOSED,1,1,0,NULLROOM,15);
3647 	_objectState[3] = Object(_id, kStringDoor,kStringDefaultDescription,DOOR,EXIT|OPENABLE,2,2,11,OFFICE_L,0);
3648 	_objectState[4] = Object(_id, kStringLamp2,kStringDefaultDescription,LAMP,COMBINABLE,3,3,0);
3649 	_objectState[5] = Object(_id, kStringAxacussan,kStringDefaultDescription,GUARDIAN,TALK,5,5,0);
3650 	_objectState[6] = Object(_id, kStringImage,kStringGenericDescription5,NULLOBJECT,NULLTYPE,4,4,0);
3651 }
3652 
interact(Action verb,Object & obj1,Object & obj2)3653 bool AxacussExit::interact(Action verb, Object &obj1, Object &obj2) {
3654 	byte rowsX[6] = {1, 1, 1, 0, 0, 0};
3655 
3656 	if (((verb == ACTION_WALK) || (verb == ACTION_OPEN)) && (obj1._id == DOOR) && !_gm->_state._powerOff)
3657 		_gm->guard3Shot();
3658 	else if ((verb == ACTION_TALK) && (obj1._id == GUARDIAN)) {
3659 		_gm->dialog(3, rowsX, _dialogsX,0);
3660 		_gm->guard3Shot();
3661 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, LAMP, MAGNET)) {
3662 		_gm->_inventory.remove(*_gm->_rooms[CELL]->getObject(7));
3663 		for (int i = 4; i <= 11; i++) {
3664 			_vm->renderImage(i);
3665 			if (i == 11)
3666 				_vm->playSound(kAudioSmash); // 046/4020
3667 			_gm->wait(1);
3668 			_vm->renderImage(i + kSectionInvert);
3669 		}
3670 		_gm->_state._powerOff = true;
3671 		_objectState[5]._click = 255;
3672 
3673 		_gm->search(450);
3674 		_gm->roomBrightness();
3675 	} else if ((verb == ACTION_USE) && (Object::combine(obj1,obj2,MAGNET,GUARDIAN) || Object::combine(obj1,obj2,KNIFE,GUARDIAN)))
3676 		_vm->renderMessage(kStringArsanoEntrance27);
3677 	else
3678 		return false;
3679 
3680 	return true;
3681 }
3682 
AxacussOffice1(SupernovaEngine * vm,GameManager1 * gm)3683 AxacussOffice1::AxacussOffice1(SupernovaEngine *vm, GameManager1 *gm) {
3684 	_vm = vm;
3685 	_gm = gm;
3686 
3687 	_fileNumber = 7;
3688 	_id = OFFICE_L1;
3689 	_shown[0] = kShownTrue;
3690 	_shown[2] = kShownTrue;
3691 	_shown[7] = kShownTrue;
3692 	_shown[9] = kShownTrue;
3693 	_shown[16] = kShownTrue;
3694 
3695 	_objectState[0] = Object(_id, kStringDoor,kStringDefaultDescription,DOOR,EXIT|OPENABLE|OPENED,6,6,9,BCORRIDOR,9);
3696 	_objectState[1] = Object(_id, kStringComputer,kStringDefaultDescription,COMPUTER,COMBINABLE,4,4,0);
3697 	_objectState[2] = Object(_id, kStringMoney,kStringMoneyDescription1,MONEY,TAKE,255,255,0);
3698 	_objectState[3] = Object(_id, kStringLocker,kStringLockerDescription,LOCKER,OPENABLE|CLOSED,5,5,0);
3699 	_objectState[4] = Object(_id, kStringLetter,kStringDefaultDescription,LETTER,UNNECESSARY,3,3,0);
3700 }
3701 
interact(Action verb,Object & obj1,Object & obj2)3702 bool AxacussOffice1::interact(Action verb, Object &obj1, Object &obj2) {
3703 	Common::String input;
3704 	if ((verb == ACTION_CLOSE) && (obj1._id == DOOR) &&
3705 			obj1.hasProperty(OPENED)) {
3706 		_vm->renderImage(_gm->invertSection(9));
3707 		obj1.disableProperty(OPENED);
3708 		obj1.setProperty(CLOSED);
3709 		_vm->playSound(kAudioDoorClose);
3710 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, MASTERKEYCARD, DOOR) &&
3711 			   !getObject(0)->hasProperty(OPENED)) {
3712 		_vm->renderImage(9);
3713 		getObject(0)->disableProperty(CLOSED);
3714 		getObject(0)->setProperty(OPENED);
3715 		_vm->playSound(kAudioDoorOpen);
3716 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, COMPUTER, MAGNET)) {
3717 		_vm->renderImage(4);
3718 		setSectionVisible(16, false);
3719 		_vm->playSound(kAudioSmash);
3720 	} else if ((verb == ACTION_LOOK) && (obj1._id == COMPUTER)) {
3721 		if (isSectionVisible(4))
3722 			_vm->renderMessage(kStringBroken);
3723 		else
3724 			_gm->telomat(0);
3725 	} else if (((verb == ACTION_OPEN) || (verb == ACTION_USE)) &&
3726 			   (obj1._id == LOCKER) &&
3727 			   !obj1.hasProperty(OPENED)) {
3728 		_vm->renderMessage(kStringAxacussOffice1_1);
3729 		_vm->renderBox(160, 70, 70, 10, kColorDarkBlue);
3730 		_gm->edit(input, 161, 71, 10);
3731 
3732 		_vm->removeMessage();
3733 		if (_gm->_key.keycode != Common::KEYCODE_ESCAPE) {
3734 			if (!input.equals("89814")) {
3735 				if (input.equals("41898"))
3736 					_vm->renderMessage(kStringAxacussOffice1_2);
3737 				else
3738 					_vm->renderMessage(kStringAxacussOffice1_3);
3739 			} else {
3740 				_vm->renderImage(6);
3741 				setSectionVisible(7, false);
3742 				obj1.resetProperty(OPENABLE | OPENED);
3743 				if (getObject(2)->hasProperty(TAKE)) {
3744 					_vm->renderImage(8);
3745 					getObject(2)->_click = 9;
3746 				}
3747 				_vm->playSound(kAudioDoorOpen);
3748 				_gm->great(7);
3749 			}
3750 		}
3751 	} else if ((verb == ACTION_CLOSE) && (obj1._id == LOCKER) && obj1.hasProperty(OPENED)) {
3752 		_vm->renderImage(7);
3753 		setSectionVisible(6, false);
3754 		obj1.resetProperty(OPENABLE | CLOSED);
3755 		setSectionVisible(8, false);
3756 		getObject(2)->_click = 255;
3757 		_vm->playSound(kAudioDoorClose);
3758 	} else if ((verb == ACTION_TAKE) && (obj1._id == MONEY)) {
3759 		_vm->renderImage(6);
3760 		setSectionVisible(8, false);
3761 		getObject(2)->_click = 255;
3762 		getObject(2)->resetProperty();
3763 		_gm->takeMoney(500);
3764 	} else if ((verb == ACTION_LOOK) && (obj1._id == LETTER)) {
3765 		g_system->fillScreen(kColorBlack);
3766 		_vm->renderText(kStringAxacussOffice1_4, 10, 10, 4);
3767 		_vm->renderText(kStringAxacussOffice1_5, 270, 10, 4);
3768 		_vm->renderText(kStringAxacussOffice1_6, 10, 60, 4);
3769 		_vm->renderText(kStringAxacussOffice1_7, 10, 75, 4);
3770 		_vm->renderText(kStringAxacussOffice1_8, 10, 86, 4);
3771 		_vm->renderText(kStringAxacussOffice1_9, 10, 97, 4);
3772 		_vm->renderText(kStringAxacussOffice1_10, 10, 108, 4);
3773 		_vm->renderText(kStringAxacussOffice1_11, 10, 119, 4);
3774 		_vm->renderText(kStringAxacussOffice1_12, 10, 130, 4);
3775 		_vm->renderText(kStringAxacussOffice1_13, 10, 147, 4);
3776 		_vm->renderText(kStringAxacussOffice1_14, 200, 170, 4);
3777 		_vm->renderText(kStringAxacussOffice1_15, 200, 181, 4);
3778 		_gm->getInput();
3779 		g_system->fillScreen(kColorBlack);
3780 		_vm->renderMessage(kStringAxacussOffice1_16);
3781 	} else
3782 		return false;
3783 
3784 	return true;
3785 }
3786 
AxacussOffice2(SupernovaEngine * vm,GameManager1 * gm)3787 AxacussOffice2::AxacussOffice2(SupernovaEngine *vm, GameManager1 *gm) {
3788 	_vm = vm;
3789 	_gm = gm;
3790 
3791 	_fileNumber = 7;
3792 	_id = OFFICE_L2;
3793 	_shown[0] = kShownTrue;
3794 	_shown[1] = kShownTrue;
3795 	_shown[9] = kShownTrue;
3796 	_shown[16] = kShownTrue;
3797 
3798 	_objectState[0] = Object(_id, kStringDoor,kStringDefaultDescription,DOOR,EXIT|OPENABLE|OPENED,6,6,9,BCORRIDOR,9);
3799 	_objectState[1] = Object(_id, kStringComputer,kStringDefaultDescription,COMPUTER,COMBINABLE,4,4,0);
3800 	_objectState[2] = Object(_id, kStringCube,kStringGenericDescription6,NULLOBJECT,NULLTYPE,0,0,0);
3801 	_objectState[3] = Object(_id, kStringImage,kStringGenericDescription7,NULLOBJECT,NULLTYPE,1,1,0);
3802 	_objectState[4] = Object(_id, kStringStrangeThing,kStringGenericDescription8,NULLOBJECT,UNNECESSARY,2,2,0);
3803 }
3804 
interact(Action verb,Object & obj1,Object & obj2)3805 bool AxacussOffice2::interact(Action verb, Object &obj1, Object &obj2) {
3806 	if ((verb == ACTION_CLOSE) && (obj1._id == DOOR) &&
3807 			obj1.hasProperty(OPENED)) {
3808 		_vm->renderImage(_gm->invertSection(9));
3809 		obj1.disableProperty(OPENED);
3810 		obj1.setProperty(CLOSED);
3811 		_vm->playSound(kAudioDoorClose);
3812 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, MASTERKEYCARD, DOOR) && !getObject(0)->hasProperty(OPENED)) {
3813 		_vm->renderImage(9);
3814 		getObject(0)->disableProperty(CLOSED);
3815 		getObject(0)->setProperty(OPENED);
3816 		_vm->playSound(kAudioDoorOpen);
3817 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, COMPUTER, MAGNET)) {
3818 		_vm->renderImage(4);
3819 		setSectionVisible(16, false);
3820 		_vm->playSound(kAudioSmash);
3821 	} else if ((verb == ACTION_LOOK) && (obj1._id == COMPUTER)) {
3822 		if (isSectionVisible(4))
3823 			_vm->renderMessage(kStringBroken);
3824 		else
3825 			_gm->telomat(1);
3826 	} else
3827 		return false;
3828 
3829 	return true;
3830 }
3831 
AxacussOffice3(SupernovaEngine * vm,GameManager1 * gm)3832 AxacussOffice3::AxacussOffice3(SupernovaEngine *vm, GameManager1 *gm) {
3833 	_vm = vm;
3834 	_gm = gm;
3835 
3836 	_fileNumber = 8;
3837 	_id = OFFICE_R1;
3838 	_shown[0] = kShownTrue;
3839 	_shown[1] = kShownTrue;
3840 	_shown[3] = kShownTrue;
3841 
3842 	_objectState[0] = Object(_id, kStringDoor,kStringDefaultDescription,DOOR,EXIT|OPENABLE|OPENED,0,0,3,BCORRIDOR,5);
3843 	_objectState[1] = Object(_id, kStringComputer,kStringDefaultDescription,COMPUTER,COMBINABLE,4,4,0);
3844 	_objectState[2] = Object(_id, kStringImage,kStringImageDescription2,NULLOBJECT,UNNECESSARY,1,1,0);
3845 	_objectState[3] = Object(_id, kStringImage,kStringImageDescription2,PAINTING,UNNECESSARY,2,2,0);
3846 	_objectState[4] = Object(_id, kStringPlant,kStringDefaultDescription,NULLOBJECT,UNNECESSARY,3,3,0);
3847 	_objectState[5] = Object(_id, kNoString,kStringDefaultDescription,MONEY,TAKE|COMBINABLE,255,255,0);
3848 }
3849 
interact(Action verb,Object & obj1,Object & obj2)3850 bool AxacussOffice3::interact(Action verb, Object &obj1, Object &obj2) {
3851 	if ((verb == ACTION_CLOSE) && (obj1._id == DOOR) &&
3852 			obj1.hasProperty(OPENED)) {
3853 		_vm->renderImage(_gm->invertSection(3));
3854 		obj1.disableProperty(OPENED);
3855 		obj1.setProperty(CLOSED);
3856 		_vm->playSound(kAudioDoorClose);
3857 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, MASTERKEYCARD, DOOR) &&
3858 			   !getObject(0)->hasProperty(OPENED)) {
3859 		_vm->renderImage(3);
3860 		getObject(0)->disableProperty(CLOSED);
3861 		getObject(0)->setProperty(OPENED);
3862 		_vm->playSound(kAudioDoorOpen);
3863 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, COMPUTER, MAGNET)) {
3864 		_vm->renderImage(4);
3865 		_vm->playSound(kAudioSmash);
3866 	} else if ((verb == ACTION_LOOK) && (obj1._id == COMPUTER)) {
3867 		if (isSectionVisible(4))
3868 			_vm->renderMessage(kStringBroken);
3869 		else
3870 			_gm->telomat(2);
3871 	} else if ((verb == ACTION_LOOK) && (obj1._id == PAINTING)) {
3872 		_vm->renderMessage(kStringAxacussOffice3_1);
3873 		_gm->takeMoney(300);
3874 		obj1._id = NULLOBJECT;
3875 	} else
3876 		return false;
3877 
3878 	return true;
3879 }
3880 
AxacussOffice4(SupernovaEngine * vm,GameManager1 * gm)3881 AxacussOffice4::AxacussOffice4(SupernovaEngine *vm, GameManager1 *gm) {
3882 	_vm = vm;
3883 	_gm = gm;
3884 
3885 	_fileNumber = 8;
3886 	_id = OFFICE_R2;
3887 	_shown[0] = kShownTrue;
3888 	_shown[2] = kShownTrue;
3889 	_shown[3] = kShownTrue;
3890 
3891 	_objectState[0] = Object(_id, kStringDoor,kStringDefaultDescription,DOOR,EXIT|OPENABLE|OPENED,0,0,3,BCORRIDOR,5);
3892 	_objectState[1] = Object(_id, kStringComputer,kStringDefaultDescription,COMPUTER,COMBINABLE,4,4,0);
3893 	_objectState[2] = Object(_id, kStringStatue,kStringStatueDescription,NULLOBJECT,UNNECESSARY,6,6,0);
3894 	_objectState[3] = Object(_id, kStringPlant,kStringPlantDescription,NULLOBJECT,UNNECESSARY,5,5,0);
3895 }
3896 
interact(Action verb,Object & obj1,Object & obj2)3897 bool AxacussOffice4::interact(Action verb, Object &obj1, Object &obj2) {
3898 	if ((verb == ACTION_CLOSE) && (obj1._id == DOOR) && obj1.hasProperty(OPENED)) {
3899 		_vm->renderImage(_gm->invertSection(3));
3900 		obj1.disableProperty(OPENED);
3901 		obj1.setProperty(CLOSED);
3902 		_vm->playSound(kAudioDoorClose);
3903 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, MASTERKEYCARD, DOOR) &&
3904 			   !getObject(0)->hasProperty(OPENED)) {
3905 		_vm->renderImage(3);
3906 		getObject(0)->disableProperty(CLOSED);
3907 		getObject(0)->setProperty(OPENED);
3908 		_vm->playSound(kAudioDoorOpen);
3909 	} else if ((verb == ACTION_USE) && Object::combine(obj1, obj2, COMPUTER, MAGNET)) {
3910 		_vm->renderImage(4);
3911 		_vm->playSound(kAudioSmash);
3912 	} else if ((verb == ACTION_LOOK) && (obj1._id == COMPUTER)) {
3913 		if (isSectionVisible(4))
3914 			_vm->renderMessage(kStringBroken);
3915 		else
3916 			_gm->telomat(3);
3917 	} else
3918 		return false;
3919 
3920 	return true;
3921 }
3922 
AxacussOffice5(SupernovaEngine * vm,GameManager1 * gm)3923 AxacussOffice5::AxacussOffice5(SupernovaEngine *vm, GameManager1 *gm) {
3924 	_vm = vm;
3925 	_gm = gm;
3926 
3927 	_fileNumber = 7;
3928 	_id = OFFICE_L;
3929 	_shown[0] = kShownTrue;
3930 	_shown[3] = kShownTrue;
3931 	_shown[5] = kShownTrue;
3932 	_shown[17] = kShownTrue;
3933 
3934 	_objectState[0] = Object(_id, kStringDoor,kStringDefaultDescription,DOOR,EXIT|OPENABLE|OPENED,6,6,17,GUARD3,9);
3935 	_objectState[1] = Object(_id, kStringComputer,kStringComputerDescription,COMPUTER,COMBINABLE,4,4,0);
3936 	_objectState[2] = Object(_id, kStringGraffiti,kStringGraffitiDescription,NULLOBJECT,NULLTYPE,7,7,0);
3937 	_objectState[3] = Object(_id, kStringMoney,kStringMoneyDescription2,MONEY,TAKE,8,8,0);
3938 }
3939 
onEntrance()3940 void AxacussOffice5::onEntrance() {
3941 	_gm->great(5);
3942 }
3943 
interact(Action verb,Object & obj1,Object & obj2)3944 bool AxacussOffice5::interact(Action verb, Object &obj1, Object &obj2) {
3945 	if ((verb == ACTION_USE) && Object::combine(obj1, obj2, COMPUTER, MAGNET)) {
3946 		_vm->renderImage(4);
3947 		_vm->playSound(kAudioSmash);
3948 	} else if ((verb == ACTION_TAKE) && (obj1._id == MONEY)) {
3949 		_vm->renderImage(_gm->invertSection(5));
3950 		obj1._click = 255;
3951 		_gm->takeMoney(350);
3952 	} else
3953 		return false;
3954 
3955 	return true;
3956 }
3957 
AxacussElevator(SupernovaEngine * vm,GameManager1 * gm)3958 AxacussElevator::AxacussElevator(SupernovaEngine *vm, GameManager1 *gm) {
3959 	_vm = vm;
3960 	_gm = gm;
3961 
3962 	_fileNumber = 3;
3963 	_id = ELEVATOR;
3964 	_shown[0] = kShownTrue;
3965 
3966 	_objectState[0] = Object(_id, kStringButton,kStringDefaultDescription,BUTTON1,PRESS,0,0,0);
3967 	_objectState[1] = Object(_id, kStringButton,kStringDefaultDescription,BUTTON2,PRESS,1,1,0);
3968 	_objectState[2] = Object(_id, kStringExit,kStringDefaultDescription,DOOR,EXIT,255,255,0,NULLROOM,22);
3969 	_objectState[3] = Object(_id, kStringJungle,kStringJungleDescription,JUNGLE,NULLTYPE,255,255,0,STATION,2);
3970 }
3971 
interact(Action verb,Object & obj1,Object & obj2)3972 bool AxacussElevator::interact(Action verb, Object &obj1, Object &obj2) {
3973 	if ((verb == ACTION_WALK) && (obj1._id == DOOR)) {
3974 		g_system->fillScreen(kColorBlack);
3975 		_vm->setCurrentImage(41);
3976 		_vm->renderImage(0);
3977 		_vm->paletteBrightness();
3978 		_gm->reply(kStringAxacussElevator_1, 1, 1 + kSectionInvert);
3979 		_gm->say(kStringAxacussElevator_2);
3980 		g_system->fillScreen(kColorBlack);
3981 	} else if ((verb == ACTION_PRESS) && (obj1._id == BUTTON1)) {
3982 		if (!isSectionVisible(3)) {
3983 			_vm->renderImage(1);
3984 			getObject(2)->resetProperty();
3985 			_vm->playSound(kAudioSlideDoor);
3986 			_gm->wait(25);
3987 			for (int i = 3; i <= 7; i++) {
3988 				_gm->wait(2);
3989 				_vm->renderImage(i);
3990 			}
3991 			getObject(3)->resetProperty(EXIT);
3992 			getObject(3)->_click = 2;
3993 			_vm->renderImage(_gm->invertSection(1));
3994 			if (!(_gm->_state._greatFlag & 0x4000)) {
3995 				_vm->playSound(kAudioFoundLocation);
3996 				_gm->_state._greatFlag |= 0x4000;
3997 			}
3998 		}
3999 	} else if ((verb == ACTION_PRESS) && (obj1._id == BUTTON2)) {
4000 		if (isSectionVisible(3)) {
4001 			_vm->renderImage(2);
4002 			getObject(3)->resetProperty();
4003 			getObject(3)->_click = 255;
4004 			_vm->playSound(kAudioSlideDoor);
4005 			for (int i = 7; i >= 3; i--) {
4006 				_gm->wait(2);
4007 				_vm->renderImage(_gm->invertSection(i));
4008 			}
4009 			_gm->wait(25);
4010 			_vm->playSound(kAudioSlideDoor);
4011 			getObject(2)->resetProperty(EXIT);
4012 			_vm->renderImage(_gm->invertSection(2));
4013 		}
4014 	} else if ((verb == ACTION_WALK) && (obj1._id == JUNGLE)) {
4015 		_vm->paletteFadeOut();
4016 		g_system->fillScreen(kColorBlack);
4017 		_vm->_screen->setGuiBrightness(255);
4018 		_vm->paletteBrightness();
4019 		_vm->renderMessage(kStringAxacussElevator_3);
4020 		_gm->wait(_gm->_messageDuration, true);
4021 		_vm->removeMessage();
4022 		_vm->_screen->setGuiBrightness(0);
4023 		_vm->paletteBrightness();
4024 		_gm->_time += ticksToMsec(125000); // 2 hours
4025 		_gm->_state._alarmOn = (_gm->_state._timeAlarm > _gm->_time);
4026 		return false;
4027 	} else
4028 		return false;
4029 
4030 	return true;
4031 }
4032 
AxacussStation(SupernovaEngine * vm,GameManager1 * gm)4033 AxacussStation::AxacussStation(SupernovaEngine *vm, GameManager1 *gm) {
4034 	_vm = vm;
4035 	_gm = gm;
4036 
4037 	_fileNumber = 5;
4038 	_id = STATION;
4039 	_shown[0] = kShownTrue;
4040 	_objectState[0] = Object(_id, kStringSign,kStringDefaultDescription,STATION_SIGN,NULLTYPE,0,0,0);
4041 	_objectState[1] = Object(_id, kStringDoor,kStringDefaultDescription,DOOR,EXIT|OPENABLE|CLOSED,1,1,0,NULLROOM,7);
4042 }
4043 
interact(Action verb,Object & obj1,Object & obj2)4044 bool AxacussStation::interact(Action verb, Object &obj1, Object &obj2) {
4045 	if ((verb == ACTION_LOOK) && (obj1._id == STATION_SIGN)) {
4046 		_gm->changeRoom(SIGN_ROOM);
4047 	} else if ((verb == ACTION_WALK) && (obj1._id == DOOR) && obj1.hasProperty(OPENED)) {
4048 		_gm->great(0);
4049 		_gm->_guiEnabled = false;
4050 		_vm->paletteFadeOut();
4051 		_vm->_system->fillScreen(kColorBlack);
4052 		_gm->changeRoom(OUTRO);
4053 	} else
4054 		return false;
4055 
4056 	return true;
4057 }
4058 
AxacussSign(SupernovaEngine * vm,GameManager1 * gm)4059 AxacussSign::AxacussSign(SupernovaEngine *vm, GameManager1 *gm) {
4060 	_vm = vm;
4061 	_gm = gm;
4062 
4063 	_fileNumber = 32;
4064 	_id = SIGN_ROOM;
4065 	_shown[0] = kShownTrue;
4066 	_shown[1] = kShownTrue;
4067 
4068 	_objectState[0] = Object(_id, kStringExit,kStringDefaultDescription,NULLOBJECT,EXIT,255,255,0,STATION,22);
4069 	_objectState[1] = Object(_id, kStringSlot,kStringDefaultDescription,STATION_SLOT,COMBINABLE,0,0,0);
4070 }
4071 
interact(Action verb,Object & obj1,Object & obj2)4072 bool AxacussSign::interact(Action verb, Object &obj1, Object &obj2) {
4073 	if ((verb == ACTION_USE) && Object::combine(obj1, obj2, STATION_SLOT, MONEY) &&
4074 		isSectionVisible(1)) {
4075 		_gm->takeMoney(-180);
4076 		_vm->renderImage(2);
4077 		setSectionVisible(1, false);
4078 		_gm->_state._eventTime = _gm->_time + ticksToMsec(600);
4079 		_gm->_state._eventCallback = kTaxiFn;
4080 		return true;
4081 	}
4082 	return false;
4083 }
4084 
4085 
Outro(SupernovaEngine * vm,GameManager1 * gm)4086 Outro::Outro(SupernovaEngine *vm, GameManager1 *gm) {
4087 	_vm = vm;
4088 	_gm = gm;
4089 
4090 	_fileNumber = -1;
4091 	_id = OUTRO;
4092 	_shown[0] = kShownFalse;
4093 
4094 	_outroText =
4095 		_vm->getGameString(kStringOutro1) + '\1' +
4096 		_vm->getGameString(kStringOutro2) + '\1' +
4097 		_vm->getGameString(kStringOutro3) + '\1' +
4098 		_vm->getGameString(kStringOutro4) + '\1' +
4099 		_vm->getGameString(kStringOutro5) + '\1' +
4100 		_vm->getGameString(kStringOutro6) + '\1' +
4101 		_vm->getGameString(kStringOutro7) + '\1' +
4102 		_vm->getGameString(kStringOutro8) + '\1' +
4103 		_vm->getGameString(kStringOutro9) + '\1' +
4104 		_vm->getGameString(kStringOutro10) + '\1' +
4105 		_vm->getGameString(kStringOutro11) + '\1' +
4106 		_vm->getGameString(kStringOutro12) + '\1' +
4107 		_vm->getGameString(kStringOutro13) + '\1' +
4108 		_vm->getGameString(kStringOutro14) + '\1';
4109 }
4110 
onEntrance()4111 void Outro::onEntrance() {
4112 	_vm->setCurrentImage(35);
4113 	_vm->renderImage(0);
4114 	_vm->renderImage(1);
4115 	_vm->paletteFadeIn();
4116 	_gm->wait(10);
4117 	for (int i = 8; i <= 21; i++) {
4118 		_vm->renderImage(i);
4119 		_gm->wait(2);
4120 		_vm->renderImage(_gm->invertSection(i));
4121 	}
4122 	_gm->wait(18);
4123 	_vm->renderImage(_gm->invertSection(1));
4124 	for (int i = 2; i <= 7; i++) {
4125 		_vm->renderImage(i);
4126 		_gm->wait(3);
4127 		_vm->renderImage(_gm->invertSection(i));
4128 	}
4129 
4130 	_vm->playSound(kMusicOutro);
4131 	Marquee marquee(_vm->_screen, Marquee::kMarqueeOutro, _outroText.c_str());
4132 	while (!_vm->shouldQuit()) {
4133 		_gm->updateEvents();
4134 		marquee.renderCharacter();
4135 		if (_gm->_mouseClicked || _gm->_keyPressed)
4136 			break;
4137 		g_system->updateScreen();
4138 		g_system->delayMillis(_vm->_delay);
4139 	}
4140 	_vm->paletteFadeOut();
4141 	_vm->setCurrentImage(55);
4142 	_vm->renderImage(0);
4143 	_vm->paletteFadeIn();
4144 	_gm->getInput();
4145 	_vm->paletteFadeOut();
4146 	_vm->_screen->setViewportBrightness(1);
4147 
4148 	Common::Event event;
4149 	event.type = Common::EVENT_RETURN_TO_LAUNCHER;
4150 	_vm->getEventManager()->pushEvent(event);
4151 }
4152 
animation()4153 void Outro::animation() {
4154 }
4155 
animate(int filenumber,int section1,int section2,int duration)4156 void Outro::animate(int filenumber, int section1, int section2, int duration) {
4157 	_vm->setCurrentImage(filenumber);
4158 	while (duration) {
4159 		_vm->renderImage(section1);
4160 		_gm->wait(2);
4161 		_vm->renderImage(section2);
4162 		_gm->wait(2);
4163 		--duration;
4164 	}
4165 }
4166 
animate(int filenumber,int section1,int section2,int duration,MessagePosition position,const char * text)4167 void Outro::animate(int filenumber, int section1, int section2, int duration,
4168 					MessagePosition position, const char *text) {
4169 	_vm->renderMessage(text, position);
4170 	int delay = (Common::strnlen(text, 512) + 20) * (10 - duration) * _vm->_textSpeed / 400;
4171 	_vm->setCurrentImage(filenumber);
4172 	while (delay) {
4173 		if (section1)
4174 			_vm->renderImage(section1);
4175 		_gm->wait(2);
4176 		if (section2)
4177 			_vm->renderImage(section2);
4178 		_gm->wait(2);
4179 		--delay;
4180 	}
4181 	_vm->removeMessage();
4182 }
4183 
animate(int filenumber,int section1,int section2,int section3,int section4,int duration,MessagePosition position,const char * text)4184 void Outro::animate(int filenumber, int section1, int section2, int section3, int section4,
4185 					int duration, MessagePosition position, const char *text) {
4186 	_vm->renderMessage(text, position);
4187 	if (duration == 0)
4188 		duration = (Common::strnlen(text, 512) + 20) * _vm->_textSpeed / 40;
4189 
4190 	_vm->setCurrentImage(filenumber);
4191 	while(duration) {
4192 		_vm->renderImage(section1);
4193 		_vm->renderImage(section3);
4194 		_gm->wait(2);
4195 		_vm->renderImage(section2);
4196 		_vm->renderImage(section4);
4197 		_gm->wait(2);
4198 		duration--;
4199 	}
4200 	_vm->removeMessage();
4201 }
4202 
4203 }
4204