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 * Additional copyright for this file:
8 * Copyright (C) 1995 Presto Studios, Inc.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 *
24 */
25
26 #include "buried/avi_frames.h"
27 #include "buried/biochip_right.h"
28 #include "buried/buried.h"
29 #include "buried/gameui.h"
30 #include "buried/graphics.h"
31 #include "buried/invdata.h"
32 #include "buried/inventory_window.h"
33 #include "buried/navarrow.h"
34 #include "buried/resources.h"
35 #include "buried/scene_view.h"
36 #include "buried/sound.h"
37 #include "buried/environ/scene_base.h"
38 #include "buried/environ/scene_common.h"
39
40 #include "common/system.h"
41 #include "graphics/surface.h"
42
43 namespace Buried {
44
45 enum {
46 WAR_GOD_HEAD_TIMER_VALUE = 3000
47 };
48
49 class PlaceCeramicBowl : public SceneBase {
50 public:
51 PlaceCeramicBowl(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
52 int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
53 int timerCallback(Window *viewWindow);
54
55 private:
56 bool _dropped;
57 };
58
PlaceCeramicBowl(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)59 PlaceCeramicBowl::PlaceCeramicBowl(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
60 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
61 _dropped = false;
62 }
63
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)64 int PlaceCeramicBowl::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
65 if (pointLocation.x == -1 && pointLocation.y == -1)
66 return SIC_REJECT;
67
68 if (itemID != kItemCeramicBowl)
69 return SIC_REJECT;
70
71 _staticData.navFrameIndex = 112;
72 viewWindow->invalidateWindow(false);
73 _dropped = true;
74 return SIC_ACCEPT;
75 }
76
timerCallback(Window * viewWindow)77 int PlaceCeramicBowl::timerCallback(Window *viewWindow) {
78 if (_dropped) {
79 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelStatus == 0) {
80 // Play slide death animation
81 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(4);
82
83 // Notify the player of his gruesome death
84 ((SceneViewWindow *)viewWindow)->showDeathScene(11);
85 return SC_DEATH;
86 } else {
87 // Kill the ambient
88 _vm->_sound->setAmbientSound();
89
90 // Jump to the start of the main cavern
91 DestinationScene newDest;
92 newDest.destinationScene.timeZone = 2;
93 newDest.destinationScene.environment = 2;
94 newDest.destinationScene.node = 0;
95 newDest.destinationScene.facing = 1;
96 newDest.destinationScene.orientation = 1;
97 newDest.destinationScene.depth = 0;
98 newDest.transitionType = TRANSITION_VIDEO;
99 newDest.transitionData = 3;
100 newDest.transitionStartFrame = -1;
101 newDest.transitionLength = -1;
102 ((SceneViewWindow *)viewWindow)->moveToDestination(newDest);
103 }
104 }
105
106 return SC_TRUE;
107 }
108
109 class AdjustWheels : public SceneBase {
110 public:
111 AdjustWheels(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
112 void preDestructor();
113 int paint(Window *viewWindow, Graphics::Surface *preBuffer);
114 int gdiPaint(Window *viewWindow);
115 int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
116 int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
117 int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
118
119 private:
120 AVIFrames _leftWheelFrames;
121 int _curLeftFrame;
122 AVIFrames _rightWheelFrames;
123 int _curRightFrame;
124 Common::Rect _leftUpRegion;
125 Common::Rect _leftDownRegion;
126 Common::Rect _rightUpRegion;
127 Common::Rect _rightDownRegion;
128 bool _translateText;
129 };
130
AdjustWheels(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)131 AdjustWheels::AdjustWheels(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
132 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
133 _curLeftFrame = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelLeftIndex;
134 _curRightFrame = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelRightIndex;
135 _leftUpRegion = Common::Rect(46, 0, 200, 70);
136 _leftDownRegion = Common::Rect(46, 106, 200, 189);
137 _rightUpRegion = Common::Rect(212, 0, 432, 66);
138 _rightDownRegion = Common::Rect(212, 109, 432, 189);
139 _translateText = false;
140
141 if (!_leftWheelFrames.open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 9)))
142 error("Failed to open left wheel frames video");
143
144 if (!_rightWheelFrames.open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 10)))
145 error("Failed to open right wheel frames video");
146 }
147
preDestructor()148 void AdjustWheels::preDestructor() {
149 _leftWheelFrames.close();
150 _rightWheelFrames.close();
151 }
152
paint(Window * viewWindow,Graphics::Surface * preBuffer)153 int AdjustWheels::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
154 if (_staticData.navFrameIndex >= 0) {
155 const Graphics::Surface *leftFrame = _leftWheelFrames.getFrame(_curLeftFrame);
156 if (leftFrame)
157 _vm->_gfx->crossBlit(preBuffer, 0, 0, 208, 189, leftFrame, 0, 0);
158
159 const Graphics::Surface *rightFrame = _rightWheelFrames.getFrame(_curRightFrame);
160 if (rightFrame)
161 _vm->_gfx->crossBlit(preBuffer, 208, 0, 224, 189, rightFrame, 0, 0);
162 }
163
164 return SC_REPAINT;
165 }
166
gdiPaint(Window * viewWindow)167 int AdjustWheels::gdiPaint(Window *viewWindow) {
168 if (_translateText && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
169 Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
170 Common::Rect rect(168, 70, 262, 108);
171 rect.translate(absoluteRect.left, absoluteRect.top);
172 _vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
173 }
174
175 return SC_REPAINT;
176 }
177
mouseUp(Window * viewWindow,const Common::Point & pointLocation)178 int AdjustWheels::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
179 // TODO: Wait between frames after figuring out timing
180
181 if (_leftUpRegion.contains(pointLocation) || _leftDownRegion.contains(pointLocation) ||
182 _rightUpRegion.contains(pointLocation) || _rightDownRegion.contains(pointLocation)) {
183 if (_leftDownRegion.contains(pointLocation)) {
184 // Move the wheel one frame and redraw
185 _curLeftFrame++;
186
187 if (_curLeftFrame > _leftWheelFrames.getFrameCount() - 1)
188 _curLeftFrame = 0;
189
190 viewWindow->invalidateWindow(false);
191
192 // And again for the final frame
193 _curLeftFrame++;
194
195 if (_curLeftFrame > _leftWheelFrames.getFrameCount() - 1)
196 _curLeftFrame = 0;
197
198 viewWindow->invalidateWindow(false);
199 } else if (_leftUpRegion.contains(pointLocation)) {
200 // Move the wheel one frame and redraw
201 _curLeftFrame--;
202
203 if (_curLeftFrame < 0)
204 _curLeftFrame = _leftWheelFrames.getFrameCount() - 1;
205
206 viewWindow->invalidateWindow(false);
207
208 // And again for the final frame
209 _curLeftFrame--;
210
211 if (_curLeftFrame < 0)
212 _curLeftFrame = _leftWheelFrames.getFrameCount() - 1;
213
214 viewWindow->invalidateWindow(false);
215 } else if (_rightDownRegion.contains(pointLocation)) {
216 // Move the wheel one frame and redraw
217 _curRightFrame++;
218
219 if (_curRightFrame > _rightWheelFrames.getFrameCount() - 1)
220 _curRightFrame = 0;
221
222 viewWindow->invalidateWindow(false);
223
224 // And again for the final frame
225 _curRightFrame++;
226
227 if (_curRightFrame > _rightWheelFrames.getFrameCount() - 1)
228 _curRightFrame = 0;
229
230 viewWindow->invalidateWindow(false);
231 } else if (_rightUpRegion.contains(pointLocation)) {
232 // Move the wheel one frame and redraw
233 _curRightFrame--;
234
235 if (_curRightFrame < 0)
236 _curRightFrame = _rightWheelFrames.getFrameCount() - 1;
237
238 viewWindow->invalidateWindow(false);
239
240 // And again for the final frame
241 _curRightFrame--;
242
243 if (_curRightFrame < 0)
244 _curRightFrame = _rightWheelFrames.getFrameCount() - 1;
245
246 viewWindow->invalidateWindow(false);
247 }
248
249 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelLeftIndex = _curLeftFrame;
250 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelRightIndex = _curRightFrame;
251
252 byte status = 0;
253 if (_curLeftFrame == 8 && _curRightFrame == 12)
254 status = 1;
255 else if (_curLeftFrame == 16 && _curRightFrame == 22)
256 status = 1;
257 else if (_curLeftFrame == 20 && _curRightFrame == 4)
258 status = 1;
259 else if (_curLeftFrame == 0 && _curRightFrame == 24)
260 status = 1;
261 else if (_curLeftFrame == 14 && _curRightFrame == 8)
262 status = 1;
263 else if (_curLeftFrame == 6 && _curRightFrame == 6)
264 status = 1;
265 else if (_curLeftFrame == 6 && _curRightFrame == 30)
266 status = 1;
267 else if (_curLeftFrame == 24 && _curRightFrame == 0)
268 status = 1;
269 else if (_curLeftFrame == 10 && _curRightFrame == 28)
270 status = 1;
271
272 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelStatus = status;
273
274 return SC_TRUE;
275 }
276
277 // Did not click on the wheels, pop back to depth 0
278 DestinationScene newDest;
279 newDest.destinationScene = _staticData.location;
280 newDest.destinationScene.depth = 0;
281 newDest.transitionType = TRANSITION_NONE;
282 newDest.transitionData = -1;
283 newDest.transitionStartFrame = -1;
284 newDest.transitionLength = -1;
285 ((SceneViewWindow *)viewWindow)->moveToDestination(newDest);
286 return SC_TRUE;
287 }
288
mouseMove(Window * viewWindow,const Common::Point & pointLocation)289 int AdjustWheels::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
290 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
291 Common::Rect translateTextRegion(168, 72, 260, 106);
292
293 if (translateTextRegion.contains(pointLocation)) {
294 if (!_translateText) {
295 Common::String leftText = _vm->getString(IDMYTP_WHEELS_LEFT_TRANS_TEXT_BASE + _curLeftFrame / 2);
296 Common::String rightText = _vm->getString(IDMYTP_WHEELS_RIGHT_TRANS_TEXT_BASE + _curRightFrame / 2);
297 Common::String finalString = leftText + rightText;
298
299 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 &&
300 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCodeWheelStatus == 1) {
301
302 if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0))
303 finalString += _vm->getString(IDS_MYTP_WALKTHROUGH_HINT_TEXT);
304 else
305 finalString += " (Mayan Sacred Day)";
306 }
307
308 ((SceneViewWindow *)viewWindow)->displayTranslationText(finalString);
309 _translateText = true;
310 viewWindow->invalidateWindow(false);
311 }
312 } else {
313 if (_translateText) {
314 _translateText = false;
315 viewWindow->invalidateWindow(false);
316 }
317 }
318
319 return SC_TRUE;
320 }
321
322 return SC_FALSE;
323 }
324
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)325 int AdjustWheels::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
326 if (_leftUpRegion.contains(pointLocation) || _rightUpRegion.contains(pointLocation))
327 return kCursorArrowUp;
328
329 if (_leftDownRegion.contains(pointLocation) || _rightDownRegion.contains(pointLocation))
330 return kCursorArrowDown;
331
332 return kCursorPutDown;
333 }
334
335 class DateCombinationRead : public SceneBase {
336 public:
337 DateCombinationRead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
338 int gdiPaint(Window *viewWindow);
339 int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
340
341 private:
342 int _currentRegion;
343 };
344
DateCombinationRead(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)345 DateCombinationRead::DateCombinationRead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
346 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
347 _currentRegion = -1;
348 }
349
gdiPaint(Window * viewWindow)350 int DateCombinationRead::gdiPaint(Window *viewWindow) {
351 if (_currentRegion >= 0 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
352 Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
353 int left = _currentRegion * 43 + 20 + absoluteRect.left;
354 Common::Rect rect(left, absoluteRect.top + 18, left + 43, absoluteRect.top + 110);
355 _vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
356 }
357
358 return SC_REPAINT;
359 }
360
mouseMove(Window * viewWindow,const Common::Point & pointLocation)361 int DateCombinationRead::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
362 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
363 Common::Rect symbols(20, 18, 407, 110);
364
365 if (symbols.contains(pointLocation)) {
366 int translatedSymbolIndex = (pointLocation.x - 20) / 43;
367
368 if (_currentRegion != translatedSymbolIndex) {
369 // Update flags
370 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPCalendarListTranslated = 1;
371 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myTPTextTranslated = 1;
372
373 // Display the text
374 ((SceneViewWindow *)viewWindow)->displayTranslationText(_vm->getString(IDMYTP_WALLS_COMBO_TRANS_TEXT_BASE + translatedSymbolIndex));
375
376 // Reset the current region and redraw
377 _currentRegion = translatedSymbolIndex;
378 viewWindow->invalidateWindow(false);
379 }
380 } else {
381 if (_currentRegion >= 0) {
382 _currentRegion = -1;
383 viewWindow->invalidateWindow(false);
384 }
385 }
386
387 return SC_TRUE;
388 }
389
390 return SC_FALSE;
391 }
392
393 class ViewSingleTranslation : public SceneBase {
394 public:
395 ViewSingleTranslation(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
396 int translatedTextID = -1, int left = -1, int top = -1, int right = -1, int bottom = -1,
397 int flagAOffset = -1, int flagBOffset = -1, int visitedFlagOffset = -1);
398 int gdiPaint(Window *viewWindow);
399 int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
400 int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
401 int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
402
403 private:
404 bool _textTranslated;
405 int _textID;
406 Common::Rect _clickableRegion;
407 int _flagAOffset;
408 int _flagBOffset;
409 int _visitedFlagOffset;
410 };
411
ViewSingleTranslation(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int translatedTextID,int left,int top,int right,int bottom,int flagAOffset,int flagBOffset,int visitedFlagOffset)412 ViewSingleTranslation::ViewSingleTranslation(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
413 int translatedTextID, int left, int top, int right, int bottom,
414 int flagAOffset, int flagBOffset, int visitedFlagOffset) :
415 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
416 _textTranslated = false;
417 _textID = translatedTextID;
418 _clickableRegion = Common::Rect(left, top, right, bottom);
419 _flagAOffset = flagAOffset;
420 _flagBOffset = flagBOffset;
421 _visitedFlagOffset = visitedFlagOffset;
422
423 if (_visitedFlagOffset >= 0)
424 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_visitedFlagOffset, 1);
425 }
426
gdiPaint(Window * viewWindow)427 int ViewSingleTranslation::gdiPaint(Window *viewWindow) {
428 // Draw the translated box, if applicable
429 if (_textTranslated && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
430 Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
431 Common::Rect rect(_clickableRegion);
432 rect.translate(absoluteRect.left, absoluteRect.top);
433 _vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
434 }
435
436 return SC_REPAINT;
437 }
438
mouseUp(Window * viewWindow,const Common::Point & pointLocation)439 int ViewSingleTranslation::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
440 if (_staticData.location.depth != 0) {
441 // If we're not at depth zero, move to depth zero
442 Location newLocation = _staticData.location;
443 newLocation.depth = 0;
444 ((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
445 return SC_TRUE;
446 }
447
448 return SC_FALSE;
449 }
450
mouseMove(Window * viewWindow,const Common::Point & pointLocation)451 int ViewSingleTranslation::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
452 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
453 if (_clickableRegion.contains(pointLocation)) {
454 // Make sure we didn't already render the text
455 if (!_textTranslated) {
456 if (_flagAOffset >= 0)
457 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagAOffset, 1);
458 if (_flagBOffset >= 0)
459 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(_flagBOffset, 1);
460
461 // Load and display the text
462 ((SceneViewWindow *)viewWindow)->displayTranslationText(_vm->getString(_textID));
463 _textTranslated = true;
464 viewWindow->invalidateWindow(false);
465 }
466 } else {
467 if (_textTranslated) {
468 _textTranslated = false;
469 viewWindow->invalidateWindow(false);
470 }
471 }
472
473 return SC_TRUE;
474 }
475
476 return SC_FALSE;
477 }
478
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)479 int ViewSingleTranslation::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
480 if (_staticData.location.depth != 0)
481 return kCursorPutDown;
482
483 return kCursorArrow;
484 }
485
486 class GenericCavernDoorMainView : public SceneBase {
487 public:
488 GenericCavernDoorMainView(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
489 int topZoomDepth = 0, int topLeft = -1, int topTop = -1, int topRight = -1, int topBottom = -1,
490 int rightZoomDepth = 0, int rightLeft = -1, int rightTop = -1, int rightRight = -1, int rightBottom = -1,
491 int offeringHeadZoomDepth = 0, int offeringHeadLeft = -1, int offeringHeadTop = -1, int offeringHeadRight = -1, int offeringHeadBottom = -1);
492 int postEnterRoom(Window *viewWindow, const Location &priorLocation);
493 int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
494 int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
495
496 private:
497 int _topZoomDepth;
498 int _rightZoomDepth;
499 int _offeringHeadZoomDepth;
500 Common::Rect _topZoomRegion;
501 Common::Rect _rightZoomRegion;
502 Common::Rect _offeringHeadZoomRegion;
503 };
504
GenericCavernDoorMainView(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int topZoomDepth,int topLeft,int topTop,int topRight,int topBottom,int rightZoomDepth,int rightLeft,int rightTop,int rightRight,int rightBottom,int offeringHeadZoomDepth,int offeringHeadLeft,int offeringHeadTop,int offeringHeadRight,int offeringHeadBottom)505 GenericCavernDoorMainView::GenericCavernDoorMainView(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
506 int topZoomDepth, int topLeft, int topTop, int topRight, int topBottom,
507 int rightZoomDepth, int rightLeft, int rightTop, int rightRight, int rightBottom,
508 int offeringHeadZoomDepth, int offeringHeadLeft, int offeringHeadTop, int offeringHeadRight, int offeringHeadBottom) :
509 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
510 _topZoomDepth = topZoomDepth;
511 _rightZoomDepth = rightZoomDepth;
512 _offeringHeadZoomDepth = offeringHeadZoomDepth;
513 _topZoomRegion = Common::Rect(topLeft, topTop, topRight, topBottom);
514 _rightZoomRegion = Common::Rect(rightLeft, rightTop, rightRight, rightBottom);
515 _offeringHeadZoomRegion = Common::Rect(offeringHeadLeft, offeringHeadTop, offeringHeadRight, offeringHeadBottom);
516
517 if (_staticData.location.node == 7)
518 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myMCViewedDeathGodDoor = 1;
519 }
520
postEnterRoom(Window * viewWindow,const Location & priorLocation)521 int GenericCavernDoorMainView::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
522 if (_staticData.location.node == 7 && (_staticData.location.timeZone != priorLocation.timeZone ||
523 _staticData.location.environment != priorLocation.environment || _staticData.location.node != priorLocation.node ||
524 _staticData.location.facing != priorLocation.facing || _staticData.location.orientation != priorLocation.orientation ||
525 _staticData.location.depth != priorLocation.depth) && !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID))
526 ((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
527 return SC_TRUE;
528 }
529
mouseUp(Window * viewWindow,const Common::Point & pointLocation)530 int GenericCavernDoorMainView::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
531 // Build a default structure
532 DestinationScene newDestination;
533 newDestination.destinationScene = _staticData.location;
534 newDestination.transitionType = TRANSITION_FADE;
535 newDestination.transitionData = -1;
536 newDestination.transitionStartFrame = -1;
537 newDestination.transitionLength = -1;
538
539 if (_topZoomRegion.contains(pointLocation)) {
540 newDestination.destinationScene.depth = _topZoomDepth;
541 ((SceneViewWindow *)viewWindow)->moveToDestination(newDestination);
542 return SC_TRUE;
543 }
544
545 if (_rightZoomRegion.contains(pointLocation)) {
546 newDestination.destinationScene.depth = _rightZoomDepth;
547 ((SceneViewWindow *)viewWindow)->moveToDestination(newDestination);
548 return SC_TRUE;
549 }
550
551 if (_offeringHeadZoomRegion.contains(pointLocation)) {
552 newDestination.destinationScene.depth = _offeringHeadZoomDepth;
553 ((SceneViewWindow *)viewWindow)->moveToDestination(newDestination);
554 return SC_TRUE;
555 }
556
557 return SC_FALSE;
558 }
559
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)560 int GenericCavernDoorMainView::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
561 if (_topZoomRegion.contains(pointLocation) || _rightZoomRegion.contains(pointLocation) || _offeringHeadZoomRegion.contains(pointLocation))
562 return kCursorMagnifyingGlass;
563
564 return kCursorArrow;
565 }
566
567 class GenericCavernDoorOfferingHead : public SceneBase {
568 public:
569 GenericCavernDoorOfferingHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
570 int correctOfferingID = -1, int correctOfferingDestDepth = 0, int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1);
571 int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
572 int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
573 int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
574 int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
575
576 private:
577 DestinationScene _correctDestination;
578 int _correctOfferingID;
579 Common::Rect _dropRegion;
580
581 bool isValidItemToDrop(Window *viewWindow, int itemID);
582 };
583
GenericCavernDoorOfferingHead(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int correctOfferingID,int correctOfferingDestDepth,int transitionType,int transitionData,int transitionStartFrame,int transitionLength)584 GenericCavernDoorOfferingHead::GenericCavernDoorOfferingHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
585 int correctOfferingID, int correctOfferingDestDepth, int transitionType, int transitionData, int transitionStartFrame, int transitionLength) :
586 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
587 _correctDestination.destinationScene = _staticData.location;
588 _correctDestination.destinationScene.depth = correctOfferingDestDepth;
589 _correctDestination.transitionType = transitionType;
590 _correctDestination.transitionData = transitionData;
591 _correctDestination.transitionStartFrame = transitionStartFrame;
592 _correctDestination.transitionLength = transitionLength;
593 _correctOfferingID = correctOfferingID;
594 _dropRegion = Common::Rect(24, 92, 226, 154);
595 }
596
draggingItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)597 int GenericCavernDoorOfferingHead::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
598 // If this is walkthrough mode, only accept the correct item
599 if (isValidItemToDrop(viewWindow, itemID) && _dropRegion.contains(pointLocation))
600 return 1;
601
602 return 0;
603 }
604
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)605 int GenericCavernDoorOfferingHead::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
606 if (pointLocation.x == -1 && pointLocation.y == -1)
607 return SIC_REJECT;
608
609 if (!isValidItemToDrop(viewWindow, itemID))
610 return SIC_REJECT;
611
612 if (_dropRegion.contains(pointLocation)) {
613 switch (itemID) {
614 case kItemBalconyKey:
615 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(2);
616 break;
617 case kItemBloodyArrow:
618 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(3);
619 break;
620 case kItemObsidianBlock:
621 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(5);
622 break;
623 case kItemCoilOfRope:
624 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(6);
625 break;
626 case kItemCopperKey:
627 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(7);
628 break;
629 case kItemCopperMedallion:
630 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(8);
631 break;
632 case kItemCeramicBowl:
633 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(9);
634 break;
635 case kItemGrapplingHook:
636 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(10);
637 break;
638 case kItemHammer:
639 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(11);
640 break;
641 case kItemPreservedHeart:
642 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(12);
643 break;
644 case kItemJadeBlock:
645 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(13);
646 break;
647 case kItemLimestoneBlock:
648 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(14);
649 break;
650 case kItemMetalBar:
651 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(15);
652 break;
653 case kItemCavernSkull:
654 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(16);
655 break;
656 case kItemEntrySkull:
657 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(17);
658 break;
659 case kItemSpearSkull:
660 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(18);
661 break;
662 case kItemWaterCanFull:
663 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(19);
664 break;
665 case kItemWoodenPegs:
666 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(20);
667 break;
668 case kItemGoldCoins:
669 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(21);
670 break;
671 }
672
673 // Reset the offering flag
674 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myMCTransMadeAnOffering = 1;
675
676 // If this was the correct offering, move to the open door scene
677 if (itemID == _correctOfferingID) {
678 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 10), 128, false, true);
679 ((SceneViewWindow *)viewWindow)->moveToDestination(_correctDestination);
680 }
681
682 // These items don't get consumed
683 if (itemID == kItemWaterCanFull || itemID == kItemGoldCoins)
684 return SIC_REJECT;
685
686 return SIC_ACCEPT;
687 }
688
689 return SIC_REJECT;
690 }
691
mouseUp(Window * viewWindow,const Common::Point & pointLocation)692 int GenericCavernDoorOfferingHead::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
693 Location newLocation = _staticData.location;
694 newLocation.depth = 0;
695 ((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
696 return SC_TRUE;
697 }
698
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)699 int GenericCavernDoorOfferingHead::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
700 return kCursorPutDown;
701 }
702
isValidItemToDrop(Window * viewWindow,int itemID)703 bool GenericCavernDoorOfferingHead::isValidItemToDrop(Window *viewWindow, int itemID) {
704 // If this is walkthrough mode, only accept the correct item
705 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1) {
706 if (itemID == _correctOfferingID || (_staticData.location.node == 8 && itemID == kItemBloodyArrow))
707 return true;
708
709 return false;
710 }
711
712 // Otherwise, any of the allowed items
713 switch (itemID) {
714 case kItemCavernSkull:
715 case kItemEntrySkull:
716 case kItemSpearSkull:
717 case kItemBloodyArrow:
718 case kItemCopperMedallion:
719 case kItemCoilOfRope:
720 case kItemCopperKey:
721 case kItemJadeBlock:
722 case kItemLimestoneBlock:
723 case kItemObsidianBlock:
724 case kItemGrapplingHook:
725 case kItemPreservedHeart:
726 case kItemHammer:
727 case kItemGoldCoins:
728 case kItemWaterCanEmpty:
729 case kItemWaterCanFull:
730 case kItemWoodenPegs:
731 case kItemBalconyKey:
732 case kItemBurnedLetter: // Can't actually drop this, though
733 return true;
734 }
735
736 return false;
737 }
738
739 class DeathGodCavernDoorOfferingHead : public SceneBase {
740 public:
741 DeathGodCavernDoorOfferingHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
742 int correctOfferingDestDepth = 0, int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1);
743 int preExitRoom(Window *viewWindow, const Location &newLocation);
744 int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
745 int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
746 int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
747 int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
748
749 private:
750 DestinationScene _correctDestination;
751 Common::Rect _dropRegion;
752 };
753
DeathGodCavernDoorOfferingHead(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int correctOfferingDestDepth,int transitionType,int transitionData,int transitionStartFrame,int transitionLength)754 DeathGodCavernDoorOfferingHead::DeathGodCavernDoorOfferingHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
755 int correctOfferingDestDepth, int transitionType, int transitionData, int transitionStartFrame, int transitionLength) :
756 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
757 _correctDestination.destinationScene = _staticData.location;
758 _correctDestination.destinationScene.depth = correctOfferingDestDepth;
759 _correctDestination.transitionType = transitionType;
760 _correctDestination.transitionData = transitionData;
761 _correctDestination.transitionStartFrame = transitionStartFrame;
762 _correctDestination.transitionLength = transitionLength;
763 _dropRegion = Common::Rect(50, 76, 228, 182);
764
765 byte offerings = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myMCDeathGodOfferings;
766
767 if (offerings & 1) {
768 if (offerings & 2) {
769 if (offerings & 4)
770 _staticData.navFrameIndex = 190;
771 else
772 _staticData.navFrameIndex = 189;
773 } else if (offerings & 4) {
774 _staticData.navFrameIndex = 188;
775 } else {
776 _staticData.navFrameIndex = 186;
777 }
778 } else if (offerings & 2) {
779 if (offerings & 4)
780 _staticData.navFrameIndex = 187;
781 else
782 _staticData.navFrameIndex = 185;
783 } else if (offerings & 4) {
784 _staticData.navFrameIndex = 184;
785 }
786 }
787
preExitRoom(Window * viewWindow,const Location & newLocation)788 int DeathGodCavernDoorOfferingHead::preExitRoom(Window *viewWindow, const Location &newLocation) {
789 // Put any pieces placed in the head back in the inventory
790 byte &offerings = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myMCDeathGodOfferings;
791
792 if (offerings & 1)
793 ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->addItem(kItemObsidianBlock);
794 if (offerings & 2)
795 ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->addItem(kItemJadeBlock);
796 if (offerings & 4)
797 ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->addItem(kItemLimestoneBlock);
798
799 offerings = 0;
800 return SC_TRUE;
801 }
802
mouseUp(Window * viewWindow,const Common::Point & pointLocation)803 int DeathGodCavernDoorOfferingHead::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
804 // Return to depth zero
805 DestinationScene newDest;
806 newDest.destinationScene = _staticData.location;
807 newDest.destinationScene.depth = 0;
808 newDest.transitionType = TRANSITION_NONE;
809 newDest.transitionData = -1;
810 newDest.transitionStartFrame = -1;
811 newDest.transitionLength = -1;
812 ((SceneViewWindow *)viewWindow)->moveToDestination(newDest);
813 return SC_TRUE;
814 }
815
draggingItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)816 int DeathGodCavernDoorOfferingHead::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
817 if ((itemID == kItemJadeBlock || itemID == kItemLimestoneBlock || itemID == kItemObsidianBlock) && _dropRegion.contains(pointLocation)) {
818 byte offerings = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myMCDeathGodOfferings;
819
820 if ((offerings & 1) != 0 && itemID == kItemObsidianBlock)
821 return 0;
822 if ((offerings & 2) != 0 && itemID == kItemJadeBlock)
823 return 0;
824 if ((offerings & 4) != 0 && itemID == kItemLimestoneBlock)
825 return 0;
826
827 return 1;
828 }
829
830 return 0;
831 }
832
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)833 int DeathGodCavernDoorOfferingHead::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
834 if (pointLocation.x == -1 && pointLocation.y == -1)
835 return SIC_REJECT;
836
837 if ((itemID == kItemJadeBlock || itemID == kItemLimestoneBlock || itemID == kItemObsidianBlock) && _dropRegion.contains(pointLocation)) {
838 byte &offerings = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myMCDeathGodOfferings;
839
840 // Make sure we didn't already place the item
841 if ((offerings & 1) != 0 && itemID == kItemObsidianBlock)
842 return SIC_REJECT;
843 if ((offerings & 2) != 0 && itemID == kItemJadeBlock)
844 return SIC_REJECT;
845 if ((offerings & 4) != 0 && itemID == kItemLimestoneBlock)
846 return SIC_REJECT;
847
848 // Add the item
849 if (itemID == kItemObsidianBlock)
850 offerings |= 1;
851 else if (itemID == kItemJadeBlock)
852 offerings |= 2;
853 else if (itemID == kItemLimestoneBlock)
854 offerings |= 4;
855
856 // Change the image
857 if (offerings & 1) {
858 if (offerings & 2) {
859 if (offerings & 4)
860 _staticData.navFrameIndex = 190;
861 else
862 _staticData.navFrameIndex = 189;
863 } else if (offerings & 4) {
864 _staticData.navFrameIndex = 188;
865 } else {
866 _staticData.navFrameIndex = 186;
867 }
868 } else if (offerings & 2) {
869 if (offerings & 4)
870 _staticData.navFrameIndex = 187;
871 else
872 _staticData.navFrameIndex = 185;
873 } else if (offerings & 4) {
874 _staticData.navFrameIndex = 184;
875 } else {
876 _staticData.navFrameIndex = 152;
877 }
878
879 viewWindow->invalidateWindow(false);
880
881 if ((offerings & 1) != 0 && (offerings & 2) != 0 && (offerings & 4) != 0) {
882 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 10), 128, false, true);
883 ((SceneViewWindow *)viewWindow)->moveToDestination(_correctDestination);
884 }
885
886 return SIC_ACCEPT;
887 }
888
889 return SIC_REJECT;
890 }
891
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)892 int DeathGodCavernDoorOfferingHead::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
893 return kCursorPutDown;
894 }
895
896 class WealthGodRopeDrop : public SceneBase {
897 public:
898 WealthGodRopeDrop(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
899 int postEnterRoom(Window *viewWindow, const Location &priorLocation);
900 int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
901 int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
902
903 private:
904 Common::Rect _dropRope;
905 };
906
WealthGodRopeDrop(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)907 WealthGodRopeDrop::WealthGodRopeDrop(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
908 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
909 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().myWGPlacedRope == 1)
910 _staticData.navFrameIndex = 121;
911
912 _dropRope = Common::Rect(222, 149, 282, 189);
913 }
914
postEnterRoom(Window * viewWindow,const Location & priorLocation)915 int WealthGodRopeDrop::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
916 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().myWGPlacedRope != 0) {
917 Location newLocation = _staticData.location;
918 newLocation.depth = 1;
919 ((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
920 }
921
922 return SC_TRUE;
923 }
924
draggingItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)925 int WealthGodRopeDrop::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
926 // OK, I honestly didn't know you could use the grappling hook here
927 if (_dropRope.contains(pointLocation) && (itemID == kItemCoilOfRope || itemID == kItemGrapplingHook))
928 return 1;
929
930 return 0;
931 }
932
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)933 int WealthGodRopeDrop::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
934 if (pointLocation.x == -1 && pointLocation.y == -1)
935 return SIC_REJECT;
936
937 if (_dropRope.contains(pointLocation) && (itemID == kItemCoilOfRope || itemID == kItemGrapplingHook)) {
938 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myWGPlacedRope = 1;
939 Location newLocation = _staticData.location;
940 newLocation.depth = 1;
941 ((SceneViewWindow *)viewWindow)->jumpToScene(newLocation);
942 return SIC_ACCEPT;
943 }
944
945 return SIC_REJECT;
946 }
947
948 class WaterGodInitialWalkSetFlag : public SceneBase {
949 public:
950 WaterGodInitialWalkSetFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
951 };
952
WaterGodInitialWalkSetFlag(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)953 WaterGodInitialWalkSetFlag::WaterGodInitialWalkSetFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
954 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
955 // Set flag on entry
956 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myWTCurrentBridgeStatus = 1;
957 }
958
959 class WaterGodBridgeJump : public SceneBase {
960 public:
961 WaterGodBridgeJump(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
962 int movieFileNameID = 0, int playingStartingFrame = 0, int sequenceStartingFrame = 0, int framesPerCycle = 0,
963 int jumpFudgeFrames = 0, int sequenceLength = 0, bool jumpMidCycle = false, int frameOffsetToEndOfSwing = 0);
964 int postEnterRoom(Window *viewWindow, const Location &priorLocation);
965 int preExitRoom(Window *viewWindow, const Location &newLocation);
966 int postExitRoom(Window *viewWindow, const Location &newLocation);
967 int timerCallback(Window *viewWindow);
968 int movieCallback(Window *viewWindow, VideoWindow *movie, int animationID, int status);
969
970 private:
971 int _movieID;
972 int _startingMovieFrame;
973 int _playingStartingFrame;
974 int _framesPerCycle;
975 int _sequenceLength;
976 int _jumpFudgeFrames;
977 int _finalFrameIndex;
978 int _soundID;
979 DestinationScene _savedDestForward;
980 bool _jumpMidCycle;
981 int _frameOffsetToEndOfSwing;
982 };
983
WaterGodBridgeJump(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int movieFileNameID,int playingStartingFrame,int sequenceStartingFrame,int framesPerCycle,int jumpFudgeFrames,int sequenceLength,bool jumpMidCycle,int frameOffsetToEndOfSwing)984 WaterGodBridgeJump::WaterGodBridgeJump(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
985 int movieFileNameID, int playingStartingFrame, int sequenceStartingFrame, int framesPerCycle,
986 int jumpFudgeFrames, int sequenceLength, bool jumpMidCycle, int frameOffsetToEndOfSwing) :
987 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
988 _movieID = movieFileNameID;
989 _playingStartingFrame = playingStartingFrame;
990 _startingMovieFrame = sequenceStartingFrame;
991 _framesPerCycle = framesPerCycle;
992 _sequenceLength = sequenceLength;
993 _jumpFudgeFrames = jumpFudgeFrames;
994 _finalFrameIndex = -1;
995 _soundID = -1;
996 _jumpMidCycle = jumpMidCycle;
997 _frameOffsetToEndOfSwing = frameOffsetToEndOfSwing;
998
999 // Save the forward movement data for later
1000 _savedDestForward = _staticData.destForward;
1001 _staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
1002 _staticData.destForward.transitionType = -1;
1003 _staticData.destForward.transitionData = -1;
1004 _staticData.destForward.transitionStartFrame = -1;
1005 _staticData.destForward.transitionLength = -1;
1006
1007 // Set visited flag
1008 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myWTSteppedOnSwings = 1;
1009 }
1010
postEnterRoom(Window * viewWindow,const Location & priorLocation)1011 int WaterGodBridgeJump::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
1012 // Raise the ambient sound
1013 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
1014 uint32 ambientPos = _vm->_sound->getSecondaryAmbientPosition();
1015
1016 int frameStartingOffset = (ambientPos / 1838) % _sequenceLength + (_startingMovieFrame - _playingStartingFrame) % _sequenceLength;
1017
1018 // Load and start the new asynchronous animation
1019 ((SceneViewWindow *)viewWindow)->startAsynchronousAnimation(_movieID, _startingMovieFrame, _playingStartingFrame + frameStartingOffset, _sequenceLength, true);
1020 return SC_TRUE;
1021 }
1022
preExitRoom(Window * viewWindow,const Location & newLocation)1023 int WaterGodBridgeJump::preExitRoom(Window *viewWindow, const Location &newLocation) {
1024 _finalFrameIndex = ((SceneViewWindow *)viewWindow)->getAsynchronousAnimationCurrentPosition();
1025
1026 // Moving to another node should kill the anim
1027 if (newLocation.node != 4 || newLocation.timeZone != 2 || newLocation.environment != 4)
1028 ((SceneViewWindow *)viewWindow)->stopAsynchronousAnimation();
1029
1030 // If we are walking into a node less than 5, kill the ambient
1031 if (newLocation.node <= 3)
1032 _vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
1033
1034 return SC_TRUE;
1035 }
1036
postExitRoom(Window * viewWindow,const Location & newLocation)1037 int WaterGodBridgeJump::postExitRoom(Window *viewWindow, const Location &newLocation) {
1038 if (newLocation.facing == _staticData.location.facing && newLocation.timeZone == _staticData.location.timeZone &&
1039 newLocation.environment == _staticData.location.environment) {
1040 if (_jumpMidCycle) {
1041 int diff = (_finalFrameIndex - _playingStartingFrame) % (_framesPerCycle * 2);
1042 int diffB = (_finalFrameIndex - _playingStartingFrame - _framesPerCycle) % _framesPerCycle;
1043 int diffC = _framesPerCycle - (_finalFrameIndex - _playingStartingFrame) % _framesPerCycle;
1044
1045 if (diff > _framesPerCycle || diffB > _framesPerCycle || diffC > _jumpFudgeFrames * 2) {
1046 if (_staticData.location.facing == 0)
1047 ((SceneViewWindow *)viewWindow)->showDeathScene(14);
1048 else
1049 ((SceneViewWindow *)viewWindow)->showDeathScene(15);
1050
1051 return SC_DEATH;
1052 }
1053 } else {
1054 if ((_finalFrameIndex - _playingStartingFrame) % _framesPerCycle > _jumpFudgeFrames && _framesPerCycle - (_finalFrameIndex - _playingStartingFrame) % _framesPerCycle > _jumpFudgeFrames) {
1055 if (_staticData.location.facing == 0)
1056 ((SceneViewWindow *)viewWindow)->showDeathScene(14);
1057 else
1058 ((SceneViewWindow *)viewWindow)->showDeathScene(15);
1059
1060 return SC_DEATH;
1061 }
1062 }
1063 }
1064
1065 return SC_TRUE;
1066 }
1067
timerCallback(Window * viewWindow)1068 int WaterGodBridgeJump::timerCallback(Window *viewWindow) {
1069 // If we have reached the end of the starting sequence, reset the arrows
1070 if (_staticData.destForward.destinationScene.timeZone == -1 && ((SceneViewWindow *)viewWindow)->getAsynchronousAnimationCurrentPosition() >= _startingMovieFrame) {
1071 _staticData.destForward = _savedDestForward;
1072 ((GameUIWindow *)viewWindow->getParent())->_navArrowWindow->updateAllArrows(_staticData);
1073 }
1074
1075 return SC_TRUE;
1076 }
1077
movieCallback(Window * viewWindow,VideoWindow * movie,int animationID,int status)1078 int WaterGodBridgeJump::movieCallback(Window *viewWindow, VideoWindow *movie, int animationID, int status) {
1079 if (status == MOVIE_LOOPING_RESTART)
1080 _vm->_sound->restartSecondaryAmbientSound();
1081
1082 return SC_TRUE;
1083 }
1084
1085 class ArrowGodHead : public SceneBase {
1086 public:
1087 ArrowGodHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
1088 int headID = 0, int clickLeft = -1, int clickTop = -1, int clickRight = -1, int clickBottom = -1,
1089 int emptyClosedStill = -1, int emptyOpenStill = -1, int fullClosedStill = -1, int fullOpenStill = -1,
1090 int emptyClosedAnim = -1, int emptyOpenAnim = -1, int fullClosedAnim = -1, int fullOpenAnim = -1);
1091 int postEnterRoom(Window *viewWindow, const Location &priorLocation);
1092 int mouseDown(Window *viewWindow, const Common::Point &pointLocation);
1093 int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
1094 int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
1095 int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
1096 int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1097 int timerCallback(Window *viewWindow);
1098
1099 private:
1100 int _headID;
1101 Common::Rect _skullRegion;
1102 int _stillFrames[4];
1103 int _soundID;
1104 int _headAnimations[4];
1105 };
1106
ArrowGodHead(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,int headID,int clickLeft,int clickTop,int clickRight,int clickBottom,int emptyClosedStill,int emptyOpenStill,int fullClosedStill,int fullOpenStill,int emptyClosedAnim,int emptyOpenAnim,int fullClosedAnim,int fullOpenAnim)1107 ArrowGodHead::ArrowGodHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
1108 int headID, int clickLeft, int clickTop, int clickRight, int clickBottom,
1109 int emptyClosedStill, int emptyOpenStill, int fullClosedStill, int fullOpenStill,
1110 int emptyClosedAnim, int emptyOpenAnim, int fullClosedAnim, int fullOpenAnim) :
1111 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1112 _soundID = -1;
1113 _headID = headID;
1114 _skullRegion = Common::Rect(clickLeft, clickTop, clickRight, clickBottom);
1115 _stillFrames[0] = emptyClosedStill;
1116 _stillFrames[1] = emptyOpenStill;
1117 _stillFrames[2] = fullClosedStill;
1118 _stillFrames[3] = fullOpenStill;
1119 _headAnimations[0] = emptyClosedAnim;
1120 _headAnimations[1] = emptyOpenAnim;
1121 _headAnimations[2] = fullClosedAnim;
1122 _headAnimations[3] = fullOpenAnim;
1123 _staticData.navFrameIndex = _stillFrames[((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID)];
1124 }
1125
postEnterRoom(Window * viewWindow,const Location & priorLocation)1126 int ArrowGodHead::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
1127 byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
1128 byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
1129
1130 if (_staticData.location.node == 0) {
1131 if (headAStatus == 0)
1132 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
1133 else if (headDStatus == 0)
1134 _vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
1135 else
1136 _vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
1137 } else if (_staticData.location.node == 2) {
1138 if (headAStatus == 0 || headDStatus == 0)
1139 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
1140 else
1141 _vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
1142 }
1143
1144 return SC_TRUE;
1145 }
1146
mouseDown(Window * viewWindow,const Common::Point & pointLocation)1147 int ArrowGodHead::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
1148 // For walkthrough mode, don't allow input
1149 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
1150 return SC_FALSE;
1151
1152 if (_skullRegion.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID) == 3) {
1153 byte skullIndex = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatusSkullID) + _headID);
1154 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatusSkullID) + _headID, 0);
1155 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID, 1);
1156 _staticData.navFrameIndex = _stillFrames[1];
1157 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadATouched) + _headID, 1);
1158
1159 // Begin dragging
1160 Common::Point ptInventoryWindow = viewWindow->convertPointToWindow(pointLocation, ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow);
1161 ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->startDraggingNewItem(skullIndex, ptInventoryWindow);
1162 ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
1163 return SC_TRUE;
1164 }
1165
1166 return SC_FALSE;
1167 }
1168
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1169 int ArrowGodHead::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1170 // For walkthrough mode, don't allow input
1171 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
1172 return SC_FALSE;
1173
1174 // Did we click on the head?
1175 if (_skullRegion.contains(pointLocation)) {
1176 byte headStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID);
1177 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadATouched) + _headID, 1);
1178
1179 if (headStatus & 1)
1180 headStatus--;
1181 else
1182 headStatus++;
1183
1184 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID, headStatus);
1185
1186 // Play the proper movie
1187 int currentSoundID = -1;
1188 if (headStatus == 2)
1189 currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
1190 else
1191 currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128, false, true);
1192
1193 if ((_headID == 1 || _headID == 2) && headStatus == 0) {
1194 if (_staticData.location.node == 0)
1195 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 127);
1196 else
1197 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 96);
1198 }
1199
1200 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_headAnimations[headStatus]);
1201
1202 _staticData.navFrameIndex = _stillFrames[headStatus];
1203 viewWindow->invalidateWindow(false);
1204
1205 byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
1206 byte headBStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadBStatus;
1207 byte headCStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadCStatus;
1208 byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
1209
1210 if (_staticData.location.node == 0) {
1211 if (headAStatus == 0)
1212 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
1213 else if (headDStatus == 0)
1214 _vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
1215 else
1216 _vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
1217 } else if (_staticData.location.node == 2) {
1218 if (headAStatus == 0 || headDStatus == 0)
1219 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
1220 else
1221 _vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
1222 }
1223
1224 _vm->_sound->stopSoundEffect(currentSoundID);
1225
1226 if (_staticData.location.node == 0 && (headBStatus < 3 && headCStatus < 3))
1227 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 127);
1228 else if (_staticData.location.node == 2 && (headBStatus < 3 && headCStatus < 3))
1229 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 96);
1230
1231 if (headStatus & 1)
1232 ((SceneViewWindow *)viewWindow)->setGlobalFlagDWord(offsetof(GlobalFlags, myAGHeadAOpenedTime) + _headID * 4, g_system->getMillis());
1233
1234 ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
1235 return SC_TRUE;
1236 }
1237
1238 return SC_FALSE;
1239 }
1240
draggingItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)1241 int ArrowGodHead::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
1242 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
1243 return 0;
1244
1245 if ((itemID == kItemCavernSkull || itemID == kItemEntrySkull || itemID == kItemSpearSkull) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID) < 2 && _skullRegion.contains(pointLocation))
1246 return 1;
1247
1248 return 0;
1249 }
1250
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)1251 int ArrowGodHead::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
1252 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
1253 return SIC_REJECT;
1254
1255 if (pointLocation.x == -1 && pointLocation.y == -1)
1256 return SIC_REJECT;
1257
1258 if ((itemID == kItemCavernSkull || itemID == kItemEntrySkull || itemID == kItemSpearSkull) && ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID) == 1 && _skullRegion.contains(pointLocation)) {
1259 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID, 2);
1260 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadATouched) + _headID, 1);
1261 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatusSkullID) + _headID, itemID);
1262
1263 int currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
1264
1265 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_headAnimations[2]);
1266
1267 _staticData.navFrameIndex = _stillFrames[2];
1268 viewWindow->invalidateWindow(false);
1269
1270 byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
1271 byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
1272
1273 if (_staticData.location.node == 0) {
1274 if (headAStatus == 0)
1275 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
1276 else if (headDStatus == 0)
1277 _vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
1278 else
1279 _vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
1280 } else if (_staticData.location.node == 2) {
1281 if (headAStatus == 0 || headDStatus == 0)
1282 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
1283 else
1284 _vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
1285 }
1286
1287 _vm->_sound->stopSoundEffect(currentSoundID);
1288
1289 ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
1290 return SIC_ACCEPT;
1291 }
1292
1293 return SIC_REJECT;
1294 }
1295
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1296 int ArrowGodHead::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1297 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
1298 return 0;
1299
1300 if (_skullRegion.contains(pointLocation)) {
1301 if (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + _headID) == 3)
1302 return kCursorOpenHand;
1303
1304 return kCursorFinger;
1305 }
1306
1307 return 0;
1308 }
1309
timerCallback(Window * viewWindow)1310 int ArrowGodHead::timerCallback(Window *viewWindow) {
1311 for (int i = 0; i < 4; i++) {
1312 uint32 lastStartedTimer = ((SceneViewWindow *)viewWindow)->getGlobalFlagDWord(offsetof(GlobalFlags, myAGHeadAOpenedTime) + i * 4);
1313
1314 if (lastStartedTimer > 0 && g_system->getMillis() > (lastStartedTimer + WAR_GOD_HEAD_TIMER_VALUE)) {
1315 ((SceneViewWindow *)viewWindow)->setGlobalFlagDWord(offsetof(GlobalFlags, myAGHeadAOpenedTime) + i * 4, 0);
1316
1317 TempCursorChange cursorChange(kCursorWait);
1318
1319 if (i == _headID) {
1320 byte status = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i);
1321
1322 if (status & 1) {
1323 status--;
1324 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i, status);
1325
1326 int currentSoundID = -1;
1327 if (status == 2)
1328 currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
1329 else
1330 currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128, false, true);
1331
1332 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(_headAnimations[status]);
1333
1334 _staticData.navFrameIndex = _stillFrames[status];
1335 viewWindow->invalidateWindow(false);
1336
1337 _vm->_sound->stopSoundEffect(currentSoundID);
1338
1339 byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
1340 byte headBStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadBStatus;
1341 byte headCStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadCStatus;
1342 byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
1343
1344 if (_staticData.location.node == 0) {
1345 if (headAStatus == 0)
1346 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
1347 else if (headDStatus == 0)
1348 _vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
1349 else
1350 _vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
1351 } else if (_staticData.location.node == 2) {
1352 if (headAStatus == 0 || headDStatus == 0)
1353 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
1354 else
1355 _vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
1356 }
1357
1358 // Play the door closing sound, if applicable
1359 if (i == 1 || i == 2) {
1360 if (_staticData.location.node == 0 && (headBStatus == 0 || headCStatus == 0))
1361 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 127);
1362 else if (_staticData.location.node == 2 && (headBStatus == 0 || headCStatus == 0))
1363 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 96);
1364 }
1365 }
1366
1367 ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
1368 } else {
1369 byte status = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i);
1370
1371 if (status & 1) {
1372 status--;
1373 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i, status);
1374
1375 if (status == 2)
1376 _vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128);
1377 else
1378 _vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128);
1379
1380 byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
1381 byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
1382
1383 if (_staticData.location.node == 0) {
1384 if (headAStatus == 0)
1385 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
1386 else if (headDStatus == 0)
1387 _vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
1388 else
1389 _vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
1390 } else if (_staticData.location.node == 2) {
1391 if (headAStatus == 0 || headDStatus == 0)
1392 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
1393 else
1394 _vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
1395 }
1396 }
1397
1398 ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
1399
1400 if (_headID == 1 || _headID == 2) {
1401 if (_staticData.location.node == 0)
1402 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 127);
1403 else if (_staticData.location.node == 2)
1404 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), 96);
1405 }
1406 }
1407 }
1408 }
1409
1410 return SC_TRUE;
1411 }
1412
1413 class ArrowGodDepthChange : public SceneBase {
1414 public:
1415 ArrowGodDepthChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1416 int postEnterRoom(Window *viewWindow, const Location &priorLocation);
1417 int postExitRoom(Window *viewWindow, const Location &newLocation);
1418 int timerCallback(Window *viewWindow);
1419
1420 private:
1421 bool _scheduledDepthChange;
1422 int _soundID;
1423
1424 bool adjustSpearVolume(Window *viewWindow);
1425 };
1426
ArrowGodDepthChange(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1427 ArrowGodDepthChange::ArrowGodDepthChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1428 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1429 _scheduledDepthChange = false;
1430 _soundID = -1;
1431
1432 byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
1433 byte headBStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadBStatus;
1434 byte headCStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadCStatus;
1435 byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
1436
1437 int targetDepth = 0;
1438
1439 if (headBStatus > 0 || headCStatus > 0) {
1440 if (headBStatus > 0) {
1441 if (headAStatus == 0 || headDStatus == 0) {
1442 if (headAStatus == 0 && headDStatus == 0) {
1443 targetDepth = 11;
1444 } else if (headAStatus > 0 && headDStatus == 0) {
1445 targetDepth = 10;
1446 } else if (headAStatus == 0 && headDStatus > 0) {
1447 targetDepth = 9;
1448 }
1449 } else {
1450 targetDepth = 8;
1451 }
1452 } else if (headCStatus > 0) {
1453 if (headAStatus == 0 || headDStatus == 0) {
1454 if (headAStatus == 0 && headDStatus == 0) {
1455 targetDepth = 7;
1456 } else if (headAStatus > 0 && headDStatus == 0) {
1457 targetDepth = 6;
1458 } else if (headAStatus == 0 && headDStatus > 0) {
1459 targetDepth = 5;
1460 }
1461 } else {
1462 targetDepth = 4;
1463 }
1464 }
1465 } else if (headAStatus == 0 || headDStatus == 0) {
1466 if (headAStatus == 0 && headBStatus == 0) {
1467 targetDepth = 3;
1468 } else {
1469 if (headAStatus > 0 && headDStatus == 0) {
1470 targetDepth = 2;
1471 } else if (headAStatus == 0 && headDStatus > 0) {
1472 targetDepth = 1;
1473 }
1474 }
1475 }
1476
1477 if (_staticData.location.depth != targetDepth) {
1478 Location newLocation = _staticData.location;
1479 newLocation.depth = targetDepth;
1480 ((SceneViewWindow *)viewWindow)->getSceneStaticData(newLocation, _staticData);
1481 _frameCycleCount = _staticData.cycleStartFrame;
1482
1483 // Reload the frame files, if applicable
1484 ((SceneViewWindow *)viewWindow)->changeStillFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_STILLS));
1485
1486 if (_staticData.cycleStartFrame >= 0)
1487 ((SceneViewWindow *)viewWindow)->changeCycleFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_CYCLES));
1488 }
1489 }
1490
postEnterRoom(Window * viewWindow,const Location & priorLocation)1491 int ArrowGodDepthChange::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
1492 if (((priorLocation.depth >= 8 && priorLocation.depth <= 11) && _staticData.location.depth < 8) ||
1493 ((priorLocation.depth >= 4 && priorLocation.depth <= 7) && _staticData.location.depth < 4)) {
1494 byte headBStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadBStatus;
1495 byte headCStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadCStatus;
1496 byte &headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
1497 byte doorLevelVolume = 0;
1498
1499 switch (_staticData.location.node) {
1500 case 0:
1501 case 1:
1502 doorLevelVolume = 127;
1503 break;
1504 case 2:
1505 doorLevelVolume = 96;
1506
1507 if (headDStatus == 2) {
1508 headDStatus--;
1509 _vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128);
1510 _scheduledDepthChange = true;
1511 adjustSpearVolume(viewWindow);
1512 ((SceneViewWindow *)viewWindow)->jumpToScene(_staticData.location);
1513 return SC_TRUE; // Original does not return here, but the status of this would be bad in that case
1514 }
1515 break;
1516 case 3:
1517 if (headCStatus == 0)
1518 doorLevelVolume = 127;
1519 else if (headBStatus == 0)
1520 doorLevelVolume = 64;
1521 break;
1522 }
1523
1524 if (doorLevelVolume > 0)
1525 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), doorLevelVolume);
1526 }
1527
1528 adjustSpearVolume(viewWindow);
1529 return SC_TRUE;
1530 }
1531
postExitRoom(Window * viewWindow,const Location & newLocation)1532 int ArrowGodDepthChange::postExitRoom(Window *viewWindow, const Location &newLocation) {
1533 if (_staticData.location.timeZone == newLocation.timeZone &&
1534 _staticData.location.environment == newLocation.environment &&
1535 _staticData.location.node == newLocation.node &&
1536 _staticData.location.facing == newLocation.facing &&
1537 _staticData.location.orientation == newLocation.orientation &&
1538 _staticData.location.depth == newLocation.depth &&
1539 !_scheduledDepthChange) {
1540 // Notify the player of his gruesome death
1541 ((SceneViewWindow *)viewWindow)->showDeathScene(13);
1542 return SC_DEATH;
1543 }
1544
1545 return SC_TRUE;
1546 }
1547
timerCallback(Window * viewWindow)1548 int ArrowGodDepthChange::timerCallback(Window *viewWindow) {
1549 SceneBase::timerCallback(viewWindow);
1550
1551 // Check to see if we moved into a death scene
1552 if (_staticData.location.timeZone == 2 && _staticData.location.environment == 5 &&
1553 _staticData.location.node == 1 && _staticData.location.facing == 3 &&
1554 _staticData.location.orientation == 1 && (_staticData.location.depth == 1 ||
1555 _staticData.location.depth == 3 || _staticData.location.depth == 11 ||
1556 _staticData.location.depth == 7 || _staticData.location.depth == 5 ||
1557 _staticData.location.depth == 9)) {
1558 if (_staticData.location.depth == 1)
1559 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(19);
1560
1561 ((SceneViewWindow *)viewWindow)->showDeathScene(13);
1562 return SC_DEATH;
1563 }
1564
1565 if (_staticData.location.timeZone == 2 && _staticData.location.environment == 5 &&
1566 _staticData.location.node == 3 && _staticData.location.facing == 3 &&
1567 _staticData.location.orientation == 1 && (_staticData.location.depth == 2 ||
1568 _staticData.location.depth == 3 || _staticData.location.depth == 11 ||
1569 _staticData.location.depth == 10 || _staticData.location.depth == 6 ||
1570 _staticData.location.depth == 7)) {
1571 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(17);
1572 ((SceneViewWindow *)viewWindow)->showDeathScene(13);
1573 return SC_DEATH;
1574 }
1575
1576 // Loop through the four heads
1577 for (int i = 0; i < 4; i++) {
1578 uint32 lastStartedTimer = ((SceneViewWindow *)viewWindow)->getGlobalFlagDWord(offsetof(GlobalFlags, myAGHeadAOpenedTime) + i * 4);
1579
1580 // Check if there is a timer going for this head
1581 if (lastStartedTimer > 0 && (g_system->getMillis() > (lastStartedTimer + WAR_GOD_HEAD_TIMER_VALUE) ||
1582 i == 0 || (((SceneViewWindow *)viewWindow)->getGlobalFlags().generalWalkthroughMode == 1 && i == 1) ||
1583 (((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i) == 2 && i == 3))) {
1584 ((SceneViewWindow *)viewWindow)->setGlobalFlagDWord(offsetof(GlobalFlags, myAGHeadAOpenedTime) + i * 4, 0);
1585 TempCursorChange cursorChange(kCursorWait);
1586 byte status = ((SceneViewWindow *)viewWindow)->getGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i);
1587
1588 if (status & 1) {
1589 status--;
1590 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(offsetof(GlobalFlags, myAGHeadAStatus) + i, status);
1591 _vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, (status == 2) ? 14 : 13), 128);
1592 _scheduledDepthChange = true;
1593 adjustSpearVolume(viewWindow);
1594 }
1595
1596 ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->sceneChanged();
1597 }
1598 }
1599
1600 if (_scheduledDepthChange) {
1601 _scheduledDepthChange = false;
1602 Location location = _staticData.location;
1603 ((SceneViewWindow *)viewWindow)->jumpToScene(location);
1604 }
1605
1606 return SC_TRUE;
1607 }
1608
adjustSpearVolume(Window * viewWindow)1609 bool ArrowGodDepthChange::adjustSpearVolume(Window *viewWindow) {
1610 // TODO: Looks like there's a bug in the original. node == 3 should also be in here, I think
1611 // Need to investigate
1612 if (_staticData.location.node >= 0 && _staticData.location.node <= 2) {
1613 byte headAStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadAStatus;
1614 byte headDStatus = ((SceneViewWindow *)viewWindow)->getGlobalFlags().myAGHeadDStatus;
1615
1616 if (headAStatus == 0) {
1617 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
1618 } else if (headDStatus == 0) {
1619 if (_staticData.location.node == 2)
1620 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
1621 else
1622 _vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
1623 } else {
1624 _vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
1625 }
1626 }
1627
1628 return true;
1629 }
1630
1631 class DeathGodAltar : public SceneBase {
1632 public:
1633 DeathGodAltar(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1634 int postEnterRoom(Window *viewWindow, const Location &priorLocation);
1635 int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
1636 int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
1637 int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags);
1638 int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1639 int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
1640
1641 private:
1642 Common::Rect _heartPool;
1643 Common::Rect _puzzleBox;
1644 Common::Rect _blood;
1645 };
1646
DeathGodAltar(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1647 DeathGodAltar::DeathGodAltar(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1648 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1649 _heartPool = Common::Rect(89, 80, 159, 112);
1650 _puzzleBox = Common::Rect(150, 45, 260, 111);
1651 _blood = Common::Rect(88, 76, 162, 114);
1652 }
1653
postEnterRoom(Window * viewWindow,const Location & priorLocation)1654 int DeathGodAltar::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
1655 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart == 1) {
1656 if (!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), MAYAN_EVIDENCE_ENVIRON_CART)) {
1657 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(3);
1658 _staticData.navFrameIndex = 51;
1659 viewWindow->invalidateWindow(false);
1660
1661 if ((_staticData.location.timeZone != priorLocation.timeZone || _staticData.location.environment != priorLocation.environment ||
1662 _staticData.location.node != priorLocation.node || _staticData.location.facing != priorLocation.facing ||
1663 _staticData.location.orientation != priorLocation.orientation || _staticData.location.depth != priorLocation.depth) &&
1664 !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), MAYAN_EVIDENCE_ENVIRON_CART))
1665 ((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
1666 }
1667 } else if ((_staticData.location.timeZone != priorLocation.timeZone || _staticData.location.environment != priorLocation.environment ||
1668 _staticData.location.node != priorLocation.node || _staticData.location.facing != priorLocation.facing ||
1669 _staticData.location.orientation != priorLocation.orientation || _staticData.location.depth != priorLocation.depth) &&
1670 !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), MAYAN_EVIDENCE_PHONY_BLOOD)) {
1671 ((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
1672 }
1673
1674 return SC_TRUE;
1675 }
1676
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1677 int DeathGodAltar::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1678 if (_puzzleBox.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart == 1 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().takenEnvironCart == 0) {
1679 Location puzzleLocation = _staticData.location;
1680 puzzleLocation.depth = 1;
1681 ((SceneViewWindow *)viewWindow)->jumpToScene(puzzleLocation);
1682 }
1683
1684 return SC_FALSE;
1685 }
1686
draggingItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)1687 int DeathGodAltar::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
1688 if (itemID == kItemPreservedHeart && ((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart == 0 && _heartPool.contains(pointLocation))
1689 return 1;
1690
1691 return 0;
1692 }
1693
droppedItem(Window * viewWindow,int itemID,const Common::Point & pointLocation,int itemFlags)1694 int DeathGodAltar::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
1695 if (pointLocation.x == -1 && pointLocation.y == -1)
1696 return SIC_REJECT;
1697
1698 if (itemID == kItemPreservedHeart && ((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart == 0 && _heartPool.contains(pointLocation)) {
1699 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart = 1;
1700 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(2);
1701 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(3);
1702 _staticData.navFrameIndex = 51;
1703
1704 if (!((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), MAYAN_EVIDENCE_ENVIRON_CART))
1705 ((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
1706
1707 return SIC_ACCEPT;
1708 }
1709
1710 return SIC_REJECT;
1711 }
1712
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1713 int DeathGodAltar::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1714 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
1715 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart == 1 &&
1716 ((SceneViewWindow *)viewWindow)->getGlobalFlags().takenEnvironCart == 0 &&
1717 _staticData.navFrameIndex == 51 && _puzzleBox.contains(pointLocation))
1718 return -2;
1719
1720 if (_blood.contains(pointLocation))
1721 return -2;
1722
1723 return -1;
1724 } else if (_puzzleBox.contains(pointLocation) && ((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOfferedHeart == 1 && ((SceneViewWindow *)viewWindow)->getGlobalFlags().takenEnvironCart == 0) {
1725 // This logic is broken in 1.04, 1.05, and 1.10. I fixed it here to match mouseUp
1726 return kCursorFinger;
1727 }
1728
1729 return kCursorArrow;
1730 }
1731
locateAttempted(Window * viewWindow,const Common::Point & pointLocation)1732 int DeathGodAltar::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
1733 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1 &&
1734 ((SceneViewWindow *)viewWindow)->getGlobalFlags().takenEnvironCart == 0 &&
1735 _puzzleBox.contains(pointLocation) && _staticData.navFrameIndex == 51 &&
1736 !((SceneViewWindow *)viewWindow)->isNumberInGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), MAYAN_EVIDENCE_ENVIRON_CART)) {
1737 ((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_MUST_BE_REVEALED)); // All will be reveaaaaaaaaled (Yes, I used this joke twice now)
1738 return SC_TRUE;
1739 }
1740
1741 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
1742 if (_blood.contains(pointLocation)) {
1743 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(6);
1744
1745 // Attempt to add it to the biochip
1746 if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, MAYAN_EVIDENCE_PHONY_BLOOD))
1747 ((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
1748 else
1749 ((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
1750
1751 // Disable capture
1752 ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
1753 }
1754
1755 return SC_TRUE;
1756 }
1757
1758 return SC_FALSE;
1759 }
1760
1761 class DeathGodPuzzleBox : public SceneBase {
1762 public:
1763 DeathGodPuzzleBox(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1764 ~DeathGodPuzzleBox();
1765 void preDestructor();
1766 int paint(Window *viewWindow, Graphics::Surface *preBuffer);
1767 int gdiPaint(Window *viewWindow);
1768 int mouseUp(Window *viewWindow, const Common::Point &pointLocation);
1769 int mouseMove(Window *viewWindow, const Common::Point &pointLocation);
1770 int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1771
1772 private:
1773 int _puzzleIndexes[4];
1774 Common::Rect _clickableRegions[4];
1775 Common::Rect _puzzleRightHandle;
1776 AVIFrames _puzzleFrames[4];
1777 bool _translateText;
1778
1779 bool isPuzzleSolved() const;
1780 };
1781
DeathGodPuzzleBox(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)1782 DeathGodPuzzleBox::DeathGodPuzzleBox(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
1783 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
1784 _translateText = false;
1785 _puzzleIndexes[0] = _puzzleIndexes[1] = _puzzleIndexes[2] = _puzzleIndexes[3] = 0;
1786 _clickableRegions[0] = Common::Rect(30, 0, 111, 189);
1787 _clickableRegions[1] = Common::Rect(112, 0, 187, 189);
1788 _clickableRegions[2] = Common::Rect(188, 0, 252, 189);
1789 _clickableRegions[3] = Common::Rect(253, 0, 330, 189);
1790 _puzzleRightHandle = Common::Rect(380, 0, 432, 189);
1791
1792 // Load the spinner movies
1793 _puzzleFrames[0].open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 4));
1794 _puzzleFrames[1].open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 5));
1795 _puzzleFrames[2].open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 6));
1796 _puzzleFrames[3].open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 7));
1797 }
1798
~DeathGodPuzzleBox()1799 DeathGodPuzzleBox::~DeathGodPuzzleBox() {
1800 preDestructor();
1801 }
1802
preDestructor()1803 void DeathGodPuzzleBox::preDestructor() {
1804 _puzzleFrames[0].close();
1805 _puzzleFrames[1].close();
1806 _puzzleFrames[2].close();
1807 _puzzleFrames[3].close();
1808 }
1809
paint(Window * viewWindow,Graphics::Surface * preBuffer)1810 int DeathGodPuzzleBox::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
1811 SceneBase::paint(viewWindow, preBuffer);
1812
1813 for (int i = 0; i < 4; i++) {
1814 const Graphics::Surface *spinnerFrame = _puzzleFrames[i].getFrame(_puzzleIndexes[i]);
1815 _vm->_gfx->crossBlit(preBuffer, _clickableRegions[i].left, _clickableRegions[i].top, _clickableRegions[i].width(), _clickableRegions[i].height(), spinnerFrame, 0, 0);
1816 }
1817
1818 return SC_REPAINT;
1819 }
1820
gdiPaint(Window * viewWindow)1821 int DeathGodPuzzleBox::gdiPaint(Window *viewWindow) {
1822 if (_translateText && ((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
1823 Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
1824 Common::Rect rect(42, 64, 324, 125);
1825 rect.translate(absoluteRect.left, absoluteRect.top);
1826 _vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
1827 }
1828
1829 return SC_REPAINT;
1830 }
1831
mouseUp(Window * viewWindow,const Common::Point & pointLocation)1832 int DeathGodPuzzleBox::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
1833 for (int i = 0; i < 4; i++) {
1834 if (_clickableRegions[i].contains(pointLocation)) {
1835 if (pointLocation.y - _clickableRegions[i].top > _clickableRegions[i].height() / 2) {
1836 // Start the roll sound
1837 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
1838
1839 // Spin the wheel, stop at the new value
1840 // FIXME: Timing
1841 for (int j = 0; j < 6; j++) {
1842 _puzzleIndexes[i]--;
1843 if (_puzzleIndexes[i] < 0)
1844 _puzzleIndexes[i] = _puzzleFrames[i].getFrameCount() - 2;
1845 viewWindow->invalidateWindow();
1846 _vm->_gfx->updateScreen();
1847 }
1848
1849 _translateText = false;
1850 mouseMove(viewWindow, pointLocation);
1851 } else {
1852 // Start the roll sound
1853 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
1854
1855 // Spin the wheel, stop at the new value
1856 // FIXME: Timing
1857 for (int j = 0; j < 6; j++) {
1858 _puzzleIndexes[i]++;
1859 if (_puzzleIndexes[i] > _puzzleFrames[i].getFrameCount() - 2)
1860 _puzzleIndexes[i] = 0;
1861 viewWindow->invalidateWindow();
1862 _vm->_gfx->updateScreen();
1863 }
1864
1865 _translateText = false;
1866 mouseMove(viewWindow, pointLocation);
1867 }
1868 }
1869 }
1870
1871 if (_puzzleRightHandle.contains(pointLocation)) {
1872 if (isPuzzleSolved()) {
1873 DestinationScene newDestination;
1874 newDestination.destinationScene = _staticData.location;
1875 newDestination.destinationScene.depth = 2;
1876 newDestination.transitionType = TRANSITION_VIDEO;
1877 newDestination.transitionStartFrame = -1;
1878 newDestination.transitionLength = -1;
1879
1880 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().takenEnvironCart == 0)
1881 newDestination.transitionData = 4;
1882 else
1883 newDestination.transitionData = 5;
1884
1885 BuriedEngine *vm = _vm;
1886 ((SceneViewWindow *)viewWindow)->moveToDestination(newDestination);
1887
1888 // Play animation capturing the evidence
1889 // FIXME: Is this right? Shouldn't this be if takenEnvironCart == 0 only?
1890 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(7);
1891
1892 // Attempt to add it to the biochip
1893 if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, MAYAN_EVIDENCE_ENVIRON_CART))
1894 ((SceneViewWindow *)viewWindow)->displayLiveText(vm->getString(IDS_MBT_EVIDENCE_RIPPLE_DOCUMENTED));
1895 else
1896 ((SceneViewWindow *)viewWindow)->displayLiveText(vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
1897
1898 // Disable capture
1899 ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
1900
1901 // Set the scoring flag
1902 ((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreCompletedDeathGod = 1;
1903 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myDGOpenedPuzzleBox = 1;
1904
1905 // Play an Arthur comment
1906 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().takenEnvironCart == 0 && ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemBioChipAI))
1907 vm->_sound->playSoundEffect("BITDATA/MAYAN/MYDG_C01.BTA"); // Broken in 1.01
1908
1909 return SC_TRUE;
1910 } else {
1911 // We did the puzzle incorrectly, so spin the wheels and kill the player
1912 ((SceneViewWindow *)viewWindow)->playPlacedSynchronousAnimation(8, 320, 0);
1913 ((SceneViewWindow *)viewWindow)->showDeathScene(12);
1914 return SC_DEATH;
1915 }
1916 }
1917
1918 return SC_FALSE;
1919 }
1920
mouseMove(Window * viewWindow,const Common::Point & pointLocation)1921 int DeathGodPuzzleBox::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
1922 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcTranslateEnabled == 1) {
1923 Common::Rect translateTextRegion(42, 64, 324, 126);
1924
1925 if (translateTextRegion.contains(pointLocation)) {
1926 if (!_translateText) {
1927 Common::String translatedText = _vm->getString(IDMYDG_PUZZLE_BOX_TRANS_TEXT_BASE + _puzzleIndexes[0] / 6);
1928 translatedText += ' ';
1929 translatedText += _vm->getString(IDMYDG_PUZZLE_BOX_TRANS_TEXT_BASE + 10 + _puzzleIndexes[1] / 6);
1930 translatedText += ' ';
1931 translatedText += _vm->getString(IDMYDG_PUZZLE_BOX_TRANS_TEXT_BASE + 20 + _puzzleIndexes[2] / 6);
1932 translatedText += ' ';
1933 translatedText += _vm->getString(IDMYDG_PUZZLE_BOX_TRANS_TEXT_BASE + 30 + _puzzleIndexes[3] / 6);
1934
1935 ((SceneViewWindow *)viewWindow)->displayTranslationText(translatedText);
1936
1937 _translateText = true;
1938 viewWindow->invalidateWindow(false);
1939 }
1940 } else {
1941 if (_translateText) {
1942 _translateText = false;
1943 viewWindow->invalidateWindow(false);
1944 }
1945 }
1946 }
1947
1948 return SC_FALSE;
1949 }
1950
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)1951 int DeathGodPuzzleBox::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
1952 for (int i = 0; i < 4; i++) {
1953 if (_clickableRegions[i].contains(pointLocation)) {
1954 if (pointLocation.y - _clickableRegions[i].top > _clickableRegions[i].height() / 2)
1955 return kCursorArrowDown;
1956
1957 return kCursorArrowUp;
1958 }
1959 }
1960
1961 if (_puzzleRightHandle.contains(pointLocation))
1962 return kCursorFinger;
1963
1964 return kCursorArrow;
1965 }
1966
isPuzzleSolved() const1967 bool DeathGodPuzzleBox::isPuzzleSolved() const {
1968 // TODO: Ask players for solutions for other languages
1969 // clone2727 has the English, French, and Japanese source.
1970 // clone2727 has the Italian and Spanish versions and solved the puzzle
1971 // manually for those.
1972
1973 switch (_vm->getLanguage()) {
1974 case Common::DE_DEU:
1975 case Common::ES_ESP:
1976 case Common::IT_ITA:
1977 return _puzzleIndexes[0] == 12 && _puzzleIndexes[1] == 18 && _puzzleIndexes[2] == 30 && _puzzleIndexes[3] == 24;
1978 case Common::EN_ANY:
1979 return _puzzleIndexes[0] == 18 && _puzzleIndexes[1] == 36 && _puzzleIndexes[2] == 12 && _puzzleIndexes[3] == 24;
1980 case Common::FR_FRA:
1981 return _puzzleIndexes[0] == 12 && _puzzleIndexes[1] == 18 && _puzzleIndexes[2] == 42 && _puzzleIndexes[3] == 24;
1982 case Common::JA_JPN:
1983 return _puzzleIndexes[0] == 12 && _puzzleIndexes[1] == 24 && _puzzleIndexes[2] == 30 && _puzzleIndexes[3] == 18;
1984 default:
1985 // Default to English, but warn about it
1986 warning("Unknown language for puzzle box");
1987 return _puzzleIndexes[0] == 18 && _puzzleIndexes[1] == 36 && _puzzleIndexes[2] == 12 && _puzzleIndexes[3] == 24;
1988 }
1989
1990 return false;
1991 }
1992
1993 class MainCavernGlassCapture : public SceneBase {
1994 public:
1995 MainCavernGlassCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
1996 int locateAttempted(Window *viewWindow, const Common::Point &pointLocation);
1997 int specifyCursor(Window *viewWindow, const Common::Point &pointLocation);
1998
1999 private:
2000 Common::Rect _glass;
2001 };
2002
MainCavernGlassCapture(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)2003 MainCavernGlassCapture::MainCavernGlassCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
2004 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
2005 _glass = Common::Rect(305, 126, 355, 156);
2006 }
2007
locateAttempted(Window * viewWindow,const Common::Point & pointLocation)2008 int MainCavernGlassCapture::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
2009 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
2010 if (_glass.contains(pointLocation)) {
2011 // Play the animation
2012 ((SceneViewWindow *)viewWindow)->playSynchronousAnimation(22);
2013
2014 // Attempt to add it to the biochip
2015 if (((SceneViewWindow *)viewWindow)->addNumberToGlobalFlagTable(offsetof(GlobalFlags, evcapBaseID), offsetof(GlobalFlags, evcapNumCaptured), 12, MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID))
2016 ((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
2017 else
2018 ((SceneViewWindow *)viewWindow)->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
2019
2020 // Disable capture
2021 ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow->disableEvidenceCapture();
2022 }
2023
2024 return SC_TRUE;
2025 }
2026
2027 return SC_FALSE;
2028 }
2029
specifyCursor(Window * viewWindow,const Common::Point & pointLocation)2030 int MainCavernGlassCapture::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
2031 if (((SceneViewWindow *)viewWindow)->getGlobalFlags().bcLocateEnabled == 1) {
2032 if (_glass.contains(pointLocation))
2033 return -2;
2034
2035 return -1;
2036 }
2037
2038 return kCursorArrow;
2039 }
2040
2041 class WalkVolumeChange : public SceneBase {
2042 public:
2043 WalkVolumeChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
2044 byte newVolume = 0, uint32 volumeChangeTime = 0, int stepCount = -1, int entryEffectFileNameID = -1);
2045 int postEnterRoom(Window *viewWindow, const Location &priorLocation);
2046 int preExitRoom(Window *viewWindow, const Location &newLocation);
2047
2048 private:
2049 byte _newVolume;
2050 uint32 _volumeChangeTime;
2051 int _stepCount;
2052 int _entryEffectFileNameID;
2053 };
2054
WalkVolumeChange(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,byte newVolume,uint32 volumeChangeTime,int stepCount,int entryEffectFileNameID)2055 WalkVolumeChange::WalkVolumeChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
2056 byte newVolume, uint32 volumeChangeTime, int stepCount, int entryEffectFileNameID) :
2057 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
2058 _newVolume = newVolume;
2059 _volumeChangeTime = volumeChangeTime;
2060 _stepCount = stepCount;
2061 _entryEffectFileNameID = entryEffectFileNameID;
2062 }
2063
postEnterRoom(Window * viewWindow,const Location & priorLocation)2064 int WalkVolumeChange::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
2065 if (_entryEffectFileNameID >= 0 && priorLocation.node != _staticData.location.node)
2066 _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _entryEffectFileNameID), 128, false, true);
2067
2068 return SC_TRUE;
2069 }
2070
preExitRoom(Window * viewWindow,const Location & newLocation)2071 int WalkVolumeChange::preExitRoom(Window *viewWindow, const Location &newLocation) {
2072 if (_stepCount >= 0 && newLocation.node != _staticData.location.node)
2073 _vm->_sound->adjustAmbientSoundVolume(_newVolume, true, _stepCount, _volumeChangeTime);
2074
2075 return SC_TRUE;
2076 }
2077
2078 class AdjustSecondaryAmbientOnEntry : public SceneBase {
2079 public:
2080 AdjustSecondaryAmbientOnEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
2081 int postEnterRoom(Window *viewWindow, const Location &priorLocation);
2082 int preExitRoom(Window *viewWindow, const Location &newLocation);
2083 };
2084
AdjustSecondaryAmbientOnEntry(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)2085 AdjustSecondaryAmbientOnEntry::AdjustSecondaryAmbientOnEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
2086 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
2087 }
2088
postEnterRoom(Window * viewWindow,const Location & priorLocation)2089 int AdjustSecondaryAmbientOnEntry::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
2090 _vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
2091 return SC_TRUE;
2092 }
2093
preExitRoom(Window * viewWindow,const Location & newLocation)2094 int AdjustSecondaryAmbientOnEntry::preExitRoom(Window *viewWindow, const Location &newLocation) {
2095 // Kill the ambient if moving to a different node
2096 if (newLocation.node != _staticData.location.node)
2097 _vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
2098
2099 return SC_TRUE;
2100 }
2101
2102 class WalkDualAmbientVolumeChange : public SceneBase {
2103 public:
2104 WalkDualAmbientVolumeChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
2105 byte newVolume = 0, byte secondVolume = 0, uint32 volumeChangeTime = 0, int stepCount = -1);
2106 int preExitRoom(Window *viewWindow, const Location &newLocation);
2107
2108 private:
2109 byte _newVolume;
2110 uint32 _volumeChangeTime;
2111 int _stepCount;
2112 byte _secondVolume;
2113 };
2114
WalkDualAmbientVolumeChange(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,byte newVolume,byte secondVolume,uint32 volumeChangeTime,int stepCount)2115 WalkDualAmbientVolumeChange::WalkDualAmbientVolumeChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
2116 byte newVolume, byte secondVolume, uint32 volumeChangeTime, int stepCount) :
2117 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
2118 _newVolume = newVolume;
2119 _volumeChangeTime = volumeChangeTime;
2120 _stepCount = stepCount;
2121 _secondVolume = secondVolume;
2122
2123 // If we have stepped on the far ledge, set the flag
2124 if (_staticData.location.timeZone == 2 && _staticData.location.environment == 4 &&
2125 _staticData.location.node == 5 && _staticData.location.facing == 0 &&
2126 _staticData.location.orientation == 1 && _staticData.location.depth == 0)
2127 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myWTSteppedOnFarLedge = 1;
2128 }
2129
preExitRoom(Window * viewWindow,const Location & newLocation)2130 int WalkDualAmbientVolumeChange::preExitRoom(Window *viewWindow, const Location &newLocation) {
2131 if (_stepCount >= 0 && newLocation.node != _staticData.location.node) {
2132 _vm->_sound->adjustAmbientSoundVolume(_newVolume, true, _stepCount, _volumeChangeTime);
2133 _vm->_sound->adjustSecondaryAmbientSoundVolume(_secondVolume, true, _stepCount, _volumeChangeTime);
2134 }
2135
2136 return SC_TRUE;
2137 }
2138
2139 class SetVolumeAndFlag : public SceneBase {
2140 public:
2141 SetVolumeAndFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
2142 byte newVolume = 64, int flagOffset = -1, byte flagValue = 255);
2143 };
2144
SetVolumeAndFlag(BuriedEngine * vm,Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation,byte newVolume,int flagOffset,byte flagValue)2145 SetVolumeAndFlag::SetVolumeAndFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
2146 byte newVolume, int flagOffset, byte flagValue) :
2147 SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
2148 _vm->_sound->adjustAmbientSoundVolume(newVolume, false, 0, 0);
2149
2150 if (flagOffset >= 0)
2151 ((SceneViewWindow *)viewWindow)->setGlobalFlagByte(flagOffset, flagValue);
2152 }
2153
initializeMayanTimeZoneAndEnvironment(Window * viewWindow,int environment)2154 bool SceneViewWindow::initializeMayanTimeZoneAndEnvironment(Window *viewWindow, int environment) {
2155 if (environment == -1) {
2156 GlobalFlags &flags = ((SceneViewWindow *)viewWindow)->getGlobalFlags();
2157
2158 flags.myTPCodeWheelStatus = flags.generalWalkthroughMode;
2159 flags.myTPCodeWheelLeftIndex = flags.generalWalkthroughMode == 1 ? 8 : 0;
2160 flags.myTPCodeWheelRightIndex = flags.generalWalkthroughMode == 1 ? 12 : 0;
2161 flags.myMCDeathGodOfferings = 0;
2162 flags.myWGPlacedRope = flags.generalWalkthroughMode;
2163 flags.myWTCurrentBridgeStatus = 0;
2164 flags.myAGHeadAStatus = flags.generalWalkthroughMode == 1 ? 2 : 0;
2165 flags.myAGHeadBStatus = 0;
2166 flags.myAGHeadCStatus = 0;
2167 flags.myAGHeadDStatus = flags.generalWalkthroughMode == 1 ? 2 : 0;
2168 flags.myAGHeadAStatusSkullID = flags.generalWalkthroughMode == 1 ? kItemCavernSkull : 0;
2169 flags.myAGHeadBStatusSkullID = 0;
2170 flags.myAGHeadCStatusSkullID = 0;
2171 flags.myAGHeadDStatusSkullID = flags.generalWalkthroughMode == 1 ? kItemSpearSkull : 0;
2172 flags.myAGTimerHeadID = 0;
2173 flags.myAGTimerStartTime = 0;
2174 flags.myDGOfferedHeart = 0;
2175 flags.myAGHeadAOpenedTime = 0;
2176 flags.myAGHeadBOpenedTime = 0;
2177 flags.myAGHeadCOpenedTime = 0;
2178 flags.myAGHeadDOpenedTime = 0;
2179
2180 flags.myPickedUpCeramicBowl = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemCeramicBowl) ? 1 : 0;
2181 flags.myMCPickedUpSkull = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) ? 1 : 0;
2182 flags.myWGRetrievedJadeBlock = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemJadeBlock) ? 1 : 0;
2183 flags.myWTRetrievedLimestoneBlock = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemLimestoneBlock) ? 1 : 0;
2184 flags.myAGRetrievedEntrySkull = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) ? 1 : 0;
2185 flags.myAGRetrievedSpearSkull = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull) ? 1 : 0;
2186 flags.myAGRetrievedCopperMedal = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemCopperMedallion) ? 1 : 0;
2187 flags.myAGRetrievedObsidianBlock = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemObsidianBlock) ? 1 : 0;
2188 flags.takenEnvironCart = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow->isItemInInventory(kItemEnvironCart) ? 1 : 0;
2189
2190 if (flags.generalWalkthroughMode == 1) {
2191 flags.myMCPickedUpSkull = 1;
2192 flags.myAGRetrievedSpearSkull = 1;
2193 flags.myAGRetrievedCopperMedal = 1;
2194 }
2195 } else if (environment == 2) {
2196 ((SceneViewWindow *)viewWindow)->getGlobalFlags().scoreEnteredMainCavern = 1;
2197 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedMainCavern = 1;
2198 } else if (environment == 3) {
2199 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedWealthGod = 1;
2200 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedSpecRooms = 1;
2201 } else if (environment == 4) {
2202 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedWaterGod = 1;
2203 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedSpecRooms = 1;
2204 } else if (environment == 5) {
2205 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedArrowGod = 1;
2206 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedSpecRooms = 1;
2207 } else if (environment == 6) {
2208 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedDeathGod = 1;
2209 ((SceneViewWindow *)viewWindow)->getGlobalFlags().myVisitedSpecRooms = 1;
2210 }
2211
2212 return true;
2213 }
2214
startMayanAmbient(int oldTimeZone,int oldEnvironment,int environment,bool fade)2215 bool SceneViewWindow::startMayanAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
2216 bool checkFade = true;
2217
2218 if (environment == 3) {
2219 if (oldEnvironment == 2)
2220 return _vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), checkFade, 64);
2221
2222 return _vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), checkFade, 16);
2223 } else if (environment == 4) {
2224 if (oldTimeZone == -2)
2225 _vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), fade, 64);
2226 else
2227 _vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), fade, 16);
2228
2229 return _vm->_sound->setSecondaryAmbientSound(_vm->getFilePath(2, environment, 13), checkFade, 0);
2230 } else if (environment == 5) {
2231 _vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), fade, 64);
2232 return _vm->_sound->setSecondaryAmbientSound(_vm->getFilePath(2, environment, 12), checkFade, 128);
2233 }
2234
2235 _vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), fade, 64);
2236 return true;
2237 }
2238
checkCustomMayanAICommentDependencies(const Location & commentLocation,const AIComment & commentData)2239 bool SceneViewWindow::checkCustomMayanAICommentDependencies(const Location &commentLocation, const AIComment &commentData) {
2240 //((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory
2241
2242 switch (commentData.dependencyFlagOffsetB) {
2243 case 1: // Player hasn't translated any inscriptions
2244 return _globalFlags.myTPTextTranslated == 0;
2245 case 2: // Player hasn't translated any inscriptions, has translate biochip
2246 return _globalFlags.myTPTextTranslated == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBioChipTranslate);
2247 case 3: // Player hasn't translated any inscriptions, doesn't have translate biochip
2248 return _globalFlags.myTPTextTranslated == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBioChipTranslate);
2249 case 4: // Has translated inscription above calendar, calendar not set to sacred day, player has never been to main cavern
2250 return _globalFlags.myTPCalendarTopTranslated == 1 && _globalFlags.myTPCodeWheelStatus == 0 && _globalFlags.myVisitedMainCavern == 0;
2251 case 5: // Has translated inscription above calendar, calendar is set to sacred day, player has never been to main cavern
2252 return _globalFlags.myTPCalendarTopTranslated == 1 && _globalFlags.myTPCodeWheelStatus == 1 && _globalFlags.myVisitedMainCavern == 0;
2253 case 6: // Player has never been to main cavern
2254 return _globalFlags.myVisitedMainCavern == 0;
2255 case 7: // Player has never been to main cavern, calendar not set to sacred day
2256 return _globalFlags.myVisitedMainCavern == 0 && _globalFlags.myTPCodeWheelStatus == 0;
2257 case 8: // Ceramic bowl not in the inventory
2258 return !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCeramicBowl);
2259 case 9: // If node is not 5, 6, or 8
2260 return commentLocation.node != 6 && commentLocation.node != 5 && commentLocation.node != 8;
2261 case 10: // If node is not 1, 0, 7, or 8
2262 return commentLocation.node != 1 && commentLocation.node != 0 && commentLocation.node != 7 && commentLocation.node != 8;
2263 case 11: // If node is not 0, 8, or 1
2264 return commentLocation.node != 0 && commentLocation.node != 8 && commentLocation.node != 1;
2265 case 12: // If not translated any sacred days
2266 return _globalFlags.myTPCalendarListTranslated == 0;
2267 case 13: // Not any door, no translations
2268 return _globalFlags.myVisitedSpecRooms == 0 && _globalFlags.myMCTransDoor == 0;
2269 case 14: // Not any door, no translations, has translate chip
2270 return _globalFlags.myVisitedSpecRooms == 0 && _globalFlags.myMCTransDoor == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemBioChipTranslate);
2271 case 15: // Not any door, has translated arrow or translated water or translated wealth
2272 return _globalFlags.myVisitedSpecRooms == 0 && (_globalFlags.myMCTransAGOffering == 1 || _globalFlags.myMCTransWGOffering == 1 || _globalFlags.myMCTransWTOffering == 1);
2273 case 16: // Has translated wealth, has not been through wealth god door
2274 return _globalFlags.myMCTransWGOffering == 1 && _globalFlags.myVisitedWealthGod == 0;
2275 case 17: // Has translated water, has not been through water god door
2276 return _globalFlags.myMCTransWTOffering == 1 && _globalFlags.myVisitedWaterGod == 0;
2277 case 18: // Has translated arrow, has not been through arrow god door
2278 return _globalFlags.myMCTransAGOffering == 1 && _globalFlags.myVisitedArrowGod == 0;
2279 case 19: // Has translated death, has not been through death god door
2280 return _globalFlags.myMCTransDGOffering == 1 && _globalFlags.myVisitedDeathGod == 0;
2281 case 20: // Has not been through death god door
2282 return _globalFlags.myVisitedDeathGod == 0;
2283 case 21: // Has translated death
2284 return _globalFlags.myMCTransDGOffering == 1;
2285 case 22: // After making any offering
2286 return _globalFlags.myMCTransMadeAnOffering == 1;
2287 case 23: // Before crossing rope bridge
2288 return _globalFlags.myWGCrossedRopeBridge == 0;
2289 case 24: // If player has translated inscription above wealth god door in cavern
2290 return _globalFlags.myMCTransWGOffering == 1;
2291 case 25: // If player has not translated inscription above wealth god door in cavern
2292 return _globalFlags.myMCTransWGOffering == 0;
2293 case 26: // If player has translated inscription above wealth god door in cavern, has never been to wealth god altar room
2294 return _globalFlags.myMCTransWGOffering == 1 && _globalFlags.myWGSeenLowerPassage == 0;
2295 case 27: // Has not attached either rope or grappling hook, has never been to wealth god altar room
2296 return _globalFlags.myWGPlacedRope == 0 && _globalFlags.myWGSeenLowerPassage == 0;
2297 case 28: // Player has never stepped on swings
2298 return _globalFlags.myWTSteppedOnSwings == 0;
2299 case 29: // Player has never been on far ledge
2300 return _globalFlags.myWTSteppedOnFarLedge == 0;
2301 case 30: // Never put in heart
2302 return _globalFlags.myDGOfferedHeart == 0;
2303 case 31: // Never put in heart, no heart in inventory
2304 return _globalFlags.myDGOfferedHeart == 0 && ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemPreservedHeart);
2305 case 32: // After put in heart, puzzle box never opened
2306 return _globalFlags.myDGOfferedHeart == 1 && _globalFlags.myDGOpenedPuzzleBox == 0;
2307 case 33: // After put in heart, puzzle box never opened, player has not translated 'Itzamna' inscription over inside door of temple
2308 return _globalFlags.myDGOfferedHeart == 1 && _globalFlags.myDGOpenedPuzzleBox == 0 && _globalFlags.myTPTransBreathOfItzamna == 0;
2309 case 34: // After put in heart, puzzle box never opened, player has translated 'Itzamna' inscription over inside door of temple
2310 return _globalFlags.myDGOfferedHeart == 1 && _globalFlags.myDGOpenedPuzzleBox == 0 && _globalFlags.myTPTransBreathOfItzamna == 1;
2311 case 35: // Before interacting with any heads
2312 return _globalFlags.myAGHeadATouched == 0 && _globalFlags.myAGHeadBTouched == 0 && _globalFlags.myAGHeadCTouched == 0 && _globalFlags.myAGHeadDTouched == 0;
2313 case 36: // After interacting with any head, before jamming any head
2314 return (_globalFlags.myAGHeadATouched == 1 || _globalFlags.myAGHeadBTouched == 1 || _globalFlags.myAGHeadCTouched == 1 || _globalFlags.myAGHeadDTouched == 1) && _globalFlags.myAGHeadAStatus == 0 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0;
2315 case 37: // S2 jam, S1 not jam, not altar
2316 return _globalFlags.myAGHeadAStatus == 0 && _globalFlags.myAGHeadBStatus == 2 && _globalFlags.myAGVisitedAltar == 0;
2317 case 38: // S1 jam, S2 not jam, S3 not jam, not altar
2318 return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGVisitedAltar == 0;
2319 case 39: // S1 jam, S2 not jam, S3 not jam, S4 not jam, not altar, no skulls
2320 return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGVisitedAltar == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull);
2321 case 40: // Before interacting with S3 or S4, not altar
2322 return _globalFlags.myAGHeadCTouched == 0 && _globalFlags.myAGHeadDTouched == 0 && _globalFlags.myAGVisitedAltar == 0;
2323 case 41: // S1 jam, S2 jam, S3 not jam, S4 not jam, after interacting with S3 and S4, not altar, no skulls
2324 return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 2 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGHeadCTouched == 1 && _globalFlags.myAGHeadDTouched == 1 && _globalFlags.myAGVisitedAltar == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull);
2325 case 42: // S1 jam, S2 not jam, S3 not jam, S4 not jam, after interacting with S3 and S4, not altar, only 1 skull in inventory
2326 return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGHeadCTouched == 1 && _globalFlags.myAGHeadDTouched == 1 && _globalFlags.myAGVisitedAltar == 0 && (((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) ^ ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) ^ ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull));
2327 case 43: // S1 jam, S2 jam, S3 not jam, S4 not jam, after interacting with S3 and S4, not altar, no skulls
2328 return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 2 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGHeadCTouched == 1 && _globalFlags.myAGHeadDTouched == 1 && _globalFlags.myAGVisitedAltar == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull);
2329 case 44: // S1 jam, S2 not jam, S3 jam, S4 not jam, not altar, no skulls
2330 return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 2 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGVisitedAltar == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull);
2331 case 45: // S1 jam, S2 not jam, S3 not jam, S4 jam, not altar, no skulls
2332 return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0 && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) && !((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull);
2333 case 46: // S1 jam, S2 not jam, S3 not jam, S4 jam, not altar, only 1 skull in inventory
2334 return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0 && (((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) ^ ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) ^ ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull));
2335 case 47: // S1 jam, S3 jam, S4 jam, not altar
2336 return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadCStatus == 2 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0;
2337 case 48: // S1 jam, S3 jam, not altar, only 1 skull in inventory
2338 return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadCStatus == 2 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0 && (((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemCavernSkull) ^ ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemEntrySkull) ^ ((GameUIWindow *)getParent())->_inventoryWindow->isItemInInventory(kItemSpearSkull));
2339 case 49: // S1 jam, S2 jam, S3 jam, not altar
2340 return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadCStatus == 2 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0;
2341 case 50: // S1 not jam, S2 jam, not altar
2342 return _globalFlags.myAGHeadAStatus == 0 && _globalFlags.myAGHeadBStatus == 2 && _globalFlags.myAGVisitedAltar == 0;
2343 }
2344
2345 return false;
2346 }
2347
constructMayanSceneObject(Window * viewWindow,const LocationStaticData & sceneStaticData,const Location & priorLocation)2348 SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
2349 // Special scene for the trial version
2350 if (_vm->isTrial())
2351 return new TrialRecallScene(_vm, viewWindow, sceneStaticData, priorLocation);
2352
2353 switch (sceneStaticData.classID) {
2354 case 0:
2355 // Default scene
2356 break;
2357 case 1:
2358 return new VideoDeath(_vm, viewWindow, sceneStaticData, priorLocation, 10, IDS_HUMAN_PRESENCE_500METERS);
2359 case 2:
2360 return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 60, 134, 118, 180, kItemCeramicBowl, 96, offsetof(GlobalFlags, myPickedUpCeramicBowl));
2361 case 3:
2362 return new PlaceCeramicBowl(_vm, viewWindow, sceneStaticData, priorLocation);
2363 case 4:
2364 return new ClickChangeDepth(_vm, viewWindow, sceneStaticData, priorLocation, 1, kCursorMagnifyingGlass, 0, 0, 432, 189);
2365 case 5:
2366 return new AdjustWheels(_vm, viewWindow, sceneStaticData, priorLocation);
2367 case 6:
2368 return new DateCombinationRead(_vm, viewWindow, sceneStaticData, priorLocation);
2369 case 7:
2370 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_INNER_DOOR_TRANS_TEXT, 16, 6, 402, 110, offsetof(GlobalFlags, myTPTextTranslated), offsetof(GlobalFlags, myTPTransBreathOfItzamna));
2371 case 8:
2372 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_INNER_LEFT_TRANS_TEXT, 1, 6, 431, 98, offsetof(GlobalFlags, myTPTextTranslated));
2373 case 9:
2374 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_INNER_MIDDLE_TRANS_TEXT, 16, 8, 430, 114, offsetof(GlobalFlags, myTPTextTranslated), offsetof(GlobalFlags, myTPCalendarTopTranslated));
2375 case 10:
2376 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_OUTER_SOUTHLEFT_TRANS_TEXT, 4, 55, 426, 95, offsetof(GlobalFlags, myTPTextTranslated));
2377 case 11:
2378 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_OUTER_WEST_TRANS_TEXT, 4, 72, 420, 108, offsetof(GlobalFlags, myTPTextTranslated));
2379 case 12:
2380 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_OUTER_NORTH_TRANS_TEXT, 6, 38, 428, 76, offsetof(GlobalFlags, myTPTextTranslated));
2381 case 13:
2382 return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 140, 124, 174, 158, kItemCavernSkull, 3, offsetof(GlobalFlags, myMCPickedUpSkull));
2383 case 14:
2384 return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
2385 case 15:
2386 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WG_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myWGTransDoorTop));
2387 case 16:
2388 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WG_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransWGOffering));
2389 case 17:
2390 return new GenericCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, kItemGoldCoins, 4, TRANSITION_WALK, -1, 1082, 13);
2391 case 18:
2392 return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
2393 case 19:
2394 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WATERGOD_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor));
2395 case 20:
2396 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WATERGOD_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransWTOffering));
2397 case 21:
2398 return new GenericCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, kItemWaterCanFull, 4, TRANSITION_WALK, -1, 1125, 13);
2399 case 22:
2400 return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
2401 case 23:
2402 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_AG_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor));
2403 case 24:
2404 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_AG_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransAGOffering));
2405 case 25:
2406 return new GenericCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, kItemBloodyArrow, 4, TRANSITION_WALK, -1, 1010, 12);
2407 case 26:
2408 return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
2409 case 27:
2410 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_DEATHGOD_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, offsetof(GlobalFlags, myMCTransDoor));
2411 case 28:
2412 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_DEATHGOD_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, offsetof(GlobalFlags, myMCTransDoor), offsetof(GlobalFlags, myMCTransDGOffering));
2413 case 29:
2414 return new DeathGodCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, 4, TRANSITION_WALK, -1, 1045, 13);
2415 case 30:
2416 return new WealthGodRopeDrop(_vm, viewWindow, sceneStaticData, priorLocation);
2417 case 31:
2418 return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 194, 106, 278, 126, kItemJadeBlock, 105, offsetof(GlobalFlags, myWGRetrievedJadeBlock));
2419 case 32:
2420 return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 140, 22, 306, 189, 2, 3, 0, 3, 1, 1, TRANSITION_WALK, -1, 264, 14, 14);
2421 case 33:
2422 return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 158, 88, 288, 116, kItemLimestoneBlock, 84, offsetof(GlobalFlags, myWTRetrievedLimestoneBlock));
2423 case 34:
2424 return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 80, 0, 332, 189, 2, 4, 0, 2, 1, 1, TRANSITION_WALK, -1, 401, 14, 14);
2425 case 35:
2426 return new WaterGodInitialWalkSetFlag(_vm, viewWindow, sceneStaticData, priorLocation);
2427 case 36:
2428 return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 0, 93, 37, 10, 73, false, 18);
2429 case 37:
2430 return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 166, 259, 37, 10, 73);
2431 case 38:
2432 return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 332, 425, 37, 10, 73);
2433 case 39:
2434 return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 498, 591, 37, 10, 73);
2435 case 40:
2436 return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 664, 757, 37, 10, 73);
2437 case 41:
2438 return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 830, 925, 37, 10, 71, true);
2439 case 42:
2440 return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 999, 1075, 37, 10, 73);
2441 case 43:
2442 return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1149, 1242, 37, 10, 73);
2443 case 44:
2444 return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1315, 1408, 37, 10, 73);
2445 case 45:
2446 return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1481, 1574, 37, 10, 73);
2447 case 46:
2448 return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1647, 1740, 37, 10, 73);
2449 case 47:
2450 return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1813, 1906, 37, 10, 73);
2451 case 50:
2452 return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation,106, 0, 294, 189, 2, 5, 0, 1, 1, 1, TRANSITION_WALK, -1, 427, 13, 11);
2453 case 51:
2454 return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 235, 144, 285, 181, kItemEntrySkull, 3, offsetof(GlobalFlags, myAGRetrievedEntrySkull));
2455 case 52:
2456 return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 200, 138, 231, 185, kItemSpearSkull, 46, offsetof(GlobalFlags, myAGRetrievedSpearSkull));
2457 case 53:
2458 return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 201, 4, 235, 22, kItemCopperMedallion, 45, offsetof(GlobalFlags, myAGRetrievedCopperMedal));
2459 case 54:
2460 return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 206, 110, 280, 142, kItemObsidianBlock, 72, offsetof(GlobalFlags, myAGRetrievedObsidianBlock));
2461 case 55:
2462 return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 0, 182, 87, 242, 189, 4, 75, 83, 79, 0, 2, 1, 3);
2463 case 56:
2464 return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 1, 194, 89, 256, 189, 10, 76, 84, 80, 4, 6, 5, 7);
2465 case 57:
2466 return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 2, 178, 93, 246, 189, 28, 77, 85, 81, 8, 10, 9, 11);
2467 case 58:
2468 return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 3, 188, 92, 252, 189, 34, 78, 86, 82, 12, 14, 13, 15);
2469 case 59:
2470 return new ArrowGodDepthChange(_vm, viewWindow, sceneStaticData, priorLocation);
2471 case 60:
2472 return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 11);
2473 case 65:
2474 return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 90, 15, 346, 189, 2, 6, 0, 0, 1, 1, TRANSITION_WALK, -1, 33, 12, 13);
2475 case 66:
2476 return new DeathGodAltar(_vm, viewWindow, sceneStaticData, priorLocation);
2477 case 67:
2478 return new DeathGodPuzzleBox(_vm, viewWindow, sceneStaticData, priorLocation);
2479 case 68:
2480 return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 206, 76, 246, 116, kItemEnvironCart, 53, offsetof(GlobalFlags, takenEnvironCart));
2481 case 69:
2482 return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 10);
2483 case 70:
2484 return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, offsetof(GlobalFlags, myMCStingerID), offsetof(GlobalFlags, myMCStingerChannelID), 11, 14);
2485 case 71:
2486 return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID, IDS_MBT_EVIDENCE_PRESENT);
2487 case 72:
2488 return new MainCavernGlassCapture(_vm, viewWindow, sceneStaticData, priorLocation);
2489 case 75:
2490 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 4500, 12, 14);
2491 case 76:
2492 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 64, 6333, 12);
2493 case 77:
2494 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 2, 1000, 2);
2495 case 78:
2496 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 2, 1000, 2, 14);
2497 case 79:
2498 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 6500, 12);
2499 case 80:
2500 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 16, 4750, 12);
2501 case 81:
2502 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 30, 7750, 6);
2503 case 82:
2504 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 16, 2250, 18);
2505 case 83:
2506 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 30, 2410, 6);
2507 case 84:
2508 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 64, 7666, 18);
2509 case 85:
2510 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 255, 0, -1, 10); // First param has to be wrong
2511 case 86:
2512 return new SetVolumeAndFlag(_vm, viewWindow, sceneStaticData, priorLocation, 64, offsetof(GlobalFlags, myWGSeenLowerPassage));
2513 case 87:
2514 return new SetVolumeAndFlag(_vm, viewWindow, sceneStaticData, priorLocation, 64, offsetof(GlobalFlags, myWGCrossedRopeBridge));
2515 case 88:
2516 return new SetVolumeAndFlag(_vm, viewWindow, sceneStaticData, priorLocation, 64);
2517 case 90:
2518 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 3160, 12, 14);
2519 case 91:
2520 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 64, 4160, 12);
2521 case 92:
2522 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 4160, 12);
2523 case 93:
2524 return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 16, 3160, 12);
2525 case 100:
2526 return new AdjustSecondaryAmbientOnEntry(_vm, viewWindow, sceneStaticData, priorLocation);
2527 case 101:
2528 return new WalkDualAmbientVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 16, 32, 6900, 12);
2529 case 102:
2530 return new WalkDualAmbientVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 64, 128, 6900, 12);
2531 case 103:
2532 return new PlaySoundEnteringFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 12, 2, 4, 4, 2, 1, 5);
2533 case 120:
2534 return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 10);
2535 case 121:
2536 return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
2537 case 125:
2538 return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 226, 90, 256, 104, kItemCopperMedallion, 15, offsetof(GlobalFlags, myAGRetrievedCopperMedal));
2539 case 126:
2540 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDS_MY_AG_ALTAR_TEXT, 120, 44, 330, 72, -1, -1, offsetof(GlobalFlags, myAGVisitedAltar));
2541 case 127:
2542 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDS_MY_WG_ALTAR_TEXT, 118, 14, 338, 44);
2543 case 128:
2544 return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDS_MY_WT_ALTAR_TEXT, 106, 128, 344, 162);
2545 default:
2546 warning("Unknown Mayan scene object %d", sceneStaticData.classID);
2547 break;
2548 }
2549
2550 return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
2551 }
2552
2553 } // End of namespace Buried
2554