mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-09 11:20:56 +00:00
3750 lines
126 KiB
C++
Executable File
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
|