aboutsummaryrefslogtreecommitdiff
path: root/engines/pegasus/neighborhood
diff options
context:
space:
mode:
authorMatthew Hoops2011-10-13 20:59:20 -0400
committerMatthew Hoops2011-10-13 20:59:20 -0400
commit753006ae1a89d2e54477e3782e72c187d90d4083 (patch)
tree6f9f9521e3f78f188cbb674078bda7d050500db8 /engines/pegasus/neighborhood
parent13fef21fed3631af3c8ebc5c34ccaf2d077af983 (diff)
downloadscummvm-rg350-753006ae1a89d2e54477e3782e72c187d90d4083.tar.gz
scummvm-rg350-753006ae1a89d2e54477e3782e72c187d90d4083.tar.bz2
scummvm-rg350-753006ae1a89d2e54477e3782e72c187d90d4083.zip
PEGASUS: Add the WSC neighborhood
Seems to be working fine, minus the molecule sprites (though the minigame is completable and the antidote can be found).
Diffstat (limited to 'engines/pegasus/neighborhood')
-rwxr-xr-xengines/pegasus/neighborhood/tsa/fulltsa.cpp1
-rwxr-xr-xengines/pegasus/neighborhood/tsa/tinytsa.cpp1
-rwxr-xr-xengines/pegasus/neighborhood/wsc/moleculebin.cpp127
-rwxr-xr-xengines/pegasus/neighborhood/wsc/moleculebin.h72
-rwxr-xr-xengines/pegasus/neighborhood/wsc/wsc.cpp2544
-rwxr-xr-xengines/pegasus/neighborhood/wsc/wsc.h163
6 files changed, 2908 insertions, 0 deletions
diff --git a/engines/pegasus/neighborhood/tsa/fulltsa.cpp b/engines/pegasus/neighborhood/tsa/fulltsa.cpp
index 51404b47c6..e5508ba9a9 100755
--- a/engines/pegasus/neighborhood/tsa/fulltsa.cpp
+++ b/engines/pegasus/neighborhood/tsa/fulltsa.cpp
@@ -33,6 +33,7 @@
#include "pegasus/neighborhood/caldoria/caldoria.h"
#include "pegasus/neighborhood/prehistoric/prehistoric.h"
#include "pegasus/neighborhood/tsa/fulltsa.h"
+#include "pegasus/neighborhood/wsc/wsc.h"
namespace Pegasus {
diff --git a/engines/pegasus/neighborhood/tsa/tinytsa.cpp b/engines/pegasus/neighborhood/tsa/tinytsa.cpp
index fa611bd4d7..419ecba034 100755
--- a/engines/pegasus/neighborhood/tsa/tinytsa.cpp
+++ b/engines/pegasus/neighborhood/tsa/tinytsa.cpp
@@ -30,6 +30,7 @@
#include "pegasus/items/biochips/aichip.h"
#include "pegasus/items/biochips/opticalchip.h"
#include "pegasus/neighborhood/tsa/tinytsa.h"
+#include "pegasus/neighborhood/wsc/wsc.h"
namespace Pegasus {
diff --git a/engines/pegasus/neighborhood/wsc/moleculebin.cpp b/engines/pegasus/neighborhood/wsc/moleculebin.cpp
new file mode 100755
index 0000000000..87850055d7
--- /dev/null
+++ b/engines/pegasus/neighborhood/wsc/moleculebin.cpp
@@ -0,0 +1,127 @@
+/* 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/graphics.h"
+#include "pegasus/neighborhood/wsc/moleculebin.h"
+#include "pegasus/neighborhood/wsc/wsc.h"
+
+namespace Pegasus {
+
+static const tCoordType kMoleculeBinWidth = 138;
+static const tCoordType kMoleculeBinHeight = 128;
+
+static const tCoordType kMoleculeWidth = 66;
+static const tCoordType kMoleculeHeight = 40;
+
+static const tCoordType kMoleculeBinLeft = kNavAreaLeft + 286;
+static const tCoordType kMoleculeBinTop = kNavAreaLeft + 96;
+
+// Layouts:
+
+MoleculeBin::MoleculeBin() : DisplayElement(kNoDisplayElement) {
+ _highlightColor = g_system->getScreenFormat().RGBToColor(0xff, 0xff, 102);
+ _selectedMolecule = -1;
+}
+
+void MoleculeBin::initMoleculeBin() {
+ if (!isDisplaying()) {
+ for (int i = 0; i < 6; i++)
+ _binLayout[i] = i;
+
+ resetBin();
+ _binImages.getImageFromPICTFile("Images/World Science Center/Molecules");
+ setDisplayOrder(kWSCMoleculeBinOrder);
+ setBounds(kMoleculeBinLeft, kMoleculeBinTop, kMoleculeBinLeft + kMoleculeBinWidth,
+ kMoleculeBinTop + kMoleculeBinHeight);
+ startDisplaying();
+ show();
+ }
+}
+
+void MoleculeBin::cleanUpMoleculeBin() {
+ if (isDisplaying()) {
+ stopDisplaying();
+ _binImages.deallocateSurface();
+ }
+}
+
+void MoleculeBin::setBinLayout(const uint32 *layout) {
+ for (int i = 0; i < 6; i++)
+ _binLayout[i] = layout[i];
+}
+
+void MoleculeBin::highlightMolecule(const uint32 whichMolecule) {
+ if (!_moleculeFlags.getFlag(whichMolecule)) {
+ _moleculeFlags.setFlag(whichMolecule, true);
+ triggerRedraw();
+ }
+}
+
+bool MoleculeBin::isMoleculeHighlighted(uint32 whichMolecule) {
+ return _moleculeFlags.getFlag(whichMolecule);
+}
+
+void MoleculeBin::selectMolecule(const int whichMolecule) {
+ if (_selectedMolecule != whichMolecule) {
+ _selectedMolecule = whichMolecule;
+ triggerRedraw();
+ }
+}
+
+void MoleculeBin::resetBin() {
+ _moleculeFlags.clearAllFlags();
+ _selectedMolecule = -1;
+ triggerRedraw();
+}
+
+void MoleculeBin::draw(const Common::Rect &) {
+ Common::Rect r1(0, 0, kMoleculeWidth, kMoleculeHeight);
+ Common::Rect r2 = r1;
+
+ for (int i = 0; i < 6; i++) {
+ r1.moveTo(i * (kMoleculeWidth * 2), 0);
+
+ if (_moleculeFlags.getFlag(_binLayout[i]))
+ r1.translate(kMoleculeWidth, 0);
+
+ r1.moveTo((_binLayout[i] & 1) * (kMoleculeWidth + 2) + _bounds.left + 2,
+ (_binLayout[i] >> 1) * (kMoleculeHeight + 2) + _bounds.top + 2);
+
+ _binImages.copyToCurrentPort(r1, r2);
+ }
+
+ if (_selectedMolecule >= 0) {
+ r2.moveTo((_selectedMolecule & 1) * (kMoleculeWidth + 2) + _bounds.left + 2,
+ (_selectedMolecule >> 1) * (kMoleculeHeight + 2) + _bounds.top + 2);
+
+ Graphics::Surface *screen = ((PegasusEngine *)g_engine)->_gfx->getWorkArea();
+
+ screen->frameRect(r2, _highlightColor);
+ r2.grow(1);
+ screen->frameRect(r2, _highlightColor);
+ }
+}
+
+} // End of namespace Pegasus
diff --git a/engines/pegasus/neighborhood/wsc/moleculebin.h b/engines/pegasus/neighborhood/wsc/moleculebin.h
new file mode 100755
index 0000000000..3de4b5ed2a
--- /dev/null
+++ b/engines/pegasus/neighborhood/wsc/moleculebin.h
@@ -0,0 +1,72 @@
+/* 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.
+ *
+ */
+
+#ifndef PEGASUS_NEIGHBORHOOD_WSC_MOLECULEBIN_H
+#define PEGASUS_NEIGHBORHOOD_WSC_MOLECULEBIN_H
+
+#include "pegasus/elements.h"
+#include "pegasus/surface.h"
+#include "pegasus/util.h"
+
+namespace Pegasus {
+
+enum {
+ kMolecule1,
+ kMolecule2,
+ kMolecule3,
+ kMolecule4,
+ kMolecule5,
+ kMolecule6
+};
+
+class MoleculeBin : public DisplayElement {
+public:
+ MoleculeBin();
+ virtual ~MoleculeBin() {}
+
+ void initMoleculeBin();
+ void cleanUpMoleculeBin();
+
+ void setBinLayout(const uint32 *);
+
+ void highlightMolecule(const uint32 whichMolecule);
+ void selectMolecule(const int whichMolecule);
+ void resetBin();
+
+ bool isMoleculeHighlighted(uint32);
+
+protected:
+ void draw(const Common::Rect &);
+
+ Surface _binImages;
+ FlagsArray<byte, kMolecule6 + 1> _moleculeFlags;
+ int _selectedMolecule;
+ uint32 _binLayout[6];
+ uint32 _highlightColor;
+};
+
+} // End of namespace Pegasus
+
+#endif
diff --git a/engines/pegasus/neighborhood/wsc/wsc.cpp b/engines/pegasus/neighborhood/wsc/wsc.cpp
new file mode 100755
index 0000000000..82fbdb815c
--- /dev/null
+++ b/engines/pegasus/neighborhood/wsc/wsc.cpp
@@ -0,0 +1,2544 @@
+/* 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/pegasus.h"
+#include "pegasus/ai/ai_area.h"
+#include "pegasus/items/biochips/opticalchip.h"
+#include "pegasus/items/biochips/shieldchip.h"
+#include "pegasus/neighborhood/wsc/wsc.h"
+
+namespace Pegasus {
+
+const tCanMoveForwardReason kCantMoveWatchingDiagnosis = kCantMoveLastReason + 1;
+
+const tCanTurnReason kCantTurnWatchingDiagnosis = kCantTurnLastReason + 1;
+const tCanTurnReason kCantTurnWatchingAnalysis = kCantTurnWatchingDiagnosis + 1;
+const tCanTurnReason kCantTurnInMoleculeGame = kCantTurnWatchingAnalysis + 1;
+
+const TimeScale kMoleculesMovieScale = 600;
+const TimeValue kMoleculeLoopTime = 4 * kMoleculesMovieScale;
+const TimeValue kMoleculeFailTime = 2 * kMoleculesMovieScale;
+
+enum {
+ kMoleculeLoop0Time = 0,
+ kMoleculeFail0Time = kMoleculeLoop0Time + kMoleculeLoopTime,
+ kMoleculeLoop1Time = kMoleculeFail0Time + kMoleculeFailTime,
+ kMoleculeFail1Time = kMoleculeLoop1Time + kMoleculeLoopTime,
+ kMoleculeLoop2Time = kMoleculeFail1Time + kMoleculeFailTime,
+ kMoleculeFail2Time = kMoleculeLoop2Time + kMoleculeLoopTime,
+ kMoleculeLoop3Time = kMoleculeFail2Time + kMoleculeFailTime,
+ kMoleculeFail3Time = kMoleculeLoop3Time + kMoleculeLoopTime,
+ kMoleculeLoop4Time = kMoleculeFail3Time + kMoleculeFailTime,
+ kMoleculeFail4Time = kMoleculeLoop4Time + kMoleculeLoopTime,
+ kMoleculeLoop5Time = kMoleculeFail4Time + kMoleculeFailTime,
+ kMoleculeFail5Time = kMoleculeLoop5Time + kMoleculeLoopTime,
+ kMoleculeLoop6Time = kMoleculeFail5Time + kMoleculeFailTime
+};
+
+const TimeValue s_moleculeLoopTimes[] = {
+ kMoleculeLoop0Time,
+ kMoleculeLoop1Time,
+ kMoleculeLoop2Time,
+ kMoleculeLoop3Time,
+ kMoleculeLoop4Time,
+ kMoleculeLoop5Time,
+ kMoleculeLoop6Time
+};
+
+const TimeValue s_moleculeFailTimes[] = {
+ kMoleculeFail0Time,
+ kMoleculeFail1Time,
+ kMoleculeFail2Time,
+ kMoleculeFail3Time,
+ kMoleculeFail4Time,
+ kMoleculeFail5Time
+};
+
+const short kAuditoriumAngleOffset = 5;
+
+const long kPlasmaEnergyWithShield = kMaxJMPEnergy * 10 / 100;
+const long kPlasmaEnergyNoShield = kMaxJMPEnergy * 20 / 100;
+
+const long kTimerEventPlasmaHit = 0;
+const long kTimerEventPlayerGawkingAtRobot = 1;
+const long kTimerEventPlayerGawkingAtRobot2 = 2;
+
+const TimeValue kWSCMolecule1In = 0;
+const TimeValue kWSCMolecule1Out = 937;
+
+const TimeValue kWSCMolecule2In = 937;
+const TimeValue kWSCMolecule2Out = 1864;
+
+const TimeValue kWSCMolecule3In = 1864;
+const TimeValue kWSCMolecule3Out = 2790;
+
+const TimeValue kWSCClick1In = 2790;
+const TimeValue kWSCClick1Out = 2890;
+
+const TimeValue kWSCClick2In = 2890;
+const TimeValue kWSCClick2Out = 3059;
+
+const TimeValue kWSCClick3In = 3059;
+const TimeValue kWSCClick3Out = 3156;
+
+const TimeValue kWSCFlashlightClickIn = 3156;
+const TimeValue kWSCFlashlightClickOut = 3211;
+
+const TimeValue kWSCBumpIntoWallIn = 3211;
+const TimeValue kWSCBumpIntoWallOut = 3514;
+
+const TimeValue kWSCCantTransportIn = 3514;
+const TimeValue kWSCCantTransportOut = 7791;
+
+const TimeValue kHernandezNotHomeIn = 7791;
+const TimeValue kHernandezNotHomeOut = 10199;
+
+const TimeValue kWashingtonNotHomeIn = 10199;
+const TimeValue kWashingtonNotHomeOut = 12649;
+
+const TimeValue kSullivanNotHomeIn = 12649;
+const TimeValue kSullivanNotHomeOut = 15031;
+
+const TimeValue kNakamuraNotHomeIn = 15031;
+const TimeValue kNakamuraNotHomeOut = 17545;
+
+const TimeValue kGrailisNotHomeIn = 17545;
+const TimeValue kGrailisNotHomeOut = 19937;
+
+const TimeValue kTheriaultNotHomeIn = 19937;
+const TimeValue kTheriaultNotHomeOut = 22395;
+
+const TimeValue kGlennerNotHomeIn = 22395;
+const TimeValue kGlennerNotHomeOut = 24770;
+
+const TimeValue kSinclairNotHomeIn = 24770;
+const TimeValue kSinclairNotHomeOut = 27328;
+
+const TimeValue kWSCLabClosedIn = 27328;
+const TimeValue kWSCLabClosedOut = 28904;
+
+const TimeValue kSlidingDoorCloseIn = 28904;
+const TimeValue kSlidingDoorCloseOut = 29295;
+
+const TimeValue kSlimyDoorCloseIn = 29295;
+const TimeValue kSlimyDoorCloseOut = 29788;
+
+const TimeValue kPaging1In = 29788;
+const TimeValue kPaging1Out = 32501;
+
+const TimeValue kPaging2In = 32501;
+const TimeValue kPaging2Out = 34892;
+
+const TimeValue kCheckInIn = 34892;
+const TimeValue kCheckInOut = 37789;
+
+const TimeValue kDrinkAntidoteIn = 37789;
+const TimeValue kDrinkAntidoteOut = 39725;
+
+const TimeScale kWSCMovieScale = 600;
+const TimeScale kWSCFramesPerSecond = 15;
+const TimeScale kWSCFrameDuration = 40;
+
+// Alternate IDs.
+
+const tAlternateID kAltWSCNormal = 0;
+const tAlternateID kAltWSCTookMachineGun = 1;
+const tAlternateID kAltWSCW0ZDoorOpen = 2;
+const tAlternateID kAltWSCPeopleAtW19North = 3;
+
+// Room IDs.
+
+const tRoomID kWSC02 = 1;
+const tRoomID kWSC02Morph = 2;
+const tRoomID kWSC02Messages = 3;
+const tRoomID kWSC03 = 4;
+const tRoomID kWSC04 = 5;
+const tRoomID kWSC06 = 6;
+const tRoomID kWSC07 = 7;
+const tRoomID kWSC08 = 8;
+const tRoomID kWSC09 = 9;
+const tRoomID kWSC10 = 10;
+const tRoomID kWSC11 = 11;
+const tRoomID kWSC13 = 12;
+const tRoomID kWSC14 = 13;
+const tRoomID kWSC15 = 14;
+const tRoomID kWSC16 = 15;
+const tRoomID kWSC17 = 16;
+const tRoomID kWSC18 = 17;
+const tRoomID kWSC19 = 18;
+const tRoomID kWSC20 = 19;
+const tRoomID kWSC21 = 20;
+const tRoomID kWSC22 = 21;
+const tRoomID kWSC23 = 22;
+const tRoomID kWSC24 = 23;
+const tRoomID kWSC25 = 24;
+const tRoomID kWSC26 = 25;
+const tRoomID kWSC27 = 26;
+const tRoomID kWSC28 = 27;
+const tRoomID kWSC29 = 28;
+const tRoomID kWSC31 = 29;
+const tRoomID kWSC32 = 30;
+const tRoomID kWSC33 = 31;
+const tRoomID kWSC34 = 32;
+const tRoomID kWSC35 = 33;
+const tRoomID kWSC36 = 34;
+const tRoomID kWSC37 = 35;
+const tRoomID kWSC38 = 36;
+const tRoomID kWSC39 = 37;
+const tRoomID kWSC40 = 38;
+const tRoomID kWSC41 = 39;
+const tRoomID kWSC42 = 40;
+const tRoomID kWSC43 = 41;
+const tRoomID kWSC44 = 42;
+const tRoomID kWSC45 = 43;
+const tRoomID kWSC46 = 44;
+const tRoomID kWSC47 = 45;
+const tRoomID kWSC48 = 46;
+const tRoomID kWSC49 = 47;
+const tRoomID kWSC50 = 48;
+const tRoomID kWSC52 = 49;
+const tRoomID kWSC53 = 50;
+const tRoomID kWSC54 = 51;
+const tRoomID kWSC55 = 52;
+const tRoomID kWSC56 = 53;
+const tRoomID kWSC57 = 54;
+const tRoomID kWSC58 = 55;
+const tRoomID kWSC60 = 56;
+const tRoomID kWSC60East = 57;
+const tRoomID kWSC60North = 58;
+const tRoomID kWSC61 = 59;
+const tRoomID kWSC61South = 60;
+const tRoomID kWSC61West = 61;
+const tRoomID kWSC62 = 62;
+const tRoomID kWSC63 = 63;
+const tRoomID kWSC64 = 64;
+const tRoomID kWSC65 = 65;
+const tRoomID kWSC65Screen = 66;
+const tRoomID kWSC66 = 67;
+const tRoomID kWSC67 = 68;
+const tRoomID kWSC68 = 69;
+const tRoomID kWSC69 = 70;
+const tRoomID kWSC70 = 71;
+const tRoomID kWSC71 = 72;
+const tRoomID kWSC72 = 73;
+const tRoomID kWSC73 = 74;
+const tRoomID kWSC74 = 75;
+const tRoomID kWSC75 = 76;
+const tRoomID kWSC0Z = 77;
+const tRoomID kWSC76 = 78;
+const tRoomID kWSC77 = 79;
+const tRoomID kWSC78 = 80;
+const tRoomID kWSC79 = 81;
+const tRoomID kWSC80 = 82;
+const tRoomID kWSC81 = 83;
+const tRoomID kWSC82 = 84;
+const tRoomID kWSC83 = 85;
+const tRoomID kWSC84 = 86;
+const tRoomID kWSC85 = 87;
+const tRoomID kWSC86 = 88;
+const tRoomID kWSC87 = 89;
+const tRoomID kWSC88 = 90;
+const tRoomID kWSC89 = 91;
+const tRoomID kWSC90 = 92;
+const tRoomID kWSC91 = 93;
+const tRoomID kWSC92 = 94;
+const tRoomID kWSC93 = 95;
+const tRoomID kWSC94 = 96;
+const tRoomID kWSC95 = 97;
+const tRoomID kWSC96 = 98;
+const tRoomID kWSC97 = 99;
+const tRoomID kWSC98 = 100;
+const tRoomID kWSCDeathRoom = 101;
+
+// Hot Spot Activation IDs.
+
+const tHotSpotActivationID kActivationZoomedInToAnalyzer = 1;
+const tHotSpotActivationID kActivationShotByRobot = 2;
+const tHotSpotActivationID kActivationWarnedAboutPoison = 3;
+const tHotSpotActivationID kActivationMorphScreenOff = 4;
+const tHotSpotActivationID kActivationReadyForMorph = 5;
+const tHotSpotActivationID kActivationMorphLooping = 6;
+const tHotSpotActivationID kActivationMorphInterrupted = 7;
+const tHotSpotActivationID kActivationW03NorthOff = 8;
+const tHotSpotActivationID kActivationW03NorthReadyForInstructions = 9;
+const tHotSpotActivationID kActivationW03NorthSawInstructions = 10;
+const tHotSpotActivationID kActivationW03NorthInGame = 11;
+const tHotSpotActivationID kActivationReadyForSynthesis = 12;
+const tHotSpotActivationID kActivationSynthesizerLooping = 13;
+const tHotSpotActivationID kActivationReadyForMap = 14;
+const tHotSpotActivationID kActivationSinclairOfficeLocked = 15;
+const tHotSpotActivationID kActivationW58SouthDoorLocked = 16;
+const tHotSpotActivationID kActivationW61SouthOff = 17;
+const tHotSpotActivationID kActivationW61SouthOn = 18;
+const tHotSpotActivationID kActivationW61MessagesOff = 19;
+const tHotSpotActivationID kActivationW61MessagesOn = 20;
+const tHotSpotActivationID kActivationWSCRobotHeadOpen = 21;
+const tHotSpotActivationID kActivationRobotTurning = 22;
+const tHotSpotActivationID kActivationRobotDead = 23;
+const tHotSpotActivationID kActivationRobotGone = 24;
+
+// Hot Spot IDs.
+
+const tHotSpotID kWSCDropDartSpotID = 5000;
+const tHotSpotID kWSCTurnOnAnalyzerSpotID = 5001;
+const tHotSpotID kWSCAnalyzerScreenSpotID = 5002;
+const tHotSpotID kWSCSpinRobotSpotID = 5003;
+const tHotSpotID kWSC01YesSpotID = 5004;
+const tHotSpotID kWSC01NoSpotID = 5005;
+const tHotSpotID kWSC01AcknowledgeWarningSpotID = 5006;
+const tHotSpotID kWSC02SouthMorphSpotID = 5007;
+const tHotSpotID kWSC02SouthMessagesSpotID = 5008;
+const tHotSpotID kWSC02SouthMorphOutSpotID = 5009;
+const tHotSpotID kWSC02ActivateMorphScreenSpotID = 5010;
+const tHotSpotID kWSC02SouthStartMorphSpotID = 5011;
+const tHotSpotID kWSC02SouthInterruptMorphSpotID = 5012;
+const tHotSpotID kWSC02SouthMorphFinishedSpotID = 5013;
+const tHotSpotID kWSC02SouthTakeArgonSpotID = 5014;
+const tHotSpotID kWSC02SouthMessagesOutSpotID = 5015;
+const tHotSpotID kWSC02SouthTakeNitrogenSpotID = 5016;
+const tHotSpotID kWSC02SouthPlayMessagesSpotID = 5017;
+const tHotSpotID kWSC03NorthActivateScreenSpotID = 5018;
+const tHotSpotID kWSC03NorthBuildMoleculeSpotID = 5019;
+const tHotSpotID kWSC03NorthProceedSpotID = 5020;
+const tHotSpotID kWSC03NorthMolecule1SpotID = 5021;
+const tHotSpotID kWSC03NorthMolecule2SpotID = 5022;
+const tHotSpotID kWSC03NorthMolecule3SpotID = 5023;
+const tHotSpotID kWSC03NorthMolecule4SpotID = 5024;
+const tHotSpotID kWSC03NorthMolecule5SpotID = 5025;
+const tHotSpotID kWSC03NorthMolecule6SpotID = 5026;
+const tHotSpotID kWSC03SouthActivateSynthesizerSpotID = 5027;
+const tHotSpotID kWSC03SouthPickUpAntidoteSpotID = 5028;
+const tHotSpotID kWSC07SouthMapSpotID = 5029;
+const tHotSpotID kW42EastUnlockDoorSpotID = 5030;
+const tHotSpotID kW56NorthMapSpotID = 5031;
+const tHotSpotID kW58SouthPryDoorSpotID = 5032;
+const tHotSpotID kWSC60EastSpotID = 5033;
+const tHotSpotID kWSC60NorthSpotID = 5034;
+const tHotSpotID kWSC60EastOutSpotID = 5035;
+const tHotSpotID kWSC60NorthOutSpotID = 5036;
+const tHotSpotID kWSC61EastSpotID = 5037;
+const tHotSpotID kWSC61SouthSpotID = 5038;
+const tHotSpotID kW61SouthMachineGunSpotID = 5039;
+const tHotSpotID kW61SouthDropMachineGunSpotID = 5040;
+const tHotSpotID kWSC61WestSpotID = 5041;
+const tHotSpotID kWSC61SouthOutSpotID = 5042;
+const tHotSpotID kW61SouthActivateSpotID = 5043;
+const tHotSpotID kW61SmartAlloysSpotID = 5044;
+const tHotSpotID kW61MorphingSpotID = 5045;
+const tHotSpotID kW61TimeBendingSpotID = 5046;
+const tHotSpotID kWSC61WestOutSpotID = 5047;
+const tHotSpotID kW61TurnOnMessagesSpotID = 5048;
+const tHotSpotID kW61WhiteMessageSpotID = 5049;
+const tHotSpotID kW61WalchekMessageSpotID = 5050;
+const tHotSpotID kWSC65SouthScreenSpotID = 5051;
+const tHotSpotID kWSC65SouthScreenOutSpotID = 5052;
+const tHotSpotID kW98RetinalChipSpotID = 5053;
+const tHotSpotID kW98MapChipSpotID = 5054;
+const tHotSpotID kW98OpticalChipSpotID = 5055;
+const tHotSpotID kW98DropArgonSpotID = 5056;
+const tHotSpotID kW98GrabCableSpotID = 5057;
+const tHotSpotID kW98OpenRobotSpotID = 5058;
+const tHotSpotID kW98StunGunSpotID = 5059;
+
+// Extra sequence IDs.
+
+const tExtraID kWSCArrivalFromTSA = 0;
+const tExtraID kWSCShotByRobot = 1;
+const tExtraID kWSCDartScan1 = 2;
+const tExtraID kWSCDartScan2 = 3;
+const tExtraID kWSCDartScanNo = 4;
+const tExtraID kWSCDartScan3 = 5;
+const tExtraID kWSCAnalyzerPowerUp = 6;
+const tExtraID kWSCAnalyzerPowerUpWithDart = 7;
+const tExtraID kWSCDropDartIntoAnalyzer = 8;
+const tExtraID kWSCAnalyzeDart = 9;
+const tExtraID kWSCZoomOutFromAnalyzer = 10;
+const tExtraID kWSCSpinRobot = 11;
+const tExtraID kWSC02MorphZoomNoArgon = 12;
+const tExtraID kWSC02MessagesZoomNoNitrogen = 13;
+const tExtraID kWSC02ZoomOutNoArgon = 14;
+const tExtraID kWSC02TurnOnMorphScreen = 15;
+const tExtraID kWSC02DropToMorphExperiment = 16;
+const tExtraID kWSC02MorphLoop = 17;
+const tExtraID kWSC02MorphInterruption = 18;
+const tExtraID kWSC02MorphFinished = 19;
+const tExtraID kWSC02TurnOffMorphScreen = 20;
+const tExtraID kWSC02SouthViewNoArgon = 21;
+const tExtraID kMessagesMovedToOffice = 22;
+const tExtraID kMessagesOff = 23;
+const tExtraID kMessagesZoomOutNoNitrogen = 24;
+const tExtraID kMessagesMovedToOfficeNoNitrogen = 25;
+const tExtraID kMessagesOffNoNitrogen = 26;
+const tExtraID kMessagesViewNoNitrogen = 27;
+const tExtraID kMessagesViewMachineOnNoNitrogen = 28;
+const tExtraID kW03NorthActivate = 29;
+const tExtraID kW03NorthGetData = 30;
+const tExtraID kW03NorthInstructions = 31;
+const tExtraID kW03NorthPrepMolecule1 = 32;
+const tExtraID kW03NorthPrepMolecule2 = 33;
+const tExtraID kW03NorthPrepMolecule3 = 34;
+const tExtraID kW03NorthFinishSynthesis = 35;
+const tExtraID kW03SouthCreateAntidote = 36;
+const tExtraID kW03SouthAntidoteLoop = 37;
+const tExtraID kW03SouthDeactivate = 38;
+const tExtraID kW03SouthViewNoAntidote = 39;
+const tExtraID kWSC07SouthMap = 40;
+const tExtraID kW17WestPeopleCrossing = 41;
+const tExtraID kW17WestPeopleCrossingView = 42;
+const tExtraID kW21SouthPeopleCrossing = 43;
+const tExtraID kW24SouthPeopleCrossing = 44;
+const tExtraID kW34EastPeopleCrossing = 45;
+const tExtraID kW36WestPeopleCrossing = 46;
+const tExtraID kW38NorthPeopleCrossing = 47;
+const tExtraID kW46SouthPeopleCrossing = 48;
+const tExtraID kW49NorthPeopleCrossing = 49;
+const tExtraID kW49NorthPeopleCrossingView = 50;
+const tExtraID kWSC56SouthMap = 51;
+const tExtraID kNerdAtTheDoor1 = 52;
+const tExtraID kNerdAtTheDoor2 = 53;
+const tExtraID kW61SouthZoomInNoGun = 54;
+const tExtraID kW61Brochure = 55;
+const tExtraID kW61SouthScreenOnWithGun = 56;
+const tExtraID kW61SouthScreenOffWithGun = 57;
+const tExtraID kW61SouthSmartAlloysWithGun = 58;
+const tExtraID kW61SouthMorphingWithGun = 59;
+const tExtraID kW61SouthTimeBendingWithGun = 60;
+const tExtraID kW61SouthZoomOutNoGun = 61;
+const tExtraID kW61SouthScreenOnNoGun = 62;
+const tExtraID kW61SouthScreenOffNoGun = 63;
+const tExtraID kW61SouthSmartAlloysNoGun = 64;
+const tExtraID kW61SouthMorphingNoGun = 65;
+const tExtraID kW61SouthTimeBendingNoGun = 66;
+const tExtraID kW61MessagesOn = 67;
+const tExtraID kW61MessagesOff = 68;
+const tExtraID kW61WhiteMessage = 69;
+const tExtraID kW61WalchekMessage = 70;
+const tExtraID kW61WalchekEasterEgg1 = 71;
+const tExtraID kW62SouthPlasmaRobotAppears = 72;
+const tExtraID kW62ZoomToRobot = 73;
+const tExtraID kW62ZoomOutFromRobot = 74;
+const tExtraID kW62PlasmaDodgeSurvive = 75;
+const tExtraID kW62PlasmaDodgeDie = 76;
+const tExtraID kW65SouthSinclairLecture = 77;
+const tExtraID kW73WestPeopleCrossing = 78;
+const tExtraID kW73WestPeopleCrossingView = 79;
+const tExtraID kW0ZSpottedByWomen = 80;
+const tExtraID kW95RobotShoots = 81;
+const tExtraID kW98MorphsToRobot = 82;
+const tExtraID kW98RobotShoots = 83;
+const tExtraID kW98RobotShocked = 84;
+const tExtraID kW98RobotGassed = 85;
+const tExtraID kW98RobotHeadOpensDark = 86;
+const tExtraID kW98RobotHead000Dark = 87;
+const tExtraID kW98RobotHead001Dark = 88;
+const tExtraID kW98RobotHead010Dark = 89;
+const tExtraID kW98RobotHead011Dark = 90;
+const tExtraID kW98RobotHead100Dark = 91;
+const tExtraID kW98RobotHead101Dark = 92;
+const tExtraID kW98RobotHead110Dark = 93;
+const tExtraID kW98RobotHead111Dark = 94;
+const tExtraID kW98RobotHeadClosesDark = 95;
+const tExtraID kW98WestViewWithGunDark = 96;
+const tExtraID kW98WestViewNoGunDark = 97;
+const tExtraID kW98RobotHeadOpensLight = 98;
+const tExtraID kW98RobotHead000Light = 99;
+const tExtraID kW98RobotHead001Light = 100;
+const tExtraID kW98RobotHead010Light = 101;
+const tExtraID kW98RobotHead011Light = 102;
+const tExtraID kW98RobotHead100Light = 103;
+const tExtraID kW98RobotHead101Light = 104;
+const tExtraID kW98RobotHead110Light = 105;
+const tExtraID kW98RobotHead111Light = 106;
+const tExtraID kW98RobotHeadClosesLight = 107;
+const tExtraID kW98WestViewWithGunLight = 108;
+const tExtraID kW98WestViewNoGunLight = 109;
+
+const tCoordType kMoleculesMovieLeft = kNavAreaLeft + 112;
+const tCoordType kMoleculesMovieTop = kNavAreaTop + 40;
+
+WSC::WSC(InputHandler *nextHandler, PegasusEngine *owner) : Neighborhood(nextHandler, owner, "WSC", kWSCID),
+ _moleculesMovie(kNoDisplayElement) {
+ setIsItemTaken(kArgonCanister);
+ setIsItemTaken(kSinclairKey);
+ setIsItemTaken(kNitrogenCanister);
+ setIsItemTaken(kPoisonDart);
+ setIsItemTaken(kAntidote);
+ setIsItemTaken(kMachineGun);
+ setIsItemTaken(kStunGun);
+
+ GameState.setTakenItemID(kArgonPickup, GameState.isTakenItemID(kArgonCanister) &&
+ GameState.isTakenItemID(kSinclairKey));
+}
+
+uint16 WSC::getDateResID() const {
+ return kDate2310ID;
+}
+
+void WSC::init() {
+ Neighborhood::init();
+
+ _cachedZoomSpot = 0;
+ _argonSprite = 0;
+
+ // HACK: Fix the drag item for picking up the Sinclair Key Card
+ HotspotInfoTable::Entry *entry = findHotspotEntry(kWSC02SouthTakeArgonSpotID);
+ entry->hotspotItem = kArgonPickup;
+}
+
+void WSC::flushGameState() {
+ g_energyMonitor->saveCurrentEnergyValue();
+}
+
+void WSC::start() {
+ if (g_energyMonitor) {
+ g_energyMonitor->stopEnergyDraining();
+ g_energyMonitor->restoreLastEnergyValue();
+ _vm->resetEnergyDeathReason();
+ g_energyMonitor->startEnergyDraining();
+ }
+
+ if (!GameState.getWSCDidPlasmaDodge())
+ forceStridingStop(kWSC58, kSouth, kAltWSCNormal);
+
+ Neighborhood::start();
+}
+
+class PryDoorMessage : public AIPlayMessageAction {
+public:
+ PryDoorMessage() : AIPlayMessageAction("Images/AI/WSC/XW59SD3", false) {}
+
+protected:
+ virtual void performAIAction(AIRule *);
+};
+
+void PryDoorMessage::performAIAction(AIRule *rule) {
+ if (((PegasusEngine *)g_engine)->playerHasItemID(kShieldBiochip)
+ && ((PegasusEngine *)g_engine)->getCurrentBiochip()->getObjectID() != kShieldBiochip)
+ AIPlayMessageAction::performAIAction(rule);
+}
+
+void WSC::setUpAIRules() {
+ Neighborhood::setUpAIRules();
+
+ if (g_AIArea) {
+ AIPlayMessageAction *messageAction = new AIPlayMessageAction("Images/AI/WSC/XW1WB1", false);
+ AILastExtraCondition *extraCondition = new AILastExtraCondition(kWSCDartScan1);
+ AIRule *rule = new AIRule(extraCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+
+ messageAction = new AIPlayMessageAction("Images/AI/Globals/XGLOB5A", false);
+ AILocationCondition *locCondition = new AILocationCondition(1);
+ locCondition->addLocation(MakeRoomView(kWSC06, kNorth));
+ rule = new AIRule(locCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+
+ messageAction = new AIPlayMessageAction("Images/AI/Globals/XGLOB5A", false);
+ locCondition = new AILocationCondition(1);
+ locCondition->addLocation(MakeRoomView(kWSC10, kWest));
+ rule = new AIRule(locCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+
+ messageAction = new AIPlayMessageAction("Images/AI/Globals/XGLOB5A", false);
+ locCondition = new AILocationCondition(1);
+ locCondition->addLocation(MakeRoomView(kWSC28, kWest));
+ rule = new AIRule(locCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+
+ messageAction = new AIPlayMessageAction("Images/AI/Globals/XGLOB5A", false);
+ locCondition = new AILocationCondition(1);
+ locCondition->addLocation(MakeRoomView(kWSC49, kWest));
+ rule = new AIRule(locCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+
+ messageAction = new AIPlayMessageAction("Images/AI/Globals/XGLOB5A", false);
+ locCondition = new AILocationCondition(1);
+ locCondition->addLocation(MakeRoomView(kWSC65, kSouth));
+ rule = new AIRule(locCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+
+ messageAction = new AIPlayMessageAction("Images/AI/Globals/XGLOB5A", false);
+ locCondition = new AILocationCondition(1);
+ locCondition->addLocation(MakeRoomView(kWSC73, kSouth));
+ rule = new AIRule(locCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+
+ messageAction = new AIPlayMessageAction("Images/AI/Globals/XGLOB5A", false);
+ locCondition = new AILocationCondition(1);
+ locCondition->addLocation(MakeRoomView(kWSC79, kWest));
+ rule = new AIRule(locCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+
+ messageAction = new AIPlayMessageAction("Images/AI/WSC/XW59SD1", false);
+ locCondition = new AILocationCondition(1);
+ locCondition->addLocation(MakeRoomView(kWSC58, kSouth));
+ rule = new AIRule(locCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+
+ PryDoorMessage *pryDoorMessage = new PryDoorMessage();
+ AIDoorOpenedCondition *doorCondition = new AIDoorOpenedCondition(MakeRoomView(kWSC58, kSouth));
+ rule = new AIRule(doorCondition, pryDoorMessage);
+ g_AIArea->addAIRule(rule);
+
+ messageAction = new AIPlayMessageAction("Images/AI/WSC/XW61E", false);
+ AIHasItemCondition *itemCondition = new AIHasItemCondition(kMachineGun);
+ rule = new AIRule(itemCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+
+ messageAction = new AIPlayMessageAction("Images/AI/Globals/XGLOB1E", false);
+ locCondition = new AILocationCondition(1);
+ locCondition->addLocation(MakeRoomView(kWSC95, kWest));
+ rule = new AIRule(locCondition, messageAction);
+ g_AIArea->addAIRule(rule);
+ }
+}
+
+Common::String WSC::getBriefingMovie() {
+ return "Images/AI/WSC/XWO";
+}
+
+Common::String WSC::getEnvScanMovie() {
+ tRoomID room = GameState.getCurrentRoom();
+
+ if (room >= kWSC01 && room <= kWSC04)
+ return "Images/AI/WSC/XWE1";
+ else if (room >= kWSC06 && room <= kWSC58)
+ return "Images/AI/WSC/XWE2";
+ else if (room >= kWSC60 && room <= kWSC61West)
+ return "Images/AI/WSC/XWE3";
+ else if (room >= kWSC64 && room <= kWSC98)
+ return "Images/AI/WSC/XWE4";
+
+ return "Images/AI/WSC/XWE5";
+}
+
+uint WSC::getNumHints() {
+ switch (GameState.getCurrentRoomAndView()) {
+ case MakeRoomView(kWSC10, kWest):
+ case MakeRoomView(kWSC28, kWest):
+ case MakeRoomView(kWSC49, kWest):
+ case MakeRoomView(kWSC65, kSouth):
+ case MakeRoomView(kWSC75, kSouth):
+ case MakeRoomView(kWSC79, kWest):
+ return 2;
+ case MakeRoomView(kWSC02, kSouth):
+ if (_vm->getEnergyDeathReason() == kDeathDidntStopPoison &&
+ !_privateFlags.getFlag(kWSCPrivateInMoleculeGameFlag) &&
+ !GameState.getWSCDesignedAntidote())
+ return 3;
+ else if (!GameState.getScoringGotNitrogenCanister() ||
+ !GameState.getScoringGotSinclairKey())
+ return 1;
+ break;
+ case MakeRoomView(kWSC03, kNorth):
+ if (inSynthesizerGame() || (_vm->getEnergyDeathReason() == kDeathDidntStopPoison &&
+ !_privateFlags.getFlag(kWSCPrivateInMoleculeGameFlag) &&
+ !GameState.getWSCDesignedAntidote()))
+ return 3;
+ break;
+ case MakeRoomView(kWSC01, kNorth):
+ case MakeRoomView(kWSC01, kSouth):
+ case MakeRoomView(kWSC01, kEast):
+ case MakeRoomView(kWSC01, kWest):
+ case MakeRoomView(kWSC02, kNorth):
+ case MakeRoomView(kWSC02, kEast):
+ case MakeRoomView(kWSC02, kWest):
+ case MakeRoomView(kWSC02Morph, kNorth):
+ case MakeRoomView(kWSC02Morph, kEast):
+ case MakeRoomView(kWSC02Morph, kWest):
+ case MakeRoomView(kWSC02Messages, kNorth):
+ case MakeRoomView(kWSC02Messages, kEast):
+ case MakeRoomView(kWSC02Messages, kWest):
+ case MakeRoomView(kWSC03, kSouth):
+ case MakeRoomView(kWSC03, kEast):
+ case MakeRoomView(kWSC03, kWest):
+ case MakeRoomView(kWSC04, kNorth):
+ case MakeRoomView(kWSC04, kSouth):
+ case MakeRoomView(kWSC04, kEast):
+ case MakeRoomView(kWSC04, kWest):
+ if (_vm->getEnergyDeathReason() == kDeathDidntStopPoison &&
+ !_privateFlags.getFlag(kWSCPrivateInMoleculeGameFlag) &&
+ !GameState.getWSCDesignedAntidote())
+ return 3;
+ break;
+ case MakeRoomView(kWSC02Messages, kSouth):
+ if (_vm->getEnergyDeathReason() == kDeathDidntStopPoison &&
+ !_privateFlags.getFlag(kWSCPrivateInMoleculeGameFlag) &&
+ !GameState.getWSCDesignedAntidote())
+ return 3;
+ else if (!GameState.getScoringGotNitrogenCanister())
+ return 1;
+ break;
+ case MakeRoomView(kWSC02Morph, kSouth):
+ if (_vm->getEnergyDeathReason() == kDeathDidntStopPoison &&
+ !_privateFlags.getFlag(kWSCPrivateInMoleculeGameFlag) &&
+ !GameState.getWSCDesignedAntidote())
+ return 3;
+ else if (!GameState.getScoringGotSinclairKey())
+ return 1;
+ break;
+ case MakeRoomView(kWSC42, kEast):
+ if (!GameState.isCurrentDoorOpen())
+ return 1;
+ break;
+ case MakeRoomView(kWSC58, kSouth):
+ if (GameState.isCurrentDoorOpen()) {
+ if (GameState.getWSCDidPlasmaDodge())
+ return 0;
+ else
+ return 1;
+ } else if (_vm->playerHasItemID(kCrowbar))
+ return 2;
+
+ return 3;
+ case MakeRoomView(kWSC61, kEast):
+ if (!GameState.getScoringSawBrochure())
+ return 1;
+ break;
+ case MakeRoomView(kWSC61, kSouth):
+ if (!GameState.getScoringSawSinclairEntry1() ||
+ !GameState.getScoringSawSinclairEntry2() ||
+ !GameState.getScoringSawSinclairEntry3())
+ return 1;
+ break;
+ case MakeRoomView(kWSC98, kWest):
+ if (getCurrentActivation() == kActivationRobotTurning)
+ return 1;
+ break;
+ }
+
+ return 0;
+}
+
+Common::String WSC::getHintMovie(uint hintNum) {
+ switch (GameState.getCurrentRoomAndView()) {
+ case MakeRoomView(kWSC10, kWest):
+ case MakeRoomView(kWSC28, kWest):
+ case MakeRoomView(kWSC49, kWest):
+ case MakeRoomView(kWSC65, kSouth):
+ case MakeRoomView(kWSC75, kSouth):
+ case MakeRoomView(kWSC79, kWest):
+ if (hintNum == 1)
+ return "Images/AI/Globals/XGLOB5B";
+
+ return "Images/AI/Globals/XGLOB5C";
+ case MakeRoomView(kWSC02, kSouth):
+ if (_vm->getEnergyDeathReason() == kDeathDidntStopPoison &&
+ !_privateFlags.getFlag(kWSCPrivateInMoleculeGameFlag) &&
+ !GameState.getWSCDesignedAntidote())
+ return Common::String::format("Images/AI/WSC/XWPH%d", hintNum);
+
+ return "Images/AI/Globals/XGLOB1C";
+ case MakeRoomView(kWSC61, kEast):
+ case MakeRoomView(kWSC61, kSouth):
+ return "Images/AI/Globals/XGLOB1C";
+ case MakeRoomView(kWSC42, kEast):
+ if (_vm->playerHasItemID(kSinclairKey))
+ return "Images/AI/Globals/XGLOB1A";
+
+ return "Images/AI/Globals/XGLOB2C";
+ case MakeRoomView(kWSC58, kSouth):
+ switch (hintNum) {
+ case 1:
+ if (GameState.isCurrentDoorOpen()) {
+ // Only get here if we haven't done the plasma dodge game...
+ if (_vm->playerHasItemID(kShieldBiochip))
+ return "Images/AI/Globals/XGLOB1A";
+ else
+ return "Images/AI/Globals/XGLOB3F";
+ } else if (_vm->playerHasItemID(kCrowbar)) {
+ return "Images/AI/Globals/XGLOB1A";
+ }
+
+ return "Images/AI/Globals/XGLOB1B";
+ case 2:
+ // Only get here if the door is still locked...
+ if (_vm->playerHasItemID(kCrowbar))
+ return "Images/AI/WSC/XW59SD2";
+
+ return "Images/AI/Globals/XGLOB2D";
+ case 3:
+ // Only get here if the door is still locked and we don't have the
+ // crowbar...
+ return "Images/AI/WSC/XW59SD2";
+ }
+ break;
+ case MakeRoomView(kWSC03, kNorth):
+ if (inSynthesizerGame())
+ return Common::String::format("Images/AI/WSC/XW03NH%d", hintNum);
+
+ return Common::String::format("Images/AI/WSC/XWPH%d", hintNum);
+ case MakeRoomView(kWSC01, kNorth):
+ case MakeRoomView(kWSC01, kSouth):
+ case MakeRoomView(kWSC01, kEast):
+ case MakeRoomView(kWSC01, kWest):
+ case MakeRoomView(kWSC02, kNorth):
+ case MakeRoomView(kWSC02, kEast):
+ case MakeRoomView(kWSC02, kWest):
+ case MakeRoomView(kWSC02Morph, kNorth):
+ case MakeRoomView(kWSC02Morph, kEast):
+ case MakeRoomView(kWSC02Morph, kWest):
+ case MakeRoomView(kWSC02Messages, kNorth):
+ case MakeRoomView(kWSC02Messages, kEast):
+ case MakeRoomView(kWSC02Messages, kWest):
+ case MakeRoomView(kWSC03, kSouth):
+ case MakeRoomView(kWSC03, kEast):
+ case MakeRoomView(kWSC03, kWest):
+ case MakeRoomView(kWSC04, kNorth):
+ case MakeRoomView(kWSC04, kSouth):
+ case MakeRoomView(kWSC04, kEast):
+ case MakeRoomView(kWSC04, kWest):
+ // analyzer hint
+ return Common::String::format("Images/AI/WSC/XWPH%d", hintNum);
+ case MakeRoomView(kWSC02Messages, kSouth):
+ case MakeRoomView(kWSC02Morph, kSouth):
+ if (_vm->getEnergyDeathReason() == kDeathDidntStopPoison &&
+ !_privateFlags.getFlag(kWSCPrivateInMoleculeGameFlag) &&
+ !GameState.getWSCDesignedAntidote())
+ // analyzer hint
+ return Common::String::format("Images/AI/WSC/XWPH%d", hintNum);
+
+ return "Images/AI/Globals/XGLOB1C";
+ case MakeRoomView(kWSC98, kWest):
+ return "Images/AI/WSC/XW98WH2";
+ }
+
+ return "";
+}
+
+void WSC::prepareForAIHint(const Common::String &movieName) {
+ if (movieName == "Images/AI/WSC/XW98WH2" && isEventTimerRunning())
+ pauseTimer();
+}
+
+void WSC::cleanUpAfterAIHint(const Common::String &movieName) {
+ if (movieName == "Images/AI/WSC/XW98WH2" && isEventTimerRunning())
+ resumeTimer();
+}
+
+bool WSC::okayToJump() {
+ if (GameState.getWSCPoisoned()) {
+ die(kDeathDidntStopPoison);
+ return false;
+ }
+
+ bool result = Neighborhood::okayToJump();
+ if (!result)
+ playSpotSoundSync(kWSCCantTransportIn, kWSCCantTransportOut);
+
+ return result;
+}
+
+TimeValue WSC::getViewTime(const tRoomID room, const tDirectionConstant direction) {
+ tExtraID viewExtra = 0xffffffff;
+ ExtraTable::Entry extra;
+
+ switch (MakeRoomView(room, direction)) {
+ case MakeRoomView(kWSC01, kWest):
+ if (!GameState.getWSCSeenTimeStream()) {
+ getExtraEntry(kWSCArrivalFromTSA, extra);
+ return extra.movieStart;
+ } else if (GameState.getWSCPoisoned() && !GameState.getWSCAnsweredAboutDart()) {
+ viewExtra = kWSCDartScan1;
+ }
+ break;
+ case MakeRoomView(kWSC02Morph, kSouth):
+ if (GameState.isTakenItemID(kArgonPickup) || GameState.isTakenItemID(kArgonCanister))
+ viewExtra = kWSC02SouthViewNoArgon;
+ break;
+ case MakeRoomView(kWSC02Messages, kSouth):
+ if (GameState.isTakenItemID(kNitrogenCanister)) {
+ if (_privateFlags.getFlag(kWSCPrivateLabMessagesOpenFlag))
+ viewExtra = kMessagesViewMachineOnNoNitrogen;
+ else
+ viewExtra = kMessagesViewNoNitrogen;
+ }
+ break;
+ case MakeRoomView(kWSC03, kSouth):
+ if (_privateFlags.getFlag(kWSCDraggingAntidoteFlag))
+ viewExtra = kW03SouthViewNoAntidote;
+ break;
+ case MakeRoomView(kWSC17, kWest):
+ if (_privateFlags.getFlag(kWSCPrivateNeedPeopleAt17WestFlag))
+ viewExtra = kW17WestPeopleCrossingView;
+ break;
+ case MakeRoomView(kWSC49, kNorth):
+ if (_privateFlags.getFlag(kWSCPrivateNeedPeopleAt49NorthFlag))
+ viewExtra = kW49NorthPeopleCrossingView;
+ break;
+ case MakeRoomView(kWSC73, kWest):
+ if (_privateFlags.getFlag(kWSCPrivateNeedPeopleAt73WestFlag))
+ viewExtra = kW73WestPeopleCrossingView;
+ break;
+ case MakeRoomView(kWSC98, kWest):
+ if (GameState.getWSCRobotDead()) {
+ if (GameState.getWSCRobotGone()) {
+ if (GameState.isTakenItemID(kStunGun)) {
+ if (GameState.getWSCCatwalkDark())
+ viewExtra = kW98WestViewNoGunDark;
+ else
+ viewExtra = kW98WestViewNoGunLight;
+ } else {
+ if (GameState.getWSCCatwalkDark())
+ viewExtra = kW98WestViewWithGunDark;
+ else
+ viewExtra = kW98WestViewWithGunLight;
+ }
+ } else if (_privateFlags.getFlag(kWSCPrivateRobotHeadOpenFlag)) {
+ if (GameState.getWSCCatwalkDark())
+ viewExtra = kW98RobotHead111Dark;
+ else
+ viewExtra = kW98RobotHead111Light;
+
+ if (_privateFlags.getFlag(kWSCPrivateGotRetScanChipFlag))
+ viewExtra -= 1;
+ if (_privateFlags.getFlag(kWSCPrivateGotMapChipFlag))
+ viewExtra -= 2;
+ if (_privateFlags.getFlag(kWSCPrivateGotOpticalChipFlag))
+ viewExtra -= 4;
+ } else if (GameState.getWSCRobotDead()) {
+ // Should only happen on loading a saved game, so it can take its time.
+ if (GameState.getWSCCatwalkDark())
+ viewExtra = kW98RobotShocked;
+ else
+ viewExtra = kW98RobotGassed;
+ }
+ }
+ break;
+ }
+
+ if (viewExtra != 0xffffffff) {
+ getExtraEntry(viewExtra, extra);
+ return extra.movieEnd - 1;
+ }
+
+ return Neighborhood::getViewTime(room, direction);
+}
+
+void WSC::findSpotEntry(const tRoomID room, const tDirectionConstant direction, tSpotFlags flags, SpotTable::Entry &spotEntry) {
+ switch (MakeRoomView(room, direction)) {
+ case MakeRoomView(kWSC58, kSouth):
+ case MakeRoomView(kWSC79, kWest):
+ if ((flags & kSpotOnTurnMask) != 0) {
+ spotEntry.clear();
+ return;
+ }
+ break;
+ }
+
+ Neighborhood::findSpotEntry(room, direction, flags, spotEntry);
+}
+
+void WSC::getZoomEntry(const tHotSpotID id, ZoomTable::Entry &zoomEntry) {
+ Neighborhood::getZoomEntry(id, zoomEntry);
+
+ ExtraTable::Entry extra;
+ tExtraID zoomExtra = 0xffffffff;
+
+ switch (id) {
+ case kWSC02SouthMessagesSpotID:
+ if (GameState.isTakenItemID(kNitrogenCanister))
+ zoomExtra = kWSC02MessagesZoomNoNitrogen;
+ break;
+ case kWSC02SouthMessagesOutSpotID:
+ if (GameState.isTakenItemID(kNitrogenCanister))
+ zoomExtra = kMessagesZoomOutNoNitrogen;
+ break;
+ case kWSC02SouthMorphSpotID:
+ if (GameState.isTakenItemID(kArgonCanister))
+ zoomExtra = kWSC02MorphZoomNoArgon;
+ break;
+ case kWSC02SouthMorphOutSpotID:
+ if (GameState.isTakenItemID(kArgonCanister))
+ zoomExtra = kWSC02ZoomOutNoArgon;
+ break;
+ case kWSC61SouthSpotID:
+ if (GameState.isTakenItemID(kMachineGun))
+ zoomExtra = kW61SouthZoomInNoGun;
+ break;
+ case kWSC61SouthOutSpotID:
+ if (GameState.isTakenItemID(kMachineGun))
+ zoomExtra = kW61SouthZoomOutNoGun;
+ break;
+ }
+
+ if (zoomExtra != 0xffffffff) {
+ getExtraEntry(zoomExtra, extra);
+ zoomEntry.movieStart = extra.movieStart;
+ zoomEntry.movieEnd = extra.movieEnd;
+ }
+}
+
+void WSC::getExtraEntry(const uint32 id, ExtraTable::Entry &extraEntry) {
+ switch (id) {
+ case kWSCZoomOutFromAnalyzer:
+ Neighborhood::getExtraEntry(kWSCZoomOutFromAnalyzer, extraEntry);
+ extraEntry.movieEnd = extraEntry.movieStart + 14 * kWSCFrameDuration;
+ break;
+ case kW61WalchekMessage:
+ if (GameState.getEasterEgg())
+ Neighborhood::getExtraEntry(kW61WalchekEasterEgg1, extraEntry);
+ else
+ Neighborhood::getExtraEntry(id, extraEntry);
+ break;
+ case kW61SouthScreenOnWithGun:
+ if (GameState.isTakenItemID(kMachineGun))
+ Neighborhood::getExtraEntry(id, extraEntry);
+ else
+ Neighborhood::getExtraEntry(kW61SouthScreenOnNoGun, extraEntry);
+ break;
+ case kW61SouthSmartAlloysWithGun:
+ if (GameState.isTakenItemID(kMachineGun))
+ Neighborhood::getExtraEntry(id, extraEntry);
+ else
+ Neighborhood::getExtraEntry(kW61SouthSmartAlloysNoGun, extraEntry);
+ break;
+ case kW61SouthMorphingWithGun:
+ if (GameState.isTakenItemID(kMachineGun))
+ Neighborhood::getExtraEntry(id, extraEntry);
+ else
+ Neighborhood::getExtraEntry(kW61SouthMorphingNoGun, extraEntry);
+ break;
+ case kW61SouthTimeBendingWithGun:
+ if (GameState.isTakenItemID(kMachineGun))
+ Neighborhood::getExtraEntry(id, extraEntry);
+ else
+ Neighborhood::getExtraEntry(kW61SouthTimeBendingNoGun, extraEntry);
+ break;
+ case kW98RobotHeadOpensLight:
+ if (GameState.getWSCCatwalkDark())
+ Neighborhood::getExtraEntry(kW98RobotHeadOpensDark, extraEntry);
+ else
+ Neighborhood::getExtraEntry(id, extraEntry);
+ break;
+ default:
+ Neighborhood::getExtraEntry(id, extraEntry);
+ break;
+ }
+}
+
+tCanMoveForwardReason WSC::canMoveForward(ExitTable::Entry &entry) {
+ if (GameState.getCurrentRoomAndView() == MakeRoomView(kWSC01, kWest) &&
+ getCurrentActivation() != kActivateHotSpotAlways)
+ return kCantMoveWatchingDiagnosis;
+
+ return Neighborhood::canMoveForward(entry);
+}
+
+// Also add cases here for compound analyzer...
+tCanTurnReason WSC::canTurn(tTurnDirection turnDirection, tDirectionConstant &nextDir) {
+ switch (GameState.getCurrentRoomAndView()) {
+ case MakeRoomView(kWSC01, kWest):
+ if (getCurrentActivation() != kActivateHotSpotAlways)
+ return kCantTurnWatchingDiagnosis;
+ break;
+ case MakeRoomView(kWSC01, kEast):
+ if (getCurrentActivation() != kActivateHotSpotAlways)
+ return kCantTurnWatchingAnalysis;
+ break;
+ case MakeRoomView(kWSC03, kNorth):
+ if (_privateFlags.getFlag(kWSCPrivateInMoleculeGameFlag))
+ return kCantTurnInMoleculeGame;
+ break;
+ }
+
+ return Neighborhood::canTurn(turnDirection, nextDir);
+}
+
+tCanOpenDoorReason WSC::canOpenDoor(DoorTable::Entry &entry) {
+ switch (GameState.getCurrentRoom()) {
+ case kWSC42:
+ if (!_privateFlags.getFlag(kWSCPrivateSinclairOfficeOpenFlag))
+ return kCantOpenLocked;
+ break;
+ case kWSC58:
+ if (!_privateFlags.getFlag(kWSCPrivate58SouthOpenFlag))
+ return kCantOpenLocked;
+ break;
+ }
+
+ return Neighborhood::canOpenDoor(entry);
+}
+
+void WSC::bumpIntoWall() {
+ requestSpotSound(kWSCBumpIntoWallIn, kWSCBumpIntoWallOut, kFilterAllInput, 0);
+ Neighborhood::bumpIntoWall();
+}
+
+void WSC::closeDoorOffScreen(const tRoomID room, const tDirectionConstant) {
+ Item *keyCard;
+
+ switch (room) {
+ case kWSC58:
+ case kWSC62:
+ case kWSC63:
+ case kWSC64:
+ case kWSC85:
+ case kWSC86:
+ case kWSC88:
+ case kWSC89:
+ playSpotSoundSync(kSlidingDoorCloseIn, kSlidingDoorCloseOut);
+ break;
+ case kWSC81:
+ case kWSC82:
+ case kWSC92:
+ case kWSC93:
+ keyCard = g_allItems.findItemByID(kKeyCard);
+ if (keyCard->getItemState() == kFlashlightOn && (GameState.getCurrentRoom() == kWSC81 ||
+ GameState.getCurrentRoom() == kWSC93)) {
+ keyCard->setItemState(kFlashlightOff);
+ playSpotSoundSync(kWSCFlashlightClickIn, kWSCFlashlightClickOut);
+ } else if (keyCard->getItemState() == kFlashlightOff && (GameState.getCurrentRoom() == kWSC82 ||
+ GameState.getCurrentRoom() == kWSC92)) {
+ keyCard->setItemState(kFlashlightOn);
+ playSpotSoundSync(kWSCFlashlightClickIn, kWSCFlashlightClickOut);
+ }
+
+ playSpotSoundSync(kSlimyDoorCloseIn, kSlimyDoorCloseOut);
+ break;
+ default:
+ playSpotSoundSync(kSlimyDoorCloseIn, kSlimyDoorCloseOut);
+ break;
+ }
+}
+
+void WSC::cantMoveThatWay(tCanMoveForwardReason reason) {
+ if (reason != kCantMoveWatchingDiagnosis)
+ Neighborhood::cantMoveThatWay(reason);
+}
+
+void WSC::cantOpenDoor(tCanOpenDoorReason reason) {
+ switch (GameState.getCurrentRoomAndView()) {
+ case MakeRoomView(kWSC22, kWest):
+ playSpotSoundSync(kNakamuraNotHomeIn, kNakamuraNotHomeOut);
+ break;
+ case MakeRoomView(kWSC23, kEast):
+ playSpotSoundSync(kHernandezNotHomeIn, kHernandezNotHomeOut);
+ break;
+ case MakeRoomView(kWSC26, kWest):
+ playSpotSoundSync(kGrailisNotHomeIn, kGrailisNotHomeOut);
+ break;
+ case MakeRoomView(kWSC27, kEast):
+ playSpotSoundSync(kWashingtonNotHomeIn, kWashingtonNotHomeOut);
+ break;
+ case MakeRoomView(kWSC32, kWest):
+ playSpotSoundSync(kTheriaultNotHomeIn, kTheriaultNotHomeOut);
+ break;
+ case MakeRoomView(kWSC33, kEast):
+ playSpotSoundSync(kSullivanNotHomeIn, kSullivanNotHomeOut);
+ break;
+ case MakeRoomView(kWSC41, kWest):
+ playSpotSoundSync(kGlennerNotHomeIn, kGlennerNotHomeOut);
+ break;
+ case MakeRoomView(kWSC42, kEast):
+ playSpotSoundSync(kSinclairNotHomeIn, kSinclairNotHomeOut);
+ break;
+ case MakeRoomView(kWSC15, kWest):
+ case MakeRoomView(kWSC25, kWest):
+ case MakeRoomView(kWSC33, kWest):
+ case MakeRoomView(kWSC41, kEast):
+ case MakeRoomView(kWSC46, kWest):
+ playSpotSoundSync(kWSCLabClosedIn, kWSCLabClosedOut);
+ break;
+ default:
+ Neighborhood::cantOpenDoor(reason);
+ break;
+ }
+}
+
+void WSC::doorOpened() {
+ Neighborhood::doorOpened();
+
+ switch (GameState.getCurrentRoomAndView()) {
+ case MakeRoomView(kWSC42, kEast):
+ _vm->addItemToInventory((InventoryItem *)g_allItems.findItemByID(kSinclairKey));
+ break;
+ case MakeRoomView(kWSC58, kSouth):
+ GameState.setScoringUsedCrowBarInWSC();
+ _vm->addItemToInventory((InventoryItem *)g_allItems.findItemByID(kCrowbar));
+ break;
+ case MakeRoomView(kWSC06, kNorth):
+ case MakeRoomView(kWSC79, kWest):
+ die(kDeathArrestedInWSC);
+ break;
+ case MakeRoomView(kWSC60, kWest):
+ if (_vm->itemInInventory(kMachineGun))
+ startExtraSequence(kNerdAtTheDoor2, kExtraCompletedFlag, kFilterNoInput);
+ else if (!GameState.getWSCSeenNerd())
+ startExtraSequence(kNerdAtTheDoor1, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case MakeRoomView(kWSC95, kWest):
+ GameState.setScoringOpenedCatwalk();
+ scheduleEvent(kGawkAtRobotTime, 1, kTimerEventPlayerGawkingAtRobot);
+ break;
+ }
+}
+
+void WSC::turnLeft() {
+ switch (GameState.getCurrentRoomAndView()) {
+ case MakeRoomView(kWSC17, kNorth):
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt17WestFlag) && _vm->getRandomNumber(2) == 0)
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt17WestFlag, true);
+ break;
+ case MakeRoomView(kWSC49, kEast):
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt49NorthFlag) && _vm->getRandomNumber(2) == 0)
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt49NorthFlag, true);
+ break;
+ case MakeRoomView(kWSC73, kNorth):
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt73WestFlag) && _vm->getRandomNumber(2) == 0)
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt73WestFlag, true);
+ break;
+ case MakeRoomView(kWSC73, kWest):
+ if (!GameState.getWSCBeenAtWSC93())
+ setCurrentAlternate(kAltWSCW0ZDoorOpen);
+ break;
+ case MakeRoomView(kWSC95, kWest):
+ cancelEvent();
+ break;
+ }
+
+ Neighborhood::turnLeft();
+}
+
+void WSC::turnRight() {
+ switch (GameState.getCurrentRoomAndView()) {
+ case MakeRoomView(kWSC17, kSouth):
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt17WestFlag) && _vm->getRandomNumber(2) == 0)
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt17WestFlag, true);
+ break;
+ case MakeRoomView(kWSC49, kWest):
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt49NorthFlag) && _vm->getRandomNumber(2) == 0)
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt49NorthFlag, true);
+ break;
+ case MakeRoomView(kWSC73, kSouth):
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt73WestFlag) && _vm->getRandomNumber(2) == 0)
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt73WestFlag, true);
+ break;
+ case MakeRoomView(kWSC73, kEast):
+ if (!GameState.getWSCBeenAtWSC93())
+ setCurrentAlternate(kAltWSCW0ZDoorOpen);
+ break;
+ case MakeRoomView(kWSC95, kWest):
+ cancelEvent();
+ break;
+ }
+
+ Neighborhood::turnRight();
+}
+
+void WSC::moveForward() {
+ switch (GameState.getCurrentRoomAndView()) {
+ case MakeRoomView(kWSC19, kNorth):
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt19NorthFlag))
+ setCurrentAlternate(kAltWSCPeopleAtW19North);
+ break;
+ case MakeRoomView(kWSC95, kWest):
+ cancelEvent();
+ break;
+ }
+
+ Neighborhood::moveForward();
+}
+
+void WSC::zoomTo(const Hotspot *hotspot) {
+ switch (GameState.getCurrentRoomAndView()) {
+ case MakeRoomView(kWSC02Messages, kSouth):
+ if (_privateFlags.getFlag(kWSCPrivateLabMessagesOpenFlag)) {
+ _cachedZoomSpot = hotspot;
+ if (GameState.isTakenItemID(kNitrogenCanister))
+ startExtraSequence(kMessagesOffNoNitrogen, kExtraCompletedFlag, kFilterNoInput);
+ else
+ startExtraSequence(kMessagesOff, kExtraCompletedFlag, kFilterNoInput);
+ return;
+ }
+ break;
+ case MakeRoomView(kWSC61West, kWest):
+ if (GameState.getWSCOfficeMessagesOpen()) {
+ _cachedZoomSpot = hotspot;
+ startExtraSequence(kW61MessagesOff, kExtraCompletedFlag, kFilterNoInput);
+ return;
+ }
+ break;
+ case MakeRoomView(kWSC61South, kSouth):
+ if (_privateFlags.getFlag(kWSCPrivateOfficeLogOpenFlag)) {
+ _cachedZoomSpot = hotspot;
+ if (GameState.isTakenItemID(kMachineGun))
+ startExtraSequence(kW61SouthScreenOffNoGun, kExtraCompletedFlag, kFilterNoInput);
+ else
+ startExtraSequence(kW61SouthScreenOffWithGun, kExtraCompletedFlag, kFilterNoInput);
+ return;
+ }
+ break;
+ }
+
+ Neighborhood::zoomTo(hotspot);
+}
+
+void WSC::startExtraSequence(const tExtraID extraID, const tNotificationFlags flags, const tInputBits interruptionFilter) {
+ if (extraID == kW61Brochure)
+ loadLoopSound1("");
+
+ Neighborhood::startExtraSequence(extraID, flags, interruptionFilter);
+}
+
+int16 WSC::getStaticCompassAngle(const tRoomID room, const tDirectionConstant dir) {
+ int16 angle = Neighborhood::getStaticCompassAngle(room, dir);
+
+ switch (room) {
+ case kWSC02Messages:
+ angle -= 50;
+ break;
+ case kWSC02Morph:
+ angle += 5;
+ break;
+ case kWSC60East:
+ angle -= 10;
+ break;
+ case kWSC66:
+ angle -= kAuditoriumAngleOffset;
+ break;
+ case kWSC67:
+ angle += kAuditoriumAngleOffset;
+ break;
+ case kWSC68:
+ angle -= kAuditoriumAngleOffset * 2;
+ break;
+ case kWSC69:
+ angle += kAuditoriumAngleOffset * 2;
+ break;
+ case kWSC70:
+ angle -= kAuditoriumAngleOffset * 3;
+ break;
+ case kWSC71:
+ angle += kAuditoriumAngleOffset * 3;
+ break;
+ case kWSC72:
+ if (dir == kEast || dir == kWest)
+ angle -= kAuditoriumAngleOffset * 4;
+ break;
+ case kWSC73:
+ if (dir == kEast || dir == kWest)
+ angle += kAuditoriumAngleOffset * 4;
+ break;
+ }
+
+ return angle;
+}
+
+void WSC::getExitCompassMove(const ExitTable::Entry &exitEntry, FaderMoveSpec &compassMove) {
+ Neighborhood::getExitCompassMove(exitEntry, compassMove);
+
+ if (exitEntry.room == kWSC65 && exitEntry.direction == kSouth) {
+ compassMove.insertFaderKnot(exitEntry.movieStart + 100 * kWSCFrameDuration, 180);
+ compassMove.insertFaderKnot(exitEntry.movieStart + 108 * kWSCFrameDuration, 150);
+ compassMove.insertFaderKnot(exitEntry.movieEnd, 150);
+ }
+}
+
+void WSC::getExtraCompassMove(const ExtraTable::Entry &entry, FaderMoveSpec &compassMove) {
+ switch (entry.extra) {
+ case kW61Brochure:
+ compassMove.insertFaderKnot(entry.movieStart + 15 * kWSCFrameDuration, 85);
+ compassMove.insertFaderKnot(entry.movieEnd - 15 * kWSCFrameDuration, 85);
+ compassMove.insertFaderKnot(entry.movieEnd, 90);
+ break;
+ default:
+ Neighborhood::getExtraCompassMove(entry, compassMove);
+ break;
+ }
+}
+
+void WSC::loadAmbientLoops() {
+ tRoomID room = GameState.getCurrentRoom();
+
+ if (room >= kWSC01 && room <= kWSC04) {
+ if (GameState.getWSCSeenTimeStream())
+ loadLoopSound1("Sounds/World Science Center/WLabLoop.22K.AIFF", 0x100 / 2);
+ } else if ((room >= kWSC06 && room <= kWSC58) || (room >= kWSC62 && room <= kWSC63))
+ loadLoopSound1("Sounds/World Science Center/Organic Walls.22K.AIFF", 0x100 / 2);
+ else if (room >= kWSC82 && room <= kWSC92)
+ loadLoopSound1("Sounds/World Science Center/Creature Feature.22K.AIFF");
+ else if ((room >= kWSC60 && room <= kWSC61West) || (room >= kWSC64 && room <= kWSC81) ||
+ (room >= kWSC93 && room <= kWSC97))
+ loadLoopSound1("Sounds/World Science Center/The Other Side.22K.AIFF", 0x100 / 12);
+ else if (room == kWSC98)
+ loadLoopSound1("Sounds/World Science Center/WCatLoop.22K.AIFF");
+}
+
+void WSC::checkContinuePoint(const tRoomID room, const tDirectionConstant direction) {
+ switch (MakeRoomView(room, direction)) {
+ case MakeRoomView(kWSC07, kNorth):
+ case MakeRoomView(kWSC11, kSouth):
+ case MakeRoomView(kWSC13, kSouth):
+ case MakeRoomView(kWSC13, kWest):
+ case MakeRoomView(kWSC16, kWest):
+ case MakeRoomView(kWSC17, kEast):
+ case MakeRoomView(kWSC19, kWest):
+ case MakeRoomView(kWSC28, kNorth):
+ case MakeRoomView(kWSC28, kSouth):
+ case MakeRoomView(kWSC28, kEast):
+ case MakeRoomView(kWSC28, kWest):
+ case MakeRoomView(kWSC29, kNorth):
+ case MakeRoomView(kWSC29, kSouth):
+ case MakeRoomView(kWSC29, kEast):
+ case MakeRoomView(kWSC29, kWest):
+ case MakeRoomView(kWSC40, kEast):
+ case MakeRoomView(kWSC42, kEast):
+ case MakeRoomView(kWSC49, kWest):
+ case MakeRoomView(kWSC49, kNorth):
+ case MakeRoomView(kWSC50, kNorth):
+ case MakeRoomView(kWSC55, kEast):
+ case MakeRoomView(kWSC65, kSouth):
+ case MakeRoomView(kWSC65, kEast):
+ case MakeRoomView(kWSC65, kWest):
+ case MakeRoomView(kWSC72, kEast):
+ case MakeRoomView(kWSC72, kSouth):
+ case MakeRoomView(kWSC73, kWest):
+ case MakeRoomView(kWSC73, kSouth):
+ case MakeRoomView(kWSC79, kWest):
+ case MakeRoomView(kWSC81, kEast):
+ case MakeRoomView(kWSC93, kNorth):
+ case MakeRoomView(kWSC95, kWest):
+ makeContinuePoint();
+ break;
+ case MakeRoomView(kWSC58, kSouth):
+ if (!GameState.getWSCDidPlasmaDodge())
+ makeContinuePoint();
+ break;
+ case MakeRoomView(kWSC60, kWest):
+ if (_vm->playerHasItemID(kMachineGun))
+ makeContinuePoint();
+ break;
+ }
+}
+
+void WSC::arriveAt(const tRoomID room, const tDirectionConstant dir) {
+ switch (MakeRoomView(room, dir)) {
+ case MakeRoomView(kWSC60, kNorth):
+ case MakeRoomView(kWSC60, kSouth):
+ case MakeRoomView(kWSC60, kEast):
+ case MakeRoomView(kWSC60, kWest):
+ case MakeRoomView(kWSC60East, kNorth):
+ case MakeRoomView(kWSC60East, kSouth):
+ case MakeRoomView(kWSC60East, kEast):
+ case MakeRoomView(kWSC60East, kWest):
+ case MakeRoomView(kWSC60North, kNorth):
+ case MakeRoomView(kWSC60North, kSouth):
+ case MakeRoomView(kWSC60North, kEast):
+ case MakeRoomView(kWSC60North, kWest):
+ case MakeRoomView(kWSC61, kNorth):
+ case MakeRoomView(kWSC61, kSouth):
+ case MakeRoomView(kWSC61, kEast):
+ case MakeRoomView(kWSC61, kWest):
+ case MakeRoomView(kWSC61South, kNorth):
+ case MakeRoomView(kWSC61South, kSouth):
+ case MakeRoomView(kWSC61South, kEast):
+ case MakeRoomView(kWSC61South, kWest):
+ case MakeRoomView(kWSC61West, kNorth):
+ case MakeRoomView(kWSC61West, kSouth):
+ case MakeRoomView(kWSC61West, kEast):
+ case MakeRoomView(kWSC61West, kWest):
+ if (GameState.isTakenItemID(kMachineGun))
+ setCurrentAlternate(kAltWSCTookMachineGun);
+ else
+ setCurrentAlternate(kAltWSCNormal);
+ break;
+ case MakeRoomView(kWSC73, kSouth):
+ case MakeRoomView(kWSC75, kNorth):
+ case MakeRoomView(kWSC75, kSouth):
+ case MakeRoomView(kWSC75, kEast):
+ case MakeRoomView(kWSC75, kWest):
+ if (!GameState.getWSCBeenAtWSC93())
+ setCurrentAlternate(kAltWSCW0ZDoorOpen);
+ break;
+ }
+
+ Neighborhood::arriveAt(room, dir);
+
+ switch (MakeRoomView(room, dir)) {
+ case MakeRoomView(kWSC01, kWest):
+ if (!GameState.getWSCSeenTimeStream()) {
+ requestExtraSequence(kWSCArrivalFromTSA, kExtraCompletedFlag, kFilterNoInput);
+ requestExtraSequence(kWSCShotByRobot, 0, kFilterNoInput);
+ requestExtraSequence(kWSCDartScan1, kExtraCompletedFlag, kFilterNoInput);
+ } else if (GameState.getWSCPoisoned() && !GameState.getWSCAnsweredAboutDart()) {
+ setCurrentActivation(kActivationShotByRobot);
+ }
+ break;
+ case MakeRoomView(kWSC01, kEast):
+ if (GameState.getWSCDartInAnalyzer())
+ requestExtraSequence(kWSCDropDartIntoAnalyzer, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case MakeRoomView(kWSC02Morph, kSouth):
+ setCurrentActivation(kActivationMorphScreenOff);
+ break;
+ case MakeRoomView(kWSC03, kNorth):
+ setCurrentActivation(kActivationW03NorthOff);
+ break;
+ case MakeRoomView(kWSC03, kSouth):
+ if (GameState.getWSCDesignedAntidote() && !GameState.getWSCPickedUpAntidote())
+ setCurrentActivation(kActivationReadyForSynthesis);
+ break;
+ case MakeRoomView(kWSC16, kNorth):
+ if (getCurrentAlternate() == kAltWSCPeopleAtW19North) {
+ setCurrentAlternate(kAltWSCNormal);
+ _privateFlags.setFlag(kWSCPrivateSeenPeopleAt19NorthFlag, true);
+ }
+ break;
+ case MakeRoomView(kWSC07, kSouth):
+ case MakeRoomView(kWSC56, kNorth):
+ setCurrentActivation(kActivationReadyForMap);
+ break;
+ case MakeRoomView(kWSC42, kWest):
+ setCurrentAlternate(kAltWSCNormal);
+ break;
+ case MakeRoomView(kWSC42, kEast):
+ _privateFlags.setFlag(kWSCPrivateSinclairOfficeOpenFlag, false);
+ setCurrentActivation(kActivationSinclairOfficeLocked);
+ break;
+ case MakeRoomView(kWSC58, kSouth):
+ setCurrentActivation(kActivationW58SouthDoorLocked);
+ _privateFlags.setFlag(kWSCPrivate58SouthOpenFlag, false);
+ break;
+ case MakeRoomView(kWSC60, kEast):
+ GameState.setScoringEnteredSinclairOffice();
+ break;
+ case MakeRoomView(kWSC61West, kWest):
+ setCurrentActivation(kActivationW61MessagesOff);
+ break;
+ case MakeRoomView(kWSC61South, kSouth):
+ setCurrentActivation(kActivationW61SouthOff);
+ break;
+ case MakeRoomView(kWSC62, kSouth):
+ if (!GameState.getWSCDidPlasmaDodge()) {
+ g_AIArea->lockAIOut();
+ loadLoopSound1("Sounds/World Science Center/Plasma Rock.22K.AIFF");
+ requestExtraSequence(kW62SouthPlasmaRobotAppears, 0, kFilterNoInput);
+ requestExtraSequence(kW62ZoomToRobot, 0, kFilterNoInput);
+ requestExtraSequence(kW62ZoomOutFromRobot, kExtraCompletedFlag, kFilterNoInput);
+ }
+ break;
+ case MakeRoomView(kWSC65Screen, kSouth):
+ if (!GameState.getWSCSeenSinclairLecture()) {
+ GameState.setWSCSeenSinclairLecture(true);
+ startExtraSequence(kW65SouthSinclairLecture, kExtraCompletedFlag, kFilterAllInput);
+ }
+ break;
+ case MakeRoomView(kWSC66, kWest):
+ case MakeRoomView(kWSC67, kEast):
+ if (!GameState.getWSCHeardPage2()) {
+ playSpotSoundSync(kPaging2In, kPaging2Out);
+ GameState.setWSCHeardPage2(true);
+ }
+ case MakeRoomView(kWSC10, kNorth):
+ case MakeRoomView(kWSC26, kSouth):
+ case MakeRoomView(kWSC72, kWest):
+ case MakeRoomView(kWSC83, kWest):
+ if (!GameState.getWSCHeardCheckIn()) {
+ playSpotSoundSync(kCheckInIn, kCheckInOut);
+ GameState.setWSCHeardCheckIn(true);
+ }
+ break;
+ case MakeRoomView(kWSC0Z, kSouth):
+ if (getCurrentAlternate() == kAltWSCW0ZDoorOpen)
+ turnLeft();
+ break;
+ case MakeRoomView(kWSC93, kEast):
+ GameState.setWSCBeenAtWSC93(true);
+ break;
+ case MakeRoomView(kWSC98, kWest):
+ if (!GameState.getWSCRobotDead()) {
+ scheduleEvent(kGawkAtRobotTime2, 1, kTimerEventPlayerGawkingAtRobot2);
+ setCurrentActivation(kActivationRobotTurning);
+ if (g_AIArea)
+ g_AIArea->checkMiddleArea();
+ } else if (!GameState.getWSCRobotGone()) {
+ setCurrentActivation(kActivationRobotDead);
+ } else {
+ if (GameState.getWSCCatwalkDark()) {
+ // Change the gun hot spot...
+ g_allHotspots.setHotspotRect(kW98StunGunSpotID, Common::Rect(181 + kNavAreaLeft,
+ 99 + kNavAreaTop,372 + kNavAreaLeft, 149 + kNavAreaTop));
+ }
+ setCurrentActivation(kActivationRobotGone);
+ }
+ break;
+ case MakeRoomView(kWSCDeathRoom, kNorth):
+ case MakeRoomView(kWSCDeathRoom, kSouth):
+ case MakeRoomView(kWSCDeathRoom, kEast):
+ case MakeRoomView(kWSCDeathRoom, kWest):
+ die(kDeathArrestedInWSC);
+ break;
+ }
+
+ checkPeopleCrossing();
+ setUpPoison();
+}
+
+void WSC::turnTo(const tDirectionConstant direction) {
+ Neighborhood::turnTo(direction);
+
+ switch (MakeRoomView(GameState.getCurrentRoom(), direction)) {
+ case MakeRoomView(kWSC01, kNorth):
+ case MakeRoomView(kWSC01, kSouth):
+ GameState.setWSCAnalyzerOn(false);
+ break;
+ case MakeRoomView(kWSC03, kNorth):
+ setCurrentActivation(kActivationW03NorthOff);
+ break;
+ case MakeRoomView(kWSC03, kSouth):
+ if (GameState.getWSCDesignedAntidote() && !GameState.getWSCPickedUpAntidote())
+ setCurrentActivation(kActivationReadyForSynthesis);
+ break;
+ case MakeRoomView(kWSC07, kSouth):
+ case MakeRoomView(kWSC56, kNorth):
+ setCurrentActivation(kActivationReadyForMap);
+ break;
+ case MakeRoomView(kWSC18, kSouth):
+ case MakeRoomView(kWSC57, kEast):
+ case MakeRoomView(kWSC75, kEast):
+ case MakeRoomView(kWSC90, kSouth):
+ if (!GameState.getWSCHeardCheckIn()) {
+ playSpotSoundSync(kCheckInIn, kCheckInOut);
+ GameState.setWSCHeardCheckIn(true);
+ }
+ break;
+ case MakeRoomView(kWSC56, kSouth):
+ if (!GameState.getWSCHeardPage1()) {
+ playSpotSoundSync(kPaging1In, kPaging1Out);
+ GameState.setWSCHeardPage1(true);
+ }
+ // clone2727 says: This falls through?!??! WTF?
+ case MakeRoomView(kWSC42, kEast):
+ _privateFlags.setFlag(kWSCPrivateSinclairOfficeOpenFlag, false);
+ setCurrentActivation(kActivationSinclairOfficeLocked);
+ break;
+ case MakeRoomView(kWSC58, kSouth):
+ setCurrentActivation(kActivationW58SouthDoorLocked);
+ _privateFlags.setFlag(kWSCPrivate58SouthOpenFlag, false);
+ break;
+ case MakeRoomView(kWSC73, kWest):
+ setCurrentAlternate(kAltWSCNormal);
+ break;
+ case MakeRoomView(kWSC0Z, kEast):
+ if (getCurrentAlternate() == kAltWSCW0ZDoorOpen)
+ startExtraSequence(kW0ZSpottedByWomen, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ }
+
+ checkPeopleCrossing();
+}
+
+void WSC::receiveNotification(Notification *notification, const tNotificationFlags flags) {
+ int32 currentEnergy;
+ Item *item;
+
+ if (flags & kExtraCompletedFlag) {
+ _interruptionFilter = kFilterAllInput;
+
+ switch (_lastExtra) {
+ case kWSCArrivalFromTSA:
+ GameState.setWSCSeenTimeStream(true);
+ loadAmbientLoops();
+ break;
+ case kWSCDartScan1:
+ setCurrentActivation(kActivationShotByRobot);
+ GameState.setWSCPoisoned(true);
+ setUpPoison();
+ makeContinuePoint();
+ break;
+ case kWSCDartScan2:
+ _vm->addItemToInventory((InventoryItem *)g_allItems.findItemByID(kPoisonDart));
+ GameState.setScoringRemovedDart();
+ GameState.setWSCRemovedDart(true);
+ setUpPoison();
+ g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/WSC/XW1WB2", false, kHintInterruption);
+ // Fall through...
+ case kWSCDartScanNo:
+ GameState.setWSCAnsweredAboutDart(true);
+ startExtraSequence(kWSCDartScan3, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case kWSCDartScan3:
+ setCurrentActivation(kActivateHotSpotAlways);
+ break;
+ case kWSCAnalyzerPowerUp:
+ case kWSCAnalyzerPowerUpWithDart:
+ GameState.setWSCAnalyzerOn(true);
+ break;
+ case kWSCDropDartIntoAnalyzer:
+ setCurrentActivation(kActivationZoomedInToAnalyzer);
+ break;
+ case kWSCAnalyzeDart:
+ GameState.setWSCAnalyzedDart(true);
+ GameState.setScoringAnalyzedDart();
+ break;
+ case kWSCZoomOutFromAnalyzer:
+ setCurrentActivation(kActivateHotSpotAlways);
+ GameState.setWSCAnalyzerOn(false);
+ GameState.setWSCDartInAnalyzer(false);
+ updateViewFrame();
+ break;
+ case kMessagesMovedToOffice:
+ case kMessagesMovedToOfficeNoNitrogen:
+ _privateFlags.setFlag(kWSCPrivateLabMessagesOpenFlag, true);
+ GameState.setScoringPlayedWithMessages();
+ break;
+ case kMessagesOff:
+ case kMessagesOffNoNitrogen:
+ _privateFlags.setFlag(kWSCPrivateLabMessagesOpenFlag, false);
+ if (_cachedZoomSpot) {
+ zoomTo(_cachedZoomSpot);
+ _cachedZoomSpot = 0;
+ }
+ break;
+ case kWSC02TurnOnMorphScreen:
+ setCurrentActivation(kActivationReadyForMorph);
+ break;
+ case kWSC02DropToMorphExperiment:
+ loopExtraSequence(kWSC02MorphLoop, kExtraCompletedFlag);
+ setCurrentActivation(kActivationMorphLooping);
+ break;
+ case kWSC02MorphLoop:
+ if (_privateFlags.getFlag(kWSCPrivateInterruptedMorphFlag))
+ startExtraSequence(kWSC02MorphInterruption, kExtraCompletedFlag, kFilterNoInput);
+ else
+ scheduleNavCallBack(kExtraCompletedFlag);
+ break;
+ case kWSC02MorphInterruption:
+ setCurrentActivation(kActivationMorphInterrupted);
+ GameState.setScoringSawMorphExperiment();
+ break;
+ case kWSC02TurnOffMorphScreen:
+ setCurrentActivation(kActivationMorphScreenOff);
+ GameState.setWSCSawMorph(true);
+ break;
+ case kW03NorthActivate:
+ if (GameState.getWSCAnalyzedDart() && !GameState.getWSCDesignedAntidote())
+ startExtraSequence(kW03NorthGetData, kExtraCompletedFlag, kFilterNoInput);
+ else
+ setCurrentActivation(kActivateHotSpotAlways);
+ break;
+ case kW03NorthGetData:
+ setCurrentActivation(kActivationW03NorthReadyForInstructions);
+ break;
+ case kW03NorthInstructions:
+ setCurrentActivation(kActivationW03NorthSawInstructions);
+ break;
+ case kW03NorthPrepMolecule1:
+ setUpMoleculeGame();
+ break;
+ case kW03NorthPrepMolecule2:
+ case kW03NorthPrepMolecule3:
+ nextMoleculeGameLevel();
+ break;
+ case kW03NorthFinishSynthesis:
+ setCurrentActivation(kActivateHotSpotAlways);
+ _privateFlags.setFlag(kWSCPrivateInMoleculeGameFlag, false);
+ GameState.setWSCDesignedAntidote(true);
+ GameState.setScoringBuiltAntidote();
+ break;
+ case kW03SouthCreateAntidote:
+ setCurrentActivation(kActivationSynthesizerLooping);
+ loopExtraSequence(kW03SouthAntidoteLoop);
+ break;
+ case kW03SouthDeactivate:
+ setCurrentActivation(kActivateHotSpotAlways);
+ break;
+ case kWSC07SouthMap:
+ case kWSC56SouthMap:
+ setCurrentActivation(kActivateHotSpotAlways);
+ GameState.setScoringSawWSCDirectory();
+ break;
+ case kNerdAtTheDoor1:
+ GameState.setWSCSeenNerd(true);
+ break;
+ case kNerdAtTheDoor2:
+ die(kDeathArrestedInWSC);
+ break;
+ case kW61Brochure:
+ GameState.setScoringSawBrochure();
+ loadAmbientLoops();
+ break;
+ case kW61SouthSmartAlloysWithGun:
+ case kW61SouthSmartAlloysNoGun:
+ GameState.setScoringSawSinclairEntry1();
+ break;
+ case kW61SouthMorphingWithGun:
+ case kW61SouthMorphingNoGun:
+ GameState.setScoringSawSinclairEntry2();
+ break;
+ case kW61SouthTimeBendingWithGun:
+ case kW61SouthTimeBendingNoGun:
+ GameState.setScoringSawSinclairEntry3();
+ break;
+ case kW61MessagesOn:
+ GameState.setWSCOfficeMessagesOpen(true);
+ setCurrentActivation(kActivationW61MessagesOn);
+ break;
+ case kW61MessagesOff:
+ GameState.setWSCOfficeMessagesOpen(false);
+ setCurrentActivation(kActivationW61MessagesOff);
+ if (_cachedZoomSpot) {
+ zoomTo(_cachedZoomSpot);
+ _cachedZoomSpot = 0;
+ }
+ break;
+ case kW61SouthScreenOnWithGun:
+ case kW61SouthScreenOnNoGun:
+ _privateFlags.setFlag(kWSCPrivateOfficeLogOpenFlag, true);
+ setCurrentActivation(kActivationW61SouthOn);
+ break;
+ case kW61SouthScreenOffWithGun:
+ case kW61SouthScreenOffNoGun:
+ _privateFlags.setFlag(kWSCPrivateOfficeLogOpenFlag, false);
+ setCurrentActivation(kActivationW61SouthOff);
+ if (_cachedZoomSpot) {
+ zoomTo(_cachedZoomSpot);
+ _cachedZoomSpot = 0;
+ }
+ break;
+ case kW62ZoomOutFromRobot:
+ // Handle action queue before starting new movie sequences.
+ Neighborhood::receiveNotification(notification, flags);
+ _energyDrainRate = g_energyMonitor->getEnergyDrainRate();
+ g_energyMonitor->setEnergyDrainRate(0);
+ currentEnergy = g_energyMonitor->getCurrentEnergy();
+ _vm->setEnergyDeathReason(kDeathHitByPlasma);
+
+ if (GameState.getShieldOn())
+ currentEnergy -= kPlasmaEnergyWithShield;
+ else
+ currentEnergy -= kPlasmaEnergyNoShield;
+
+ if (currentEnergy <= 0)
+ startExtraSequence(kW62PlasmaDodgeDie, kExtraCompletedFlag, kFilterNoInput);
+ else
+ startExtraSequence(kW62PlasmaDodgeSurvive, kExtraCompletedFlag, kFilterNoInput);
+
+ scheduleEvent(kPlasmaImpactTime, kOneTickPerSecond, kTimerEventPlasmaHit);
+ break;
+ case kW62PlasmaDodgeDie:
+ g_energyMonitor->setEnergyValue(0);
+ break;
+ case kW62PlasmaDodgeSurvive:
+ if (GameState.getShieldOn()) {
+ g_shield->setItemState(kShieldNormal);
+ g_energyMonitor->drainEnergy(kPlasmaEnergyWithShield);
+ } else {
+ g_energyMonitor->drainEnergy(kPlasmaEnergyNoShield);
+ }
+
+ g_energyMonitor->setEnergyDrainRate(_energyDrainRate);
+ g_AIArea->unlockAI();
+ GameState.setScoringFinishedPlasmaDodge();
+ GameState.setWSCDidPlasmaDodge(true);
+ restoreStriding(kWSC58, kSouth, kAltWSCNormal);
+ loadAmbientLoops();
+ break;
+ case kW0ZSpottedByWomen:
+ die(kDeathArrestedInWSC);
+ break;
+ case kW17WestPeopleCrossing:
+ _privateFlags.setFlag(kWSCPrivateSeenPeopleAt17WestFlag, true);
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt17WestFlag, false);
+ break;
+ case kW21SouthPeopleCrossing:
+ _privateFlags.setFlag(kWSCPrivateSeenPeopleAt21SouthFlag, true);
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt21SouthFlag, true);
+ break;
+ case kW24SouthPeopleCrossing:
+ _privateFlags.setFlag(kWSCPrivateSeenPeopleAt24SouthFlag, true);
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt24SouthFlag, true);
+ break;
+ case kW34EastPeopleCrossing:
+ _privateFlags.setFlag(kWSCPrivateSeenPeopleAt34EastFlag, true);
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt34EastFlag, true);
+ break;
+ case kW36WestPeopleCrossing:
+ _privateFlags.setFlag(kWSCPrivateSeenPeopleAt36WestFlag, true);
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt36WestFlag, true);
+ break;
+ case kW38NorthPeopleCrossing:
+ _privateFlags.setFlag(kWSCPrivateSeenPeopleAt38NorthFlag, true);
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt38NorthFlag, true);
+ break;
+ case kW46SouthPeopleCrossing:
+ _privateFlags.setFlag(kWSCPrivateSeenPeopleAt46SouthFlag, true);
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt46SouthFlag, true);
+ break;
+ case kW49NorthPeopleCrossing:
+ _privateFlags.setFlag(kWSCPrivateSeenPeopleAt49NorthFlag, true);
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt49NorthFlag, false);
+ break;
+ case kW73WestPeopleCrossing:
+ _privateFlags.setFlag(kWSCPrivateSeenPeopleAt73WestFlag, true);
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt73WestFlag, false);
+ break;
+ case kW95RobotShoots:
+ case kW98RobotShoots:
+ die(kDeathShotOnCatwalk);
+ break;
+ case kW98MorphsToRobot:
+ if (_argonSprite) {
+ delete _argonSprite; _argonSprite = 0;
+ startExtraSequence(kW98RobotGassed, kExtraCompletedFlag, kFilterNoInput);
+ } else if (_privateFlags.getFlag(kWSCPrivateClickedCatwalkCableFlag)) {
+ startExtraSequence(kW98RobotShocked, kExtraCompletedFlag, kFilterNoInput);
+ } else {
+ startExtraSequence(kW98RobotShoots, kExtraCompletedFlag, kFilterNoInput);
+ }
+ break;
+ case kW98RobotShocked:
+ GameState.setWSCCatwalkDark(true);
+ // Change the gun hot spot...
+ g_allHotspots.setHotspotRect(kW98StunGunSpotID, Common::Rect(181 + kNavAreaLeft, 99 + kNavAreaTop,
+ 372 + kNavAreaLeft, 149 + kNavAreaTop));
+ setCurrentActivation(kActivationRobotDead);
+ GameState.setWSCRobotDead(true);
+ g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/WSC/XN59WD", false, kWarningInterruption);
+ break;
+ case kW98RobotGassed:
+ item = (Item *)g_allItems.findItemByID(kArgonCanister);
+ _vm->addItemToInventory((InventoryItem *)item);
+ setCurrentActivation(kActivationRobotDead);
+ GameState.setWSCRobotDead(true);
+ g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/WSC/XN59WD", false, kWarningInterruption);
+ break;
+ case kW98RobotHeadOpensLight:
+ case kW98RobotHeadOpensDark:
+ setCurrentActivation(kActivationWSCRobotHeadOpen);
+ _privateFlags.setFlag(kWSCPrivateRobotHeadOpenFlag, true);
+ break;
+ case kW98RobotHeadClosesDark:
+ case kW98RobotHeadClosesLight:
+ setCurrentActivation(kActivationRobotGone);
+ _privateFlags.setFlag(kWSCPrivateRobotHeadOpenFlag, false);
+ GameState.setWSCRobotGone(true);
+ break;
+ }
+ }
+
+ Neighborhood::receiveNotification(notification, flags);
+ g_AIArea->checkMiddleArea();
+}
+
+void WSC::timerExpired(const uint32 event) {
+ switch (event) {
+ case kTimerEventPlasmaHit:
+ if (GameState.getShieldOn())
+ g_shield->setItemState(kShieldPlasma);
+ break;
+ case kTimerEventPlayerGawkingAtRobot:
+ startExtraSequence(kW95RobotShoots, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case kTimerEventPlayerGawkingAtRobot2:
+ startExtraSequence(kW98MorphsToRobot, kExtraCompletedFlag, kFilterAllInput);
+ break;
+ }
+}
+
+void WSC::setUpMoleculeGame() {
+ _privateFlags.setFlag(kWSCPrivateInMoleculeGameFlag, true);
+ setCurrentActivation(kActivationW03NorthInGame);
+ initOneMovie(&_moleculesMovie, "Images/World Science Center/Molecules.movie",
+ kWSCMoleculesMovieOrder, kMoleculesMovieLeft, kMoleculesMovieTop, true);
+ _moleculesMovie.redrawMovieWorld();
+ _moleculeBin.initMoleculeBin();
+ _moleculeGameLevel = 0;
+ nextMoleculeGameLevel();
+}
+
+void WSC::nextMoleculeGameLevel() {
+ _moleculeGameLevel++;
+
+ for (byte i = 0; i < 6; ++i)
+ _levelArray[i] = i;
+
+ _vm->shuffleArray((int32 *)_levelArray, 6);
+ _moleculeBin.setBinLayout(_levelArray);
+ startMoleculeGameLevel();
+}
+
+void WSC::startMoleculeGameLevel() {
+ _moleculeBin.resetBin();
+ _numCorrect = 0;
+ _moleculesMovie.stop();
+ _moleculesMovie.setFlags(0);
+ _moleculesMovie.setSegment(s_moleculeLoopTimes[0], s_moleculeLoopTimes[0] + kMoleculeLoopTime);
+ _moleculesMovie.setTime(s_moleculeLoopTimes[0]);
+ _moleculesMovie.setFlags(kLoopTimeBase);
+ _moleculesMovie.show();
+
+ switch (_moleculeGameLevel) {
+ case 1:
+ playSpotSoundSync(kWSCMolecule1In, kWSCMolecule1Out);
+ break;
+ case 2:
+ playSpotSoundSync(kWSCMolecule2In, kWSCMolecule2Out);
+ break;
+ case 3:
+ playSpotSoundSync(kWSCMolecule3In, kWSCMolecule3Out);
+ break;
+ }
+
+ _moleculesMovie.start();
+}
+
+void WSC::moleculeGameClick(const tHotSpotID id) {
+ uint32 molecule = id - kWSC03NorthMolecule1SpotID;
+
+ _moleculeBin.highlightMolecule(molecule);
+ _moleculeBin.selectMolecule(molecule);
+
+ if (molecule == _levelArray[_numCorrect]) {
+ playSpotSoundSync(kWSCClick2In, kWSCClick2Out);
+ _numCorrect++;
+ _moleculesMovie.stop();
+ _moleculesMovie.setFlags(0);
+
+ TimeValue time = _moleculesMovie.getTime();
+ _moleculesMovie.setSegment(s_moleculeLoopTimes[_numCorrect], s_moleculeLoopTimes[_numCorrect] + kMoleculeLoopTime);
+ _moleculesMovie.setTime(s_moleculeLoopTimes[_numCorrect] + time - s_moleculeLoopTimes[_numCorrect - 1]);
+
+ if (_numCorrect == 6) {
+ _moleculesMovie.start();
+
+ while (_moleculesMovie.isRunning()) {
+ _vm->checkCallBacks();
+ _vm->refreshDisplay();
+ _vm->_system->delayMillis(10);
+ }
+
+ _moleculesMovie.stop();
+ _moleculesMovie.hide();
+
+ switch (_moleculeGameLevel) {
+ case 1:
+ startExtraSequence(kW03NorthPrepMolecule2, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case 2:
+ startExtraSequence(kW03NorthPrepMolecule3, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case 3:
+ _moleculesMovie.releaseMovie();
+ _moleculeBin.cleanUpMoleculeBin();
+ requestExtraSequence(kW03NorthFinishSynthesis, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ }
+ } else {
+ _moleculesMovie.setFlags(kLoopTimeBase);
+ _moleculesMovie.start();
+ }
+ } else {
+ // FAIL
+ playSpotSoundSync(kWSCClick3In, kWSCClick3Out);
+
+ _moleculesMovie.stop();
+ _moleculesMovie.setFlags(0);
+ _moleculesMovie.start();
+
+ while (_moleculesMovie.isRunning()) {
+ _vm->checkCallBacks();
+ _vm->refreshDisplay();
+ _vm->_system->delayMillis(10);
+ }
+
+ _moleculesMovie.stop();
+ _moleculesMovie.setFlags(0);
+ _moleculesMovie.setSegment(s_moleculeFailTimes[_numCorrect], s_moleculeFailTimes[_numCorrect] + kMoleculeFailTime);
+ _moleculesMovie.setTime(s_moleculeFailTimes[_numCorrect]);
+ _moleculesMovie.start();
+
+
+ while (_moleculesMovie.isRunning()) {
+ _vm->checkCallBacks();
+ _vm->refreshDisplay();
+ _vm->_system->delayMillis(10);
+ }
+
+ _moleculesMovie.stop();
+ startMoleculeGameLevel();
+ }
+}
+
+void WSC::activateOneHotspot(HotspotInfoTable::Entry &entry, Hotspot *hotspot) {
+ Neighborhood::activateOneHotspot(entry, hotspot);
+
+ Item *argonCanister;
+
+ switch (hotspot->getObjectID()) {
+ case kWSCTurnOnAnalyzerSpotID:
+ if (GameState.getWSCAnalyzerOn())
+ hotspot->setInactive();
+ break;
+ case kWSC02SouthTakeArgonSpotID:
+ if (!GameState.getWSCSawMorph() || GameState.isTakenItemID(kArgonCanister))
+ hotspot->setInactive();
+ break;
+ case kWSC02ActivateMorphScreenSpotID:
+ if (GameState.getWSCSawMorph())
+ hotspot->setInactive();
+ break;
+ case kWSC03NorthMolecule1SpotID:
+ case kWSC03NorthMolecule2SpotID:
+ case kWSC03NorthMolecule3SpotID:
+ case kWSC03NorthMolecule4SpotID:
+ case kWSC03NorthMolecule5SpotID:
+ case kWSC03NorthMolecule6SpotID:
+ if (_moleculeBin.isMoleculeHighlighted(hotspot->getObjectID() - kWSC03NorthMolecule1SpotID))
+ hotspot->setInactive();
+ break;
+ case kWSC03SouthPickUpAntidoteSpotID:
+ if (getCurrentActivation() == kActivationSynthesizerLooping)
+ hotspot->setActive();
+ break;
+ case kW98DropArgonSpotID:
+ argonCanister = g_allItems.findItemByID(kArgonCanister);
+ if (argonCanister->getItemState() != kArgonFull)
+ hotspot->setInactive();
+ break;
+ }
+}
+
+void WSC::activateHotspots() {
+ Neighborhood::activateHotspots();
+
+ if (GameState.getCurrentRoomAndView() == MakeRoomView(kWSC98, kWest) && _privateFlags.getFlag(kWSCPrivateRobotHeadOpenFlag)) {
+ if (_privateFlags.getFlag(kWSCPrivateGotRetScanChipFlag))
+ g_allHotspots.deactivateOneHotspot(kW98RetinalChipSpotID);
+ else
+ g_allHotspots.activateOneHotspot(kW98RetinalChipSpotID);
+
+ if (_privateFlags.getFlag(kWSCPrivateGotMapChipFlag))
+ g_allHotspots.deactivateOneHotspot(kW98MapChipSpotID);
+ else
+ g_allHotspots.activateOneHotspot(kW98MapChipSpotID);
+
+ if (_privateFlags.getFlag(kWSCPrivateGotOpticalChipFlag))
+ g_allHotspots.deactivateOneHotspot(kW98OpticalChipSpotID);
+ else
+ g_allHotspots.activateOneHotspot(kW98OpticalChipSpotID);
+ }
+}
+
+void WSC::clickInHotspot(const Input &input, const Hotspot *clickedSpot) {
+ if (JMPPPInput::isEasterEggModifierInput(input))
+ GameState.setEasterEgg(true);
+
+ if (clickedSpot) {
+ switch (clickedSpot->getObjectID()) {
+ case kWSCAnalyzerScreenSpotID:
+ requestExtraSequence(kWSCAnalyzeDart, kExtraCompletedFlag, kFilterNoInput);
+ requestExtraSequence(kWSCZoomOutFromAnalyzer, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case kWSC02SouthPlayMessagesSpotID:
+ if (GameState.isTakenItemID(kNitrogenCanister)) {
+ if (_lastExtra == (uint32)kMessagesMovedToOfficeNoNitrogen)
+ startExtraSequence(kMessagesOffNoNitrogen, kExtraCompletedFlag, kFilterNoInput);
+ else
+ startExtraSequence(kMessagesMovedToOfficeNoNitrogen, kExtraCompletedFlag, kFilterNoInput);
+ } else {
+ if (_lastExtra == (uint32)kMessagesMovedToOffice)
+ startExtraSequence(kMessagesOff, kExtraCompletedFlag, kFilterNoInput);
+ else
+ startExtraSequence(kMessagesMovedToOffice, kExtraCompletedFlag, kFilterNoInput);
+ }
+ break;
+ case kWSC02SouthInterruptMorphSpotID:
+ _privateFlags.setFlag(kWSCPrivateInterruptedMorphFlag, true);
+ break;
+ case kWSC02SouthMorphFinishedSpotID:
+ requestExtraSequence(kWSC02MorphFinished, 0, kFilterNoInput);
+ requestExtraSequence(kWSC02TurnOffMorphScreen, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case kWSC03NorthMolecule1SpotID:
+ case kWSC03NorthMolecule2SpotID:
+ case kWSC03NorthMolecule3SpotID:
+ case kWSC03NorthMolecule4SpotID:
+ case kWSC03NorthMolecule5SpotID:
+ case kWSC03NorthMolecule6SpotID:
+ moleculeGameClick(clickedSpot->getObjectID());
+ break;
+ case kW98GrabCableSpotID:
+ if (isEventTimerRunning()) {
+ cancelEvent();
+ startExtraSequence(kW98MorphsToRobot, kExtraCompletedFlag, kFilterAllInput);
+ }
+
+ _privateFlags.setFlag(kWSCPrivateClickedCatwalkCableFlag, true);
+ break;
+ default:
+ Neighborhood::clickInHotspot(input, clickedSpot);
+ break;
+ }
+ } else {
+ Neighborhood::clickInHotspot(input, clickedSpot);
+ }
+
+ GameState.setEasterEgg(false);
+}
+
+void WSC::dropItemIntoRoom(Item *item, Hotspot *dropSpot) {
+ tCoordType h, v;
+
+ switch (item->getObjectID()) {
+ case kPoisonDart:
+ Neighborhood::dropItemIntoRoom(item, dropSpot);
+ GameState.setWSCDartInAnalyzer(true);
+ if (dropSpot && dropSpot->getObjectID() == kWSCDropDartSpotID) {
+ if (!GameState.getWSCAnalyzerOn())
+ requestExtraSequence(kWSCAnalyzerPowerUpWithDart, kExtraCompletedFlag, kFilterNoInput);
+
+ requestExtraSequence(kWSCDropDartIntoAnalyzer, kExtraCompletedFlag, kFilterNoInput);
+ }
+ break;
+ case kAntidote:
+ _privateFlags.setFlag(kWSCDraggingAntidoteFlag, false);
+ Neighborhood::dropItemIntoRoom(item, dropSpot);
+ loopExtraSequence(kW03SouthAntidoteLoop);
+ break;
+ case kSinclairKey:
+ Neighborhood::dropItemIntoRoom(item, dropSpot);
+ _privateFlags.setFlag(kWSCPrivateSinclairOfficeOpenFlag, true);
+ openDoor();
+ break;
+ case kCrowbar:
+ Neighborhood::dropItemIntoRoom(item, dropSpot);
+ _privateFlags.setFlag(kWSCPrivate58SouthOpenFlag, true);
+ openDoor();
+ break;
+ case kMachineGun:
+ setCurrentAlternate(kAltWSCNormal);
+ Neighborhood::dropItemIntoRoom(item, dropSpot);
+ break;
+ case kArgonCanister:
+ item->setItemState(kArgonEmpty);
+ _argonSprite = item->getDragSprite(0);
+ _argonSprite->setCurrentFrameIndex(1);
+ _argonSprite->setDisplayOrder(kDragSpriteOrder);
+ dropSpot->getCenter(h, v);
+ _argonSprite->centerElementAt(h, v);
+ _argonSprite->startDisplaying();
+ _argonSprite->show();
+
+ if (isEventTimerRunning()) {
+ cancelEvent();
+ startExtraSequence(kW98MorphsToRobot, kExtraCompletedFlag, kFilterAllInput);
+ }
+ break;
+ case kRetinalScanBiochip:
+ _privateFlags.setFlag(kWSCPrivateGotRetScanChipFlag, false);
+ Neighborhood::dropItemIntoRoom(item, dropSpot);
+ break;
+ case kMapBiochip:
+ _privateFlags.setFlag(kWSCPrivateGotMapChipFlag, false);
+ Neighborhood::dropItemIntoRoom(item, dropSpot);
+ break;
+ case kOpticalBiochip:
+ _privateFlags.setFlag(kWSCPrivateGotOpticalChipFlag, false);
+ Neighborhood::dropItemIntoRoom(item, dropSpot);
+ break;
+ default:
+ Neighborhood::dropItemIntoRoom(item, dropSpot);
+ break;
+ }
+}
+
+void WSC::takeItemFromRoom(Item *item) {
+ switch (item->getObjectID()) {
+ case kAntidote:
+ _privateFlags.setFlag(kWSCDraggingAntidoteFlag, true);
+ Neighborhood::takeItemFromRoom(item);
+ break;
+ case kMachineGun:
+ setCurrentAlternate(kAltWSCTookMachineGun);
+ Neighborhood::takeItemFromRoom(item);
+ break;
+ case kRetinalScanBiochip:
+ _privateFlags.setFlag(kWSCPrivateGotRetScanChipFlag, true);
+ Neighborhood::takeItemFromRoom(item);
+ break;
+ case kMapBiochip:
+ _privateFlags.setFlag(kWSCPrivateGotMapChipFlag, true);
+ Neighborhood::takeItemFromRoom(item);
+ break;
+ case kOpticalBiochip:
+ _privateFlags.setFlag(kWSCPrivateGotOpticalChipFlag, true);
+ Neighborhood::takeItemFromRoom(item);
+ break;
+ default:
+ Neighborhood::takeItemFromRoom(item);
+ break;
+ }
+}
+
+Hotspot *WSC::getItemScreenSpot(Item *item, DisplayElement *element) {
+ tHotSpotID destSpotID;
+
+ switch (item->getObjectID()) {
+ case kNitrogenCanister:
+ destSpotID = kWSC02SouthTakeNitrogenSpotID;
+ break;
+ case kArgonPickup:
+ destSpotID = kWSC02SouthTakeArgonSpotID;
+ break;
+ case kAntidote:
+ destSpotID = kWSC03SouthPickUpAntidoteSpotID;
+ break;
+ case kMachineGun:
+ destSpotID = kW61SouthMachineGunSpotID;
+ break;
+ case kRetinalScanBiochip:
+ destSpotID = kW98RetinalChipSpotID;
+ break;
+ case kMapBiochip:
+ destSpotID = kW98MapChipSpotID;
+ break;
+ case kOpticalBiochip:
+ destSpotID = kW98OpticalChipSpotID;
+ break;
+ default:
+ destSpotID = kNoHotSpotID;
+ break;
+ }
+
+ if (destSpotID == kNoHotSpotID)
+ return Neighborhood::getItemScreenSpot(item, element);
+
+ return g_allHotspots.findHotspotByID(destSpotID);
+}
+
+void WSC::pickedUpItem(Item *item) {
+ switch (item->getObjectID()) {
+ case kAntidote:
+ if (!GameState.getWSCPickedUpAntidote()) {
+ GameState.setWSCPoisoned(false);
+ GameState.setWSCRemovedDart(false);
+ GameState.setWSCPickedUpAntidote(true);
+ _privateFlags.setFlag(kWSCDraggingAntidoteFlag, false);
+ playSpotSoundSync(kDrinkAntidoteIn, kDrinkAntidoteOut);
+ setUpPoison();
+ startExtraSequence(kW03SouthDeactivate, kExtraCompletedFlag, kFilterNoInput);
+ }
+ break;
+ case kArgonPickup:
+ _vm->removeItemFromInventory((InventoryItem *)item);
+ item = (Item *)g_allItems.findItemByID(kArgonCanister);
+ _vm->addItemToInventory((InventoryItem *)item);
+ item = (Item *)g_allItems.findItemByID(kSinclairKey);
+ _vm->addItemToInventory((InventoryItem *)item);
+ g_allHotspots.setHotspotRect(kWSC02SouthMorphOutSpotID,
+ Common::Rect(kNavAreaLeft, kNavAreaTop, 512 + kNavAreaLeft, 256 + kNavAreaTop));
+ break;
+ case kArgonCanister:
+ GameState.setScoringGotArgonCanister();
+ break;
+ case kSinclairKey:
+ GameState.setScoringGotSinclairKey();
+ break;
+ case kNitrogenCanister:
+ GameState.setScoringGotNitrogenCanister();
+ break;
+ case kRetinalScanBiochip:
+ if (_privateFlags.getFlag(kWSCPrivateGotMapChipFlag) && _privateFlags.getFlag(kWSCPrivateGotOpticalChipFlag)) {
+ if (GameState.getWSCCatwalkDark())
+ startExtraSequence(kW98RobotHeadClosesDark, kExtraCompletedFlag, kFilterNoInput);
+ else
+ startExtraSequence(kW98RobotHeadClosesLight, kExtraCompletedFlag, kFilterNoInput);
+ }
+ break;
+ case kMapBiochip:
+ if (_privateFlags.getFlag(kWSCPrivateGotRetScanChipFlag) && _privateFlags.getFlag(kWSCPrivateGotOpticalChipFlag)) {
+ if (GameState.getWSCCatwalkDark())
+ startExtraSequence(kW98RobotHeadClosesDark, kExtraCompletedFlag, kFilterNoInput);
+ else
+ startExtraSequence(kW98RobotHeadClosesLight, kExtraCompletedFlag, kFilterNoInput);
+ }
+ break;
+ case kOpticalBiochip:
+ g_opticalChip->addMercury();
+ GameState.setScoringGotWSCOpMemChip();
+ if (_privateFlags.getFlag(kWSCPrivateGotRetScanChipFlag) && _privateFlags.getFlag(kWSCPrivateGotMapChipFlag)) {
+ if (GameState.getWSCCatwalkDark())
+ startExtraSequence(kW98RobotHeadClosesDark, kExtraCompletedFlag, kFilterNoInput);
+ else
+ startExtraSequence(kW98RobotHeadClosesLight, kExtraCompletedFlag, kFilterNoInput);
+ }
+ break;
+ case kStunGun:
+ GameState.setWSCFinished(true);
+
+ if (!GameState.getWSCCatwalkDark())
+ GameState.setScoringWSCGandhi();
+
+ recallToTSASuccess();
+ break;
+ }
+}
+
+void WSC::checkPeopleCrossing() {
+ switch (GameState.getCurrentRoomAndView()) {
+ case MakeRoomView(kWSC17, kWest):
+ if (_privateFlags.getFlag(kWSCPrivateNeedPeopleAt17WestFlag))
+ startExtraSequence(kW17WestPeopleCrossing, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case MakeRoomView(kWSC21, kSouth):
+ if (_privateFlags.getFlag(kWSCPrivateNeedPeopleAt21SouthFlag))
+ startExtraSequence(kW21SouthPeopleCrossing, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case MakeRoomView(kWSC24, kSouth):
+ if (_privateFlags.getFlag(kWSCPrivateNeedPeopleAt24SouthFlag))
+ startExtraSequence(kW24SouthPeopleCrossing, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case MakeRoomView(kWSC34, kEast):
+ if (_privateFlags.getFlag(kWSCPrivateNeedPeopleAt34EastFlag))
+ startExtraSequence(kW34EastPeopleCrossing, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case MakeRoomView(kWSC36, kWest):
+ if (_privateFlags.getFlag(kWSCPrivateNeedPeopleAt36WestFlag))
+ startExtraSequence(kW36WestPeopleCrossing, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case MakeRoomView(kWSC38, kNorth):
+ if (_privateFlags.getFlag(kWSCPrivateNeedPeopleAt38NorthFlag))
+ startExtraSequence(kW38NorthPeopleCrossing, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case MakeRoomView(kWSC46, kSouth):
+ if (_privateFlags.getFlag(kWSCPrivateNeedPeopleAt46SouthFlag))
+ startExtraSequence(kW46SouthPeopleCrossing, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case MakeRoomView(kWSC49, kNorth):
+ if (_privateFlags.getFlag(kWSCPrivateNeedPeopleAt49NorthFlag))
+ startExtraSequence(kW49NorthPeopleCrossing, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ case MakeRoomView(kWSC73, kWest):
+ if (_privateFlags.getFlag(kWSCPrivateNeedPeopleAt73WestFlag))
+ startExtraSequence(kW73WestPeopleCrossing, kExtraCompletedFlag, kFilterNoInput);
+ break;
+ default:
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt21SouthFlag) && _vm->getRandomNumber(2) == 0) {
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt21SouthFlag, true);
+ forceStridingStop(kWSC18, kSouth, kAltWSCNormal);
+ } else {
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt21SouthFlag, false);
+ restoreStriding(kWSC18, kSouth, kAltWSCNormal);
+ }
+
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt19NorthFlag) && _vm->getRandomNumber(2) == 0) {
+ forceStridingStop(kWSC22, kNorth, kAltWSCNormal);
+ } else {
+ restoreStriding(kWSC22, kNorth, kAltWSCNormal);
+ }
+
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt24SouthFlag) && _vm->getRandomNumber(2) == 0) {
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt24SouthFlag, true);
+ forceStridingStop(kWSC22, kSouth, kAltWSCNormal);
+ } else {
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt24SouthFlag, false);
+ restoreStriding(kWSC22, kSouth, kAltWSCNormal);
+ }
+
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt34EastFlag) && _vm->getRandomNumber(2) == 0) {
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt34EastFlag, true);
+ forceStridingStop(kWSC28, kEast, kAltWSCNormal);
+ } else {
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt34EastFlag, false);
+ restoreStriding(kWSC28, kEast, kAltWSCNormal);
+ }
+
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt36WestFlag) && _vm->getRandomNumber(2) == 0) {
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt36WestFlag, true);
+ forceStridingStop(kWSC40, kWest, kAltWSCNormal);
+ } else {
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt36WestFlag, false);
+ restoreStriding(kWSC40, kWest, kAltWSCNormal);
+ }
+
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt38NorthFlag) && _vm->getRandomNumber(2) == 0) {
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt38NorthFlag, true);
+ forceStridingStop(kWSC42, kNorth, kAltWSCNormal);
+ } else {
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt38NorthFlag, false);
+ restoreStriding(kWSC42, kNorth, kAltWSCNormal);
+ }
+
+ if (!_privateFlags.getFlag(kWSCPrivateSeenPeopleAt46SouthFlag) && _vm->getRandomNumber(2) == 0) {
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt46SouthFlag, true);
+ forceStridingStop(kWSC44, kSouth, kAltWSCNormal);
+ } else {
+ _privateFlags.setFlag(kWSCPrivateNeedPeopleAt46SouthFlag, false);
+ restoreStriding(kWSC44, kSouth, kAltWSCNormal);
+ }
+ break;
+ }
+}
+
+void WSC::setUpPoison() {
+ if (GameState.getWSCPoisoned()) {
+ if (GameState.getWSCRemovedDart()) {
+ if (g_energyMonitor->getEnergyDrainRate() != kWSCPoisonEnergyDrainNoDart) {
+ g_energyMonitor->setEnergyDrainRate(kWSCPoisonEnergyDrainNoDart);
+ _vm->setEnergyDeathReason(kDeathDidntStopPoison);
+ }
+ } else {
+ if (g_energyMonitor->getEnergyDrainRate() != kWSCPoisonEnergyDrainWithDart) {
+ g_energyMonitor->setEnergyDrainRate(kWSCPoisonEnergyDrainWithDart);
+ _vm->setEnergyDeathReason(kDeathDidntStopPoison);
+ }
+ }
+ } else if (g_energyMonitor->getEnergyDrainRate() != kEnergyDrainNormal) {
+ g_energyMonitor->setEnergyDrainRate(kEnergyDrainNormal);
+ _vm->resetEnergyDeathReason();
+ }
+}
+
+bool WSC::inSynthesizerGame() {
+ return _moleculesMovie.isMovieValid();
+}
+
+bool WSC::canSolve() {
+ return (inSynthesizerGame() || (GameState.getCurrentRoom() == kWSC98 && !GameState.getWSCRobotDead()));
+}
+
+void WSC::doSolve() {
+ if (inSynthesizerGame()) {
+ _moleculesMovie.releaseMovie();
+ _moleculeBin.cleanUpMoleculeBin();
+ requestExtraSequence(kW03NorthFinishSynthesis, kExtraCompletedFlag, kFilterNoInput);
+ } else if (GameState.getCurrentRoom() == kWSC98 && !GameState.getWSCRobotDead()) {
+ cancelEvent();
+ startExtraSequence(kW98RobotShocked, kExtraCompletedFlag, kFilterNoInput);
+ }
+}
+
+Common::String WSC::getNavMovieName() {
+ return "Images/World Science Center/WSC.movie";
+}
+
+Common::String WSC::getSoundSpotsName() {
+ return "Sounds/World Science Center/WSC Spots";
+}
+
+} // End of namespace Pegasus
diff --git a/engines/pegasus/neighborhood/wsc/wsc.h b/engines/pegasus/neighborhood/wsc/wsc.h
new file mode 100755
index 0000000000..554c2f713d
--- /dev/null
+++ b/engines/pegasus/neighborhood/wsc/wsc.h
@@ -0,0 +1,163 @@
+/* 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.
+ *
+ */
+
+#ifndef PEGASUS_NEIGHBORHOOD_WSC_WSC_H
+#define PEGASUS_NEIGHBORHOOD_WSC_WSC_H
+
+#include "pegasus/neighborhood/neighborhood.h"
+#include "pegasus/neighborhood/wsc/moleculebin.h"
+
+namespace Pegasus {
+
+const tDisplayOrder kWSCMoleculeBinOrder = kMonitorLayer;
+const tDisplayOrder kWSCMoleculesMovieOrder = kWSCMoleculeBinOrder + 1;
+
+const tRoomID kWSC01 = 0;
+
+class WSC : public Neighborhood {
+public:
+ WSC(InputHandler *, PegasusEngine *);
+ virtual ~WSC() {}
+
+ void flushGameState();
+
+ virtual uint16 getDateResID() const;
+
+ bool okayToJump();
+
+ void checkContinuePoint(const tRoomID, const tDirectionConstant);
+
+ bool inSynthesizerGame();
+
+ bool canSolve();
+ void doSolve();
+
+ virtual void prepareForAIHint(const Common::String &);
+ virtual void cleanUpAfterAIHint(const Common::String &);
+
+ void init();
+ void start();
+
+protected:
+ enum {
+ kWSCDraggingAntidoteFlag,
+
+ kWSCPrivateLabMessagesOpenFlag,
+ kWSCPrivateInterruptedMorphFlag,
+ kWSCPrivateInMoleculeGameFlag,
+ kWSCPrivateSinclairOfficeOpenFlag,
+ kWSCPrivateOfficeLogOpenFlag,
+ kWSCPrivate58SouthOpenFlag,
+ kWSCPrivateClickedCatwalkCableFlag,
+ kWSCPrivateRobotHeadOpenFlag,
+
+ kWSCPrivateSeenPeopleAt17WestFlag,
+ kWSCPrivateSeenPeopleAt19NorthFlag,
+ kWSCPrivateSeenPeopleAt21SouthFlag,
+ kWSCPrivateSeenPeopleAt24SouthFlag,
+ kWSCPrivateSeenPeopleAt34EastFlag,
+ kWSCPrivateSeenPeopleAt36WestFlag,
+ kWSCPrivateSeenPeopleAt38NorthFlag,
+ kWSCPrivateSeenPeopleAt46SouthFlag,
+ kWSCPrivateSeenPeopleAt49NorthFlag,
+ kWSCPrivateSeenPeopleAt73WestFlag,
+
+ kWSCPrivateNeedPeopleAt17WestFlag,
+ kWSCPrivateNeedPeopleAt21SouthFlag,
+ kWSCPrivateNeedPeopleAt24SouthFlag,
+ kWSCPrivateNeedPeopleAt34EastFlag,
+ kWSCPrivateNeedPeopleAt36WestFlag,
+ kWSCPrivateNeedPeopleAt38NorthFlag,
+ kWSCPrivateNeedPeopleAt46SouthFlag,
+ kWSCPrivateNeedPeopleAt49NorthFlag,
+ kWSCPrivateNeedPeopleAt73WestFlag,
+
+ kWSCPrivateGotRetScanChipFlag,
+ kWSCPrivateGotMapChipFlag,
+ kWSCPrivateGotOpticalChipFlag,
+
+ kNumWSCPrivateFlags
+ };
+
+ void arriveAt(const tRoomID, const tDirectionConstant);
+ void turnTo(const tDirectionConstant);
+ void receiveNotification(Notification *, const tNotificationFlags);
+ void dropItemIntoRoom(Item *, Hotspot *);
+ void clickInHotspot(const Input &, const Hotspot *);
+ TimeValue getViewTime(const tRoomID, const tDirectionConstant);
+ void getZoomEntry(const tHotSpotID, ZoomTable::Entry &);
+ tCanMoveForwardReason canMoveForward(ExitTable::Entry &entry);
+ void cantMoveThatWay(tCanMoveForwardReason reason);
+ tCanTurnReason canTurn(tTurnDirection turn, tDirectionConstant &nextDir);
+ void zoomTo(const Hotspot *hotspot);
+ void activateOneHotspot(HotspotInfoTable::Entry &, Hotspot *);
+ void setUpMoleculeGame();
+ void nextMoleculeGameLevel();
+ void startMoleculeGameLevel();
+ void moleculeGameClick(const tHotSpotID);
+ void loadAmbientLoops();
+ tCanOpenDoorReason canOpenDoor(DoorTable::Entry &);
+ void cantOpenDoor(tCanOpenDoorReason);
+ void pickedUpItem(Item *);
+ void doorOpened();
+ void startExtraSequence(const tExtraID, const tNotificationFlags, const tInputBits);
+ void getExtraEntry(const uint32, ExtraTable::Entry &);
+ void takeItemFromRoom(Item *item);
+ void checkPeopleCrossing();
+ void turnLeft();
+ void turnRight();
+ void moveForward();
+ Hotspot *getItemScreenSpot(Item *, DisplayElement *);
+ int16 getStaticCompassAngle(const tRoomID, const tDirectionConstant);
+ void getExitCompassMove(const ExitTable::Entry &exitEntry, FaderMoveSpec &compassMove);
+ void getExtraCompassMove(const ExtraTable::Entry &entry, FaderMoveSpec &compassMove);
+ void bumpIntoWall();
+ void activateHotspots();
+ void setUpAIRules();
+ Common::String getBriefingMovie();
+ Common::String getEnvScanMovie();
+ uint getNumHints();
+ Common::String getHintMovie(uint);
+ void closeDoorOffScreen(const tRoomID, const tDirectionConstant);
+ void setUpPoison();
+ void findSpotEntry(const tRoomID, const tDirectionConstant, tSpotFlags, SpotTable::Entry &);
+ void timerExpired(const uint32);
+
+ Common::String getSoundSpotsName();
+ Common::String getNavMovieName();
+
+ FlagsArray<byte, kNumWSCPrivateFlags> _privateFlags;
+ const Hotspot *_cachedZoomSpot;
+ MoleculeBin _moleculeBin;
+ int32 _moleculeGameLevel, _numCorrect;
+ Movie _moleculesMovie;
+ uint32 _levelArray[6];
+ Common::Rational _energyDrainRate;
+ Sprite *_argonSprite;
+};
+
+} // End of namespace Pegasus
+
+#endif