aboutsummaryrefslogtreecommitdiff
path: root/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/pegasus/neighborhood/norad/delta/noraddelta.cpp')
-rw-r--r--engines/pegasus/neighborhood/norad/delta/noraddelta.cpp869
1 files changed, 869 insertions, 0 deletions
diff --git a/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp b/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
new file mode 100644
index 0000000000..2b208aab71
--- /dev/null
+++ b/engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
@@ -0,0 +1,869 @@
+/* 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 "pegasus/energymonitor.h"
+#include "pegasus/gamestate.h"
+#include "pegasus/interface.h"
+#include "pegasus/pegasus.h"
+#include "pegasus/ai/ai_area.h"
+#include "pegasus/items/biochips/opticalchip.h"
+#include "pegasus/items/biochips/retscanchip.h"
+#include "pegasus/items/inventory/airmask.h"
+#include "pegasus/neighborhood/norad/constants.h"
+#include "pegasus/neighborhood/norad/subcontrolroom.h"
+#include "pegasus/neighborhood/norad/delta/globegame.h"
+#include "pegasus/neighborhood/norad/delta/noraddelta.h"
+
+namespace Pegasus {
+
+const uint32 NoradDelta::_noradDeltaClawExtras[22] = {
+ kN60ClawFromAToB,
+ kN60ClawALoop,
+ kN60ClawAPinch,
+ kN60ClawACounterclockwise,
+ kN60ClawAClockwise,
+ kN60ClawFromBToA,
+ kN60ClawFromBToC,
+ kN60ClawFromBToD,
+ kN60ClawBLoop,
+ kN60ClawBPinch,
+ kN60ClawBCounterclockwise,
+ kN60ClawBClockwise,
+ kN60ClawFromCToB,
+ kN60ClawCLoop,
+ kN60ClawCPinch,
+ kN60ClawCCounterclockwise,
+ kN60ClawCClockwise,
+ kN60ClawFromDToB,
+ kN60ClawDLoop,
+ kN60ClawDPinch,
+ kN60ClawDCounterclockwise,
+ kN60ClawDClockwise
+};
+
+NoradDelta::NoradDelta(InputHandler *nextHandler, PegasusEngine *owner) : Norad(nextHandler, owner, "Norad Delta", kNoradDeltaID) {
+ _elevatorUpRoomID = kNorad49South;
+ _elevatorDownRoomID = kNorad48South;
+ _elevatorUpSpotID = kNorad48ElevatorUpSpotID;
+ _elevatorDownSpotID = kNorad49ElevatorDownSpotID;
+
+ // Pressure door stuff.
+
+ _subRoomEntryRoom1 = kNorad50;
+ _subRoomEntryDir1 = kEast;
+ _subRoomEntryRoom2 = kNorad59;
+ _subRoomEntryDir2 = kWest;
+ _upperPressureDoorRoom = kNorad50East;
+ _lowerPressureDoorRoom = kNorad59West;
+
+ _upperPressureDoorUpSpotID = kDeltaUpperPressureDoorUpSpotID;
+ _upperPressureDoorDownSpotID = kDeltaUpperPressureDoorDownSpotID;
+ _upperPressureDoorAbortSpotID = kNorad50DoorOutSpotID;
+
+ _lowerPressureDoorUpSpotID = kDeltaLowerPressureDoorUpSpotID;
+ _lowerPressureDoorDownSpotID = kDeltaLowerPressureDoorDownSpotID;
+ _lowerPressureDoorAbortSpotID = kNorad59WestOutSpotID;
+
+ _pressureSoundIn = kPressureDoorIntro1In;
+ _pressureSoundOut = kPressureDoorIntro1Out;
+ _equalizeSoundIn = kPressureDoorIntro2In;
+ _equalizeSoundOut = kPressureDoorIntro2Out;
+ _accessDeniedIn = kDeltaAccessDeniedIn;
+ _accessDeniedOut = kDeltaAccessDeniedOut;
+
+ GameState.setNoradSubPrepState(kSubDamaged);
+
+ _subControlRoom = kNorad60West;
+}
+
+void NoradDelta::init() {
+ Norad::init();
+
+ // Little fix for the retinal scan zoom in spot...
+ Hotspot *hotspot = g_allHotspots.findHotspotByID(kNorad68WestSpotID);
+ hotspot->setMaskedHotspotFlags(kZoomInSpotFlag, kZoomInSpotFlag | kZoomOutSpotFlag);
+
+ hotspot = g_allHotspots.findHotspotByID(kNorad79WestSpotID);
+ hotspot->setMaskedHotspotFlags(kZoomInSpotFlag, kZoomInSpotFlag | kZoomOutSpotFlag);
+
+ hotspot = g_allHotspots.findHotspotByID(kDelta59RobotShieldBiochipSpotID);
+ hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag);
+ HotspotInfoTable::Entry *hotspotEntry = findHotspotEntry(kDelta59RobotShieldBiochipSpotID);
+ hotspotEntry->hotspotItem = kShieldBiochip;
+
+ hotspot = g_allHotspots.findHotspotByID(kDelta59RobotOpMemBiochipSpotID);
+ hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag);
+ hotspotEntry = findHotspotEntry(kDelta59RobotOpMemBiochipSpotID);
+ hotspotEntry->hotspotItem = kOpticalBiochip;
+
+ hotspot = g_allHotspots.findHotspotByID(kDelta59RobotRetinalBiochipSpotID);
+ hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag);
+ hotspotEntry = findHotspotEntry(kDelta59RobotRetinalBiochipSpotID);
+ hotspotEntry->hotspotItem = kRetinalScanBiochip;
+
+ hotspot = g_allHotspots.findHotspotByID(kDelta60RobotShieldBiochipSpotID);
+ hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag);
+ hotspotEntry = findHotspotEntry(kDelta60RobotShieldBiochipSpotID);
+ hotspotEntry->hotspotItem = kShieldBiochip;
+
+ hotspot = g_allHotspots.findHotspotByID(kDelta60RobotOpMemBiochipSpotID);
+ hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag);
+ hotspotEntry = findHotspotEntry(kDelta60RobotOpMemBiochipSpotID);
+ hotspotEntry->hotspotItem = kOpticalBiochip;
+
+ hotspot = g_allHotspots.findHotspotByID(kDelta60RobotRetinalBiochipSpotID);
+ hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag);
+ hotspotEntry = findHotspotEntry(kDelta60RobotRetinalBiochipSpotID);
+ hotspotEntry->hotspotItem = kRetinalScanBiochip;
+}
+
+void NoradDelta::start() {
+ if (g_energyMonitor) {
+ g_energyMonitor->stopEnergyDraining();
+ g_energyMonitor->restoreLastEnergyValue();
+ _vm->resetEnergyDeathReason();
+ g_energyMonitor->startEnergyDraining();
+ }
+
+ Norad::start();
+}
+
+void NoradDelta::setUpAIRules() {
+ Neighborhood::setUpAIRules();
+
+ if (g_AIArea) {
+ AIPlayMessageAction *messageAction = new AIPlayMessageAction("Images/AI/Norad/XN07NE", false);
+ AILocationCondition *locCondition = new AILocationCondition(1);
+ locCondition->addLocation(MakeRoomView(kNorad68, kWest));
+ AIRule *rule = new AIRule(locCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+ }
+}
+
+void NoradDelta::getExtraCompassMove(const ExtraTable::Entry &entry, FaderMoveSpec &compassMove) {
+ switch (entry.extra) {
+ case kArriveFromSubChase:
+ compassMove.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, entry.movieStart, 20, entry.movieEnd, 90);
+ compassMove.insertFaderKnot(entry.movieStart + 25 * kNoradDeltaFrameDuration, 20);
+ compassMove.insertFaderKnot(entry.movieStart + 94 * kNoradDeltaFrameDuration, 45);
+ compassMove.insertFaderKnot(entry.movieStart + 101 * kNoradDeltaFrameDuration, 45);
+ compassMove.insertFaderKnot(entry.movieStart + 146 * kNoradDeltaFrameDuration, 90 + 15);
+ compassMove.insertFaderKnot(entry.movieStart + 189 * kNoradDeltaFrameDuration, 90 + 15);
+ compassMove.insertFaderKnot(entry.movieStart + 204 * kNoradDeltaFrameDuration, 90 + 30);
+ compassMove.insertFaderKnot(entry.movieStart + 214 * kNoradDeltaFrameDuration, 90 + 20);
+ compassMove.insertFaderKnot(entry.movieStart + 222 * kNoradDeltaFrameDuration, 90 + 20);
+ compassMove.insertFaderKnot(entry.movieStart + 228 * kNoradDeltaFrameDuration, 90 + 10);
+ compassMove.insertFaderKnot(entry.movieStart + 245 * kNoradDeltaFrameDuration, 90 + 85);
+ compassMove.insertFaderKnot(entry.movieStart + 262 * kNoradDeltaFrameDuration, 90 + 70);
+ compassMove.insertFaderKnot(entry.movieStart + 273 * kNoradDeltaFrameDuration, 90 + 80);
+ compassMove.insertFaderKnot(entry.movieStart + 287 * kNoradDeltaFrameDuration, 90);
+ break;
+ case kN60PlayerFollowsRobotToDoor:
+ compassMove.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, entry.movieStart, 270 + kSubControlCompassAngle,
+ entry.movieEnd, 270 - 15);
+ compassMove.insertFaderKnot(entry.movieStart + 280, 270 + kSubControlCompassAngle);
+ compassMove.insertFaderKnot(entry.movieStart + 920, 360);
+ compassMove.insertFaderKnot(entry.movieStart + 1840, 360);
+ compassMove.insertFaderKnot(entry.movieStart + 2520, 270);
+ compassMove.insertFaderKnot(entry.movieStart + 3760, 270);
+ compassMove.insertFaderKnot(entry.movieStart + 4640, 270 + kSubControlCompassAngle);
+ break;
+ case kN59PlayerWins2:
+ compassMove.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, entry.movieStart, 270, entry.movieEnd, 280);
+ compassMove.insertFaderKnot(entry.movieEnd - 1000, 270);
+ default:
+ Norad::getExtraCompassMove(entry, compassMove);
+ break;
+ }
+}
+
+GameInteraction *NoradDelta::makeInteraction(const InteractionID interactionID) {
+ if (interactionID == kNoradGlobeGameInteractionID)
+ return new GlobeGame(this);
+
+ return Norad::makeInteraction(interactionID);
+}
+
+void NoradDelta::playClawMonitorIntro() {
+ playSpotSoundSync(kLoadClawIntroIn, kLoadClawIntroOut);
+}
+
+void NoradDelta::getExitEntry(const RoomID room, const DirectionConstant direction, ExitTable::Entry &entry) {
+ Norad::getExitEntry(room, direction, entry);
+
+ if (room == kNorad61 && direction == kSouth)
+ entry.movieStart += kNoradDeltaFrameDuration;
+}
+
+void NoradDelta::getZoomEntry(const HotSpotID id, ZoomTable::Entry &zoomEntry) {
+ Norad::getZoomEntry(id, zoomEntry);
+
+ if (id == kNorad59WestSpotID && GameState.getNoradPlayedGlobeGame()) {
+ ExtraTable::Entry extraEntry;
+ getExtraEntry(kN59ZoomWithRobot, extraEntry);
+ zoomEntry.movieStart = extraEntry.movieStart;
+ zoomEntry.movieEnd = extraEntry.movieEnd;
+ }
+}
+
+void NoradDelta::loadAmbientLoops() {
+/*
+ Logic:
+
+ loop sound 1:
+ if room == kNorad79West
+ if player globe game
+ play kNoradGlobeLoop2SoundNum
+ else
+ play kNoradRedAlertLoopSoundNum
+ else if room >= kNorad78 && room <= kNorad79
+ play kNoradGlobeLoop2SoundNum
+ else if gassed,
+ if room >= kNorad41 && room <= kNorad49South
+ play kNoradNewSubLoopSoundNum, kNoradWarningVolume
+ else if room >= kNorad59 && room <= kNorad60West
+ play kNoradSubControlLoopSoundNum, kNoradWarningVolume
+ else
+ play kNoradWarningLoopSoundNum, kNoradWarningVolume
+ else
+ play nothing
+ loop sound 2:
+ if gassed and not wearing air mask
+ if room == kNorad54North
+ play breathing unmanned loop
+ else
+ play breathing
+ else
+ if room == kNorad54North
+ play unmanned loop
+ else
+ play nothing
+*/
+
+ if (GameState.getNoradArrivedFromSub()) {
+ RoomID room = GameState.getCurrentRoom();
+
+ if (room == kNorad79West) {
+ if (_privateFlags.getFlag(kNoradPrivateFinishedGlobeGameFlag))
+ loadLoopSound1("Sounds/Norad/GlobAmb2.22K.AIFF");
+ else
+ loadLoopSound1("Sounds/Norad/RedAlert.22K.AIFF");
+ } else if (room >= kNorad78 && room <= kNorad79) {
+ // clone2727 says: This looks like it should be loadLoopSound1...
+ loadLoopSound2("Sounds/Norad/RedAlert.22K.AIFF");
+ } else if (GameState.getNoradGassed()) {
+ if (room >= kNorad41 && room <= kNorad49South)
+ loadLoopSound1("Sounds/Norad/NEW SUB AMB.22K.AIFF", kNoradWarningVolume * 3);
+ else if (room >= kNorad59 && room <= kNorad60West)
+ loadLoopSound1("Sounds/Norad/SUB CONTRL LOOP.22K.AIFF", kNoradWarningVolume * 3);
+ else
+ loadLoopSound1("Sounds/Norad/WARNING LOOP.22K.AIFF", kNoradWarningVolume);
+ } else {
+ loadLoopSound1("");
+ }
+
+ if (GameState.getNoradGassed() && !g_airMask->isAirFilterOn()) {
+ if (room == kNorad54North)
+ loadLoopSound2("Sounds/Norad/Breathing Typing.22K.AIFF", 0x100 / 2);
+ else
+ loadLoopSound2("Sounds/Norad/SUCKING WIND.22K.AIFF", kNoradSuckWindVolume, 0, 0);
+ } else {
+ if (room == kNorad54North)
+ loadLoopSound2("Sounds/Norad/N54NAS.22K.AIFF", 0x100 / 2);
+ else
+ loadLoopSound2("");
+ }
+ } else {
+ // Start them off at zero...
+ if (GameState.getNoradGassed())
+ loadLoopSound1("Sounds/Norad/NEW SUB AMB.22K.AIFF", 0, 0, 0);
+ if (!g_airMask->isAirFilterOn())
+ loadLoopSound2("Sounds/Norad/SUCKING WIND.22K.AIFF", 0, 0, 0);
+ }
+}
+
+void NoradDelta::checkContinuePoint(const RoomID room, const DirectionConstant direction) {
+ switch (MakeRoomView(room, direction)) {
+ case MakeRoomView(kNorad41, kEast):
+ case MakeRoomView(kNorad49, kEast):
+ case MakeRoomView(kNorad49, kWest):
+ case MakeRoomView(kNorad61, kSouth):
+ case MakeRoomView(kNorad68, kEast):
+ case MakeRoomView(kNorad79, kWest):
+ makeContinuePoint();
+ break;
+ }
+}
+
+void NoradDelta::arriveAt(const RoomID room, const DirectionConstant direction) {
+ if (room != kNorad68)
+ GameState.setNoradRetScanGood(false);
+
+ Norad::arriveAt(room, direction);
+
+ FaderMoveSpec loop1Spec, loop2Spec;
+ ExtraTable::Entry entry;
+
+ switch (room) {
+ case kNorad41:
+ if (direction == kEast && !GameState.getNoradArrivedFromSub()) {
+ GameState.setNoradPlayedGlobeGame(false);
+
+ GameState.setNoradBeatRobotWithClaw(false);
+ GameState.setNoradBeatRobotWithDoor(false);
+ GameState.setNoradRetScanGood(false);
+
+ GameState.setScoringExitedSub(true);
+
+ getExtraEntry(kArriveFromSubChase, entry);
+
+ loop1Spec.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, 0, 0, entry.movieEnd -
+ entry.movieStart, kNoradWarningVolume);
+ loop1Spec.insertFaderKnot(7320, 0);
+ loop1Spec.insertFaderKnot(7880, kNoradWarningVolume);
+
+ loop2Spec.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, 0, 0, entry.movieEnd -
+ entry.movieStart, kNoradSuckWindVolume);
+ loop1Spec.insertFaderKnot(7320, 0);
+ loop1Spec.insertFaderKnot(7880, kNoradSuckWindVolume);
+
+ startExtraSequence(kArriveFromSubChase, kExtraCompletedFlag, kFilterNoInput);
+
+ startLoop1Fader(loop1Spec);
+ startLoop2Fader(loop2Spec);
+ }
+ break;
+ case kNorad54North:
+ GameState.setScoringSawRobotAt54North(true);
+ break;
+ case kNorad68:
+ if (GameState.getNoradRetScanGood())
+ openDoor();
+ break;
+ case kNorad68West:
+ arriveAtNorad68West();
+ break;
+ case kNorad79West:
+ arriveAtNorad79West();
+ break;
+ default:
+ break;
+ }
+}
+
+void NoradDelta::doorOpened() {
+ Norad::doorOpened();
+ GameState.setNoradRetScanGood(false);
+}
+
+void NoradDelta::arriveAtNorad68West() {
+ playSpotSoundSync(kHoldForRetinalIn, kHoldForRetinalOut);
+
+ BiochipItem *retScan = _vm->getCurrentBiochip();
+
+ if (retScan != 0 && retScan->getObjectID() == kRetinalScanBiochip) {
+ ((RetScanChip *)retScan)->searchForLaser();
+ succeedRetinalScan();
+ } else {
+ failRetinalScan();
+ }
+}
+
+void NoradDelta::arriveAtNorad79West() {
+ if (!GameState.getNoradPlayedGlobeGame())
+ newInteraction(kNoradGlobeGameInteractionID);
+}
+
+void NoradDelta::bumpIntoWall() {
+ requestSpotSound(kDeltaBumpIntoWallIn, kDeltaBumpIntoWallOut, kFilterNoInput, 0);
+ Neighborhood::bumpIntoWall();
+}
+
+void NoradDelta::failRetinalScan() {
+ startExtraSequence(kNoradDeltaRetinalScanBad, kExtraCompletedFlag, kFilterNoInput);
+}
+
+void NoradDelta::succeedRetinalScan() {
+ startExtraSequence(kNoradDeltaRetinalScanGood, kExtraCompletedFlag, kFilterNoInput);
+ GameState.setNoradRetScanGood(true);
+ GameState.setScoringUsedRetinalChip(true);
+}
+
+void NoradDelta::getDoorEntry(const RoomID room, const DirectionConstant direction, DoorTable::Entry &entry) {
+ Norad::getDoorEntry(room, direction, entry);
+
+ if (room == kNorad68 && direction == kWest && !GameState.getNoradRetScanGood())
+ entry.flags = kDoorPresentMask | kDoorLockedMask;
+}
+
+void NoradDelta::finishedGlobeGame() {
+ GameState.setNoradPlayedGlobeGame(true);
+ _privateFlags.setFlag(kNoradPrivateFinishedGlobeGameFlag, true);
+ GameState.setScoringFinishedGlobeGame(true);
+ loadAmbientLoops();
+ g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN60WD1", false, kWarningInterruption);
+}
+
+bool NoradDelta::playingAgainstRobot() {
+ return GameState.getNoradPlayedGlobeGame();
+}
+
+void NoradDelta::getClawInfo(HotSpotID &outSpotID, HotSpotID &prepSpotID, HotSpotID &clawControlSpotID, HotSpotID &pinchClawSpotID,
+ HotSpotID &moveClawDownSpotID, HotSpotID &moveClawRightSpotID, HotSpotID &moveClawLeftSpotID, HotSpotID &moveClawUpSpotID,
+ HotSpotID &clawCCWSpotID, HotSpotID &clawCWSpotID, uint32 &clawPosition, const uint32 *&clawExtraIDs) {
+ outSpotID = kNorad60MonitorOutSpotID;
+ prepSpotID = kNorad60LaunchPrepSpotID;
+ clawControlSpotID = kNorad60ClawControlSpotID;
+ pinchClawSpotID = kNorad60ClawPinchSpotID;
+ moveClawDownSpotID = kNorad60ClawDownSpotID;
+ moveClawRightSpotID = kNorad60ClawRightSpotID;
+ moveClawLeftSpotID = kNorad60ClawLeftSpotID;
+ moveClawUpSpotID = kNorad60ClawUpSpotID;
+ clawCCWSpotID = kNorad60ClawCCWSpotID;
+ clawCWSpotID = kNorad60ClawCWSpotID;
+ clawPosition = kClawAtC;
+ clawExtraIDs = _noradDeltaClawExtras;
+}
+
+void NoradDelta::playerBeatRobotWithDoor() {
+ GameState.setNoradBeatRobotWithDoor(true);
+ updateViewFrame();
+ GameState.setScoringStoppedNoradRobot(true);
+ g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN59WD", false, kWarningInterruption);
+}
+
+void NoradDelta::playerBeatRobotWithClaw() {
+ GameState.setNoradBeatRobotWithClaw(true);
+ updateViewFrame();
+ GameState.setScoringStoppedNoradRobot(true);
+ GameState.setScoringNoradGandhi(true);
+ g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN59WD", false, kWarningInterruption);
+}
+
+TimeValue NoradDelta::getViewTime(const RoomID room, const DirectionConstant direction) {
+ ExtraTable::Entry entry;
+
+ if (room == kNorad41 && direction == kSouth && !GameState.getNoradArrivedFromSub()) {
+ getExtraEntry(kArriveFromSubChase, entry);
+ return entry.movieStart;
+ }
+
+ if (GameState.getNoradBeatRobotWithDoor()) {
+ if (_privateFlags.getFlag(kNoradPrivateRobotHeadOpenFlag)) {
+ uint32 extraID = kN59Biochips111;
+ if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag))
+ extraID += 1;
+ if (_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag))
+ extraID += 2;
+ if (_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag))
+ extraID += 4;
+ getExtraEntry(extraID, entry);
+ return entry.movieStart;
+ }
+
+ getExtraEntry(kN59RobotHeadOpens, entry);
+ return entry.movieStart;
+ } else if (GameState.getNoradBeatRobotWithClaw()) {
+ if (_privateFlags.getFlag(kNoradPrivateRobotHeadOpenFlag)) {
+ uint32 extraID = kN60Biochips111;
+ if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag))
+ extraID += 1;
+ if (_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag))
+ extraID += 2;
+ if (_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag))
+ extraID += 4;
+ getExtraEntry(extraID, entry);
+ return entry.movieStart;
+ }
+
+ getExtraEntry(kN60RobotHeadOpens, entry);
+ return entry.movieStart;
+ }
+
+ return Norad::getViewTime(room, direction);
+}
+
+void NoradDelta::openDoor() {
+ if (GameState.getCurrentRoom() == kNorad59 && GameState.getCurrentDirection() == kWest && GameState.getNoradPlayedGlobeGame()) {
+ Input scratch;
+ InputHandler::_inputHandler->clickInHotspot(scratch, g_allHotspots.findHotspotByID(kNorad59WestSpotID));
+ } else {
+ Norad::openDoor();
+ }
+}
+
+void NoradDelta::activateHotspots() {
+ Norad::activateHotspots();
+
+ if (GameState.getCurrentRoom() == kNorad59West && GameState.getCurrentDirection() == kWest && GameState.getNoradBeatRobotWithDoor()) {
+ g_allHotspots.deactivateOneHotspot(kNorad59WestOutSpotID);
+
+ if (_privateFlags.getFlag(kNoradPrivateRobotHeadOpenFlag)) {
+ if (!_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag))
+ g_allHotspots.activateOneHotspot(kDelta59RobotShieldBiochipSpotID);
+ else
+ g_allHotspots.deactivateOneHotspot(kDelta59RobotShieldBiochipSpotID);
+
+ if (!_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag))
+ g_allHotspots.activateOneHotspot(kDelta59RobotOpMemBiochipSpotID);
+ else
+ g_allHotspots.deactivateOneHotspot(kDelta59RobotOpMemBiochipSpotID);
+
+ if (!_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag))
+ g_allHotspots.activateOneHotspot(kDelta59RobotRetinalBiochipSpotID);
+ else
+ g_allHotspots.deactivateOneHotspot(kDelta59RobotRetinalBiochipSpotID);
+ } else
+ g_allHotspots.activateOneHotspot(kDelta59RobotHeadSpotID);
+ } else if (GameState.getCurrentRoom() == kNorad60West && GameState.getCurrentDirection() == kWest &&
+ GameState.getNoradBeatRobotWithClaw()) {
+ g_allHotspots.deactivateOneHotspot(kNorad60MonitorOutSpotID);
+
+ if (_privateFlags.getFlag(kNoradPrivateRobotHeadOpenFlag)) {
+ if (!_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag))
+ g_allHotspots.activateOneHotspot(kDelta60RobotShieldBiochipSpotID);
+ else
+ g_allHotspots.deactivateOneHotspot(kDelta60RobotShieldBiochipSpotID);
+
+ if (!_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag))
+ g_allHotspots.activateOneHotspot(kDelta60RobotOpMemBiochipSpotID);
+ else
+ g_allHotspots.deactivateOneHotspot(kDelta60RobotOpMemBiochipSpotID);
+
+ if (!_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag))
+ g_allHotspots.activateOneHotspot(kDelta60RobotRetinalBiochipSpotID);
+ else
+ g_allHotspots.deactivateOneHotspot(kDelta60RobotRetinalBiochipSpotID);
+ } else {
+ g_allHotspots.activateOneHotspot(kDelta60RobotHeadSpotID);
+ }
+ } else if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad50, kEast)) {
+ if (GameState.isCurrentDoorOpen())
+ g_allHotspots.deactivateOneHotspot(kNorad50DoorSpotID);
+ } else if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad59, kWest)) {
+ if (GameState.isCurrentDoorOpen())
+ g_allHotspots.deactivateOneHotspot(kNorad59WestSpotID);
+ }
+}
+
+void NoradDelta::clickInHotspot(const Input &input, const Hotspot *clickedSpot) {
+ switch (clickedSpot->getObjectID()) {
+ case kDelta59RobotHeadSpotID:
+ startExtraSequence(kN59RobotHeadOpens, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case kDelta60RobotHeadSpotID:
+ startExtraSequence(kN60RobotHeadOpens, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ default:
+ Norad::clickInHotspot(input, clickedSpot);
+ break;
+ }
+}
+
+void NoradDelta::receiveNotification(Notification *notification, const NotificationFlags flags) {
+ Norad::receiveNotification(notification, flags);
+
+ if ((flags & kExtraCompletedFlag) != 0) {
+ RetScanChip *retScan;
+ Input dummy;
+
+ switch (_lastExtra) {
+ case kArriveFromSubChase:
+ GameState.setNoradArrivedFromSub(true);
+ GameState.setCurrentRoom(kNoRoomID);
+ GameState.setCurrentDirection(kNoDirection);
+ arriveAt(kNorad41, kEast);
+ break;
+ case kN59RobotHeadOpens:
+ case kN60RobotHeadOpens:
+ _privateFlags.setFlag(kNoradPrivateRobotHeadOpenFlag, true);
+ break;
+ case kNoradDeltaRetinalScanBad:
+ retScan = (RetScanChip *)_vm->getCurrentBiochip();
+ retScan->setItemState(kNormalItem);
+ playSpotSoundSync(kRetinalScanFailedIn, kRetinalScanFailedOut);
+ downButton(dummy);
+ break;
+ case kNoradDeltaRetinalScanGood:
+ retScan = (RetScanChip *)_vm->getCurrentBiochip();
+ retScan->setItemState(kNormalItem);
+ downButton(dummy);
+ break;
+ case kN59RobotDisappears:
+ case kN60RobotDisappears:
+ recallToTSASuccess();
+ break;
+ }
+
+ _interruptionFilter = kFilterAllInput;
+ }
+
+ g_AIArea->checkMiddleArea();
+}
+
+void NoradDelta::pickedUpItem(Item *item) {
+ switch (item->getObjectID()) {
+ case kShieldBiochip:
+ if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag) &&
+ _privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag) &&
+ _privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag)) {
+ GameState.setNoradFinished(true);
+
+ if (GameState.getCurrentRoom() == kNorad59West)
+ startExtraSequence(kN59RobotDisappears, kExtraCompletedFlag, kFilterNoInput);
+ else
+ startExtraSequence(kN60RobotDisappears, kExtraCompletedFlag, kFilterNoInput);
+ }
+ break;
+ case kRetinalScanBiochip:
+ if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag) &&
+ _privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag) &&
+ _privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag)) {
+ GameState.setNoradFinished(true);
+
+ if (GameState.getCurrentRoom() == kNorad59West)
+ startExtraSequence(kN59RobotDisappears, kExtraCompletedFlag, kFilterNoInput);
+ else
+ startExtraSequence(kN60RobotDisappears, kExtraCompletedFlag, kFilterNoInput);
+ }
+ break;
+ case kOpticalBiochip:
+ g_opticalChip->addPoseidon();
+ GameState.setScoringGotNoradOpMemChip();
+
+ if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag) &&
+ _privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag) &&
+ _privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag)) {
+ GameState.setNoradFinished(true);
+
+ if (GameState.getCurrentRoom() == kNorad59West)
+ startExtraSequence(kN59RobotDisappears, kExtraCompletedFlag, kFilterNoInput);
+ else
+ startExtraSequence(kN60RobotDisappears, kExtraCompletedFlag, kFilterNoInput);
+ }
+ break;
+ }
+
+ Norad::pickedUpItem(item);
+}
+
+void NoradDelta::takeItemFromRoom(Item *item) {
+ switch (item->getObjectID()) {
+ case kShieldBiochip:
+ _privateFlags.setFlag(kNoradPrivateGotShieldChipFlag, true);
+ break;
+ case kRetinalScanBiochip:
+ _privateFlags.setFlag(kNoradPrivateGotRetScanChipFlag, true);
+ break;
+ case kOpticalBiochip:
+ _privateFlags.setFlag(kNoradPrivateGotOpticalChipFlag, true);
+ break;
+ }
+
+ Norad::takeItemFromRoom(item);
+}
+
+void NoradDelta::dropItemIntoRoom(Item *item, Hotspot *hotspot) {
+ switch (item->getObjectID()) {
+ case kShieldBiochip:
+ _privateFlags.setFlag(kNoradPrivateGotShieldChipFlag, false);
+ break;
+ case kOpticalBiochip:
+ _privateFlags.setFlag(kNoradPrivateGotOpticalChipFlag, false);
+ break;
+ case kRetinalScanBiochip:
+ _privateFlags.setFlag(kNoradPrivateGotRetScanChipFlag, false);
+ break;
+ }
+
+ Norad::dropItemIntoRoom(item, hotspot);
+}
+
+Hotspot *NoradDelta::getItemScreenSpot(Item *item, DisplayElement *element) {
+ HotSpotID id = kNoHotSpotID;
+
+ switch (item->getObjectID()) {
+ case kShieldBiochip:
+ if (GameState.getNoradBeatRobotWithDoor())
+ id = kDelta59RobotShieldBiochipSpotID;
+ else
+ id = kDelta60RobotShieldBiochipSpotID;
+ break;
+ case kOpticalBiochip:
+ if (GameState.getNoradBeatRobotWithDoor())
+ id = kDelta59RobotOpMemBiochipSpotID;
+ else
+ id = kDelta60RobotOpMemBiochipSpotID;
+ break;
+ case kRetinalScanBiochip:
+ if (GameState.getNoradBeatRobotWithDoor())
+ id = kDelta59RobotRetinalBiochipSpotID;
+ else
+ id = kDelta60RobotRetinalBiochipSpotID;
+ break;
+ }
+
+ if (id != kNoHotSpotID)
+ return g_allHotspots.findHotspotByID(id);
+
+ return Norad::getItemScreenSpot(item, element);
+}
+
+Common::String NoradDelta::getEnvScanMovie() {
+ return "Images/AI/Norad/XNE2";
+}
+
+uint NoradDelta::getNumHints() {
+ uint numHints = Neighborhood::getNumHints();
+
+ if (numHints == 0) {
+ switch (GameState.getCurrentRoomAndView()) {
+ case MakeRoomView(kNorad60, kWest):
+ if (GameState.getNoradPlayedGlobeGame())
+ numHints = 2;
+ else
+ numHints = 1;
+ break;
+ case MakeRoomView(kNorad59, kNorth):
+ case MakeRoomView(kNorad59, kSouth):
+ case MakeRoomView(kNorad59, kEast):
+ case MakeRoomView(kNorad59, kWest):
+ case MakeRoomView(kNorad60, kNorth):
+ case MakeRoomView(kNorad60, kSouth):
+ case MakeRoomView(kNorad60, kEast):
+ if (GameState.getNoradPlayedGlobeGame())
+ numHints = 2;
+ break;
+ case MakeRoomView(kNorad68, kWest):
+ if (_vm->playerHasItemID(kRetinalScanBiochip)) {
+ BiochipItem *retScan = _vm->getCurrentBiochip();
+ if (retScan == 0 || retScan->getObjectID() != kRetinalScanBiochip)
+ numHints = 2;
+ } else if (!GameState.isCurrentDoorOpen()) {
+ numHints = 2;
+ }
+ break;
+ }
+ }
+
+ return numHints;
+}
+
+Common::String NoradDelta::getHintMovie(uint hintNum) {
+ Common::String movieName = Neighborhood::getHintMovie(hintNum);
+
+ if (movieName.empty()) {
+ switch (GameState.getCurrentRoomAndView()) {
+ case MakeRoomView(kNorad60, kWest):
+ if (GameState.getNoradPlayedGlobeGame()) {
+ if (hintNum == 1)
+ return "Images/AI/Norad/XN60WD2";
+
+ return "Images/AI/Norad/XN60WD3";
+ }
+
+ return "Images/AI/Globals/XGLOB1C";
+ case MakeRoomView(kNorad59, kNorth):
+ case MakeRoomView(kNorad59, kSouth):
+ case MakeRoomView(kNorad59, kEast):
+ case MakeRoomView(kNorad59, kWest):
+ case MakeRoomView(kNorad60, kNorth):
+ case MakeRoomView(kNorad60, kSouth):
+ case MakeRoomView(kNorad60, kEast):
+ if (hintNum == 1)
+ return "Images/AI/Norad/XN60WD2";
+
+ return "Images/AI/Norad/XN60WD3";
+ case MakeRoomView(kNorad68, kWest):
+ if (_vm->playerHasItemID(kRetinalScanBiochip)) {
+ if (hintNum == 1)
+ return "Images/AI/Globals/XGLOB1A";
+
+ return "Images/AI/Globals/XGLOB1C";
+ }
+
+ if (hintNum == 1)
+ return "Images/AI/Globals/XGLOB1B";
+
+ return "Images/AI/Globals/XGLOB3B";
+ }
+ }
+
+ return movieName;
+}
+
+void NoradDelta::closeDoorOffScreen(const RoomID room, const DirectionConstant) {
+ switch (room) {
+ case kNorad47:
+ case kNorad48:
+ case kNorad41:
+ case kNorad42:
+ playSpotSoundSync(kDeltaElevatorDoorCloseIn, kDeltaElevatorDoorCloseOut);
+ break;
+ default:
+ playSpotSoundSync(kDeltaRegDoorCloseIn, kDeltaRegDoorCloseOut);
+ break;
+ }
+}
+
+bool NoradDelta::canSolve() {
+ if (Norad::canSolve())
+ return true;
+
+ if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad68, kWest)) {
+ BiochipItem *biochip = _vm->getCurrentBiochip();
+ if (biochip != 0 && biochip->getObjectID() != kRetinalScanBiochip)
+ return true;
+ }
+
+ return false;
+}
+
+void NoradDelta::doSolve() {
+ Norad::doSolve();
+
+ if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad68, kWest)) {
+ if (!_vm->playerHasItemID(kRetinalScanBiochip))
+ _vm->addItemToBiochips((BiochipItem *)g_allItems.findItemByID(kRetinalScanBiochip));
+
+ BiochipItem *biochip = _vm->getCurrentBiochip();
+ if (biochip != 0 && biochip->getObjectID() != kRetinalScanBiochip && g_interface)
+ g_interface->setCurrentBiochipID(kRetinalScanBiochip);
+
+ Hotspot *spot = g_allHotspots.findHotspotByID(kNorad68WestSpotID);
+ Input scratch;
+ InputHandler::_inputHandler->clickInHotspot(scratch, spot);
+ }
+}
+
+Common::String NoradDelta::getSoundSpotsName() {
+ return "Sounds/Norad/Norad Delta Spots";
+}
+
+Common::String NoradDelta::getNavMovieName() {
+ return "Images/Norad Delta/Norad Delta.movie";
+}
+
+} // End of namespace Pegasus