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 "startrek/room.h"
24
25 #define OBJECT_MUDD 8
26 #define OBJECT_9 9
27 #define OBJECT_ALIEN_IMAGE 10
28 #define OBJECT_ALIENDV 11
29 #define OBJECT_NORTH_DOOR 12
30 #define OBJECT_REPAIR_TOOL 13
31
32 #define HOTSPOT_SCREEN 0x20
33 #define HOTSPOT_SPHERE 0x21
34 #define HOTSPOT_NORTH_DOOR 0x22
35 #define HOTSPOT_EAST_DOOR 0x23
36
37 namespace StarTrek {
38
39 // BUG-ish: trying to scan the sphere while someone is behind it causes it to scan that
40 // object instead.
41
mudd3Tick1()42 void Room::mudd3Tick1() {
43 playVoc("MUD3LOOP");
44
45 _awayMission->crewDirectionsAfterWalk[OBJECT_REDSHIRT] = DIR_W;
46
47 if (_awayMission->mudd.databaseDestroyed) {
48 loadActorAnim(OBJECT_9, "s4lbpb", 0xa2, 0x9f);
49
50 // FIXME: is this supposed to be in this if statement?
51 if (!_awayMission->mudd.tookRepairTool)
52 loadActorAnim(OBJECT_REPAIR_TOOL, "s4lbdv", 0xb7, 0xa8);
53 }
54
55 _awayMission->mudd.muddInDatabaseRoom = false;
56
57 if (!_awayMission->mudd.muddVisitedDatabaseRoom && _awayMission->mudd.translatedAlienLanguage && !_awayMission->mudd.muddUnavailable) {
58 _awayMission->mudd.muddVisitedDatabaseRoom = true;
59 loadActorAnim(OBJECT_MUDD, "s4lbhs", 0xa2, 0x9f);
60 playMidiMusicTracks(3);
61 _awayMission->mudd.muddInDatabaseRoom = true;
62 _awayMission->timers[2] = 10;
63 }
64 }
65
mudd3UseCommunicator()66 void Room::mudd3UseCommunicator() {
67 showText(TX_SPEAKER_KIRK, TX_MUD3_003);
68 showText(TX_SPEAKER_UHURA, TX_STATICU1);
69 }
70
mudd3LookAtScreen()71 void Room::mudd3LookAtScreen() {
72 // BUGFIX: the condition was flipped in the original; the more "vague" description
73 // should be shown before the alien language is understood.
74 if (_awayMission->mudd.translatedAlienLanguage)
75 showText(TX_SPEAKER_SPOCK, TX_MUD3_038);
76 else
77 showDescription(TX_MUD3N017);
78 }
79
mudd3UseSTricorderOnScreen()80 void Room::mudd3UseSTricorderOnScreen() {
81 if (_roomVar.mudd.tricordersUnavailable)
82 showText(TX_SPEAKER_SPOCK, TX_MUD3_039);
83 else
84 spockScan(DIR_S, TX_MUD3_017, false);
85 }
86
87 // BUGFIX: Event was actually "use screen on kirk", which makes no sense.
mudd3UseKirkOnScreen()88 void Room::mudd3UseKirkOnScreen() {
89 if (!_awayMission->mudd.translatedAlienLanguage) {
90 showDescription(TX_MUD3N011);
91 showText(TX_SPEAKER_SPOCK, TX_MUD3_037);
92 }
93 }
94
mudd3UseSpockOnSphere()95 void Room::mudd3UseSpockOnSphere() {
96 _awayMission->crewDirectionsAfterWalk[OBJECT_SPOCK] = DIR_S;
97 loadActorStandAnim(OBJECT_SPOCK);
98
99 if (_awayMission->mudd.computerDataErasedOrDestroyed) {
100 if (!_awayMission->mudd.databaseDestroyed) {
101 showDescription(TX_MUD3N000);
102 showText(TX_SPEAKER_SPOCK, TX_MUD3_052);
103 showText(TX_SPEAKER_KIRK, TX_MUD3_012);
104 showText(TX_SPEAKER_MCCOY, TX_MUD3_024);
105 }
106 showText(TX_SPEAKER_KIRK, TX_MUD3_006);
107 showText(TX_SPEAKER_SPOCK, TX_MUD3_048);
108 showText(TX_SPEAKER_KIRK, TX_MUD3_008);
109 showText(TX_SPEAKER_SPOCK, TX_MUD3_051);
110 } else if (_awayMission->mudd.translatedAlienLanguage) {
111 if (_awayMission->mudd.accessedAlienDatabase)
112 showText(TX_SPEAKER_SPOCK, TX_MUD3_035);
113 else {
114 _awayMission->mudd.accessedAlienDatabase = true;
115
116 showText(TX_SPEAKER_SPOCK, TX_MUD3_054);
117 showText(TX_SPEAKER_MCCOY, TX_MUD3_032);
118 showText(TX_SPEAKER_SPOCK, TX_MUD3_050);
119 showText(TX_SPEAKER_SPOCK, TX_MUD3_049);
120 showText(TX_SPEAKER_SPOCK, TX_MUD3_046);
121 showText(TX_SPEAKER_KIRK, TX_MUD3_007);
122
123 _awayMission->mudd.missionScore++;
124 playVoc("LSHAIANS");
125 loadActorAnim(OBJECT_ALIEN_IMAGE, "s4lbap", 0x32, 0x64);
126
127 _awayMission->crewDirectionsAfterWalk[OBJECT_KIRK] = DIR_W;
128 _awayMission->crewDirectionsAfterWalk[OBJECT_SPOCK] = DIR_W;
129 _awayMission->crewDirectionsAfterWalk[OBJECT_MCCOY] = DIR_W;
130 _awayMission->crewDirectionsAfterWalk[OBJECT_REDSHIRT] = DIR_W;
131 loadActorStandAnim(OBJECT_KIRK);
132 loadActorStandAnim(OBJECT_SPOCK);
133 loadActorStandAnim(OBJECT_MCCOY);
134 loadActorStandAnim(OBJECT_REDSHIRT);
135
136 _awayMission->disableInput = true;
137 _awayMission->timers[3] = 40;
138 }
139 } else if (_awayMission->mudd.discoveredBase3System) {
140 showText(TX_SPEAKER_SPOCK, TX_MUD3_043);
141 showText(TX_SPEAKER_MCCOY, TX_MUD3_022);
142 showText(TX_SPEAKER_SPOCK, TX_MUD3_056);
143 showText(TX_SPEAKER_KIRK, TX_MUD3_015);
144 showText(TX_SPEAKER_SPOCK, TX_MUD3_047);
145 _roomVar.mudd.suggestedUsingTricorders = true;
146 } else {
147 showText(TX_SPEAKER_SPOCK, TX_MUD3_044);
148 _awayMission->crewDirectionsAfterWalk[OBJECT_SPOCK] = DIR_W;
149 walkCrewman(OBJECT_SPOCK, 0xcd, 0x87);
150 }
151 }
152
153 // Finished looking at alien image
mudd3Timer3Expired()154 void Room::mudd3Timer3Expired() {
155 _awayMission->disableInput = false;
156
157 showText(TX_SPEAKER_MCCOY, TX_MUD3_027);
158 showText(TX_SPEAKER_SPOCK, TX_MUD3_053);
159 showText(TX_SPEAKER_MCCOY, TX_MUD3_028);
160 showText(TX_SPEAKER_MCCOY, TX_MUD3_026);
161 }
162
mudd3UseMccoyOnSphere()163 void Room::mudd3UseMccoyOnSphere() {
164 // ENHANCEMENT: Turn to face south
165 _awayMission->crewDirectionsAfterWalk[OBJECT_MCCOY] = DIR_S;
166 loadActorStandAnim(OBJECT_MCCOY);
167
168 showText(TX_SPEAKER_MCCOY, TX_MUD3_021);
169 _awayMission->crewDirectionsAfterWalk[OBJECT_MCCOY] = DIR_W;
170 walkCrewman(OBJECT_MCCOY, 0xec, 0x84);
171 }
172
mudd3UseRedshirtOnSphere()173 void Room::mudd3UseRedshirtOnSphere() {
174 // ENHANCEMENT: Turn to face south
175 _awayMission->crewDirectionsAfterWalk[OBJECT_REDSHIRT] = DIR_S;
176 loadActorStandAnim(OBJECT_REDSHIRT);
177
178 showText(TX_SPEAKER_BUCHERT, TX_MUD3_068); // BUGFIX: original played McCoy's audio by mistake
179 _awayMission->crewDirectionsAfterWalk[OBJECT_REDSHIRT] = DIR_W;
180 walkCrewman(OBJECT_REDSHIRT, 0xec, 0x84);
181 }
182
mudd3UseMTricorderOnSphere()183 void Room::mudd3UseMTricorderOnSphere() {
184 if (_roomVar.mudd.tricordersUnavailable)
185 showText(TX_SPEAKER_SPOCK, TX_MUD3_039); // BUGFIX: speaker is Spock
186 else {
187 _awayMission->crewDirectionsAfterWalk[OBJECT_MCCOY] = DIR_S;
188 loadActorStandAnim(OBJECT_MCCOY);
189 if (!_awayMission->mudd.translatedAlienLanguage && _roomVar.mudd.suggestedUsingTricorders && _awayMission->mudd.discoveredBase3System) {
190 _awayMission->disableInput = true;
191
192 _awayMission->crewDirectionsAfterWalk[OBJECT_MCCOY] = DIR_S;
193 walkCrewman(OBJECT_MCCOY, 0xac, 0x88);
194 _awayMission->crewDirectionsAfterWalk[OBJECT_SPOCK] = DIR_S;
195 walkCrewmanC(OBJECT_SPOCK, 0xa5, 0x8c, &Room::mudd3ReadyToHookUpTricorders);
196 } else {
197 showText(TX_SPEAKER_MCCOY, TX_MUD3_021);
198 _awayMission->crewDirectionsAfterWalk[OBJECT_MCCOY] = DIR_W;
199 walkCrewman(OBJECT_MCCOY, 0xec, 0x84);
200 }
201 }
202 }
203
mudd3UseSTricorderOnSphere()204 void Room::mudd3UseSTricorderOnSphere() {
205 _awayMission->crewDirectionsAfterWalk[OBJECT_SPOCK] = DIR_S;
206 loadActorStandAnim(OBJECT_SPOCK);
207
208 if (_roomVar.mudd.tricordersUnavailable)
209 showText(TX_SPEAKER_SPOCK, TX_MUD3_039); // BUGFIX: speaker is Spock
210 else if (_awayMission->mudd.translatedAlienLanguage || (_awayMission->mudd.discoveredBase3System && !_roomVar.mudd.suggestedUsingTricorders)) {
211 showText(TX_SPEAKER_SPOCK, TX_MUD3_041);
212 _awayMission->crewDirectionsAfterWalk[OBJECT_SPOCK] = DIR_W;
213 walkCrewman(OBJECT_SPOCK, 0xcd, 0x87);
214 } else if (_awayMission->mudd.discoveredBase3System && _roomVar.mudd.suggestedUsingTricorders) { // Hooking up tricorders
215 _awayMission->disableInput = true;
216 _awayMission->crewDirectionsAfterWalk[OBJECT_MCCOY] = DIR_S;
217 walkCrewmanC(OBJECT_MCCOY, 0xca, 0x88, &Room::mudd3ReadyToHookUpTricorders);
218 } else { // No idea how to access it
219 showText(TX_SPEAKER_SPOCK, TX_MUD3_042);
220 walkCrewman(OBJECT_SPOCK, 0xcd, 0x87);
221 }
222 }
223
mudd3ReadyToHookUpTricorders()224 void Room::mudd3ReadyToHookUpTricorders() {
225 showText(TX_SPEAKER_SPOCK, TX_MUD3_018);
226
227 _roomVar.mudd.tricordersUnavailable = true;
228 _awayMission->timers[1] = 50;
229
230 loadActorAnim2(OBJECT_SPOCK, "sscans");
231 playSoundEffectIndex(SND_TRICORDER);
232 }
233
mudd3Timer1Expired()234 void Room::mudd3Timer1Expired() { // Tricorders ready for use again
235 showText(TX_SPEAKER_SPOCK, TX_MUD3_040);
236 showText(TX_SPEAKER_SPOCK, TX_MUD3_034);
237
238 _awayMission->disableInput = false;
239 _roomVar.mudd.tricordersUnavailable = false;
240 _roomVar.mudd.suggestedUsingTricorders = false;
241 _awayMission->mudd.translatedAlienLanguage = true;
242 _awayMission->mudd.missionScore++;
243
244 _awayMission->crewDirectionsAfterWalk[OBJECT_SPOCK] = DIR_W;
245 _awayMission->crewDirectionsAfterWalk[OBJECT_MCCOY] = DIR_W;
246 walkCrewman(OBJECT_SPOCK, 0xcd, 0x87);
247 walkCrewman(OBJECT_MCCOY, 0xec, 0x84);
248 }
249
250 // Harry Mudd stumbled into the room
mudd3Timer2Expired()251 void Room::mudd3Timer2Expired() {
252 const TextRef choices[] = {
253 TX_SPEAKER_KIRK,
254 TX_MUD3_010,
255 TX_MUD3_009,
256 TX_BLANK
257 };
258
259 _awayMission->mudd.computerDataErasedOrDestroyed = true;
260
261 showText(TX_SPEAKER_MUDD, TX_MUD3_065);
262 int choice = showMultipleTexts(choices);
263
264 if (choice == 0) { // Allow him to access the database (he ends up erasing it)
265 showText(TX_SPEAKER_MUDD, TX_MUD3_066);
266 _awayMission->mudd.muddErasedDatabase = true;
267
268 // ENHANCEMENT: Add a few lines to make it clear that Mudd erased the databanks.
269 // Otherwise, the end of the mission when you confront Mudd doesn't make sense
270 // unless the player happened to try accessing the database again. Also, if you
271 // talk to the crew, they berate him for no apparent reason if this isn't clear.
272 showDescription(TX_MUD3N000);
273 showText(TX_SPEAKER_MCCOY, TX_MUD3_031);
274
275 } else { // Don't allow it (he destroys it by accident)
276 showText(TX_SPEAKER_MUDD, TX_MUD3_064);
277 _awayMission->timers[4] = 98;
278 _awayMission->disableInput = 2;
279 playMidiMusicTracks(26);
280 loadActorAnim(OBJECT_MUDD, "s4lbhb", 0xa2, 0x9f);
281 }
282 }
283
mudd3Timer4Expired()284 void Room::mudd3Timer4Expired() {
285 _awayMission->mudd.databaseDestroyed = true;
286
287 showText(TX_SPEAKER_MUDD, TX_MUD3_063);
288 showText(TX_SPEAKER_MCCOY, TX_MUD3_031);
289
290 _awayMission->disableInput = false;
291 }
292
mudd3UseMemoryDiskOnSphere()293 void Room::mudd3UseMemoryDiskOnSphere() {
294 // ENHANCEMENT: Turn to face south
295 _awayMission->crewDirectionsAfterWalk[OBJECT_KIRK] = DIR_S;
296 loadActorStandAnim(OBJECT_KIRK);
297
298 if (_awayMission->mudd.databaseDestroyed)
299 showDescription(TX_MUD3N014);
300 else if (_awayMission->mudd.translatedAlienLanguage && !_awayMission->mudd.muddErasedDatabase) {
301 showDescription(TX_MUD3N020);
302 if (!_awayMission->mudd.gotPointsForDownloadingData) {
303 _awayMission->mudd.missionScore += 3;
304 _awayMission->mudd.gotPointsForDownloadingData = true;
305 }
306 } else
307 showDescription(TX_MUD3N019);
308 }
309
310
mudd3GetRepairTool()311 void Room::mudd3GetRepairTool() {
312 if (_awayMission->mudd.tookRepairTool)
313 showDescription(TX_MUD3N018); // NOTE: unused, since the object disappears, can't be selected again
314 else {
315 _awayMission->disableInput = true;
316 _awayMission->crewDirectionsAfterWalk[OBJECT_KIRK] = DIR_N;
317 walkCrewmanC(OBJECT_KIRK, 0xba, 0xc1, &Room::mudd3ReachedRepairTool);
318 }
319 }
320
mudd3ReachedRepairTool()321 void Room::mudd3ReachedRepairTool() {
322 _awayMission->crewDirectionsAfterWalk[OBJECT_KIRK] = DIR_N;
323 loadActorAnimC(OBJECT_KIRK, "kusemn", -1, -1, &Room::mudd3PickedUpRepairTool);
324 }
325
mudd3PickedUpRepairTool()326 void Room::mudd3PickedUpRepairTool() {
327 _awayMission->disableInput = false;
328 loadActorStandAnim(OBJECT_REPAIR_TOOL);
329 _awayMission->mudd.tookRepairTool = true;
330 _awayMission->mudd.missionScore++;
331 giveItem(OBJECT_IDOOVER);
332 }
333
mudd3LookAtSphere()334 void Room::mudd3LookAtSphere() {
335 // ENHANCEMENT: Turn to face south
336 _awayMission->crewDirectionsAfterWalk[OBJECT_KIRK] = DIR_S;
337 loadActorStandAnim(OBJECT_KIRK);
338
339 showDescription(TX_MUD3N015);
340 }
341
mudd3WalkToNorthDoor()342 void Room::mudd3WalkToNorthDoor() {
343 _roomVar.mudd.walkingToDoor = true;
344 _awayMission->disableInput = true;
345 walkCrewman(OBJECT_KIRK, 0xb8, 0x70);
346 }
347
mudd3TouchedHotspot0()348 void Room::mudd3TouchedHotspot0() { // Triggers north door
349 if (_roomVar.mudd.walkingToDoor) {
350 playVoc("SMADOOR3");
351 loadActorAnim(OBJECT_NORTH_DOOR, "s4lbdo", 0xba, 0x6f);
352 }
353 }
354
mudd3WalkToEastDoor()355 void Room::mudd3WalkToEastDoor() {
356 _roomVar.mudd.walkingToDoor = true;
357 _awayMission->disableInput = true;
358 walkCrewman(OBJECT_KIRK, 0x121, 0x81);
359 }
360
mudd3TouchedHotspot1()361 void Room::mudd3TouchedHotspot1() {
362 if (_roomVar.mudd.walkingToDoor) {
363 playVoc("SMADOOR3");
364 }
365 }
366
mudd3LookAtKirk()367 void Room::mudd3LookAtKirk() {
368 if (!_awayMission->mudd.muddInDatabaseRoom)
369 showDescription(TX_MUD3N005);
370 else
371 showDescription(TX_MUD3N004);
372 }
373
mudd3LookAtSpock()374 void Room::mudd3LookAtSpock() {
375 if (!_awayMission->mudd.muddInDatabaseRoom)
376 showDescription(TX_MUD3N012);
377 else
378 showDescription(TX_MUD3N002);
379 }
380
mudd3LookAtMccoy()381 void Room::mudd3LookAtMccoy() {
382 if (!_awayMission->mudd.muddInDatabaseRoom)
383 showDescription(TX_MUD3N010);
384 else
385 showDescription(TX_MUD3N009);
386 }
387
mudd3LookAtRedshirt()388 void Room::mudd3LookAtRedshirt() {
389 if (!_awayMission->mudd.muddInDatabaseRoom)
390 showDescription(TX_MUD3N007);
391 else
392 showDescription(TX_MUD3N006);
393 }
394
mudd3LookAtMudd()395 void Room::mudd3LookAtMudd() {
396 showDescription(TX_MUD3N003);
397 }
398
mudd3TalkToKirk()399 void Room::mudd3TalkToKirk() {
400 if (!_awayMission->mudd.muddInDatabaseRoom) {
401 showText(TX_SPEAKER_KIRK, TX_MUD3_014);
402 showText(TX_SPEAKER_SPOCK, TX_MUD3_057);
403 showText(TX_SPEAKER_MCCOY, TX_MUD3_025);
404 } else
405 showText(TX_SPEAKER_KIRK, TX_MUD3_002);
406 }
407
mudd3TalkToSpock()408 void Room::mudd3TalkToSpock() {
409 if (!_awayMission->mudd.muddInDatabaseRoom) {
410 showText(TX_SPEAKER_SPOCK, TX_MUD3_055);
411 showText(TX_SPEAKER_MCCOY, TX_MUD3_033);
412 showText(TX_SPEAKER_KIRK, TX_MUD3_011);
413 } else
414 showText(TX_SPEAKER_SPOCK, TX_MUD3_019);
415 }
416
mudd3TalkToMccoy()417 void Room::mudd3TalkToMccoy() {
418 if (!_awayMission->mudd.muddInDatabaseRoom)
419 showText(TX_SPEAKER_MCCOY, TX_MUD3_023);
420 else {
421 showText(TX_SPEAKER_MCCOY, TX_MUD3_030);
422 showText(TX_SPEAKER_MUDD, TX_MUD3_062);
423 }
424 }
425
mudd3TalkToRedshirt()426 void Room::mudd3TalkToRedshirt() {
427 if (!_awayMission->mudd.muddInDatabaseRoom) {
428 showText(TX_SPEAKER_BUCHERT, TX_MUD3_070);
429 showText(TX_SPEAKER_KIRK, TX_MUD3_016);
430 showText(TX_SPEAKER_BUCHERT, TX_MUD3_071);
431 } else
432 showText(TX_SPEAKER_BUCHERT, TX_MUD3_067);
433 }
434
mudd3TalkToMudd()435 void Room::mudd3TalkToMudd() {
436 // ENHANCEMENT: the 2nd part of the if condition is new; whether he physically
437 // destroys the database or does through software, he should give this reaction.
438 if (_awayMission->mudd.databaseDestroyed || _awayMission->mudd.muddErasedDatabase) {
439 showText(TX_SPEAKER_MUDD, TX_MUD3_060);
440 showText(TX_SPEAKER_MCCOY, TX_MUD3_029);
441 showText(TX_SPEAKER_MUDD, TX_MUD3_061);
442 showText(TX_SPEAKER_KIRK, TX_MUD3_013);
443 showText(TX_SPEAKER_MUDD, TX_MUD3_058);
444 showText(TX_SPEAKER_SPOCK, TX_MUD3C001);
445 showText(TX_SPEAKER_BUCHERT, TX_MUD3_069);
446 showText(TX_SPEAKER_MUDD, TX_MUD3_059);
447 showText(TX_SPEAKER_KIRK, TX_MUD3_005);
448 }
449 }
450
mudd3UseMedkit()451 void Room::mudd3UseMedkit() {
452 showText(TX_SPEAKER_MCCOY, TX_MUD3_020);
453 }
454
455 }
456