scummvm/engines/pegasus/neighborhood/mars/mars.cpp
2011-10-28 22:21:30 -04:00

3750 lines
126 KiB
C++
Executable File

/* 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-1997 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 2
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/events.h"
#include "video/qt_decoder.h"
#include "pegasus/cursor.h"
#include "pegasus/energymonitor.h"
#include "pegasus/gamestate.h"
#include "pegasus/pegasus.h"
#include "pegasus/ai/ai_area.h"
#include "pegasus/items/biochips/opticalchip.h"
#include "pegasus/items/biochips/shieldchip.h"
#include "pegasus/items/inventory/airmask.h"
#include "pegasus/neighborhood/mars/mars.h"
namespace Pegasus {
// This should really be 22.5.
// Probably no one will know the difference.
const int16 kMarsShieldPanelOffsetAngle = 22;
const tCanMoveForwardReason kCantMoveRobotBlocking = kCantMoveLastReason + 1;
const tNotificationFlags kTimeForCanyonChaseFlag = kLastNeighborhoodNotificationFlag << 1;
const tNotificationFlags kExplosionFinishedFlag = kTimeForCanyonChaseFlag << 1;
const tNotificationFlags kTimeToTransportFlag = kExplosionFinishedFlag << 1;
const tNotificationFlags kMarsNotificationFlags = kTimeForCanyonChaseFlag |
kExplosionFinishedFlag |
kTimeToTransportFlag;
const TimeValue kLittleExplosionStart = 0 * 40;
const TimeValue kLittleExplosionStop = 24 * 40;
const TimeValue kBigExplosionStart = 24 * 40;
const TimeValue kBigExplosionStop = 62 * 40;
enum {
kMaze007RobotLoopingEvent,
kMaze015RobotLoopingEvent,
kMaze101RobotLoopingEvent,
kMaze104RobotLoopingEvent,
kMaze133RobotLoopingEvent,
kMaze136RobotLoopingEvent,
kMaze184RobotLoopingEvent
};
enum {
kMaze007RobotLoopingTime = (64 + 96) * kMarsFrameDuration,
kMaze015RobotLoopingTime = (64 + 93) * kMarsFrameDuration,
kMaze101RobotLoopingTime = (64 + 45) * kMarsFrameDuration,
kMaze104RobotLoopingTime = 96 * kMarsFrameDuration,
kMaze133RobotLoopingTime = (64 + 96) * kMarsFrameDuration,
kMaze136RobotLoopingTime = (64 + 96) * kMarsFrameDuration,
kMaze184RobotLoopingTime = 96 * kMarsFrameDuration
};
// I've made a couple macros for these rects so we don't
// have to globally construct them or whatnot
#define kShuttleEnergyBeamBounds Common::Rect(24, 27, 24 + 112, 27 + 46)
#define kShuttleGravitonBounds Common::Rect(24, 73, 24 + 112, 73 + 30)
#define kShuttleTractorBounds Common::Rect(24, 103, 24 + 112, 103 + 30)
#define kShuttleTransportBounds Common::Rect(484, 353, 89 + 484, 79 + 353)
void robotTimerExpiredFunction(FunctionPtr *, void *mars) {
((Mars *)mars)->robotTiredOfWaiting();
}
void lockThawTimerExpiredFunction(FunctionPtr *, void *mars) {
((Mars *)mars)->lockThawed();
}
void bombTimerExpiredFunction(FunctionPtr *, void *mars) {
((Mars *)mars)->didntFindBomb();
}
void bombTimerExpiredInGameFunction(FunctionPtr *, void *mars) {
((Mars *)mars)->bombExplodesInGame();
}
void airStageExpiredFunction(FunctionPtr *, void *mars) {
((Mars *)mars)->airStageExpired();
}
void marsTimerFunction(FunctionPtr *, void *event) {
((MarsTimerEvent *)event)->mars->marsTimerExpired(*(MarsTimerEvent *)event);
}
Mars::Mars(InputHandler *nextHandler, PegasusEngine *owner) : Neighborhood(nextHandler, owner, "Mars", kMarsID),
_guessObject(kNoDisplayElement), _undoPict(kNoDisplayElement), _guessHistory(kNoDisplayElement),
_choiceHighlight(kNoDisplayElement), _shuttleInterface1(kNoDisplayElement), _shuttleInterface2(kNoDisplayElement),
_shuttleInterface3(kNoDisplayElement), _shuttleInterface4(kNoDisplayElement), _canyonChaseMovie(kNoDisplayElement),
_leftShuttleMovie(kNoDisplayElement), _rightShuttleMovie(kNoDisplayElement), _lowerLeftShuttleMovie(kNoDisplayElement),
_lowerRightShuttleMovie(kNoDisplayElement), _centerShuttleMovie(kNoDisplayElement),
_upperLeftShuttleMovie(kNoDisplayElement), _upperRightShuttleMovie(kNoDisplayElement),
_leftDamageShuttleMovie(kNoDisplayElement), _rightDamageShuttleMovie(kNoDisplayElement), _explosions(kNoDisplayElement),
_planetMovie(kNoDisplayElement), _junk(kNoDisplayElement), _energyChoiceSpot(kShuttleEnergySpotID),
_gravitonChoiceSpot(kShuttleGravitonSpotID), _tractorChoiceSpot(kShuttleTractorSpotID),
_shuttleViewSpot(kShuttleViewSpotID), _shuttleTransportSpot(kShuttleTransportSpotID) {
_noAirFuse.setFunctionPtr(&airStageExpiredFunction, this);
setIsItemTaken(kMarsCard);
setIsItemTaken(kAirMask);
setIsItemTaken(kCrowbar);
setIsItemTaken(kCardBomb);
}
Mars::~Mars() {
g_allHotspots.remove(&_energyChoiceSpot);
g_allHotspots.remove(&_gravitonChoiceSpot);
g_allHotspots.remove(&_tractorChoiceSpot);
g_allHotspots.remove(&_shuttleViewSpot);
g_allHotspots.remove(&_shuttleTransportSpot);
}
void Mars::init() {
Neighborhood::init();
Hotspot *attackSpot = g_allHotspots.findHotspotByID(kAttackRobotHotSpotID);
attackSpot->setMaskedHotspotFlags(kDropItemSpotFlag, kDropItemSpotFlag);
_attackingItem = NULL;
forceStridingStop(kMars08, kNorth, kAltMarsNormal);
_neighborhoodNotification.notifyMe(this, kMarsNotificationFlags, kMarsNotificationFlags);
_explosionCallBack.setNotification(&_neighborhoodNotification);
_explosionCallBack.setCallBackFlag(kExplosionFinishedFlag);
}
void Mars::flushGameState() {
g_energyMonitor->saveCurrentEnergyValue();
}
void Mars::start() {
g_energyMonitor->stopEnergyDraining();
g_energyMonitor->restoreLastEnergyValue();
_vm->resetEnergyDeathReason();
g_energyMonitor->startEnergyDraining();
Neighborhood::start();
}
class AirMaskCondition : public AICondition {
public:
AirMaskCondition(const uint32);
virtual bool fireCondition();
protected:
uint32 _airThreshold;
uint32 _lastAirLevel;
};
AirMaskCondition::AirMaskCondition(const uint32 airThreshold) {
_airThreshold = airThreshold;
_lastAirLevel = g_airMask->getAirLeft();
}
bool AirMaskCondition::fireCondition() {
bool result = g_airMask && g_airMask->isAirMaskOn() &&
g_airMask->getAirLeft() <= _airThreshold && _lastAirLevel > _airThreshold;
_lastAirLevel = g_airMask->getAirLeft();
return result;
}
void Mars::setUpAIRules() {
Neighborhood::setUpAIRules();
// Don't add these rules if we're going to the robot's shuttle...
if (g_AIArea && !GameState.getMarsReadyForShuttleTransport()) {
AIPlayMessageAction *messageAction = new AIPlayMessageAction("Images/AI/Globals/XGLOB1E", false);
AILocationCondition *locCondition = new AILocationCondition(1);
locCondition->addLocation(MakeRoomView(kMars47, kSouth));
AIRule *rule = new AIRule(locCondition, messageAction);
g_AIArea->addAIRule(rule);
messageAction = new AIPlayMessageAction("Images/AI/Mars/XM27NB", false);
locCondition = new AILocationCondition(1);
locCondition->addLocation(MakeRoomView(kMars27, kNorth));
rule = new AIRule(locCondition, messageAction);
g_AIArea->addAIRule(rule);
messageAction = new AIPlayMessageAction("Images/AI/Mars/XM27NB", false);
locCondition = new AILocationCondition(1);
locCondition->addLocation(MakeRoomView(kMars28, kNorth));
rule = new AIRule(locCondition, messageAction);
g_AIArea->addAIRule(rule);
messageAction = new AIPlayMessageAction("Images/AI/Mars/XM41ED", false);
locCondition = new AILocationCondition(1);
locCondition->addLocation(MakeRoomView(kMars19, kEast));
rule = new AIRule(locCondition, messageAction);
g_AIArea->addAIRule(rule);
AIDeactivateRuleAction *deactivate = new AIDeactivateRuleAction(rule);
locCondition = new AILocationCondition(1);
locCondition->addLocation(MakeRoomView(kMars35, kWest));
rule = new AIRule(locCondition, deactivate);
g_AIArea->addAIRule(rule);
messageAction = new AIPlayMessageAction("Images/AI/Mars/XM41ED", false);
locCondition = new AILocationCondition(1);
locCondition->addLocation(MakeRoomView(kMars48, kWest));
rule = new AIRule(locCondition, messageAction);
g_AIArea->addAIRule(rule);
AirMaskCondition *airMask50Condition = new AirMaskCondition(50);
messageAction = new AIPlayMessageAction("Images/AI/Mars/XMMAZB1", false);
AIRule *rule50 = new AIRule(airMask50Condition, messageAction);
AirMaskCondition *airMask25Condition = new AirMaskCondition(25);
AICompoundAction *compound = new AICompoundAction();
messageAction = new AIPlayMessageAction("Images/AI/Mars/XMMAZB2", false);
compound->addAction(messageAction);
deactivate = new AIDeactivateRuleAction(rule50);
compound->addAction(deactivate);
AIRule *rule25 = new AIRule(airMask25Condition, compound);
AirMaskCondition *airMask5Condition = new AirMaskCondition(5);
compound = new AICompoundAction;
messageAction = new AIPlayMessageAction("Images/AI/Mars/XMMAZB3", false);
compound->addAction(messageAction);
deactivate = new AIDeactivateRuleAction(rule50);
compound->addAction(deactivate);
deactivate = new AIDeactivateRuleAction(rule25);
compound->addAction(deactivate);
AIRule *rule5 = new AIRule(airMask5Condition, compound);
g_AIArea->addAIRule(rule5);
g_AIArea->addAIRule(rule25);
g_AIArea->addAIRule(rule50);
messageAction = new AIPlayMessageAction("Images/AI/Mars/XM51ND", false);
AIDoorOpenedCondition *doorOpen = new AIDoorOpenedCondition(MakeRoomView(kMars51, kEast));
rule = new AIRule(doorOpen, messageAction);
g_AIArea->addAIRule(rule);
}
}
uint16 Mars::getDateResID() const {
return kDate2185ID;
}
TimeValue Mars::getViewTime(const tRoomID room, const tDirectionConstant direction) {
ExtraTable::Entry extra;
SpotTable::Entry spotEntry;
uint32 extraID = 0xffffffff;
switch (MakeRoomView(room, direction)) {
case MakeRoomView(kMars0A, kNorth):
if (!GameState.getMarsSeenTimeStream()) {
getExtraEntry(kMarsArrivalFromTSA, extra);
return extra.movieStart;
}
break;
case MakeRoomView(kMars31South, kSouth):
if (GameState.isTakenItemID(kMarsCard))
extraID = kMars31SouthZoomViewNoCard;
break;
case MakeRoomView(kMars31, kSouth):
if (GameState.isTakenItemID(kMarsCard))
extraID = kMars31SouthViewNoCard;
break;
case MakeRoomView(kMars34, kSouth):
if (_privateFlags.getFlag(kMarsPrivatePodStorageOpenFlag)) {
if (GameState.isTakenItemID(kCrowbar))
extraID = kMars34ViewOpenNoBar;
else
extraID = kMars34ViewOpenWithBar;
}
break;
case MakeRoomView(kMars36, kSouth):
case MakeRoomView(kMars37, kSouth):
case MakeRoomView(kMars38, kSouth):
findSpotEntry(room, direction, kSpotOnTurnMask | kSpotLoopsMask, spotEntry);
return spotEntry.movieStart;
case MakeRoomView(kMars45, kNorth):
if (_privateFlags.getFlag(kMarsPrivatePodStorageOpenFlag)) {
if (GameState.isTakenItemID(kCrowbar))
extraID = kMars45ViewOpenNoBar;
else
extraID = kMars45ViewOpenWithBar;
}
break;
case MakeRoomView(kMars48, kEast):
if (GameState.getMarsSeenRobotAtReactor() && !GameState.getMarsAvoidedReactorRobot())
extraID = kMars48RobotView;
break;
case MakeRoomView(kMars56, kEast):
if (_privateFlags.getFlag(kMarsPrivateBombExposedFlag)) {
if (_privateFlags.getFlag(kMarsPrivateDraggingBombFlag))
extraID = kMars57ViewOpenNoBomb;
else
extraID = kMars57ExposeBomb;
} else if (GameState.getMarsLockBroken()) {
extraID = kMars57OpenPanelChoices;
} else if (GameState.getMarsLockFrozen()) {
extraID = kMars57LockFrozenView;
}
break;
case MakeRoomView(kMarsRobotShuttle, kEast):
if (getCurrentActivation() == kActivationRobotHeadOpen) {
extraID = kMarsRobotHead111;
if (_privateFlags.getFlag(kMarsPrivateGotMapChipFlag))
extraID -= 1;
if (_privateFlags.getFlag(kMarsPrivateGotOpticalChipFlag))
extraID -= 2;
if (_privateFlags.getFlag(kMarsPrivateGotShieldChipFlag))
extraID -= 4;
}
break;
}
if (extraID == 0xffffffff)
return Neighborhood::getViewTime(room, direction);
getExtraEntry(extraID, extra);
return extra.movieEnd - 1;
}
void Mars::getZoomEntry(const tHotSpotID spotID, ZoomTable::Entry &entry) {
Neighborhood::getZoomEntry(spotID, entry);
uint32 extraID = 0xffffffff;
switch (spotID) {
case kMars31SouthSpotID:
if (GameState.getCurrentDirection() == kSouth && GameState.isTakenItemID(kMarsCard))
extraID = kMars31SouthZoomInNoCard;
break;
case kMars31SouthOutSpotID:
if (GameState.getCurrentDirection() == kSouth && GameState.isTakenItemID(kMarsCard))
extraID = kMars31SouthZoomOutNoCard;
break;
}
if (extraID != 0xffffffff) {
ExtraTable::Entry extra;
getExtraEntry(extraID, extra);
entry.movieStart = extra.movieStart;
entry.movieEnd = extra.movieEnd;
}
}
void Mars::findSpotEntry(const tRoomID room, const tDirectionConstant direction, tSpotFlags flags, SpotTable::Entry &entry) {
Neighborhood::findSpotEntry(room, direction, flags, entry);
if ((flags & (kSpotOnArrivalMask | kSpotOnTurnMask)) != 0) {
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars27, kNorth):
if (GameState.getMarsSeenThermalScan())
entry.clear();
else
GameState.setMarsSeenThermalScan(true);
break;
case MakeRoomView(kMars28, kNorth):
if (GameState.getMarsSeenThermalScan())
entry.clear();
else
GameState.setMarsSeenThermalScan(true);
break;
}
}
}
tCanMoveForwardReason Mars::canMoveForward(ExitTable::Entry &entry) {
tCanMoveForwardReason reason = Neighborhood::canMoveForward(entry);
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars48, kEast):
if (GameState.getMarsSeenRobotAtReactor() && !GameState.getMarsAvoidedReactorRobot())
reason = kCantMoveRobotBlocking;
break;
case MakeRoomView(kMars48, kSouth):
if (GameState.getMarsSeenRobotAtReactor() && !GameState.getMarsAvoidedReactorRobot())
_utilityFuse.stopFuse();
break;
}
return reason;
}
void Mars::cantMoveThatWay(tCanMoveForwardReason reason) {
if (reason == kCantMoveRobotBlocking) {
startExtraSequence(kMars48RobotKillsPlayer, kExtraCompletedFlag, kFilterNoInput);
loadLoopSound2("");
} else {
Neighborhood::cantMoveThatWay(reason);
}
}
void Mars::moveForward() {
if (GameState.getCurrentRoom() == kMars02 || (GameState.getCurrentRoom() >= kMars05 && GameState.getCurrentRoom() <= kMars08))
loadLoopSound2("");
Neighborhood::moveForward();
}
void Mars::bumpIntoWall() {
requestSpotSound(kMarsBumpIntoWallIn, kMarsBumpIntoWallOut, kFilterNoInput, 0);
Neighborhood::bumpIntoWall();
}
tCanOpenDoorReason Mars::canOpenDoor(DoorTable::Entry &entry) {
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars05, kEast):
case MakeRoomView(kMars06, kEast):
case MakeRoomView(kMars07, kEast):
if (!GameState.getMarsSecurityDown())
return kCantOpenLocked;
break;
case MakeRoomView(kMarsMaze037, kWest):
case MakeRoomView(kMarsMaze038, kEast):
if (GameState.getMarsMazeDoorPair1())
return kCantOpenLocked;
break;
case MakeRoomView(kMarsMaze050, kNorth):
case MakeRoomView(kMarsMaze058, kSouth):
if (!GameState.getMarsMazeDoorPair1())
return kCantOpenLocked;
break;
case MakeRoomView(kMarsMaze047, kNorth):
case MakeRoomView(kMarsMaze142, kSouth):
if (GameState.getMarsMazeDoorPair2())
return kCantOpenLocked;
break;
case MakeRoomView(kMarsMaze057, kNorth):
case MakeRoomView(kMarsMaze136, kSouth):
if (!GameState.getMarsMazeDoorPair2())
return kCantOpenLocked;
break;
case MakeRoomView(kMarsMaze120, kWest):
case MakeRoomView(kMarsMaze121, kEast):
if (GameState.getMarsMazeDoorPair3())
return kCantOpenLocked;
break;
case MakeRoomView(kMarsMaze081, kNorth):
case MakeRoomView(kMarsMaze083, kSouth):
if (!GameState.getMarsMazeDoorPair3())
return kCantOpenLocked;
break;
}
return Neighborhood::canOpenDoor(entry);
}
void Mars::cantOpenDoor(tCanOpenDoorReason reason) {
switch (GameState.getCurrentRoom()) {
case kMars05:
case kMars06:
case kMars07:
playSpotSoundSync(kMarsCantOpenShuttleIn, kMarsCantOpenShuttleOut);
break;
default:
Neighborhood::cantOpenDoor(reason);
break;
}
}
void Mars::openDoor() {
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars06, kEast):
case MakeRoomView(kMars07, kEast):
if (GameState.getMarsSecurityDown())
playSpotSoundSync(kMarsNoShuttleIn, kMarsNoShuttleOut);
break;
case MakeRoomView(kMars47, kSouth):
if (GameState.isTakenItemID(kAirMask))
setCurrentAlternate(kAltMarsTookMask);
else
setCurrentAlternate(kAltMarsNormal);
break;
case MakeRoomView(kMars48, kNorth):
if (GameState.getMarsPodAtUpperPlatform())
setCurrentAlternate(kAltMarsNormal);
else
setCurrentAlternate(kAltMarsPodAtMars45);
break;
case MakeRoomView(kMars48, kEast):
if (GameState.getMarsSeenRobotAtReactor() && !GameState.getMarsAvoidedReactorRobot()) {
die(kDeathDidntGetOutOfWay);
return;
}
break;
}
Neighborhood::openDoor();
}
void Mars::doorOpened() {
switch (GameState.getCurrentRoom()) {
case kMars27:
case kMars28:
if (GameState.getCurrentDirection() == kNorth)
_vm->die(kDeathArrestedInMars);
else
Neighborhood::doorOpened();
break;
case kMars41:
case kMars42:
if (GameState.getCurrentDirection() == kEast)
_vm->die(kDeathWrongShuttleLock);
else
Neighborhood::doorOpened();
break;
case kMars51:
Neighborhood::doorOpened();
setUpReactorEnergyDrain();
if (g_AIArea)
g_AIArea->checkRules();
break;
case kMars19:
if (GameState.getCurrentDirection() == kEast)
GameState.setMarsAirlockOpen(true);
Neighborhood::doorOpened();
break;
case kMars48:
if (GameState.getCurrentDirection() == kWest)
GameState.setMarsAirlockOpen(true);
Neighborhood::doorOpened();
break;
default:
Neighborhood::doorOpened();
break;
}
}
void Mars::setUpReactorEnergyDrain() {
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars51, kEast):
if (GameState.isCurrentDoorOpen()) {
if (g_energyMonitor->getEnergyDrainRate() == kEnergyDrainNormal) {
if (GameState.getShieldOn()) {
g_shield->setItemState(kShieldRadiation);
g_energyMonitor->setEnergyDrainRate(kMarsReactorEnergyDrainWithShield);
} else {
g_energyMonitor->setEnergyDrainRate(kMarsReactorEnergyDrainNoShield);
}
_vm->setEnergyDeathReason(kDeathReactorBurn);
}
} else {
if (g_energyMonitor->getEnergyDrainRate() != kEnergyDrainNormal) {
if (GameState.getShieldOn())
g_shield->setItemState(kShieldNormal);
g_energyMonitor->setEnergyDrainRate(kEnergyDrainNormal);
_vm->resetEnergyDeathReason();
}
}
break;
case MakeRoomView(kMars52, kNorth):
case MakeRoomView(kMars52, kSouth):
case MakeRoomView(kMars52, kEast):
case MakeRoomView(kMars52, kWest):
case MakeRoomView(kMars54, kNorth):
case MakeRoomView(kMars54, kSouth):
case MakeRoomView(kMars54, kEast):
case MakeRoomView(kMars54, kWest):
case MakeRoomView(kMars56, kNorth):
case MakeRoomView(kMars56, kSouth):
case MakeRoomView(kMars56, kEast):
case MakeRoomView(kMars56, kWest):
case MakeRoomView(kMars58, kNorth):
case MakeRoomView(kMars58, kSouth):
case MakeRoomView(kMars58, kEast):
case MakeRoomView(kMars58, kWest):
if (g_energyMonitor->getEnergyDrainRate() == kEnergyDrainNormal) {
if (GameState.getShieldOn()) {
g_shield->setItemState(kShieldRadiation);
g_energyMonitor->setEnergyDrainRate(kMarsReactorEnergyDrainWithShield);
} else {
g_energyMonitor->setEnergyDrainRate(kMarsReactorEnergyDrainNoShield);
}
_vm->setEnergyDeathReason(kDeathReactorBurn);
}
break;
default:
if (g_energyMonitor->getEnergyDrainRate() != kEnergyDrainNormal) {
if (GameState.getShieldOn())
g_shield->setItemState(kShieldNormal);
g_energyMonitor->setEnergyDrainRate(kEnergyDrainNormal);
_vm->resetEnergyDeathReason();
}
break;
}
}
void Mars::closeDoorOffScreen(const tRoomID room, const tDirectionConstant direction) {
switch (room) {
case kMars51:
playSpotSoundSync(kMarsGantryDoorCloseIn, kMarsGantryDoorCloseOut);
if (GameState.getShieldOn())
g_shield->setItemState(kShieldNormal);
g_energyMonitor->setEnergyDrainRate(kEnergyDrainNormal);
_vm->resetEnergyDeathReason();
break;
case kMars05:
case kMars06:
case kMars07:
case kMars13:
case kMars22:
case kMars47:
case kMars52:
playSpotSoundSync(kMarsGantryDoorCloseIn, kMarsGantryDoorCloseOut);
break;
case kMars18:
case kMars32:
playSpotSoundSync(kMarsTransportDoorCloseIn, kMarsTransportDoorCloseOut);
break;
case kMars19:
if (GameState.getCurrentRoom() != kMars35) {
playSpotSoundSync(kMarsBigAirlockDoorCloseIn, kMarsBigAirlockDoorCloseOut);
GameState.setMarsAirlockOpen(false);
}
break;
case kMars36:
if (GameState.getCurrentRoom() != kMars35)
playSpotSoundSync(kMarsSmallAirlockDoorCloseIn, kMarsSmallAirlockDoorCloseOut);
break;
case kMars48:
if (direction == kWest) {
if (GameState.getCurrentRoom() != kMars60) {
playSpotSoundSync(kMarsSmallAirlockDoorCloseIn, kMarsSmallAirlockDoorCloseOut);
GameState.setMarsAirlockOpen(false);
}
} else {
playSpotSoundSync(kMarsGantryDoorCloseIn, kMarsGantryDoorCloseOut);
}
break;
case kMars41:
case kMars42:
case kMars43:
if (direction == kWest)
playSpotSoundSync(kMarsGantryDoorCloseIn, kMarsGantryDoorCloseOut);
break;
case kMarsMaze037:
case kMarsMaze038:
case kMarsMaze012:
case kMarsMaze066:
case kMarsMaze050:
case kMarsMaze058:
case kMarsMaze057:
case kMarsMaze136:
case kMarsMaze047:
case kMarsMaze142:
case kMarsMaze133:
case kMarsMaze132:
case kMarsMaze113:
case kMarsMaze114:
case kMarsMaze120:
case kMarsMaze121:
case kMarsMaze081:
case kMarsMaze083:
case kMarsMaze088:
case kMarsMaze089:
case kMarsMaze179:
case kMarsMaze180:
playSpotSoundSync(kMarsMazeDoorCloseIn, kMarsMazeDoorCloseOut);
break;
}
}
void Mars::checkAirlockDoors() {
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars19, kWest):
case MakeRoomView(kMars18, kWest):
case MakeRoomView(kMars17, kWest):
case MakeRoomView(kMars16, kWest):
case MakeRoomView(kMars15, kWest):
case MakeRoomView(kMars14, kWest):
case MakeRoomView(kMars12, kWest):
case MakeRoomView(kMars11, kWest):
case MakeRoomView(kMars10, kWest):
if (GameState.getMarsInAirlock()) {
playSpotSoundSync(kMarsBigAirlockDoorCloseIn, kMarsBigAirlockDoorCloseOut);
GameState.setMarsInAirlock(false);
}
break;
case MakeRoomView(kMars36, kEast):
case MakeRoomView(kMars37, kEast):
case MakeRoomView(kMars38, kEast):
case MakeRoomView(kMars39, kEast):
case MakeRoomView(kMars48, kEast):
case MakeRoomView(kMars50, kEast):
case MakeRoomView(kMars51, kEast):
case MakeRoomView(kMars52, kEast):
if (GameState.getMarsInAirlock()) {
playSpotSoundSync(kMarsSmallAirlockDoorCloseIn, kMarsSmallAirlockDoorCloseOut);
GameState.setMarsInAirlock(false);
}
break;
case MakeRoomView(kMars35, kWest):
case MakeRoomView(kMars35, kEast):
case MakeRoomView(kMars60, kWest):
case MakeRoomView(kMars60, kEast):
GameState.setMarsInAirlock(true);
break;
default:
GameState.setMarsInAirlock(false);
break;
}
}
int16 Mars::getStaticCompassAngle(const tRoomID room, const tDirectionConstant dir) {
int16 angle = Neighborhood::getStaticCompassAngle(room, dir);
switch (MakeRoomView(room, dir)) {
case MakeRoomView(kMars0A, kNorth):
angle -= 20;
break;
case MakeRoomView(kMars23, kNorth):
case MakeRoomView(kMars23, kSouth):
case MakeRoomView(kMars23, kEast):
case MakeRoomView(kMars23, kWest):
case MakeRoomView(kMars26, kNorth):
case MakeRoomView(kMars26, kSouth):
case MakeRoomView(kMars26, kEast):
case MakeRoomView(kMars26, kWest):
angle += 30;
break;
case MakeRoomView(kMars24, kNorth):
case MakeRoomView(kMars24, kSouth):
case MakeRoomView(kMars24, kEast):
case MakeRoomView(kMars24, kWest):
case MakeRoomView(kMars25, kNorth):
case MakeRoomView(kMars25, kSouth):
case MakeRoomView(kMars25, kEast):
case MakeRoomView(kMars25, kWest):
angle -= 30;
break;
case MakeRoomView(kMars54, kNorth):
case MakeRoomView(kMars54, kSouth):
case MakeRoomView(kMars54, kEast):
case MakeRoomView(kMars54, kWest):
angle += 90;
break;
case MakeRoomView(kMars56, kNorth):
case MakeRoomView(kMars56, kSouth):
case MakeRoomView(kMars56, kEast):
case MakeRoomView(kMars56, kWest):
angle += 180;
break;
case MakeRoomView(kMars58, kNorth):
case MakeRoomView(kMars58, kSouth):
case MakeRoomView(kMars58, kEast):
case MakeRoomView(kMars58, kWest):
angle -= 90;
break;
}
return angle;
}
void Mars::getExitCompassMove(const ExitTable::Entry &exitEntry, FaderMoveSpec &compassMove) {
Neighborhood::getExitCompassMove(exitEntry, compassMove);
if (exitEntry.room == kMars43 && exitEntry.direction == kEast) {
compassMove.insertFaderKnot(exitEntry.movieStart + 16 * kMarsFrameDuration, 90);
compassMove.insertFaderKnot(exitEntry.movieStart + 32 * kMarsFrameDuration, 270);
} else if (exitEntry.room == kMars46 && exitEntry.direction == kWest && exitEntry.altCode != kAltMarsPodAtMars45) {
compassMove.makeTwoKnotFaderSpec(kMarsMovieScale, exitEntry.movieStart, 270, exitEntry.movieEnd, 360);
compassMove.insertFaderKnot(exitEntry.movieStart + 43 * kMarsFrameDuration, 270);
compassMove.insertFaderKnot(exitEntry.movieStart + 58 * kMarsFrameDuration, 360);
}
}
void Mars::getExtraCompassMove(const ExtraTable::Entry &entry, FaderMoveSpec &compassMove) {
switch (entry.extra) {
case kMarsTakePodToMars45:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart, 0, entry.movieEnd, 180);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * (kMarsFramesPerSecond * 3), 30);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * (kMarsFramesPerSecond * 11), 10);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * (kMarsFramesPerSecond * 14), 40);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * (kMarsFramesPerSecond * 16), 30);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * (kMarsFramesPerSecond * 23), 100);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * (kMarsFramesPerSecond * 31), 70);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * (kMarsFramesPerSecond * 34), 100);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * (kMarsFramesPerSecond * 37), 85);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * (kMarsFramesPerSecond * 42), 135);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * (kMarsFramesPerSecond * 44), 125);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * (kMarsFramesPerSecond * 46), 145);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * (kMarsFramesPerSecond * 49), 160);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * (kMarsFramesPerSecond * 51), 180);
break;
case kMars35WestSpinAirlockToEast:
case kMars60WestSpinAirlockToEast:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart, 90, entry.movieEnd, 270);
compassMove.insertFaderKnot(entry.movieStart + kMarsMovieScale, 90);
compassMove.insertFaderKnot(entry.movieStart + kMarsMovieScale * 3, 270);
break;
case kMars35EastSpinAirlockToWest:
case kMars60EastSpinAirlockToWest:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart, 270, entry.movieEnd, 90);
compassMove.insertFaderKnot(entry.movieStart + kMarsMovieScale, 270);
compassMove.insertFaderKnot(entry.movieStart + kMarsMovieScale * 3, 90);
break;
case kMars52SpinLeft:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart, kMars52Compass, entry.movieEnd, kMars54Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 10, kMars52Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 110, kMars54Compass);
break;
case kMars52SpinRight:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart, kMars52Compass, entry.movieEnd, kMars58Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 10, kMars52Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 110, kMars58Compass);
break;
case kMars52Extend:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart, kMars52Compass,
entry.movieEnd, kMars52Compass + kMarsShieldPanelOffsetAngle);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 10, kMars52Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 60, kMars52Compass + kMarsShieldPanelOffsetAngle);
break;
case kMars53Retract:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart,
kMars52Compass + kMarsShieldPanelOffsetAngle, entry.movieEnd, kMars52Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 10, kMars52Compass + kMarsShieldPanelOffsetAngle);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 60, kMars52Compass);
break;
case kMars56ExtendWithBomb:
case kMars56ExtendNoBomb:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart, kMars56Compass,
entry.movieEnd, kMars56Compass - kMarsShieldPanelOffsetAngle);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 10, kMars56Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 60, kMars56Compass - kMarsShieldPanelOffsetAngle);
break;
case kMars57RetractWithBomb:
case kMars57RetractNoBomb:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart,
kMars56Compass - kMarsShieldPanelOffsetAngle, entry.movieEnd, kMars56Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 10, kMars56Compass - kMarsShieldPanelOffsetAngle);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 60, kMars56Compass);
break;
case kMars54SpinLeft:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart, kMars54Compass, entry.movieEnd, kMars56Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 10, kMars54Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 110, kMars56Compass);
break;
case kMars54SpinRight:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart, kMars54Compass, entry.movieEnd, kMars52Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 10, kMars54Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 110, kMars52Compass);
break;
case kMars56SpinLeft:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart, kMars56Compass,
entry.movieEnd, kMars58Compass + 360);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 10, kMars56Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 110, kMars58Compass + 360);
break;
case kMars56SpinRight:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart, kMars56Compass, entry.movieEnd, kMars54Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 10, kMars56Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 110, kMars54Compass);
break;
case kMars58SpinLeft:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart, kMars58Compass,
entry.movieEnd, kMars52Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 10, kMars58Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 110, kMars52Compass);
break;
case kMars58SpinRight:
compassMove.makeTwoKnotFaderSpec(_navMovie.getScale(), entry.movieStart,
kMars58Compass + 360, entry.movieEnd, kMars56Compass);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 10, kMars58Compass + 360);
compassMove.insertFaderKnot(entry.movieStart + kMarsFrameDuration * 110, kMars56Compass);
break;
default:
Neighborhood::getExtraCompassMove(entry, compassMove);
}
}
void Mars::loadAmbientLoops() {
tRoomID room = GameState.getCurrentRoom();
if ((room >= kMars0A && room <= kMars21) || (room >= kMars41 && room <= kMars43)) {
if (GameState.getMarsSeenTimeStream())
loadLoopSound1("Sounds/Mars/Gantry Ambient.22K.8.AIFF");
} else if (room >= kMars22 && room <= kMars31South) {
loadLoopSound1("Sounds/Mars/Reception.02.22K.8.AIFF", 0x100 / 4);
} else if (room >= kMars32 && room <= kMars34) {
loadLoopSound1("Sounds/Mars/Pod Room Ambient.22K.8.AIFF");
} else if (room == kMars35) {
if (getAirQuality(room) == kAirQualityVacuum)
loadLoopSound1("Sounds/Mars/Gear Room Ambient.22K.8.AIFF");
else
loadLoopSound1("Sounds/Mars/Gantry Ambient.22K.8.AIFF", 0x100 / 2);
} else if (room >= kMars36 && room <= kMars39) {
loadLoopSound1("Sounds/Mars/Gear Room Ambient.22K.8.AIFF");
} else if (room >= kMars45 && room <= kMars51) {
loadLoopSound1("Sounds/Mars/Lower Mars Ambient.22K.8.AIFF");
} else if (room >= kMars52 && room <= kMars58) {
loadLoopSound1("Sounds/Mars/ReactorLoop.22K.8.AIFF");
} else if (room == kMars60) {
if (getAirQuality(room) == kAirQualityVacuum)
loadLoopSound1("Sounds/Mars/Mars Maze Ambient.22K.8.AIFF");
else
loadLoopSound1("Sounds/Mars/Lower Mars Ambient.22K.8.AIFF", 0x100 / 2);
} else if (room >= kMarsMaze004 && room <= kMarsMaze200) {
loadLoopSound1("Sounds/Mars/Mars Maze Ambient.22K.8.AIFF");
} else if (room == kMarsRobotShuttle) {
loadLoopSound1("Sounds/Mars/Robot Shuttle.22K.8.AIFF");
}
if (!_noAirFuse.isFuseLit()) {
switch (room) {
case kMars02:
case kMars05:
case kMars06:
case kMars07:
case kMars08:
loadLoopSound2("Sounds/Mars/Gantry Loop.aiff", 0x100, 0, 0);
break;
// Robot at maze 48
case kMarsMaze037:
if (GameState.isCurrentDoorOpen())
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 / 2);
else
loadLoopSound2("");
break;
case kMarsMaze038:
case kMarsMaze039:
case kMarsMaze049:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100);
break;
case kMarsMaze050:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 * 3 / 4);
break;
case kMarsMaze051:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 / 2);
break;
case kMarsMaze052:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 / 4);
break;
case kMarsMaze042:
case kMarsMaze053:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 / 8);
break;
case kMarsMaze058:
if (GameState.isCurrentDoorOpen())
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 / 4);
else
loadLoopSound2("");
break;
// Robot at 151
case kMarsMaze148:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100);
break;
case kMarsMaze147:
case kMarsMaze149:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 * 3 / 4);
break;
case kMarsMaze146:
case kMarsMaze152:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 / 2);
break;
case kMarsMaze145:
case kMarsMaze153:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 / 4);
break;
// Robots at 80 and 82.
case kMarsMaze079:
case kMarsMaze081:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100);
break;
case kMarsMaze078:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 * 3 / 4);
break;
case kMarsMaze083:
if (GameState.isCurrentDoorOpen())
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 * 3 / 4);
else
loadLoopSound2("");
break;
case kMarsMaze118:
case kMarsMaze076:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 / 2);
break;
case kMarsMaze074:
case kMarsMaze117:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 / 4);
break;
// Robot at 94
case kMarsMaze093:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100);
break;
case kMarsMaze091:
case kMarsMaze092:
case kMarsMaze098:
case kMarsMaze101:
case kMarsMaze100:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 * 3 / 4);
break;
case kMarsMaze090:
case kMarsMaze099:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 / 2);
break;
case kMarsMaze089:
if (GameState.isCurrentDoorOpen())
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 / 2);
break;
case kMarsMaze178:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 / 4);
break;
// Robot at 197
case kMarsMaze191:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100);
break;
case kMarsMaze190:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 * 3 / 4);
break;
case kMarsMaze198:
case kMarsMaze189:
loadLoopSound2("Sounds/Mars/Maze Sparks.22K.AIFF", 0x100 / 2);
break;
default:
loadLoopSound2("");
break;
}
}
}
void Mars::checkContinuePoint(const tRoomID room, const tDirectionConstant direction) {
switch (MakeRoomView(room, direction)) {
case MakeRoomView(kMars02, kSouth):
case MakeRoomView(kMars19, kEast):
case MakeRoomView(kMars22, kNorth):
case MakeRoomView(kMars43, kEast):
case MakeRoomView(kMars51, kEast):
case MakeRoomView(kMars56, kEast):
case MakeRoomView(kMars60, kWest):
case MakeRoomView(kMarsMaze004, kWest):
case MakeRoomView(kMarsMaze009, kWest):
case MakeRoomView(kMarsMaze012, kWest):
case MakeRoomView(kMarsMaze037, kWest):
case MakeRoomView(kMarsMaze047, kNorth):
case MakeRoomView(kMarsMaze052, kWest):
case MakeRoomView(kMarsMaze057, kNorth):
case MakeRoomView(kMarsMaze071, kWest):
case MakeRoomView(kMarsMaze081, kNorth):
case MakeRoomView(kMarsMaze088, kWest):
case MakeRoomView(kMarsMaze093, kWest):
case MakeRoomView(kMarsMaze115, kNorth):
case MakeRoomView(kMarsMaze120, kWest):
case MakeRoomView(kMarsMaze126, kEast):
case MakeRoomView(kMarsMaze133, kNorth):
case MakeRoomView(kMarsMaze144, kNorth):
case MakeRoomView(kMarsMaze156, kEast):
case MakeRoomView(kMarsMaze162, kNorth):
case MakeRoomView(kMarsMaze177, kWest):
case MakeRoomView(kMarsMaze180, kNorth):
case MakeRoomView(kMarsMaze187, kWest):
case MakeRoomView(kMarsMaze199, kWest):
makeContinuePoint();
break;
case MakeRoomView(kMars05, kEast):
case MakeRoomView(kMars06, kEast):
case MakeRoomView(kMars07, kEast):
if (GameState.getMarsSecurityDown())
makeContinuePoint();
break;
case MakeRoomView(kMars46, kSouth):
if (!GameState.getMarsSeenRobotAtReactor())
makeContinuePoint();
break;
case MakeRoomView(kMars46, kWest):
if (GameState.getMarsAvoidedReactorRobot())
makeContinuePoint();
break;
}
}
void Mars::launchMaze007Robot() {
startExtraLongSequence(kMarsMaze007RobotApproach, kMarsMaze007RobotDeath, kExtraCompletedFlag, kFilterAllInput);
scheduleEvent(kMaze007RobotLoopingTime, kMarsMovieScale, kMaze007RobotLoopingEvent);
}
void Mars::launchMaze015Robot() {
startExtraLongSequence(kMarsMaze015SouthRobotApproach, kMarsMaze015SouthRobotDeath, kExtraCompletedFlag, kFilterAllInput);
scheduleEvent(kMaze015RobotLoopingTime, kMarsMovieScale, kMaze015RobotLoopingEvent);
}
void Mars::launchMaze101Robot() {
startExtraLongSequence(kMarsMaze101EastRobotApproach, kMarsMaze101EastRobotDeath, kExtraCompletedFlag, kFilterAllInput);
scheduleEvent(kMaze101RobotLoopingTime, kMarsMovieScale, kMaze101RobotLoopingEvent);
}
void Mars::launchMaze104Robot() {
startExtraLongSequence(kMarsMaze104WestLoop, kMarsMaze104WestDeath, kExtraCompletedFlag, kFilterAllInput);
scheduleEvent(kMaze104RobotLoopingTime, kMarsMovieScale, kMaze104RobotLoopingEvent);
}
void Mars::launchMaze133Robot() {
startExtraLongSequence(kMarsMaze133SouthApproach, kMarsMaze133SouthDeath, kExtraCompletedFlag, kFilterAllInput);
scheduleEvent(kMaze133RobotLoopingTime, kMarsMovieScale, kMaze133RobotLoopingEvent);
}
void Mars::launchMaze136Robot() {
startExtraLongSequence(kMarsMaze136NorthApproach, kMarsMaze136NorthDeath, kExtraCompletedFlag, kFilterAllInput);
scheduleEvent(kMaze136RobotLoopingTime, kMarsMovieScale, kMaze136RobotLoopingEvent);
}
void Mars::launchMaze184Robot() {
startExtraLongSequence(kMarsMaze184WestLoop, kMarsMaze184WestDeath, kExtraCompletedFlag, kFilterAllInput);
scheduleEvent(kMaze184RobotLoopingTime, kMarsMovieScale, kMaze184RobotLoopingEvent);
}
void Mars::timerExpired(const uint32 eventType) {
switch (eventType) {
case kMaze007RobotLoopingEvent:
case kMaze015RobotLoopingEvent:
case kMaze101RobotLoopingEvent:
case kMaze104RobotLoopingEvent:
case kMaze133RobotLoopingEvent:
case kMaze136RobotLoopingEvent:
case kMaze184RobotLoopingEvent:
_interruptionFilter = kFilterNoInput;
break;
}
}
void Mars::arriveAt(const tRoomID room, const tDirectionConstant direction) {
switch (MakeRoomView(room, direction)) {
case MakeRoomView(kMars18, kNorth):
if (GameState.getMarsPodAtUpperPlatform())
setCurrentAlternate(kAltMarsPodAtMars34);
break;
case MakeRoomView(kMars27, kEast):
case MakeRoomView(kMars29, kEast):
if (GameState.isTakenItemID(kMarsCard))
setCurrentAlternate(kAltMarsTookCard);
else
setCurrentAlternate(kAltMarsNormal);
break;
case MakeRoomView(kMars35, kEast):
case MakeRoomView(kMars35, kWest):
if (GameState.getMarsAirlockOpen())
setCurrentAlternate(kAltMars35AirlockWest);
else
setCurrentAlternate(kAltMars35AirlockEast);
break;
case MakeRoomView(kMars60, kEast):
case MakeRoomView(kMars60, kWest):
if (GameState.getMarsAirlockOpen())
setCurrentAlternate(kAltMars60AirlockEast);
else
setCurrentAlternate(kAltMars60AirlockWest);
break;
case MakeRoomView(kMars45, kNorth):
case MakeRoomView(kMars45, kSouth):
case MakeRoomView(kMars45, kEast):
case MakeRoomView(kMars45, kWest):
GameState.setMarsPodAtUpperPlatform(false);
setCurrentAlternate(kAltMarsPodAtMars45);
break;
case MakeRoomView(kMars46, kNorth):
case MakeRoomView(kMars46, kSouth):
case MakeRoomView(kMars46, kEast):
case MakeRoomView(kMars46, kWest):
case MakeRoomView(kMars47, kNorth):
case MakeRoomView(kMars47, kSouth):
case MakeRoomView(kMars47, kEast):
case MakeRoomView(kMars47, kWest):
if (GameState.getMarsPodAtUpperPlatform())
setCurrentAlternate(kAltMarsNormal);
else
setCurrentAlternate(kAltMarsPodAtMars45);
break;
case MakeRoomView(kMars48, kNorth):
case MakeRoomView(kMars48, kSouth):
case MakeRoomView(kMars48, kEast):
case MakeRoomView(kMars48, kWest):
case MakeRoomView(kMars49, kNorth):
case MakeRoomView(kMars49, kEast):
case MakeRoomView(kMars49, kWest):
if (GameState.isTakenItemID(kAirMask))
setCurrentAlternate(kAltMarsTookMask);
else
setCurrentAlternate(kAltMarsNormal);
break;
case MakeRoomView(kMars49, kSouth):
if (GameState.getMarsMaskOnFiller())
setCurrentAlternate(kAltMarsMaskOnFiller);
else if (GameState.isTakenItemID(kAirMask))
setCurrentAlternate(kAltMarsTookMask);
else
setCurrentAlternate(kAltMarsNormal);
break;
}
Neighborhood::arriveAt(room, direction);
checkAirlockDoors();
setUpReactorEnergyDrain();
switch (MakeRoomView(room, direction)) {
case MakeRoomView(kMars0A, kNorth):
if (!GameState.getMarsSeenTimeStream())
startExtraLongSequence(kMarsArrivalFromTSA, kMars0AWatchShuttleDepart, kExtraCompletedFlag, kFilterNoInput);
break;
case MakeRoomView(kMars07, kSouth):
case MakeRoomView(kMars13, kNorth):
if (!GameState.getMarsHeardCheckInMessage()) {
playSpotSoundSync(kMarsCheckInRequiredIn, kMarsCheckInRequiredOut);
GameState.setMarsHeardCheckInMessage(true);
}
break;
case MakeRoomView(kMars44, kWest):
if (GameState.getMarsReadyForShuttleTransport())
startUpFromFinishedSpaceChase();
else if (GameState.getMarsFinishedCanyonChase())
startUpFromSpaceChase();
else
_neighborhoodNotification.setNotificationFlags(kTimeForCanyonChaseFlag, kTimeForCanyonChaseFlag);
break;
case MakeRoomView(kMars10, kNorth):
if (!GameState.getMarsRobotThrownPlayer())
startExtraSequence(kRobotThrowsPlayer, kExtraCompletedFlag, kFilterNoInput);
break;
case MakeRoomView(kMars11, kSouth):
case MakeRoomView(kMars12, kSouth):
setCurrentActivation(kActivationReadyForKiosk);
break;
case MakeRoomView(kMars15, kWest):
if (GameState.getMarsThreadedMaze() && !GameState.getMarsSecurityDown()) {
playSpotSoundSync(kMarsShuttle2DepartedIn, kMarsShuttle2DepartedOut);
restoreStriding(kMars17, kWest, kAltMarsNormal);
GameState.setMarsSecurityDown(true);
}
break;
case MakeRoomView(kMars17, kNorth):
case MakeRoomView(kMars17, kSouth):
case MakeRoomView(kMars17, kEast):
case MakeRoomView(kMars17, kWest):
if (GameState.getMarsThreadedMaze() && !GameState.getMarsSecurityDown())
forceStridingStop(kMars17, kWest, kAltMarsNormal);
if (GameState.getMarsThreadedMaze() && !GameState.getMarsSawRobotLeave()) {
startExtraSequence(kRobotOnWayToShuttle, kExtraCompletedFlag, kFilterNoInput);
restoreStriding(kMars19, kWest, kAltMarsNormal);
GameState.setMarsSawRobotLeave(true);
}
break;
case MakeRoomView(kMars19, kNorth):
case MakeRoomView(kMars19, kSouth):
case MakeRoomView(kMars19, kWest):
if (GameState.getMarsThreadedMaze() && !GameState.getMarsSawRobotLeave())
forceStridingStop(kMars19, kWest, kAltMarsNormal);
if (GameState.getMarsThreadedMaze() && !GameState.getMarsSecurityDown())
forceStridingStop(kMars17, kWest, kAltMarsNormal);
break;
case MakeRoomView(kMars19, kEast):
if (GameState.getMarsThreadedMaze() && !GameState.getMarsSawRobotLeave())
forceStridingStop(kMars19, kWest, kAltMarsNormal);
if (GameState.getMarsThreadedMaze() && !GameState.getMarsSecurityDown())
forceStridingStop(kMars17, kWest, kAltMarsNormal);
break;
case MakeRoomView(kMars32, kNorth):
if (!GameState.getMarsPodAtUpperPlatform()) {
playSpotSoundSync(kMarsPodArrivedUpperPlatformIn, kMarsPodArrivedUpperPlatformOut);
GameState.setMarsPodAtUpperPlatform(true);
}
break;
case MakeRoomView(kMars33North, kNorth):
setCurrentActivation(kActivationTunnelMapReady);
// Fall through...
case MakeRoomView(kMars33, kSouth):
case MakeRoomView(kMars33, kEast):
case MakeRoomView(kMars33, kWest):
case MakeRoomView(kMars32, kSouth):
case MakeRoomView(kMars32, kEast):
case MakeRoomView(kMars32, kWest):
if (!GameState.getMarsPodAtUpperPlatform())
GameState.setMarsPodAtUpperPlatform(true);
break;
case MakeRoomView(kMars34, kNorth):
startExtraSequence(kMars34NorthPodGreeting, kExtraCompletedFlag, kFilterNoInput);
break;
case MakeRoomView(kMars34, kSouth):
case MakeRoomView(kMars45, kNorth):
setCurrentActivation(kActivateMarsPodClosed);
break;
case MakeRoomView(kMars35, kWest):
if (GameState.getMarsThreadedMaze() && !GameState.getMarsSecurityDown())
forceStridingStop(kMars19, kWest, kAltMarsNormal);
// Fall through...
case MakeRoomView(kMars60, kEast):
if (!GameState.getMarsAirlockOpen())
setCurrentActivation(kActivateReadyToPressurizeAirlock);
break;
case MakeRoomView(kMars35, kEast):
case MakeRoomView(kMars60, kWest):
if (GameState.getMarsAirlockOpen())
setCurrentActivation(kActivateReadyToPressurizeAirlock);
break;
case MakeRoomView(kMars39, kWest):
if (GameState.getLastRoom() == kMarsMaze200)
GameState.setMarsPodAtUpperPlatform(false);
break;
case MakeRoomView(kMars45, kSouth):
// Set up maze doors here.
// Doing it here makes sure that it will be the same if the player comes
// back out of the maze and goes back in, but will vary if
// the player comes back down to the maze a second time.
GameState.setMarsMazeDoorPair1(_vm->getRandomBit());
GameState.setMarsMazeDoorPair2(_vm->getRandomBit());
GameState.setMarsMazeDoorPair3(_vm->getRandomBit());
GameState.setMarsArrivedBelow(true);
break;
case MakeRoomView(kMars48, kEast):
if (!GameState.getMarsSeenRobotAtReactor()) {
// Preload the looping sound...
loadLoopSound2("Sounds/Mars/Robot Loop.aiff", 0, 0, 0);
startExtraSequence(kMars48RobotApproaches, kExtraCompletedFlag, kFilterNoInput);
} else if (!GameState.getMarsAvoidedReactorRobot()) {
loadLoopSound2("Sounds/Mars/Robot Loop.aiff", 0x100, 0, 0);
loopExtraSequence(kMars48RobotLoops);
_utilityFuse.primeFuse(kMarsRobotPatienceLimit);
_utilityFuse.setFunctionPtr(&robotTimerExpiredFunction, (void *)this);
_utilityFuse.lightFuse();
}
break;
case MakeRoomView(kMars48, kSouth):
if (GameState.getMarsSeenRobotAtReactor() && !GameState.getMarsAvoidedReactorRobot()) {
loadLoopSound2("Sounds/Mars/Robot Loop.aiff", 0x100, 0, 0);
_utilityFuse.primeFuse(kMarsRobotPatienceLimit);
_utilityFuse.setFunctionPtr(&robotTimerExpiredFunction, (void *)this);
_utilityFuse.lightFuse();
}
break;
case MakeRoomView(kMars49, kSouth):
if (GameState.getMarsSeenRobotAtReactor() && !GameState.getMarsAvoidedReactorRobot()) {
playSpotSoundSync(kMarsRobotTakesTransportIn, kMarsRobotTakesTransportOut);
playSpotSoundSync(kMarsPodDepartedLowerPlatformIn, kMarsPodDepartedLowerPlatformOut);
GameState.setMarsAvoidedReactorRobot(true);
GameState.setMarsPodAtUpperPlatform(true);
GameState.getScoringAvoidedRobot();
}
if (GameState.isTakenItemID(kAirMask))
setCurrentActivation(kActivateHotSpotAlways);
else if (GameState.getMarsMaskOnFiller())
setCurrentActivation(kActivateMaskOnFiller);
else
setCurrentActivation(kActivateMaskOnHolder);
break;
case MakeRoomView(kMars51, kWest):
case MakeRoomView(kMars50, kWest):
case MakeRoomView(kMars48, kWest):
if (GameState.getShieldOn())
g_shield->setItemState(kShieldNormal);
g_energyMonitor->setEnergyDrainRate(kEnergyDrainNormal);
_vm->resetEnergyDeathReason();
break;
case MakeRoomView(kMars52, kNorth):
case MakeRoomView(kMars52, kSouth):
case MakeRoomView(kMars52, kEast):
case MakeRoomView(kMars52, kWest):
case MakeRoomView(kMars54, kNorth):
case MakeRoomView(kMars54, kSouth):
case MakeRoomView(kMars54, kEast):
case MakeRoomView(kMars54, kWest):
case MakeRoomView(kMars56, kNorth):
case MakeRoomView(kMars56, kSouth):
case MakeRoomView(kMars56, kWest):
case MakeRoomView(kMars58, kNorth):
case MakeRoomView(kMars58, kSouth):
case MakeRoomView(kMars58, kEast):
case MakeRoomView(kMars58, kWest):
setCurrentActivation(kActivateReactorPlatformOut);
break;
case MakeRoomView(kMars56, kEast):
if (GameState.getMarsLockBroken()) {
setCurrentActivation(kActivateReactorAskOperation);
_privateFlags.setFlag(kMarsPrivatePlatformZoomedInFlag, true);
} else if (GameState.getMarsLockFrozen()) {
setCurrentActivation(kActivateReactorReadyForCrowBar);
_privateFlags.setFlag(kMarsPrivatePlatformZoomedInFlag, true);
_utilityFuse.primeFuse(kLockFreezeTimeLmit);
_utilityFuse.setFunctionPtr(&lockThawTimerExpiredFunction, (void *)this);
_utilityFuse.lightFuse();
} else {
setCurrentActivation(kActivateReactorPlatformOut);
}
break;
case MakeRoomView(kMarsRobotShuttle, kEast):
setCurrentActivation(kActivationRobotHeadClosed);
break;
case MakeRoomView(kMarsMaze007, kNorth):
launchMaze007Robot();
break;
case MakeRoomView(kMarsMaze015, kSouth):
launchMaze015Robot();
break;
case MakeRoomView(kMarsMaze101, kEast):
launchMaze101Robot();
break;
case MakeRoomView(kMarsMaze104, kWest):
launchMaze104Robot();
break;
case MakeRoomView(kMarsMaze133, kSouth):
launchMaze133Robot();
break;
case MakeRoomView(kMarsMaze136, kNorth):
launchMaze136Robot();
break;
case MakeRoomView(kMarsMaze184, kWest):
launchMaze184Robot();
break;
case MakeRoomView(kMarsMaze199, kSouth):
GameState.setScoringThreadedMaze();
GameState.setMarsThreadedMaze(true);
break;
case MakeRoomView(kMarsDeathRoom, kNorth):
case MakeRoomView(kMarsDeathRoom, kSouth):
case MakeRoomView(kMarsDeathRoom, kEast):
case MakeRoomView(kMarsDeathRoom, kWest):
switch (GameState.getLastRoom()) {
case kMars39:
die(kDeathDidntLeaveBucket);
break;
case kMars46:
die(kDeathRunOverByPod);
break;
}
break;
}
checkAirMask();
}
void Mars::shieldOn() {
setUpReactorEnergyDrain();
}
void Mars::shieldOff() {
setUpReactorEnergyDrain();
}
void Mars::turnTo(const tDirectionConstant direction) {
switch (MakeRoomView(GameState.getCurrentRoom(), direction)) {
case MakeRoomView(kMars27, kNorth):
case MakeRoomView(kMars27, kSouth):
case MakeRoomView(kMars27, kEast):
case MakeRoomView(kMars29, kNorth):
case MakeRoomView(kMars29, kSouth):
case MakeRoomView(kMars29, kEast):
if (GameState.isTakenItemID(kMarsCard))
setCurrentAlternate(kAltMarsTookCard);
break;
case MakeRoomView(kMars35, kNorth):
case MakeRoomView(kMars35, kSouth):
case MakeRoomView(kMars60, kNorth):
case MakeRoomView(kMars60, kSouth):
if (getCurrentActivation() == kActivateAirlockPressurized)
playSpotSoundSync(kMarsAirlockPressurizeIn, kMarsAirlockPressurizeOut);
break;
}
Neighborhood::turnTo(direction);
switch (MakeRoomView(GameState.getCurrentRoom(), direction)) {
case MakeRoomView(kMars11, kSouth):
case MakeRoomView(kMars12, kSouth):
setCurrentActivation(kActivationReadyForKiosk);
break;
case MakeRoomView(kMars18, kNorth):
if (GameState.getMarsPodAtUpperPlatform())
setCurrentAlternate(kAltMarsPodAtMars34);
break;
case MakeRoomView(kMars22, kSouth):
if (!GameState.getMarsHeardCheckInMessage()) {
playSpotSoundSync(kMarsCheckInRequiredIn, kMarsCheckInRequiredOut);
GameState.setMarsHeardCheckInMessage(true);
}
break;
case MakeRoomView(kMars34, kSouth):
case MakeRoomView(kMars45, kNorth):
setCurrentActivation(kActivateMarsPodClosed);
break;
case MakeRoomView(kMars34, kNorth):
startExtraSequence(kMars34NorthPodGreeting, kExtraCompletedFlag, kFilterNoInput);
break;
case MakeRoomView(kMars35, kEast):
case MakeRoomView(kMars60, kWest):
if (GameState.getMarsAirlockOpen())
setCurrentActivation(kActivateReadyToPressurizeAirlock);
break;
case MakeRoomView(kMars60, kEast):
if (!GameState.getMarsAirlockOpen())
setCurrentActivation(kActivateReadyToPressurizeAirlock);
break;
case MakeRoomView(kMars35, kWest):
if (!GameState.getMarsAirlockOpen())
setCurrentActivation(kActivateReadyToPressurizeAirlock);
// Do this here because this will be called after spinning the airlock after
// going through the gear room.
if (GameState.getMarsThreadedMaze())
GameState.setScoringThreadedGearRoom();
break;
case MakeRoomView(kMars48, kNorth):
if (GameState.getMarsSeenRobotAtReactor() && !GameState.getMarsAvoidedReactorRobot())
die(kDeathDidntGetOutOfWay);
break;
case MakeRoomView(kMars48, kEast):
if (!GameState.getMarsSeenRobotAtReactor()) {
// Preload the looping sound...
loadLoopSound2("Sounds/Mars/Robot Loop.aiff", 0, 0, 0);
startExtraSequence(kMars48RobotApproaches, kExtraCompletedFlag, kFilterNoInput);
} else if (!GameState.getMarsAvoidedReactorRobot()) {
loopExtraSequence(kMars48RobotLoops);
} else if (GameState.isTakenItemID(kAirMask)) {
setCurrentAlternate(kAltMarsTookMask);
} else {
setCurrentAlternate(kAltMarsNormal);
}
break;
case MakeRoomView(kMars48, kWest):
if (GameState.getMarsSeenRobotAtReactor() && !GameState.getMarsAvoidedReactorRobot())
die(kDeathDidntGetOutOfWay);
else if (GameState.isTakenItemID(kAirMask))
setCurrentAlternate(kAltMarsTookMask);
else
setCurrentAlternate(kAltMarsNormal);
break;
case MakeRoomView(kMars49, kSouth):
if (GameState.isTakenItemID(kAirMask))
setCurrentActivation(kActivateHotSpotAlways);
else
setCurrentActivation(kActivateMaskOnHolder);
break;
case MakeRoomView(kMars52, kNorth):
case MakeRoomView(kMars52, kSouth):
case MakeRoomView(kMars52, kEast):
case MakeRoomView(kMars52, kWest):
case MakeRoomView(kMars54, kNorth):
case MakeRoomView(kMars54, kSouth):
case MakeRoomView(kMars54, kEast):
case MakeRoomView(kMars54, kWest):
case MakeRoomView(kMars56, kNorth):
case MakeRoomView(kMars56, kSouth):
case MakeRoomView(kMars56, kEast):
case MakeRoomView(kMars56, kWest):
case MakeRoomView(kMars58, kNorth):
case MakeRoomView(kMars58, kSouth):
case MakeRoomView(kMars58, kEast):
case MakeRoomView(kMars58, kWest):
setCurrentActivation(kActivateReactorPlatformOut);
break;
case MakeRoomView(kMarsMaze007, kNorth):
launchMaze007Robot();
break;
case MakeRoomView(kMarsMaze015, kSouth):
launchMaze015Robot();
break;
case MakeRoomView(kMarsMaze101, kEast):
launchMaze101Robot();
break;
case MakeRoomView(kMarsMaze104, kWest):
launchMaze104Robot();
break;
case MakeRoomView(kMarsMaze133, kSouth):
launchMaze133Robot();
break;
case MakeRoomView(kMarsMaze136, kNorth):
launchMaze136Robot();
break;
case MakeRoomView(kMarsMaze184, kWest):
launchMaze184Robot();
break;
}
}
void Mars::activateOneHotspot(HotspotInfoTable::Entry &entry, Hotspot *hotspot) {
switch (hotspot->getObjectID()) {
case kMars57RedMoveSpotID:
case kMars57YellowMoveSpotID:
case kMars57GreenMoveSpotID:
if (!_choiceHighlight.choiceHighlighted(hotspot->getObjectID() - kMars57RedMoveSpotID))
hotspot->setActive();
break;
case kMars57BlueMoveSpotID:
if (_reactorStage >= 2 && !_choiceHighlight.choiceHighlighted(3))
hotspot->setActive();
break;
case kMars57PurpleMoveSpotID:
if (_reactorStage == 3 && !_choiceHighlight.choiceHighlighted(4))
hotspot->setActive();
break;
default:
Neighborhood::activateOneHotspot(entry, hotspot);
break;
}
}
void Mars::activateHotspots() {
InventoryItem *item;
Neighborhood::activateHotspots();
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars48, kEast):
if ((_navMovie.getFlags() & kLoopTimeBase) != 0 && _vm->getDragType() == kDragInventoryUse)
g_allHotspots.activateOneHotspot(kAttackRobotHotSpotID);
break;
case MakeRoomView(kMars56, kEast):
switch (getCurrentActivation()) {
case kActivateReactorReadyForNitrogen:
item = (InventoryItem *)g_allItems.findItemByID(kNitrogenCanister);
if (item->getItemState() != kNitrogenFull)
g_allHotspots.deactivateOneHotspot(kMars57DropNitrogenSpotID);
// Fall through...
case kActivateReactorReadyForCrowBar:
g_allHotspots.activateOneHotspot(kMars57CantOpenPanelSpotID);
break;
}
break;
case MakeRoomView(kMarsRobotShuttle, kEast):
if (_privateFlags.getFlag(kMarsPrivateGotMapChipFlag))
g_allHotspots.deactivateOneHotspot(kRobotShuttleMapChipSpotID);
else
g_allHotspots.activateOneHotspot(kRobotShuttleMapChipSpotID);
if (_privateFlags.getFlag(kMarsPrivateGotOpticalChipFlag))
g_allHotspots.deactivateOneHotspot(kRobotShuttleOpticalChipSpotID);
else
g_allHotspots.activateOneHotspot(kRobotShuttleOpticalChipSpotID);
if (_privateFlags.getFlag(kMarsPrivateGotShieldChipFlag))
g_allHotspots.deactivateOneHotspot(kRobotShuttleShieldChipSpotID);
else
g_allHotspots.activateOneHotspot(kRobotShuttleShieldChipSpotID);
break;
default:
if (_privateFlags.getFlag(kMarsPrivateInSpaceChaseFlag)) {
if (GameState.getMarsReadyForShuttleTransport()) {
_shuttleTransportSpot.setActive();
} else {
_energyChoiceSpot.setActive();
_gravitonChoiceSpot.setActive();
_tractorChoiceSpot.setActive();
if (_weaponSelection != kNoWeapon)
_shuttleViewSpot.setActive();
}
}
break;
}
}
void Mars::clickInHotspot(const Input &input, const Hotspot *clickedSpot) {
switch (clickedSpot->getObjectID()) {
case kMars11NorthKioskSpotID:
case kMars12NorthKioskSpotID:
playSpotSoundSync(kMarsKioskBeepIn, kMarsKioskBeepOut);
Neighborhood::clickInHotspot(input, clickedSpot);
break;
case kMars11NorthKioskSightsSpotID:
case kMars12NorthKioskSightsSpotID:
playSpotSoundSync(kMarsKioskBeepIn, kMarsKioskBeepOut);
if (!startExtraSequenceSync(kMarsSightsInfo, kFilterAllInput))
showExtraView(kMarsInfoKioskIntro);
break;
case kMars11NorthKioskColonySpotID:
case kMars12NorthKioskColonySpotID:
playSpotSoundSync(kMarsKioskBeepIn, kMarsKioskBeepOut);
if (!startExtraSequenceSync(kMarsColonyInfo, kFilterAllInput))
showExtraView(kMarsInfoKioskIntro);
break;
case kMars33NorthMonitorSpotID:
switch (_lastExtra) {
case kMars33SlideShow1:
startExtraSequence(kMars33SlideShow2, kExtraCompletedFlag, kFilterNoInput);
break;
case kMars33SlideShow2:
startExtraSequence(kMars33SlideShow3, kExtraCompletedFlag, kFilterNoInput);
break;
case kMars33SlideShow3:
startExtraSequence(kMars33SlideShow4, kExtraCompletedFlag, kFilterNoInput);
break;
case kMars33SlideShow4:
// Should never happen...
default:
startExtraSequence(kMars33SlideShow1, kExtraCompletedFlag, kFilterNoInput);
break;
}
break;
case kMars34SouthOpenStorageSpotID:
if (GameState.isTakenItemID(kCrowbar))
startExtraSequence(kMars34SpotOpenNoBar, kExtraCompletedFlag, kFilterNoInput);
else
startExtraSequence(kMars34SpotOpenWithBar, kExtraCompletedFlag, kFilterNoInput);
break;
case kMars34SouthCloseStorageSpotID:
if (GameState.isTakenItemID(kCrowbar))
startExtraSequence(kMars34SpotCloseNoBar, kExtraCompletedFlag, kFilterNoInput);
else
startExtraSequence(kMars34SpotCloseWithBar, kExtraCompletedFlag, kFilterNoInput);
break;
case kMars35WestPressurizeSpotID:
case kMars35EastPressurizeSpotID:
case kMars60WestPressurizeSpotID:
case kMars60EastPressurizeSpotID:
playSpotSoundSync(kMarsAirlockButtonBeepIn, kMarsAirlockButtonBeepOut);
playSpotSoundSync(kMarsAirlockPressurizeIn, kMarsAirlockPressurizeOut);
setCurrentActivation(kActivateAirlockPressurized);
break;
case kMars45NorthOpenStorageSpotID:
if (GameState.isTakenItemID(kCrowbar))
startExtraSequence(kMars45SpotOpenNoBar, kExtraCompletedFlag, kFilterNoInput);
else
startExtraSequence(kMars45SpotOpenWithBar, kExtraCompletedFlag, kFilterNoInput);
break;
case kMars45NorthCloseStorageSpotID:
if (GameState.isTakenItemID(kCrowbar))
startExtraSequence(kMars45SpotCloseNoBar, kExtraCompletedFlag, kFilterNoInput);
else
startExtraSequence(kMars45SpotCloseWithBar, kExtraCompletedFlag, kFilterNoInput);
break;
case kMars56ExtractSpotID:
if (GameState.isTakenItemID(kCardBomb)) {
startExtraSequence(kMars56ExtendNoBomb, kExtraCompletedFlag, kFilterNoInput);
setCurrentActivation(kActivateReactorPlatformIn);
} else {
startExtraSequence(kMars56ExtendWithBomb, kExtraCompletedFlag, kFilterNoInput);
setCurrentActivation(kActivateReactorAskLowerScreen);
}
break;
case kMars57UndoMoveSpotID:
playSpotSoundSync(kMarsColorMatchingButtonBeepIn, kMarsColorMatchingButtonBeepOut);
doUndoOneGuess();
break;
case kMars57RedMoveSpotID:
playSpotSoundSync(kMarsColorMatchingButtonBeepIn, kMarsColorMatchingButtonBeepOut);
doReactorGuess(0);
break;
case kMars57YellowMoveSpotID:
playSpotSoundSync(kMarsColorMatchingButtonBeepIn, kMarsColorMatchingButtonBeepOut);
doReactorGuess(1);
break;
case kMars57GreenMoveSpotID:
playSpotSoundSync(kMarsColorMatchingButtonBeepIn, kMarsColorMatchingButtonBeepOut);
doReactorGuess(2);
break;
case kMars57BlueMoveSpotID:
playSpotSoundSync(kMarsColorMatchingButtonBeepIn, kMarsColorMatchingButtonBeepOut);
doReactorGuess(3);
break;
case kMars57PurpleMoveSpotID:
playSpotSoundSync(kMarsColorMatchingButtonBeepIn, kMarsColorMatchingButtonBeepOut);
doReactorGuess(4);
break;
case kShuttleEnergySpotID:
case kShuttleGravitonSpotID:
case kShuttleTractorSpotID:
case kShuttleViewSpotID:
case kShuttleTransportSpotID:
spaceChaseClick(input, clickedSpot->getObjectID());
break;
default:
Neighborhood::clickInHotspot(input, clickedSpot);
break;
}
}
tInputBits Mars::getInputFilter() {
tInputBits result = Neighborhood::getInputFilter();
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars49, kSouth):
if (GameState.getMarsMaskOnFiller())
// Can't move when mask is on filler.
result &= ~kFilterAllDirections;
break;
case MakeRoomView(kMars52, kNorth):
case MakeRoomView(kMars52, kSouth):
case MakeRoomView(kMars52, kEast):
case MakeRoomView(kMars52, kWest):
case MakeRoomView(kMars54, kNorth):
case MakeRoomView(kMars54, kSouth):
case MakeRoomView(kMars54, kEast):
case MakeRoomView(kMars54, kWest):
case MakeRoomView(kMars56, kNorth):
case MakeRoomView(kMars56, kSouth):
case MakeRoomView(kMars56, kEast):
case MakeRoomView(kMars56, kWest):
case MakeRoomView(kMars58, kNorth):
case MakeRoomView(kMars58, kSouth):
case MakeRoomView(kMars58, kEast):
case MakeRoomView(kMars58, kWest):
if (_privateFlags.getFlag(kMarsPrivatePlatformZoomedInFlag))
// Can't move when platform is extended.
result &= ~kFilterAllDirections;
break;
case MakeRoomView(kMars44, kWest):
if (_canyonChaseMovie.isMovieValid() && _canyonChaseMovie.isRunning())
result &= ~kFilterAllDirections;
break;
}
return result;
}
// Only called when trying to pick up an item and the player can't (because
// the inventory is too full or because the player lets go of the item before
// dropping it into the inventory).
Hotspot *Mars::getItemScreenSpot(Item *item, DisplayElement *element) {
tHotSpotID destSpotID;
switch (item->getObjectID()) {
case kCardBomb:
destSpotID = kMars57GrabBombSpotID;
break;
case kMarsCard:
destSpotID = kMars31SouthCardSpotID;
break;
case kAirMask:
if (GameState.getMarsMaskOnFiller())
destSpotID = kMars49AirFillingDropSpotID;
else
destSpotID = kMars49AirMaskSpotID;
break;
case kCrowbar:
if (GameState.getCurrentRoom() == kMars34)
destSpotID = kMars34SouthCrowbarSpotID;
else
destSpotID = kMars45NorthCrowbarSpotID;
break;
case kMapBiochip:
destSpotID = kRobotShuttleMapChipSpotID;
break;
case kOpticalBiochip:
destSpotID = kRobotShuttleOpticalChipSpotID;
break;
case kShieldBiochip:
destSpotID = kRobotShuttleShieldChipSpotID;
break;
default:
destSpotID = kNoHotSpotID;
break;
}
if (destSpotID == kNoHotSpotID)
return Neighborhood::getItemScreenSpot(item, element);
return g_allHotspots.findHotspotByID(destSpotID);
}
void Mars::takeItemFromRoom(Item *item) {
switch (item->getObjectID()) {
case kAirMask:
setCurrentAlternate(kAltMarsTookMask);
break;
case kCardBomb:
_privateFlags.setFlag(kMarsPrivateDraggingBombFlag, true);
break;
case kMapBiochip:
_privateFlags.setFlag(kMarsPrivateGotMapChipFlag, true);
break;
case kShieldBiochip:
_privateFlags.setFlag(kMarsPrivateGotShieldChipFlag, true);
break;
case kOpticalBiochip:
_privateFlags.setFlag(kMarsPrivateGotOpticalChipFlag, true);
break;
}
Neighborhood::takeItemFromRoom(item);
}
void Mars::pickedUpItem(Item *item) {
switch (item->getObjectID()) {
case kAirMask:
setCurrentActivation(kActivateHotSpotAlways);
if (!GameState.getScoringGotOxygenMask()) {
g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Mars/XM48SB", false, kWarningInterruption);
GameState.setScoringGotOxygenMask();
}
break;
case kCrowbar:
GameState.setScoringGotCrowBar();
g_AIArea->checkMiddleArea();
break;
case kMarsCard:
GameState.setScoringGotMarsCard();
g_AIArea->checkMiddleArea();
break;
case kCardBomb:
GameState.setScoringGotCardBomb();
if (GameState.getMarsLockBroken()) {
startExtraSequence(kMars57BackToNormal, kExtraCompletedFlag, kFilterNoInput);
GameState.setMarsLockBroken(false);
}
_privateFlags.setFlag(kMarsPrivateDraggingBombFlag, false);
break;
case kMapBiochip:
if (_privateFlags.getFlag(kMarsPrivateGotMapChipFlag) &&
_privateFlags.getFlag(kMarsPrivateGotShieldChipFlag) &&
_privateFlags.getFlag(kMarsPrivateGotOpticalChipFlag)) {
GameState.setMarsFinished(true);
GameState.setScoringMarsGandhi();
startExtraSequence(kMarsRobotHeadClose, kExtraCompletedFlag, kFilterNoInput);
}
break;
case kShieldBiochip:
if (_privateFlags.getFlag(kMarsPrivateGotMapChipFlag) &&
_privateFlags.getFlag(kMarsPrivateGotShieldChipFlag) &&
_privateFlags.getFlag(kMarsPrivateGotOpticalChipFlag)) {
GameState.setMarsFinished(true);
GameState.setScoringMarsGandhi();
startExtraSequence(kMarsRobotHeadClose, kExtraCompletedFlag, kFilterNoInput);
}
break;
case kOpticalBiochip:
g_opticalChip->addAries();
GameState.setScoringGotMarsOpMemChip();
if (_privateFlags.getFlag(kMarsPrivateGotMapChipFlag) &&
_privateFlags.getFlag(kMarsPrivateGotShieldChipFlag) &&
_privateFlags.getFlag(kMarsPrivateGotOpticalChipFlag)) {
GameState.setMarsFinished(true);
GameState.setScoringMarsGandhi();
startExtraSequence(kMarsRobotHeadClose, kExtraCompletedFlag, kFilterNoInput);
}
break;
}
}
void Mars::dropItemIntoRoom(Item *item, Hotspot *dropSpot) {
if (dropSpot->getObjectID() == kAttackRobotHotSpotID) {
_attackingItem = (InventoryItem *)item;
startExtraSequence(kMars48RobotDefends, kExtraCompletedFlag, kFilterNoInput);
loadLoopSound2("");
} else {
switch (item->getObjectID()) {
case kMarsCard:
Neighborhood::dropItemIntoRoom(item, dropSpot);
if (dropSpot && dropSpot->getObjectID() == kMars34NorthCardDropSpotID)
startExtraSequence(kMarsTurnOnPod, kExtraCompletedFlag, kFilterNoInput);
break;
case kNitrogenCanister:
Neighborhood::dropItemIntoRoom(item, dropSpot);
if (dropSpot && dropSpot->getObjectID() == kMars57DropNitrogenSpotID)
startExtraSequence(kMars57FreezeLock, kExtraCompletedFlag, kFilterNoInput);
break;
case kCrowbar:
_utilityFuse.stopFuse();
Neighborhood::dropItemIntoRoom(item, dropSpot);
if (dropSpot && dropSpot->getObjectID() == kMars57DropCrowBarSpotID)
startExtraSequence(kMars57BreakLock, kExtraCompletedFlag, kFilterNoInput);
break;
case kAirMask:
if (dropSpot) {
if (dropSpot->getObjectID() == kMars49AirFillingDropSpotID) {
if (!GameState.getMarsMaskOnFiller()) {
Neighborhood::dropItemIntoRoom(item, dropSpot);
startExtraSequence(kMars49SouthViewMaskFilling, kExtraCompletedFlag, kFilterNoInput);
} else {
setCurrentActivation(kActivateMaskOnFiller);
setCurrentAlternate(kAltMarsMaskOnFiller);
Neighborhood::dropItemIntoRoom(item, dropSpot);
}
} else if (dropSpot->getObjectID() == kMars49AirMaskSpotID) {
setCurrentAlternate(kAltMarsNormal);
setCurrentActivation(kActivateMaskOnHolder);
Neighborhood::dropItemIntoRoom(item, dropSpot);
}
}
break;
case kCardBomb:
_privateFlags.setFlag(kMarsPrivateDraggingBombFlag, false);
Neighborhood::dropItemIntoRoom(item, dropSpot);
break;
case kMapBiochip:
_privateFlags.setFlag(kMarsPrivateGotMapChipFlag, false);
Neighborhood::dropItemIntoRoom(item, dropSpot);
break;
case kShieldBiochip:
_privateFlags.setFlag(kMarsPrivateGotShieldChipFlag, false);
Neighborhood::dropItemIntoRoom(item, dropSpot);
break;
case kOpticalBiochip:
_privateFlags.setFlag(kMarsPrivateGotOpticalChipFlag, false);
Neighborhood::dropItemIntoRoom(item, dropSpot);
break;
default:
Neighborhood::dropItemIntoRoom(item, dropSpot);
break;
}
}
}
void Mars::robotTiredOfWaiting() {
if (GameState.getCurrentRoomAndView() == MakeRoomView(kMars48, kEast)) {
if (_attackingItem) {
startExtraSequence(kMars48RobotKillsPlayer, kExtraCompletedFlag, kFilterNoInput);
loadLoopSound2("");
} else {
_privateFlags.setFlag(kMarsPrivateRobotTiredOfWaitingFlag, true);
}
} else {
die(kDeathDidntGetOutOfWay);
}
}
void Mars::turnLeft() {
if (isEventTimerRunning())
cancelEvent();
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars34, kSouth):
if (_privateFlags.getFlag(kMarsPrivatePodStorageOpenFlag)) {
_privateFlags.setFlag(kMarsPrivatePodTurnLeftFlag, true);
if (GameState.isTakenItemID(kCrowbar))
startExtraSequence(kMars34SpotCloseNoBar, kExtraCompletedFlag, kFilterNoInput);
else
startExtraSequence(kMars34SpotCloseWithBar, kExtraCompletedFlag, kFilterNoInput);
} else {
Neighborhood::turnLeft();
}
break;
case MakeRoomView(kMars45, kNorth):
if (_privateFlags.getFlag(kMarsPrivatePodStorageOpenFlag)) {
_privateFlags.setFlag(kMarsPrivatePodTurnLeftFlag, true);
if (GameState.isTakenItemID(kCrowbar))
startExtraSequence(kMars45SpotCloseNoBar, kExtraCompletedFlag, kFilterNoInput);
else
startExtraSequence(kMars45SpotCloseWithBar, kExtraCompletedFlag, kFilterNoInput);
} else {
Neighborhood::turnLeft();
}
break;
default:
Neighborhood::turnLeft();
break;
}
}
void Mars::turnRight() {
if (isEventTimerRunning())
cancelEvent();
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars34, kSouth):
if (_privateFlags.getFlag(kMarsPrivatePodStorageOpenFlag)) {
_privateFlags.setFlag(kMarsPrivatePodTurnRightFlag, true);
if (GameState.isTakenItemID(kCrowbar))
startExtraSequence(kMars34SpotCloseNoBar, kExtraCompletedFlag, kFilterNoInput);
else
startExtraSequence(kMars34SpotCloseWithBar, kExtraCompletedFlag, kFilterNoInput);
} else {
Neighborhood::turnRight();
}
break;
case MakeRoomView(kMars45, kNorth):
if (_privateFlags.getFlag(kMarsPrivatePodStorageOpenFlag)) {
_privateFlags.setFlag(kMarsPrivatePodTurnRightFlag, true);
if (GameState.isTakenItemID(kCrowbar))
startExtraSequence(kMars45SpotCloseNoBar, kExtraCompletedFlag, kFilterNoInput);
else
startExtraSequence(kMars45SpotCloseWithBar, kExtraCompletedFlag, kFilterNoInput);
} else {
Neighborhood::turnRight();
}
break;
default:
Neighborhood::turnRight();
break;
}
}
void Mars::receiveNotification(Notification *notification, const tNotificationFlags flag) {
InventoryItem *item;
Neighborhood::receiveNotification(notification, flag);
if ((flag & kExtraCompletedFlag) != 0) {
_interruptionFilter = kFilterAllInput;
switch (_lastExtra) {
case kMarsArrivalFromTSA:
GameState.setMarsSeenTimeStream(true);
loadAmbientLoops();
playSpotSoundSync(kMarsShuttle1DepartedIn, kMarsShuttle1DepartedOut);
makeContinuePoint();
break;
case kRobotThrowsPlayer:
GameState.setMarsRobotThrownPlayer(true);
GameState.setScoringThrownByRobot();
restoreStriding(kMars08, kNorth, kAltMarsNormal);
arriveAt(kMars08, kNorth);
if (!GameState.getMarsHeardUpperPodMessage()) {
playSpotSoundSync(kMarsPodDepartedUpperPlatformIn,
kMarsPodDepartedUpperPlatformOut);
GameState.setMarsHeardUpperPodMessage(true);
}
break;
case kMarsInfoKioskIntro:
GameState.setScoringSawMarsKiosk();
setCurrentActivation(kActivationKioskChoice);
break;
case kMars33SlideShow4:
GameState.setScoringSawTransportMap();
setCurrentActivation(kActivateHotSpotAlways);
break;
case kMars34SpotOpenNoBar:
case kMars34SpotOpenWithBar:
case kMars45SpotOpenNoBar:
case kMars45SpotOpenWithBar:
_privateFlags.setFlag(kMarsPrivatePodStorageOpenFlag, true);
setCurrentActivation(kActivateMarsPodOpen);
break;
case kMars34SpotCloseNoBar:
case kMars34SpotCloseWithBar:
case kMars45SpotCloseNoBar:
case kMars45SpotCloseWithBar:
_privateFlags.setFlag(kMarsPrivatePodStorageOpenFlag, false);
setCurrentActivation(kActivateMarsPodClosed);
if (_privateFlags.getFlag(kMarsPrivatePodTurnLeftFlag)) {
_privateFlags.setFlag(kMarsPrivatePodTurnLeftFlag, false);
turnLeft();
} else if (_privateFlags.getFlag(kMarsPrivatePodTurnRightFlag)) {
_privateFlags.setFlag(kMarsPrivatePodTurnRightFlag, false);
turnRight();
}
break;
case kMarsTurnOnPod:
item = (InventoryItem *)g_allItems.findItemByID(kMarsCard);
_vm->addItemToInventory(item);
GameState.setScoringTurnedOnTransport();
loadLoopSound1("");
loadLoopSound2("");
startExtraSequence(kMarsTakePodToMars45, kExtraCompletedFlag, kFilterNoInput);
break;
case kMarsTakePodToMars45:
arriveAt(kMars45, kSouth);
break;
case kMars35WestSpinAirlockToEast:
GameState.setMarsAirlockOpen(false);
setCurrentAlternate(kAltMars35AirlockEast);
turnTo(kWest);
setCurrentActivation(kActivateReadyToPressurizeAirlock);
g_airMask->airQualityChanged();
checkAirMask();
loadAmbientLoops();
break;
case kMars35EastSpinAirlockToWest:
GameState.setMarsAirlockOpen(true);
setCurrentAlternate(kAltMars35AirlockWest);
turnTo(kEast);
setCurrentActivation(kActivateReadyToPressurizeAirlock);
g_airMask->airQualityChanged();
checkAirMask();
loadAmbientLoops();
break;
case kMars48RobotApproaches:
loadLoopSound2("Sounds/Mars/Robot Loop.aiff", 0x100, 0, 0);
GameState.setMarsSeenRobotAtReactor(true);
loopExtraSequence(kMars48RobotLoops);
_utilityFuse.primeFuse(kMarsRobotPatienceLimit);
_utilityFuse.setFunctionPtr(&robotTimerExpiredFunction, (void *)this);
_utilityFuse.lightFuse();
break;
case kMars48RobotDefends:
_vm->addItemToInventory(_attackingItem);
_attackingItem = 0;
if (_privateFlags.getFlag(kMarsPrivateRobotTiredOfWaitingFlag)) {
startExtraSequence(kMars48RobotKillsPlayer, kExtraCompletedFlag, kFilterNoInput);
loadLoopSound2("", 0x100, 0, 0);
} else {
loadLoopSound2("Sounds/Mars/Robot Loop.aiff", 0x100, 0, 0);
loopExtraSequence(kMars48RobotLoops, kExtraCompletedFlag);
}
break;
case kMars48RobotKillsPlayer:
loadLoopSound2("");
die(kDeathDidntGetOutOfWay);
break;
case kMars49SouthViewMaskFilling:
setCurrentActivation(kActivateMaskOnFiller);
setCurrentAlternate(kAltMarsMaskOnFiller);
GameState.setMarsMaskOnFiller(true);
break;
case kMars58SpinLeft:
case kMars54SpinRight:
GameState.setScoringActivatedPlatform();
arriveAt(kMars52, kEast);
break;
case kMars52SpinLeft:
case kMars56SpinRight:
GameState.setScoringActivatedPlatform();
arriveAt(kMars54, kEast);
break;
case kMars54SpinLeft:
case kMars58SpinRight:
GameState.setScoringActivatedPlatform();
arriveAt(kMars56, kEast);
break;
case kMars56SpinLeft:
case kMars52SpinRight:
GameState.setScoringActivatedPlatform();
arriveAt(kMars58, kEast);
break;
case kMars52Extend:
case kMars54Extend:
case kMars56ExtendNoBomb:
case kMars58Extend:
GameState.setScoringActivatedPlatform();
setCurrentActivation(kActivateReactorPlatformIn);
_privateFlags.setFlag(kMarsPrivatePlatformZoomedInFlag, true);
break;
case kMars53Retract:
case kMars55Retract:
case kMars57RetractWithBomb:
case kMars57RetractNoBomb:
case kMars59Retract:
GameState.setScoringActivatedPlatform();
setCurrentActivation(kActivateReactorPlatformOut);
_privateFlags.setFlag(kMarsPrivatePlatformZoomedInFlag, false);
break;
case kMars56ExtendWithBomb:
playSpotSoundSync(kMustBeUnlockedIn, kMustBeUnlockedOut);
GameState.setScoringActivatedPlatform();
_privateFlags.setFlag(kMarsPrivatePlatformZoomedInFlag, true);
break;
case kMars57CantOpenPanel:
GameState.setScoringActivatedPlatform();
setCurrentActivation(kActivateReactorAskLowerScreen);
break;
case kMars57LowerScreenClosed:
case kMars57ThawLock:
setCurrentActivation(kActivateReactorReadyForNitrogen);
GameState.setMarsLockFrozen(false);
break;
case kMars57FreezeLock:
item = (InventoryItem *)g_allItems.findItemByID(kNitrogenCanister);
item->setItemState(kNitrogenEmpty);
_vm->addItemToInventory(item);
setCurrentActivation(kActivateReactorReadyForCrowBar);
GameState.setScoringUsedLiquidNitrogen();
GameState.setMarsLockFrozen(true);
showExtraView(kMars57LockFrozenView);
_utilityFuse.primeFuse(kLockFreezeTimeLmit);
_utilityFuse.setFunctionPtr(&lockThawTimerExpiredFunction, (void *)this);
_utilityFuse.lightFuse();
break;
case kMars57BreakLock:
item = (InventoryItem *)g_allItems.findItemByID(kCrowbar);
_vm->addItemToInventory(item);
GameState.setScoringUsedCrowBar();
GameState.setMarsLockBroken(true);
GameState.setMarsLockFrozen(false);
startExtraLongSequence(kMars57OpenPanel, kMars57OpenPanelChoices, kExtraCompletedFlag, kFilterNoInput);
break;
case kMars57OpenPanel:
case kMars57OpenPanelChoices:
setCurrentActivation(kActivateReactorAskOperation);
break;
case kMars57ShieldEvaluation:
case kMars57MeasureOutput:
setCurrentActivation(kActivateReactorRanEvaluation);
loopExtraSequence(kMars57ShieldOkayLoop);
break;
case kMars57RunDiagnostics:
setCurrentActivation(kActivateReactorRanDiagnostics);
GameState.setScoringFoundCardBomb();
break;
case kMars57BombExplodes:
case kMars57BombExplodesInGame:
die(kDeathDidntDisarmMarsBomb);
break;
case kMars57BombAnalysis:
setCurrentActivation(kActivateReactorAnalyzed);
break;
case kMars57DontLink:
startExtraSequence(kMars57OpenPanelChoices, kExtraCompletedFlag, kFilterNoInput);
break;
case kMars57CircuitLink:
setCurrentActivation(kActivateReactorInstructions);
break;
case kMars57GameLevel1:
setUpReactorLevel1();
break;
case kMars57GameLevel2:
case kMars57GameLevel3:
setUpNextReactorLevel();
break;
case kMars57GameSolved:
setCurrentActivation(kActivateReactorBombSafe);
break;
case kMars57ExposeBomb:
setCurrentActivation(kActivateReactorBombExposed);
_privateFlags.setFlag(kMarsPrivateBombExposedFlag, true);
break;
case kMars57BackToNormal:
setCurrentActivation(kActivateReactorPlatformIn);
_privateFlags.setFlag(kMarsPrivateBombExposedFlag, false);
g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Mars/XM51SW", false, kWarningInterruption);
break;
case kMars60WestSpinAirlockToEast:
GameState.setMarsAirlockOpen(true);
setCurrentAlternate(kAltMars60AirlockEast);
turnTo(kWest);
setCurrentActivation(kActivateReadyToPressurizeAirlock);
g_airMask->airQualityChanged();
checkAirMask();
loadAmbientLoops();
break;
case kMars60EastSpinAirlockToWest:
GameState.setMarsAirlockOpen(false);
setCurrentAlternate(kAltMars60AirlockWest);
turnTo(kEast);
setCurrentActivation(kActivateReadyToPressurizeAirlock);
g_airMask->airQualityChanged();
checkAirMask();
loadAmbientLoops();
break;
case kMarsRobotHeadOpen:
setCurrentActivation(kActivationRobotHeadOpen);
break;
case kMarsRobotHeadClose:
recallToTSASuccess();
break;
case kMarsMaze007RobotApproach:
case kMarsMaze015SouthRobotApproach:
case kMarsMaze101EastRobotApproach:
case kMarsMaze104WestLoop:
case kMarsMaze133SouthApproach:
case kMarsMaze136NorthApproach:
case kMarsMaze184WestLoop:
die(kDeathGroundByMazebot);
break;
}
} else if ((flag & kTimeForCanyonChaseFlag) != 0) {
doCanyonChase();
} else if ((flag & kExplosionFinishedFlag) != 0) {
_explosions.stop();
_explosions.hide();
if (g_robotShip->isDead()) {
GameState.setMarsFinished(true);
_centerShuttleMovie.hide();
_upperRightShuttleMovie.show();
_upperRightShuttleMovie.setTime(kShuttleUpperRightTargetDestroyedTime);
_upperRightShuttleMovie.redrawMovieWorld();
_rightDamageShuttleMovie.hide();
playMovieSegment(&_rightShuttleMovie, kShuttleRightDestroyedStart, kShuttleRightDestroyedStop);
playSpotSoundSync(kShuttleDestroyedIn, kShuttleDestroyedOut);
throwAwayMarsShuttle();
reinstateMonocleInterface();
recallToTSASuccess();
}
} else if ((flag & kTimeToTransportFlag) != 0) {
transportToRobotShip();
}
if (g_AIArea)
g_AIArea->checkMiddleArea();
}
void Mars::spotCompleted() {
Neighborhood::spotCompleted();
if (GameState.getCurrentRoom() == kMarsRobotShuttle)
g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Mars/XN59WD", false, kWarningInterruption);
}
void Mars::doCanyonChase() {
GameState.setScoringEnteredShuttle();
setNextHandler(_vm);
throwAwayInterface();
_vm->_cursor->hide();
// Open the spot sounds movie again...
_spotSounds.initFromQuickTime(getSoundSpotsName());
_spotSounds.setVolume(_vm->getSoundFXLevel());
Video::VideoDecoder *video = new Video::QuickTimeDecoder();
if (!video->loadFile("Images/Mars/M44ESA.movie"))
error("Could not load interface->shuttle transition video");
while (!_vm->shouldQuit() && !video->endOfVideo()) {
if (video->needsUpdate()) {
const Graphics::Surface *frame = video->decodeNextFrame();
if (frame)
_vm->drawScaledFrame(frame, 0, 0);
}
Common::Event event;
while (g_system->getEventManager()->pollEvent(event))
;
g_system->delayMillis(10);
}
delete video;
if (_vm->shouldQuit())
return;
initOnePicture(&_shuttleInterface1, "Images/Mars/MCmain1.pict", kShuttleBackgroundOrder, kShuttle1Left,
kShuttle1Top, true);
initOnePicture(&_shuttleInterface2, "Images/Mars/MCmain2.pict", kShuttleBackgroundOrder, kShuttle2Left,
kShuttle2Top, true);
initOnePicture(&_shuttleInterface3, "Images/Mars/MCmain3.pict", kShuttleBackgroundOrder, kShuttle3Left,
kShuttle3Top, true);
initOnePicture(&_shuttleInterface4, "Images/Mars/MCmain4.pict", kShuttleBackgroundOrder, kShuttle4Left,
kShuttle4Top, true);
initOneMovie(&_canyonChaseMovie, "Images/Mars/Canyon.movie",
kShuttleMonitorOrder, kShuttleWindowLeft, kShuttleWindowTop, true);
_canyonChaseMovie.setVolume(_vm->getSoundFXLevel());
loadLoopSound1("Sounds/Mars/Inside Cockpit.22K.8.AIFF");
// Swing shuttle around...
playMovieSegment(&_canyonChaseMovie, kShuttleSwingStart, kShuttleSwingStop);
initOneMovie(&_leftShuttleMovie, "Images/Mars/Left Shuttle.movie",
kShuttleMonitorOrder, kShuttleLeftLeft, kShuttleLeftTop, false);
initOneMovie(&_rightShuttleMovie, "Images/Mars/Right Shuttle.movie",
kShuttleMonitorOrder, kShuttleRightLeft, kShuttleRightTop, false);
initOneMovie(&_lowerLeftShuttleMovie, "Images/Mars/Lower Left Shuttle.movie", kShuttleMonitorOrder,
kShuttleLowerLeftLeft, kShuttleLowerLeftTop, false);
initOneMovie(&_lowerRightShuttleMovie, "Images/Mars/Lower Right Shuttle.movie", kShuttleMonitorOrder,
kShuttleLowerRightLeft, kShuttleLowerRightTop, false);
initOneMovie(&_centerShuttleMovie, "Images/Mars/Center Shuttle.movie",
kShuttleMonitorOrder, kShuttleCenterLeft, kShuttleCenterTop, false);
initOneMovie(&_upperLeftShuttleMovie, "Images/Mars/Upper Left Shuttle.movie", kShuttleMonitorOrder,
kShuttleUpperLeftLeft, kShuttleUpperLeftTop, false);
initOneMovie(&_upperRightShuttleMovie, "Images/Mars/Upper Right Shuttle.movie", kShuttleMonitorOrder,
kShuttleUpperRightLeft, kShuttleUpperRightTop, false);
initOneMovie(&_leftDamageShuttleMovie, "Images/Mars/Left Damage Shuttle.movie",
kShuttleStatusOrder, kShuttleLeftEnergyLeft, kShuttleLeftEnergyTop, false);
initOneMovie(&_rightDamageShuttleMovie, "Images/Mars/Right Damage Shuttle.movie",
kShuttleStatusOrder, kShuttleRightEnergyLeft, kShuttleRightEnergyTop, false);
_centerShuttleMovie.show();
_centerShuttleMovie.setTime(kShuttleCenterBoardingTime);
playSpotSoundSync(kShuttleCockpitIn, kShuttleCockpitOut);
_centerShuttleMovie.setTime(kShuttleCenterCheckTime);
playSpotSoundSync(kShuttleOnboardIn, kShuttleOnboardOut);
_shuttleEnergyMeter.initShuttleEnergyMeter();
_shuttleEnergyMeter.powerUpMeter();
while (_shuttleEnergyMeter.isFading()) {
_vm->checkCallBacks();
_vm->refreshDisplay();
g_system->updateScreen();
}
_leftShuttleMovie.show();
playMovieSegment(&_leftShuttleMovie, kShuttleLeftIntroStart, kShuttleLeftIntroStop);
_leftShuttleMovie.setTime(kShuttleLeftNormalTime);
_leftShuttleMovie.redrawMovieWorld();
_leftDamageShuttleMovie.show();
playMovieSegment(&_leftDamageShuttleMovie);
// Take it down a tick initially. This sets the time to the time of the last tick,
// so that subsequence drops will drop it down a tick.
_leftDamageShuttleMovie.setTime(_leftDamageShuttleMovie.getTime() - 40);
_leftDamageShuttleMovie.redrawMovieWorld();
_lowerRightShuttleMovie.show();
_lowerRightShuttleMovie.setTime(kShuttleLowerRightOffTime);
_lowerRightShuttleMovie.redrawMovieWorld();
_centerShuttleMovie.setTime(kShuttleCenterNavCompTime);
_centerShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttleNavigationIn, kShuttleNavigationOut);
_centerShuttleMovie.setTime(kShuttleCenterCommTime);
_centerShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttleCommunicationIn, kShuttleCommunicationOut);
_centerShuttleMovie.setTime(kShuttleCenterAllSystemsTime);
_centerShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttleAllSystemsIn, kShuttleAllSystemsOut);
_centerShuttleMovie.setTime(kShuttleCenterSecureLooseTime);
_centerShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttleSecureLooseIn, kShuttleSecureLooseOut);
_centerShuttleMovie.setTime(kShuttleCenterAutoTestTime);
_centerShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttleAutoTestingIn, kShuttleAutoTestingOut);
_leftShuttleMovie.setTime(kShuttleLeftAutoTestTime);
_leftShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kMarsThrusterAutoTestIn, kMarsThrusterAutoTestOut);
_leftShuttleMovie.setTime(kShuttleLeftNormalTime);
_leftShuttleMovie.redrawMovieWorld();
_centerShuttleMovie.setTime(kShuttleCenterLaunchTime);
_centerShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttlePrepareForDropIn, kShuttlePrepareForDropOut);
playSpotSoundSync(kShuttleAllClearIn, kShuttleAllClearOut);
_centerShuttleMovie.setTime(kShuttleCenterEnterTubeTime);
_centerShuttleMovie.redrawMovieWorld();
_lowerLeftShuttleMovie.show();
_lowerLeftShuttleMovie.setTime(kShuttleLowerLeftCollisionTime);
loadLoopSound1("");
_canyonChaseMovie.setSegment(kCanyonChaseStart, kCanyonChaseStop);
_canyonChaseMovie.start();
startMarsTimer(kLaunchTubeReachedTime, kMovieTicksPerSecond, kMarsLaunchTubeReached);
}
void Mars::startUpFromFinishedSpaceChase() {
setNextHandler(_vm);
throwAwayInterface();
initOnePicture(&_shuttleInterface1, "Images/Mars/MCmain1.pict", kShuttleBackgroundOrder, kShuttle1Left,
kShuttle1Top, true);
initOnePicture(&_shuttleInterface2, "Images/Mars/MCmain2.pict", kShuttleBackgroundOrder, kShuttle2Left,
kShuttle2Top, true);
initOnePicture(&_shuttleInterface3, "Images/Mars/MCmain3.pict", kShuttleBackgroundOrder, kShuttle3Left,
kShuttle3Top, true);
initOnePicture(&_shuttleInterface4, "Images/Mars/MCmain4.pict", kShuttleBackgroundOrder, kShuttle4Left,
kShuttle4Top, true);
initOneMovie(&_leftShuttleMovie, "Images/Mars/Left Shuttle.movie",
kShuttleMonitorOrder, kShuttleLeftLeft, kShuttleLeftTop, false);
initOneMovie(&_rightShuttleMovie, "Images/Mars/Right Shuttle.movie",
kShuttleMonitorOrder, kShuttleRightLeft, kShuttleRightTop, false);
initOneMovie(&_lowerLeftShuttleMovie, "Images/Mars/Lower Left Shuttle.movie", kShuttleMonitorOrder,
kShuttleLowerLeftLeft, kShuttleLowerLeftTop, false);
initOneMovie(&_lowerRightShuttleMovie, "Images/Mars/Lower Right Shuttle.movie", kShuttleMonitorOrder,
kShuttleLowerRightLeft, kShuttleLowerRightTop, false);
initOneMovie(&_centerShuttleMovie, "Images/Mars/Center Shuttle.movie",
kShuttleMonitorOrder, kShuttleCenterLeft, kShuttleCenterTop, false);
initOneMovie(&_upperLeftShuttleMovie, "Images/Mars/Upper Left Shuttle.movie", kShuttleMonitorOrder,
kShuttleUpperLeftLeft, kShuttleUpperLeftTop, false);
initOneMovie(&_upperRightShuttleMovie, "Images/Mars/Upper Right Shuttle.movie", kShuttleMonitorOrder,
kShuttleUpperRightLeft, kShuttleUpperRightTop, false);
initOneMovie(&_leftDamageShuttleMovie, "Images/Mars/Left Damage Shuttle.movie",
kShuttleStatusOrder, kShuttleLeftEnergyLeft, kShuttleLeftEnergyTop, false);
initOneMovie(&_rightDamageShuttleMovie, "Images/Mars/Right Damage Shuttle.movie",
kShuttleStatusOrder, kShuttleRightEnergyLeft, kShuttleRightEnergyTop, false);
_centerShuttleMovie.show();
_shuttleEnergyMeter.initShuttleEnergyMeter();
_shuttleEnergyMeter.setEnergyValue(kFullShuttleEnergy);
_leftShuttleMovie.show();
_leftShuttleMovie.setTime(kShuttleLeftNormalTime);
_leftShuttleMovie.redrawMovieWorld();
_leftDamageShuttleMovie.show();
_leftDamageShuttleMovie.setTime(_leftDamageShuttleMovie.getDuration() - 40);
_leftDamageShuttleMovie.redrawMovieWorld();
_lowerRightShuttleMovie.show();
_lowerLeftShuttleMovie.show();
loadLoopSound1("Sounds/Mars/Space Ambient.22K.8.AIFF");
initOneMovie(&_junk, "Images/Mars/Junk.movie", kShuttleJunkOrder, kShuttleJunkLeft,
kShuttleJunkTop, false);
initOneMovie(&_explosions, "Images/Mars/Explosions.movie", kShuttleWeaponFrontOrder, 0, 0, false);
_explosionCallBack.initCallBack(&_explosions, kCallBackAtExtremes);
_energyBeam.initShuttleWeapon();
_gravitonCannon.initShuttleWeapon();
_upperLeftShuttleMovie.show();
_upperLeftShuttleMovie.setTime(kShuttleUpperLeftDimTime);
_upperLeftShuttleMovie.redrawMovieWorld();
_rightShuttleMovie.show();
_rightShuttleMovie.setTime(kShuttleRightIntroStop - 1);
_rightShuttleMovie.redrawMovieWorld();
_rightDamageShuttleMovie.show();
_rightDamageShuttleMovie.setTime(40);
_rightDamageShuttleMovie.redrawMovieWorld();
_lowerLeftShuttleMovie.setTime(kShuttleLowerLeftAutopilotTime);
_lowerLeftShuttleMovie.redrawMovieWorld();
_shuttleTransportSpot.setArea(kShuttleTransportBounds);
_shuttleTransportSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
g_allHotspots.push_back(&_shuttleTransportSpot);
_privateFlags.setFlag(kMarsPrivateInSpaceChaseFlag, true);
_upperRightShuttleMovie.show();
_upperRightShuttleMovie.setTime(kShuttleUpperRightOverloadTime);
_upperRightShuttleMovie.redrawMovieWorld();
_centerShuttleMovie.setTime(kShuttleCenterSafeTime);
_centerShuttleMovie.redrawMovieWorld();
_lowerRightShuttleMovie.setTime(kShuttleLowerRightTransportTime);
_lowerRightShuttleMovie.redrawMovieWorld();
initOneMovie(&_canyonChaseMovie, "Images/Mars/M98EAS.movie", kShuttleTractorBeamMovieOrder,
kShuttleWindowLeft, kShuttleWindowTop, true);
_canyonChaseMovie.setTime(_canyonChaseMovie.getDuration());
_canyonChaseMovie.redrawMovieWorld();
}
void Mars::startUpFromSpaceChase() {
setNextHandler(_vm);
throwAwayInterface();
// Open the spot sounds movie again...
_spotSounds.initFromQuickTime(getSoundSpotsName());
_spotSounds.setVolume(_vm->getSoundFXLevel());;
initOnePicture(&_shuttleInterface1, "Images/Mars/MCmain1.pict", kShuttleBackgroundOrder, kShuttle1Left,
kShuttle1Top, true);
initOnePicture(&_shuttleInterface2, "Images/Mars/MCmain2.pict", kShuttleBackgroundOrder, kShuttle2Left,
kShuttle2Top, true);
initOnePicture(&_shuttleInterface3, "Images/Mars/MCmain3.pict", kShuttleBackgroundOrder, kShuttle3Left,
kShuttle3Top, true);
initOnePicture(&_shuttleInterface4, "Images/Mars/MCmain4.pict", kShuttleBackgroundOrder, kShuttle4Left,
kShuttle4Top, true);
initOneMovie(&_leftShuttleMovie, "Images/Mars/Left Shuttle.movie",
kShuttleMonitorOrder, kShuttleLeftLeft, kShuttleLeftTop, false);
initOneMovie(&_rightShuttleMovie, "Images/Mars/Right Shuttle.movie",
kShuttleMonitorOrder, kShuttleRightLeft, kShuttleRightTop, false);
initOneMovie(&_lowerLeftShuttleMovie, "Images/Mars/Lower Left Shuttle.movie", kShuttleMonitorOrder,
kShuttleLowerLeftLeft, kShuttleLowerLeftTop, false);
initOneMovie(&_lowerRightShuttleMovie, "Images/Mars/Lower Right Shuttle.movie", kShuttleMonitorOrder,
kShuttleLowerRightLeft, kShuttleLowerRightTop, false);
initOneMovie(&_centerShuttleMovie, "Images/Mars/Center Shuttle.movie",
kShuttleMonitorOrder, kShuttleCenterLeft, kShuttleCenterTop, false);
initOneMovie(&_upperLeftShuttleMovie, "Images/Mars/Upper Left Shuttle.movie", kShuttleMonitorOrder,
kShuttleUpperLeftLeft, kShuttleUpperLeftTop, false);
initOneMovie(&_upperRightShuttleMovie, "Images/Mars/Upper Right Shuttle.movie", kShuttleMonitorOrder,
kShuttleUpperRightLeft, kShuttleUpperRightTop, false);
initOneMovie(&_leftDamageShuttleMovie, "Images/Mars/Left Damage Shuttle.movie",
kShuttleStatusOrder, kShuttleLeftEnergyLeft, kShuttleLeftEnergyTop, false);
initOneMovie(&_rightDamageShuttleMovie, "Images/Mars/Right Damage Shuttle.movie",
kShuttleStatusOrder, kShuttleRightEnergyLeft, kShuttleRightEnergyTop, false);
_centerShuttleMovie.show();
_shuttleEnergyMeter.initShuttleEnergyMeter();
_shuttleEnergyMeter.setEnergyValue(kFullShuttleEnergy);
_leftShuttleMovie.show();
_leftShuttleMovie.setTime(kShuttleLeftNormalTime);
_leftShuttleMovie.redrawMovieWorld();
_leftDamageShuttleMovie.show();
_leftDamageShuttleMovie.setTime(_leftDamageShuttleMovie.getDuration() - 40);
_leftDamageShuttleMovie.redrawMovieWorld();
_lowerRightShuttleMovie.show();
_lowerLeftShuttleMovie.show();
loadLoopSound1("Sounds/Mars/Space Ambient.22K.8.AIFF");
initOneMovie(&_planetMovie, "Images/Mars/Planet.movie", kShuttlePlanetOrder,
kPlanetStartLeft, kPlanetStartTop, true);
_planetMovie.setFlags(kLoopTimeBase);
initOneMovie(&_junk, "Images/Mars/Junk.movie", kShuttleJunkOrder, kShuttleJunkLeft,
kShuttleJunkTop, false);
initOneMovie(&_explosions, "Images/Mars/Explosions.movie", kShuttleWeaponFrontOrder, 0, 0, false);
_explosionCallBack.initCallBack(&_explosions, kCallBackAtExtremes);
_energyBeam.initShuttleWeapon();
_gravitonCannon.initShuttleWeapon();
_upperLeftShuttleMovie.show();
_robotShip.initRobotShip();
_planetMovie.start();
_planetMover.startMoving(&_planetMovie);
_upperLeftShuttleMovie.setTime(kShuttleUpperLeftDimTime);
_upperLeftShuttleMovie.redrawMovieWorld();
_centerShuttleMovie.setTime(kShuttleCenterTargetSightedTime);
_centerShuttleMovie.redrawMovieWorld();
_lowerRightShuttleMovie.setTime(kShuttleLowerRightTrackingTime);
_lowerRightShuttleMovie.redrawMovieWorld();
_rightShuttleMovie.show();
_rightShuttleMovie.setTime(kShuttleRightIntroStop - 1);
_rightShuttleMovie.redrawMovieWorld();
_rightDamageShuttleMovie.show();
_rightDamageShuttleMovie.setTime(_rightDamageShuttleMovie.getDuration() - 40);
_rightDamageShuttleMovie.redrawMovieWorld();
_lowerLeftShuttleMovie.setTime(kShuttleLowerLeftAutopilotTime);
_lowerLeftShuttleMovie.redrawMovieWorld();
_robotShip.startMoving();
_shuttleHUD.initShuttleHUD();
_tractorBeam.startDisplaying();
_energyChoiceSpot.setArea(kShuttleEnergyBeamBounds);
_energyChoiceSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
g_allHotspots.push_back(&_energyChoiceSpot);
_gravitonChoiceSpot.setArea(kShuttleGravitonBounds);
_gravitonChoiceSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
g_allHotspots.push_back(&_gravitonChoiceSpot);
_tractorChoiceSpot.setArea(kShuttleTractorBounds);
_tractorChoiceSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
g_allHotspots.push_back(&_tractorChoiceSpot);
_shuttleViewSpot.setArea(kShuttleWindowLeft, kShuttleWindowTop,
kShuttleWindowLeft + kShuttleWindowWidth, kShuttleWindowTop + kShuttleWindowHeight);
_shuttleViewSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
g_allHotspots.push_back(&_shuttleViewSpot);
_shuttleTransportSpot.setArea(kShuttleTransportBounds);
_shuttleTransportSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
g_allHotspots.push_back(&_shuttleTransportSpot);
_privateFlags.setFlag(kMarsPrivateInSpaceChaseFlag, true);
startMarsTimer(kSpaceChaseTimeLimit, kOneTickPerSecond, kMarsSpaceChaseFinished);
}
void Mars::setSoundFXLevel(const uint16 level) {
Neighborhood::setSoundFXLevel(level);
if (_canyonChaseMovie.isMovieValid())
_canyonChaseMovie.setVolume(level);
if (_explosions.isMovieValid())
_explosions.setVolume(level);
}
void Mars::startMarsTimer(TimeValue time, TimeScale scale, MarsTimerCode code) {
_utilityFuse.primeFuse(time, scale);
_marsEvent.mars = this;
_marsEvent.event = code;
_utilityFuse.setFunctionPtr(&marsTimerFunction, (void *)&_marsEvent);
_utilityFuse.lightFuse();
}
void Mars::marsTimerExpired(MarsTimerEvent &event) {
Common::Rect r;
uint16 x, y;
switch (event.event) {
case kMarsLaunchTubeReached:
_lowerLeftShuttleMovie.setTime(kShuttleLowerLeftTubeTime);
_lowerLeftShuttleMovie.redrawMovieWorld();
startMarsTimer(kCanyonChaseFinishedTime, kMovieTicksPerSecond, kMarsCanyonChaseFinished);
break;
case kMarsCanyonChaseFinished:
GameState.setScoringEnteredLaunchTube();
while (_canyonChaseMovie.isRunning()) {
_vm->checkCallBacks();
_vm->refreshDisplay();
_vm->_system->delayMillis(10);
}
_canyonChaseMovie.stop();
_canyonChaseMovie.stopDisplaying();
_canyonChaseMovie.releaseMovie();
_vm->_gfx->enableErase();
loadLoopSound1("Sounds/Mars/Space Ambient.22K.8.AIFF");
playSpotSoundSync(kShuttleConfiguringIn, kShuttleConfiguringOut);
playSpotSoundSync(kShuttleGeneratingIn, kShuttleGeneratingOut);
playSpotSoundSync(kShuttleBreakawayIn, kShuttleBreakawayOut);
playSpotSoundSync(kMarsAtmosphericBreakawayIn, kMarsAtmosphericBreakawayOut);
initOneMovie(&_planetMovie, "Images/Mars/Planet.movie", kShuttlePlanetOrder, kPlanetStartLeft, kPlanetStartTop, true);
_planetMovie.setFlags(kLoopTimeBase);
initOneMovie(&_junk, "Images/Mars/Junk.movie", kShuttleJunkOrder, kShuttleJunkLeft, kShuttleJunkTop, false);
initOneMovie(&_explosions, "Images/Mars/Explosions.movie", kShuttleWeaponFrontOrder, 0, 0, false);
_explosionCallBack.initCallBack(&_explosions, kCallBackAtExtremes);
_energyBeam.initShuttleWeapon();
_gravitonCannon.initShuttleWeapon();
_centerShuttleMovie.setTime(kShuttleCenterWeaponsTime);
_centerShuttleMovie.redrawMovieWorld();
_upperLeftShuttleMovie.show();
_upperLeftShuttleMovie.setTime(kShuttleUpperLeftDampingTime);
_upperLeftShuttleMovie.redrawMovieWorld();
_robotShip.initRobotShip();
_planetMovie.start();
_planetMover.startMoving(&_planetMovie);
playSpotSoundSync(kShuttleDamperDescIn, kShuttleDamperDescOut);
_upperLeftShuttleMovie.setTime(kShuttleUpperLeftGravitonTime);
_upperLeftShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttleGravitonDescIn, kShuttleGravitonDescOut);
_upperLeftShuttleMovie.setTime(kShuttleUpperLeftTractorTime);
_upperLeftShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttleTractorDescIn, kShuttleTractorDescOut);
_upperLeftShuttleMovie.setTime(kShuttleUpperLeftDimTime);
_upperLeftShuttleMovie.redrawMovieWorld();
_centerShuttleMovie.setTime(kShuttleCenterTargetSightedTime);
_centerShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttleTargetSightedIn, kShuttleTargetSightedOut);
_lowerRightShuttleMovie.setTime(kShuttleLowerRightTrackingTime);
_lowerRightShuttleMovie.redrawMovieWorld();
_rightShuttleMovie.show();
playMovieSegment(&_rightShuttleMovie, kShuttleRightIntroStart, kShuttleRightIntroStop);
_rightDamageShuttleMovie.show();
playMovieSegment(&_rightDamageShuttleMovie);
// Take it down a tick initially. This sets the time to the time of the last tick,
// so that subsequence drops will drop it down a tick.
_rightDamageShuttleMovie.setTime(_rightDamageShuttleMovie.getTime() - 40);
_rightDamageShuttleMovie.redrawMovieWorld();
_lowerLeftShuttleMovie.setTime(kShuttleLowerLeftAutopilotTime);
_lowerLeftShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttleAutopilotEngagedIn, kShuttleAutopilotEngagedOut);
_robotShip.startMoving();
_shuttleHUD.initShuttleHUD();
_tractorBeam.startDisplaying();
_energyChoiceSpot.setArea(kShuttleEnergyBeamBounds);
_energyChoiceSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
g_allHotspots.push_back(&_energyChoiceSpot);
_gravitonChoiceSpot.setArea(kShuttleGravitonBounds);
_gravitonChoiceSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
g_allHotspots.push_back(&_gravitonChoiceSpot);
_tractorChoiceSpot.setArea(kShuttleTractorBounds);
_tractorChoiceSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
g_allHotspots.push_back(&_tractorChoiceSpot);
_shuttleViewSpot.setArea(kShuttleWindowLeft, kShuttleWindowTop,
kShuttleWindowLeft + kShuttleWindowWidth, kShuttleWindowTop + kShuttleWindowHeight);
_shuttleViewSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
g_allHotspots.push_back(&_shuttleViewSpot);
_shuttleTransportSpot.setArea(kShuttleTransportBounds);
_shuttleTransportSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
g_allHotspots.push_back(&_shuttleTransportSpot);
_privateFlags.setFlag(kMarsPrivateInSpaceChaseFlag, true);
playSpotSoundSync(kMarsCockpitChatterIn, kMarsCockpitChatterOut);
GameState.setMarsFinishedCanyonChase(true);
startMarsTimer(kSpaceChaseTimeLimit, kOneTickPerSecond, kMarsSpaceChaseFinished);
_vm->_cursor->hideUntilMoved();
break;
case kMarsSpaceChaseFinished:
// Player failed to stop the robot in time...
_interruptionFilter = kFilterNoInput;
_rightShuttleMovie.setTime(kShuttleRightTargetLockTime);
_rightShuttleMovie.redrawMovieWorld();
_upperRightShuttleMovie.show();
_upperRightShuttleMovie.setTime(kShuttleUpperRightLockedTime);
_upperRightShuttleMovie.redrawMovieWorld();
_rightShuttleMovie.setTime(kShuttleRightGravitonTime);
_rightShuttleMovie.redrawMovieWorld();
_upperRightShuttleMovie.setTime(kShuttleUpperRightArmedTime);
_upperRightShuttleMovie.redrawMovieWorld();
_vm->delayShell(3, 1);
x = _vm->getRandomNumber(19);
y = _vm->getRandomNumber(19);
r = Common::Rect(kShuttleWindowMidH - x, kShuttleWindowMidV - y,
kShuttleWindowMidH - x + 20, kShuttleWindowMidV - y + 20);
showBigExplosion(r, kShuttleAlienShipOrder);
while (_explosions.isRunning()) {
_vm->checkCallBacks();
_vm->refreshDisplay();
g_system->delayMillis(10);
}
throwAwayMarsShuttle();
reinstateMonocleInterface();
recallToTSAFailure();
break;
default:
break;
}
_interruptionFilter = kFilterAllInput;
}
void Mars::throwAwayMarsShuttle() {
_shuttleInterface1.deallocateSurface();
_shuttleInterface1.stopDisplaying();
_shuttleInterface2.deallocateSurface();
_shuttleInterface2.stopDisplaying();
_shuttleInterface3.deallocateSurface();
_shuttleInterface3.stopDisplaying();
_shuttleInterface4.deallocateSurface();
_shuttleInterface4.stopDisplaying();
_spotSounds.disposeSound();
_canyonChaseMovie.releaseMovie();
_canyonChaseMovie.stopDisplaying();
_leftShuttleMovie.releaseMovie();
_leftShuttleMovie.stopDisplaying();
_rightShuttleMovie.releaseMovie();
_rightShuttleMovie.stopDisplaying();
_lowerLeftShuttleMovie.releaseMovie();
_lowerLeftShuttleMovie.stopDisplaying();
_lowerRightShuttleMovie.releaseMovie();
_lowerRightShuttleMovie.stopDisplaying();
_centerShuttleMovie.releaseMovie();
_centerShuttleMovie.stopDisplaying();
_upperLeftShuttleMovie.releaseMovie();
_upperLeftShuttleMovie.stopDisplaying();
_upperRightShuttleMovie.releaseMovie();
_upperRightShuttleMovie.stopDisplaying();
_leftDamageShuttleMovie.releaseMovie();
_leftDamageShuttleMovie.stopDisplaying();
_rightDamageShuttleMovie.releaseMovie();
_rightDamageShuttleMovie.stopDisplaying();
_shuttleEnergyMeter.disposeShuttleEnergyMeter();
_robotShip.cleanUpRobotShip();
_shuttleHUD.cleanUpShuttleHUD();
_tractorBeam.stopDisplaying();
_junk.releaseMovie();
_junk.stopDisplaying();
_energyBeam.cleanUpShuttleWeapon();
_gravitonCannon.cleanUpShuttleWeapon();
g_allHotspots.remove(&_energyChoiceSpot);
g_allHotspots.remove(&_gravitonChoiceSpot);
g_allHotspots.remove(&_tractorChoiceSpot);
g_allHotspots.remove(&_shuttleViewSpot);
g_allHotspots.remove(&_shuttleTransportSpot);
_explosions.releaseMovie();
_explosions.stopDisplaying();
loadLoopSound1("");
}
void Mars::transportToRobotShip() {
throwAwayMarsShuttle();
Video::VideoDecoder *video = new Video::QuickTimeDecoder();
if (!video->loadFile("Images/Mars/M98EAE.movie"))
error("Could not load shuttle->interface transition video");
while (!_vm->shouldQuit() && !video->endOfVideo()) {
if (video->needsUpdate()) {
const Graphics::Surface *frame = video->decodeNextFrame();
if (frame)
_vm->drawScaledFrame(frame, 0, 0);
}
Common::Event event;
while (g_system->getEventManager()->pollEvent(event))
;
g_system->delayMillis(10);
}
delete video;
if (_vm->shouldQuit())
return;
reinstateMonocleInterface();
g_energyMonitor->stopEnergyDraining();
g_energyMonitor->restoreLastEnergyValue();
_vm->resetEnergyDeathReason();
g_energyMonitor->startEnergyDraining();
arriveAt(kMarsRobotShuttle, kEast);
_navMovie.stop();
_navMovie.setTime(_navMovie.getStart());
_navMovie.start();
}
const int kRobotTooStrong = 1;
const int kTractorTooWeak = 2;
const int kCapturedRobotShip = 3;
void Mars::spaceChaseClick(const Input &input, const tHotSpotID id) {
Common::Point pt;
switch (id) {
case kShuttleEnergySpotID:
_upperLeftShuttleMovie.setTime(kShuttleUpperLeftDampingTime);
_upperLeftShuttleMovie.redrawMovieWorld();
_leftShuttleMovie.setTime(kShuttleLeftDampingTime);
_leftShuttleMovie.redrawMovieWorld();
_shuttleHUD.hide();
_weaponSelection = kEnergyBeam;
playSpotSoundSync(kShuttleDampingBeamIn, kShuttleDampingBeamOut);
break;
case kShuttleGravitonSpotID:
_upperLeftShuttleMovie.setTime(kShuttleUpperLeftGravitonTime);
_upperLeftShuttleMovie.redrawMovieWorld();
_leftShuttleMovie.setTime(kShuttleLeftGravitonTime);
_leftShuttleMovie.redrawMovieWorld();
_shuttleHUD.hide();
_weaponSelection = kGravitonCannon;
playSpotSoundSync(kShuttleGravitonIn, kShuttleGravitonOut);
break;
case kShuttleTractorSpotID:
_upperLeftShuttleMovie.setTime(kShuttleUpperLeftTractorTime);
_upperLeftShuttleMovie.redrawMovieWorld();
_leftShuttleMovie.setTime(kShuttleLeftTractorTime);
_leftShuttleMovie.redrawMovieWorld();
_shuttleHUD.show();
_weaponSelection = kTractorBeam;
playSpotSoundSync(kShuttleTractorBeamIn, kShuttleTractorBeamOut);
break;
case kShuttleViewSpotID:
switch (_weaponSelection) {
case kEnergyBeam:
if (_shuttleEnergyMeter.getEnergyValue() < kMinDampingEnergy) {
playSpotSoundSync(kShuttleEnergyTooLowIn, kShuttleEnergyTooLowOut);
} else {
if (_energyBeam.canFireWeapon()) {
_shuttleEnergyMeter.dropEnergyValue(kMinDampingEnergy);
input.getInputLocation(pt);
_energyBeam.fireWeapon(pt.x, pt.y);
playSpotSoundSync(kMarsEDBBlastIn, kMarsEDBBlastOut);
}
}
break;
case kGravitonCannon:
if (_shuttleEnergyMeter.getEnergyValue() < kMinGravitonEnergy) {
playSpotSoundSync(kShuttleEnergyTooLowIn, kShuttleEnergyTooLowOut);
} else {
if (_gravitonCannon.canFireWeapon()) {
_shuttleEnergyMeter.dropEnergyValue(kMinGravitonEnergy);
input.getInputLocation(pt);
_gravitonCannon.fireWeapon(pt.x, pt.y);
playSpotSoundSync(kMarsGravitonBlastIn, kMarsGravitonBlastOut);
}
}
break;
case kTractorBeam:
if (_shuttleHUD.isTargetLocked()) {
// play tractor beam sound?
_utilityFuse.stopFuse();
_tractorBeam.show();
int capture;
if (_rightDamageShuttleMovie.getTime() > 40) {
capture = kRobotTooStrong;
} else if (!_shuttleEnergyMeter.enoughEnergyForTractorBeam()) {
capture = kTractorTooWeak;
} else {
_robotShip.snareByTractorBeam();
capture = kCapturedRobotShip;
_planetMover.dropPlanetOutOfSight();
}
_shuttleEnergyMeter.drainForTractorBeam();
while (_shuttleEnergyMeter.isFading()) {
_vm->checkCallBacks();
_vm->refreshDisplay();
_vm->_system->delayMillis(10);
}
_shuttleEnergyMeter.setEnergyValue(_shuttleEnergyMeter.getEnergyValue());
switch (capture) {
case kRobotTooStrong:
_tractorBeam.hide();
playSpotSoundSync(kShuttleBrokeFreeIn, kShuttleBrokeFreeOut);
_utilityFuse.lightFuse();
break;
case kTractorTooWeak:
playSpotSoundSync(kShuttleCantHoldIn, kShuttleCantHoldOut);
_tractorBeam.hide();
_utilityFuse.lightFuse();
break;
case kCapturedRobotShip:
_tractorBeam.hide();
_shuttleHUD.hide();
_robotShip.cleanUpRobotShip();
_planetMovie.stop();
_planetMovie.stopDisplaying();
_planetMovie.releaseMovie();
// Shameless reuse of a variable :P
initOneMovie(&_canyonChaseMovie, "Images/Mars/M98EAS.movie", kShuttleTractorBeamMovieOrder,
kShuttleWindowLeft, kShuttleWindowTop, true);
_canyonChaseMovie.redrawMovieWorld();
playMovieSegment(&_canyonChaseMovie, 0, _canyonChaseMovie.getDuration());
// wait here until any junk clears...
while (_junk.junkFlying()) {
_vm->checkCallBacks();
_vm->refreshDisplay();
_vm->_system->delayMillis(10);
}
_upperRightShuttleMovie.show();
_upperRightShuttleMovie.setTime(kShuttleUpperRightOverloadTime);
_upperRightShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttleOverloadedIn, kShuttleOverloadedOut);
_centerShuttleMovie.setTime(kShuttleCenterVerifyingTime);
_centerShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttleCoordinatesIn, kShuttleCoordinatesOut);
_centerShuttleMovie.setTime(kShuttleCenterScanningTime);
_centerShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttleScanningIn, kShuttleScanningOut);
_centerShuttleMovie.setTime(kShuttleCenterSafeTime);
_centerShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kShuttleSafeIn, kShuttleSafeOut);
_lowerRightShuttleMovie.setTime(kShuttleLowerRightTransportTime);
_lowerRightShuttleMovie.redrawMovieWorld();
GameState.setMarsReadyForShuttleTransport(true);
break;
}
} else {
playSpotSoundSync(kShuttleTractorLimitedIn, kShuttleTractorLimitedOut);
}
break;
default:
break;
}
break;
case kShuttleTransportSpotID:
_lowerRightShuttleMovie.setTime(kShuttleLowerRightTransportHiliteTime);
_lowerRightShuttleMovie.redrawMovieWorld();
_neighborhoodNotification.setNotificationFlags(kTimeToTransportFlag, kTimeToTransportFlag);
break;
}
}
void Mars::showBigExplosion(const Common::Rect &r, const tDisplayOrder order) {
if (_explosions.isMovieValid()) {
_explosions.setDisplayOrder(order);
Common::Rect r2 = r;
int dx = r.width() / 2;
int dy = r.height() / 2;
r2.left -= dx;
r2.right += dx;
r2.top -= dy;
r2.bottom += dy;
_explosions.setBounds(r2);
_explosions.show();
_explosions.stop();
_explosions.setSegment(kBigExplosionStart, kBigExplosionStop);
_explosions.setTime(kBigExplosionStart);
_explosionCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
_explosions.start();
}
}
void Mars::showLittleExplosion(const Common::Rect &r, const tDisplayOrder order) {
if (_explosions.isMovieValid()) {
_explosions.setDisplayOrder(order);
Common::Rect r2 = r;
int dx = r.width() / 2;
int dy = r.height() / 2;
r2.left -= dx;
r2.right += dx;
r2.top -= dy;
r2.bottom += dy;
_explosions.setBounds(r2);
_explosions.show();
_explosions.stop();
_explosions.setSegment(kLittleExplosionStart, kLittleExplosionStop);
_explosions.setTime(kLittleExplosionStart);
_explosionCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
_explosions.start();
}
}
void Mars::hitByJunk() {
_leftDamageShuttleMovie.setTime(_leftDamageShuttleMovie.getTime() - 40);
_leftDamageShuttleMovie.redrawMovieWorld();
playSpotSoundSync(kMarsJunkCollisionIn, kMarsJunkCollisionOut);
if (_leftDamageShuttleMovie.getTime() == 0) {
die(kDeathRanIntoSpaceJunk);
} else {
TimeValue t = _leftDamageShuttleMovie.getTime() / 40;
if (t == 1)
playSpotSoundSync(kShuttleHullBreachIn, kShuttleHullBreachOut);
t = _leftShuttleMovie.getTime();
_leftShuttleMovie.setTime(kShuttleLeftDamagedTime);
_leftShuttleMovie.redrawMovieWorld();
_vm->delayShell(1, 3);
_leftShuttleMovie.setTime(t);
_leftShuttleMovie.redrawMovieWorld();
}
}
void Mars::setUpNextDropTime() {
_robotShip.setUpNextDropTime();
}
void Mars::decreaseRobotShuttleEnergy(const int delta, Common::Point impactPoint) {
_rightDamageShuttleMovie.setTime(_rightDamageShuttleMovie.getTime() - 40 * delta);
_rightDamageShuttleMovie.redrawMovieWorld();
if (_rightDamageShuttleMovie.getTime() == 0) {
Common::Rect r;
_robotShip.getShuttleBounds(r);
int size = MAX(r.width(), r.height());
r = Common::Rect::center(impactPoint.x, impactPoint.y, size, size);
_robotShip.killRobotShip();
showBigExplosion(r, kShuttleRobotShipOrder);
} else if (delta > 1) {
Common::Rect r;
_robotShip.getShuttleBounds(r);
int size = MIN(r.width(), r.height());
r = Common::Rect::center(impactPoint.x, impactPoint.y, size, size);
showLittleExplosion(r, kShuttleWeaponBackOrder);
TimeValue t = _rightShuttleMovie.getTime();
_rightShuttleMovie.setTime(kShuttleRightDamagedTime);
_rightShuttleMovie.redrawMovieWorld();
_vm->delayShell(1, 3);
_rightShuttleMovie.setTime(t);
_rightShuttleMovie.redrawMovieWorld();
}
if (_rightDamageShuttleMovie.getTime() <= 40) {
GameState.setScoringStoppedRobotsShuttle();
if (!GameState.getMarsHitRobotWithCannon())
GameState.setScoringMarsGandhi();
}
}
void Mars::updateCursor(const Common::Point cursorLocation, const Hotspot *cursorSpot) {
if (cursorSpot && cursorSpot->getObjectID() == kShuttleViewSpotID) {
if (_weaponSelection != kNoWeapon)
_vm->_cursor->setCurrentFrameIndex(6);
else
_vm->_cursor->setCurrentFrameIndex(0);
} else {
Neighborhood::updateCursor(cursorLocation, cursorSpot);
}
}
tAirQuality Mars::getAirQuality(const tRoomID room) {
if ((room >= kMars36 && room <= kMars39) || (room >= kMarsMaze004 && room <= kMarsMaze200))
return kAirQualityVacuum;
if (room == kMars35 && !GameState.getMarsAirlockOpen())
return kAirQualityVacuum;
if (room == kMars60 && !GameState.getMarsAirlockOpen())
return kAirQualityVacuum;
return Neighborhood::getAirQuality(room);
}
// Start up panting sound if necessary.
void Mars::checkAirMask() {
Neighborhood::checkAirMask();
if (getAirQuality(GameState.getCurrentRoom()) == kAirQualityVacuum) {
if (g_airMask->isAirMaskOn()) {
if (_noAirFuse.isFuseLit()) {
_noAirFuse.stopFuse();
loadLoopSound2("");
loadAmbientLoops();
playSpotSoundSync(kMarsOxyMaskOnIn, kMarsOxyMaskOnOut);
}
} else {
if (!_noAirFuse.isFuseLit()) {
loadLoopSound2("Sounds/Mars/SukWind1.22K.AIFF");
_noAirFuse.primeFuse(kVacuumSurvivalTimeLimit);
_noAirFuse.lightFuse();
}
}
} else {
if (_noAirFuse.isFuseLit()) {
_noAirFuse.stopFuse();
loadLoopSound2("");
loadAmbientLoops();
}
}
}
void Mars::airStageExpired() {
if (((PegasusEngine *)g_engine)->playerHasItemID(kAirMask))
die(kDeathNoAirInMaze);
else
die(kDeathNoMaskInMaze);
}
void Mars::lockThawed() {
startExtraSequence(kMars57ThawLock, kExtraCompletedFlag, kFilterNoInput);
}
void Mars::setUpReactorLevel1() {
_reactorStage = 1;
makeColorSequence();
_guessObject.initReactorGuess();
_undoPict.initFromPICTResource(_vm->_resFork, kReactorUndoHilitePICTID);
_undoPict.setDisplayOrder(kMonitorLayer);
_undoPict.moveElementTo(kUndoHiliteLeft, kUndoHiliteTop);
_undoPict.startDisplaying();
_guessHistory.initReactorHistory();
_choiceHighlight.initReactorChoiceHighlight();
setCurrentActivation(kActivateReactorInGame);
_bombFuse.primeFuse(kColorMatchingTimeLimit);
_bombFuse.setFunctionPtr(&bombTimerExpiredInGameFunction, (void *)this);
_bombFuse.lightFuse();
}
void Mars::setUpNextReactorLevel() {
_guessObject.show();
_guessHistory.show();
_guessHistory.clearHistory();
_choiceHighlight.show();
_reactorStage++;
makeColorSequence();
}
void Mars::makeColorSequence() {
int32 code[5];
int32 highest = _reactorStage + 2;
for (int32 i = 0; i < highest; i++)
code[i] = i;
_vm->shuffleArray(code, highest);
_currentGuess[0] = -1;
_currentGuess[1] = -1;
_currentGuess[2] = -1;
_nextGuess = 0;
_guessObject.setGuess(-1, -1, -1);
_guessHistory.setAnswer(code[0], code[1], code[2]);
}
void Mars::doUndoOneGuess() {
if (_nextGuess > 0) {
_undoPict.show();
_vm->delayShell(1, 2);
_undoPict.hide();
_nextGuess--;
_currentGuess[_nextGuess] = -1;
_guessObject.setGuess(_currentGuess[0], _currentGuess[1], _currentGuess[2]);
_choiceHighlight.resetHighlight();
if (_currentGuess[0] != -1) {
_choiceHighlight.highlightChoice(_currentGuess[0]);
if (_currentGuess[1] != -1) {
_choiceHighlight.highlightChoice(_currentGuess[1]);
if (_currentGuess[2] != -1)
_choiceHighlight.highlightChoice(_currentGuess[2]);
}
}
}
}
void Mars::doReactorGuess(int32 guess) {
_choiceHighlight.highlightChoice(guess);
_currentGuess[_nextGuess] = guess;
_guessObject.setGuess(_currentGuess[0], _currentGuess[1], _currentGuess[2]);
switch (guess) {
case 0:
playSpotSoundSync(kColorMatchRedIn, kColorMatchRedOut);
break;
case 1:
playSpotSoundSync(kColorMatchYellowIn, kColorMatchYellowOut);
break;
case 2:
playSpotSoundSync(kColorMatchGreenIn, kColorMatchGreenOut);
break;
case 3:
playSpotSoundSync(kColorMatchBlueIn, kColorMatchBlueOut);
break;
case 4:
playSpotSoundSync(kColorMatchPurpleIn, kColorMatchPurpleOut);
break;
}
_nextGuess++;
if (_nextGuess == 3) {
_vm->delayShell(1, 2);
_nextGuess = 0;
_guessHistory.addGuess(_currentGuess[0], _currentGuess[1], _currentGuess[2]);
switch (_guessHistory.getCurrentNumCorrect()) {
case 0:
playSpotSoundSync(kColorMatchZeroNodesIn, kColorMatchZeroNodesOut);
break;
case 1:
playSpotSoundSync(kColorMatchOneNodeIn, kColorMatchOneNodeOut);
break;
case 2:
playSpotSoundSync(kColorMatchTwoNodesIn, kColorMatchTwoNodesOut);
break;
case 3:
playSpotSoundSync(kColorMatchThreeNodesIn, kColorMatchThreeNodesOut);
break;
}
_currentGuess[0] = -1;
_currentGuess[1] = -1;
_currentGuess[2] = -1;
_guessObject.setGuess(-1, -1, -1);
_choiceHighlight.resetHighlight();
if (_guessHistory.isSolved()) {
_guessHistory.showAnswer();
_vm->delayShell(1, 2);
_guessObject.hide();
_guessHistory.hide();
_choiceHighlight.hide();
switch (_reactorStage) {
case 1:
startExtraSequence(kMars57GameLevel2, kExtraCompletedFlag, kFilterNoInput);
break;
case 2:
startExtraSequence(kMars57GameLevel3, kExtraCompletedFlag, kFilterNoInput);
break;
case 3:
_bombFuse.stopFuse();
_guessObject.disposeReactorGuess();
_undoPict.deallocateSurface();
_guessHistory.disposeReactorHistory();
_choiceHighlight.disposeReactorChoiceHighlight();
GameState.setScoringDisarmedCardBomb();
startExtraSequence(kMars57GameSolved, kExtraCompletedFlag, kFilterNoInput);
break;
}
} else if (_guessHistory.getNumGuesses() >= 5) {
_vm->delayShell(2, 1);
bombExplodesInGame();
}
}
}
void Mars::bombExplodesInGame() {
_guessObject.disposeReactorGuess();
_undoPict.deallocateSurface();
_guessHistory.disposeReactorHistory();
_choiceHighlight.disposeReactorChoiceHighlight();
startExtraSequence(kMars57BombExplodesInGame, kExtraCompletedFlag, kFilterNoInput);
}
void Mars::didntFindBomb() {
die(kDeathDidntFindMarsBomb);
}
Common::String Mars::getBriefingMovie() {
Common::String movieName = Neighborhood::getBriefingMovie();
if (!movieName.empty())
return movieName;
return "Images/AI/Mars/XM01";
}
Common::String Mars::getEnvScanMovie() {
Common::String movieName = Neighborhood::getEnvScanMovie();
if (movieName.empty()) {
tRoomID room = GameState.getCurrentRoom();
if (room >= kMars0A && room <= kMars21)
return "Images/AI/Mars/XME1";
else if (room >= kMars22 && room <= kMars31South)
return "Images/AI/Mars/XME2";
else if (room >= kMars52 && room <= kMars58)
return "Images/AI/Mars/XMREACE";
return "Images/AI/Mars/XME3";
}
return movieName;
}
uint Mars::getNumHints() {
uint numHints = Neighborhood::getNumHints();
if (numHints == 0) {
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars27, kNorth):
case MakeRoomView(kMars28, kNorth):
case MakeRoomView(kMars49, kSouth):
numHints = 1;
break;
case MakeRoomView(kMars31, kSouth):
case MakeRoomView(kMars31South, kSouth):
if (!GameState.isTakenItemID(kMarsCard))
numHints = 1;
break;
case MakeRoomView(kMars34, kNorth):
if (!GameState.isTakenItemID(kMarsCard))
numHints = 2;
break;
case MakeRoomView(kMars34, kSouth):
case MakeRoomView(kMars45, kNorth):
if (!GameState.isTakenItemID(kCrowbar))
numHints = 1;
break;
case MakeRoomView(kMars51, kEast):
if (GameState.isCurrentDoorOpen() && !GameState.getShieldOn()) {
if (GameState.isTakenItemID(kShieldBiochip))
numHints = 1;
else
numHints = 2;
}
break;
case MakeRoomView(kMars52, kNorth):
case MakeRoomView(kMars52, kSouth):
case MakeRoomView(kMars52, kEast):
case MakeRoomView(kMars52, kWest):
case MakeRoomView(kMars54, kNorth):
case MakeRoomView(kMars54, kSouth):
case MakeRoomView(kMars54, kEast):
case MakeRoomView(kMars54, kWest):
case MakeRoomView(kMars56, kNorth):
case MakeRoomView(kMars56, kSouth):
case MakeRoomView(kMars56, kWest):
case MakeRoomView(kMars58, kNorth):
case MakeRoomView(kMars58, kSouth):
case MakeRoomView(kMars58, kEast):
case MakeRoomView(kMars58, kWest):
if (!GameState.getShieldOn()) {
if (GameState.isTakenItemID(kShieldBiochip))
numHints = 1;
else
numHints = 2;
}
break;
case MakeRoomView(kMars56, kEast):
if (getCurrentActivation() == kActivateReactorReadyForNitrogen) {
if ((tExtraID)_lastExtra == kMars57LowerScreenClosed)
numHints = 3;
} else if (getCurrentActivation() == kActivateReactorPlatformOut) {
if (!GameState.getShieldOn()) {
if (GameState.isTakenItemID(kShieldBiochip))
numHints = 1;
else
numHints = 2;
}
}
break;
}
}
return numHints;
}
Common::String Mars::getHintMovie(uint hintNum) {
Common::String movieName = Neighborhood::getHintMovie(hintNum);
if (movieName.empty()) {
switch (GameState.getCurrentRoomAndView()) {
case MakeRoomView(kMars27, kNorth):
case MakeRoomView(kMars28, kNorth):
return "Images/AI/Globals/XGLOB5C";
case MakeRoomView(kMars31, kSouth):
case MakeRoomView(kMars31South, kSouth):
case MakeRoomView(kMars34, kSouth):
case MakeRoomView(kMars45, kNorth):
return "Images/AI/Globals/XGLOB1C";
case MakeRoomView(kMars34, kNorth):
if (hintNum == 1)
return "Images/AI/Globals/XGLOB2C";
return "Images/AI/Globals/XGLOB3G";
case MakeRoomView(kMars49, kSouth):
if (GameState.isTakenItemID(kAirMask))
return "Images/AI/Globals/XGLOB3E";
return "Images/AI/Globals/XGLOB1C";
case MakeRoomView(kMars51, kEast):
if (GameState.isTakenItemID(kShieldBiochip))
return "Images/AI/Mars/XM52NW";
if (hintNum == 1)
return "Images/AI/Globals/XGLOB2D";
return "Images/AI/Globals/XGLOB3F";
case MakeRoomView(kMars52, kNorth):
case MakeRoomView(kMars52, kSouth):
case MakeRoomView(kMars52, kEast):
case MakeRoomView(kMars52, kWest):
case MakeRoomView(kMars54, kNorth):
case MakeRoomView(kMars54, kSouth):
case MakeRoomView(kMars54, kEast):
case MakeRoomView(kMars54, kWest):
case MakeRoomView(kMars56, kNorth):
case MakeRoomView(kMars56, kSouth):
case MakeRoomView(kMars56, kWest):
case MakeRoomView(kMars58, kNorth):
case MakeRoomView(kMars58, kSouth):
case MakeRoomView(kMars58, kEast):
case MakeRoomView(kMars58, kWest):
if (hintNum == 1) {
if (GameState.isTakenItemID(kShieldBiochip))
return "Images/AI/Mars/XM52NW";
return "Images/AI/Globals/XGLOB2D";
}
return "Images/AI/Globals/XGLOB3F";
case MakeRoomView(kMars56, kEast):
if (getCurrentActivation() == kActivateReactorReadyForNitrogen)
return Common::String::format("Images/AI/Mars/XM57SD%d", hintNum);
if (hintNum == 1) {
if (GameState.isTakenItemID(kShieldBiochip))
return "Images/AI/Mars/XM52NW";
return "Images/AI/Globals/XGLOB2D";
}
return "Images/AI/Globals/XGLOB3F";
}
}
return movieName;
}
bool Mars::inColorMatchingGame() {
return _guessObject.isDisplaying();
}
bool Mars::canSolve() {
return GameState.getCurrentRoomAndView() == MakeRoomView(kMars56, kEast) && (getCurrentActivation() == kActivateReactorReadyForNitrogen ||
getCurrentActivation() == kActivateReactorReadyForCrowBar || inColorMatchingGame());
}
void Mars::doSolve() {
if (getCurrentActivation() == kActivateReactorReadyForNitrogen || getCurrentActivation() == kActivateReactorReadyForCrowBar) {
_utilityFuse.stopFuse();
GameState.setMarsLockBroken(true);
GameState.setMarsLockFrozen(false);
startExtraLongSequence(kMars57OpenPanel, kMars57OpenPanelChoices, kExtraCompletedFlag, kFilterNoInput);
} else if (inColorMatchingGame()) {
_bombFuse.stopFuse();
_guessObject.disposeReactorGuess();
_undoPict.deallocateSurface();
_guessHistory.disposeReactorHistory();
_choiceHighlight.disposeReactorChoiceHighlight();
startExtraSequence(kMars57GameSolved, kExtraCompletedFlag, kFilterNoInput);
}
}
Common::String Mars::getSoundSpotsName() {
return "Sounds/Mars/Mars Spots";
}
Common::String Mars::getNavMovieName() {
return "Images/Mars/Mars.movie";
}
} // End of namespace Pegasus