Files
scummvm-cursorfix/engines/buried/environ/mayan.cpp
2026-02-02 04:50:13 +01:00

2872 lines
114 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* Additional copyright for this file:
* Copyright (C) 1995 Presto Studios, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "buried/avi_frames.h"
#include "buried/biochip_right.h"
#include "buried/buried.h"
#include "buried/gameui.h"
#include "buried/graphics.h"
#include "buried/invdata.h"
#include "buried/inventory_window.h"
#include "buried/navarrow.h"
#include "buried/resources.h"
#include "buried/scene_view.h"
#include "buried/sound.h"
#include "buried/environ/scene_base.h"
#include "buried/environ/scene_common.h"
#include "common/system.h"
#include "graphics/surface.h"
namespace Buried {
enum {
WAR_GOD_HEAD_TIMER_VALUE = 3000
};
class PlaceCeramicBowl : public SceneBase {
public:
PlaceCeramicBowl(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
int timerCallback(Window *viewWindow) override;
private:
bool _dropped;
};
PlaceCeramicBowl::PlaceCeramicBowl(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
_dropped = false;
}
int PlaceCeramicBowl::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
if (pointLocation.x == -1 && pointLocation.y == -1)
return SIC_REJECT;
if (itemID != kItemCeramicBowl)
return SIC_REJECT;
_staticData.navFrameIndex = 112;
viewWindow->invalidateWindow(false);
_dropped = true;
return SIC_ACCEPT;
}
int PlaceCeramicBowl::timerCallback(Window *viewWindow) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (_dropped) {
if (globalFlags.myTPCodeWheelStatus == 0) {
// Play slide death animation
sceneView->playSynchronousAnimation(4);
// Notify the player of his gruesome death
sceneView->showDeathScene(11);
return SC_DEATH;
} else {
// Kill the ambient
_vm->_sound->setAmbientSound();
// Jump to the start of the main cavern
DestinationScene newDest;
newDest.destinationScene.timeZone = 2;
newDest.destinationScene.environment = 2;
newDest.destinationScene.node = 0;
newDest.destinationScene.facing = 1;
newDest.destinationScene.orientation = 1;
newDest.destinationScene.depth = 0;
newDest.transitionType = TRANSITION_VIDEO;
newDest.transitionData = 3;
newDest.transitionStartFrame = -1;
newDest.transitionLength = -1;
sceneView->moveToDestination(newDest);
}
}
return SC_TRUE;
}
class AdjustWheels : public SceneBase {
public:
AdjustWheels(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
void preDestructor() override;
int paint(Window *viewWindow, Graphics::Surface *preBuffer) override;
int gdiPaint(Window *viewWindow) override;
int mouseUp(Window *viewWindow, const Common::Point &pointLocation) override;
int mouseMove(Window *viewWindow, const Common::Point &pointLocation) override;
int specifyCursor(Window *viewWindow, const Common::Point &pointLocation) override;
private:
AVIFrames _leftWheelFrames;
int _curLeftFrame;
AVIFrames _rightWheelFrames;
int _curRightFrame;
Common::Rect _leftUpRegion;
Common::Rect _leftDownRegion;
Common::Rect _rightUpRegion;
Common::Rect _rightDownRegion;
bool _translateText;
};
AdjustWheels::AdjustWheels(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
_curLeftFrame = globalFlags.myTPCodeWheelLeftIndex;
_curRightFrame = globalFlags.myTPCodeWheelRightIndex;
_leftUpRegion = Common::Rect(46, 0, 200, 70);
_leftDownRegion = Common::Rect(46, 106, 200, 189);
_rightUpRegion = Common::Rect(212, 0, 432, 66);
_rightDownRegion = Common::Rect(212, 109, 432, 189);
_translateText = false;
if (!_leftWheelFrames.open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 9)))
error("Failed to open left wheel frames video");
if (!_rightWheelFrames.open(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 10)))
error("Failed to open right wheel frames video");
}
void AdjustWheels::preDestructor() {
_leftWheelFrames.close();
_rightWheelFrames.close();
}
int AdjustWheels::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
if (_staticData.navFrameIndex >= 0) {
const Graphics::Surface *leftFrame = _leftWheelFrames.getFrame(_curLeftFrame);
if (leftFrame)
_vm->_gfx->crossBlit(preBuffer, 0, 0, 208, 189, leftFrame, 0, 0);
const Graphics::Surface *rightFrame = _rightWheelFrames.getFrame(_curRightFrame);
if (rightFrame)
_vm->_gfx->crossBlit(preBuffer, 208, 0, 224, 189, rightFrame, 0, 0);
}
return SC_REPAINT;
}
int AdjustWheels::gdiPaint(Window *viewWindow) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (_translateText && globalFlags.bcTranslateEnabled == 1) {
Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
Common::Rect rect(168, 70, 262, 108);
rect.translate(absoluteRect.left, absoluteRect.top);
_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
}
return SC_REPAINT;
}
int AdjustWheels::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
// TODO: Wait between frames after figuring out timing
if (_leftUpRegion.contains(pointLocation) || _leftDownRegion.contains(pointLocation) ||
_rightUpRegion.contains(pointLocation) || _rightDownRegion.contains(pointLocation)) {
if (_leftDownRegion.contains(pointLocation)) {
// Move the wheel one frame and redraw
_curLeftFrame++;
if (_curLeftFrame > _leftWheelFrames.getFrameCount() - 1)
_curLeftFrame = 0;
viewWindow->invalidateWindow(false);
// And again for the final frame
_curLeftFrame++;
if (_curLeftFrame > _leftWheelFrames.getFrameCount() - 1)
_curLeftFrame = 0;
viewWindow->invalidateWindow(false);
} else if (_leftUpRegion.contains(pointLocation)) {
// Move the wheel one frame and redraw
_curLeftFrame--;
if (_curLeftFrame < 0)
_curLeftFrame = _leftWheelFrames.getFrameCount() - 1;
viewWindow->invalidateWindow(false);
// And again for the final frame
_curLeftFrame--;
if (_curLeftFrame < 0)
_curLeftFrame = _leftWheelFrames.getFrameCount() - 1;
viewWindow->invalidateWindow(false);
} else if (_rightDownRegion.contains(pointLocation)) {
// Move the wheel one frame and redraw
_curRightFrame++;
if (_curRightFrame > _rightWheelFrames.getFrameCount() - 1)
_curRightFrame = 0;
viewWindow->invalidateWindow(false);
// And again for the final frame
_curRightFrame++;
if (_curRightFrame > _rightWheelFrames.getFrameCount() - 1)
_curRightFrame = 0;
viewWindow->invalidateWindow(false);
} else if (_rightUpRegion.contains(pointLocation)) {
// Move the wheel one frame and redraw
_curRightFrame--;
if (_curRightFrame < 0)
_curRightFrame = _rightWheelFrames.getFrameCount() - 1;
viewWindow->invalidateWindow(false);
// And again for the final frame
_curRightFrame--;
if (_curRightFrame < 0)
_curRightFrame = _rightWheelFrames.getFrameCount() - 1;
viewWindow->invalidateWindow(false);
}
globalFlags.myTPCodeWheelLeftIndex = _curLeftFrame;
globalFlags.myTPCodeWheelRightIndex = _curRightFrame;
byte status = 0;
if (_curLeftFrame == 8 && _curRightFrame == 12)
status = 1;
else if (_curLeftFrame == 16 && _curRightFrame == 22)
status = 1;
else if (_curLeftFrame == 20 && _curRightFrame == 4)
status = 1;
else if (_curLeftFrame == 0 && _curRightFrame == 24)
status = 1;
else if (_curLeftFrame == 14 && _curRightFrame == 8)
status = 1;
else if (_curLeftFrame == 6 && _curRightFrame == 6)
status = 1;
else if (_curLeftFrame == 6 && _curRightFrame == 30)
status = 1;
else if (_curLeftFrame == 24 && _curRightFrame == 0)
status = 1;
else if (_curLeftFrame == 10 && _curRightFrame == 28)
status = 1;
globalFlags.myTPCodeWheelStatus = status;
return SC_TRUE;
}
// Did not click on the wheels, pop back to depth 0
DestinationScene newDest;
newDest.destinationScene = _staticData.location;
newDest.destinationScene.depth = 0;
newDest.transitionType = TRANSITION_NONE;
newDest.transitionData = -1;
newDest.transitionStartFrame = -1;
newDest.transitionLength = -1;
sceneView->moveToDestination(newDest);
return SC_TRUE;
}
int AdjustWheels::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (globalFlags.bcTranslateEnabled == 1) {
Common::Rect translateTextRegion(168, 72, 260, 106);
if (translateTextRegion.contains(pointLocation)) {
if (!_translateText) {
Common::String leftText = _vm->getString(IDMYTP_WHEELS_LEFT_TRANS_TEXT_BASE + _curLeftFrame / 2);
Common::String rightText = _vm->getString(IDMYTP_WHEELS_RIGHT_TRANS_TEXT_BASE + _curRightFrame / 2);
Common::String finalString = leftText + rightText;
if (globalFlags.generalWalkthroughMode == 1 &&
globalFlags.myTPCodeWheelStatus == 1) {
if (_vm->getVersion() >= MAKEVERSION(1, 0, 4, 0))
finalString += _vm->getString(IDS_MYTP_WALKTHROUGH_HINT_TEXT);
else
finalString += " (Mayan Sacred Day)";
}
sceneView->displayTranslationText(finalString);
_translateText = true;
viewWindow->invalidateWindow(false);
}
} else {
if (_translateText) {
_translateText = false;
viewWindow->invalidateWindow(false);
}
}
return SC_TRUE;
}
return SC_FALSE;
}
int AdjustWheels::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
if (_leftUpRegion.contains(pointLocation) || _rightUpRegion.contains(pointLocation))
return kCursorArrowUp;
if (_leftDownRegion.contains(pointLocation) || _rightDownRegion.contains(pointLocation))
return kCursorArrowDown;
return kCursorPutDown;
}
class DateCombinationRead : public SceneBase {
public:
DateCombinationRead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
int gdiPaint(Window *viewWindow) override;
int mouseMove(Window *viewWindow, const Common::Point &pointLocation) override;
private:
int _currentRegion;
};
DateCombinationRead::DateCombinationRead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
_currentRegion = -1;
}
int DateCombinationRead::gdiPaint(Window *viewWindow) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (_currentRegion >= 0 && globalFlags.bcTranslateEnabled == 1) {
Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
int left = _currentRegion * 43 + 20 + absoluteRect.left;
Common::Rect rect(left, absoluteRect.top + 18, left + 43, absoluteRect.top + 110);
_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
}
return SC_REPAINT;
}
int DateCombinationRead::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (globalFlags.bcTranslateEnabled == 1) {
Common::Rect symbols(20, 18, 407, 110);
if (symbols.contains(pointLocation)) {
int translatedSymbolIndex = (pointLocation.x - 20) / 43;
if (_currentRegion != translatedSymbolIndex) {
// Update flags
globalFlags.myTPCalendarListTranslated = 1;
globalFlags.myTPTextTranslated = 1;
// Display the text
sceneView->displayTranslationText(_vm->getString(IDMYTP_WALLS_COMBO_TRANS_TEXT_BASE + translatedSymbolIndex));
// Reset the current region and redraw
_currentRegion = translatedSymbolIndex;
viewWindow->invalidateWindow(false);
}
} else {
if (_currentRegion >= 0) {
_currentRegion = -1;
viewWindow->invalidateWindow(false);
}
}
return SC_TRUE;
}
return SC_FALSE;
}
class ViewSingleTranslation : public SceneBase {
public:
ViewSingleTranslation(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
int translatedTextID, int left, int top, int right, int bottom,
byte &flagA, byte &flagB, byte &visitedFlag);
int gdiPaint(Window *viewWindow) override;
int mouseUp(Window *viewWindow, const Common::Point &pointLocation) override;
int mouseMove(Window *viewWindow, const Common::Point &pointLocation) override;
int specifyCursor(Window *viewWindow, const Common::Point &pointLocation) override;
private:
bool _textTranslated;
int _textID;
Common::Rect _clickableRegion;
byte &_flagA;
byte &_flagB;
};
ViewSingleTranslation::ViewSingleTranslation(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
int translatedTextID, int left, int top, int right, int bottom,
byte &flagA, byte &flagB, byte &visitedFlag) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation),
_flagA(flagA), _flagB(flagB) {
_textTranslated = false;
_textID = translatedTextID;
_clickableRegion = Common::Rect(left, top, right, bottom);
visitedFlag = 1;
}
int ViewSingleTranslation::gdiPaint(Window *viewWindow) {
// Draw the translated box, if applicable
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
if (_textTranslated && sceneView->getGlobalFlags().bcTranslateEnabled == 1) {
Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
Common::Rect rect(_clickableRegion);
rect.translate(absoluteRect.left, absoluteRect.top);
_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
}
return SC_REPAINT;
}
int ViewSingleTranslation::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
if (_staticData.location.depth != 0) {
// If we're not at depth zero, move to depth zero
Location newLocation = _staticData.location;
newLocation.depth = 0;
sceneView->jumpToScene(newLocation);
return SC_TRUE;
}
return SC_FALSE;
}
int ViewSingleTranslation::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
if (sceneView->getGlobalFlags().bcTranslateEnabled == 1) {
if (_clickableRegion.contains(pointLocation)) {
// Make sure we didn't already render the text
if (!_textTranslated) {
_flagA = 1;
_flagB = 1;
// Load and display the text
sceneView->displayTranslationText(_vm->getString(_textID));
_textTranslated = true;
viewWindow->invalidateWindow(false);
}
} else {
if (_textTranslated) {
_textTranslated = false;
viewWindow->invalidateWindow(false);
}
}
return SC_TRUE;
}
return SC_FALSE;
}
int ViewSingleTranslation::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
if (_staticData.location.depth != 0)
return kCursorPutDown;
return kCursorArrow;
}
class GenericCavernDoorMainView : public SceneBase {
public:
GenericCavernDoorMainView(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
int topZoomDepth = 0, int topLeft = -1, int topTop = -1, int topRight = -1, int topBottom = -1,
int rightZoomDepth = 0, int rightLeft = -1, int rightTop = -1, int rightRight = -1, int rightBottom = -1,
int offeringHeadZoomDepth = 0, int offeringHeadLeft = -1, int offeringHeadTop = -1, int offeringHeadRight = -1, int offeringHeadBottom = -1);
int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
int mouseUp(Window *viewWindow, const Common::Point &pointLocation) override;
int specifyCursor(Window *viewWindow, const Common::Point &pointLocation) override;
private:
int _topZoomDepth;
int _rightZoomDepth;
int _offeringHeadZoomDepth;
Common::Rect _topZoomRegion;
Common::Rect _rightZoomRegion;
Common::Rect _offeringHeadZoomRegion;
};
GenericCavernDoorMainView::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) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
_topZoomDepth = topZoomDepth;
_rightZoomDepth = rightZoomDepth;
_offeringHeadZoomDepth = offeringHeadZoomDepth;
_topZoomRegion = Common::Rect(topLeft, topTop, topRight, topBottom);
_rightZoomRegion = Common::Rect(rightLeft, rightTop, rightRight, rightBottom);
_offeringHeadZoomRegion = Common::Rect(offeringHeadLeft, offeringHeadTop, offeringHeadRight, offeringHeadBottom);
if (_staticData.location.node == 7)
globalFlags.myMCViewedDeathGodDoor = 1;
}
int GenericCavernDoorMainView::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
Location &loc = _staticData.location;
if (loc.node == 7 && (loc.timeZone != priorLocation.timeZone ||
loc.environment != priorLocation.environment || loc.node != priorLocation.node ||
loc.facing != priorLocation.facing || loc.orientation != priorLocation.orientation ||
loc.depth != priorLocation.depth) && !sceneView->isNumberInGlobalFlagTable(MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID))
sceneView->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
return SC_TRUE;
}
int GenericCavernDoorMainView::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
// Build a default structure
DestinationScene newDestination;
newDestination.destinationScene = _staticData.location;
newDestination.transitionType = TRANSITION_FADE;
newDestination.transitionData = -1;
newDestination.transitionStartFrame = -1;
newDestination.transitionLength = -1;
if (_topZoomRegion.contains(pointLocation)) {
newDestination.destinationScene.depth = _topZoomDepth;
sceneView->moveToDestination(newDestination);
return SC_TRUE;
}
if (_rightZoomRegion.contains(pointLocation)) {
newDestination.destinationScene.depth = _rightZoomDepth;
sceneView->moveToDestination(newDestination);
return SC_TRUE;
}
if (_offeringHeadZoomRegion.contains(pointLocation)) {
newDestination.destinationScene.depth = _offeringHeadZoomDepth;
sceneView->moveToDestination(newDestination);
return SC_TRUE;
}
return SC_FALSE;
}
int GenericCavernDoorMainView::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
if (_topZoomRegion.contains(pointLocation) || _rightZoomRegion.contains(pointLocation) || _offeringHeadZoomRegion.contains(pointLocation))
return kCursorMagnifyingGlass;
return kCursorArrow;
}
class GenericCavernDoorOfferingHead : public SceneBase {
public:
GenericCavernDoorOfferingHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
int correctOfferingID = -1, int correctOfferingDestDepth = 0, int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1);
int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
int mouseUp(Window *viewWindow, const Common::Point &pointLocation) override;
int specifyCursor(Window *viewWindow, const Common::Point &pointLocation) override;
private:
DestinationScene _correctDestination;
int _correctOfferingID;
Common::Rect _dropRegion;
bool isValidItemToDrop(Window *viewWindow, int itemID);
};
GenericCavernDoorOfferingHead::GenericCavernDoorOfferingHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
int correctOfferingID, int correctOfferingDestDepth, int transitionType, int transitionData, int transitionStartFrame, int transitionLength) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
_correctDestination.destinationScene = _staticData.location;
_correctDestination.destinationScene.depth = correctOfferingDestDepth;
_correctDestination.transitionType = transitionType;
_correctDestination.transitionData = transitionData;
_correctDestination.transitionStartFrame = transitionStartFrame;
_correctDestination.transitionLength = transitionLength;
_correctOfferingID = correctOfferingID;
_dropRegion = Common::Rect(24, 92, 226, 154);
}
int GenericCavernDoorOfferingHead::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
// If this is walkthrough mode, only accept the correct item
if (isValidItemToDrop(viewWindow, itemID) && _dropRegion.contains(pointLocation))
return 1;
return 0;
}
int GenericCavernDoorOfferingHead::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
if (pointLocation.x == -1 && pointLocation.y == -1)
return SIC_REJECT;
if (!isValidItemToDrop(viewWindow, itemID))
return SIC_REJECT;
if (_dropRegion.contains(pointLocation)) {
switch (itemID) {
case kItemBalconyKey:
sceneView->playSynchronousAnimation(2);
break;
case kItemBloodyArrow:
sceneView->playSynchronousAnimation(3);
break;
case kItemObsidianBlock:
sceneView->playSynchronousAnimation(5);
break;
case kItemCoilOfRope:
sceneView->playSynchronousAnimation(6);
break;
case kItemCopperKey:
sceneView->playSynchronousAnimation(7);
break;
case kItemCopperMedallion:
sceneView->playSynchronousAnimation(8);
break;
case kItemCeramicBowl:
sceneView->playSynchronousAnimation(9);
break;
case kItemGrapplingHook:
sceneView->playSynchronousAnimation(10);
break;
case kItemHammer:
sceneView->playSynchronousAnimation(11);
break;
case kItemPreservedHeart:
sceneView->playSynchronousAnimation(12);
break;
case kItemJadeBlock:
sceneView->playSynchronousAnimation(13);
break;
case kItemLimestoneBlock:
sceneView->playSynchronousAnimation(14);
break;
case kItemMetalBar:
sceneView->playSynchronousAnimation(15);
break;
case kItemCavernSkull:
sceneView->playSynchronousAnimation(16);
break;
case kItemEntrySkull:
sceneView->playSynchronousAnimation(17);
break;
case kItemSpearSkull:
sceneView->playSynchronousAnimation(18);
break;
case kItemWaterCanFull:
sceneView->playSynchronousAnimation(19);
break;
case kItemWoodenPegs:
sceneView->playSynchronousAnimation(20);
break;
case kItemGoldCoins:
sceneView->playSynchronousAnimation(21);
break;
}
// Reset the offering flag
sceneView->getGlobalFlags().myMCTransMadeAnOffering = 1;
// If this was the correct offering, move to the open door scene
if (itemID == _correctOfferingID) {
_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 10), 128, false, true);
sceneView->moveToDestination(_correctDestination);
}
// These items don't get consumed
if (itemID == kItemWaterCanFull || itemID == kItemGoldCoins)
return SIC_REJECT;
return SIC_ACCEPT;
}
return SIC_REJECT;
}
int GenericCavernDoorOfferingHead::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
Location newLocation = _staticData.location;
newLocation.depth = 0;
sceneView->jumpToScene(newLocation);
return SC_TRUE;
}
int GenericCavernDoorOfferingHead::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
return kCursorPutDown;
}
bool GenericCavernDoorOfferingHead::isValidItemToDrop(Window *viewWindow, int itemID) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
// If this is walkthrough mode, only accept the correct item
if (globalFlags.generalWalkthroughMode == 1) {
if (itemID == _correctOfferingID || (_staticData.location.node == 8 && itemID == kItemBloodyArrow))
return true;
return false;
}
// Otherwise, any of the allowed items
switch (itemID) {
case kItemCavernSkull:
case kItemEntrySkull:
case kItemSpearSkull:
case kItemBloodyArrow:
case kItemCopperMedallion:
case kItemCoilOfRope:
case kItemCopperKey:
case kItemJadeBlock:
case kItemLimestoneBlock:
case kItemObsidianBlock:
case kItemGrapplingHook:
case kItemPreservedHeart:
case kItemHammer:
case kItemGoldCoins:
case kItemWaterCanEmpty:
case kItemWaterCanFull:
case kItemWoodenPegs:
case kItemBalconyKey:
case kItemBurnedLetter: // Can't actually drop this, though
return true;
}
return false;
}
class DeathGodCavernDoorOfferingHead : public SceneBase {
public:
DeathGodCavernDoorOfferingHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
int correctOfferingDestDepth = 0, int transitionType = -1, int transitionData = -1, int transitionStartFrame = -1, int transitionLength = -1);
int preExitRoom(Window *viewWindow, const Location &newLocation) override;
int mouseUp(Window *viewWindow, const Common::Point &pointLocation) override;
int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
int specifyCursor(Window *viewWindow, const Common::Point &pointLocation) override;
private:
DestinationScene _correctDestination;
Common::Rect _dropRegion;
};
DeathGodCavernDoorOfferingHead::DeathGodCavernDoorOfferingHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
int correctOfferingDestDepth, int transitionType, int transitionData, int transitionStartFrame, int transitionLength) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
_correctDestination.destinationScene = _staticData.location;
_correctDestination.destinationScene.depth = correctOfferingDestDepth;
_correctDestination.transitionType = transitionType;
_correctDestination.transitionData = transitionData;
_correctDestination.transitionStartFrame = transitionStartFrame;
_correctDestination.transitionLength = transitionLength;
_dropRegion = Common::Rect(50, 76, 228, 182);
byte offerings = globalFlags.myMCDeathGodOfferings;
if (offerings & 1) {
if (offerings & 2) {
if (offerings & 4)
_staticData.navFrameIndex = 190;
else
_staticData.navFrameIndex = 189;
} else if (offerings & 4) {
_staticData.navFrameIndex = 188;
} else {
_staticData.navFrameIndex = 186;
}
} else if (offerings & 2) {
if (offerings & 4)
_staticData.navFrameIndex = 187;
else
_staticData.navFrameIndex = 185;
} else if (offerings & 4) {
_staticData.navFrameIndex = 184;
}
}
int DeathGodCavernDoorOfferingHead::preExitRoom(Window *viewWindow, const Location &newLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
InventoryWindow *inventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow;
// Put any pieces placed in the head back in the inventory
byte &offerings = globalFlags.myMCDeathGodOfferings;
if (offerings & 1)
inventoryWindow->addItem(kItemObsidianBlock);
if (offerings & 2)
inventoryWindow->addItem(kItemJadeBlock);
if (offerings & 4)
inventoryWindow->addItem(kItemLimestoneBlock);
offerings = 0;
return SC_TRUE;
}
int DeathGodCavernDoorOfferingHead::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
// Return to depth zero
DestinationScene newDest;
newDest.destinationScene = _staticData.location;
newDest.destinationScene.depth = 0;
newDest.transitionType = TRANSITION_NONE;
newDest.transitionData = -1;
newDest.transitionStartFrame = -1;
newDest.transitionLength = -1;
sceneView->moveToDestination(newDest);
return SC_TRUE;
}
int DeathGodCavernDoorOfferingHead::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if ((itemID == kItemJadeBlock || itemID == kItemLimestoneBlock || itemID == kItemObsidianBlock) && _dropRegion.contains(pointLocation)) {
byte offerings = globalFlags.myMCDeathGodOfferings;
if ((offerings & 1) != 0 && itemID == kItemObsidianBlock)
return 0;
if ((offerings & 2) != 0 && itemID == kItemJadeBlock)
return 0;
if ((offerings & 4) != 0 && itemID == kItemLimestoneBlock)
return 0;
return 1;
}
return 0;
}
int DeathGodCavernDoorOfferingHead::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (pointLocation.x == -1 && pointLocation.y == -1)
return SIC_REJECT;
if ((itemID == kItemJadeBlock || itemID == kItemLimestoneBlock || itemID == kItemObsidianBlock) && _dropRegion.contains(pointLocation)) {
byte &offerings = globalFlags.myMCDeathGodOfferings;
// Make sure we didn't already place the item
if ((offerings & 1) != 0 && itemID == kItemObsidianBlock)
return SIC_REJECT;
if ((offerings & 2) != 0 && itemID == kItemJadeBlock)
return SIC_REJECT;
if ((offerings & 4) != 0 && itemID == kItemLimestoneBlock)
return SIC_REJECT;
// Add the item
if (itemID == kItemObsidianBlock)
offerings |= 1;
else if (itemID == kItemJadeBlock)
offerings |= 2;
else if (itemID == kItemLimestoneBlock)
offerings |= 4;
// Change the image
if (offerings & 1) {
if (offerings & 2) {
if (offerings & 4)
_staticData.navFrameIndex = 190;
else
_staticData.navFrameIndex = 189;
} else if (offerings & 4) {
_staticData.navFrameIndex = 188;
} else {
_staticData.navFrameIndex = 186;
}
} else if (offerings & 2) {
if (offerings & 4)
_staticData.navFrameIndex = 187;
else
_staticData.navFrameIndex = 185;
} else if (offerings & 4) {
_staticData.navFrameIndex = 184;
} else {
_staticData.navFrameIndex = 152;
}
viewWindow->invalidateWindow(false);
if ((offerings & 1) != 0 && (offerings & 2) != 0 && (offerings & 4) != 0) {
_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 10), 128, false, true);
sceneView->moveToDestination(_correctDestination);
}
return SIC_ACCEPT;
}
return SIC_REJECT;
}
int DeathGodCavernDoorOfferingHead::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
return kCursorPutDown;
}
class WealthGodRopeDrop : public SceneBase {
public:
WealthGodRopeDrop(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
private:
Common::Rect _dropRope;
};
WealthGodRopeDrop::WealthGodRopeDrop(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (globalFlags.myWGPlacedRope == 1)
_staticData.navFrameIndex = 121;
_dropRope = Common::Rect(222, 149, 282, 189);
}
int WealthGodRopeDrop::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (globalFlags.myWGPlacedRope != 0) {
Location newLocation = _staticData.location;
newLocation.depth = 1;
sceneView->jumpToScene(newLocation);
}
return SC_TRUE;
}
int WealthGodRopeDrop::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
// OK, I honestly didn't know you could use the grappling hook here
if (_dropRope.contains(pointLocation) && (itemID == kItemCoilOfRope || itemID == kItemGrapplingHook))
return 1;
return 0;
}
int WealthGodRopeDrop::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (pointLocation.x == -1 && pointLocation.y == -1)
return SIC_REJECT;
if (_dropRope.contains(pointLocation) && (itemID == kItemCoilOfRope || itemID == kItemGrapplingHook)) {
globalFlags.myWGPlacedRope = 1;
Location newLocation = _staticData.location;
newLocation.depth = 1;
sceneView->jumpToScene(newLocation);
return SIC_ACCEPT;
}
return SIC_REJECT;
}
class WaterGodInitialWalkSetFlag : public SceneBase {
public:
WaterGodInitialWalkSetFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
};
WaterGodInitialWalkSetFlag::WaterGodInitialWalkSetFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
// Set flag on entry
globalFlags.myWTCurrentBridgeStatus = 1;
}
class WaterGodBridgeJump : public SceneBase {
public:
WaterGodBridgeJump(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
int movieFileNameID = 0, int playingStartingFrame = 0, int sequenceStartingFrame = 0, int framesPerCycle = 0,
int jumpFudgeFrames = 0, int sequenceLength = 0, bool jumpMidCycle = false, int frameOffsetToEndOfSwing = 0);
int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
int preExitRoom(Window *viewWindow, const Location &newLocation) override;
int postExitRoom(Window *viewWindow, const Location &newLocation) override;
int timerCallback(Window *viewWindow) override;
int movieCallback(Window *viewWindow, VideoWindow *movie, int animationID, int status) override;
private:
int _movieID;
int _startingMovieFrame;
int _playingStartingFrame;
int _framesPerCycle;
int _sequenceLength;
int _jumpFudgeFrames;
int _finalFrameIndex;
int _soundID;
DestinationScene _savedDestForward;
bool _jumpMidCycle;
int _frameOffsetToEndOfSwing;
};
WaterGodBridgeJump::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) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
_movieID = movieFileNameID;
_playingStartingFrame = playingStartingFrame;
_startingMovieFrame = sequenceStartingFrame;
_framesPerCycle = framesPerCycle;
_sequenceLength = sequenceLength;
_jumpFudgeFrames = jumpFudgeFrames;
_finalFrameIndex = -1;
_soundID = -1;
_jumpMidCycle = jumpMidCycle;
_frameOffsetToEndOfSwing = frameOffsetToEndOfSwing;
// Save the forward movement data for later
_savedDestForward = _staticData.destForward;
_staticData.destForward.destinationScene = Location(-1, -1, -1, -1, -1, -1);
_staticData.destForward.transitionType = -1;
_staticData.destForward.transitionData = -1;
_staticData.destForward.transitionStartFrame = -1;
_staticData.destForward.transitionLength = -1;
// Set visited flag
globalFlags.myWTSteppedOnSwings = 1;
}
int WaterGodBridgeJump::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
// Raise the ambient sound
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
uint32 ambientPos = _vm->_sound->getSecondaryAmbientPosition();
int frameStartingOffset = (ambientPos / 1838) % _sequenceLength + (_startingMovieFrame - _playingStartingFrame) % _sequenceLength;
// Load and start the new asynchronous animation
sceneView->startAsynchronousAnimation(_movieID, _startingMovieFrame, _playingStartingFrame + frameStartingOffset, _sequenceLength, true);
return SC_TRUE;
}
int WaterGodBridgeJump::preExitRoom(Window *viewWindow, const Location &newLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
_finalFrameIndex = sceneView->getAsynchronousAnimationCurrentPosition();
// Moving to another node should kill the anim
if (newLocation.node != 4 || newLocation.timeZone != 2 || newLocation.environment != 4)
sceneView->stopAsynchronousAnimation();
// If we are walking into a node less than 5, kill the ambient
if (newLocation.node <= 3)
_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
return SC_TRUE;
}
int WaterGodBridgeJump::postExitRoom(Window *viewWindow, const Location &newLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
if (newLocation.facing == _staticData.location.facing && newLocation.timeZone == _staticData.location.timeZone &&
newLocation.environment == _staticData.location.environment) {
if (_jumpMidCycle) {
int diff = (_finalFrameIndex - _playingStartingFrame) % (_framesPerCycle * 2);
int diffB = (_finalFrameIndex - _playingStartingFrame - _framesPerCycle) % _framesPerCycle;
int diffC = _framesPerCycle - (_finalFrameIndex - _playingStartingFrame) % _framesPerCycle;
if (diff > _framesPerCycle || diffB > _framesPerCycle || diffC > _jumpFudgeFrames * 2) {
if (_staticData.location.facing == 0)
sceneView->showDeathScene(14);
else
sceneView->showDeathScene(15);
return SC_DEATH;
}
} else {
if ((_finalFrameIndex - _playingStartingFrame) % _framesPerCycle > _jumpFudgeFrames && _framesPerCycle - (_finalFrameIndex - _playingStartingFrame) % _framesPerCycle > _jumpFudgeFrames) {
if (_staticData.location.facing == 0)
sceneView->showDeathScene(14);
else
sceneView->showDeathScene(15);
return SC_DEATH;
}
}
}
return SC_TRUE;
}
int WaterGodBridgeJump::timerCallback(Window *viewWindow) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
NavArrowWindow *navArrow = ((GameUIWindow *)viewWindow->getParent())->_navArrowWindow;
// If we have reached the end of the starting sequence, reset the arrows
if (_staticData.destForward.destinationScene.timeZone == -1 && sceneView->getAsynchronousAnimationCurrentPosition() >= _startingMovieFrame) {
_staticData.destForward = _savedDestForward;
navArrow->updateAllArrows(_staticData);
}
return SC_TRUE;
}
int WaterGodBridgeJump::movieCallback(Window *viewWindow, VideoWindow *movie, int animationID, int status) {
if (status == MOVIE_LOOPING_RESTART)
_vm->_sound->restartSecondaryAmbientSound();
return SC_TRUE;
}
class ArrowGodHead : public SceneBase {
public:
ArrowGodHead(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
int headID = 0, int clickLeft = -1, int clickTop = -1, int clickRight = -1, int clickBottom = -1,
int emptyClosedStill = -1, int emptyOpenStill = -1, int fullClosedStill = -1, int fullOpenStill = -1,
int emptyClosedAnim = -1, int emptyOpenAnim = -1, int fullClosedAnim = -1, int fullOpenAnim = -1);
int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
int mouseDown(Window *viewWindow, const Common::Point &pointLocation) override;
int mouseUp(Window *viewWindow, const Common::Point &pointLocation) override;
int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
int specifyCursor(Window *viewWindow, const Common::Point &pointLocation) override;
int timerCallback(Window *viewWindow) override;
private:
int _headID;
Common::Rect _skullRegion;
int _stillFrames[4];
int _soundID;
int _headAnimations[4];
GlobalFlags &_globalFlags;
uint32 *headOpenedTime(byte headId);
uint32 getHeadOpenedTime(byte headId);
void setHeadOpenedTime(byte headId, uint32 value);
byte *headTouched(byte headId);
void setHeadTouched(byte value);
byte *headStatus(byte headId);
byte getHeadStatus();
byte getHeadStatus(byte headId);
void setHeadStatus(byte headId, byte value);
void setHeadStatus(byte value);
byte *headStatusSkullId(byte headId);
byte getHeadStatusSkullId();
void setHeadStatusSkullId(byte value);
};
ArrowGodHead::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) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation),
_globalFlags(((SceneViewWindow *)viewWindow)->getGlobalFlags()) {
_soundID = -1;
_headID = headID;
_skullRegion = Common::Rect(clickLeft, clickTop, clickRight, clickBottom);
_stillFrames[0] = emptyClosedStill;
_stillFrames[1] = emptyOpenStill;
_stillFrames[2] = fullClosedStill;
_stillFrames[3] = fullOpenStill;
_headAnimations[0] = emptyClosedAnim;
_headAnimations[1] = emptyOpenAnim;
_headAnimations[2] = fullClosedAnim;
_headAnimations[3] = fullOpenAnim;
_staticData.navFrameIndex = _stillFrames[getHeadStatus()];
}
uint32 *ArrowGodHead::headOpenedTime(byte headId) {
switch (headId) {
case 0:
return &_globalFlags.myAGHeadAOpenedTime;
case 1:
return &_globalFlags.myAGHeadBOpenedTime;
case 2:
return &_globalFlags.myAGHeadCOpenedTime;
case 3:
return &_globalFlags.myAGHeadDOpenedTime;
default:
return nullptr;
}
}
uint32 ArrowGodHead::getHeadOpenedTime(byte headId) {
uint32 *openedTime = headOpenedTime(headId);
return openedTime ? *openedTime : 0;
}
void ArrowGodHead::setHeadOpenedTime(byte headId, uint32 value) {
uint32 *openedTime = headOpenedTime(headId);
if (openedTime)
*openedTime = value;
}
byte *ArrowGodHead::headTouched(byte headId) {
switch (headId) {
case 0:
return &_globalFlags.myAGHeadATouched;
case 1:
return &_globalFlags.myAGHeadBTouched;
case 2:
return &_globalFlags.myAGHeadCTouched;
case 3:
return &_globalFlags.myAGHeadDTouched;
default:
return nullptr;
}
}
void ArrowGodHead::setHeadTouched(byte value) {
byte *touched = headTouched(_headID);
if (touched)
*touched = value;
}
byte *ArrowGodHead::headStatus(byte headId) {
switch (headId) {
case 0:
return &_globalFlags.myAGHeadAStatus;
case 1:
return &_globalFlags.myAGHeadBStatus;
case 2:
return &_globalFlags.myAGHeadCStatus;
case 3:
return &_globalFlags.myAGHeadDStatus;
default:
return nullptr;
}
}
byte ArrowGodHead::getHeadStatus() {
return getHeadStatus(_headID);
}
byte ArrowGodHead::getHeadStatus(byte headId) {
byte *status = headStatus(headId);
return status ? *status : 0;
}
void ArrowGodHead::setHeadStatus(byte value) {
setHeadStatus(_headID, value);
}
void ArrowGodHead::setHeadStatus(byte headId, byte value) {
byte *status = headStatus(headId);
if (status)
*status = value;
}
byte *ArrowGodHead::headStatusSkullId(byte headId) {
switch (headId) {
case 0:
return &_globalFlags.myAGHeadAStatusSkullID;
case 1:
return &_globalFlags.myAGHeadBStatusSkullID;
case 2:
return &_globalFlags.myAGHeadCStatusSkullID;
case 3:
return &_globalFlags.myAGHeadDStatusSkullID;
default:
return nullptr;
}
}
byte ArrowGodHead::getHeadStatusSkullId() {
byte *status = headStatusSkullId(_headID);
return status ? *status : 0;
}
void ArrowGodHead::setHeadStatusSkullId(byte value) {
byte *status = headStatusSkullId(_headID);
if (status)
*status = value;
}
int ArrowGodHead::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
byte headAStatus = _globalFlags.myAGHeadAStatus;
byte headDStatus = _globalFlags.myAGHeadDStatus;
if (_staticData.location.node == 0) {
if (headAStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
else if (headDStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
else
_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
} else if (_staticData.location.node == 2) {
if (headAStatus == 0 || headDStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
else
_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
}
return SC_TRUE;
}
int ArrowGodHead::mouseDown(Window *viewWindow, const Common::Point &pointLocation) {
BioChipRightWindow *bioChipRightWindow = ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow;
InventoryWindow *inventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow;
// For walkthrough mode, don't allow input
if (_globalFlags.generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
return SC_FALSE;
if (_skullRegion.contains(pointLocation) && getHeadStatus() == 3) {
byte skullIndex = getHeadStatusSkullId();
setHeadStatusSkullId(0);
setHeadStatus(1);
_staticData.navFrameIndex = _stillFrames[1];
setHeadTouched(1);
// Begin dragging
Common::Point ptInventoryWindow = viewWindow->convertPointToWindow(pointLocation, inventoryWindow);
inventoryWindow->startDraggingNewItem(skullIndex, ptInventoryWindow);
bioChipRightWindow->sceneChanged();
return SC_TRUE;
}
return SC_FALSE;
}
int ArrowGodHead::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
BioChipRightWindow *bioChipRightWindow = ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow;
Location &loc = _staticData.location;
// For walkthrough mode, don't allow input
if (_globalFlags.generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
return SC_FALSE;
// Did we click on the head?
if (_skullRegion.contains(pointLocation)) {
byte headStatus = getHeadStatus();
setHeadTouched(1);
if (headStatus & 1)
headStatus--;
else
headStatus++;
setHeadStatus(headStatus);
// Play the proper movie
int currentSoundID = -1;
if (headStatus == 2)
currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 14), 128, false, true);
else
currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 13), 128, false, true);
if ((_headID == 1 || _headID == 2) && headStatus == 0) {
if (loc.node == 0)
_vm->_sound->playSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 11), 127);
else
_vm->_sound->playSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 11), 96);
}
sceneView->playSynchronousAnimation(_headAnimations[headStatus]);
_staticData.navFrameIndex = _stillFrames[headStatus];
viewWindow->invalidateWindow(false);
byte headAStatus = _globalFlags.myAGHeadAStatus;
byte headBStatus = _globalFlags.myAGHeadBStatus;
byte headCStatus = _globalFlags.myAGHeadCStatus;
byte headDStatus = _globalFlags.myAGHeadDStatus;
if (loc.node == 0) {
if (headAStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
else if (headDStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
else
_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
} else if (loc.node == 2) {
if (headAStatus == 0 || headDStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
else
_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
}
_vm->_sound->stopSoundEffect(currentSoundID);
if (loc.node == 0 && (headBStatus < 3 && headCStatus < 3))
_vm->_sound->playSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 11), 127);
else if (loc.node == 2 && (headBStatus < 3 && headCStatus < 3))
_vm->_sound->playSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 11), 96);
if (headStatus & 1)
setHeadOpenedTime(_headID, g_system->getMillis());
bioChipRightWindow->sceneChanged();
return SC_TRUE;
}
return SC_FALSE;
}
int ArrowGodHead::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
if (_globalFlags.generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
return 0;
if ((itemID == kItemCavernSkull || itemID == kItemEntrySkull || itemID == kItemSpearSkull) && getHeadStatus() < 2 && _skullRegion.contains(pointLocation))
return 1;
return 0;
}
int ArrowGodHead::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
BioChipRightWindow *bioChipRightWindow = ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow;
if (_globalFlags.generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
return SIC_REJECT;
if (pointLocation.x == -1 && pointLocation.y == -1)
return SIC_REJECT;
if ((itemID == kItemCavernSkull || itemID == kItemEntrySkull || itemID == kItemSpearSkull) && getHeadStatus() == 1 && _skullRegion.contains(pointLocation)) {
setHeadStatus(2);
setHeadTouched(1);
setHeadStatusSkullId(itemID);
int currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
sceneView->playSynchronousAnimation(_headAnimations[2]);
_staticData.navFrameIndex = _stillFrames[2];
viewWindow->invalidateWindow(false);
byte headAStatus = _globalFlags.myAGHeadAStatus;
byte headDStatus = _globalFlags.myAGHeadDStatus;
if (_staticData.location.node == 0) {
if (headAStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
else if (headDStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
else
_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
} else if (_staticData.location.node == 2) {
if (headAStatus == 0 || headDStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
else
_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
}
_vm->_sound->stopSoundEffect(currentSoundID);
bioChipRightWindow->sceneChanged();
return SIC_ACCEPT;
}
return SIC_REJECT;
}
int ArrowGodHead::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
if (_globalFlags.generalWalkthroughMode == 1 && (_headID == 0 || _headID == 3))
return 0;
if (_skullRegion.contains(pointLocation)) {
if (getHeadStatus() == 3)
return kCursorOpenHand;
return kCursorFinger;
}
return 0;
}
int ArrowGodHead::timerCallback(Window *viewWindow) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
BioChipRightWindow *bioChipRightWindow = ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow;
Location &loc = _staticData.location;
for (int i = 0; i < 4; i++) {
uint32 lastStartedTimer = getHeadOpenedTime(i);
if (lastStartedTimer > 0 && g_system->getMillis() > (lastStartedTimer + WAR_GOD_HEAD_TIMER_VALUE)) {
setHeadOpenedTime(i, 0);
TempCursorChange cursorChange(kCursorWait);
if (i == _headID) {
byte status = getHeadStatus();
if (status & 1) {
status--;
setHeadStatus(status);
int currentSoundID = -1;
if (status == 2)
currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 14), 128, false, true);
else
currentSoundID = _vm->_sound->playSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 13), 128, false, true);
sceneView->playSynchronousAnimation(_headAnimations[status]);
_staticData.navFrameIndex = _stillFrames[status];
viewWindow->invalidateWindow(false);
_vm->_sound->stopSoundEffect(currentSoundID);
byte headAStatus = _globalFlags.myAGHeadAStatus;
byte headBStatus = _globalFlags.myAGHeadBStatus;
byte headCStatus = _globalFlags.myAGHeadCStatus;
byte headDStatus = _globalFlags.myAGHeadDStatus;
if (loc.node == 0) {
if (headAStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
else if (headDStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
else
_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
} else if (loc.node == 2) {
if (headAStatus == 0 || headDStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
else
_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
}
// Play the door closing sound, if applicable
if (i == 1 || i == 2) {
if (loc.node == 0 && (headBStatus == 0 || headCStatus == 0))
_vm->_sound->playSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 11), 127);
else if (loc.node == 2 && (headBStatus == 0 || headCStatus == 0))
_vm->_sound->playSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 11), 96);
}
}
bioChipRightWindow->sceneChanged();
} else {
byte status = getHeadStatus(i);
if (status & 1) {
status--;
setHeadStatus(i, status);
if (status == 2)
_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 14), 128);
else
_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 13), 128);
byte headAStatus = _globalFlags.myAGHeadAStatus;
byte headDStatus = _globalFlags.myAGHeadDStatus;
if (loc.node == 0) {
if (headAStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
else if (headDStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
else
_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
} else if (loc.node == 2) {
if (headAStatus == 0 || headDStatus == 0)
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
else
_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
}
}
bioChipRightWindow->sceneChanged();
if (_headID == 1 || _headID == 2) {
if (loc.node == 0)
_vm->_sound->playSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 11), 127);
else if (loc.node == 2)
_vm->_sound->playSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, 11), 96);
}
}
}
}
return SC_TRUE;
}
class ArrowGodDepthChange : public SceneBase {
public:
ArrowGodDepthChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
int postExitRoom(Window *viewWindow, const Location &newLocation) override;
int timerCallback(Window *viewWindow) override;
private:
bool _scheduledDepthChange;
int _soundID;
GlobalFlags &_globalFlags;
bool adjustSpearVolume(Window *viewWindow);
uint32 *headOpenedTime(byte headId);
uint32 getHeadOpenedTime(byte headId);
void setHeadOpenedTime(byte headId, uint32 value);
byte *headStatus(byte headId);
byte getHeadStatus(byte headId);
void setHeadStatus(byte headId, byte value);
};
ArrowGodDepthChange::ArrowGodDepthChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation),
_globalFlags(((SceneViewWindow *)viewWindow)->getGlobalFlags()) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
_scheduledDepthChange = false;
_soundID = -1;
byte headAStatus = _globalFlags.myAGHeadAStatus;
byte headBStatus = _globalFlags.myAGHeadBStatus;
byte headCStatus = _globalFlags.myAGHeadCStatus;
byte headDStatus = _globalFlags.myAGHeadDStatus;
int targetDepth = 0;
if (headBStatus > 0 || headCStatus > 0) {
if (headBStatus > 0) {
if (headAStatus == 0 || headDStatus == 0) {
if (headAStatus == 0 && headDStatus == 0) {
targetDepth = 11;
} else if (headAStatus > 0 && headDStatus == 0) {
targetDepth = 10;
} else if (headAStatus == 0 && headDStatus > 0) {
targetDepth = 9;
}
} else {
targetDepth = 8;
}
} else if (headCStatus > 0) {
if (headAStatus == 0 || headDStatus == 0) {
if (headAStatus == 0 && headDStatus == 0) {
targetDepth = 7;
} else if (headAStatus > 0 && headDStatus == 0) {
targetDepth = 6;
} else if (headAStatus == 0 && headDStatus > 0) {
targetDepth = 5;
}
} else {
targetDepth = 4;
}
}
} else if (headAStatus == 0 || headDStatus == 0) {
if (headAStatus == 0 && headBStatus == 0) {
targetDepth = 3;
} else {
if (headAStatus > 0 && headDStatus == 0) {
targetDepth = 2;
} else if (headAStatus == 0 && headDStatus > 0) {
targetDepth = 1;
}
}
}
if (_staticData.location.depth != targetDepth) {
Location newLocation = _staticData.location;
newLocation.depth = targetDepth;
sceneView->getSceneStaticData(newLocation, _staticData);
_frameCycleCount = _staticData.cycleStartFrame;
// Reload the frame files, if applicable
sceneView->changeStillFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_STILLS));
if (_staticData.cycleStartFrame >= 0)
sceneView->changeCycleFrameMovie(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, SF_CYCLES));
}
}
int ArrowGodDepthChange::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
if (((priorLocation.depth >= 8 && priorLocation.depth <= 11) && _staticData.location.depth < 8) ||
((priorLocation.depth >= 4 && priorLocation.depth <= 7) && _staticData.location.depth < 4)) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
byte headBStatus = _globalFlags.myAGHeadBStatus;
byte headCStatus = _globalFlags.myAGHeadCStatus;
byte &headDStatus = _globalFlags.myAGHeadDStatus;
byte doorLevelVolume = 0;
switch (_staticData.location.node) {
case 0:
case 1:
doorLevelVolume = 127;
break;
case 2:
doorLevelVolume = 96;
if (headDStatus == 2) {
headDStatus--;
_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 13), 128);
_scheduledDepthChange = true;
adjustSpearVolume(viewWindow);
sceneView->jumpToScene(_staticData.location);
return SC_TRUE; // Original does not return here, but the status of this would be bad in that case
}
break;
case 3:
if (headCStatus == 0)
doorLevelVolume = 127;
else if (headBStatus == 0)
doorLevelVolume = 64;
break;
}
if (doorLevelVolume > 0)
_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 11), doorLevelVolume);
}
adjustSpearVolume(viewWindow);
return SC_TRUE;
}
int ArrowGodDepthChange::postExitRoom(Window *viewWindow, const Location &newLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
Location &loc = _staticData.location;
if (loc.timeZone == newLocation.timeZone &&
loc.environment == newLocation.environment &&
loc.node == newLocation.node &&
loc.facing == newLocation.facing &&
loc.orientation == newLocation.orientation &&
loc.depth == newLocation.depth &&
!_scheduledDepthChange) {
// Notify the player of his gruesome death
sceneView->showDeathScene(13);
return SC_DEATH;
}
return SC_TRUE;
}
uint32 *ArrowGodDepthChange::headOpenedTime(byte headId) {
switch (headId) {
case 0:
return &_globalFlags.myAGHeadAOpenedTime;
case 1:
return &_globalFlags.myAGHeadBOpenedTime;
case 2:
return &_globalFlags.myAGHeadCOpenedTime;
case 3:
return &_globalFlags.myAGHeadDOpenedTime;
default:
return nullptr;
}
}
uint32 ArrowGodDepthChange::getHeadOpenedTime(byte headId) {
uint32 *openedTime = headOpenedTime(headId);
return openedTime ? *openedTime : 0;
}
void ArrowGodDepthChange::setHeadOpenedTime(byte headId, uint32 value) {
uint32 *openedTime = headOpenedTime(headId);
if (openedTime)
*openedTime = value;
}
byte *ArrowGodDepthChange::headStatus(byte headId) {
switch (headId) {
case 0:
return &_globalFlags.myAGHeadAStatus;
case 1:
return &_globalFlags.myAGHeadBStatus;
case 2:
return &_globalFlags.myAGHeadCStatus;
case 3:
return &_globalFlags.myAGHeadDStatus;
default:
return nullptr;
}
}
byte ArrowGodDepthChange::getHeadStatus(byte headId) {
byte *status = headStatus(headId);
return status ? *status : 0;
}
void ArrowGodDepthChange::setHeadStatus(byte headId, byte value) {
byte *status = headStatus(headId);
if (status)
*status = value;
}
int ArrowGodDepthChange::timerCallback(Window *viewWindow) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
BioChipRightWindow *bioChipRightWindow = ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow;
Location &loc = _staticData.location;
SceneBase::timerCallback(viewWindow);
// Check to see if we moved into a death scene
if (loc.timeZone == 2 && loc.environment == 5 &&
loc.node == 1 && loc.facing == 3 &&
loc.orientation == 1 && (
loc.depth == 1 || loc.depth == 3 || loc.depth == 11 ||
loc.depth == 7 || loc.depth == 5 || loc.depth == 9)) {
if (loc.depth == 1)
sceneView->playSynchronousAnimation(19);
sceneView->showDeathScene(13);
return SC_DEATH;
}
if (loc.timeZone == 2 && loc.environment == 5 &&
loc.node == 3 && loc.facing == 3 &&
loc.orientation == 1 && (
loc.depth == 2 || loc.depth == 3 || loc.depth == 11 ||
loc.depth == 10 || loc.depth == 6 || loc.depth == 7)) {
sceneView->playSynchronousAnimation(17);
sceneView->showDeathScene(13);
return SC_DEATH;
}
// Loop through the four heads
for (int i = 0; i < 4; i++) {
uint32 lastStartedTimer = getHeadOpenedTime(i);
// Check if there is a timer going for this head
if (lastStartedTimer > 0 && (g_system->getMillis() > (lastStartedTimer + WAR_GOD_HEAD_TIMER_VALUE) ||
i == 0 || (_globalFlags.generalWalkthroughMode == 1 && i == 1) ||
(getHeadStatus(i) == 2 && i == 3))) {
setHeadOpenedTime(i, 0);
TempCursorChange cursorChange(kCursorWait);
byte status = getHeadStatus(i);
if (status & 1) {
status--;
setHeadStatus(i, status);
_vm->_sound->playSynchronousSoundEffect(_vm->getFilePath(loc.timeZone, loc.environment, (status == 2) ? 14 : 13), 128);
_scheduledDepthChange = true;
adjustSpearVolume(viewWindow);
}
bioChipRightWindow->sceneChanged();
}
}
if (_scheduledDepthChange) {
_scheduledDepthChange = false;
sceneView->jumpToScene(loc);
}
return SC_TRUE;
}
bool ArrowGodDepthChange::adjustSpearVolume(Window *viewWindow) {
// TODO: Looks like there's a bug in the original. node == 3 should also be in here, I think
// Need to investigate
if (_staticData.location.node >= 0 && _staticData.location.node <= 2) {
byte headAStatus = _globalFlags.myAGHeadAStatus;
byte headDStatus = _globalFlags.myAGHeadDStatus;
if (headAStatus == 0) {
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
} else if (headDStatus == 0) {
if (_staticData.location.node == 2)
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
else
_vm->_sound->adjustSecondaryAmbientSoundVolume(64, false, 0, 0);
} else {
_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
}
}
return true;
}
class DeathGodAltar : public SceneBase {
public:
DeathGodAltar(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
int mouseUp(Window *viewWindow, const Common::Point &pointLocation) override;
int draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
int droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) override;
int specifyCursor(Window *viewWindow, const Common::Point &pointLocation) override;
int locateAttempted(Window *viewWindow, const Common::Point &pointLocation) override;
private:
Common::Rect _heartPool;
Common::Rect _puzzleBox;
Common::Rect _blood;
};
DeathGodAltar::DeathGodAltar(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
_heartPool = Common::Rect(89, 80, 159, 112);
_puzzleBox = Common::Rect(150, 45, 260, 111);
_blood = Common::Rect(88, 76, 162, 114);
}
int DeathGodAltar::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
Location &loc = _staticData.location;
if (globalFlags.myDGOfferedHeart == 1) {
if (!sceneView->isNumberInGlobalFlagTable(MAYAN_EVIDENCE_ENVIRON_CART)) {
sceneView->playSynchronousAnimation(3);
_staticData.navFrameIndex = 51;
viewWindow->invalidateWindow(false);
if ((loc.timeZone != priorLocation.timeZone || loc.environment != priorLocation.environment ||
loc.node != priorLocation.node || loc.facing != priorLocation.facing ||
loc.orientation != priorLocation.orientation || loc.depth != priorLocation.depth) &&
!sceneView->isNumberInGlobalFlagTable(MAYAN_EVIDENCE_ENVIRON_CART))
sceneView->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
}
} else if ((loc.timeZone != priorLocation.timeZone || loc.environment != priorLocation.environment ||
loc.node != priorLocation.node || loc.facing != priorLocation.facing ||
loc.orientation != priorLocation.orientation || loc.depth != priorLocation.depth) &&
!sceneView->isNumberInGlobalFlagTable(MAYAN_EVIDENCE_PHONY_BLOOD)) {
sceneView->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
}
return SC_TRUE;
}
int DeathGodAltar::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (_puzzleBox.contains(pointLocation) && globalFlags.myDGOfferedHeart == 1 && globalFlags.takenEnvironCart == 0) {
Location puzzleLocation = _staticData.location;
puzzleLocation.depth = 1;
sceneView->jumpToScene(puzzleLocation);
}
return SC_FALSE;
}
int DeathGodAltar::draggingItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (itemID == kItemPreservedHeart && globalFlags.myDGOfferedHeart == 0 && _heartPool.contains(pointLocation))
return 1;
return 0;
}
int DeathGodAltar::droppedItem(Window *viewWindow, int itemID, const Common::Point &pointLocation, int itemFlags) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (pointLocation.x == -1 && pointLocation.y == -1)
return SIC_REJECT;
if (itemID == kItemPreservedHeart && globalFlags.myDGOfferedHeart == 0 && _heartPool.contains(pointLocation)) {
globalFlags.myDGOfferedHeart = 1;
sceneView->playSynchronousAnimation(2);
sceneView->playSynchronousAnimation(3);
_staticData.navFrameIndex = 51;
if (!sceneView->isNumberInGlobalFlagTable(MAYAN_EVIDENCE_ENVIRON_CART))
sceneView->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_PRESENT));
return SIC_ACCEPT;
}
return SIC_REJECT;
}
int DeathGodAltar::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (globalFlags.bcLocateEnabled == 1) {
if (globalFlags.myDGOfferedHeart == 1 &&
globalFlags.takenEnvironCart == 0 &&
_staticData.navFrameIndex == 51 && _puzzleBox.contains(pointLocation))
return -2;
if (_blood.contains(pointLocation))
return -2;
return -1;
} else if (_puzzleBox.contains(pointLocation) && globalFlags.myDGOfferedHeart == 1 && globalFlags.takenEnvironCart == 0) {
// This logic is broken in 1.04, 1.05, and 1.10. I fixed it here to match mouseUp
return kCursorFinger;
}
return kCursorArrow;
}
int DeathGodAltar::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
BioChipRightWindow *bioChipRightWindow = ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow;
if (globalFlags.bcLocateEnabled == 1 &&
globalFlags.takenEnvironCart == 0 &&
_puzzleBox.contains(pointLocation) && _staticData.navFrameIndex == 51 &&
!sceneView->isNumberInGlobalFlagTable(MAYAN_EVIDENCE_ENVIRON_CART)) {
sceneView->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_MUST_BE_REVEALED)); // All will be reveaaaaaaaaled (Yes, I used this joke twice now)
return SC_TRUE;
}
if (globalFlags.bcLocateEnabled == 1) {
if (_blood.contains(pointLocation)) {
sceneView->playSynchronousAnimation(6);
// Attempt to add it to the biochip
if (sceneView->addNumberToGlobalFlagTable(MAYAN_EVIDENCE_PHONY_BLOOD))
sceneView->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
else
sceneView->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
// Disable capture
bioChipRightWindow->disableEvidenceCapture();
}
return SC_TRUE;
}
return SC_FALSE;
}
class DeathGodPuzzleBox : public SceneBase {
public:
DeathGodPuzzleBox(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
~DeathGodPuzzleBox();
void preDestructor() override;
int paint(Window *viewWindow, Graphics::Surface *preBuffer) override;
int gdiPaint(Window *viewWindow) override;
int mouseUp(Window *viewWindow, const Common::Point &pointLocation) override;
int mouseMove(Window *viewWindow, const Common::Point &pointLocation) override;
int specifyCursor(Window *viewWindow, const Common::Point &pointLocation) override;
private:
int _puzzleIndexes[4];
Common::Rect _clickableRegions[4];
Common::Rect _puzzleRightHandle;
AVIFrames _puzzleFrames[4];
bool _translateText;
bool isPuzzleSolved() const;
};
DeathGodPuzzleBox::DeathGodPuzzleBox(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
Location &loc = _staticData.location;
_translateText = false;
_puzzleIndexes[0] = _puzzleIndexes[1] = _puzzleIndexes[2] = _puzzleIndexes[3] = 0;
_clickableRegions[0] = Common::Rect(30, 0, 111, 189);
_clickableRegions[1] = Common::Rect(112, 0, 187, 189);
_clickableRegions[2] = Common::Rect(188, 0, 252, 189);
_clickableRegions[3] = Common::Rect(253, 0, 330, 189);
_puzzleRightHandle = Common::Rect(380, 0, 432, 189);
// Load the spinner movies
_puzzleFrames[0].open(_vm->getFilePath(loc.timeZone, loc.environment, 4));
_puzzleFrames[1].open(_vm->getFilePath(loc.timeZone, loc.environment, 5));
_puzzleFrames[2].open(_vm->getFilePath(loc.timeZone, loc.environment, 6));
_puzzleFrames[3].open(_vm->getFilePath(loc.timeZone, loc.environment, 7));
}
DeathGodPuzzleBox::~DeathGodPuzzleBox() {
preDestructor();
}
void DeathGodPuzzleBox::preDestructor() {
_puzzleFrames[0].close();
_puzzleFrames[1].close();
_puzzleFrames[2].close();
_puzzleFrames[3].close();
}
int DeathGodPuzzleBox::paint(Window *viewWindow, Graphics::Surface *preBuffer) {
SceneBase::paint(viewWindow, preBuffer);
for (int i = 0; i < 4; i++) {
const Graphics::Surface *spinnerFrame = _puzzleFrames[i].getFrame(_puzzleIndexes[i]);
_vm->_gfx->crossBlit(preBuffer, _clickableRegions[i].left, _clickableRegions[i].top, _clickableRegions[i].width(), _clickableRegions[i].height(), spinnerFrame, 0, 0);
}
return SC_REPAINT;
}
int DeathGodPuzzleBox::gdiPaint(Window *viewWindow) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (_translateText && globalFlags.bcTranslateEnabled == 1) {
Common::Rect absoluteRect = viewWindow->getAbsoluteRect();
Common::Rect rect(42, 64, 324, 125);
rect.translate(absoluteRect.left, absoluteRect.top);
_vm->_gfx->getScreen()->frameRect(rect, _vm->_gfx->getColor(255, 0, 0));
}
return SC_REPAINT;
}
int DeathGodPuzzleBox::mouseUp(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
BioChipRightWindow *bioChipRightWindow = ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow;
InventoryWindow *inventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow;
for (int i = 0; i < 4; i++) {
if (_clickableRegions[i].contains(pointLocation)) {
if (pointLocation.y - _clickableRegions[i].top > _clickableRegions[i].height() / 2) {
// Start the roll sound
_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
// Spin the wheel, stop at the new value
// FIXME: Timing
for (int j = 0; j < 6; j++) {
_puzzleIndexes[i]--;
if (_puzzleIndexes[i] < 0)
_puzzleIndexes[i] = _puzzleFrames[i].getFrameCount() - 2;
viewWindow->invalidateWindow();
_vm->_gfx->updateScreen();
}
_translateText = false;
mouseMove(viewWindow, pointLocation);
} else {
// Start the roll sound
_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, 14), 128, false, true);
// Spin the wheel, stop at the new value
// FIXME: Timing
for (int j = 0; j < 6; j++) {
_puzzleIndexes[i]++;
if (_puzzleIndexes[i] > _puzzleFrames[i].getFrameCount() - 2)
_puzzleIndexes[i] = 0;
viewWindow->invalidateWindow();
_vm->_gfx->updateScreen();
}
_translateText = false;
mouseMove(viewWindow, pointLocation);
}
}
}
if (_puzzleRightHandle.contains(pointLocation)) {
if (isPuzzleSolved()) {
DestinationScene newDestination;
newDestination.destinationScene = _staticData.location;
newDestination.destinationScene.depth = 2;
newDestination.transitionType = TRANSITION_VIDEO;
newDestination.transitionStartFrame = -1;
newDestination.transitionLength = -1;
if (globalFlags.takenEnvironCart == 0)
newDestination.transitionData = 4;
else
newDestination.transitionData = 5;
BuriedEngine *vm = _vm;
sceneView->moveToDestination(newDestination);
// Play animation capturing the evidence
// FIXME: Is this right? Shouldn't this be if takenEnvironCart == 0 only?
sceneView->playSynchronousAnimation(7);
// Attempt to add it to the biochip
if (sceneView->addNumberToGlobalFlagTable(MAYAN_EVIDENCE_ENVIRON_CART))
sceneView->displayLiveText(vm->getString(IDS_MBT_EVIDENCE_RIPPLE_DOCUMENTED));
else
sceneView->displayLiveText(vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
// Disable capture
bioChipRightWindow->disableEvidenceCapture();
// Set the scoring flag
globalFlags.scoreCompletedDeathGod = 1;
globalFlags.myDGOpenedPuzzleBox = 1;
// Play an Arthur comment
if (globalFlags.takenEnvironCart == 0 && inventoryWindow->isItemInInventory(kItemBioChipAI))
vm->_sound->playSoundEffect("BITDATA/MAYAN/MYDG_C01.BTA"); // Broken in 1.01
return SC_TRUE;
} else {
// We did the puzzle incorrectly, so spin the wheels and kill the player
sceneView->playPlacedSynchronousAnimation(8, 320, 0);
sceneView->showDeathScene(12);
return SC_DEATH;
}
}
return SC_FALSE;
}
int DeathGodPuzzleBox::mouseMove(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (globalFlags.bcTranslateEnabled == 1) {
Common::Rect translateTextRegion(42, 64, 324, 126);
if (translateTextRegion.contains(pointLocation)) {
if (!_translateText) {
Common::String translatedText = _vm->getString(IDMYDG_PUZZLE_BOX_TRANS_TEXT_BASE + _puzzleIndexes[0] / 6);
translatedText += ' ';
translatedText += _vm->getString(IDMYDG_PUZZLE_BOX_TRANS_TEXT_BASE + 10 + _puzzleIndexes[1] / 6);
translatedText += ' ';
translatedText += _vm->getString(IDMYDG_PUZZLE_BOX_TRANS_TEXT_BASE + 20 + _puzzleIndexes[2] / 6);
translatedText += ' ';
translatedText += _vm->getString(IDMYDG_PUZZLE_BOX_TRANS_TEXT_BASE + 30 + _puzzleIndexes[3] / 6);
sceneView->displayTranslationText(translatedText);
_translateText = true;
viewWindow->invalidateWindow(false);
}
} else {
if (_translateText) {
_translateText = false;
viewWindow->invalidateWindow(false);
}
}
}
return SC_FALSE;
}
int DeathGodPuzzleBox::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
for (int i = 0; i < 4; i++) {
if (_clickableRegions[i].contains(pointLocation)) {
if (pointLocation.y - _clickableRegions[i].top > _clickableRegions[i].height() / 2)
return kCursorArrowDown;
return kCursorArrowUp;
}
}
if (_puzzleRightHandle.contains(pointLocation))
return kCursorFinger;
return kCursorArrow;
}
bool DeathGodPuzzleBox::isPuzzleSolved() const {
switch (_vm->getLanguage()) {
case Common::DE_DEU:
case Common::ES_ESP:
case Common::IT_ITA:
return _puzzleIndexes[0] == 12 && _puzzleIndexes[1] == 18 && _puzzleIndexes[2] == 30 && _puzzleIndexes[3] == 24;
case Common::EN_ANY:
return _puzzleIndexes[0] == 18 && _puzzleIndexes[1] == 36 && _puzzleIndexes[2] == 12 && _puzzleIndexes[3] == 24;
case Common::FR_FRA:
return _puzzleIndexes[0] == 12 && _puzzleIndexes[1] == 18 && _puzzleIndexes[2] == 42 && _puzzleIndexes[3] == 24;
case Common::JA_JPN:
return _puzzleIndexes[0] == 12 && _puzzleIndexes[1] == 24 && _puzzleIndexes[2] == 30 && _puzzleIndexes[3] == 18;
default:
// Default to English, but warn about it
warning("Unknown language for puzzle box");
return _puzzleIndexes[0] == 18 && _puzzleIndexes[1] == 36 && _puzzleIndexes[2] == 12 && _puzzleIndexes[3] == 24;
}
return false;
}
class MainCavernGlassCapture : public SceneBase {
public:
MainCavernGlassCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
int locateAttempted(Window *viewWindow, const Common::Point &pointLocation) override;
int specifyCursor(Window *viewWindow, const Common::Point &pointLocation) override;
private:
Common::Rect _glass;
};
MainCavernGlassCapture::MainCavernGlassCapture(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
_glass = Common::Rect(305, 126, 355, 156);
}
int MainCavernGlassCapture::locateAttempted(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
BioChipRightWindow *bioChipRightWindow = ((GameUIWindow *)viewWindow->getParent())->_bioChipRightWindow;
if (globalFlags.bcLocateEnabled == 1) {
if (_glass.contains(pointLocation)) {
// Play the animation
sceneView->playSynchronousAnimation(22);
// Attempt to add it to the biochip
if (sceneView->addNumberToGlobalFlagTable(MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID))
sceneView->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ACQUIRED));
else
sceneView->displayLiveText(_vm->getString(IDS_MBT_EVIDENCE_ALREADY_ACQUIRED));
// Disable capture
bioChipRightWindow->disableEvidenceCapture();
}
return SC_TRUE;
}
return SC_FALSE;
}
int MainCavernGlassCapture::specifyCursor(Window *viewWindow, const Common::Point &pointLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
if (globalFlags.bcLocateEnabled == 1) {
if (_glass.contains(pointLocation))
return -2;
return -1;
}
return kCursorArrow;
}
class WalkVolumeChange : public SceneBase {
public:
WalkVolumeChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
byte newVolume = 0, uint32 volumeChangeTime = 0, int stepCount = -1, int entryEffectFileNameID = -1);
int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
int preExitRoom(Window *viewWindow, const Location &newLocation) override;
private:
byte _newVolume;
uint32 _volumeChangeTime;
int _stepCount;
int _entryEffectFileNameID;
};
WalkVolumeChange::WalkVolumeChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
byte newVolume, uint32 volumeChangeTime, int stepCount, int entryEffectFileNameID) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
_newVolume = newVolume;
_volumeChangeTime = volumeChangeTime;
_stepCount = stepCount;
_entryEffectFileNameID = entryEffectFileNameID;
}
int WalkVolumeChange::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
if (_entryEffectFileNameID >= 0 && priorLocation.node != _staticData.location.node)
_vm->_sound->playSoundEffect(_vm->getFilePath(_staticData.location.timeZone, _staticData.location.environment, _entryEffectFileNameID), 128, false, true);
return SC_TRUE;
}
int WalkVolumeChange::preExitRoom(Window *viewWindow, const Location &newLocation) {
if (_stepCount >= 0 && newLocation.node != _staticData.location.node)
_vm->_sound->adjustAmbientSoundVolume(_newVolume, true, _stepCount, _volumeChangeTime);
return SC_TRUE;
}
class AdjustSecondaryAmbientOnEntry : public SceneBase {
public:
AdjustSecondaryAmbientOnEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation);
int postEnterRoom(Window *viewWindow, const Location &priorLocation) override;
int preExitRoom(Window *viewWindow, const Location &newLocation) override;
};
AdjustSecondaryAmbientOnEntry::AdjustSecondaryAmbientOnEntry(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
}
int AdjustSecondaryAmbientOnEntry::postEnterRoom(Window *viewWindow, const Location &priorLocation) {
_vm->_sound->adjustSecondaryAmbientSoundVolume(128, false, 0, 0);
return SC_TRUE;
}
int AdjustSecondaryAmbientOnEntry::preExitRoom(Window *viewWindow, const Location &newLocation) {
// Kill the ambient if moving to a different node
if (newLocation.node != _staticData.location.node)
_vm->_sound->adjustSecondaryAmbientSoundVolume(0, false, 0, 0);
return SC_TRUE;
}
class WalkDualAmbientVolumeChange : public SceneBase {
public:
WalkDualAmbientVolumeChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
byte newVolume = 0, byte secondVolume = 0, uint32 volumeChangeTime = 0, int stepCount = -1);
int preExitRoom(Window *viewWindow, const Location &newLocation) override;
private:
byte _newVolume;
uint32 _volumeChangeTime;
int _stepCount;
byte _secondVolume;
};
WalkDualAmbientVolumeChange::WalkDualAmbientVolumeChange(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
byte newVolume, byte secondVolume, uint32 volumeChangeTime, int stepCount) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
Location &loc = _staticData.location;
_newVolume = newVolume;
_volumeChangeTime = volumeChangeTime;
_stepCount = stepCount;
_secondVolume = secondVolume;
// If we have stepped on the far ledge, set the flag
if (loc.timeZone == 2 && loc.environment == 4 &&
loc.node == 5 && loc.facing == 0 &&
loc.orientation == 1 && loc.depth == 0)
globalFlags.myWTSteppedOnFarLedge = 1;
}
int WalkDualAmbientVolumeChange::preExitRoom(Window *viewWindow, const Location &newLocation) {
if (_stepCount >= 0 && newLocation.node != _staticData.location.node) {
_vm->_sound->adjustAmbientSoundVolume(_newVolume, true, _stepCount, _volumeChangeTime);
_vm->_sound->adjustSecondaryAmbientSoundVolume(_secondVolume, true, _stepCount, _volumeChangeTime);
}
return SC_TRUE;
}
class SetVolumeAndFlag : public SceneBase {
public:
SetVolumeAndFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
byte newVolume, byte &flag, byte flagValue = 255);
};
SetVolumeAndFlag::SetVolumeAndFlag(BuriedEngine *vm, Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation,
byte newVolume, byte &flag, byte flagValue) :
SceneBase(vm, viewWindow, sceneStaticData, priorLocation) {
_vm->_sound->adjustAmbientSoundVolume(newVolume, false, 0, 0);
flag = flagValue;
}
bool SceneViewWindow::initializeMayanTimeZoneAndEnvironment(Window *viewWindow, int environment) {
InventoryWindow *inventoryWindow = ((GameUIWindow *)viewWindow->getParent())->_inventoryWindow;
if (environment == -1) {
_globalFlags.myTPCodeWheelStatus = _globalFlags.generalWalkthroughMode;
_globalFlags.myTPCodeWheelLeftIndex = _globalFlags.generalWalkthroughMode == 1 ? 8 : 0;
_globalFlags.myTPCodeWheelRightIndex = _globalFlags.generalWalkthroughMode == 1 ? 12 : 0;
_globalFlags.myMCDeathGodOfferings = 0;
_globalFlags.myWGPlacedRope = _globalFlags.generalWalkthroughMode;
_globalFlags.myWTCurrentBridgeStatus = 0;
_globalFlags.myAGHeadAStatus = _globalFlags.generalWalkthroughMode == 1 ? 2 : 0;
_globalFlags.myAGHeadBStatus = 0;
_globalFlags.myAGHeadCStatus = 0;
_globalFlags.myAGHeadDStatus = _globalFlags.generalWalkthroughMode == 1 ? 2 : 0;
_globalFlags.myAGHeadAStatusSkullID = _globalFlags.generalWalkthroughMode == 1 ? kItemCavernSkull : 0;
_globalFlags.myAGHeadBStatusSkullID = 0;
_globalFlags.myAGHeadCStatusSkullID = 0;
_globalFlags.myAGHeadDStatusSkullID = _globalFlags.generalWalkthroughMode == 1 ? kItemSpearSkull : 0;
_globalFlags.myAGTimerHeadID = 0;
_globalFlags.myAGTimerStartTime = 0;
_globalFlags.myDGOfferedHeart = 0;
_globalFlags.myAGHeadAOpenedTime = 0;
_globalFlags.myAGHeadBOpenedTime = 0;
_globalFlags.myAGHeadCOpenedTime = 0;
_globalFlags.myAGHeadDOpenedTime = 0;
_globalFlags.myPickedUpCeramicBowl = inventoryWindow->isItemInInventory(kItemCeramicBowl) ? 1 : 0;
_globalFlags.myMCPickedUpSkull = inventoryWindow->isItemInInventory(kItemCavernSkull) ? 1 : 0;
_globalFlags.myWGRetrievedJadeBlock = inventoryWindow->isItemInInventory(kItemJadeBlock) ? 1 : 0;
_globalFlags.myWTRetrievedLimestoneBlock = inventoryWindow->isItemInInventory(kItemLimestoneBlock) ? 1 : 0;
_globalFlags.myAGRetrievedEntrySkull = inventoryWindow->isItemInInventory(kItemEntrySkull) ? 1 : 0;
_globalFlags.myAGRetrievedSpearSkull = inventoryWindow->isItemInInventory(kItemSpearSkull) ? 1 : 0;
_globalFlags.myAGRetrievedCopperMedal = inventoryWindow->isItemInInventory(kItemCopperMedallion) ? 1 : 0;
_globalFlags.myAGRetrievedObsidianBlock = inventoryWindow->isItemInInventory(kItemObsidianBlock) ? 1 : 0;
_globalFlags.takenEnvironCart = inventoryWindow->isItemInInventory(kItemEnvironCart) ? 1 : 0;
if (_globalFlags.generalWalkthroughMode == 1) {
_globalFlags.myMCPickedUpSkull = 1;
_globalFlags.myAGRetrievedSpearSkull = 1;
_globalFlags.myAGRetrievedCopperMedal = 1;
}
} else if (environment == 2) {
_globalFlags.scoreEnteredMainCavern = 1;
_globalFlags.myVisitedMainCavern = 1;
} else if (environment == 3) {
_globalFlags.myVisitedWealthGod = 1;
_globalFlags.myVisitedSpecRooms = 1;
} else if (environment == 4) {
_globalFlags.myVisitedWaterGod = 1;
_globalFlags.myVisitedSpecRooms = 1;
} else if (environment == 5) {
_globalFlags.myVisitedArrowGod = 1;
_globalFlags.myVisitedSpecRooms = 1;
} else if (environment == 6) {
_globalFlags.myVisitedDeathGod = 1;
_globalFlags.myVisitedSpecRooms = 1;
}
return true;
}
bool SceneViewWindow::startMayanAmbient(int oldTimeZone, int oldEnvironment, int environment, bool fade) {
bool checkFade = true;
if (environment == 3) {
if (oldEnvironment == 2)
return _vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), checkFade, 64);
return _vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), checkFade, 16);
} else if (environment == 4) {
if (oldTimeZone == -2)
_vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), fade, 64);
else
_vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), fade, 16);
return _vm->_sound->setSecondaryAmbientSound(_vm->getFilePath(2, environment, 13), checkFade, 0);
} else if (environment == 5) {
_vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), fade, 64);
return _vm->_sound->setSecondaryAmbientSound(_vm->getFilePath(2, environment, 12), checkFade, 128);
}
_vm->_sound->setAmbientSound(_vm->getFilePath(2, environment, SF_AMBIENT), fade, 64);
return true;
}
bool SceneViewWindow::checkCustomMayanAICommentDependencies(const Location &commentLocation, const AIComment &commentData) {
InventoryWindow *inventoryWindow = ((GameUIWindow *)getParent())->_inventoryWindow;
switch (commentData.dependencyFlagOffsetB) {
case 1: // Player hasn't translated any inscriptions
return _globalFlags.myTPTextTranslated == 0;
case 2: // Player hasn't translated any inscriptions, has translate biochip
return _globalFlags.myTPTextTranslated == 0 && inventoryWindow->isItemInInventory(kItemBioChipTranslate);
case 3: // Player hasn't translated any inscriptions, doesn't have translate biochip
return _globalFlags.myTPTextTranslated == 0 && !inventoryWindow->isItemInInventory(kItemBioChipTranslate);
case 4: // Has translated inscription above calendar, calendar not set to sacred day, player has never been to main cavern
return _globalFlags.myTPCalendarTopTranslated == 1 && _globalFlags.myTPCodeWheelStatus == 0 && _globalFlags.myVisitedMainCavern == 0;
case 5: // Has translated inscription above calendar, calendar is set to sacred day, player has never been to main cavern
return _globalFlags.myTPCalendarTopTranslated == 1 && _globalFlags.myTPCodeWheelStatus == 1 && _globalFlags.myVisitedMainCavern == 0;
case 6: // Player has never been to main cavern
return _globalFlags.myVisitedMainCavern == 0;
case 7: // Player has never been to main cavern, calendar not set to sacred day
return _globalFlags.myVisitedMainCavern == 0 && _globalFlags.myTPCodeWheelStatus == 0;
case 8: // Ceramic bowl not in the inventory
return !inventoryWindow->isItemInInventory(kItemCeramicBowl);
case 9: // If node is not 5, 6, or 8
return commentLocation.node != 6 && commentLocation.node != 5 && commentLocation.node != 8;
case 10: // If node is not 1, 0, 7, or 8
return commentLocation.node != 1 && commentLocation.node != 0 && commentLocation.node != 7 && commentLocation.node != 8;
case 11: // If node is not 0, 8, or 1
return commentLocation.node != 0 && commentLocation.node != 8 && commentLocation.node != 1;
case 12: // If not translated any sacred days
return _globalFlags.myTPCalendarListTranslated == 0;
case 13: // Not any door, no translations
return _globalFlags.myVisitedSpecRooms == 0 && _globalFlags.myMCTransDoor == 0;
case 14: // Not any door, no translations, has translate chip
return _globalFlags.myVisitedSpecRooms == 0 && _globalFlags.myMCTransDoor == 0 && inventoryWindow->isItemInInventory(kItemBioChipTranslate);
case 15: // Not any door, has translated arrow or translated water or translated wealth
return _globalFlags.myVisitedSpecRooms == 0 && (_globalFlags.myMCTransAGOffering == 1 || _globalFlags.myMCTransWGOffering == 1 || _globalFlags.myMCTransWTOffering == 1);
case 16: // Has translated wealth, has not been through wealth god door
return _globalFlags.myMCTransWGOffering == 1 && _globalFlags.myVisitedWealthGod == 0;
case 17: // Has translated water, has not been through water god door
return _globalFlags.myMCTransWTOffering == 1 && _globalFlags.myVisitedWaterGod == 0;
case 18: // Has translated arrow, has not been through arrow god door
return _globalFlags.myMCTransAGOffering == 1 && _globalFlags.myVisitedArrowGod == 0;
case 19: // Has translated death, has not been through death god door
return _globalFlags.myMCTransDGOffering == 1 && _globalFlags.myVisitedDeathGod == 0;
case 20: // Has not been through death god door
return _globalFlags.myVisitedDeathGod == 0;
case 21: // Has translated death
return _globalFlags.myMCTransDGOffering == 1;
case 22: // After making any offering
return _globalFlags.myMCTransMadeAnOffering == 1;
case 23: // Before crossing rope bridge
return _globalFlags.myWGCrossedRopeBridge == 0;
case 24: // If player has translated inscription above wealth god door in cavern
return _globalFlags.myMCTransWGOffering == 1;
case 25: // If player has not translated inscription above wealth god door in cavern
return _globalFlags.myMCTransWGOffering == 0;
case 26: // If player has translated inscription above wealth god door in cavern, has never been to wealth god altar room
return _globalFlags.myMCTransWGOffering == 1 && _globalFlags.myWGSeenLowerPassage == 0;
case 27: // Has not attached either rope or grappling hook, has never been to wealth god altar room
return _globalFlags.myWGPlacedRope == 0 && _globalFlags.myWGSeenLowerPassage == 0;
case 28: // Player has never stepped on swings
return _globalFlags.myWTSteppedOnSwings == 0;
case 29: // Player has never been on far ledge
return _globalFlags.myWTSteppedOnFarLedge == 0;
case 30: // Never put in heart
return _globalFlags.myDGOfferedHeart == 0;
case 31: // Never put in heart, no heart in inventory
return _globalFlags.myDGOfferedHeart == 0 && inventoryWindow->isItemInInventory(kItemPreservedHeart);
case 32: // After put in heart, puzzle box never opened
return _globalFlags.myDGOfferedHeart == 1 && _globalFlags.myDGOpenedPuzzleBox == 0;
case 33: // After put in heart, puzzle box never opened, player has not translated 'Itzamna' inscription over inside door of temple
return _globalFlags.myDGOfferedHeart == 1 && _globalFlags.myDGOpenedPuzzleBox == 0 && _globalFlags.myTPTransBreathOfItzamna == 0;
case 34: // After put in heart, puzzle box never opened, player has translated 'Itzamna' inscription over inside door of temple
return _globalFlags.myDGOfferedHeart == 1 && _globalFlags.myDGOpenedPuzzleBox == 0 && _globalFlags.myTPTransBreathOfItzamna == 1;
case 35: // Before interacting with any heads
return _globalFlags.myAGHeadATouched == 0 && _globalFlags.myAGHeadBTouched == 0 && _globalFlags.myAGHeadCTouched == 0 && _globalFlags.myAGHeadDTouched == 0;
case 36: // After interacting with any head, before jamming any head
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;
case 37: // S2 jam, S1 not jam, not altar
return _globalFlags.myAGHeadAStatus == 0 && _globalFlags.myAGHeadBStatus == 2 && _globalFlags.myAGVisitedAltar == 0;
case 38: // S1 jam, S2 not jam, S3 not jam, not altar
return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGVisitedAltar == 0;
case 39: // S1 jam, S2 not jam, S3 not jam, S4 not jam, not altar, no skulls
return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGVisitedAltar == 0 && !inventoryWindow->isItemInInventory(kItemCavernSkull) && !inventoryWindow->isItemInInventory(kItemEntrySkull) && !inventoryWindow->isItemInInventory(kItemSpearSkull);
case 40: // Before interacting with S3 or S4, not altar
return _globalFlags.myAGHeadCTouched == 0 && _globalFlags.myAGHeadDTouched == 0 && _globalFlags.myAGVisitedAltar == 0;
case 41: // S1 jam, S2 jam, S3 not jam, S4 not jam, after interacting with S3 and S4, not altar, no skulls
return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 2 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGHeadCTouched == 1 && _globalFlags.myAGHeadDTouched == 1 && _globalFlags.myAGVisitedAltar == 0 && !inventoryWindow->isItemInInventory(kItemCavernSkull) && !inventoryWindow->isItemInInventory(kItemEntrySkull) && !inventoryWindow->isItemInInventory(kItemSpearSkull);
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
return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGHeadCTouched == 1 && _globalFlags.myAGHeadDTouched == 1 && _globalFlags.myAGVisitedAltar == 0 && (inventoryWindow->isItemInInventory(kItemCavernSkull) ^ inventoryWindow->isItemInInventory(kItemEntrySkull) ^ inventoryWindow->isItemInInventory(kItemSpearSkull));
case 43: // S1 jam, S2 jam, S3 not jam, S4 not jam, after interacting with S3 and S4, not altar, no skulls
return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 2 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGHeadCTouched == 1 && _globalFlags.myAGHeadDTouched == 1 && _globalFlags.myAGVisitedAltar == 0 && !inventoryWindow->isItemInInventory(kItemCavernSkull) && !inventoryWindow->isItemInInventory(kItemEntrySkull) && !inventoryWindow->isItemInInventory(kItemSpearSkull);
case 44: // S1 jam, S2 not jam, S3 jam, S4 not jam, not altar, no skulls
return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 2 && _globalFlags.myAGHeadDStatus == 0 && _globalFlags.myAGVisitedAltar == 0 && !inventoryWindow->isItemInInventory(kItemCavernSkull) && !inventoryWindow->isItemInInventory(kItemEntrySkull) && !inventoryWindow->isItemInInventory(kItemSpearSkull);
case 45: // S1 jam, S2 not jam, S3 not jam, S4 jam, not altar, no skulls
return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0 && !inventoryWindow->isItemInInventory(kItemCavernSkull) && !inventoryWindow->isItemInInventory(kItemEntrySkull) && !inventoryWindow->isItemInInventory(kItemSpearSkull);
case 46: // S1 jam, S2 not jam, S3 not jam, S4 jam, not altar, only 1 skull in inventory
return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadBStatus == 0 && _globalFlags.myAGHeadCStatus == 0 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0 && (inventoryWindow->isItemInInventory(kItemCavernSkull) ^ inventoryWindow->isItemInInventory(kItemEntrySkull) ^ inventoryWindow->isItemInInventory(kItemSpearSkull));
case 47: // S1 jam, S3 jam, S4 jam, not altar
return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadCStatus == 2 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0;
case 48: // S1 jam, S3 jam, not altar, only 1 skull in inventory
return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadCStatus == 2 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0 && (inventoryWindow->isItemInInventory(kItemCavernSkull) ^ inventoryWindow->isItemInInventory(kItemEntrySkull) ^ inventoryWindow->isItemInInventory(kItemSpearSkull));
case 49: // S1 jam, S2 jam, S3 jam, not altar
return _globalFlags.myAGHeadAStatus == 2 && _globalFlags.myAGHeadCStatus == 2 && _globalFlags.myAGHeadDStatus == 2 && _globalFlags.myAGVisitedAltar == 0;
case 50: // S1 not jam, S2 jam, not altar
return _globalFlags.myAGHeadAStatus == 0 && _globalFlags.myAGHeadBStatus == 2 && _globalFlags.myAGVisitedAltar == 0;
}
return false;
}
SceneBase *SceneViewWindow::constructMayanSceneObject(Window *viewWindow, const LocationStaticData &sceneStaticData, const Location &priorLocation) {
SceneViewWindow *sceneView = ((SceneViewWindow *)viewWindow);
GlobalFlags &globalFlags = sceneView->getGlobalFlags();
byte dummyFlag = 0; // a dummy flag, used as a placeholder for writing (but not reading)
// Special scene for the trial version
if (_vm->isTrial())
return new TrialRecallScene(_vm, viewWindow, sceneStaticData, priorLocation);
switch (sceneStaticData.classID) {
case 0:
// Default scene
break;
case 1:
return new VideoDeath(_vm, viewWindow, sceneStaticData, priorLocation, 10, IDS_HUMAN_PRESENCE_500METERS);
case 2:
return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 60, 134, 118, 180, kItemCeramicBowl, 96, globalFlags.myPickedUpCeramicBowl);
case 3:
return new PlaceCeramicBowl(_vm, viewWindow, sceneStaticData, priorLocation);
case 4:
return new ClickChangeDepth(_vm, viewWindow, sceneStaticData, priorLocation, 1, kCursorMagnifyingGlass, 0, 0, 432, 189);
case 5:
return new AdjustWheels(_vm, viewWindow, sceneStaticData, priorLocation);
case 6:
return new DateCombinationRead(_vm, viewWindow, sceneStaticData, priorLocation);
case 7:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_INNER_DOOR_TRANS_TEXT, 16, 6, 402, 110, globalFlags.myTPTextTranslated, globalFlags.myTPTransBreathOfItzamna, dummyFlag);
case 8:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_INNER_LEFT_TRANS_TEXT, 1, 6, 431, 98, globalFlags.myTPTextTranslated, dummyFlag, dummyFlag);
case 9:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_INNER_MIDDLE_TRANS_TEXT, 16, 8, 430, 114, globalFlags.myTPTextTranslated, globalFlags.myTPCalendarTopTranslated, dummyFlag);
case 10:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_OUTER_SOUTHLEFT_TRANS_TEXT, 4, 55, 426, 95, globalFlags.myTPTextTranslated, dummyFlag, dummyFlag);
case 11:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_OUTER_WEST_TRANS_TEXT, 4, 72, 420, 108, globalFlags.myTPTextTranslated, dummyFlag, dummyFlag);
case 12:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYTP_OUTER_NORTH_TRANS_TEXT, 6, 38, 428, 76, globalFlags.myTPTextTranslated, dummyFlag, dummyFlag);
case 13:
return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 140, 124, 174, 158, kItemCavernSkull, 3, globalFlags.myMCPickedUpSkull);
case 14:
return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
case 15:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WG_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, globalFlags.myMCTransDoor, globalFlags.myWGTransDoorTop, dummyFlag);
case 16:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WG_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, globalFlags.myMCTransDoor, globalFlags.myMCTransWGOffering, dummyFlag);
case 17:
return new GenericCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, kItemGoldCoins, 4, TRANSITION_WALK, -1, 1082, 13);
case 18:
return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
case 19:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WATERGOD_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, globalFlags.myMCTransDoor, dummyFlag, dummyFlag);
case 20:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_WATERGOD_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, globalFlags.myMCTransDoor, globalFlags.myMCTransWTOffering, dummyFlag);
case 21:
return new GenericCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, kItemWaterCanFull, 4, TRANSITION_WALK, -1, 1125, 13);
case 22:
return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
case 23:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_AG_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, globalFlags.myMCTransDoor, dummyFlag, dummyFlag);
case 24:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_AG_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, globalFlags.myMCTransDoor, globalFlags.myMCTransAGOffering, dummyFlag);
case 25:
return new GenericCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, kItemBloodyArrow, 4, TRANSITION_WALK, -1, 1010, 12);
case 26:
return new GenericCavernDoorMainView(_vm, viewWindow, sceneStaticData, priorLocation, 1, 126, 1, 306, 30, 2, 287, 30, 379, 82, 3, 275, 84, 401, 174);
case 27:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_DEATHGOD_DOOR_TOP_TRANS_TEXT, 12, 128, 426, 156, globalFlags.myMCTransDoor, dummyFlag, dummyFlag);
case 28:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDMYMC_DEATHGOD_DOOR_RIGHT_TRANS_TEXT, 46, 1, 315, 188, globalFlags.myMCTransDoor, globalFlags.myMCTransDGOffering, dummyFlag);
case 29:
return new DeathGodCavernDoorOfferingHead(_vm, viewWindow, sceneStaticData, priorLocation, 4, TRANSITION_WALK, -1, 1045, 13);
case 30:
return new WealthGodRopeDrop(_vm, viewWindow, sceneStaticData, priorLocation);
case 31:
return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 194, 106, 278, 126, kItemJadeBlock, 105, globalFlags.myWGRetrievedJadeBlock);
case 32:
return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 140, 22, 306, 189, 2, 3, 0, 3, 1, 1, TRANSITION_WALK, -1, 264, 14, 14);
case 33:
return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 158, 88, 288, 116, kItemLimestoneBlock, 84, globalFlags.myWTRetrievedLimestoneBlock);
case 34:
return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 80, 0, 332, 189, 2, 4, 0, 2, 1, 1, TRANSITION_WALK, -1, 401, 14, 14);
case 35:
return new WaterGodInitialWalkSetFlag(_vm, viewWindow, sceneStaticData, priorLocation);
case 36:
return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 0, 93, 37, 10, 73, false, 18);
case 37:
return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 166, 259, 37, 10, 73);
case 38:
return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 332, 425, 37, 10, 73);
case 39:
return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 498, 591, 37, 10, 73);
case 40:
return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 664, 757, 37, 10, 73);
case 41:
return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 830, 925, 37, 10, 71, true);
case 42:
return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 999, 1075, 37, 10, 73);
case 43:
return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1149, 1242, 37, 10, 73);
case 44:
return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1315, 1408, 37, 10, 73);
case 45:
return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1481, 1574, 37, 10, 73);
case 46:
return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1647, 1740, 37, 10, 73);
case 47:
return new WaterGodBridgeJump(_vm, viewWindow, sceneStaticData, priorLocation, 4, 1813, 1906, 37, 10, 73);
case 50:
return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation,106, 0, 294, 189, 2, 5, 0, 1, 1, 1, TRANSITION_WALK, -1, 427, 13, 11);
case 51:
return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 235, 144, 285, 181, kItemEntrySkull, 3, globalFlags.myAGRetrievedEntrySkull);
case 52:
return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 200, 138, 231, 185, kItemSpearSkull, 46, globalFlags.myAGRetrievedSpearSkull);
case 53:
return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 201, 4, 235, 22, kItemCopperMedallion, 45, globalFlags.myAGRetrievedCopperMedal);
case 54:
return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 206, 110, 280, 142, kItemObsidianBlock, 72, globalFlags.myAGRetrievedObsidianBlock);
case 55:
return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 0, 182, 87, 242, 189, 4, 75, 83, 79, 0, 2, 1, 3);
case 56:
return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 1, 194, 89, 256, 189, 10, 76, 84, 80, 4, 6, 5, 7);
case 57:
return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 2, 178, 93, 246, 189, 28, 77, 85, 81, 8, 10, 9, 11);
case 58:
return new ArrowGodHead(_vm, viewWindow, sceneStaticData, priorLocation, 3, 188, 92, 252, 189, 34, 78, 86, 82, 12, 14, 13, 15);
case 59:
return new ArrowGodDepthChange(_vm, viewWindow, sceneStaticData, priorLocation);
case 60:
return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 11);
case 65:
return new BasicDoor(_vm, viewWindow, sceneStaticData, priorLocation, 90, 15, 346, 189, 2, 6, 0, 0, 1, 1, TRANSITION_WALK, -1, 33, 12, 13);
case 66:
return new DeathGodAltar(_vm, viewWindow, sceneStaticData, priorLocation);
case 67:
return new DeathGodPuzzleBox(_vm, viewWindow, sceneStaticData, priorLocation);
case 68:
return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 206, 76, 246, 116, kItemEnvironCart, 53, globalFlags.takenEnvironCart);
case 69:
return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 10);
case 70:
return new PlayStingers(_vm, viewWindow, sceneStaticData, priorLocation, 128, globalFlags.myMCStingerID, globalFlags.myMCStingerChannelID, 11, 14);
case 71:
return new DisplayMessageWithEvidenceWhenEnteringNode(_vm, viewWindow, sceneStaticData, priorLocation, MAYAN_EVIDENCE_BROKEN_GLASS_PYRAMID, IDS_MBT_EVIDENCE_PRESENT);
case 72:
return new MainCavernGlassCapture(_vm, viewWindow, sceneStaticData, priorLocation);
case 75:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 4500, 12, 14);
case 76:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 64, 6333, 12);
case 77:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 2, 1000, 2);
case 78:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 2, 1000, 2, 14);
case 79:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 6500, 12);
case 80:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 16, 4750, 12);
case 81:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 30, 7750, 6);
case 82:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 16, 2250, 18);
case 83:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 30, 2410, 6);
case 84:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 64, 7666, 18);
case 85:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 255, 0, -1, 10); // First param has to be wrong
case 86:
return new SetVolumeAndFlag(_vm, viewWindow, sceneStaticData, priorLocation, 64, globalFlags.myWGSeenLowerPassage);
case 87:
return new SetVolumeAndFlag(_vm, viewWindow, sceneStaticData, priorLocation, 64, globalFlags.myWGCrossedRopeBridge);
case 88:
return new SetVolumeAndFlag(_vm, viewWindow, sceneStaticData, priorLocation, 64, dummyFlag);
case 90:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 3160, 12, 14);
case 91:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 64, 4160, 12);
case 92:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 40, 4160, 12);
case 93:
return new WalkVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 16, 3160, 12);
case 100:
return new AdjustSecondaryAmbientOnEntry(_vm, viewWindow, sceneStaticData, priorLocation);
case 101:
return new WalkDualAmbientVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 16, 32, 6900, 12);
case 102:
return new WalkDualAmbientVolumeChange(_vm, viewWindow, sceneStaticData, priorLocation, 64, 128, 6900, 12);
case 103:
return new PlaySoundEnteringFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 12, 2, 4, 4, 2, 1, 5);
case 120:
return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 10);
case 121:
return new PlaySoundExitingFromScene(_vm, viewWindow, sceneStaticData, priorLocation, 14);
case 125:
return new GenericItemAcquire(_vm, viewWindow, sceneStaticData, priorLocation, 226, 90, 256, 104, kItemCopperMedallion, 15, globalFlags.myAGRetrievedCopperMedal);
case 126:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDS_MY_AG_ALTAR_TEXT, 120, 44, 330, 72, dummyFlag, dummyFlag, globalFlags.myAGVisitedAltar);
case 127:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDS_MY_WG_ALTAR_TEXT, 118, 14, 338, 44, dummyFlag, dummyFlag, dummyFlag);
case 128:
return new ViewSingleTranslation(_vm, viewWindow, sceneStaticData, priorLocation, IDS_MY_WT_ALTAR_TEXT, 106, 128, 344, 162, dummyFlag, dummyFlag, dummyFlag);
default:
warning("Unknown Mayan scene object %d", sceneStaticData.classID);
break;
}
return new SceneBase(_vm, viewWindow, sceneStaticData, priorLocation);
}
} // End of namespace Buried