Initial commit
This commit is contained in:
224
engines/pegasus/neighborhood/norad/alpha/ecrmonitor.cpp
Normal file
224
engines/pegasus/neighborhood/norad/alpha/ecrmonitor.cpp
Normal file
@@ -0,0 +1,224 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/items/biochips/arthurchip.h"
|
||||
#include "pegasus/neighborhood/norad/constants.h"
|
||||
#include "pegasus/neighborhood/norad/norad.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/ecrmonitor.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
static const NotificationFlags kECRSection1FinishedFlag = 1;
|
||||
static const NotificationFlags kECRPanFinishedFlag = kECRSection1FinishedFlag << 1;
|
||||
static const NotificationFlags kECRSection2FinishedFlag = kECRPanFinishedFlag << 1;
|
||||
static const NotificationFlags kECRNotificationFlags = kECRSection1FinishedFlag |
|
||||
kECRPanFinishedFlag |
|
||||
kECRSection2FinishedFlag;
|
||||
|
||||
static const TimeValue kSection1Start = 0;
|
||||
static const TimeValue kSection1Stop = 25;
|
||||
static const TimeValue kPanStart = 0;
|
||||
static const TimeValue kPanStop = 20;
|
||||
static const TimeValue kSection2Start = 26;
|
||||
static const TimeValue kSection2Stop = 1000;
|
||||
|
||||
// Seems to be a good value for a 20 second pan.
|
||||
enum {
|
||||
kPanPixelsPerFrame = 8
|
||||
};
|
||||
|
||||
// Interesting times are in seconds.
|
||||
static const TimeValue s_ECRInterestingTimes[] = {
|
||||
0, 1, 2, 10, 25, 26, 56, 64, 72, 80, 88, 94, 102, 108, 116, 999
|
||||
};
|
||||
|
||||
// Index into s_ECRInterestingTimes of interesting time before security pan.
|
||||
static const int kBeforePanTime = 3;
|
||||
|
||||
// Index into s_ECRInterestingTimes of interesting time after security pan.
|
||||
static const int kAfterPanTime = 5;
|
||||
|
||||
NoradAlphaECRMonitor::NoradAlphaECRMonitor(Neighborhood *nextHandler) : GameInteraction(kNoradECRMonitorInteractionID, nextHandler),
|
||||
_ecrSlideShowNotification(kNoradECRNotificationID, g_vm), _ecrMovie(kECRSlideShowMovieID),
|
||||
_ecrPan(kECRPanID) {
|
||||
}
|
||||
|
||||
void NoradAlphaECRMonitor::receiveNotification(Notification *, const NotificationFlags flags) {
|
||||
if (flags & kECRSection1FinishedFlag)
|
||||
ecrSection1Finished();
|
||||
else if (flags & kECRPanFinishedFlag)
|
||||
ecrPanFinished();
|
||||
else if (flags & kECRSection2FinishedFlag)
|
||||
ecrSection2Finished();
|
||||
}
|
||||
|
||||
int NoradAlphaECRMonitor::findCurrentInterestingTime() {
|
||||
TimeValue time = _ecrMovie.getTime();
|
||||
TimeScale scale = _ecrMovie.getScale();
|
||||
|
||||
for (int i = ARRAYSIZE(s_ECRInterestingTimes) - 1; i >= 0; i--)
|
||||
if (time >= s_ECRInterestingTimes[i] * scale)
|
||||
return i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void NoradAlphaECRMonitor::skipToNextInterestingTime() {
|
||||
if (_ecrMovie.isRunning()) {
|
||||
int interestingTime = findCurrentInterestingTime();
|
||||
_ecrMovie.setTime(s_ECRInterestingTimes[interestingTime + 1] * _ecrMovie.getScale());
|
||||
_ecrMovie.redrawMovieWorld();
|
||||
} else if (_ecrPan.isRunning()) {
|
||||
_ecrPanCallBack.cancelCallBack();
|
||||
ecrPanFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlphaECRMonitor::skipToPreviousInterestingTime() {
|
||||
if (_ecrPan.isRunning()) {
|
||||
_ecrPan.stop();
|
||||
_ecrPan.stopDisplaying();
|
||||
_ecrPanCallBack.cancelCallBack();
|
||||
|
||||
_ecrMovieCallBack.setCallBackFlag(kECRSection1FinishedFlag);
|
||||
_ecrMovieCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
|
||||
TimeScale scale = _ecrMovie.getScale();
|
||||
_ecrMovie.setSegment(kSection1Start * scale, kSection1Stop * scale + 1);
|
||||
_ecrMovie.setTime(s_ECRInterestingTimes[kBeforePanTime] * scale);
|
||||
_ecrMovie.start();
|
||||
} else {
|
||||
int interestingTime = findCurrentInterestingTime();
|
||||
|
||||
if (interestingTime == kAfterPanTime) {
|
||||
_ecrMovieCallBack.cancelCallBack();
|
||||
TimeScale scale = _ecrMovie.getScale();
|
||||
_ecrMovie.setSegment(kSection1Start * scale, kSection1Stop * scale + 1);
|
||||
_ecrMovie.setTime(kSection1Stop * scale);
|
||||
ecrSection1Finished();
|
||||
} else if (interestingTime == 0) {
|
||||
_ecrMovie.setTime(kSection1Start * _ecrMovie.getScale());
|
||||
_ecrMovie.redrawMovieWorld();
|
||||
} else {
|
||||
_ecrMovie.setTime(s_ECRInterestingTimes[interestingTime - 1] * _ecrMovie.getScale());
|
||||
_ecrMovie.redrawMovieWorld();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlphaECRMonitor::handleInput(const Input &input, const Hotspot *cursorSpot) {
|
||||
if (isInteracting()) {
|
||||
if (input.rightButtonDown())
|
||||
skipToNextInterestingTime();
|
||||
else if (input.leftButtonDown())
|
||||
skipToPreviousInterestingTime();
|
||||
else
|
||||
InputHandler::handleInput(input, cursorSpot);
|
||||
} else {
|
||||
InputHandler::handleInput(input, cursorSpot);
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlphaECRMonitor::ecrSection1Finished() {
|
||||
_ecrMovie.stop();
|
||||
_ecrPanCallBack.setNotification(&_ecrSlideShowNotification);
|
||||
_ecrPanCallBack.initCallBack(&_ecrPan, kCallBackAtExtremes);
|
||||
_ecrPanCallBack.setCallBackFlag(kECRPanFinishedFlag);
|
||||
_ecrSlideShowNotification.notifyMe(this, kECRNotificationFlags, kECRNotificationFlags);
|
||||
_ecrPanCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
_ecrPan.startDisplaying();
|
||||
_ecrPan.show();
|
||||
|
||||
TimeScale scale = _ecrPan.getScale();
|
||||
_ecrPan.setSegment(kPanStart * scale, kPanStop * scale);
|
||||
_ecrPan.setTime(0);
|
||||
_ecrPan.start();
|
||||
}
|
||||
|
||||
void NoradAlphaECRMonitor::ecrPanFinished() {
|
||||
_ecrPan.stop();
|
||||
_ecrPan.stopDisplaying();
|
||||
_ecrMovieCallBack.setCallBackFlag(kECRSection2FinishedFlag);
|
||||
_ecrMovieCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
|
||||
TimeScale scale = _ecrMovie.getScale();
|
||||
_ecrMovie.setSegment(kSection2Start * scale, kSection2Stop * scale);
|
||||
_ecrMovie.start();
|
||||
}
|
||||
|
||||
void NoradAlphaECRMonitor::ecrSection2Finished() {
|
||||
_ecrMovie.stop();
|
||||
_ecrMovie.stopDisplaying();
|
||||
}
|
||||
|
||||
void NoradAlphaECRMonitor::openInteraction() {
|
||||
// Initialize the security pan.
|
||||
_ecrPan.initFromMovieFile("Images/Norad Alpha/Security Pan.pano");
|
||||
_ecrPan.initMaskFromPICTFile("Images/Norad Alpha/Security Pan Mask");
|
||||
_ecrPan.setBounds(Common::Rect(kECRPanLeft, kECRPanTop, kECRPanRight, kECRPanBottom));
|
||||
_ecrPan.setDisplayOrder(kECRPanOrder);
|
||||
_ecrPan.setScale(15); // 15 fps.
|
||||
|
||||
// Begin the lame ECR slide show.
|
||||
// clone2727: I didn't say it :P
|
||||
_ecrMovie.initFromMovieFile("Images/Norad Alpha/ECR Monitor Movie");
|
||||
|
||||
_ecrMovieCallBack.setNotification(&_ecrSlideShowNotification);
|
||||
_ecrMovieCallBack.initCallBack(&_ecrMovie, kCallBackAtExtremes);
|
||||
_ecrMovieCallBack.setCallBackFlag(kECRSection1FinishedFlag);
|
||||
|
||||
_ecrSlideShowNotification.notifyMe(this, kECRNotificationFlags, kECRNotificationFlags);
|
||||
_ecrMovieCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
|
||||
_ecrMovie.moveElementTo(kECRSlideShowLeft, kECRSlideShowTop);
|
||||
_ecrMovie.setDisplayOrder(kECRMonitorOrder);
|
||||
_ecrMovie.startDisplaying();
|
||||
_ecrMovie.show();
|
||||
_ecrMovie.redrawMovieWorld();
|
||||
|
||||
TimeScale scale = _ecrMovie.getScale();
|
||||
_ecrMovie.setSegment(kSection1Start * scale, kSection1Stop * scale + 1);
|
||||
|
||||
_ecrMovie.start();
|
||||
}
|
||||
|
||||
void NoradAlphaECRMonitor::closeInteraction() {
|
||||
_ecrMovieCallBack.releaseCallBack();
|
||||
_ecrMovie.stop();
|
||||
_ecrMovie.stopDisplaying();
|
||||
_ecrMovie.releaseMovie();
|
||||
_ecrMovieCallBack.releaseCallBack();
|
||||
|
||||
_ecrPanCallBack.releaseCallBack();
|
||||
_ecrPan.stop();
|
||||
_ecrPan.stopDisplaying();
|
||||
_ecrPan.releasePanorama();
|
||||
_ecrPanCallBack.releaseCallBack();
|
||||
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB33", kArthurNoradAtSecurityMonitor);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
64
engines/pegasus/neighborhood/norad/alpha/ecrmonitor.h
Normal file
64
engines/pegasus/neighborhood/norad/alpha/ecrmonitor.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_ecrMONITOR_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_ecrMONITOR_H
|
||||
|
||||
#include "pegasus/interaction.h"
|
||||
#include "pegasus/notification.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/panoramascroll.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class NoradAlphaECRMonitor : public GameInteraction, public NotificationReceiver {
|
||||
public:
|
||||
NoradAlphaECRMonitor(Neighborhood *);
|
||||
~NoradAlphaECRMonitor() override {}
|
||||
|
||||
void handleInput(const Input &, const Hotspot *) override;
|
||||
|
||||
protected:
|
||||
void openInteraction() override;
|
||||
void closeInteraction() override;
|
||||
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
|
||||
void ecrSection1Finished();
|
||||
void ecrPanFinished();
|
||||
void ecrSection2Finished();
|
||||
|
||||
int findCurrentInterestingTime();
|
||||
void skipToNextInterestingTime();
|
||||
void skipToPreviousInterestingTime();
|
||||
|
||||
Notification _ecrSlideShowNotification;
|
||||
Movie _ecrMovie;
|
||||
NotificationCallBack _ecrMovieCallBack;
|
||||
PanoramaScroll _ecrPan;
|
||||
NotificationCallBack _ecrPanCallBack;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
459
engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp
Normal file
459
engines/pegasus/neighborhood/norad/alpha/fillingstation.cpp
Normal file
@@ -0,0 +1,459 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/items/biochips/arthurchip.h"
|
||||
#include "pegasus/items/inventory/airmask.h"
|
||||
#include "pegasus/neighborhood/norad/constants.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/fillingstation.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/noradalpha.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
static const NotificationFlags kFSPowerUpFinishedFlag = 1;
|
||||
static const NotificationFlags kFSSplashFinishedFlag = kFSPowerUpFinishedFlag << 1;
|
||||
static const NotificationFlags kFSIntakeWarningFinishedFlag = kFSSplashFinishedFlag << 1;
|
||||
static const NotificationFlags kFSIntakeHiliteFinishedFlag = kFSIntakeWarningFinishedFlag << 1;
|
||||
static const NotificationFlags kFSDispenseHiliteFinishedFlag = kFSIntakeHiliteFinishedFlag << 1;
|
||||
static const NotificationFlags kFSArHiliteFinishedFlag = kFSDispenseHiliteFinishedFlag << 1;
|
||||
static const NotificationFlags kFSCO2HiliteFinishedFlag = kFSArHiliteFinishedFlag << 1;
|
||||
static const NotificationFlags kFSHeHiliteFinishedFlag = kFSCO2HiliteFinishedFlag << 1;
|
||||
static const NotificationFlags kFSOHiliteFinishedFlag = kFSHeHiliteFinishedFlag << 1;
|
||||
static const NotificationFlags kFSNHiliteFinishedFlag = kFSOHiliteFinishedFlag << 1;
|
||||
|
||||
static const NotificationFlags kFSNotificationFlags = kFSPowerUpFinishedFlag |
|
||||
kFSSplashFinishedFlag |
|
||||
kFSIntakeWarningFinishedFlag |
|
||||
kFSIntakeHiliteFinishedFlag |
|
||||
kFSDispenseHiliteFinishedFlag |
|
||||
kFSArHiliteFinishedFlag |
|
||||
kFSCO2HiliteFinishedFlag |
|
||||
kFSHeHiliteFinishedFlag |
|
||||
kFSOHiliteFinishedFlag |
|
||||
kFSNHiliteFinishedFlag;
|
||||
|
||||
static const int16 kNoState = 0;
|
||||
static const int16 kMainMenu = 1;
|
||||
static const int16 kWaitingForAttach = 2;
|
||||
static const int16 kDispenseMenu = 3;
|
||||
static const int16 kWaitingForDispense = 4;
|
||||
|
||||
// Dummy itemIDs
|
||||
static const ItemID kCO2Item = 10000;
|
||||
static const ItemID kHeItem = 10001;
|
||||
|
||||
// Interactive points.
|
||||
enum {
|
||||
kFSPowerUpStartStart = 0,
|
||||
kFSPowerUpStartStop = 600,
|
||||
kFSSplashStart = 600,
|
||||
kFSSplashStop = 7800,
|
||||
kFSSplashIntakeStart = 7800,
|
||||
kFSSplashIntakeStop = 18600,
|
||||
|
||||
kFSMainMenu = 18600,
|
||||
kFSIntakeHiliteStart = 19200,
|
||||
kFSIntakeHiliteStop = 19800,
|
||||
kFSDispenseHiliteStart = 19800,
|
||||
kFSDispenseHiliteStop = 20400,
|
||||
|
||||
kFSDispenseMenu = 20400,
|
||||
|
||||
kFSArHiliteStart = 21000,
|
||||
kFSArHiliteStop = 21600,
|
||||
kFSArAttach = 21600,
|
||||
kFSArFilledStart = 22200,
|
||||
kFSArFilledStop = 25200,
|
||||
kFSArIncompatibleStart = 25200,
|
||||
kFSArIncompatibleStop = 30000,
|
||||
|
||||
kFSCO2HiliteStart = 30000,
|
||||
kFSCO2HiliteStop = 30600,
|
||||
kFSCO2Attach = 30600,
|
||||
kFSCO2FilledStart = 31200,
|
||||
kFSCO2FilledStop = 34200,
|
||||
kFSCO2IncompatibleStart = 34200,
|
||||
kFSCO2IncompatibleStop = 39000,
|
||||
|
||||
kFSHeHiliteStart = 39000,
|
||||
kFSHeHiliteStop = 39600,
|
||||
kFSHeAttach = 39600,
|
||||
kFSHeFilledStart = 40200,
|
||||
kFSHeFilledStop = 43200,
|
||||
kFSHeIncompatibleStart = 43200,
|
||||
kFSHeIncompatibleStop = 48000,
|
||||
|
||||
kFSOHiliteStart = 48000,
|
||||
kFSOHiliteStop = 48600,
|
||||
kFSOAttach = 48600,
|
||||
kFSOFilledStart = 49200,
|
||||
kFSOFilledStop = 52200,
|
||||
kFSOIncompatibleStart = 52200,
|
||||
kFSOIncompatibleStop = 57000,
|
||||
|
||||
kFSNHiliteStart = 57000,
|
||||
kFSNHiliteStop = 57600,
|
||||
kFSNAttach = 57600,
|
||||
kFSNFilledStart = 58200,
|
||||
kFSNFilledStop = 61200,
|
||||
kFSNIncompatibleStart = 61200,
|
||||
kFSNIncompatibleStop = 66000,
|
||||
|
||||
kFSIntakeMenu = 66000,
|
||||
kFSIntakeInProgressStart = 66600,
|
||||
kFSIntakeInProgressStop = 69600
|
||||
};
|
||||
|
||||
NoradAlphaFillingStation::NoradAlphaFillingStation(Neighborhood *owner) : GameInteraction(kNoradFillingStationInteractionID, owner),
|
||||
_rightSideMovie(kN01RightSideID), _rightSideNotification(kNoradFillingStationNotificationID, g_vm) {
|
||||
_state = kNoState;
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::openInteraction() {
|
||||
_rightSideMovie.initFromMovieFile("Images/Norad Alpha/N01W Right Side");
|
||||
_rightSideMovie.moveElementTo(kNoradAlpha01RightSideLeft, kNoradAlpha01RightSideTop);
|
||||
_rightSideMovie.setDisplayOrder(kN01RightSideOrder);
|
||||
_rightSideMovie.startDisplaying();
|
||||
_rightSideCallBack.setNotification(&_rightSideNotification);
|
||||
_rightSideCallBack.initCallBack(&_rightSideMovie, kCallBackAtExtremes);
|
||||
_rightSideCallBack.setCallBackFlag(kFSPowerUpFinishedFlag);
|
||||
_rightSideNotification.notifyMe(this, kFSNotificationFlags, kFSNotificationFlags);
|
||||
_rightSideCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
_rightSideMovie.show();
|
||||
_rightSideMovie.redrawMovieWorld();
|
||||
_rightSideMovie.setSegment(kFSPowerUpStartStart, kFSPowerUpStartStop);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::initInteraction() {
|
||||
allowInput(false);
|
||||
|
||||
_rightSideMovie.setRate(2);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::closeInteraction() {
|
||||
_rightSideMovie.stop();
|
||||
_rightSideMovie.stopDisplaying();
|
||||
_rightSideMovie.releaseMovie();
|
||||
_rightSideCallBack.releaseCallBack();
|
||||
((NoradAlpha *)getOwner())->turnOffFillingStation();
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::setStaticState(TimeValue time, int16 state) {
|
||||
_rightSideMovie.stop();
|
||||
_rightSideMovie.setSegment(0, _rightSideMovie.getDuration());
|
||||
_rightSideMovie.setTime(time);
|
||||
_rightSideMovie.redrawMovieWorld();
|
||||
_state = state;
|
||||
allowInput(true);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::setSegmentState(TimeValue start, TimeValue stop, NotificationFlags flag, int16 state) {
|
||||
_rightSideMovie.stop();
|
||||
_rightSideMovie.setSegment(start, stop);
|
||||
_rightSideMovie.setTime(start);
|
||||
_rightSideCallBack.setCallBackFlag(flag);
|
||||
_rightSideCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
_state = state;
|
||||
allowInput(false);
|
||||
_rightSideMovie.setRate(2);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::powerUpFinished() {
|
||||
((NoradAlpha *)getOwner())->turnOnFillingStation();
|
||||
setSegmentState(kFSSplashStart, kFSSplashStop, kFSSplashFinishedFlag, kNoState);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::splashFinished() {
|
||||
if (GameState.getNoradGassed())
|
||||
setSegmentState(kFSSplashIntakeStart, kFSSplashIntakeStop, kFSIntakeWarningFinishedFlag, kNoState);
|
||||
else
|
||||
intakeWarningFinished();
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::intakeWarningFinished() {
|
||||
setStaticState(kFSMainMenu, kMainMenu);
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA29", kArthurNoradSawIntakeWarning);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::showIntakeInProgress(uint16 numSeconds) {
|
||||
if (numSeconds == 0) {
|
||||
setSegmentState(kFSIntakeInProgressStart, kFSIntakeInProgressStop, kFSIntakeWarningFinishedFlag, kNoState);
|
||||
Item *item = ((NoradAlpha *)getOwner())->getFillingItem();
|
||||
|
||||
if (item->getObjectID() == kGasCanister) {
|
||||
GameState.setNoradGassed(true);
|
||||
((NoradAlpha *)getOwner())->checkAirMask();
|
||||
getOwner()->restoreStriding(kNorad03, kEast, kAltNoradAlphaNormal);
|
||||
}
|
||||
} else {
|
||||
setSegmentState(kFSIntakeInProgressStart, kFSIntakeInProgressStart + _rightSideMovie.getScale() * numSeconds,
|
||||
kFSIntakeWarningFinishedFlag, kNoState);
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::intakeHighlightFinished() {
|
||||
_rightSideMovie.stop();
|
||||
|
||||
if (GameState.getNoradGassed()) {
|
||||
showIntakeInProgress(2);
|
||||
} else {
|
||||
Item *item = ((NoradAlpha *)getOwner())->getFillingItem();
|
||||
if (item)
|
||||
showIntakeInProgress(0);
|
||||
else
|
||||
setStaticState(kFSIntakeMenu, kWaitingForAttach);
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::dispenseHighlightFinished() {
|
||||
setStaticState(kFSDispenseMenu, kDispenseMenu);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::dispenseGas() {
|
||||
Item *item = ((NoradAlpha *)getOwner())->getFillingItem();
|
||||
|
||||
if (item) {
|
||||
if (item->getObjectID() != _dispenseItemID)
|
||||
switch (_dispenseItemID) {
|
||||
case kArgonCanister:
|
||||
setSegmentState(kFSArIncompatibleStart, kFSArIncompatibleStop,
|
||||
kFSIntakeWarningFinishedFlag, kNoState);
|
||||
break;
|
||||
case kCO2Item:
|
||||
setSegmentState(kFSCO2IncompatibleStart, kFSCO2IncompatibleStop,
|
||||
kFSIntakeWarningFinishedFlag, kNoState);
|
||||
break;
|
||||
case kHeItem:
|
||||
setSegmentState(kFSHeIncompatibleStart, kFSHeIncompatibleStop,
|
||||
kFSIntakeWarningFinishedFlag, kNoState);
|
||||
break;
|
||||
case kAirMask:
|
||||
setSegmentState(kFSOIncompatibleStart, kFSOIncompatibleStop,
|
||||
kFSIntakeWarningFinishedFlag, kNoState);
|
||||
break;
|
||||
case kNitrogenCanister:
|
||||
setSegmentState(kFSNIncompatibleStart, kFSNIncompatibleStop,
|
||||
kFSIntakeWarningFinishedFlag, kNoState);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (_dispenseItemID == kArgonCanister) {
|
||||
setSegmentState(kFSArFilledStart, kFSArFilledStop, kFSIntakeWarningFinishedFlag, kNoState);
|
||||
item->setItemState(kArgonFull);
|
||||
GameState.setScoringFilledArgonCanister(true);
|
||||
} else if (_dispenseItemID == kAirMask) {
|
||||
setSegmentState(kFSOFilledStart, kFSOFilledStop, kFSIntakeWarningFinishedFlag, kNoState);
|
||||
((AirMask *)item)->refillAirMask();
|
||||
GameState.setScoringFilledOxygenCanister(true);
|
||||
} else if (_dispenseItemID == kNitrogenCanister) {
|
||||
setSegmentState(kFSNFilledStart, kFSNFilledStop, kFSIntakeWarningFinishedFlag, kNoState);
|
||||
item->setItemState(kNitrogenFull);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (_dispenseItemID) {
|
||||
case kArgonCanister:
|
||||
setStaticState(kFSArAttach, kWaitingForDispense);
|
||||
break;
|
||||
case kCO2Item:
|
||||
setStaticState(kFSCO2Attach, kWaitingForDispense);
|
||||
break;
|
||||
case kHeItem:
|
||||
setStaticState(kFSHeAttach, kWaitingForDispense);
|
||||
break;
|
||||
case kAirMask:
|
||||
setStaticState(kFSOAttach, kWaitingForDispense);
|
||||
break;
|
||||
case kNitrogenCanister:
|
||||
setStaticState(kFSNAttach, kWaitingForDispense);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::ArHighlightFinished() {
|
||||
_dispenseItemID = kArgonCanister;
|
||||
dispenseGas();
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::CO2HighlightFinished() {
|
||||
_dispenseItemID = kCO2Item;
|
||||
dispenseGas();
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::HeHighlightFinished() {
|
||||
_dispenseItemID = kHeItem;
|
||||
dispenseGas();
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::OHighlightFinished() {
|
||||
_dispenseItemID = kAirMask;
|
||||
dispenseGas();
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::NHighlightFinished() {
|
||||
_dispenseItemID = kNitrogenCanister;
|
||||
dispenseGas();
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::receiveNotification(Notification *, const NotificationFlags flags) {
|
||||
switch (flags) {
|
||||
case kFSPowerUpFinishedFlag:
|
||||
powerUpFinished();
|
||||
break;
|
||||
case kFSSplashFinishedFlag:
|
||||
splashFinished();
|
||||
break;
|
||||
case kFSIntakeWarningFinishedFlag:
|
||||
intakeWarningFinished();
|
||||
break;
|
||||
case kFSIntakeHiliteFinishedFlag:
|
||||
intakeHighlightFinished();
|
||||
break;
|
||||
case kFSDispenseHiliteFinishedFlag:
|
||||
dispenseHighlightFinished();
|
||||
break;
|
||||
case kFSArHiliteFinishedFlag:
|
||||
ArHighlightFinished();
|
||||
break;
|
||||
case kFSCO2HiliteFinishedFlag:
|
||||
CO2HighlightFinished();
|
||||
break;
|
||||
case kFSHeHiliteFinishedFlag:
|
||||
HeHighlightFinished();
|
||||
break;
|
||||
case kFSOHiliteFinishedFlag:
|
||||
OHighlightFinished();
|
||||
break;
|
||||
case kFSNHiliteFinishedFlag:
|
||||
NHighlightFinished();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::handleInput(const Input &input, const Hotspot *cursorSpot) {
|
||||
InputHandler::handleInput(input, cursorSpot);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::clickInIntake() {
|
||||
setSegmentState(kFSIntakeHiliteStart, kFSIntakeHiliteStop, kFSIntakeHiliteFinishedFlag, kNoState);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::clickInDispense() {
|
||||
setSegmentState(kFSDispenseHiliteStart, kFSDispenseHiliteStop, kFSDispenseHiliteFinishedFlag, kNoState);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::clickInAr() {
|
||||
setSegmentState(kFSArHiliteStart, kFSArHiliteStop, kFSArHiliteFinishedFlag, kNoState);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::clickInCO2() {
|
||||
setSegmentState(kFSCO2HiliteStart, kFSCO2HiliteStop, kFSCO2HiliteFinishedFlag, kNoState);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::clickInHe() {
|
||||
setSegmentState(kFSHeHiliteStart, kFSHeHiliteStop, kFSHeHiliteFinishedFlag, kNoState);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::clickInO() {
|
||||
setSegmentState(kFSOHiliteStart, kFSOHiliteStop, kFSOHiliteFinishedFlag, kNoState);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::clickInN() {
|
||||
setSegmentState(kFSNHiliteStart, kFSNHiliteStop, kFSNHiliteFinishedFlag, kNoState);
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::clickInHotspot(const Input &input, const Hotspot *spot) {
|
||||
GameInteraction::clickInHotspot(input, spot);
|
||||
|
||||
switch (spot->getObjectID()) {
|
||||
case kNorad01IntakeSpotID:
|
||||
clickInIntake();
|
||||
break;
|
||||
case kNorad01DispenseSpotID:
|
||||
clickInDispense();
|
||||
break;
|
||||
case kNorad01ArSpotID:
|
||||
clickInAr();
|
||||
break;
|
||||
case kNorad01CO2SpotID:
|
||||
clickInCO2();
|
||||
break;
|
||||
case kNorad01HeSpotID:
|
||||
clickInHe();
|
||||
break;
|
||||
case kNorad01OSpotID:
|
||||
clickInO();
|
||||
break;
|
||||
case kNorad01NSpotID:
|
||||
clickInN();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::activateHotspots() {
|
||||
GameInteraction::activateHotspots();
|
||||
|
||||
switch (_state) {
|
||||
case kMainMenu:
|
||||
g_allHotspots.activateOneHotspot(kNorad01IntakeSpotID);
|
||||
g_allHotspots.activateOneHotspot(kNorad01DispenseSpotID);
|
||||
break;
|
||||
case kDispenseMenu:
|
||||
g_allHotspots.activateOneHotspot(kNorad01ArSpotID);
|
||||
g_allHotspots.activateOneHotspot(kNorad01CO2SpotID);
|
||||
g_allHotspots.activateOneHotspot(kNorad01HeSpotID);
|
||||
g_allHotspots.activateOneHotspot(kNorad01OSpotID);
|
||||
g_allHotspots.activateOneHotspot(kNorad01NSpotID);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlphaFillingStation::newFillingItem(Item *item) {
|
||||
switch (_state) {
|
||||
case kWaitingForAttach:
|
||||
if (item)
|
||||
showIntakeInProgress(0);
|
||||
break;
|
||||
case kWaitingForDispense:
|
||||
dispenseGas();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
90
engines/pegasus/neighborhood/norad/alpha/fillingstation.h
Normal file
90
engines/pegasus/neighborhood/norad/alpha/fillingstation.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_FILLINGSTATION_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_FILLINGSTATION_H
|
||||
|
||||
#include "pegasus/interaction.h"
|
||||
#include "pegasus/movie.h"
|
||||
#include "pegasus/notification.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class Item;
|
||||
|
||||
class NoradAlphaFillingStation : public GameInteraction, public NotificationReceiver {
|
||||
public:
|
||||
NoradAlphaFillingStation(Neighborhood *);
|
||||
~NoradAlphaFillingStation() override {}
|
||||
|
||||
void handleInput(const Input &, const Hotspot *) override;
|
||||
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
void activateHotspots() override;
|
||||
|
||||
void newFillingItem(Item *);
|
||||
|
||||
protected:
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
|
||||
void openInteraction() override;
|
||||
void initInteraction() override;
|
||||
void closeInteraction() override;
|
||||
|
||||
void powerUpFinished();
|
||||
void splashFinished();
|
||||
void intakeWarningFinished();
|
||||
void intakeHighlightFinished();
|
||||
void dispenseHighlightFinished();
|
||||
void ArHighlightFinished();
|
||||
void CO2HighlightFinished();
|
||||
void HeHighlightFinished();
|
||||
void OHighlightFinished();
|
||||
void NHighlightFinished();
|
||||
|
||||
void showIntakeInProgress(uint16);
|
||||
|
||||
void clickInIntake();
|
||||
void clickInDispense();
|
||||
void clickInAr();
|
||||
void clickInCO2();
|
||||
void clickInHe();
|
||||
void clickInO();
|
||||
void clickInN();
|
||||
|
||||
void dispenseGas();
|
||||
|
||||
void setStaticState(TimeValue, int16);
|
||||
void setSegmentState(TimeValue, TimeValue, NotificationFlags, int16);
|
||||
|
||||
Movie _rightSideMovie;
|
||||
Notification _rightSideNotification;
|
||||
NotificationCallBack _rightSideCallBack;
|
||||
int16 _state;
|
||||
ItemID _dispenseItemID;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
969
engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp
Normal file
969
engines/pegasus/neighborhood/norad/alpha/noradalpha.cpp
Normal file
@@ -0,0 +1,969 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/cursor.h"
|
||||
#include "pegasus/energymonitor.h"
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/interface.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/biochips/arthurchip.h"
|
||||
#include "pegasus/items/inventory/airmask.h"
|
||||
#include "pegasus/neighborhood/norad/constants.h"
|
||||
#include "pegasus/neighborhood/norad/subcontrolroom.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/ecrmonitor.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/fillingstation.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/noradalpha.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/subchase.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
static const ExtraID kShowThermalScan = 1000;
|
||||
|
||||
static const HotSpotID kThermalScanHotSpotID = 10000;
|
||||
|
||||
const uint32 NoradAlpha::_noradAlphaClawExtras[22] = {
|
||||
kN22ClawFromAToB,
|
||||
kN22ClawALoop,
|
||||
kN22ClawAPinch,
|
||||
kN22ClawACounterclockwise,
|
||||
kN22ClawAClockwise,
|
||||
kN22ClawFromBToA,
|
||||
kN22ClawFromBToC,
|
||||
kN22ClawFromBToD,
|
||||
kN22ClawBLoop,
|
||||
kN22ClawBPinch,
|
||||
kN22ClawBCounterclockwise,
|
||||
kN22ClawBClockwise,
|
||||
kN22ClawFromCToB,
|
||||
kN22ClawCLoop,
|
||||
kN22ClawCPinch,
|
||||
kN22ClawCCounterclockwise,
|
||||
kN22ClawCClockwise,
|
||||
kN22ClawFromDToB,
|
||||
kN22ClawDLoop,
|
||||
kN22ClawDPinch,
|
||||
kN22ClawDCounterclockwise,
|
||||
kN22ClawDClockwise
|
||||
};
|
||||
|
||||
NoradAlpha::NoradAlpha(InputHandler *nextHandler, PegasusEngine *owner)
|
||||
: Norad(nextHandler, owner, "Norad Alpha", kNoradAlphaID),
|
||||
_thermalScanSpot(kThermalScanHotSpotID), _extraMovie(kNoDisplayElement) {
|
||||
_elevatorUpRoomID = kNorad11South;
|
||||
_elevatorDownRoomID = kNorad12South;
|
||||
_elevatorUpSpotID = kNorad12ElevatorUpSpotID;
|
||||
_elevatorDownSpotID = kNorad11ElevatorDownSpotID;
|
||||
|
||||
_subRoomEntryRoom1 = kNorad10;
|
||||
_subRoomEntryDir1 = kEast;
|
||||
_subRoomEntryRoom2 = kNorad21;
|
||||
_subRoomEntryDir2 = kWest;
|
||||
_upperPressureDoorRoom = kNorad10East;
|
||||
_lowerPressureDoorRoom = kNorad21West;
|
||||
|
||||
_upperPressureDoorUpSpotID = kAlphaUpperPressureDoorUpSpotID;
|
||||
_upperPressureDoorDownSpotID = kAlphaUpperPressureDoorDownSpotID;
|
||||
_upperPressureDoorAbortSpotID = kNorad10EastOutSpotID;
|
||||
|
||||
_lowerPressureDoorUpSpotID = kAlphaLowerPressureDoorUpSpotID;
|
||||
_lowerPressureDoorDownSpotID = kAlphaLowerPressureDoorDownSpotID;
|
||||
_lowerPressureDoorAbortSpotID = kNorad21WestOutSpotID;
|
||||
|
||||
_pressureSoundIn = kAlphaPressureDoorIntro1In;
|
||||
_pressureSoundOut = kAlphaPressureDoorIntro1Out;
|
||||
_equalizeSoundIn = kAlphaPressureDoorIntro2In;
|
||||
_equalizeSoundOut = kAlphaPressureDoorIntro2Out;
|
||||
_accessDeniedIn = kAlphaAccessDeniedIn;
|
||||
_accessDeniedOut = kAlphaAccessDeniedOut;
|
||||
|
||||
_platformRoom = kNorad19West;
|
||||
_subControlRoom = kNorad22West;
|
||||
|
||||
_subPrepFailed = false;
|
||||
_fillingStationItem = nullptr;
|
||||
|
||||
setIsItemTaken(kGasCanister);
|
||||
}
|
||||
|
||||
NoradAlpha::~NoradAlpha() {
|
||||
if (_vm->isDVD())
|
||||
_vm->getAllHotspots().remove(&_thermalScanSpot);
|
||||
}
|
||||
|
||||
void NoradAlpha::init() {
|
||||
Norad::init();
|
||||
|
||||
_extraMovieCallBack.setNotification(&_neighborhoodNotification);
|
||||
|
||||
if (_vm->isDVD()) {
|
||||
_thermalScanSpot.setArea(Common::Rect(216, 112, 336, 312));
|
||||
_thermalScanSpot.setHotspotFlags(kNeighborhoodSpotFlag | kClickSpotFlag);
|
||||
_vm->getAllHotspots().push_back(&_thermalScanSpot);
|
||||
}
|
||||
|
||||
Hotspot *hotspot = _vm->getAllHotspots().findHotspotByID(kN01GasCanisterSpotID);
|
||||
hotspot->setMaskedHotspotFlags(kPickUpItemSpotFlag, kPickUpItemSpotFlag);
|
||||
HotspotInfoTable::Entry *hotspotEntry = findHotspotEntry(kN01GasCanisterSpotID);
|
||||
hotspotEntry->hotspotItem = kGasCanister;
|
||||
|
||||
hotspot = _vm->getAllHotspots().findHotspotByID(kN01ArgonCanisterSpotID);
|
||||
hotspot->setMaskedHotspotFlags(kPickUpItemSpotFlag, kPickUpItemSpotFlag);
|
||||
hotspotEntry = findHotspotEntry(kN01ArgonCanisterSpotID);
|
||||
hotspotEntry->hotspotItem = kArgonCanister;
|
||||
|
||||
hotspot = _vm->getAllHotspots().findHotspotByID(kN01NitrogenCanisterSpotID);
|
||||
hotspot->setMaskedHotspotFlags(kPickUpItemSpotFlag, kPickUpItemSpotFlag);
|
||||
hotspotEntry = findHotspotEntry(kN01NitrogenCanisterSpotID);
|
||||
hotspotEntry->hotspotItem = kNitrogenCanister;
|
||||
|
||||
hotspot = _vm->getAllHotspots().findHotspotByID(kN01AirMaskSpotID);
|
||||
hotspot->setMaskedHotspotFlags(kPickUpItemSpotFlag, kPickUpItemSpotFlag);
|
||||
hotspotEntry = findHotspotEntry(kN01AirMaskSpotID);
|
||||
hotspotEntry->hotspotItem = kAirMask;
|
||||
|
||||
hotspot = _vm->getAllHotspots().findHotspotByID(kN01GasOutletSpotID);
|
||||
hotspot->setMaskedHotspotFlags(kDropItemSpotFlag, kDropItemSpotFlag);
|
||||
}
|
||||
|
||||
void NoradAlpha::start() {
|
||||
if (g_energyMonitor) {
|
||||
g_energyMonitor->stopEnergyDraining();
|
||||
g_energyMonitor->restoreLastEnergyValue();
|
||||
_vm->resetEnergyDeathReason();
|
||||
g_energyMonitor->startEnergyDraining();
|
||||
}
|
||||
|
||||
NeighborhoodID itemNeighborhood;
|
||||
RoomID itemRoom;
|
||||
DirectionConstant itemDirection;
|
||||
|
||||
Item *item = (Item *)_vm->getAllItems().findItemByID(kGasCanister);
|
||||
item->getItemRoom(itemNeighborhood, itemRoom, itemDirection);
|
||||
|
||||
if (itemNeighborhood == getObjectID()) {
|
||||
_fillingStationItem = item;
|
||||
} else {
|
||||
item = (Item *)_vm->getAllItems().findItemByID(kAirMask);
|
||||
item->getItemRoom(itemNeighborhood, itemRoom, itemDirection);
|
||||
|
||||
if (itemNeighborhood == getObjectID()) {
|
||||
_fillingStationItem = item;
|
||||
} else {
|
||||
item = (Item *)_vm->getAllItems().findItemByID(kNitrogenCanister);
|
||||
item->getItemRoom(itemNeighborhood, itemRoom, itemDirection);
|
||||
|
||||
if (itemNeighborhood == getObjectID()) {
|
||||
_fillingStationItem = item;
|
||||
} else {
|
||||
item = (Item *)_vm->getAllItems().findItemByID(kArgonCanister);
|
||||
item->getItemRoom(itemNeighborhood, itemRoom, itemDirection);
|
||||
if (itemNeighborhood == getObjectID())
|
||||
_fillingStationItem = item;
|
||||
else
|
||||
_fillingStationItem = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!GameState.getNoradGassed())
|
||||
forceStridingStop(kNorad03, kEast, kAltNoradAlphaNormal);
|
||||
|
||||
GameState.setNoradArrivedFromSub(false);
|
||||
Norad::start();
|
||||
}
|
||||
|
||||
void NoradAlpha::setUpAIRules() {
|
||||
Neighborhood::setUpAIRules();
|
||||
|
||||
if (g_AIArea) {
|
||||
AIPlayMessageAction *messageAction = new AIPlayMessageAction("Images/AI/Norad/XN01WD1", false);
|
||||
AIHasItemCondition *hasGasCanisterCondition = new AIHasItemCondition(kGasCanister);
|
||||
AIRule *rule = new AIRule(hasGasCanisterCondition, messageAction);
|
||||
g_AIArea->addAIRule(rule);
|
||||
}
|
||||
}
|
||||
|
||||
bool NoradAlpha::okayToJump() {
|
||||
bool result = Neighborhood::okayToJump();
|
||||
|
||||
if (!result)
|
||||
playSpotSoundSync(kAlphaCantTransportIn, kAlphaCantTransportOut);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void NoradAlpha::getExtraCompassMove(const ExtraTable::Entry &entry, FaderMoveSpec &compassMove) {
|
||||
if (entry.extra == kNorad19ExitToSub) {
|
||||
compassMove.makeTwoKnotFaderSpec(kNoradAlphaMovieScale, entry.movieStart, 270 + kSubPlatformCompassAngle,
|
||||
entry.movieEnd, 90 + 20 + 360);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 10 * kNoradAlphaFrameDuration, 270 + kSubPlatformCompassAngle);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 29 * kNoradAlphaFrameDuration, 270 + kSubPlatformCompassAngle + 20);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 52 * kNoradAlphaFrameDuration, 270 + kSubPlatformCompassAngle + 20);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 84 * kNoradAlphaFrameDuration, 360 + 90);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 198 * kNoradAlphaFrameDuration, 360 + 90);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 270 * kNoradAlphaFrameDuration, 360 + 90 + 15);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 280 * kNoradAlphaFrameDuration, 360 + 90 + 20);
|
||||
} else {
|
||||
Norad::getExtraCompassMove(entry, compassMove);
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlpha::playClawMonitorIntro() {
|
||||
playSpotSoundSync(kAlphaLoadClawIntroIn, kAlphaLoadClawIntroOut);
|
||||
}
|
||||
|
||||
GameInteraction *NoradAlpha::makeInteraction(const InteractionID interactionID) {
|
||||
switch (interactionID) {
|
||||
case kNoradECRMonitorInteractionID:
|
||||
return new NoradAlphaECRMonitor(this);
|
||||
case kNoradFillingStationInteractionID:
|
||||
return new NoradAlphaFillingStation(this);
|
||||
case kNoradSubChaseInteractionID:
|
||||
return new SubChase(this);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Norad::makeInteraction(interactionID);
|
||||
}
|
||||
|
||||
void NoradAlpha::loadAmbientLoops() {
|
||||
// clone2727 would like to point out that the following comment does not quite
|
||||
// match the code logic below
|
||||
|
||||
/*
|
||||
Logic:
|
||||
|
||||
loop sound 1:
|
||||
if gassed,
|
||||
play warning loop of some sort
|
||||
else
|
||||
play nothing
|
||||
loop sound 2:
|
||||
if gassed and not wearing air mask
|
||||
if in ECR
|
||||
play breathing water loop
|
||||
else
|
||||
play breathing
|
||||
else
|
||||
if in ECR
|
||||
play water loop
|
||||
if at N07 north
|
||||
play unmanned loop
|
||||
*/
|
||||
|
||||
if (!GameState.getNoradSeenTimeStream() || !g_interface || _vm->getEnergyDeathReason() == kDeathSubDestroyed)
|
||||
return;
|
||||
|
||||
RoomID room = GameState.getCurrentRoom();
|
||||
if (GameState.getNoradGassed()) {
|
||||
if (room >= kNorad11 && room <= kNorad19West) {
|
||||
if (_vm->isDVD())
|
||||
loadLoopSound1("Sounds/Norad/NEW SUB AMB.44K.AIFF", kNoradWarningVolume * 3);
|
||||
else
|
||||
loadLoopSound1("Sounds/Norad/NEW SUB AMB.22K.AIFF", kNoradWarningVolume * 3);
|
||||
} else if (room >= kNorad21 && room <= kNorad22West) {
|
||||
if (_vm->isDVD())
|
||||
loadLoopSound1("Sounds/Norad/SUB CONTRL LOOP.32K.AIFF", kNoradWarningVolume * 3);
|
||||
else
|
||||
loadLoopSound1("Sounds/Norad/SUB CONTRL LOOP.22K.AIFF", kNoradWarningVolume * 3);
|
||||
} else {
|
||||
if (_vm->isDVD())
|
||||
loadLoopSound1("Sounds/Norad/WARNING LOOP.32K.AIFF", kNoradWarningVolume);
|
||||
else
|
||||
loadLoopSound1("Sounds/Norad/WARNING LOOP.22K.AIFF", kNoradWarningVolume);
|
||||
}
|
||||
} else {
|
||||
loadLoopSound1("");
|
||||
}
|
||||
|
||||
if (GameState.getNoradGassed() && !g_airMask->isAirFilterOn()) {
|
||||
if (room >= kNorad01 && room <= kNorad01West) {
|
||||
loadLoopSound2("Sounds/Norad/Breathing Water.22K.AIFF", kNoradSuckWindVolume);
|
||||
} else if (room == kNorad02) {
|
||||
if (GameState.isCurrentDoorOpen())
|
||||
loadLoopSound2("Sounds/Norad/Breathing Water.22K.AIFF", kNoradSuckWindVolume);
|
||||
else
|
||||
loadLoopSound2("Sounds/Norad/SUCKING WIND.22K.AIFF", kNoradSuckWindVolume, 0, 0);
|
||||
} else {
|
||||
loadLoopSound2("Sounds/Norad/SUCKING WIND.22K.AIFF", kNoradSuckWindVolume, 0, 0);
|
||||
}
|
||||
} else {
|
||||
if (room >= kNorad01 && room <= kNorad01West) {
|
||||
loadLoopSound2("Sounds/Norad/WATER FLOWING.AIFF", 0x100 / 2);
|
||||
} else if (room == kNorad02) {
|
||||
if (GameState.isCurrentDoorOpen())
|
||||
loadLoopSound2("Sounds/Norad/WATER FLOWING.AIFF", 0x100 / 2);
|
||||
else
|
||||
loadLoopSound2("");
|
||||
} else {
|
||||
loadLoopSound2("");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void NoradAlpha::checkContinuePoint(const RoomID room, const DirectionConstant direction) {
|
||||
switch (MakeRoomView(room, direction)) {
|
||||
case MakeRoomView(kNorad02, kEast):
|
||||
case MakeRoomView(kNorad06, kEast):
|
||||
case MakeRoomView(kNorad11, kEast):
|
||||
case MakeRoomView(kNorad15, kEast):
|
||||
case MakeRoomView(kNorad19, kWest):
|
||||
case MakeRoomView(kNorad21, kSouth):
|
||||
makeContinuePoint();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlpha::arriveAt(const RoomID room, const DirectionConstant direction) {
|
||||
Norad::arriveAt(room, direction);
|
||||
|
||||
switch (GameState.getCurrentRoom()) {
|
||||
case kNorad01:
|
||||
arriveAtNorad01();
|
||||
break;
|
||||
case kNorad01East:
|
||||
arriveAtNorad01East();
|
||||
break;
|
||||
case kNorad01West:
|
||||
arriveAtNorad01West();
|
||||
break;
|
||||
case kNorad04:
|
||||
arriveAtNorad04();
|
||||
break;
|
||||
case kNorad07:
|
||||
if (_vm->isDVD() && GameState.getLastRoom() == kNorad06)
|
||||
startExtraSequence(kShowThermalScan, kExtraCompletedFlag, kFilterNoInput);
|
||||
break;
|
||||
case kNorad07North:
|
||||
GameState.setScoringSawUnconsciousOperator(true);
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA70", kArthurNoradSawUnconsciousOperator);
|
||||
break;
|
||||
case kNorad11:
|
||||
GameState.setScoringWentThroughPressureDoor(true);
|
||||
break;
|
||||
case kNorad22:
|
||||
arriveAtNorad22();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlpha::arriveAtNorad01() {
|
||||
Item *argonCanister, *nitrogenCanister;
|
||||
|
||||
switch (GameState.getCurrentDirection()) {
|
||||
case kSouth:
|
||||
if (!GameState.getNoradSeenTimeStream()) {
|
||||
GameState.setNoradN22MessagePlayed(false);
|
||||
requestExtraSequence(kNoradArriveFromTSA, kExtraCompletedFlag, kFilterNoInput);
|
||||
// You are no match for me, human.
|
||||
requestExtraSequence(kNorad01RobotTaunt, kExtraCompletedFlag, kFilterNoInput);
|
||||
}
|
||||
break;
|
||||
case kEast:
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA33", kArthurNoradAtSecurityMonitor);
|
||||
break;
|
||||
case kWest:
|
||||
if (GameState.getLastRoom() == kNorad01West) {
|
||||
argonCanister = g_allItems.findItemByID(kArgonCanister);
|
||||
nitrogenCanister = g_allItems.findItemByID(kNitrogenCanister);
|
||||
if (((GameState.isTakenItemID(kArgonCanister) && argonCanister->getItemState() != kArgonFull) ||
|
||||
(GameState.isTakenItemID(kNitrogenCanister) && nitrogenCanister->getItemState() != kNitrogenFull)) && g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA34", kArthurNoradDidntFillCanisters);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlpha::arriveAtNorad01East() {
|
||||
GameState.setScoringSawSecurityMonitor(true);
|
||||
newInteraction(kNoradECRMonitorInteractionID);
|
||||
}
|
||||
|
||||
void NoradAlpha::arriveAtNorad01West() {
|
||||
newInteraction(kNoradFillingStationInteractionID);
|
||||
}
|
||||
|
||||
void NoradAlpha::arriveAtNorad04() {
|
||||
if (GameState.getCurrentDirection() == kEast && !GameState.getNoradGassed())
|
||||
playDeathExtra(kNorad04EastDeath, kDeathWokeUpNorad);
|
||||
}
|
||||
|
||||
void NoradAlpha::arriveAtNorad22() {
|
||||
if (!GameState.getNoradN22MessagePlayed() && GameState.getCurrentDirection() == kSouth) {
|
||||
startExtraSequence(kNorad22SouthIntro, kExtraCompletedFlag, kFilterNoInput);
|
||||
GameState.setNoradN22MessagePlayed(true);
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlpha::turnTo(const DirectionConstant direction) {
|
||||
Norad::turnTo(direction);
|
||||
if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad01, kEast) && g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA33", kArthurNoradAtSecurityMonitor);
|
||||
}
|
||||
|
||||
void NoradAlpha::bumpIntoWall() {
|
||||
requestSpotSound(kAlphaBumpIntoWallIn, kAlphaBumpIntoWallOut, kFilterNoInput, 0);
|
||||
Neighborhood::bumpIntoWall();
|
||||
}
|
||||
|
||||
void NoradAlpha::startExtraSequence(const ExtraID extraID, const NotificationFlags flags, const InputBits interruptionFilter) {
|
||||
TimeValue segmentStart = 0, segmentStop = 0;
|
||||
bool loopSequence = false;
|
||||
Common::Rect pushBounds;
|
||||
NotificationFlags extraFlags;
|
||||
|
||||
switch (extraID) {
|
||||
case kShowThermalScan:
|
||||
_turnPush.getBounds(pushBounds);
|
||||
|
||||
switch (extraID) {
|
||||
case kShowThermalScan:
|
||||
_extraMovie.initFromMovieFile("Images/Norad Alpha/N07NS.movie");
|
||||
segmentStart = 0;
|
||||
segmentStop = _extraMovie.getDuration();
|
||||
loopSequence = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_lastExtra = extraID;
|
||||
_turnPush.hide();
|
||||
|
||||
if (!loopSequence && g_AIArea)
|
||||
g_AIArea->lockAIOut();
|
||||
|
||||
extraFlags = flags;
|
||||
_interruptionFilter = interruptionFilter;
|
||||
// Stop the nav movie before doing anything else
|
||||
_navMovie.stop();
|
||||
_navMovie.stopDisplaying();
|
||||
|
||||
_extraMovie.setVolume(_vm->getSoundFXLevel());
|
||||
_extraMovie.moveElementTo(pushBounds.left, pushBounds.top);
|
||||
_extraMovie.setDisplayOrder(kNavMovieOrder + 1);
|
||||
_extraMovie.startDisplaying();
|
||||
_extraMovie.show();
|
||||
_extraMovie.setFlags(0);
|
||||
_extraMovie.setSegment(segmentStart, segmentStop);
|
||||
_extraMovie.setTime(segmentStart);
|
||||
if (loopSequence)
|
||||
_extraMovie.setFlags(kLoopTimeBase);
|
||||
else
|
||||
extraFlags |= kNeighborhoodMovieCompletedFlag;
|
||||
_extraMovieCallBack.cancelCallBack();
|
||||
_extraMovieCallBack.initCallBack(&_extraMovie, kCallBackAtExtremes);
|
||||
if (extraFlags != 0) {
|
||||
_extraMovieCallBack.setCallBackFlag(extraFlags);
|
||||
_extraMovieCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
}
|
||||
_extraMovie.start();
|
||||
break;
|
||||
default:
|
||||
Neighborhood::startExtraSequence(extraID, flags, interruptionFilter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlpha::receiveNotification(Notification *notification, const NotificationFlags flags) {
|
||||
if ((flags & kExtraCompletedFlag) != 0) {
|
||||
switch (_lastExtra) {
|
||||
case kShowThermalScan:
|
||||
_interruptionFilter = kFilterAllInput;
|
||||
_extraMovie.stopDisplaying();
|
||||
_extraMovie.releaseMovie();
|
||||
_navMovie.startDisplaying();
|
||||
break;
|
||||
case kNorad19ExitToSub:
|
||||
if (_vm->isDVD()) {
|
||||
_interruptionFilter = kFilterAllInput;
|
||||
_vm->_cursor->hide();
|
||||
setNextHandler(_vm);
|
||||
throwAwayInterface();
|
||||
loadLoopSound1("");
|
||||
newInteraction(kNoradSubChaseInteractionID);
|
||||
GameState.setScoringEnteredSub(true);
|
||||
}
|
||||
break;
|
||||
case kNoradArriveFromTSA:
|
||||
GameState.setNoradSeenTimeStream(true);
|
||||
loadAmbientLoops();
|
||||
break;
|
||||
case kNorad01RobotTaunt:
|
||||
if (_vm->isChattyAI())
|
||||
g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN01SB", false, kWarningInterruption);
|
||||
_interruptionFilter = kFilterAllInput;
|
||||
makeContinuePoint();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Norad::receiveNotification(notification, flags);
|
||||
|
||||
if ((flags & kExtraCompletedFlag) != 0) {
|
||||
switch (_lastExtra) {
|
||||
case kNorad22SouthIntro:
|
||||
loopExtraSequence(kNorad22SouthReply);
|
||||
playSpotSoundSync(kN22ReplyIn, kN22ReplyOut);
|
||||
startExtraSequence(kNorad22SouthFinish, kExtraCompletedFlag, kFilterNoInput);
|
||||
break;
|
||||
case kNorad22SouthFinish:
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB29", kArthurNoradSawSubMessage);
|
||||
_interruptionFilter = kFilterAllInput;
|
||||
// Force ArriveAt to do its thing...
|
||||
GameState.setCurrentRoom(kNorad21);
|
||||
arriveAt(kNorad22, kSouth);
|
||||
break;
|
||||
case kN22ClawFromAToB:
|
||||
case kN22ClawAPinch:
|
||||
case kN22ClawACounterclockwise:
|
||||
case kN22ClawAClockwise:
|
||||
case kN22ClawFromBToA:
|
||||
case kN22ClawFromBToC:
|
||||
case kN22ClawFromBToD:
|
||||
case kN22ClawBPinch:
|
||||
case kN22ClawBCounterclockwise:
|
||||
case kN22ClawBClockwise:
|
||||
case kN22ClawFromCToB:
|
||||
case kN22ClawCPinch:
|
||||
case kN22ClawCCounterclockwise:
|
||||
case kN22ClawCClockwise:
|
||||
case kN22ClawFromDToB:
|
||||
case kN22ClawDPinch:
|
||||
case kN22ClawDCounterclockwise:
|
||||
case kN22ClawDClockwise:
|
||||
if (g_arthurChip) {
|
||||
if (_vm->getRandomBit())
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA64", kArthurNoradPlayedWithClaw);
|
||||
else
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA66", kArthurNoradPlayedWithClaw);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_AIArea->checkMiddleArea();
|
||||
}
|
||||
|
||||
void NoradAlpha::getZoomEntry(const HotSpotID spotID, ZoomTable::Entry &entry) {
|
||||
Norad::getZoomEntry(spotID, entry);
|
||||
|
||||
ExtraTable::Entry extra;
|
||||
|
||||
if (spotID == kNorad01GasSpotID) {
|
||||
if (_fillingStationItem) {
|
||||
if (_fillingStationItem->getObjectID() == kGasCanister) {
|
||||
getExtraEntry(kNorad01ZoomInWithGasCanister, extra);
|
||||
entry.movieStart = extra.movieStart;
|
||||
entry.movieEnd = extra.movieEnd;
|
||||
} else {
|
||||
entry.clear();
|
||||
}
|
||||
}
|
||||
} else if (spotID == kNorad01GasOutSpotID) {
|
||||
if (_fillingStationItem) {
|
||||
if (_fillingStationItem->getObjectID() == kGasCanister) {
|
||||
getExtraEntry(kNorad01ZoomOutWithGasCanister, extra);
|
||||
entry.movieStart = extra.movieStart;
|
||||
entry.movieEnd = extra.movieEnd;
|
||||
} else {
|
||||
entry.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TimeValue NoradAlpha::getViewTime(const RoomID room, const DirectionConstant direction) {
|
||||
ExtraTable::Entry entry;
|
||||
|
||||
if (room == kNorad01 && direction == kSouth && !GameState.getNoradSeenTimeStream()) {
|
||||
getExtraEntry(kNoradArriveFromTSA, entry);
|
||||
return entry.movieStart;
|
||||
}
|
||||
|
||||
if (room == kNorad01 && direction == kWest) {
|
||||
if (!_fillingStationItem) {
|
||||
return Norad::getViewTime(room, direction);
|
||||
} else {
|
||||
getExtraEntry(kN01WGasCanister, entry);
|
||||
return entry.movieStart;
|
||||
}
|
||||
} else if (room == kNorad01West && direction == kWest) {
|
||||
uint32 extraID = 0xffffffff;
|
||||
if (_fillingStationItem) {
|
||||
switch (_fillingStationItem->getObjectID()) {
|
||||
case kArgonCanister:
|
||||
if (GameState.getNoradFillingStationOn())
|
||||
extraID = kN01WZArgonCanisterLit;
|
||||
else
|
||||
extraID = kN01WZArgonCanisterDim;
|
||||
break;
|
||||
case kGasCanister:
|
||||
if (GameState.getNoradFillingStationOn())
|
||||
extraID = kN01WZGasCanisterLit;
|
||||
else
|
||||
extraID = kN01WZGasCanisterDim;
|
||||
break;
|
||||
case kAirMask:
|
||||
if (GameState.getNoradFillingStationOn())
|
||||
extraID = kN01WZAirMaskLit;
|
||||
else
|
||||
extraID = kN01WZAirMaskDim;
|
||||
break;
|
||||
case kNitrogenCanister:
|
||||
if (GameState.getNoradFillingStationOn())
|
||||
extraID = kN01WZNitrogenCanisterLit;
|
||||
else
|
||||
extraID = kN01WZNitrogenCanisterDim;
|
||||
break;
|
||||
default:
|
||||
// Should never happen.
|
||||
break;
|
||||
}
|
||||
} else if (GameState.getNoradFillingStationOn()) {
|
||||
extraID = kN01WZEmptyLit;
|
||||
}
|
||||
|
||||
if (extraID == 0xffffffff) {
|
||||
return Norad::getViewTime(room, direction);
|
||||
} else {
|
||||
getExtraEntry(extraID, entry);
|
||||
return entry.movieStart;
|
||||
}
|
||||
}
|
||||
|
||||
return Norad::getViewTime(room, direction);
|
||||
}
|
||||
|
||||
void NoradAlpha::setSoundFXLevel(const uint16 level) {
|
||||
Neighborhood::setSoundFXLevel(level);
|
||||
|
||||
if (_extraMovie.isMovieValid())
|
||||
_extraMovie.setVolume(level);
|
||||
}
|
||||
|
||||
void NoradAlpha::turnOnFillingStation() {
|
||||
if (GameState.getCurrentRoom() == kNorad01West && !GameState.getNoradFillingStationOn()) {
|
||||
GameState.setNoradFillingStationOn(true);
|
||||
updateViewFrame();
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA72", kArthurNoradSawFillingStation);
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlpha::turnOffFillingStation() {
|
||||
if (GameState.getCurrentRoom() == kNorad01West && GameState.getNoradFillingStationOn()) {
|
||||
GameState.setNoradFillingStationOn(false);
|
||||
updateViewFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlpha::activateHotspots() {
|
||||
Norad::activateHotspots();
|
||||
|
||||
switch (GameState.getCurrentRoomAndView()) {
|
||||
case MakeRoomView(kNorad01West, kWest):
|
||||
if (_vm->getDragType() == kDragInventoryUse) {
|
||||
if (!_fillingStationItem) {
|
||||
ItemID itemID = _vm->getDraggingItem()->getObjectID();
|
||||
if (itemID == kArgonCanister || itemID == kGasCanister || itemID == kAirMask ||
|
||||
itemID == kNitrogenCanister)
|
||||
_vm->getAllHotspots().activateOneHotspot(kN01GasOutletSpotID);
|
||||
}
|
||||
} else {
|
||||
HotSpotID spotID;
|
||||
|
||||
if (_fillingStationItem) {
|
||||
switch (_fillingStationItem->getObjectID()) {
|
||||
case kArgonCanister:
|
||||
spotID = kN01ArgonCanisterSpotID;
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kNorad01GasOutSpotID);
|
||||
break;
|
||||
case kGasCanister:
|
||||
spotID = kN01GasCanisterSpotID;
|
||||
break;
|
||||
case kAirMask:
|
||||
spotID = kN01AirMaskSpotID;
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kNorad01GasOutSpotID);
|
||||
break;
|
||||
case kNitrogenCanister:
|
||||
spotID = kN01NitrogenCanisterSpotID;
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kNorad01GasOutSpotID);
|
||||
break;
|
||||
default:
|
||||
// Should never happen.
|
||||
spotID = kNoHotSpotID;
|
||||
break;
|
||||
}
|
||||
_vm->getAllHotspots().activateOneHotspot(spotID);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MakeRoomView(kNorad07, kNorth):
|
||||
if (_vm->isDVD())
|
||||
_vm->getAllHotspots().activateOneHotspot(kThermalScanHotSpotID);
|
||||
break;
|
||||
case MakeRoomView(kNorad10, kEast):
|
||||
if (GameState.isCurrentDoorOpen())
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kNorad10DoorSpotID);
|
||||
break;
|
||||
case MakeRoomView(kNorad21, kWest):
|
||||
if (GameState.isCurrentDoorOpen())
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kNorad21WestSpotID);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlpha::clickInHotspot(const Input &input, const Hotspot *cursorSpot) {
|
||||
Norad::clickInHotspot(input, cursorSpot);
|
||||
|
||||
if (_vm->getDragType() == kDragInventoryUse) {
|
||||
if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad01West, kWest)) {
|
||||
Item *item = _vm->getDraggingItem();
|
||||
if (item->getObjectID() == kAirMask || item->getObjectID() == kArgonCanister ||
|
||||
item->getObjectID() == kNitrogenCanister || item->getObjectID() == kGasCanister) {
|
||||
HotspotInfoTable::Entry *hotspotEntry = findHotspotEntry(kN01GasOutletSpotID);
|
||||
hotspotEntry->hotspotItem = item->getObjectID();
|
||||
}
|
||||
}
|
||||
} else if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad07, kNorth) &&
|
||||
cursorSpot->getObjectID() == kThermalScanHotSpotID) {
|
||||
startExtraSequence(kShowThermalScan, kExtraCompletedFlag, kFilterNoInput);
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlpha::takeItemFromRoom(Item *item) {
|
||||
if (GameState.getCurrentRoom() == kNorad01West) {
|
||||
if (_fillingStationItem == item) {
|
||||
_fillingStationItem = nullptr;
|
||||
GameState.setNoradGassed(false);
|
||||
checkAirMask();
|
||||
((NoradAlphaFillingStation *)_currentInteraction)->newFillingItem(nullptr);
|
||||
forceStridingStop(kNorad03, kEast, kAltNoradAlphaNormal);
|
||||
}
|
||||
}
|
||||
|
||||
Norad::takeItemFromRoom(item);
|
||||
}
|
||||
|
||||
void NoradAlpha::dropItemIntoRoom(Item *item, Hotspot *droppedSpot) {
|
||||
if (GameState.getCurrentRoom() == kNorad01West) {
|
||||
if (!_fillingStationItem) {
|
||||
_fillingStationItem = item;
|
||||
((NoradAlphaFillingStation *)_currentInteraction)->newFillingItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
Norad::dropItemIntoRoom(item, droppedSpot);
|
||||
}
|
||||
|
||||
void NoradAlpha::getClawInfo(HotSpotID &outSpotID, HotSpotID &prepSpotID, HotSpotID &clawControlSpotID, HotSpotID &pinchClawSpotID,
|
||||
HotSpotID &moveClawDownSpotID, HotSpotID &moveClawRightSpotID, HotSpotID &moveClawLeftSpotID, HotSpotID &moveClawUpSpotID,
|
||||
HotSpotID &clawCCWSpotID, HotSpotID &clawCWSpotID, uint32 &clawPosition, const uint32 *&clawExtraIDs) {
|
||||
outSpotID = kNorad22MonitorOutSpotID;
|
||||
prepSpotID = kNorad22LaunchPrepSpotID;
|
||||
clawControlSpotID = kNorad22ClawControlSpotID;
|
||||
pinchClawSpotID = kNorad22ClawPinchSpotID;
|
||||
moveClawDownSpotID = kNorad22ClawDownSpotID;
|
||||
moveClawRightSpotID = kNorad22ClawRightSpotID;
|
||||
moveClawLeftSpotID = kNorad22ClawLeftSpotID;
|
||||
moveClawUpSpotID = kNorad22ClawUpSpotID;
|
||||
clawCCWSpotID = kNorad22ClawCCWSpotID;
|
||||
clawCWSpotID = kNorad22ClawCWSpotID;
|
||||
clawPosition = kClawAtD;
|
||||
clawExtraIDs = _noradAlphaClawExtras;
|
||||
}
|
||||
|
||||
Hotspot *NoradAlpha::getItemScreenSpot(Item *item, DisplayElement *element) {
|
||||
switch (item->getObjectID()) {
|
||||
case kGasCanister:
|
||||
return _vm->getAllHotspots().findHotspotByID(kN01GasCanisterSpotID);
|
||||
case kAirMask:
|
||||
return _vm->getAllHotspots().findHotspotByID(kN01AirMaskSpotID);
|
||||
case kArgonCanister:
|
||||
return _vm->getAllHotspots().findHotspotByID(kN01ArgonCanisterSpotID);
|
||||
case kNitrogenCanister:
|
||||
return _vm->getAllHotspots().findHotspotByID(kN01NitrogenCanisterSpotID);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Norad::getItemScreenSpot(item, element);
|
||||
}
|
||||
|
||||
Common::Path NoradAlpha::getEnvScanMovie() {
|
||||
Common::Path movieName = Neighborhood::getEnvScanMovie();
|
||||
|
||||
if (movieName.empty()) {
|
||||
RoomID room = GameState.getCurrentRoom();
|
||||
if (room >= kNorad01 && room <= kNorad01West)
|
||||
return "Images/AI/Norad/XNE1";
|
||||
else if ((room >= kNorad02 && room <= kNorad19West))
|
||||
return "Images/AI/Norad/XNE2";
|
||||
|
||||
return "Images/AI/Norad/XNE3";
|
||||
}
|
||||
|
||||
return movieName;
|
||||
}
|
||||
|
||||
uint NoradAlpha::getNumHints() {
|
||||
uint numHints = Neighborhood::getNumHints();
|
||||
|
||||
if (numHints == 0) {
|
||||
switch (GameState.getCurrentRoomAndView()) {
|
||||
case MakeRoomView(kNorad01, kNorth):
|
||||
case MakeRoomView(kNorad01, kSouth):
|
||||
case MakeRoomView(kNorad01, kEast):
|
||||
case MakeRoomView(kNorad01, kWest):
|
||||
case MakeRoomView(kNorad01East, kEast):
|
||||
case MakeRoomView(kNorad01West, kWest):
|
||||
if (GameState.getNoradGassed()) {
|
||||
if (g_airMask->isAirFilterOn())
|
||||
numHints = 0;
|
||||
else
|
||||
numHints = 3;
|
||||
} else {
|
||||
numHints = 2;
|
||||
}
|
||||
break;
|
||||
case MakeRoomView(kNorad19West, kWest):
|
||||
if (getSubPrepFailed() && GameState.getNoradSubPrepState() != kSubPrepped)
|
||||
numHints = 1;
|
||||
break;
|
||||
case MakeRoomView(kNorad22, kWest):
|
||||
numHints = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return numHints;
|
||||
}
|
||||
|
||||
Common::Path NoradAlpha::getHintMovie(uint hintNum) {
|
||||
Common::Path movieName = Neighborhood::getHintMovie(hintNum);
|
||||
|
||||
if (movieName.empty()) {
|
||||
switch (GameState.getCurrentRoomAndView()) {
|
||||
case MakeRoomView(kNorad01, kNorth):
|
||||
case MakeRoomView(kNorad01, kSouth):
|
||||
case MakeRoomView(kNorad01, kEast):
|
||||
case MakeRoomView(kNorad01, kWest):
|
||||
case MakeRoomView(kNorad01East, kEast):
|
||||
case MakeRoomView(kNorad01West, kWest):
|
||||
switch (hintNum) {
|
||||
case 1:
|
||||
if (GameState.getNoradGassed())
|
||||
return "Images/AI/Norad/XN01SW";
|
||||
|
||||
return "Images/AI/Norad/XN01WD2";
|
||||
case 2:
|
||||
if (GameState.getNoradGassed()) {
|
||||
if (_vm->playerHasItemID(kAirMask))
|
||||
// Mask must not be on if we get here...
|
||||
return "Images/AI/Globals/XGLOB1A";
|
||||
|
||||
return "Images/AI/Globals/XGLOB3D";
|
||||
}
|
||||
|
||||
return "Images/AI/Globals/XGLOB5C";
|
||||
case 3:
|
||||
return "Images/AI/Norad/XN01SH";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MakeRoomView(kNorad19West, kWest):
|
||||
return "Images/AI/Norad/XN19NH";
|
||||
case MakeRoomView(kNorad22, kWest):
|
||||
return "Images/AI/Globals/XGLOB1C";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return movieName;
|
||||
}
|
||||
|
||||
void NoradAlpha::closeDoorOffScreen(const RoomID room, const DirectionConstant) {
|
||||
switch (room) {
|
||||
case kNorad12:
|
||||
case kNorad13:
|
||||
case kNorad18:
|
||||
case kNorad19:
|
||||
playSpotSoundSync(kAlphaElevatorDoorCloseIn, kAlphaElevatorDoorCloseOut);
|
||||
break;
|
||||
default:
|
||||
playSpotSoundSync(kAlphaRegDoorCloseIn, kAlphaRegDoorCloseOut);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NoradAlpha::findSpotEntry(const RoomID room, const DirectionConstant direction, SpotFlags flags, SpotTable::Entry &spotEntry) {
|
||||
if (room == kNorad01 && direction == kSouth)
|
||||
spotEntry.clear();
|
||||
else
|
||||
Norad::findSpotEntry(room, direction, flags, spotEntry);
|
||||
}
|
||||
|
||||
bool NoradAlpha::canSolve() {
|
||||
return Norad::canSolve() || getHintMovie(1) == "Images/AI/Norad/XN01SW";
|
||||
}
|
||||
|
||||
void NoradAlpha::doSolve() {
|
||||
Norad::doSolve();
|
||||
|
||||
if (getHintMovie(1) == "Images/AI/Norad/XN01SW") {
|
||||
_vm->addItemToInventory(g_airMask);
|
||||
g_airMask->putMaskOn();
|
||||
}
|
||||
}
|
||||
|
||||
Common::Path NoradAlpha::getNavMovieName() {
|
||||
return "Images/Norad Alpha/Norad Alpha.movie";
|
||||
}
|
||||
|
||||
Common::Path NoradAlpha::getSoundSpotsName() {
|
||||
return "Sounds/Norad/Norad Alpha Spots";
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
126
engines/pegasus/neighborhood/norad/alpha/noradalpha.h
Normal file
126
engines/pegasus/neighborhood/norad/alpha/noradalpha.h
Normal file
@@ -0,0 +1,126 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_NORADALPHA_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_NORADALPHA_H
|
||||
|
||||
#include "pegasus/neighborhood/norad/norad.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class Item;
|
||||
class SubChase;
|
||||
|
||||
class NoradAlpha : public Norad {
|
||||
friend class SubChase;
|
||||
public:
|
||||
NoradAlpha(InputHandler *, PegasusEngine *);
|
||||
~NoradAlpha() override;
|
||||
|
||||
void init() override;
|
||||
void start() override;
|
||||
|
||||
bool okayToJump() override;
|
||||
|
||||
void playClawMonitorIntro() override;
|
||||
|
||||
void getExtraCompassMove(const ExtraTable::Entry &, FaderMoveSpec &) override;
|
||||
|
||||
void turnOnFillingStation();
|
||||
void turnOffFillingStation();
|
||||
Item *getFillingItem() { return _fillingStationItem; }
|
||||
bool gasCanisterIntake();
|
||||
|
||||
void takeItemFromRoom(Item *) override;
|
||||
void dropItemIntoRoom(Item *, Hotspot *) override;
|
||||
|
||||
GameInteraction *makeInteraction(const InteractionID) override;
|
||||
|
||||
void getClawInfo(HotSpotID &outSpotID, HotSpotID &prepSpotID, HotSpotID &clawControlSpotID,
|
||||
HotSpotID &pinchClawSpotID, HotSpotID &moveClawDownSpotID, HotSpotID &moveClawRightSpotID,
|
||||
HotSpotID &moveClawLeftSpotID, HotSpotID &moveClawUpSpotID, HotSpotID &clawCCWSpotID,
|
||||
HotSpotID &clawCWSpotID, uint32 &, const uint32 *&) override;
|
||||
|
||||
void loadAmbientLoops() override;
|
||||
|
||||
Common::Path getEnvScanMovie() override;
|
||||
uint getNumHints() override;
|
||||
Common::Path getHintMovie(uint) override;
|
||||
void setUpAIRules() override;
|
||||
|
||||
void setSubPrepFailed(bool value) { _subPrepFailed = value; }
|
||||
bool getSubPrepFailed() { return _subPrepFailed; }
|
||||
|
||||
void closeDoorOffScreen(const RoomID, const DirectionConstant) override;
|
||||
void findSpotEntry(const RoomID, const DirectionConstant, SpotFlags, SpotTable::Entry &) override;
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
|
||||
void checkContinuePoint(const RoomID, const DirectionConstant) override;
|
||||
|
||||
void setSoundFXLevel(const uint16) override;
|
||||
|
||||
bool canSolve() override;
|
||||
void doSolve() override;
|
||||
|
||||
protected:
|
||||
static const uint32 _noradAlphaClawExtras[22];
|
||||
|
||||
virtual void arriveAtNorad01();
|
||||
virtual void arriveAtNorad01East();
|
||||
virtual void arriveAtNorad01West();
|
||||
virtual void arriveAtNorad04();
|
||||
virtual void arriveAtNorad22();
|
||||
|
||||
void arriveAt(const RoomID, const DirectionConstant) override;
|
||||
void turnTo(const DirectionConstant) override;
|
||||
|
||||
void startExtraSequence(const ExtraID, const NotificationFlags, const InputBits) override;
|
||||
|
||||
void getZoomEntry(const HotSpotID, ZoomTable::Entry &) override;
|
||||
TimeValue getViewTime(const RoomID, const DirectionConstant) override;
|
||||
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
|
||||
void activateHotspots() override;
|
||||
|
||||
Hotspot *getItemScreenSpot(Item *, DisplayElement *) override;
|
||||
|
||||
void bumpIntoWall() override;
|
||||
|
||||
Hotspot _thermalScanSpot;
|
||||
|
||||
Movie _extraMovie;
|
||||
NotificationCallBack _extraMovieCallBack;
|
||||
|
||||
Item *_fillingStationItem;
|
||||
|
||||
bool _subPrepFailed;
|
||||
|
||||
Common::Path getSoundSpotsName() override;
|
||||
Common::Path getNavMovieName() override;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
238
engines/pegasus/neighborhood/norad/alpha/panorama.cpp
Normal file
238
engines/pegasus/neighborhood/norad/alpha/panorama.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/macresman.h"
|
||||
#include "common/stream.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/panorama.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
Panorama::Panorama() : _panoramaMovie(kNoDisplayElement) {
|
||||
blankFields();
|
||||
}
|
||||
|
||||
Panorama::~Panorama() {
|
||||
releasePanorama();
|
||||
}
|
||||
|
||||
void Panorama::blankFields() {
|
||||
_viewBounds = Common::Rect();
|
||||
_drawBounds = Common::Rect();
|
||||
_mask = nullptr;
|
||||
_panoramaWidth = 0;
|
||||
_panoramaHeight = 0;
|
||||
_stripWidth = 0;
|
||||
_stripLeft = -1;
|
||||
_stripRight = -1;
|
||||
}
|
||||
|
||||
void Panorama::releasePanorama() {
|
||||
if (_panoramaMovie.isMovieValid()) {
|
||||
_panoramaMovie.releaseMovie();
|
||||
_panoramaWorld.deallocateSurface();
|
||||
blankFields();
|
||||
}
|
||||
}
|
||||
|
||||
static const uint32 kPanoramaResType = MKTAG('P', 'a', 'n', 'I'); // Panorama Information.
|
||||
static const uint16 kPanoramaResID = 128;
|
||||
|
||||
void Panorama::initFromMovieFile(const Common::Path &fileName) {
|
||||
// First, we need the resource fork for other reasons -- PanI resource
|
||||
Common::MacResManager *resFork = new Common::MacResManager();
|
||||
if (!resFork->open(fileName) || !resFork->hasResFork())
|
||||
error("Could not open the resource fork of '%s'", fileName.toString().c_str());
|
||||
|
||||
Common::SeekableReadStream *resource = resFork->getResource(kPanoramaResType, kPanoramaResID);
|
||||
if (!resource)
|
||||
error("No panorama information in the resource fork of '%s'", fileName.toString().c_str());
|
||||
|
||||
_panoramaWidth = resource->readUint16BE();
|
||||
_panoramaHeight = resource->readUint16BE();
|
||||
_stripWidth = resource->readUint16BE();
|
||||
|
||||
delete resource;
|
||||
delete resFork;
|
||||
|
||||
// Now we open the movie like normal
|
||||
_panoramaMovie.initFromMovieFile(fileName);
|
||||
}
|
||||
|
||||
void Panorama::setMask(Surface *mask) {
|
||||
_mask = mask;
|
||||
}
|
||||
|
||||
// If the panorama is not open, do nothing and return.
|
||||
// Otherwise, set up the view bounds.
|
||||
void Panorama::setViewBounds(const Common::Rect &newView) {
|
||||
if (!isPanoramaOpen())
|
||||
return;
|
||||
|
||||
if (newView.isEmpty())
|
||||
return;
|
||||
|
||||
Common::Rect r = newView;
|
||||
|
||||
if (r.width() > _panoramaWidth) {
|
||||
r.left = 0;
|
||||
r.right = _panoramaWidth;
|
||||
} else {
|
||||
if (r.right > _panoramaWidth)
|
||||
r.translate(_panoramaWidth - r.right, 0);
|
||||
|
||||
if (r.left < 0)
|
||||
r.translate(-r.left, 0);
|
||||
}
|
||||
|
||||
if (r.height() > _panoramaHeight) {
|
||||
r.top = 0;
|
||||
r.bottom = _panoramaHeight;
|
||||
} else {
|
||||
if (r.bottom > _panoramaHeight)
|
||||
r.translate(0, _panoramaHeight - r.bottom);
|
||||
|
||||
if (r.top < 0)
|
||||
r.translate(0, -r.top);
|
||||
}
|
||||
|
||||
if (_viewBounds != r) {
|
||||
CoordType stripLeft = 0;
|
||||
|
||||
if (r.width() != _viewBounds.width() || !_panoramaWorld.isSurfaceValid()) {
|
||||
_panoramaWorld.deallocateSurface();
|
||||
makeNewSurface(r);
|
||||
} else {
|
||||
CoordType stripRight;
|
||||
calcStripRange(r, stripLeft, stripRight);
|
||||
loadStrips(stripLeft, stripRight);
|
||||
}
|
||||
|
||||
_viewBounds = r;
|
||||
_drawBounds = r;
|
||||
_drawBounds.translate(-stripLeft * _stripWidth, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Panorama::getViewBounds(Common::Rect &r) const {
|
||||
r = _viewBounds;
|
||||
}
|
||||
|
||||
void Panorama::getPanoramaBounds(Common::Rect &r) const {
|
||||
r = Common::Rect(0, 0, _panoramaWidth, _panoramaHeight);
|
||||
}
|
||||
|
||||
void Panorama::drawPanorama(const Common::Rect &destRect) {
|
||||
if (_panoramaWorld.isSurfaceValid()) {
|
||||
if (_mask)
|
||||
_panoramaWorld.copyToCurrentPortMasked(_drawBounds, destRect, _mask);
|
||||
else
|
||||
_panoramaWorld.copyToCurrentPortTransparent(_drawBounds, destRect);
|
||||
}
|
||||
}
|
||||
|
||||
// Make a new Surface big enough to show r, which is assumed to be a valid view bounds.
|
||||
// Assumptions:
|
||||
// r is a valid view bounds.
|
||||
// _panoramaWorld is not allocated.
|
||||
// _panoramaHeight, _stripWidth is correct.
|
||||
// _panoramaMovie is allocated.
|
||||
void Panorama::makeNewSurface(const Common::Rect& view) {
|
||||
CoordType stripLeft, stripRight;
|
||||
calcStripRange(view, stripLeft, stripRight);
|
||||
|
||||
Common::Rect r(0, 0, (stripRight - stripLeft + 1) * _stripWidth, _panoramaHeight);
|
||||
_panoramaWorld.allocateSurface(r);
|
||||
_panoramaMovie.shareSurface(&_panoramaWorld);
|
||||
loadStrips(stripLeft, stripRight);
|
||||
}
|
||||
|
||||
// Assumes view is not empty.
|
||||
void Panorama::calcStripRange(const Common::Rect &view, CoordType &stripLeft, CoordType &stripRight) {
|
||||
stripLeft = view.left / _stripWidth;
|
||||
stripRight = (view.left - view.left % _stripWidth + _stripWidth - 1 + view.width()) / _stripWidth;
|
||||
}
|
||||
|
||||
// Load in all needed strips to put range (stripLeft, stripRight) into the
|
||||
// panorama's Surface. Try to optimize by saving any pixels already in the Surface.
|
||||
// Assumptions:
|
||||
// Surface is allocated and is big enough for maximum range of
|
||||
// stripLeft and stripRight
|
||||
void Panorama::loadStrips(CoordType stripLeft, CoordType stripRight) {
|
||||
if (_stripLeft == -1) {
|
||||
// Surface has just been allocated.
|
||||
// Load in all strips.
|
||||
for (CoordType i = stripLeft; i <= stripRight; i++)
|
||||
loadOneStrip(i, stripLeft);
|
||||
|
||||
_stripLeft = stripLeft;
|
||||
_stripRight = stripRight;
|
||||
} else if (stripLeft != _stripLeft) {
|
||||
CoordType overlapLeft = MAX(stripLeft, _stripLeft);
|
||||
CoordType overlapRight = MIN(stripRight, _stripRight);
|
||||
|
||||
if (overlapLeft <= overlapRight) {
|
||||
Common::Rect r1((overlapLeft - _stripLeft) * _stripWidth, 0,
|
||||
(overlapRight - _stripLeft + 1) * _stripWidth, _panoramaHeight);
|
||||
|
||||
if (stripLeft < _stripLeft) {
|
||||
Common::Rect bounds;
|
||||
_panoramaWorld.getSurfaceBounds(bounds);
|
||||
_panoramaWorld.getSurface()->move(bounds.right - r1.right, 0, _panoramaHeight);
|
||||
|
||||
for (CoordType i = stripLeft; i < _stripLeft; i++)
|
||||
loadOneStrip(i, stripLeft);
|
||||
} else {
|
||||
_panoramaWorld.getSurface()->move(-r1.left, 0, _panoramaHeight);
|
||||
|
||||
for (CoordType i = _stripRight + 1; i <= stripRight; i++)
|
||||
loadOneStrip(i, stripLeft);
|
||||
}
|
||||
} else {
|
||||
// No overlap.
|
||||
// Load everything.
|
||||
for (CoordType i = stripLeft; i <= stripRight; i++)
|
||||
loadOneStrip(i, stripLeft);
|
||||
}
|
||||
|
||||
_stripLeft = stripLeft;
|
||||
_stripRight = stripRight;
|
||||
} else if (stripRight > _stripRight) {
|
||||
// Need to add one or more strips.
|
||||
for (CoordType i = _stripRight + 1; i <= stripRight; i++)
|
||||
loadOneStrip(i, _stripLeft);
|
||||
|
||||
_stripRight = stripRight;
|
||||
} else if (stripRight < _stripRight) {
|
||||
// Need to chop off one strip.
|
||||
_stripRight = stripRight;
|
||||
}
|
||||
}
|
||||
|
||||
void Panorama::loadOneStrip(CoordType stripToLoad, CoordType leftStrip) {
|
||||
_panoramaMovie.moveMovieBoxTo((stripToLoad - leftStrip) * _stripWidth, 0);
|
||||
_panoramaMovie.setTime(stripToLoad, 1);
|
||||
_panoramaMovie.redrawMovieWorld();
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
97
engines/pegasus/neighborhood/norad/alpha/panorama.h
Normal file
97
engines/pegasus/neighborhood/norad/alpha/panorama.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_PANORAMA_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_PANORAMA_H
|
||||
|
||||
#include "pegasus/movie.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
/*
|
||||
|
||||
Panorama implements a wide image using a specially constructed movie file.
|
||||
The movie holds the image as a series of vertical strips, say 16 or 32 pixels wide.
|
||||
|
||||
The panorama bounds defines the entire panorama. The view bounds represents the
|
||||
area on the panorama that is kept in memory.
|
||||
|
||||
The panorama bounds is also stored in the movie file; it cannot be changed. The
|
||||
view bounds must always be a subset of the panorama bounds.
|
||||
|
||||
In actuality, the area kept in memory is at least as wide as the view bounds (but
|
||||
may be wider to coincide with the width of the movies slices), and is as tall as
|
||||
the panorama bounds. The view bounds is used by the drawPanorama function to draw
|
||||
a piece of the panorama to the current screen.
|
||||
|
||||
The panorama movie is built at a time scale of 1, with each strip lasting for one
|
||||
second, so that strip number corresponds exactly with the time value at which the
|
||||
strip is stored.
|
||||
|
||||
TO USE:
|
||||
|
||||
Call one initFromMovieFile to open the movie. Then set up a view rect by
|
||||
calling setViewBounds. Once these two functions have been called, drawPanorama
|
||||
will draw the panorama.
|
||||
|
||||
*/
|
||||
|
||||
class Panorama {
|
||||
public:
|
||||
Panorama();
|
||||
virtual ~Panorama();
|
||||
|
||||
void initFromMovieFile(const Common::Path &);
|
||||
void releasePanorama();
|
||||
bool isPanoramaOpen() { return _panoramaMovie.isMovieValid(); }
|
||||
|
||||
void setViewBounds(const Common::Rect &);
|
||||
void getViewBounds(Common::Rect &) const;
|
||||
|
||||
void setMask(Surface *);
|
||||
|
||||
void getPanoramaBounds(Common::Rect &) const;
|
||||
|
||||
void drawPanorama(const Common::Rect &);
|
||||
|
||||
protected:
|
||||
void blankFields();
|
||||
void makeNewSurface(const Common::Rect &);
|
||||
void calcStripRange(const Common::Rect &, CoordType &, CoordType &);
|
||||
void loadStrips(CoordType, CoordType);
|
||||
void loadOneStrip(CoordType, CoordType);
|
||||
|
||||
Movie _panoramaMovie;
|
||||
Surface _panoramaWorld, *_mask;
|
||||
Common::Rect _viewBounds;
|
||||
Common::Rect _drawBounds;
|
||||
CoordType _panoramaWidth, _panoramaHeight;
|
||||
CoordType _stripWidth; // Pixels per strip.
|
||||
CoordType _numStrips;
|
||||
CoordType _stripLeft, _stripRight;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
90
engines/pegasus/neighborhood/norad/alpha/panoramascroll.cpp
Normal file
90
engines/pegasus/neighborhood/norad/alpha/panoramascroll.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/neighborhood/norad/alpha/panoramascroll.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
PanoramaScroll::PanoramaScroll(const DisplayElementID id) : IdlerAnimation(id) {
|
||||
_boundsWidth = 0;
|
||||
_totalWidth = 0;
|
||||
}
|
||||
|
||||
void PanoramaScroll::initFromMovieFile(const Common::Path &fileName) {
|
||||
_panorama.initFromMovieFile(fileName);
|
||||
|
||||
Common::Rect r;
|
||||
_panorama.getPanoramaBounds(r);
|
||||
_totalWidth = r.width();
|
||||
}
|
||||
|
||||
void PanoramaScroll::initMaskFromPICTFile(const Common::Path &fileName) {
|
||||
if (!_panorama.isPanoramaOpen())
|
||||
return;
|
||||
|
||||
_mask.getImageFromPICTFile(fileName);
|
||||
_panorama.setMask(&_mask);
|
||||
}
|
||||
|
||||
void PanoramaScroll::releasePanorama() {
|
||||
if (_panorama.isPanoramaOpen())
|
||||
_panorama.releasePanorama();
|
||||
|
||||
_mask.deallocateSurface();
|
||||
}
|
||||
|
||||
void PanoramaScroll::setBounds(const Common::Rect &r) {
|
||||
Animation::setBounds(r);
|
||||
|
||||
_boundsWidth = r.width();
|
||||
|
||||
Common::Rect r2;
|
||||
_panorama.getViewBounds(r2);
|
||||
r2.right = r2.left + _boundsWidth;
|
||||
r2.bottom = r2.top + r.height();
|
||||
_panorama.setViewBounds(r2);
|
||||
}
|
||||
|
||||
void PanoramaScroll::draw(const Common::Rect &) {
|
||||
_panorama.drawPanorama(_bounds);
|
||||
}
|
||||
|
||||
void PanoramaScroll::timeChanged(const TimeValue newTime) {
|
||||
CoordType leftPixel = (_totalWidth - _boundsWidth) * newTime / getDuration();
|
||||
|
||||
Common::Rect r;
|
||||
_panorama.getViewBounds(r);
|
||||
if (leftPixel != r.left) {
|
||||
_panorama.getViewBounds(r);
|
||||
r.moveTo(leftPixel, 0);
|
||||
_panorama.setViewBounds(r);
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
void PanoramaScroll::getPanoramaBounds(Common::Rect &r) const {
|
||||
_panorama.getPanoramaBounds(r);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
59
engines/pegasus/neighborhood/norad/alpha/panoramascroll.h
Normal file
59
engines/pegasus/neighborhood/norad/alpha/panoramascroll.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_PANORAMASCROLL_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_PANORAMASCROLL_H
|
||||
|
||||
#include "pegasus/neighborhood/norad/alpha/panorama.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class PanoramaScroll : public IdlerAnimation {
|
||||
public:
|
||||
PanoramaScroll(const DisplayElementID);
|
||||
~PanoramaScroll() override {}
|
||||
|
||||
void initFromMovieFile(const Common::Path &);
|
||||
void initMaskFromPICTFile(const Common::Path &);
|
||||
|
||||
void releasePanorama();
|
||||
|
||||
bool isPanoramaOpen() { return _panorama.isPanoramaOpen(); }
|
||||
void getPanoramaBounds(Common::Rect &) const;
|
||||
|
||||
void setBounds(const Common::Rect&) override;
|
||||
|
||||
void draw(const Common::Rect &) override;
|
||||
|
||||
protected:
|
||||
void timeChanged(const TimeValue) override;
|
||||
|
||||
Panorama _panorama;
|
||||
Surface _mask;
|
||||
CoordType _totalWidth, _boundsWidth;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
458
engines/pegasus/neighborhood/norad/alpha/subchase.cpp
Normal file
458
engines/pegasus/neighborhood/norad/alpha/subchase.cpp
Normal file
@@ -0,0 +1,458 @@
|
||||
/* 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-2013 Presto Studios, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/subchase.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/noradalpha.h"
|
||||
#include "pegasus/neighborhood/norad/constants.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
static const TimeScale kSubChaseScale = 600;
|
||||
|
||||
static const DisplayOrder kSubChaseOrder = 27000;
|
||||
|
||||
// Segment start and end points.
|
||||
|
||||
static const TimeValue kIntroStart = 0;
|
||||
static const TimeValue kIntroEnd = 2400;
|
||||
static const TimeValue kDialogStart = kIntroEnd;
|
||||
static const TimeValue kDialogEnd = 20920;
|
||||
static const TimeValue kBranch1Start = kDialogEnd;
|
||||
static const TimeValue kBranch1End = 32120;
|
||||
static const TimeValue kBranch2LeftStart = kBranch1End;
|
||||
static const TimeValue kBranch2LeftEnd = 48080;
|
||||
static const TimeValue kBranch3Start = kBranch2LeftEnd;
|
||||
static const TimeValue kBranch3End = 61080;
|
||||
static const TimeValue kBranch4Start = kBranch3End;
|
||||
static const TimeValue kBranch4End = 84080;
|
||||
static const TimeValue kBranch5Start = kBranch4End;
|
||||
static const TimeValue kBranch5End = 94840;
|
||||
static const TimeValue kBranch6Start = kBranch5End;
|
||||
static const TimeValue kBranch6End = 106040;
|
||||
static const TimeValue kBranch7LeftStart = kBranch6End;
|
||||
static const TimeValue kBranch7LeftEnd = 118840;
|
||||
static const TimeValue kExitStart = kBranch7LeftEnd;
|
||||
static const TimeValue kExitEnd = 133200;
|
||||
static const TimeValue kBranch2RightStart = 133200;
|
||||
static const TimeValue kBranch2RightEnd = 149160;
|
||||
static const TimeValue kBranch7RightStart = 168000;
|
||||
static const TimeValue kBranch7RightEnd = 180800;
|
||||
|
||||
// Death start and end points.
|
||||
|
||||
static const TimeValue kDeath4Start = 149160;
|
||||
static const TimeValue kDeath4End = 158040;
|
||||
static const TimeValue kDeath5Start = kDeath4End;
|
||||
static const TimeValue kDeath5End = 163760;
|
||||
static const TimeValue kDeath6Start = kDeath5End;
|
||||
static const TimeValue kDeath6End = 168000;
|
||||
static const TimeValue kDeath7Start = 180800;
|
||||
static const TimeValue kDeath7End = 187040;
|
||||
|
||||
// Chase state.
|
||||
|
||||
enum {
|
||||
kSubDialog,
|
||||
kSubBranch1,
|
||||
kSubBranch2Left,
|
||||
kSubBranch2Right,
|
||||
kSubBranch3,
|
||||
kSubBranch4,
|
||||
kSubBranch5,
|
||||
kSubBranch6,
|
||||
kSubBranch7Left,
|
||||
kSubBranch7Right,
|
||||
kSubExit
|
||||
};
|
||||
|
||||
void HintTimerEvent::fire() {
|
||||
subChase->hintTimerExpired(*this);
|
||||
}
|
||||
|
||||
void BlinkTimerEvent::fire() {
|
||||
subChase->blinkTimerExpired(*this);
|
||||
}
|
||||
|
||||
SubChase::SubChase(Neighborhood *handler) : ChaseInteraction(kNoradSubChaseInteractionID, handler,
|
||||
kNoradSubChaseNotificationID, g_vm), _subMovie(kNoDisplayElement),
|
||||
_hintPict(kNoDisplayElement), _blinkPict(kNoDisplayElement), _canSteerSub(true) {
|
||||
}
|
||||
|
||||
void SubChase::setSoundFXLevel(const uint16 fxLevel) {
|
||||
_subMovie.setVolume(fxLevel);
|
||||
}
|
||||
|
||||
void SubChase::openInteraction() {
|
||||
_subMovie.initFromMovieFile("Images/Norad Alpha/Sub Chase Movie");
|
||||
_subMovie.setVolume(g_vm->getSoundFXLevel());
|
||||
_subMovie.moveElementTo(0, 0);
|
||||
_subMovie.setDisplayOrder(kSubChaseOrder);
|
||||
_subMovie.startDisplaying();
|
||||
_subMovie.show();
|
||||
|
||||
_subCallBack.setNotification(&_chaseNotification);
|
||||
_subCallBack.initCallBack(&_subMovie, kCallBackAtExtremes);
|
||||
|
||||
ChaseInteraction::openInteraction();
|
||||
|
||||
_steerPict.setDisplayOrder(kSubChaseOrder + 1);
|
||||
_steerPict.moveElementTo(kNoradSubSteerLeft, kNoradSubSteerTop);
|
||||
|
||||
_hintPict.initFromPICTFile("Images/Norad Alpha/Sub Chase steerk1.pict", true);
|
||||
_hintPict.setDisplayOrder(kSubChaseOrder + 1);
|
||||
_hintPict.moveElementTo(kNoradSubHintLeft, kNoradSubHintTop);
|
||||
_blinkPict.initFromPICTFile("Images/Norad Alpha/Sub Chase steerk0.pict", true);
|
||||
_blinkPict.setDisplayOrder(kSubChaseOrder + 1);
|
||||
_blinkPict.moveElementTo(kNoradSubHintLeft, kNoradSubHintTop);
|
||||
}
|
||||
|
||||
void SubChase::initInteraction() {
|
||||
_canSteerSub = !GameState.getWalkthroughMode();
|
||||
|
||||
_owner->playMovieSegment(&_subMovie, kIntroStart, kIntroEnd);
|
||||
|
||||
_subCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
|
||||
if (_canSteerSub) {
|
||||
_steerPict.startDisplaying();
|
||||
_hintPict.startDisplaying();
|
||||
_blinkPict.startDisplaying();
|
||||
startHintTimer(20000 - kDialogStart, kSubChaseScale, kStartedHint);
|
||||
_subCallBack.setCallBackFlag(kChaseEnteredBranchZone);
|
||||
_subMovie.setSegment(kDialogStart, kBranch1End - kDecisionTime);
|
||||
} else {
|
||||
_subCallBack.setCallBackFlag(kChaseFinished);
|
||||
_subMovie.setSegment(kDialogStart, kExitEnd);
|
||||
}
|
||||
|
||||
_subState = kSubDialog;
|
||||
_subMovie.setTime(kDialogStart);
|
||||
_subMovie.start();
|
||||
|
||||
ChaseInteraction::initInteraction();
|
||||
}
|
||||
|
||||
void SubChase::closeInteraction() {
|
||||
_subMovie.stop();
|
||||
_subMovie.stopDisplaying();
|
||||
_subMovie.releaseMovie();
|
||||
_subCallBack.releaseCallBack();
|
||||
|
||||
_hintPict.hide();
|
||||
_hintPict.deallocateSurface();
|
||||
|
||||
_blinkPict.hide();
|
||||
_blinkPict.deallocateSurface();
|
||||
|
||||
ChaseInteraction::closeInteraction();
|
||||
}
|
||||
|
||||
void SubChase::receiveNotification(Notification *notification, const NotificationFlags flags) {
|
||||
if (notification == &_chaseNotification && flags == kChaseFinished) {
|
||||
if (_subState != kSubDialog && _subState != kSubExit) {
|
||||
// We died
|
||||
((NoradAlpha *)_owner)->die(kDeathSubDestroyed);
|
||||
} else {
|
||||
_subMovie.stopDisplaying();
|
||||
g_vm->_gfx->enableErase();
|
||||
g_vm->_gfx->updateDisplay();
|
||||
g_vm->_gfx->disableErase();
|
||||
g_vm->jumpToNewEnvironment(kNoradDeltaID, kNorad41, kEast);
|
||||
}
|
||||
}
|
||||
ChaseInteraction::receiveNotification(notification, flags);
|
||||
}
|
||||
|
||||
void SubChase::handleInput(const Input &input, const Hotspot *cursorSpot) {
|
||||
if (_subMovie.getTime() < kBranch1Start && input.anyInput()) {
|
||||
if (_canSteerSub) {
|
||||
if (!_blinkFuse.isFuseLit()) {
|
||||
// If the hint is not blinking then it must not be running, so display it
|
||||
_hintPict.show();
|
||||
startBlinkTimer(10, 10, kEnteredBlinkState);
|
||||
}
|
||||
_subState = kSubBranch1;
|
||||
startHintTimer(3000, kSubChaseScale, kEndedHint);
|
||||
} else {
|
||||
_subState = kSubExit;
|
||||
}
|
||||
_subMovie.setTime(kBranch1Start);
|
||||
} else {
|
||||
ChaseInteraction::handleInput(input, cursorSpot);
|
||||
}
|
||||
}
|
||||
|
||||
void SubChase::setUpBranch() {
|
||||
TimeValue branchStart, branchEnd;
|
||||
|
||||
branchStart = 0;
|
||||
branchEnd = 0;
|
||||
switch (_subState) {
|
||||
case kSubDialog:
|
||||
case kSubBranch1:
|
||||
branchStart = kBranch1End - kDecisionTime;
|
||||
branchEnd = kBranch1End;
|
||||
break;
|
||||
case kSubBranch2Left:
|
||||
branchStart = kBranch2LeftEnd - kDecisionTime;
|
||||
branchEnd = kBranch2LeftEnd;
|
||||
break;
|
||||
case kSubBranch2Right:
|
||||
branchStart = kBranch2RightEnd - kDecisionTime;
|
||||
branchEnd = kBranch2RightEnd;
|
||||
break;
|
||||
case kSubBranch3:
|
||||
branchStart = kBranch3End - kDecisionTime;
|
||||
branchEnd = kBranch3End;
|
||||
break;
|
||||
case kSubBranch4:
|
||||
branchStart = kBranch4End - kDecisionTime;
|
||||
branchEnd = kBranch4End;
|
||||
break;
|
||||
case kSubBranch5:
|
||||
branchStart = kBranch5End - kDecisionTime;
|
||||
branchEnd = kBranch5End;
|
||||
break;
|
||||
case kSubBranch6:
|
||||
branchStart = kBranch6End - kDecisionTime;
|
||||
branchEnd = kBranch6End;
|
||||
break;
|
||||
case kSubBranch7Left:
|
||||
branchStart = kBranch7LeftEnd - kDecisionTime;
|
||||
branchEnd = kBranch7LeftEnd;
|
||||
break;
|
||||
case kSubBranch7Right:
|
||||
branchStart = kBranch7RightEnd - kDecisionTime;
|
||||
branchEnd = kBranch7RightEnd;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_subMovie.setSegment(branchStart, branchEnd);
|
||||
|
||||
_subCallBack.setCallBackFlag(kChaseExitedBranchZone);
|
||||
_subCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
}
|
||||
|
||||
void SubChase::branchLeft() {
|
||||
TimeValue branchStart, branchEnd;
|
||||
NotificationFlags flag;
|
||||
|
||||
branchStart = 0;
|
||||
branchEnd = 0;
|
||||
flag = 0;
|
||||
switch (_subState) {
|
||||
case kSubDialog:
|
||||
case kSubBranch1:
|
||||
branchStart = kBranch2LeftStart;
|
||||
branchEnd = kBranch2LeftEnd;
|
||||
// Don't show the controls hint when we approach the whale
|
||||
// since the branch segments here are identical
|
||||
flag = kChaseExitedBranchZone;
|
||||
_subState = kSubBranch2Left;
|
||||
break;
|
||||
case kSubBranch2Left:
|
||||
case kSubBranch2Right:
|
||||
branchStart = kBranch3Start;
|
||||
branchEnd = kBranch3End - kDecisionTime;
|
||||
flag = kChaseEnteredBranchZone;
|
||||
_subState = kSubBranch3;
|
||||
break;
|
||||
case kSubBranch3:
|
||||
branchStart = kBranch4Start;
|
||||
branchEnd = kBranch4End - kDecisionTime;
|
||||
flag = kChaseEnteredBranchZone;
|
||||
_subState = kSubBranch4;
|
||||
break;
|
||||
case kSubBranch4:
|
||||
branchStart = kDeath5Start;
|
||||
branchEnd = kDeath5End;
|
||||
flag = kChaseFinished;
|
||||
_subState = kSubBranch5;
|
||||
break;
|
||||
case kSubBranch5:
|
||||
branchStart = kBranch6Start;
|
||||
branchEnd = kBranch6End - kDecisionTime;
|
||||
flag = kChaseEnteredBranchZone;
|
||||
_subState = kSubBranch6;
|
||||
break;
|
||||
case kSubBranch6:
|
||||
branchStart = kBranch7LeftStart;
|
||||
branchEnd = kBranch7LeftEnd;
|
||||
flag = kChaseExitedBranchZone;
|
||||
_subState = kSubBranch7Left;
|
||||
break;
|
||||
case kSubBranch7Left:
|
||||
case kSubBranch7Right:
|
||||
branchStart = kExitStart;
|
||||
branchEnd = kExitEnd;
|
||||
flag = kChaseFinished;
|
||||
_subState = kSubExit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_subMovie.setSegment(branchStart, branchEnd);
|
||||
_subMovie.setTime(branchStart);
|
||||
|
||||
_subCallBack.setCallBackFlag(flag);
|
||||
_subCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
}
|
||||
|
||||
void SubChase::branchRight() {
|
||||
TimeValue branchStart, branchEnd;
|
||||
NotificationFlags flag;
|
||||
|
||||
branchStart = 0;
|
||||
branchEnd = 0;
|
||||
flag = 0;
|
||||
switch (_subState) {
|
||||
case kSubDialog:
|
||||
case kSubBranch1:
|
||||
branchStart = kBranch2RightStart;
|
||||
branchEnd = kBranch2RightEnd;
|
||||
// Don't show the controls hint when we approach the whale
|
||||
// since the branch segments here are identical
|
||||
flag = kChaseExitedBranchZone;
|
||||
_subState = kSubBranch2Right;
|
||||
break;
|
||||
case kSubBranch2Left:
|
||||
case kSubBranch2Right:
|
||||
branchStart = kBranch3Start;
|
||||
branchEnd = kBranch3End - kDecisionTime;
|
||||
flag = kChaseEnteredBranchZone;
|
||||
_subState = kSubBranch3;
|
||||
break;
|
||||
case kSubBranch3:
|
||||
branchStart = kDeath4Start;
|
||||
branchEnd = kDeath4End;
|
||||
flag = kChaseFinished;
|
||||
_subState = kSubBranch4;
|
||||
break;
|
||||
case kSubBranch4:
|
||||
branchStart = kBranch5Start;
|
||||
branchEnd = kBranch5End - kDecisionTime;
|
||||
flag = kChaseEnteredBranchZone;
|
||||
_subState = kSubBranch5;
|
||||
break;
|
||||
case kSubBranch5:
|
||||
branchStart = kDeath6Start;
|
||||
branchEnd = kDeath6End;
|
||||
flag = kChaseFinished;
|
||||
_subState = kSubBranch6;
|
||||
break;
|
||||
case kSubBranch6:
|
||||
if (g_vm->getRandomBit()) {
|
||||
branchStart = kBranch7RightStart;
|
||||
branchEnd = kBranch7RightEnd;
|
||||
flag = kChaseExitedBranchZone;
|
||||
} else {
|
||||
branchStart = kDeath7Start;
|
||||
branchEnd = kDeath7End;
|
||||
flag = kChaseFinished;
|
||||
}
|
||||
_subState = kSubBranch7Right;
|
||||
break;
|
||||
case kSubBranch7Left:
|
||||
case kSubBranch7Right:
|
||||
branchStart = kExitStart;
|
||||
branchEnd = kExitEnd;
|
||||
flag = kChaseFinished;
|
||||
_subState = kSubExit;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_subMovie.setSegment(branchStart, branchEnd);
|
||||
_subMovie.setTime(branchStart);
|
||||
|
||||
_subCallBack.setCallBackFlag(flag);
|
||||
_subCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
}
|
||||
|
||||
void SubChase::dontBranch() {
|
||||
if (g_vm->getRandomBit())
|
||||
branchLeft();
|
||||
else
|
||||
branchRight();
|
||||
}
|
||||
|
||||
void SubChase::startHintTimer(TimeValue time, TimeScale scale, HintTimerCode code) {
|
||||
if (_canSteerSub) {
|
||||
_hintFuse.primeFuse(time, scale);
|
||||
_hintEvent.subChase = this;
|
||||
_hintEvent.theEvent = code;
|
||||
_hintFuse.setFunctor(new Common::Functor0Mem<void, HintTimerEvent>(&_hintEvent, &HintTimerEvent::fire));
|
||||
_hintFuse.lightFuse();
|
||||
}
|
||||
}
|
||||
|
||||
void SubChase::hintTimerExpired(HintTimerEvent &event) {
|
||||
switch (event.theEvent) {
|
||||
case kStartedHint:
|
||||
_hintPict.show();
|
||||
startBlinkTimer(10, 10, kEnteredBlinkState);
|
||||
startHintTimer(3920, kSubChaseScale, kEndedHint);
|
||||
break;
|
||||
case kEndedHint:
|
||||
_hintPict.hide();
|
||||
_blinkPict.hide();
|
||||
_blinkFuse.stopFuse();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SubChase::startBlinkTimer(TimeValue time, TimeScale scale, BlinkTimerCode code) {
|
||||
_blinkFuse.primeFuse(time, scale);
|
||||
_blinkEvent.subChase = this;
|
||||
_blinkEvent.theEvent = code;
|
||||
_blinkFuse.setFunctor(new Common::Functor0Mem<void, BlinkTimerEvent>(&_blinkEvent, &BlinkTimerEvent::fire));
|
||||
_blinkFuse.lightFuse();
|
||||
}
|
||||
|
||||
void SubChase::blinkTimerExpired(BlinkTimerEvent &event) {
|
||||
switch (event.theEvent) {
|
||||
case kEnteredBlinkState:
|
||||
_hintPict.hide();
|
||||
_blinkPict.show();
|
||||
startBlinkTimer(5, 10, kExitedBlinkState);
|
||||
break;
|
||||
case kExitedBlinkState:
|
||||
_blinkPict.hide();
|
||||
_hintPict.show();
|
||||
startBlinkTimer(10, 10, kEnteredBlinkState);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
110
engines/pegasus/neighborhood/norad/alpha/subchase.h
Normal file
110
engines/pegasus/neighborhood/norad/alpha/subchase.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/* 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-2013 Presto Studios, Inc.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_SUBCHASE_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_ALPHA_SUBCHASE_H
|
||||
|
||||
#include "pegasus/chase.h"
|
||||
#include "pegasus/movie.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class NoradAlpha;
|
||||
class SubChase;
|
||||
|
||||
enum HintTimerCode {
|
||||
kStartedHint,
|
||||
kEndedHint
|
||||
};
|
||||
|
||||
struct HintTimerEvent {
|
||||
SubChase *subChase;
|
||||
HintTimerCode theEvent;
|
||||
|
||||
void fire();
|
||||
};
|
||||
|
||||
enum BlinkTimerCode {
|
||||
kEnteredBlinkState,
|
||||
kExitedBlinkState
|
||||
};
|
||||
|
||||
struct BlinkTimerEvent {
|
||||
SubChase *subChase;
|
||||
BlinkTimerCode theEvent;
|
||||
|
||||
void fire();
|
||||
};
|
||||
|
||||
class SubChase : public ChaseInteraction {
|
||||
friend class NoradAlpha;
|
||||
friend struct HintTimerEvent;
|
||||
friend struct BlinkTimerEvent;
|
||||
public:
|
||||
|
||||
SubChase(Neighborhood *);
|
||||
virtual ~SubChase() {}
|
||||
|
||||
void setSoundFXLevel(const uint16);
|
||||
|
||||
void handleInput(const Input &, const Hotspot *);
|
||||
|
||||
protected:
|
||||
|
||||
void openInteraction();
|
||||
void initInteraction();
|
||||
void closeInteraction();
|
||||
|
||||
void receiveNotification(Notification *, const NotificationFlags);
|
||||
|
||||
void startBranching();
|
||||
void setUpBranch();
|
||||
void branchLeft();
|
||||
void branchRight();
|
||||
void dontBranch();
|
||||
|
||||
void startHintTimer(TimeValue, TimeScale, HintTimerCode);
|
||||
void hintTimerExpired(HintTimerEvent &);
|
||||
|
||||
void startBlinkTimer(TimeValue, TimeScale, BlinkTimerCode);
|
||||
void blinkTimerExpired(BlinkTimerEvent &);
|
||||
|
||||
Movie _subMovie;
|
||||
NotificationCallBack _subCallBack;
|
||||
Picture _hintPict;
|
||||
Picture _blinkPict;
|
||||
FuseFunction _hintFuse;
|
||||
FuseFunction _blinkFuse;
|
||||
|
||||
HintTimerEvent _hintEvent;
|
||||
BlinkTimerEvent _blinkEvent;
|
||||
|
||||
short _subState;
|
||||
|
||||
bool _canSteerSub;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
762
engines/pegasus/neighborhood/norad/constants.h
Normal file
762
engines/pegasus/neighborhood/norad/constants.h
Normal file
@@ -0,0 +1,762 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_CONSTANTS_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_CONSTANTS_H
|
||||
|
||||
#include "pegasus/constants.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// Norad Alpha spot constants
|
||||
|
||||
static const TimeValue kAlphaBumpIntoWallIn = 0;
|
||||
static const TimeValue kAlphaBumpIntoWallOut = 303;
|
||||
|
||||
static const TimeValue kAlphaAccessDeniedIn = 303;
|
||||
static const TimeValue kAlphaAccessDeniedOut = 3045;
|
||||
|
||||
static const TimeValue kAlphaRegDoorCloseIn = 3045;
|
||||
static const TimeValue kAlphaRegDoorCloseOut = 4476;
|
||||
|
||||
static const TimeValue kAlphaElevatorDoorCloseIn = 4476;
|
||||
static const TimeValue kAlphaElevatorDoorCloseOut = 5071;
|
||||
|
||||
static const TimeValue kAlphaCantTransportIn = 5071;
|
||||
static const TimeValue kAlphaCantTransportOut = 9348;
|
||||
|
||||
static const TimeValue kAlphaPressureDoorIntro1In = 9348;
|
||||
static const TimeValue kAlphaPressureDoorIntro1Out = 11061;
|
||||
|
||||
static const TimeValue kAlphaPressureDoorIntro2In = 11061;
|
||||
static const TimeValue kAlphaPressureDoorIntro2Out = 14098;
|
||||
|
||||
static const TimeValue kN22ReplyIn = 14098;
|
||||
static const TimeValue kN22ReplyOut = 18442;
|
||||
|
||||
static const TimeValue kAlphaLoadClawIntroIn = 18442;
|
||||
static const TimeValue kAlphaLoadClawIntroOut = 20698;
|
||||
|
||||
// Norad Delta spot constants
|
||||
|
||||
static const TimeValue kDeltaBumpIntoWallIn = 0;
|
||||
static const TimeValue kDeltaBumpIntoWallOut = 303;
|
||||
|
||||
static const TimeValue kDeltaAccessDeniedIn = 303;
|
||||
static const TimeValue kDeltaAccessDeniedOut = 3045;
|
||||
|
||||
static const TimeValue kDeltaRegDoorCloseIn = 3045;
|
||||
static const TimeValue kDeltaRegDoorCloseOut = 4476;
|
||||
|
||||
static const TimeValue kDeltaElevatorDoorCloseIn = 4476;
|
||||
static const TimeValue kDeltaElevatorDoorCloseOut = 5071;
|
||||
|
||||
static const TimeValue kPressureDoorIntro1In = 5071;
|
||||
static const TimeValue kPressureDoorIntro1Out = 6784;
|
||||
|
||||
static const TimeValue kPressureDoorIntro2In = 6784;
|
||||
static const TimeValue kPressureDoorIntro2Out = 9821;
|
||||
|
||||
static const TimeValue kLoadClawIntroIn = 9821;
|
||||
static const TimeValue kLoadClawIntroOut = 12077;
|
||||
|
||||
static const TimeValue kHoldForRetinalIn = 12077;
|
||||
static const TimeValue kHoldForRetinalOut = 14104;
|
||||
|
||||
static const TimeValue kRetinalScanFailedIn = 14104;
|
||||
static const TimeValue kRetinalScanFailedOut = 17538;
|
||||
|
||||
static const TimeValue kAddisAbabaIn = 17538;
|
||||
static const TimeValue kAddisAbabaOut = 19263;
|
||||
|
||||
static const TimeValue kBangkokIn = 19263;
|
||||
static const TimeValue kBangkokOut = 20201;
|
||||
|
||||
static const TimeValue kBonnIn = 20201;
|
||||
static const TimeValue kBonnOut = 20915;
|
||||
|
||||
static const TimeValue kDublinIn = 20915;
|
||||
static const TimeValue kDublinOut = 21660;
|
||||
|
||||
static const TimeValue kHonoluluIn = 21660;
|
||||
static const TimeValue kHonoluluOut = 22498;
|
||||
|
||||
static const TimeValue kMadridIn = 22498;
|
||||
static const TimeValue kMadridOut = 23474;
|
||||
|
||||
static const TimeValue kReykjavikIn = 23474;
|
||||
static const TimeValue kReykjavikOut = 24488;
|
||||
|
||||
static const TimeValue kSanAntonioIn = 24488;
|
||||
static const TimeValue kSanAntonioOut = 25561;
|
||||
|
||||
static const TimeValue kSeoulIn = 25561;
|
||||
static const TimeValue kSeoulOut = 26461;
|
||||
|
||||
static const TimeValue kSvortalskIn = 26461;
|
||||
static const TimeValue kSvortalskOut = 27582;
|
||||
|
||||
static const TimeValue kSiloBeepIn = 27582;
|
||||
static const TimeValue kSiloBeepOut = 27721;
|
||||
|
||||
static const TimeValue kAllSilosDeactivatedIn = 27721;
|
||||
static const TimeValue kAllSilosDeactivatedOut = 28928;
|
||||
|
||||
static const TimeValue kGlobalLaunchOverrideIn = 28928;
|
||||
static const TimeValue kGlobalLaunchOverrideOut = 30736;
|
||||
|
||||
static const TimeValue kLaunchSiloSelectedIn = 30736;
|
||||
static const TimeValue kLaunchSiloSelectedOut = 31660;
|
||||
|
||||
static const TimeValue kLaunchToProceedIn = 31660;
|
||||
static const TimeValue kLaunchToProceedOut = 32536;
|
||||
|
||||
static const TimeValue kMaximumDeactivationIn = 32536;
|
||||
static const TimeValue kMaximumDeactivationOut = 34337;
|
||||
|
||||
static const TimeValue kMissileLaunchedIn = 34337;
|
||||
static const TimeValue kMissileLaunchedOut = 35082;
|
||||
|
||||
static const TimeValue kNewLaunchSiloIn = 35082;
|
||||
static const TimeValue kNewLaunchSiloOut = 36320;
|
||||
|
||||
static const TimeValue kStrikeAuthorizedIn = 36320;
|
||||
static const TimeValue kStrikeAuthorizedOut = 37393;
|
||||
|
||||
static const TimeValue kPrimaryTargetIn = 37393;
|
||||
static const TimeValue kPrimaryTargetOut = 38628;
|
||||
|
||||
static const TimeValue kSiloDeactivatedIn = 38628;
|
||||
static const TimeValue kSiloDeactivatedOut = 39566;
|
||||
|
||||
static const TimeValue kStrikeCodeRejectedIn = 39566;
|
||||
static const TimeValue kStrikeCodeRejectedOut = 41056;
|
||||
|
||||
static const TimeValue kToDeactivateIn = 41056;
|
||||
static const TimeValue kToDeactivateOut = 46494;
|
||||
|
||||
static const TimeValue kTwoMinutesIn = 46494;
|
||||
static const TimeValue kTwoMinutesOut = 47166;
|
||||
|
||||
static const TimeValue kOneMinuteIn = 47166;
|
||||
static const TimeValue kOneMinuteOut = 47856;
|
||||
|
||||
static const TimeValue kFiftySecondsIn = 47856;
|
||||
static const TimeValue kFiftySecondsOut = 48691;
|
||||
|
||||
static const TimeValue kFortySecondsIn = 48691;
|
||||
static const TimeValue kFortySecondsOut = 49500;
|
||||
|
||||
static const TimeValue kThirtySecondsIn = 49500;
|
||||
static const TimeValue kThirtySecondsOut = 50362;
|
||||
|
||||
static const TimeValue kTwentySecondsIn = 50362;
|
||||
static const TimeValue kTwentySecondsOut = 51245;
|
||||
|
||||
static const TimeValue kTenSecondsIn = 51245;
|
||||
static const TimeValue kTenSecondsOut = 52069;
|
||||
|
||||
static const TimeValue kGiveUpHumanIn = 52069;
|
||||
static const TimeValue kGiveUpHumanOut = 55023;
|
||||
|
||||
static const TimeValue kIJustBrokeIn = 55023;
|
||||
static const TimeValue kIJustBrokeOut = 59191;
|
||||
|
||||
static const TimeValue kTheOnlyGoodHumanIn = 59191;
|
||||
static const TimeValue kTheOnlyGoodHumanOut = 62379;
|
||||
|
||||
static const TimeValue kYouAreRunningIn = 62379;
|
||||
static const TimeValue kYouAreRunningOut = 64201;
|
||||
|
||||
static const TimeValue kYouCannotPossiblyIn = 64201;
|
||||
static const TimeValue kYouCannotPossiblyOut = 65740;
|
||||
|
||||
static const TimeValue kYouWillFailIn = 65740;
|
||||
static const TimeValue kYouWillFailOut = 67217;
|
||||
|
||||
static const CanOpenDoorReason kCantOpenBadPressure = kCantOpenLastReason + 1;
|
||||
|
||||
static const NotificationFlags kAirTimerExpiredFlag = kLastNeighborhoodNotificationFlag << 1;
|
||||
|
||||
static const uint16 kNoradWarningVolume = 0x100 / 3;
|
||||
static const uint16 kNoradSuckWindVolume = 0x100 / 2;
|
||||
|
||||
static const int16 kElevatorCompassAngle = -40;
|
||||
static const int16 kSubPlatformCompassAngle = 45;
|
||||
static const int16 kSubControlCompassAngle = -10;
|
||||
|
||||
// Norad interactions.
|
||||
|
||||
static const InteractionID kNoradGlobeGameInteractionID = 0;
|
||||
static const InteractionID kNoradECRMonitorInteractionID = 1;
|
||||
static const InteractionID kNoradFillingStationInteractionID = 2;
|
||||
static const InteractionID kNoradElevatorInteractionID = 3;
|
||||
static const InteractionID kNoradPressureDoorInteractionID = 4;
|
||||
static const InteractionID kNoradSubControlRoomInteractionID = 5;
|
||||
static const InteractionID kNoradSubPlatformInteractionID = 6;
|
||||
static const InteractionID kNoradSubChaseInteractionID = 7;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Norad Alpha
|
||||
|
||||
static const CoordType kECRSlideShowLeft = kNavAreaLeft + 78;
|
||||
static const CoordType kECRSlideShowTop = kNavAreaTop + 1;
|
||||
|
||||
static const CoordType kECRPanLeft = kNavAreaLeft + 78 + 5;
|
||||
static const CoordType kECRPanTop = kNavAreaTop + 1 + 4;
|
||||
static const CoordType kECRPanRight = kECRPanLeft + 213;
|
||||
static const CoordType kECRPanBottom = kECRPanTop + 241;
|
||||
|
||||
static const CoordType kNoradAlphaElevatorControlsLeft = kNavAreaLeft + 332;
|
||||
static const CoordType kNoradAlphaElevatorControlsTop = kNavAreaTop + 127;
|
||||
|
||||
static const CoordType kNoradAlpha01LeftSideLeft = kNavAreaLeft + 0;
|
||||
static const CoordType kNoradAlpha01LeftSideTop = kNavAreaTop + 0;
|
||||
|
||||
static const CoordType kNoradAlpha01RightSideLeft = kNavAreaLeft + 240;
|
||||
static const CoordType kNoradAlpha01RightSideTop = kNavAreaTop + 12;
|
||||
|
||||
static const CoordType kNoradUpperLevelsLeft = kNavAreaLeft + 98;
|
||||
static const CoordType kNoradUpperLevelsTop = kNavAreaTop + 31;
|
||||
|
||||
static const CoordType kNoradUpperTypeLeft = kNoradUpperLevelsLeft + 114;
|
||||
static const CoordType kNoradUpperTypeTop = kNoradUpperLevelsTop + 8;
|
||||
|
||||
static const CoordType kNoradUpperUpLeft = kNavAreaLeft + 361;
|
||||
static const CoordType kNoradUpperUpTop = kNavAreaTop + 32;
|
||||
|
||||
static const CoordType kNoradUpperDownLeft = kNavAreaLeft + 367;
|
||||
static const CoordType kNoradUpperDownTop = kNavAreaTop + 66;
|
||||
|
||||
static const CoordType kNoradLowerLevelsLeft = kNavAreaLeft + 74;
|
||||
static const CoordType kNoradLowerLevelsTop = kNavAreaTop + 157;
|
||||
|
||||
static const CoordType kNoradLowerTypeLeft = kNoradLowerLevelsLeft + 144;
|
||||
static const CoordType kNoradLowerTypeTop = kNoradLowerLevelsTop + 9;
|
||||
|
||||
static const CoordType kNoradLowerUpLeft = kNavAreaLeft + 380;
|
||||
static const CoordType kNoradLowerUpTop = kNavAreaTop + 164;
|
||||
|
||||
static const CoordType kNoradLowerDownLeft = kNavAreaLeft + 388;
|
||||
static const CoordType kNoradLowerDownTop = kNavAreaTop + 212;
|
||||
|
||||
static const CoordType kNoradPlatformLeft = kNavAreaLeft + 36;
|
||||
static const CoordType kNoradPlatformTop = kNavAreaTop + 87;
|
||||
|
||||
static const CoordType kNoradSubSteerLeft = 288;
|
||||
static const CoordType kNoradSubSteerTop = 28;
|
||||
|
||||
static const CoordType kNoradSubHintLeft = 480;
|
||||
static const CoordType kNoradSubHintTop = 240;
|
||||
|
||||
static const CoordType kNoradSubControlLeft = kNavAreaLeft + 0;
|
||||
static const CoordType kNoradSubControlTop = kNavAreaTop + 84;
|
||||
|
||||
static const CoordType kNoradSubControlPinchLeft = kNoradSubControlLeft + 106;
|
||||
static const CoordType kNoradSubControlPinchTop = kNoradSubControlTop + 86;
|
||||
|
||||
static const CoordType kNoradSubControlDownLeft = kNoradSubControlLeft + 66;
|
||||
static const CoordType kNoradSubControlDownTop = kNoradSubControlTop + 106;
|
||||
|
||||
static const CoordType kNoradSubControlRightLeft = kNoradSubControlLeft + 83;
|
||||
static const CoordType kNoradSubControlRightTop = kNoradSubControlTop + 90;
|
||||
|
||||
static const CoordType kNoradSubControlLeftLeft = kNoradSubControlLeft + 56;
|
||||
static const CoordType kNoradSubControlLeftTop = kNoradSubControlTop + 91;
|
||||
|
||||
static const CoordType kNoradSubControlUpLeft = kNoradSubControlLeft + 66;
|
||||
static const CoordType kNoradSubControlUpTop = kNoradSubControlTop + 81;
|
||||
|
||||
static const CoordType kNoradSubControlCCWLeft = kNoradSubControlLeft + 29;
|
||||
static const CoordType kNoradSubControlCCWTop = kNoradSubControlTop + 88;
|
||||
|
||||
static const CoordType kNoradSubControlCWLeft = kNoradSubControlLeft + 0;
|
||||
static const CoordType kNoradSubControlCWTop = kNoradSubControlTop + 89;
|
||||
|
||||
static const CoordType kNoradClawMonitorLeft = kNavAreaLeft + 288;
|
||||
static const CoordType kNoradClawMonitorTop = kNavAreaTop + 97;
|
||||
|
||||
static const CoordType kNoradGreenBallAtALeft = kNoradClawMonitorLeft + 179;
|
||||
static const CoordType kNoradGreenBallAtATop = kNoradClawMonitorTop + 82;
|
||||
|
||||
static const CoordType kNoradGreenBallAtBLeft = kNoradClawMonitorLeft + 130;
|
||||
static const CoordType kNoradGreenBallAtBTop = kNoradClawMonitorTop + 73;
|
||||
|
||||
static const CoordType kNoradGreenBallAtCLeft = kNoradClawMonitorLeft + 110;
|
||||
static const CoordType kNoradGreenBallAtCTop = kNoradClawMonitorTop + 26;
|
||||
|
||||
static const CoordType kNoradGreenBallAtDLeft = kNoradClawMonitorLeft + 21;
|
||||
static const CoordType kNoradGreenBallAtDTop = kNoradClawMonitorTop + 49;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Norad Delta
|
||||
|
||||
static const CoordType kGlobeMonitorLeft = kNavAreaLeft + 360;
|
||||
static const CoordType kGlobeMonitorTop = kNavAreaTop + 144;
|
||||
|
||||
static const CoordType kGlobeLeft = kNavAreaLeft + 172;
|
||||
static const CoordType kGlobeTop = kNavAreaTop;
|
||||
|
||||
static const CoordType kGlobeCircleLeftLeft = kNavAreaLeft + 186;
|
||||
static const CoordType kGlobeCircleLeftTop = kNavAreaTop + 41;
|
||||
|
||||
static const CoordType kGlobeCircleRightLeft = kNavAreaLeft + 321;
|
||||
static const CoordType kGlobeCircleRightTop = kNavAreaTop + 41;
|
||||
|
||||
static const CoordType kGlobeCircleUpLeft = kNavAreaLeft + 220;
|
||||
static const CoordType kGlobeCircleUpTop = kNavAreaTop + 7;
|
||||
|
||||
static const CoordType kGlobeCircleDownLeft = kNavAreaLeft + 220;
|
||||
static const CoordType kGlobeCircleDownTop = kNavAreaTop + 142;
|
||||
|
||||
static const CoordType kGlobeUpperLeftHiliteLeft = kNavAreaLeft + 207;
|
||||
static const CoordType kGlobeUpperLeftHiliteTop = kNavAreaTop + 28;
|
||||
|
||||
static const CoordType kGlobeUpperRightHiliteLeft = kNavAreaLeft + 307;
|
||||
static const CoordType kGlobeUpperRightHiliteTop = kNavAreaTop + 28;
|
||||
|
||||
static const CoordType kGlobeLowerLeftHiliteLeft = kNavAreaLeft + 207;
|
||||
static const CoordType kGlobeLowerLeftHiliteTop = kNavAreaTop + 128;
|
||||
|
||||
static const CoordType kGlobeLowerRightHiliteLeft = kNavAreaLeft + 307;
|
||||
static const CoordType kGlobeLowerRightHiliteTop = kNavAreaTop + 128;
|
||||
|
||||
static const CoordType kGlobeLeftMotionHiliteLeft = kNavAreaLeft + 182;
|
||||
static const CoordType kGlobeLeftMotionHiliteTop = kNavAreaTop + 60;
|
||||
|
||||
static const CoordType kGlobeRightMotionHiliteLeft = kNavAreaLeft + 331;
|
||||
static const CoordType kGlobeRightMotionHiliteTop = kNavAreaTop + 60;
|
||||
|
||||
static const CoordType kGlobeUpMotionHiliteLeft = kNavAreaLeft + 239;
|
||||
static const CoordType kGlobeUpMotionHiliteTop = kNavAreaTop + 3;
|
||||
|
||||
static const CoordType kGlobeDownMotionHiliteLeft = kNavAreaLeft + 239;
|
||||
static const CoordType kGlobeDownMotionHiliteTop = kNavAreaTop + 152;
|
||||
|
||||
static const CoordType kGlobeUpperNamesLeft = kNavAreaLeft + 368;
|
||||
static const CoordType kGlobeUpperNamesTop = kNavAreaTop + 188;
|
||||
|
||||
static const CoordType kGlobeLowerNamesLeft = kNavAreaLeft + 368;
|
||||
static const CoordType kGlobeLowerNamesTop = kNavAreaTop + 212;
|
||||
|
||||
static const CoordType kGlobeCountdownLeft = kNavAreaLeft + 478;
|
||||
static const CoordType kGlobeCountdownTop = kNavAreaTop + 164;
|
||||
|
||||
// Norad Alpha display IDs.
|
||||
|
||||
static const DisplayElementID kECRSlideShowMovieID = kNeighborhoodDisplayID;
|
||||
static const DisplayElementID kECRPanID = kECRSlideShowMovieID + 1;
|
||||
static const DisplayElementID kNoradAlphaDeathMovieID = kECRPanID + 1;
|
||||
static const DisplayElementID kNoradElevatorControlsID = kNoradAlphaDeathMovieID + 1;
|
||||
static const DisplayElementID kN01LeftSideID = kNoradElevatorControlsID + 1;
|
||||
static const DisplayElementID kN01RightSideID = kN01LeftSideID + 1;
|
||||
static const DisplayElementID kPressureDoorLevelsID = kN01RightSideID + 1;
|
||||
static const DisplayElementID kPressureDoorTypeID = kPressureDoorLevelsID + 1;
|
||||
static const DisplayElementID kPressureDoorUpButtonID = kPressureDoorTypeID + 1;
|
||||
static const DisplayElementID kPressureDoorDownButtonID = kPressureDoorUpButtonID + 1;
|
||||
static const DisplayElementID kPlatformMonitorID = kPressureDoorDownButtonID + 1;
|
||||
static const DisplayElementID kSubControlMonitorID = kPlatformMonitorID + 1;
|
||||
static const DisplayElementID kClawMonitorID = kSubControlMonitorID + 1;
|
||||
static const DisplayElementID kSubControlPinchID = kClawMonitorID + 1;
|
||||
static const DisplayElementID kSubControlDownID = kSubControlPinchID + 1;
|
||||
static const DisplayElementID kSubControlRightID = kSubControlDownID + 1;
|
||||
static const DisplayElementID kSubControlLeftID = kSubControlRightID + 1;
|
||||
static const DisplayElementID kSubControlUpID = kSubControlLeftID + 1;
|
||||
static const DisplayElementID kSubControlCCWID = kSubControlUpID + 1;
|
||||
static const DisplayElementID kSubControlCWID = kSubControlCCWID + 1;
|
||||
static const DisplayElementID kClawMonitorGreenBallID = kSubControlCWID + 1;
|
||||
|
||||
// Norad Delta display IDs.
|
||||
|
||||
static const DisplayElementID kGlobeRobotID = kNeighborhoodDisplayID;
|
||||
static const DisplayElementID kGlobeMonitorID = kGlobeRobotID + 1;
|
||||
static const DisplayElementID kGlobeMovieID = kGlobeMonitorID + 1;
|
||||
static const DisplayElementID kGlobeCircleLeftID = kGlobeMovieID + 1;
|
||||
static const DisplayElementID kGlobeCircleRightID = kGlobeCircleLeftID + 1;
|
||||
static const DisplayElementID kGlobeCircleUpID = kGlobeCircleRightID + 1;
|
||||
static const DisplayElementID kGlobeCircleDownID = kGlobeCircleUpID + 1;
|
||||
static const DisplayElementID kMotionHiliteLeftID = kGlobeCircleDownID + 1;
|
||||
static const DisplayElementID kMotionHiliteRightID = kMotionHiliteLeftID + 1;
|
||||
static const DisplayElementID kMotionHiliteUpID = kMotionHiliteRightID + 1;
|
||||
static const DisplayElementID kMotionHiliteDownID = kMotionHiliteUpID + 1;
|
||||
static const DisplayElementID kTargetHiliteUpperLeftID = kMotionHiliteDownID + 1;
|
||||
static const DisplayElementID kTargetHiliteUpperRightID = kTargetHiliteUpperLeftID + 1;
|
||||
static const DisplayElementID kTargetHiliteLowerLeftID = kTargetHiliteUpperRightID + 1;
|
||||
static const DisplayElementID kTargetHiliteLowerRightID = kTargetHiliteLowerLeftID + 1;
|
||||
static const DisplayElementID kGlobeUpperNamesID = kTargetHiliteLowerRightID + 1;
|
||||
static const DisplayElementID kGlobeLowerNamesID = kGlobeUpperNamesID + 1;
|
||||
static const DisplayElementID kGlobeCountdownID = kGlobeLowerNamesID + 1;
|
||||
|
||||
// Norad Alpha:
|
||||
|
||||
static const DisplayOrder kECRMonitorOrder = kMonitorLayer;
|
||||
static const DisplayOrder kECRPanOrder = kECRMonitorOrder + 1;
|
||||
|
||||
static const DisplayOrder kN01LeftSideOrder = kMonitorLayer;
|
||||
static const DisplayOrder kN01RightSideOrder = kN01LeftSideOrder + 1;
|
||||
|
||||
static const DisplayOrder kElevatorControlsOrder = kMonitorLayer;
|
||||
|
||||
static const DisplayOrder kPressureLevelsOrder = kMonitorLayer;
|
||||
static const DisplayOrder kPressureTypeOrder = kPressureLevelsOrder + 1;
|
||||
static const DisplayOrder kPressureUpOrder = kPressureTypeOrder + 1;
|
||||
static const DisplayOrder kPressureDownOrder = kPressureUpOrder + 1;
|
||||
|
||||
static const DisplayOrder kPlatformOrder = kMonitorLayer;
|
||||
|
||||
static const DisplayOrder kSubControlOrder = kMonitorLayer;
|
||||
static const DisplayOrder kClawMonitorOrder = kSubControlOrder + 1;
|
||||
static const DisplayOrder kSubControlPinchOrder = kClawMonitorOrder + 1;
|
||||
static const DisplayOrder kSubControlDownOrder = kSubControlPinchOrder + 1;
|
||||
static const DisplayOrder kSubControlRightOrder = kSubControlDownOrder + 1;
|
||||
static const DisplayOrder kSubControlLeftOrder = kSubControlRightOrder + 1;
|
||||
static const DisplayOrder kSubControlUpOrder = kSubControlLeftOrder + 1;
|
||||
static const DisplayOrder kSubControlCCWOrder = kSubControlUpOrder + 1;
|
||||
static const DisplayOrder kSubControlCWOrder = kSubControlCCWOrder + 1;
|
||||
static const DisplayOrder kClawMonitorGreenBallOrder = kSubControlCWOrder + 1;
|
||||
|
||||
// Norad Delta:
|
||||
|
||||
static const DisplayOrder kGlobeMonitorLayer = kMonitorLayer;
|
||||
static const DisplayOrder kGlobeMovieLayer = kGlobeMonitorLayer + 1;
|
||||
static const DisplayOrder kGlobeCircleLayer = kGlobeMovieLayer + 1;
|
||||
static const DisplayOrder kGlobeHilitesLayer = kGlobeCircleLayer + 1;
|
||||
static const DisplayOrder kGlobeUpperNamesLayer = kGlobeHilitesLayer + 1;
|
||||
static const DisplayOrder kGlobeLowerNamesLayer = kGlobeUpperNamesLayer + 1;
|
||||
static const DisplayOrder kGlobeCountdownLayer = kGlobeLowerNamesLayer + 1;
|
||||
|
||||
// Norad Alpha Tables
|
||||
|
||||
static const TimeScale kNoradAlphaMovieScale = 600;
|
||||
static const TimeScale kNoradAlphaFramesPerSecond = 15;
|
||||
static const TimeScale kNoradAlphaFrameDuration = 40;
|
||||
|
||||
// Alternate IDs.
|
||||
|
||||
static const AlternateID kAltNoradAlphaNormal = 0;
|
||||
|
||||
// Room IDs.
|
||||
|
||||
static const RoomID kNorad01 = 0;
|
||||
static const RoomID kNorad01East = 1;
|
||||
static const RoomID kNorad01West = 2;
|
||||
static const RoomID kNorad02 = 3;
|
||||
static const RoomID kNorad03 = 4;
|
||||
static const RoomID kNorad04 = 5;
|
||||
static const RoomID kNorad05 = 6;
|
||||
static const RoomID kNorad06 = 7;
|
||||
static const RoomID kNorad07 = 8;
|
||||
static const RoomID kNorad07North = 9;
|
||||
static const RoomID kNorad08 = 10;
|
||||
static const RoomID kNorad09 = 11;
|
||||
static const RoomID kNorad10 = 12;
|
||||
static const RoomID kNorad10East = 13;
|
||||
static const RoomID kNorad11 = 14;
|
||||
static const RoomID kNorad11South = 15;
|
||||
static const RoomID kNorad12 = 16;
|
||||
static const RoomID kNorad12South = 17;
|
||||
static const RoomID kNorad13 = 18;
|
||||
static const RoomID kNorad14 = 19;
|
||||
static const RoomID kNorad15 = 20;
|
||||
static const RoomID kNorad16 = 21;
|
||||
static const RoomID kNorad17 = 22;
|
||||
static const RoomID kNorad18 = 23;
|
||||
static const RoomID kNorad19 = 24;
|
||||
static const RoomID kNorad19West = 25;
|
||||
static const RoomID kNorad21 = 26;
|
||||
static const RoomID kNorad21West = 27;
|
||||
static const RoomID kNorad22 = 28;
|
||||
static const RoomID kNorad22West = 29;
|
||||
|
||||
// Hot Spot Activation IDs.
|
||||
|
||||
|
||||
// Hot Spot IDs.
|
||||
|
||||
static const HotSpotID kNorad01ECRSpotID = 5000;
|
||||
static const HotSpotID kNorad01GasSpotID = 5001;
|
||||
static const HotSpotID kNorad01ECROutSpotID = 5002;
|
||||
static const HotSpotID kNorad01GasOutSpotID = 5003;
|
||||
static const HotSpotID kNorad01MonitorSpotID = 5004;
|
||||
static const HotSpotID kNorad01IntakeSpotID = 5005;
|
||||
static const HotSpotID kNorad01DispenseSpotID = 5006;
|
||||
static const HotSpotID kNorad01ArSpotID = 5007;
|
||||
static const HotSpotID kNorad01CO2SpotID = 5008;
|
||||
static const HotSpotID kNorad01HeSpotID = 5009;
|
||||
static const HotSpotID kNorad01OSpotID = 5010;
|
||||
static const HotSpotID kNorad01NSpotID = 5011;
|
||||
static const HotSpotID kN01GasCanisterSpotID = 5012;
|
||||
static const HotSpotID kN01ArgonCanisterSpotID = 5013;
|
||||
static const HotSpotID kN01AirMaskSpotID = 5014;
|
||||
static const HotSpotID kN01NitrogenCanisterSpotID = 5015;
|
||||
static const HotSpotID kN01GasOutletSpotID = 5016;
|
||||
static const HotSpotID kNorad07DoorSpotID = 5017;
|
||||
static const HotSpotID kNorad07DoorOutSpotID = 5018;
|
||||
static const HotSpotID kNorad10DoorSpotID = 5019;
|
||||
static const HotSpotID kNorad10EastOutSpotID = 5020;
|
||||
static const HotSpotID kAlphaUpperPressureDoorUpSpotID = 5021;
|
||||
static const HotSpotID kAlphaUpperPressureDoorDownSpotID = 5022;
|
||||
static const HotSpotID kNorad11ElevatorSpotID = 5023;
|
||||
static const HotSpotID kNorad11ElevatorOutSpotID = 5024;
|
||||
static const HotSpotID kNorad11ElevatorDownSpotID = 5025;
|
||||
static const HotSpotID kNorad12ElevatorSpotID = 5026;
|
||||
static const HotSpotID kNorad12ElevatorOutSpotID = 5027;
|
||||
static const HotSpotID kNorad12ElevatorUpSpotID = 5028;
|
||||
static const HotSpotID kNorad19MonitorSpotID = 5029;
|
||||
static const HotSpotID kNorad19MonitorOutSpotID = 5030;
|
||||
static const HotSpotID kNorad19ActivateMonitorSpotID = 5031;
|
||||
static const HotSpotID kNorad21WestSpotID = 5032;
|
||||
static const HotSpotID kNorad21WestOutSpotID = 5033;
|
||||
static const HotSpotID kAlphaLowerPressureDoorUpSpotID = 5034;
|
||||
static const HotSpotID kAlphaLowerPressureDoorDownSpotID = 5035;
|
||||
static const HotSpotID kNorad22MonitorSpotID = 5036;
|
||||
static const HotSpotID kNorad22MonitorOutSpotID = 5037;
|
||||
static const HotSpotID kNorad22LaunchPrepSpotID = 5038;
|
||||
static const HotSpotID kNorad22ClawControlSpotID = 5039;
|
||||
static const HotSpotID kNorad22ClawPinchSpotID = 5040;
|
||||
static const HotSpotID kNorad22ClawDownSpotID = 5041;
|
||||
static const HotSpotID kNorad22ClawRightSpotID = 5042;
|
||||
static const HotSpotID kNorad22ClawLeftSpotID = 5043;
|
||||
static const HotSpotID kNorad22ClawUpSpotID = 5044;
|
||||
static const HotSpotID kNorad22ClawCCWSpotID = 5045;
|
||||
static const HotSpotID kNorad22ClawCWSpotID = 5046;
|
||||
|
||||
// Extra sequence IDs.
|
||||
|
||||
static const ExtraID kNoradArriveFromTSA = 0;
|
||||
static const ExtraID kNorad01RobotTaunt = 1;
|
||||
static const ExtraID kNorad01ZoomInWithGasCanister = 2;
|
||||
static const ExtraID kN01WGasCanister = 3;
|
||||
static const ExtraID kNorad01ZoomOutWithGasCanister = 4;
|
||||
static const ExtraID kN01WZEmptyLit = 5;
|
||||
static const ExtraID kN01WZGasCanisterDim = 6;
|
||||
static const ExtraID kN01WZGasCanisterLit = 7;
|
||||
static const ExtraID kN01WZArgonCanisterDim = 8;
|
||||
static const ExtraID kN01WZArgonCanisterLit = 9;
|
||||
static const ExtraID kN01WZAirMaskDim = 10;
|
||||
static const ExtraID kN01WZAirMaskLit = 11;
|
||||
static const ExtraID kN01WZNitrogenCanisterDim = 12;
|
||||
static const ExtraID kN01WZNitrogenCanisterLit = 13;
|
||||
static const ExtraID kNorad04EastDeath = 14;
|
||||
static const ExtraID kNorad19PrepSub = 15;
|
||||
static const ExtraID kNorad19ExitToSub = 16;
|
||||
static const ExtraID kNorad22SouthIntro = 17;
|
||||
static const ExtraID kNorad22SouthReply = 18;
|
||||
static const ExtraID kNorad22SouthFinish = 19;
|
||||
static const ExtraID kN22ClawFromAToB = 20;
|
||||
static const ExtraID kN22ClawALoop = 21;
|
||||
static const ExtraID kN22ClawAPinch = 22;
|
||||
static const ExtraID kN22ClawACounterclockwise = 23;
|
||||
static const ExtraID kN22ClawAClockwise = 24;
|
||||
static const ExtraID kN22ClawFromBToA = 25;
|
||||
static const ExtraID kN22ClawFromBToC = 26;
|
||||
static const ExtraID kN22ClawFromBToD = 27;
|
||||
static const ExtraID kN22ClawBLoop = 28;
|
||||
static const ExtraID kN22ClawBPinch = 29;
|
||||
static const ExtraID kN22ClawBCounterclockwise = 30;
|
||||
static const ExtraID kN22ClawBClockwise = 31;
|
||||
static const ExtraID kN22ClawFromCToB = 32;
|
||||
static const ExtraID kN22ClawCLoop = 33;
|
||||
static const ExtraID kN22ClawCPinch = 34;
|
||||
static const ExtraID kN22ClawCCounterclockwise = 35;
|
||||
static const ExtraID kN22ClawCClockwise = 36;
|
||||
static const ExtraID kN22ClawFromDToB = 37;
|
||||
static const ExtraID kN22ClawDLoop = 38;
|
||||
static const ExtraID kN22ClawDPinch = 39;
|
||||
static const ExtraID kN22ClawDCounterclockwise = 40;
|
||||
static const ExtraID kN22ClawDClockwise = 41;
|
||||
|
||||
|
||||
// Norad Delta Extra sequence IDs.
|
||||
|
||||
static const ExtraID kArriveFromSubChase = 0;
|
||||
static const ExtraID kN59ZoomWithRobot = 1;
|
||||
static const ExtraID kN59RobotApproaches = 2;
|
||||
static const ExtraID kN59RobotPunchLoop = 3;
|
||||
static const ExtraID kN59PlayerWins1 = 4;
|
||||
static const ExtraID kN59PlayerWins2 = 5;
|
||||
static const ExtraID kN59RobotWins = 6;
|
||||
static const ExtraID kN59RobotHeadOpens = 7;
|
||||
static const ExtraID kN59Biochips111 = 8;
|
||||
static const ExtraID kN59Biochips011 = 9;
|
||||
static const ExtraID kN59Biochips101 = 10;
|
||||
static const ExtraID kN59Biochips001 = 11;
|
||||
static const ExtraID kN59Biochips110 = 12;
|
||||
static const ExtraID kN59Biochips010 = 13;
|
||||
static const ExtraID kN59Biochips100 = 14;
|
||||
static const ExtraID kN59Biochips000 = 15;
|
||||
static const ExtraID kN59RobotDisappears = 16;
|
||||
static const ExtraID kN60ClawFromAToB = 17;
|
||||
static const ExtraID kN60ClawALoop = 18;
|
||||
static const ExtraID kN60ClawAPinch = 19;
|
||||
static const ExtraID kN60ClawACounterclockwise = 20;
|
||||
static const ExtraID kN60ClawAClockwise = 21;
|
||||
static const ExtraID kN60ClawFromBToA = 22;
|
||||
static const ExtraID kN60ClawFromBToC = 23;
|
||||
static const ExtraID kN60ClawFromBToD = 24;
|
||||
static const ExtraID kN60ClawBLoop = 25;
|
||||
static const ExtraID kN60ClawBPinch = 26;
|
||||
static const ExtraID kN60ClawBCounterclockwise = 27;
|
||||
static const ExtraID kN60ClawBClockwise = 28;
|
||||
static const ExtraID kN60ClawFromCToB = 29;
|
||||
static const ExtraID kN60ClawCLoop = 30;
|
||||
static const ExtraID kN60ClawCPinch = 31;
|
||||
static const ExtraID kN60ClawCCounterclockwise = 32;
|
||||
static const ExtraID kN60ClawCClockwise = 33;
|
||||
static const ExtraID kN60ClawFromDToB = 34;
|
||||
static const ExtraID kN60ClawDLoop = 35;
|
||||
static const ExtraID kN60ClawDPinch = 36;
|
||||
static const ExtraID kN60ClawDCounterclockwise = 37;
|
||||
static const ExtraID kN60ClawDClockwise = 38;
|
||||
static const ExtraID kN60RobotApproaches = 39;
|
||||
static const ExtraID kN60FirstMistake = 40;
|
||||
static const ExtraID kN60ArmActivated = 41;
|
||||
static const ExtraID kN60SecondMistake = 42;
|
||||
static const ExtraID kN60ArmToPositionB = 43;
|
||||
static const ExtraID kN60ThirdMistake = 44;
|
||||
static const ExtraID kN60ArmGrabsRobot = 45;
|
||||
static const ExtraID kN60FourthMistake = 46;
|
||||
static const ExtraID kN60ArmCarriesRobotToPositionA = 47;
|
||||
static const ExtraID kN60PlayerFollowsRobotToDoor = 48;
|
||||
static const ExtraID kN60RobotHeadOpens = 49;
|
||||
static const ExtraID kN60Biochips111 = 50;
|
||||
static const ExtraID kN60Biochips011 = 51;
|
||||
static const ExtraID kN60Biochips101 = 52;
|
||||
static const ExtraID kN60Biochips001 = 53;
|
||||
static const ExtraID kN60Biochips110 = 54;
|
||||
static const ExtraID kN60Biochips010 = 55;
|
||||
static const ExtraID kN60Biochips100 = 56;
|
||||
static const ExtraID kN60Biochips000 = 57;
|
||||
static const ExtraID kN60RobotDisappears = 58;
|
||||
static const ExtraID kNoradDeltaRetinalScanBad = 59;
|
||||
static const ExtraID kNoradDeltaRetinalScanGood = 60;
|
||||
static const ExtraID kN79BrightView = 61;
|
||||
|
||||
// Norad Delta Tables
|
||||
|
||||
static const TimeScale kNoradDeltaMovieScale = 600;
|
||||
static const TimeScale kNoradDeltaFramesPerSecond = 15;
|
||||
static const TimeScale kNoradDeltaFrameDuration = 40;
|
||||
|
||||
// Alternate IDs.
|
||||
|
||||
static const AlternateID kAltNoradDeltaNormal = 0;
|
||||
|
||||
// Room IDs.
|
||||
|
||||
static const RoomID kNorad41 = 0;
|
||||
static const RoomID kNorad42 = 1;
|
||||
static const RoomID kNorad43 = 2;
|
||||
static const RoomID kNorad44 = 3;
|
||||
static const RoomID kNorad45 = 4;
|
||||
static const RoomID kNorad46 = 5;
|
||||
static const RoomID kNorad47 = 6;
|
||||
static const RoomID kNorad48 = 7;
|
||||
static const RoomID kNorad48South = 8;
|
||||
static const RoomID kNorad49 = 9;
|
||||
static const RoomID kNorad49South = 10;
|
||||
static const RoomID kNorad50 = 11;
|
||||
static const RoomID kNorad50East = 12;
|
||||
static const RoomID kNorad51 = 13;
|
||||
static const RoomID kNorad52 = 14;
|
||||
static const RoomID kNorad53 = 15;
|
||||
static const RoomID kNorad54 = 16;
|
||||
static const RoomID kNorad54North = 17;
|
||||
static const RoomID kNorad55 = 18;
|
||||
static const RoomID kNorad56 = 19;
|
||||
static const RoomID kNorad57 = 20;
|
||||
static const RoomID kNorad58 = 21;
|
||||
static const RoomID kNorad59 = 22;
|
||||
static const RoomID kNorad59West = 23;
|
||||
static const RoomID kNorad60 = 24;
|
||||
static const RoomID kNorad60West = 25;
|
||||
static const RoomID kNorad61 = 26;
|
||||
static const RoomID kNorad62 = 27;
|
||||
static const RoomID kNorad63 = 28;
|
||||
static const RoomID kNorad64 = 29;
|
||||
static const RoomID kNorad65 = 30;
|
||||
static const RoomID kNorad66 = 31;
|
||||
static const RoomID kNorad67 = 32;
|
||||
static const RoomID kNorad68 = 33;
|
||||
static const RoomID kNorad68West = 34;
|
||||
static const RoomID kNorad69 = 35;
|
||||
static const RoomID kNorad78 = 36;
|
||||
static const RoomID kNorad79 = 37;
|
||||
static const RoomID kNorad79West = 38;
|
||||
|
||||
// Hot Spot Activation IDs.
|
||||
|
||||
|
||||
// Hot Spot IDs.
|
||||
|
||||
static const HotSpotID kNorad48ElevatorSpotID = 5000;
|
||||
static const HotSpotID kNorad48ElevatorOutSpotID = 5001;
|
||||
static const HotSpotID kNorad48ElevatorUpSpotID = 5002;
|
||||
static const HotSpotID kNorad49ElevatorSpotID = 5003;
|
||||
static const HotSpotID kNorad49ElevatorOutSpotID = 5004;
|
||||
static const HotSpotID kNorad49ElevatorDownSpotID = 5005;
|
||||
static const HotSpotID kNorad50DoorSpotID = 5006;
|
||||
static const HotSpotID kNorad50DoorOutSpotID = 5007;
|
||||
static const HotSpotID kDeltaUpperPressureDoorUpSpotID = 5008;
|
||||
static const HotSpotID kDeltaUpperPressureDoorDownSpotID = 5009;
|
||||
static const HotSpotID kNorad54DoorSpotID = 5010;
|
||||
static const HotSpotID kNorad54DoorOutSpotID = 5011;
|
||||
static const HotSpotID kNorad59WestSpotID = 5012;
|
||||
static const HotSpotID kNorad59WestOutSpotID = 5013;
|
||||
static const HotSpotID kDeltaLowerPressureDoorUpSpotID = 5014;
|
||||
static const HotSpotID kDeltaLowerPressureDoorDownSpotID = 5015;
|
||||
static const HotSpotID kDelta59RobotHeadSpotID = 5016;
|
||||
static const HotSpotID kDelta59RobotShieldBiochipSpotID = 5017;
|
||||
static const HotSpotID kDelta59RobotOpMemBiochipSpotID = 5018;
|
||||
static const HotSpotID kDelta59RobotRetinalBiochipSpotID = 5019;
|
||||
static const HotSpotID kNorad60MonitorSpotID = 5020;
|
||||
static const HotSpotID kNorad60MonitorOutSpotID = 5021;
|
||||
static const HotSpotID kNorad60LaunchPrepSpotID = 5022;
|
||||
static const HotSpotID kNorad60ClawControlSpotID = 5023;
|
||||
static const HotSpotID kNorad60ClawPinchSpotID = 5024;
|
||||
static const HotSpotID kNorad60ClawDownSpotID = 5025;
|
||||
static const HotSpotID kNorad60ClawRightSpotID = 5026;
|
||||
static const HotSpotID kNorad60ClawLeftSpotID = 5027;
|
||||
static const HotSpotID kNorad60ClawUpSpotID = 5028;
|
||||
static const HotSpotID kNorad60ClawCCWSpotID = 5029;
|
||||
static const HotSpotID kNorad60ClawCWSpotID = 5030;
|
||||
static const HotSpotID kDelta60RobotHeadSpotID = 5031;
|
||||
static const HotSpotID kDelta60RobotShieldBiochipSpotID = 5032;
|
||||
static const HotSpotID kDelta60RobotOpMemBiochipSpotID = 5033;
|
||||
static const HotSpotID kDelta60RobotRetinalBiochipSpotID = 5034;
|
||||
static const HotSpotID kNorad68WestSpotID = 5035;
|
||||
static const HotSpotID kNorad68WestOutSpotID = 5036;
|
||||
static const HotSpotID kNorad79WestSpotID = 5037;
|
||||
static const HotSpotID kNorad79WestOutSpotID = 5038;
|
||||
static const HotSpotID kNorad79SpinLeftSpotID = 5039;
|
||||
static const HotSpotID kNorad79SpinRightSpotID = 5040;
|
||||
static const HotSpotID kNorad79SpinUpSpotID = 5041;
|
||||
static const HotSpotID kNorad79SpinDownSpotID = 5042;
|
||||
static const HotSpotID kNorad79SiloAreaSpotID = 5043;
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
1270
engines/pegasus/neighborhood/norad/delta/globegame.cpp
Normal file
1270
engines/pegasus/neighborhood/norad/delta/globegame.cpp
Normal file
File diff suppressed because it is too large
Load Diff
172
engines/pegasus/neighborhood/norad/delta/globegame.h
Normal file
172
engines/pegasus/neighborhood/norad/delta/globegame.h
Normal file
@@ -0,0 +1,172 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_DELTA_GLOBEGAME_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_DELTA_GLOBEGAME_H
|
||||
|
||||
#include "pegasus/interaction.h"
|
||||
#include "pegasus/movie.h"
|
||||
#include "pegasus/notification.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
enum GlobeTrackDirection {
|
||||
kTrackLeft,
|
||||
kTrackRight,
|
||||
kTrackUp,
|
||||
kTrackDown
|
||||
};
|
||||
|
||||
// This class assumes that the globe movie is built at 15 frames per second with a
|
||||
// time scale of 600, yielding 40 time unit per frame.
|
||||
|
||||
class GlobeTracker : public Tracker {
|
||||
public:
|
||||
GlobeTracker(Movie *, Picture *, Picture *, Picture *, Picture *);
|
||||
~GlobeTracker() override {}
|
||||
|
||||
void setTrackParameters(const Hotspot *, GlobeTrackDirection);
|
||||
void continueTracking(const Input &) override;
|
||||
void startTracking(const Input &) override;
|
||||
void stopTracking(const Input &) override;
|
||||
void activateHotspots() override;
|
||||
bool stopTrackingInput(const Input &) override;
|
||||
|
||||
protected:
|
||||
void trackGlobeMovie();
|
||||
void stopGlobeMovie();
|
||||
|
||||
Movie *_globeMovie;
|
||||
Picture *_leftHighlight;
|
||||
Picture *_rightHighlight;
|
||||
Picture *_upHighlight;
|
||||
Picture *_downHighlight;
|
||||
const Hotspot *_trackSpot;
|
||||
int _trackTime;
|
||||
GlobeTrackDirection _trackDirection;
|
||||
};
|
||||
|
||||
class GlobeCountdown : public IdlerAnimation {
|
||||
public:
|
||||
GlobeCountdown(const DisplayElementID);
|
||||
~GlobeCountdown() override {}
|
||||
|
||||
void setCountdownTime(const int);
|
||||
void startCountdown();
|
||||
void stopCountdown();
|
||||
|
||||
void setDisplayOrder(const DisplayOrder);
|
||||
void show() override;
|
||||
void hide() override;
|
||||
void moveElementTo(const CoordType, const CoordType) override;
|
||||
|
||||
void draw(const Common::Rect &) override;
|
||||
|
||||
protected:
|
||||
Surface _digits;
|
||||
int16 _digitOffset;
|
||||
};
|
||||
|
||||
static const int16 kNumAllSilos = 40;
|
||||
static const int16 kNumTargetSilos = 10;
|
||||
static const int16 kNumLongSlices = 72;
|
||||
|
||||
class GlobeGame : public GameInteraction, public NotificationReceiver {
|
||||
public:
|
||||
GlobeGame(Neighborhood *);
|
||||
~GlobeGame() override {}
|
||||
|
||||
void setSoundFXLevel(const uint16) override;
|
||||
|
||||
void handleInput(const Input &, const Hotspot *) override;
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
void activateHotspots() override;
|
||||
|
||||
bool canSolve() override;
|
||||
void doSolve() override;
|
||||
|
||||
struct Point3D {
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
struct Line3D {
|
||||
Point3D pt1, pt2;
|
||||
};
|
||||
|
||||
protected:
|
||||
// Latitude (-90 - 90) and longitude (-180 - 180)
|
||||
static const int16 _siloCoords[kNumAllSilos][2];
|
||||
|
||||
static const int16 _targetSilo[kNumTargetSilos];
|
||||
static const int16 _timeLimit[kNumTargetSilos];
|
||||
static const TimeValue _siloName[kNumTargetSilos][2];
|
||||
|
||||
void openInteraction() override;
|
||||
void initInteraction() override;
|
||||
void closeInteraction() override;
|
||||
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
|
||||
void spinGlobe(const Input &, const Hotspot *, GlobeTrackDirection);
|
||||
void clickGlobe(const Input &);
|
||||
|
||||
int16 findClickedSilo(const Input &);
|
||||
|
||||
void globeMovieFrameToOrigin(int16, int16 &, int16 &);
|
||||
void globePointToLatLong(const Point3D &, int16, int16, int16 &, int16 &);
|
||||
void screenPointTo3DPoint(int16, int16, Point3D &);
|
||||
bool lineHitsGlobe(const Line3D &, Point3D &);
|
||||
|
||||
Movie _robotMovie;
|
||||
Movie _monitorMovie;
|
||||
Movie _globeMovie;
|
||||
Movie _upperNamesMovie;
|
||||
Movie _lowerNamesMovie;
|
||||
Notification _globeNotification;
|
||||
NotificationCallBack _robotCallBack;
|
||||
NotificationCallBack _monitorCallBack;
|
||||
GlobeTracker _globeTracker;
|
||||
Picture _globeCircleLeft;
|
||||
Picture _globeCircleRight;
|
||||
Picture _globeCircleUp;
|
||||
Picture _globeCircleDown;
|
||||
Picture _motionHighlightLeft;
|
||||
Picture _motionHighlightRight;
|
||||
Picture _motionHighlightUp;
|
||||
Picture _motionHighlightDown;
|
||||
Picture _targetHighlightUpperLeft;
|
||||
Picture _targetHighlightUpperRight;
|
||||
Picture _targetHighlightLowerLeft;
|
||||
Picture _targetHighlightLowerRight;
|
||||
GlobeCountdown _countdown;
|
||||
NotificationCallBack _countdownCallBack;
|
||||
int16 _gameState;
|
||||
int16 _currentSiloIndex;
|
||||
Notification *_neighborhoodNotification;
|
||||
bool _playedInstructions;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
984
engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
Normal file
984
engines/pegasus/neighborhood/norad/delta/noraddelta.cpp
Normal file
@@ -0,0 +1,984 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/energymonitor.h"
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/interface.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/biochips/arthurchip.h"
|
||||
#include "pegasus/items/biochips/opticalchip.h"
|
||||
#include "pegasus/items/biochips/retscanchip.h"
|
||||
#include "pegasus/items/inventory/airmask.h"
|
||||
#include "pegasus/neighborhood/norad/constants.h"
|
||||
#include "pegasus/neighborhood/norad/subcontrolroom.h"
|
||||
#include "pegasus/neighborhood/norad/delta/globegame.h"
|
||||
#include "pegasus/neighborhood/norad/delta/noraddelta.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
const uint32 NoradDelta::_noradDeltaClawExtras[22] = {
|
||||
kN60ClawFromAToB,
|
||||
kN60ClawALoop,
|
||||
kN60ClawAPinch,
|
||||
kN60ClawACounterclockwise,
|
||||
kN60ClawAClockwise,
|
||||
kN60ClawFromBToA,
|
||||
kN60ClawFromBToC,
|
||||
kN60ClawFromBToD,
|
||||
kN60ClawBLoop,
|
||||
kN60ClawBPinch,
|
||||
kN60ClawBCounterclockwise,
|
||||
kN60ClawBClockwise,
|
||||
kN60ClawFromCToB,
|
||||
kN60ClawCLoop,
|
||||
kN60ClawCPinch,
|
||||
kN60ClawCCounterclockwise,
|
||||
kN60ClawCClockwise,
|
||||
kN60ClawFromDToB,
|
||||
kN60ClawDLoop,
|
||||
kN60ClawDPinch,
|
||||
kN60ClawDCounterclockwise,
|
||||
kN60ClawDClockwise
|
||||
};
|
||||
|
||||
NoradDelta::NoradDelta(InputHandler *nextHandler, PegasusEngine *owner) : Norad(nextHandler, owner, "Norad Delta", kNoradDeltaID) {
|
||||
_elevatorUpRoomID = kNorad49South;
|
||||
_elevatorDownRoomID = kNorad48South;
|
||||
_elevatorUpSpotID = kNorad48ElevatorUpSpotID;
|
||||
_elevatorDownSpotID = kNorad49ElevatorDownSpotID;
|
||||
|
||||
// Pressure door stuff.
|
||||
|
||||
_subRoomEntryRoom1 = kNorad50;
|
||||
_subRoomEntryDir1 = kEast;
|
||||
_subRoomEntryRoom2 = kNorad59;
|
||||
_subRoomEntryDir2 = kWest;
|
||||
_upperPressureDoorRoom = kNorad50East;
|
||||
_lowerPressureDoorRoom = kNorad59West;
|
||||
|
||||
_upperPressureDoorUpSpotID = kDeltaUpperPressureDoorUpSpotID;
|
||||
_upperPressureDoorDownSpotID = kDeltaUpperPressureDoorDownSpotID;
|
||||
_upperPressureDoorAbortSpotID = kNorad50DoorOutSpotID;
|
||||
|
||||
_lowerPressureDoorUpSpotID = kDeltaLowerPressureDoorUpSpotID;
|
||||
_lowerPressureDoorDownSpotID = kDeltaLowerPressureDoorDownSpotID;
|
||||
_lowerPressureDoorAbortSpotID = kNorad59WestOutSpotID;
|
||||
|
||||
_pressureSoundIn = kPressureDoorIntro1In;
|
||||
_pressureSoundOut = kPressureDoorIntro1Out;
|
||||
_equalizeSoundIn = kPressureDoorIntro2In;
|
||||
_equalizeSoundOut = kPressureDoorIntro2Out;
|
||||
_accessDeniedIn = kDeltaAccessDeniedIn;
|
||||
_accessDeniedOut = kDeltaAccessDeniedOut;
|
||||
|
||||
GameState.setNoradSubPrepState(kSubDamaged);
|
||||
|
||||
_subControlRoom = kNorad60West;
|
||||
}
|
||||
|
||||
void NoradDelta::init() {
|
||||
Norad::init();
|
||||
|
||||
// Little fix for the retinal scan zoom in spot...
|
||||
Hotspot *hotspot = _vm->getAllHotspots().findHotspotByID(kNorad68WestSpotID);
|
||||
hotspot->setMaskedHotspotFlags(kZoomInSpotFlag, kZoomInSpotFlag | kZoomOutSpotFlag);
|
||||
|
||||
hotspot = _vm->getAllHotspots().findHotspotByID(kNorad79WestSpotID);
|
||||
hotspot->setMaskedHotspotFlags(kZoomInSpotFlag, kZoomInSpotFlag | kZoomOutSpotFlag);
|
||||
|
||||
hotspot = _vm->getAllHotspots().findHotspotByID(kDelta59RobotShieldBiochipSpotID);
|
||||
hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag);
|
||||
HotspotInfoTable::Entry *hotspotEntry = findHotspotEntry(kDelta59RobotShieldBiochipSpotID);
|
||||
hotspotEntry->hotspotItem = kShieldBiochip;
|
||||
|
||||
hotspot = _vm->getAllHotspots().findHotspotByID(kDelta59RobotOpMemBiochipSpotID);
|
||||
hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag);
|
||||
hotspotEntry = findHotspotEntry(kDelta59RobotOpMemBiochipSpotID);
|
||||
hotspotEntry->hotspotItem = kOpticalBiochip;
|
||||
|
||||
hotspot = _vm->getAllHotspots().findHotspotByID(kDelta59RobotRetinalBiochipSpotID);
|
||||
hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag);
|
||||
hotspotEntry = findHotspotEntry(kDelta59RobotRetinalBiochipSpotID);
|
||||
hotspotEntry->hotspotItem = kRetinalScanBiochip;
|
||||
|
||||
hotspot = _vm->getAllHotspots().findHotspotByID(kDelta60RobotShieldBiochipSpotID);
|
||||
hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag);
|
||||
hotspotEntry = findHotspotEntry(kDelta60RobotShieldBiochipSpotID);
|
||||
hotspotEntry->hotspotItem = kShieldBiochip;
|
||||
|
||||
hotspot = _vm->getAllHotspots().findHotspotByID(kDelta60RobotOpMemBiochipSpotID);
|
||||
hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag);
|
||||
hotspotEntry = findHotspotEntry(kDelta60RobotOpMemBiochipSpotID);
|
||||
hotspotEntry->hotspotItem = kOpticalBiochip;
|
||||
|
||||
hotspot = _vm->getAllHotspots().findHotspotByID(kDelta60RobotRetinalBiochipSpotID);
|
||||
hotspot->setMaskedHotspotFlags(kPickUpBiochipSpotFlag, kPickUpBiochipSpotFlag);
|
||||
hotspotEntry = findHotspotEntry(kDelta60RobotRetinalBiochipSpotID);
|
||||
hotspotEntry->hotspotItem = kRetinalScanBiochip;
|
||||
}
|
||||
|
||||
void NoradDelta::start() {
|
||||
if (g_energyMonitor) {
|
||||
g_energyMonitor->stopEnergyDraining();
|
||||
g_energyMonitor->restoreLastEnergyValue();
|
||||
_vm->resetEnergyDeathReason();
|
||||
g_energyMonitor->startEnergyDraining();
|
||||
}
|
||||
|
||||
Norad::start();
|
||||
}
|
||||
|
||||
void NoradDelta::setUpAIRules() {
|
||||
Neighborhood::setUpAIRules();
|
||||
|
||||
if (g_AIArea) {
|
||||
AIPlayMessageAction *messageAction = new AIPlayMessageAction("Images/AI/Norad/XN07NE", false);
|
||||
AILocationCondition *locCondition = new AILocationCondition(1);
|
||||
locCondition->addLocation(MakeRoomView(kNorad68, kWest));
|
||||
AIRule *rule = new AIRule(locCondition, messageAction);
|
||||
g_AIArea->addAIRule(rule);
|
||||
}
|
||||
}
|
||||
|
||||
void NoradDelta::getExtraCompassMove(const ExtraTable::Entry &entry, FaderMoveSpec &compassMove) {
|
||||
switch (entry.extra) {
|
||||
case kArriveFromSubChase:
|
||||
compassMove.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, entry.movieStart, 20, entry.movieEnd, 90);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 25 * kNoradDeltaFrameDuration, 20);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 94 * kNoradDeltaFrameDuration, 45);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 101 * kNoradDeltaFrameDuration, 45);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 146 * kNoradDeltaFrameDuration, 90 + 15);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 189 * kNoradDeltaFrameDuration, 90 + 15);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 204 * kNoradDeltaFrameDuration, 90 + 30);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 214 * kNoradDeltaFrameDuration, 90 + 20);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 222 * kNoradDeltaFrameDuration, 90 + 20);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 228 * kNoradDeltaFrameDuration, 90 + 10);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 245 * kNoradDeltaFrameDuration, 90 + 85);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 262 * kNoradDeltaFrameDuration, 90 + 70);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 273 * kNoradDeltaFrameDuration, 90 + 80);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 287 * kNoradDeltaFrameDuration, 90);
|
||||
break;
|
||||
case kN60PlayerFollowsRobotToDoor:
|
||||
compassMove.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, entry.movieStart, 270 + kSubControlCompassAngle,
|
||||
entry.movieEnd, 270 - 15);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 280, 270 + kSubControlCompassAngle);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 920, 360);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 1840, 360);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 2520, 270);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 3760, 270);
|
||||
compassMove.insertFaderKnot(entry.movieStart + 4640, 270 + kSubControlCompassAngle);
|
||||
break;
|
||||
case kN59PlayerWins2:
|
||||
compassMove.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, entry.movieStart, 270, entry.movieEnd, 280);
|
||||
compassMove.insertFaderKnot(entry.movieEnd - 1000, 270);
|
||||
// fall through
|
||||
// FIXME: fall through intentional?
|
||||
default:
|
||||
Norad::getExtraCompassMove(entry, compassMove);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
GameInteraction *NoradDelta::makeInteraction(const InteractionID interactionID) {
|
||||
if (interactionID == kNoradGlobeGameInteractionID)
|
||||
return new GlobeGame(this);
|
||||
|
||||
return Norad::makeInteraction(interactionID);
|
||||
}
|
||||
|
||||
void NoradDelta::playClawMonitorIntro() {
|
||||
playSpotSoundSync(kLoadClawIntroIn, kLoadClawIntroOut);
|
||||
}
|
||||
|
||||
void NoradDelta::getExitEntry(const RoomID room, const DirectionConstant direction, ExitTable::Entry &entry) {
|
||||
Norad::getExitEntry(room, direction, entry);
|
||||
|
||||
if (room == kNorad61 && direction == kSouth)
|
||||
entry.movieStart += kNoradDeltaFrameDuration;
|
||||
}
|
||||
|
||||
void NoradDelta::getZoomEntry(const HotSpotID id, ZoomTable::Entry &zoomEntry) {
|
||||
Norad::getZoomEntry(id, zoomEntry);
|
||||
|
||||
if (id == kNorad59WestSpotID && GameState.getNoradPlayedGlobeGame()) {
|
||||
ExtraTable::Entry extraEntry;
|
||||
getExtraEntry(kN59ZoomWithRobot, extraEntry);
|
||||
zoomEntry.movieStart = extraEntry.movieStart;
|
||||
zoomEntry.movieEnd = extraEntry.movieEnd;
|
||||
}
|
||||
}
|
||||
|
||||
void NoradDelta::loadAmbientLoops() {
|
||||
/*
|
||||
Logic:
|
||||
|
||||
loop sound 1:
|
||||
if room == kNorad79West
|
||||
if player globe game
|
||||
play kNoradGlobeLoop2SoundNum
|
||||
else
|
||||
play kNoradRedAlertLoopSoundNum
|
||||
else if room >= kNorad78 && room <= kNorad79
|
||||
play kNoradGlobeLoop2SoundNum
|
||||
else if gassed,
|
||||
if room >= kNorad41 && room <= kNorad49South
|
||||
play kNoradNewSubLoopSoundNum, kNoradWarningVolume
|
||||
else if room >= kNorad59 && room <= kNorad60West
|
||||
play kNoradSubControlLoopSoundNum, kNoradWarningVolume
|
||||
else
|
||||
play kNoradWarningLoopSoundNum, kNoradWarningVolume
|
||||
else
|
||||
play nothing
|
||||
loop sound 2:
|
||||
if gassed and not wearing air mask
|
||||
if room == kNorad54North
|
||||
play breathing unmanned loop
|
||||
else
|
||||
play breathing
|
||||
else
|
||||
if room == kNorad54North
|
||||
play unmanned loop
|
||||
else
|
||||
play nothing
|
||||
*/
|
||||
|
||||
if (GameState.getNoradArrivedFromSub()) {
|
||||
RoomID room = GameState.getCurrentRoom();
|
||||
|
||||
if (room >= kNorad78 && room <= kNorad79West) {
|
||||
if (GameState.getNoradPlayedGlobeGame()) {
|
||||
// blitter moved clone2727's globe room loop fix up here
|
||||
// since the original didn't play the red alert sound during the
|
||||
// globe game.
|
||||
|
||||
// clone2727 added this fix so we can play the correct sound
|
||||
// with the DVD version. This originally loaded it into slot 2,
|
||||
// which in addition to having the corrupted sound on the disk,
|
||||
// caused it to never play.
|
||||
if (_vm->isDVD())
|
||||
loadLoopSound1("Sounds/Norad/GlobAmb2.32K.AIFF");
|
||||
else
|
||||
loadLoopSound1("Sounds/Norad/GlobAmb2.22K.AIFF");
|
||||
} else
|
||||
loadLoopSound1("Sounds/Norad/RedAlert.22K.AIFF");
|
||||
} else if (GameState.getNoradGassed()) {
|
||||
if (room >= kNorad41 && room <= kNorad49South) {
|
||||
if (_vm->isDVD())
|
||||
loadLoopSound1("Sounds/Norad/NEW SUB AMB.44K.AIFF", kNoradWarningVolume * 3);
|
||||
else
|
||||
loadLoopSound1("Sounds/Norad/NEW SUB AMB.22K.AIFF", kNoradWarningVolume * 3);
|
||||
} else if (room >= kNorad59 && room <= kNorad60West) {
|
||||
if (_vm->isDVD())
|
||||
loadLoopSound1("Sounds/Norad/SUB CONTRL LOOP.32K.AIFF", kNoradWarningVolume * 3);
|
||||
else
|
||||
loadLoopSound1("Sounds/Norad/SUB CONTRL LOOP.22K.AIFF", kNoradWarningVolume * 3);
|
||||
} else {
|
||||
if (_vm->isDVD())
|
||||
loadLoopSound1("Sounds/Norad/WARNING LOOP.32K.AIFF", kNoradWarningVolume);
|
||||
else
|
||||
loadLoopSound1("Sounds/Norad/WARNING LOOP.22K.AIFF", kNoradWarningVolume);
|
||||
}
|
||||
} else {
|
||||
loadLoopSound1("");
|
||||
}
|
||||
|
||||
if (GameState.getNoradGassed() && !g_airMask->isAirFilterOn()) {
|
||||
if (room == kNorad54North)
|
||||
loadLoopSound2("Sounds/Norad/Breathing Typing.22K.AIFF", 0x100 / 2);
|
||||
else
|
||||
loadLoopSound2("Sounds/Norad/SUCKING WIND.22K.AIFF", kNoradSuckWindVolume, 0, 0);
|
||||
} else {
|
||||
if (room == kNorad54North) {
|
||||
if (_vm->isDVD())
|
||||
loadLoopSound2("Sounds/Norad/N54NAS.32K.AIFF", 0x100 / 2);
|
||||
else
|
||||
loadLoopSound2("Sounds/Norad/N54NAS.22K.AIFF", 0x100 / 2);
|
||||
} else
|
||||
loadLoopSound2("");
|
||||
}
|
||||
} else {
|
||||
// Start them off at zero...
|
||||
if (GameState.getNoradGassed()) {
|
||||
if (_vm->isDVD())
|
||||
loadLoopSound1("Sounds/Norad/NEW SUB AMB.44K.AIFF", 0, 0, 0);
|
||||
else
|
||||
loadLoopSound1("Sounds/Norad/NEW SUB AMB.22K.AIFF", 0, 0, 0);
|
||||
}
|
||||
if (!g_airMask->isAirFilterOn())
|
||||
loadLoopSound2("Sounds/Norad/SUCKING WIND.22K.AIFF", 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void NoradDelta::checkContinuePoint(const RoomID room, const DirectionConstant direction) {
|
||||
switch (MakeRoomView(room, direction)) {
|
||||
case MakeRoomView(kNorad41, kEast):
|
||||
case MakeRoomView(kNorad49, kEast):
|
||||
case MakeRoomView(kNorad49, kWest):
|
||||
case MakeRoomView(kNorad61, kSouth):
|
||||
case MakeRoomView(kNorad68, kEast):
|
||||
case MakeRoomView(kNorad79, kWest):
|
||||
makeContinuePoint();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NoradDelta::arriveAt(const RoomID room, const DirectionConstant direction) {
|
||||
if (room != kNorad68)
|
||||
GameState.setNoradRetScanGood(false);
|
||||
|
||||
Norad::arriveAt(room, direction);
|
||||
|
||||
FaderMoveSpec loop1Spec, loop2Spec;
|
||||
ExtraTable::Entry entry;
|
||||
|
||||
switch (room) {
|
||||
case kNorad41:
|
||||
if (direction == kEast) {
|
||||
if (!GameState.getNoradArrivedFromSub()) {
|
||||
GameState.setNoradPlayedGlobeGame(false);
|
||||
|
||||
GameState.setNoradBeatRobotWithClaw(false);
|
||||
GameState.setNoradBeatRobotWithDoor(false);
|
||||
GameState.setNoradRetScanGood(false);
|
||||
|
||||
GameState.setScoringExitedSub(true);
|
||||
|
||||
getExtraEntry(kArriveFromSubChase, entry);
|
||||
|
||||
loop1Spec.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, 0, 0, entry.movieEnd -
|
||||
entry.movieStart, kNoradWarningVolume);
|
||||
loop1Spec.insertFaderKnot(7320, 0);
|
||||
loop1Spec.insertFaderKnot(7880, kNoradWarningVolume);
|
||||
|
||||
loop2Spec.makeTwoKnotFaderSpec(kNoradDeltaMovieScale, 0, 0, entry.movieEnd -
|
||||
entry.movieStart, kNoradSuckWindVolume);
|
||||
loop1Spec.insertFaderKnot(7320, 0);
|
||||
loop1Spec.insertFaderKnot(7880, kNoradSuckWindVolume);
|
||||
|
||||
startExtraSequence(kArriveFromSubChase, kExtraCompletedFlag, kFilterNoInput);
|
||||
|
||||
startLoop1Fader(loop1Spec);
|
||||
startLoop2Fader(loop2Spec);
|
||||
} else {
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA08", kArthurNoradExitedSub);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kNorad54:
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA71", kArthurNoradApproachedDamagedDoor);
|
||||
break;
|
||||
case kNorad54North:
|
||||
GameState.setScoringSawRobotAt54North(true);
|
||||
break;
|
||||
case kNorad68:
|
||||
if (GameState.getNoradRetScanGood())
|
||||
openDoor();
|
||||
else if (!_vm->playerHasItemID(kRetinalScanBiochip) && g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA39", kArthurNoradAtRetScanNoBiochip);
|
||||
break;
|
||||
case kNorad68West:
|
||||
arriveAtNorad68West();
|
||||
break;
|
||||
case kNorad79West:
|
||||
arriveAtNorad79West();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NoradDelta::doorOpened() {
|
||||
Norad::doorOpened();
|
||||
GameState.setNoradRetScanGood(false);
|
||||
}
|
||||
|
||||
void NoradDelta::arriveAtNorad68West() {
|
||||
playSpotSoundSync(kHoldForRetinalIn, kHoldForRetinalOut);
|
||||
|
||||
BiochipItem *retScan = _vm->getCurrentBiochip();
|
||||
|
||||
if (retScan != nullptr && retScan->getObjectID() == kRetinalScanBiochip) {
|
||||
((RetScanChip *)retScan)->searchForLaser();
|
||||
succeedRetinalScan();
|
||||
} else {
|
||||
failRetinalScan();
|
||||
}
|
||||
}
|
||||
|
||||
void NoradDelta::arriveAtNorad79West() {
|
||||
if (!GameState.getNoradPlayedGlobeGame())
|
||||
newInteraction(kNoradGlobeGameInteractionID);
|
||||
}
|
||||
|
||||
void NoradDelta::turnTo(const DirectionConstant direction) {
|
||||
Norad::turnTo(direction);
|
||||
if (g_arthurChip) {
|
||||
switch (GameState.getCurrentRoomAndView()) {
|
||||
case MakeRoomView(kNorad54, kNorth):
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA71", kArthurNoradApproachedDamagedDoor);
|
||||
break;
|
||||
case MakeRoomView(kNorad68, kWest):
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA39", kArthurNoradApproachedDamagedDoor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NoradDelta::bumpIntoWall() {
|
||||
requestSpotSound(kDeltaBumpIntoWallIn, kDeltaBumpIntoWallOut, kFilterNoInput, 0);
|
||||
Neighborhood::bumpIntoWall();
|
||||
}
|
||||
|
||||
void NoradDelta::failRetinalScan() {
|
||||
startExtraSequence(kNoradDeltaRetinalScanBad, kExtraCompletedFlag, kFilterNoInput);
|
||||
}
|
||||
|
||||
void NoradDelta::succeedRetinalScan() {
|
||||
startExtraSequence(kNoradDeltaRetinalScanGood, kExtraCompletedFlag, kFilterNoInput);
|
||||
GameState.setNoradRetScanGood(true);
|
||||
GameState.setScoringUsedRetinalChip(true);
|
||||
}
|
||||
|
||||
void NoradDelta::getDoorEntry(const RoomID room, const DirectionConstant direction, DoorTable::Entry &entry) {
|
||||
Norad::getDoorEntry(room, direction, entry);
|
||||
|
||||
if (room == kNorad68 && direction == kWest && !GameState.getNoradRetScanGood())
|
||||
entry.flags = kDoorPresentMask | kDoorLockedMask;
|
||||
}
|
||||
|
||||
void NoradDelta::finishedGlobeGame() {
|
||||
GameState.setNoradPlayedGlobeGame(true);
|
||||
_privateFlags.setFlag(kNoradPrivateFinishedGlobeGameFlag, true);
|
||||
GameState.setScoringFinishedGlobeGame(true);
|
||||
loadAmbientLoops();
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA63", kArthurNoradThreatenedByRobot);
|
||||
if (_vm->isChattyAI())
|
||||
g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN60WD1", false, kWarningInterruption);
|
||||
updateViewFrame();
|
||||
}
|
||||
|
||||
bool NoradDelta::playingAgainstRobot() {
|
||||
return GameState.getNoradPlayedGlobeGame();
|
||||
}
|
||||
|
||||
void NoradDelta::getClawInfo(HotSpotID &outSpotID, HotSpotID &prepSpotID, HotSpotID &clawControlSpotID, HotSpotID &pinchClawSpotID,
|
||||
HotSpotID &moveClawDownSpotID, HotSpotID &moveClawRightSpotID, HotSpotID &moveClawLeftSpotID, HotSpotID &moveClawUpSpotID,
|
||||
HotSpotID &clawCCWSpotID, HotSpotID &clawCWSpotID, uint32 &clawPosition, const uint32 *&clawExtraIDs) {
|
||||
outSpotID = kNorad60MonitorOutSpotID;
|
||||
prepSpotID = kNorad60LaunchPrepSpotID;
|
||||
clawControlSpotID = kNorad60ClawControlSpotID;
|
||||
pinchClawSpotID = kNorad60ClawPinchSpotID;
|
||||
moveClawDownSpotID = kNorad60ClawDownSpotID;
|
||||
moveClawRightSpotID = kNorad60ClawRightSpotID;
|
||||
moveClawLeftSpotID = kNorad60ClawLeftSpotID;
|
||||
moveClawUpSpotID = kNorad60ClawUpSpotID;
|
||||
clawCCWSpotID = kNorad60ClawCCWSpotID;
|
||||
clawCWSpotID = kNorad60ClawCWSpotID;
|
||||
clawPosition = kClawAtC;
|
||||
clawExtraIDs = _noradDeltaClawExtras;
|
||||
}
|
||||
|
||||
void NoradDelta::playerBeatRobotWithDoor() {
|
||||
GameState.setNoradBeatRobotWithDoor(true);
|
||||
updateViewFrame();
|
||||
GameState.setScoringStoppedNoradRobot(true);
|
||||
if (_vm->isChattyAI())
|
||||
g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN59WD", false, kWarningInterruption);
|
||||
}
|
||||
|
||||
void NoradDelta::playerBeatRobotWithClaw() {
|
||||
GameState.setNoradBeatRobotWithClaw(true);
|
||||
updateViewFrame();
|
||||
GameState.setScoringStoppedNoradRobot(true);
|
||||
GameState.setScoringNoradGandhi(true);
|
||||
if (_vm->isChattyAI())
|
||||
g_AIArea->playAIMovie(kRightAreaSignature, "Images/AI/Norad/XN59WD", false, kWarningInterruption);
|
||||
}
|
||||
|
||||
TimeValue NoradDelta::getViewTime(const RoomID room, const DirectionConstant direction) {
|
||||
ExtraTable::Entry entry;
|
||||
|
||||
if (room == kNorad41 && direction == kSouth && !GameState.getNoradArrivedFromSub()) {
|
||||
getExtraEntry(kArriveFromSubChase, entry);
|
||||
return entry.movieStart;
|
||||
}
|
||||
|
||||
if (GameState.getNoradBeatRobotWithDoor()) {
|
||||
if (_privateFlags.getFlag(kNoradPrivateRobotHeadOpenFlag)) {
|
||||
uint32 extraID = kN59Biochips111;
|
||||
if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag))
|
||||
extraID += 1;
|
||||
if (_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag))
|
||||
extraID += 2;
|
||||
if (_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag))
|
||||
extraID += 4;
|
||||
getExtraEntry(extraID, entry);
|
||||
return entry.movieStart;
|
||||
}
|
||||
|
||||
getExtraEntry(kN59RobotHeadOpens, entry);
|
||||
return entry.movieStart;
|
||||
} else if (GameState.getNoradBeatRobotWithClaw()) {
|
||||
if (_privateFlags.getFlag(kNoradPrivateRobotHeadOpenFlag)) {
|
||||
uint32 extraID = kN60Biochips111;
|
||||
if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag))
|
||||
extraID += 1;
|
||||
if (_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag))
|
||||
extraID += 2;
|
||||
if (_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag))
|
||||
extraID += 4;
|
||||
getExtraEntry(extraID, entry);
|
||||
return entry.movieStart;
|
||||
}
|
||||
|
||||
getExtraEntry(kN60RobotHeadOpens, entry);
|
||||
return entry.movieStart;
|
||||
}
|
||||
|
||||
return Norad::getViewTime(room, direction);
|
||||
}
|
||||
|
||||
void NoradDelta::openDoor() {
|
||||
if (GameState.getCurrentRoom() == kNorad59 && GameState.getCurrentDirection() == kWest && GameState.getNoradPlayedGlobeGame()) {
|
||||
Input scratch;
|
||||
InputHandler::_inputHandler->clickInHotspot(scratch, _vm->getAllHotspots().findHotspotByID(kNorad59WestSpotID));
|
||||
} else {
|
||||
Norad::openDoor();
|
||||
}
|
||||
}
|
||||
|
||||
void NoradDelta::cantMoveThatWay(CanOpenDoorReason reason) {
|
||||
// WORKAROUND: The door outside the launch console room isn't treated as a door,
|
||||
// so play the correct sound.
|
||||
if (reason == kCantMoveBlocked && GameState.getCurrentRoomAndView() == MakeRoomView(kNorad67, kNorth)) {
|
||||
cantOpenDoor(kCantOpenLocked);
|
||||
return;
|
||||
}
|
||||
|
||||
Neighborhood::cantMoveThatWay(reason);
|
||||
}
|
||||
|
||||
void NoradDelta::activateHotspots() {
|
||||
Norad::activateHotspots();
|
||||
|
||||
if (GameState.getCurrentRoom() == kNorad59West && GameState.getCurrentDirection() == kWest && GameState.getNoradBeatRobotWithDoor()) {
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kNorad59WestOutSpotID);
|
||||
|
||||
if (_privateFlags.getFlag(kNoradPrivateRobotHeadOpenFlag)) {
|
||||
if (!_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag))
|
||||
_vm->getAllHotspots().activateOneHotspot(kDelta59RobotShieldBiochipSpotID);
|
||||
else
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kDelta59RobotShieldBiochipSpotID);
|
||||
|
||||
if (!_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag))
|
||||
_vm->getAllHotspots().activateOneHotspot(kDelta59RobotOpMemBiochipSpotID);
|
||||
else
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kDelta59RobotOpMemBiochipSpotID);
|
||||
|
||||
if (!_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag))
|
||||
_vm->getAllHotspots().activateOneHotspot(kDelta59RobotRetinalBiochipSpotID);
|
||||
else
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kDelta59RobotRetinalBiochipSpotID);
|
||||
} else
|
||||
_vm->getAllHotspots().activateOneHotspot(kDelta59RobotHeadSpotID);
|
||||
} else if (GameState.getCurrentRoom() == kNorad60West && GameState.getCurrentDirection() == kWest &&
|
||||
GameState.getNoradBeatRobotWithClaw()) {
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kNorad60MonitorOutSpotID);
|
||||
|
||||
if (_privateFlags.getFlag(kNoradPrivateRobotHeadOpenFlag)) {
|
||||
if (!_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag))
|
||||
_vm->getAllHotspots().activateOneHotspot(kDelta60RobotShieldBiochipSpotID);
|
||||
else
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kDelta60RobotShieldBiochipSpotID);
|
||||
|
||||
if (!_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag))
|
||||
_vm->getAllHotspots().activateOneHotspot(kDelta60RobotOpMemBiochipSpotID);
|
||||
else
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kDelta60RobotOpMemBiochipSpotID);
|
||||
|
||||
if (!_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag))
|
||||
_vm->getAllHotspots().activateOneHotspot(kDelta60RobotRetinalBiochipSpotID);
|
||||
else
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kDelta60RobotRetinalBiochipSpotID);
|
||||
} else {
|
||||
_vm->getAllHotspots().activateOneHotspot(kDelta60RobotHeadSpotID);
|
||||
}
|
||||
} else if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad50, kEast)) {
|
||||
if (GameState.isCurrentDoorOpen())
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kNorad50DoorSpotID);
|
||||
} else if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad59, kWest)) {
|
||||
if (GameState.isCurrentDoorOpen())
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kNorad59WestSpotID);
|
||||
} else if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad68, kWest)) {
|
||||
// WORKAROUND: Make sure the retinal hotspot is disabled after the door opens.
|
||||
// Fixes a bug in the original.
|
||||
if (GameState.isCurrentDoorOpen())
|
||||
_vm->getAllHotspots().deactivateOneHotspot(kNorad68WestSpotID);
|
||||
}
|
||||
}
|
||||
|
||||
void NoradDelta::clickInHotspot(const Input &input, const Hotspot *clickedSpot) {
|
||||
switch (clickedSpot->getObjectID()) {
|
||||
case kDelta59RobotHeadSpotID:
|
||||
startExtraSequence(kN59RobotHeadOpens, kExtraCompletedFlag, kFilterNoInput);
|
||||
break;
|
||||
case kDelta60RobotHeadSpotID:
|
||||
startExtraSequence(kN60RobotHeadOpens, kExtraCompletedFlag, kFilterNoInput);
|
||||
break;
|
||||
default:
|
||||
Norad::clickInHotspot(input, clickedSpot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void NoradDelta::receiveNotification(Notification *notification, const NotificationFlags flags) {
|
||||
Norad::receiveNotification(notification, flags);
|
||||
|
||||
if ((flags & kExtraCompletedFlag) != 0) {
|
||||
RetScanChip *retScan;
|
||||
Input dummy;
|
||||
|
||||
switch (_lastExtra) {
|
||||
case kArriveFromSubChase:
|
||||
GameState.setNoradArrivedFromSub(true);
|
||||
GameState.setCurrentRoom(kNoRoomID);
|
||||
GameState.setCurrentDirection(kNoDirection);
|
||||
arriveAt(kNorad41, kEast);
|
||||
break;
|
||||
case kN59RobotHeadOpens:
|
||||
case kN60RobotHeadOpens:
|
||||
_privateFlags.setFlag(kNoradPrivateRobotHeadOpenFlag, true);
|
||||
if (g_arthurChip) {
|
||||
switch (_vm->getRandomNumber(2)) {
|
||||
case 0:
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA36", kArthurNoradRobotHeadOpen);
|
||||
break;
|
||||
case 1:
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA37", kArthurNoradRobotHeadOpen);
|
||||
break;
|
||||
case 2:
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA40", kArthurNoradRobotHeadOpen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kNoradDeltaRetinalScanBad:
|
||||
retScan = (RetScanChip *)_vm->getCurrentBiochip();
|
||||
retScan->setItemState(kNormalItem);
|
||||
playSpotSoundSync(kRetinalScanFailedIn, kRetinalScanFailedOut);
|
||||
downButton(dummy);
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA13", kArthurNoradAtRetScanNoBiochip);
|
||||
break;
|
||||
case kNoradDeltaRetinalScanGood:
|
||||
retScan = (RetScanChip *)_vm->getCurrentBiochip();
|
||||
retScan->setItemState(kNormalItem);
|
||||
downButton(dummy);
|
||||
break;
|
||||
case kN59RobotDisappears:
|
||||
case kN60RobotDisappears:
|
||||
recallToTSASuccess();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
_interruptionFilter = kFilterAllInput;
|
||||
} else if ((flags & kSpotSoundCompletedFlag) != 0) {
|
||||
if (_spotSounds.getStart() == kToDeactivateIn && g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBB41", kArthurNoradStartGlobeGame);
|
||||
}
|
||||
|
||||
g_AIArea->checkMiddleArea();
|
||||
}
|
||||
|
||||
void NoradDelta::pickedUpItem(Item *item) {
|
||||
switch (item->getObjectID()) {
|
||||
case kShieldBiochip:
|
||||
if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag) &&
|
||||
_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag) &&
|
||||
_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag)) {
|
||||
GameState.setNoradFinished(true);
|
||||
|
||||
if (GameState.getCurrentRoom() == kNorad59West)
|
||||
startExtraSequence(kN59RobotDisappears, kExtraCompletedFlag, kFilterNoInput);
|
||||
else
|
||||
startExtraSequence(kN60RobotDisappears, kExtraCompletedFlag, kFilterNoInput);
|
||||
}
|
||||
break;
|
||||
case kRetinalScanBiochip:
|
||||
if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag) &&
|
||||
_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag) &&
|
||||
_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag)) {
|
||||
GameState.setNoradFinished(true);
|
||||
|
||||
if (GameState.getCurrentRoom() == kNorad59West)
|
||||
startExtraSequence(kN59RobotDisappears, kExtraCompletedFlag, kFilterNoInput);
|
||||
else
|
||||
startExtraSequence(kN60RobotDisappears, kExtraCompletedFlag, kFilterNoInput);
|
||||
}
|
||||
break;
|
||||
case kOpticalBiochip:
|
||||
g_opticalChip->addPoseidon();
|
||||
GameState.setScoringGotNoradOpMemChip();
|
||||
|
||||
if (_privateFlags.getFlag(kNoradPrivateGotShieldChipFlag) &&
|
||||
_privateFlags.getFlag(kNoradPrivateGotRetScanChipFlag) &&
|
||||
_privateFlags.getFlag(kNoradPrivateGotOpticalChipFlag)) {
|
||||
GameState.setNoradFinished(true);
|
||||
|
||||
if (GameState.getCurrentRoom() == kNorad59West)
|
||||
startExtraSequence(kN59RobotDisappears, kExtraCompletedFlag, kFilterNoInput);
|
||||
else
|
||||
startExtraSequence(kN60RobotDisappears, kExtraCompletedFlag, kFilterNoInput);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Norad::pickedUpItem(item);
|
||||
}
|
||||
|
||||
void NoradDelta::takeItemFromRoom(Item *item) {
|
||||
switch (item->getObjectID()) {
|
||||
case kShieldBiochip:
|
||||
_privateFlags.setFlag(kNoradPrivateGotShieldChipFlag, true);
|
||||
break;
|
||||
case kRetinalScanBiochip:
|
||||
_privateFlags.setFlag(kNoradPrivateGotRetScanChipFlag, true);
|
||||
break;
|
||||
case kOpticalBiochip:
|
||||
_privateFlags.setFlag(kNoradPrivateGotOpticalChipFlag, true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Norad::takeItemFromRoom(item);
|
||||
}
|
||||
|
||||
void NoradDelta::dropItemIntoRoom(Item *item, Hotspot *hotspot) {
|
||||
switch (item->getObjectID()) {
|
||||
case kShieldBiochip:
|
||||
_privateFlags.setFlag(kNoradPrivateGotShieldChipFlag, false);
|
||||
break;
|
||||
case kOpticalBiochip:
|
||||
_privateFlags.setFlag(kNoradPrivateGotOpticalChipFlag, false);
|
||||
break;
|
||||
case kRetinalScanBiochip:
|
||||
_privateFlags.setFlag(kNoradPrivateGotRetScanChipFlag, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Norad::dropItemIntoRoom(item, hotspot);
|
||||
}
|
||||
|
||||
Hotspot *NoradDelta::getItemScreenSpot(Item *item, DisplayElement *element) {
|
||||
HotSpotID id = kNoHotSpotID;
|
||||
|
||||
switch (item->getObjectID()) {
|
||||
case kShieldBiochip:
|
||||
if (GameState.getNoradBeatRobotWithDoor())
|
||||
id = kDelta59RobotShieldBiochipSpotID;
|
||||
else
|
||||
id = kDelta60RobotShieldBiochipSpotID;
|
||||
break;
|
||||
case kOpticalBiochip:
|
||||
if (GameState.getNoradBeatRobotWithDoor())
|
||||
id = kDelta59RobotOpMemBiochipSpotID;
|
||||
else
|
||||
id = kDelta60RobotOpMemBiochipSpotID;
|
||||
break;
|
||||
case kRetinalScanBiochip:
|
||||
if (GameState.getNoradBeatRobotWithDoor())
|
||||
id = kDelta59RobotRetinalBiochipSpotID;
|
||||
else
|
||||
id = kDelta60RobotRetinalBiochipSpotID;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (id != kNoHotSpotID)
|
||||
return _vm->getAllHotspots().findHotspotByID(id);
|
||||
|
||||
return Norad::getItemScreenSpot(item, element);
|
||||
}
|
||||
|
||||
Common::Path NoradDelta::getEnvScanMovie() {
|
||||
return "Images/AI/Norad/XNE2";
|
||||
}
|
||||
|
||||
uint NoradDelta::getNumHints() {
|
||||
uint numHints = Neighborhood::getNumHints();
|
||||
|
||||
if (numHints == 0) {
|
||||
switch (GameState.getCurrentRoomAndView()) {
|
||||
case MakeRoomView(kNorad60, kWest):
|
||||
if (GameState.getNoradPlayedGlobeGame())
|
||||
numHints = 2;
|
||||
else
|
||||
numHints = 1;
|
||||
break;
|
||||
case MakeRoomView(kNorad59, kNorth):
|
||||
case MakeRoomView(kNorad59, kSouth):
|
||||
case MakeRoomView(kNorad59, kEast):
|
||||
case MakeRoomView(kNorad59, kWest):
|
||||
case MakeRoomView(kNorad60, kNorth):
|
||||
case MakeRoomView(kNorad60, kSouth):
|
||||
case MakeRoomView(kNorad60, kEast):
|
||||
if (GameState.getNoradPlayedGlobeGame())
|
||||
numHints = 2;
|
||||
break;
|
||||
case MakeRoomView(kNorad68, kWest):
|
||||
if (_vm->playerHasItemID(kRetinalScanBiochip)) {
|
||||
BiochipItem *retScan = _vm->getCurrentBiochip();
|
||||
if (retScan == nullptr || retScan->getObjectID() != kRetinalScanBiochip)
|
||||
numHints = 2;
|
||||
} else if (!GameState.isCurrentDoorOpen()) {
|
||||
numHints = 2;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return numHints;
|
||||
}
|
||||
|
||||
Common::Path NoradDelta::getHintMovie(uint hintNum) {
|
||||
Common::Path movieName = Neighborhood::getHintMovie(hintNum);
|
||||
|
||||
if (movieName.empty()) {
|
||||
switch (GameState.getCurrentRoomAndView()) {
|
||||
case MakeRoomView(kNorad60, kWest):
|
||||
if (GameState.getNoradPlayedGlobeGame()) {
|
||||
if (hintNum == 1)
|
||||
return "Images/AI/Norad/XN60WD2";
|
||||
|
||||
return "Images/AI/Norad/XN60WD3";
|
||||
}
|
||||
|
||||
return "Images/AI/Globals/XGLOB1C";
|
||||
case MakeRoomView(kNorad59, kNorth):
|
||||
case MakeRoomView(kNorad59, kSouth):
|
||||
case MakeRoomView(kNorad59, kEast):
|
||||
case MakeRoomView(kNorad59, kWest):
|
||||
case MakeRoomView(kNorad60, kNorth):
|
||||
case MakeRoomView(kNorad60, kSouth):
|
||||
case MakeRoomView(kNorad60, kEast):
|
||||
if (hintNum == 1)
|
||||
return "Images/AI/Norad/XN60WD2";
|
||||
|
||||
return "Images/AI/Norad/XN60WD3";
|
||||
case MakeRoomView(kNorad68, kWest):
|
||||
if (_vm->playerHasItemID(kRetinalScanBiochip)) {
|
||||
if (hintNum == 1)
|
||||
return "Images/AI/Globals/XGLOB1A";
|
||||
|
||||
return "Images/AI/Globals/XGLOB1C";
|
||||
}
|
||||
|
||||
if (hintNum == 1)
|
||||
return "Images/AI/Globals/XGLOB1B";
|
||||
|
||||
return "Images/AI/Globals/XGLOB3B";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return movieName;
|
||||
}
|
||||
|
||||
void NoradDelta::closeDoorOffScreen(const RoomID room, const DirectionConstant) {
|
||||
switch (room) {
|
||||
case kNorad47:
|
||||
case kNorad48:
|
||||
case kNorad41:
|
||||
case kNorad42:
|
||||
playSpotSoundSync(kDeltaElevatorDoorCloseIn, kDeltaElevatorDoorCloseOut);
|
||||
break;
|
||||
default:
|
||||
playSpotSoundSync(kDeltaRegDoorCloseIn, kDeltaRegDoorCloseOut);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool NoradDelta::canSolve() {
|
||||
if (Norad::canSolve())
|
||||
return true;
|
||||
|
||||
if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad68, kWest)) {
|
||||
BiochipItem *biochip = _vm->getCurrentBiochip();
|
||||
if (biochip != nullptr && biochip->getObjectID() != kRetinalScanBiochip)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void NoradDelta::doSolve() {
|
||||
Norad::doSolve();
|
||||
|
||||
if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad68, kWest)) {
|
||||
if (!_vm->playerHasItemID(kRetinalScanBiochip))
|
||||
_vm->addItemToBiochips((BiochipItem *)_vm->getAllItems().findItemByID(kRetinalScanBiochip));
|
||||
|
||||
BiochipItem *biochip = _vm->getCurrentBiochip();
|
||||
if (biochip != nullptr && biochip->getObjectID() != kRetinalScanBiochip && g_interface)
|
||||
g_interface->setCurrentBiochipID(kRetinalScanBiochip);
|
||||
|
||||
Hotspot *spot = _vm->getAllHotspots().findHotspotByID(kNorad68WestSpotID);
|
||||
Input scratch;
|
||||
InputHandler::_inputHandler->clickInHotspot(scratch, spot);
|
||||
}
|
||||
}
|
||||
|
||||
void NoradDelta::setSoundFXLevel(const uint16 level) {
|
||||
Neighborhood::setSoundFXLevel(level);
|
||||
|
||||
if (GameState.getCurrentRoomAndView() == MakeRoomView(kNorad54North, kNorth))
|
||||
_loop2Fader.setMasterVolume(level);
|
||||
}
|
||||
|
||||
Common::Path NoradDelta::getSoundSpotsName() {
|
||||
return "Sounds/Norad/Norad Delta Spots";
|
||||
}
|
||||
|
||||
Common::Path NoradDelta::getNavMovieName() {
|
||||
return "Images/Norad Delta/Norad Delta.movie";
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
120
engines/pegasus/neighborhood/norad/delta/noraddelta.h
Normal file
120
engines/pegasus/neighborhood/norad/delta/noraddelta.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_DELTA_NORADDELTA_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_DELTA_NORADDELTA_H
|
||||
|
||||
#include "pegasus/neighborhood/norad/norad.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class NoradDelta : public Norad {
|
||||
public:
|
||||
NoradDelta(InputHandler *, PegasusEngine *);
|
||||
~NoradDelta() override {}
|
||||
|
||||
void init() override;
|
||||
|
||||
void start() override;
|
||||
|
||||
void getExtraCompassMove(const ExtraTable::Entry &, FaderMoveSpec &) override;
|
||||
|
||||
void finishedGlobeGame();
|
||||
|
||||
GameInteraction *makeInteraction(const InteractionID) override;
|
||||
|
||||
void playClawMonitorIntro() override;
|
||||
|
||||
void getClawInfo(HotSpotID &outSpotID, HotSpotID &prepSpotID, HotSpotID &clawControlSpotID,
|
||||
HotSpotID &pinchClawSpotID, HotSpotID &moveClawDownSpotID, HotSpotID &moveClawRightSpotID,
|
||||
HotSpotID &moveClawLeftSpotID, HotSpotID &moveClawUpSpotID, HotSpotID &clawCCWSpotID,
|
||||
HotSpotID &clawCWSpotID, uint32 &, const uint32 *&) override;
|
||||
|
||||
void playerBeatRobotWithClaw();
|
||||
void playerBeatRobotWithDoor();
|
||||
|
||||
void loadAmbientLoops() override;
|
||||
|
||||
void setUpAIRules() override;
|
||||
Common::Path getEnvScanMovie() override;
|
||||
uint getNumHints() override;
|
||||
Common::Path getHintMovie(uint) override;
|
||||
void closeDoorOffScreen(const RoomID, const DirectionConstant) override;
|
||||
|
||||
void checkContinuePoint(const RoomID, const DirectionConstant) override;
|
||||
|
||||
bool canSolve() override;
|
||||
void doSolve() override;
|
||||
|
||||
void setSoundFXLevel(const uint16) override;
|
||||
|
||||
void doorOpened() override;
|
||||
|
||||
protected:
|
||||
enum {
|
||||
kNoradPrivateArrivedFromSubFlag,
|
||||
kNoradPrivateFinishedGlobeGameFlag,
|
||||
kNoradPrivateRobotHeadOpenFlag,
|
||||
kNoradPrivateGotShieldChipFlag,
|
||||
kNoradPrivateGotOpticalChipFlag,
|
||||
kNoradPrivateGotRetScanChipFlag,
|
||||
kNumNoradPrivateFlags
|
||||
};
|
||||
|
||||
static const uint32 _noradDeltaClawExtras[22];
|
||||
|
||||
void getExitEntry(const RoomID, const DirectionConstant, ExitTable::Entry &) override;
|
||||
void getZoomEntry(const HotSpotID, ZoomTable::Entry &) override;
|
||||
void arriveAt(const RoomID, const DirectionConstant) override;
|
||||
void arriveAtNorad68West();
|
||||
void arriveAtNorad79West();
|
||||
void turnTo(const DirectionConstant) override;
|
||||
TimeValue getViewTime(const RoomID, const DirectionConstant) override;
|
||||
void openDoor() override;
|
||||
void cantMoveThatWay(CanMoveForwardReason) override;
|
||||
void activateHotspots() override;
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
void pickedUpItem(Item *item) override;
|
||||
void takeItemFromRoom(Item *item) override;
|
||||
void dropItemIntoRoom(Item *item, Hotspot *) override;
|
||||
Hotspot *getItemScreenSpot(Item *, DisplayElement *) override;
|
||||
|
||||
bool playingAgainstRobot() override;
|
||||
|
||||
void failRetinalScan();
|
||||
void succeedRetinalScan();
|
||||
void getDoorEntry(const RoomID, const DirectionConstant, DoorTable::Entry &) override;
|
||||
|
||||
void bumpIntoWall() override;
|
||||
|
||||
FlagsArray<byte, kNumNoradPrivateFlags> _privateFlags;
|
||||
|
||||
Common::Path getSoundSpotsName() override;
|
||||
Common::Path getNavMovieName() override;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
299
engines/pegasus/neighborhood/norad/norad.cpp
Normal file
299
engines/pegasus/neighborhood/norad/norad.cpp
Normal file
@@ -0,0 +1,299 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/energymonitor.h"
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/biochips/arthurchip.h"
|
||||
#include "pegasus/items/inventory/airmask.h"
|
||||
#include "pegasus/neighborhood/norad/constants.h"
|
||||
#include "pegasus/neighborhood/norad/norad.h"
|
||||
#include "pegasus/neighborhood/norad/noradelevator.h"
|
||||
#include "pegasus/neighborhood/norad/pressuredoor.h"
|
||||
#include "pegasus/neighborhood/norad/subcontrolroom.h"
|
||||
#include "pegasus/neighborhood/norad/subplatform.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
const NotificationFlags kDoneWithPressureDoorNotification = 1;
|
||||
|
||||
const NotificationFlags kNoradNotificationFlags = kDoneWithPressureDoorNotification;
|
||||
|
||||
// This class handles everything that Norad Alpha and Delta have in common, such as
|
||||
// oxygen mask usage, the elevator and the pressure doors.
|
||||
|
||||
Norad::Norad(InputHandler *nextHandler, PegasusEngine *vm, const Common::String &resName, NeighborhoodID id) :
|
||||
Neighborhood(nextHandler, vm, resName, id), _noradNotification(kNoradNotificationID, vm) {
|
||||
_elevatorUpSpotID = kNoHotSpotID;
|
||||
_elevatorDownSpotID = kNoHotSpotID;
|
||||
_elevatorUpRoomID = kNoHotSpotID;
|
||||
_elevatorDownRoomID = kNoHotSpotID;
|
||||
|
||||
_subRoomEntryRoom1 = kNoRoomID;
|
||||
_subRoomEntryDir1 = kNoDirection;
|
||||
_subRoomEntryRoom2 = kNoRoomID;
|
||||
_subRoomEntryDir2 = kNoDirection;
|
||||
_upperPressureDoorRoom = kNoRoomID;
|
||||
_lowerPressureDoorRoom = kNoRoomID;
|
||||
|
||||
_upperPressureDoorUpSpotID = kNoHotSpotID;
|
||||
_upperPressureDoorDownSpotID = kNoHotSpotID;
|
||||
_upperPressureDoorAbortSpotID = kNoHotSpotID;
|
||||
|
||||
_lowerPressureDoorUpSpotID = kNoHotSpotID;
|
||||
_lowerPressureDoorDownSpotID = kNoHotSpotID;
|
||||
_lowerPressureDoorAbortSpotID = kNoHotSpotID;
|
||||
|
||||
_pressureSoundIn = 0xffffffff;
|
||||
_pressureSoundOut = 0xffffffff;
|
||||
_equalizeSoundIn = 0xffffffff;
|
||||
_equalizeSoundOut = 0xffffffff;
|
||||
_accessDeniedIn = 0xffffffff;
|
||||
_accessDeniedOut = 0xffffffff;
|
||||
|
||||
_platformRoom = kNoRoomID;
|
||||
_subControlRoom = kNoRoomID;
|
||||
|
||||
_doneWithPressureDoor = false;
|
||||
|
||||
_noradNotification.notifyMe(this, kNoradNotificationFlags, kNoradNotificationFlags);
|
||||
}
|
||||
|
||||
GameInteraction *Norad::makeInteraction(const InteractionID interactionID) {
|
||||
PressureDoor *pressureDoor;
|
||||
SubControlRoom *subControl;
|
||||
|
||||
switch (interactionID) {
|
||||
case kNoradElevatorInteractionID:
|
||||
return new NoradElevator(this, _elevatorUpRoomID, _elevatorDownRoomID, _elevatorUpSpotID, _elevatorDownSpotID);
|
||||
case kNoradPressureDoorInteractionID:
|
||||
if (GameState.getCurrentRoom() == _upperPressureDoorRoom)
|
||||
pressureDoor = new PressureDoor(this, true, _upperPressureDoorUpSpotID, _upperPressureDoorDownSpotID,
|
||||
_upperPressureDoorAbortSpotID, _pressureSoundIn, _pressureSoundOut, _equalizeSoundIn, _equalizeSoundOut);
|
||||
else
|
||||
pressureDoor = new PressureDoor(this, false, _lowerPressureDoorUpSpotID, _lowerPressureDoorDownSpotID,
|
||||
_lowerPressureDoorAbortSpotID, _pressureSoundIn, _pressureSoundOut, _equalizeSoundIn, _equalizeSoundOut);
|
||||
|
||||
if (GameState.getCurrentRoom() == kNorad59West && playingAgainstRobot())
|
||||
pressureDoor->playAgainstRobot();
|
||||
|
||||
return pressureDoor;
|
||||
case kNoradSubControlRoomInteractionID:
|
||||
subControl = new SubControlRoom(this);
|
||||
|
||||
if (GameState.getCurrentRoom() == kNorad60West && playingAgainstRobot())
|
||||
subControl->playAgainstRobot();
|
||||
|
||||
return subControl;
|
||||
case kNoradSubPlatformInteractionID:
|
||||
return new SubPlatform(this);
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Norad::flushGameState() {
|
||||
g_energyMonitor->saveCurrentEnergyValue();
|
||||
}
|
||||
|
||||
void Norad::start() {
|
||||
setUpAirMask();
|
||||
Neighborhood::start();
|
||||
}
|
||||
|
||||
void Norad::activateHotspots() {
|
||||
Neighborhood::activateHotspots();
|
||||
|
||||
RoomID room = GameState.getCurrentRoom();
|
||||
if (room == _elevatorUpRoomID)
|
||||
_neighborhoodHotspots.activateOneHotspot(_elevatorDownSpotID);
|
||||
else if (room == _elevatorDownRoomID)
|
||||
_neighborhoodHotspots.activateOneHotspot(_elevatorUpSpotID);
|
||||
}
|
||||
|
||||
void Norad::arriveAt(const RoomID room, const DirectionConstant direction) {
|
||||
Neighborhood::arriveAt(room, direction);
|
||||
|
||||
if (GameState.getCurrentRoom() == _elevatorUpRoomID || GameState.getCurrentRoom() == _elevatorDownRoomID)
|
||||
arriveAtNoradElevator();
|
||||
else if (GameState.getCurrentRoom() == _upperPressureDoorRoom)
|
||||
arriveAtUpperPressureDoorRoom();
|
||||
else if (GameState.getCurrentRoom() == _lowerPressureDoorRoom)
|
||||
arriveAtLowerPressureDoorRoom();
|
||||
else if (GameState.getCurrentRoom() == _platformRoom)
|
||||
arriveAtSubPlatformRoom();
|
||||
else if (GameState.getCurrentRoom() == _subControlRoom)
|
||||
arriveAtSubControlRoom();
|
||||
|
||||
if (_doneWithPressureDoor) {
|
||||
_doneWithPressureDoor = false;
|
||||
openDoor();
|
||||
}
|
||||
}
|
||||
|
||||
void Norad::arriveAtNoradElevator() {
|
||||
if (_currentInteraction)
|
||||
_currentInteraction->startOverInteraction();
|
||||
else
|
||||
newInteraction(kNoradElevatorInteractionID);
|
||||
}
|
||||
|
||||
void Norad::arriveAtUpperPressureDoorRoom() {
|
||||
newInteraction(kNoradPressureDoorInteractionID);
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA69", kArthurNoradReachedPressureDoor);
|
||||
}
|
||||
|
||||
void Norad::arriveAtLowerPressureDoorRoom() {
|
||||
newInteraction(kNoradPressureDoorInteractionID);
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA69", kArthurNoradReachedPressureDoor);
|
||||
}
|
||||
|
||||
void Norad::arriveAtSubPlatformRoom() {
|
||||
newInteraction(kNoradSubPlatformInteractionID);
|
||||
}
|
||||
|
||||
void Norad::arriveAtSubControlRoom() {
|
||||
newInteraction(kNoradSubControlRoomInteractionID);
|
||||
}
|
||||
|
||||
int16 Norad::getStaticCompassAngle(const RoomID room, const DirectionConstant dir) {
|
||||
int16 result = Neighborhood::getStaticCompassAngle(room, dir);
|
||||
|
||||
if (room == _elevatorUpRoomID || room == _elevatorDownRoomID)
|
||||
result += kElevatorCompassAngle;
|
||||
else if (room == _platformRoom)
|
||||
result += kSubPlatformCompassAngle;
|
||||
else if (room == _subControlRoom)
|
||||
result += kSubControlCompassAngle;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CanOpenDoorReason Norad::canOpenDoor(DoorTable::Entry &entry) {
|
||||
if (((GameState.getCurrentRoom() == _subRoomEntryRoom1 && GameState.getCurrentDirection() == _subRoomEntryDir1) ||
|
||||
(GameState.getCurrentRoom() == _subRoomEntryRoom2 && GameState.getCurrentDirection() == _subRoomEntryDir2)) &&
|
||||
GameState.getNoradSubRoomPressure() != kNormalSubRoomPressure)
|
||||
return kCantOpenBadPressure;
|
||||
|
||||
return Neighborhood::canOpenDoor(entry);
|
||||
}
|
||||
|
||||
void Norad::cantOpenDoor(CanOpenDoorReason reason) {
|
||||
bool firstLockedDoor;
|
||||
|
||||
if (reason == kCantOpenBadPressure)
|
||||
playSpotSoundSync(_pressureSoundIn, _pressureSoundOut);
|
||||
else
|
||||
playSpotSoundSync(_accessDeniedIn, _accessDeniedOut);
|
||||
if (g_arthurChip) {
|
||||
firstLockedDoor = g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA65", kArthurNoradAttemptedLockedDoor);
|
||||
|
||||
if (!firstLockedDoor)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA68", kArthurNoradAttemptedLockedDoorAgain);
|
||||
}
|
||||
}
|
||||
|
||||
void Norad::startExitMovie(const ExitTable::Entry &exitEntry) {
|
||||
if (GameState.getCurrentRoom() == _elevatorUpRoomID) {
|
||||
if (exitEntry.exitRoom != _elevatorDownRoomID)
|
||||
newInteraction(kNoInteractionID);
|
||||
} else if (GameState.getCurrentRoom() == _elevatorDownRoomID) {
|
||||
if (exitEntry.exitRoom != _elevatorUpRoomID)
|
||||
newInteraction(kNoInteractionID);
|
||||
} else {
|
||||
newInteraction(kNoInteractionID);
|
||||
}
|
||||
|
||||
Neighborhood::startExitMovie(exitEntry);
|
||||
}
|
||||
|
||||
void Norad::startZoomMovie(const ZoomTable::Entry &zoomEntry) {
|
||||
newInteraction(kNoInteractionID);
|
||||
Neighborhood::startZoomMovie(zoomEntry);
|
||||
}
|
||||
|
||||
void Norad::upButton(const Input &input) {
|
||||
if (GameState.getCurrentRoom() != _elevatorUpRoomID && GameState.getCurrentRoom() != _elevatorDownRoomID)
|
||||
Neighborhood::upButton(input);
|
||||
}
|
||||
|
||||
void Norad::setUpAirMask() {
|
||||
_airMaskCallBack.setNotification(&_neighborhoodNotification);
|
||||
_airMaskCallBack.initCallBack(&_airMaskTimer, kCallBackAtExtremes);
|
||||
_airMaskCallBack.setCallBackFlag(kAirTimerExpiredFlag);
|
||||
_neighborhoodNotification.notifyMe(this, kAirTimerExpiredFlag, kAirTimerExpiredFlag);
|
||||
_airMaskCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
_airMaskTimer.setScale(1);
|
||||
_airMaskTimer.setSegment(0, kNoradAirMaskTimeLimit);
|
||||
checkAirMask();
|
||||
}
|
||||
|
||||
void Norad::checkAirMask() {
|
||||
// WORKAROUND: The original game forgot to handle the case where the canister would
|
||||
// be removed, leading to the timer remaining active.
|
||||
if (!GameState.getNoradGassed() || (g_airMask && g_airMask->isAirFilterOn())) {
|
||||
_airMaskTimer.stop();
|
||||
} else if (GameState.getNoradGassed() && !_airMaskTimer.isRunning()) {
|
||||
_airMaskTimer.setTime(0);
|
||||
_airMaskTimer.start();
|
||||
}
|
||||
|
||||
loadAmbientLoops();
|
||||
}
|
||||
|
||||
void Norad::receiveNotification(Notification *notification, const NotificationFlags flags) {
|
||||
if (notification == &_neighborhoodNotification && (flags & kAirTimerExpiredFlag) != 0)
|
||||
g_vm->die(kDeathGassedInNorad);
|
||||
|
||||
Neighborhood::receiveNotification(notification, flags);
|
||||
|
||||
if (notification == &_noradNotification) {
|
||||
// Must be kDoneWithPressureDoorNotification...
|
||||
Input scratch;
|
||||
_doneWithPressureDoor = true;
|
||||
downButton(scratch);
|
||||
}
|
||||
}
|
||||
|
||||
uint16 Norad::getDateResID() const {
|
||||
return kDate2112ID;
|
||||
}
|
||||
|
||||
Common::Path Norad::getBriefingMovie() {
|
||||
return "Images/AI/Norad/XNO";
|
||||
}
|
||||
|
||||
void Norad::pickedUpItem(Item *item) {
|
||||
Neighborhood::pickedUpItem(item);
|
||||
g_AIArea->checkMiddleArea();
|
||||
}
|
||||
|
||||
void Norad::doneWithPressureDoor() {
|
||||
_noradNotification.setNotificationFlags(kDoneWithPressureDoorNotification, kDoneWithPressureDoorNotification);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
120
engines/pegasus/neighborhood/norad/norad.h
Normal file
120
engines/pegasus/neighborhood/norad/norad.h
Normal file
@@ -0,0 +1,120 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_NORAD_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_NORAD_H
|
||||
|
||||
#include "pegasus/neighborhood/neighborhood.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// This is the code common to both Norad Alpha and Norad Delta
|
||||
|
||||
class Norad : public Neighborhood {
|
||||
public:
|
||||
Norad(InputHandler *, PegasusEngine *owner, const Common::String &resName, const NeighborhoodID);
|
||||
~Norad() override {}
|
||||
|
||||
void flushGameState() override;
|
||||
|
||||
void start() override;
|
||||
|
||||
virtual void getClawInfo(HotSpotID &outSpotID, HotSpotID &prepSpotID,
|
||||
HotSpotID &clawControlSpotID, HotSpotID &pinchClawSpotID,
|
||||
HotSpotID &moveClawDownSpotID, HotSpotID &moveClawRightSpotID,
|
||||
HotSpotID &moveClawLeftSpotID,HotSpotID &moveClawUpSpotID,
|
||||
HotSpotID &clawCCWSpotID, HotSpotID &clawCWSpotID, uint32 &, const uint32 *&) = 0;
|
||||
void checkAirMask() override;
|
||||
|
||||
uint16 getDateResID() const override;
|
||||
|
||||
GameInteraction *makeInteraction(const InteractionID) override;
|
||||
|
||||
Common::Path getBriefingMovie() override;
|
||||
|
||||
void pickedUpItem(Item *) override;
|
||||
|
||||
virtual void playClawMonitorIntro() {}
|
||||
|
||||
void doneWithPressureDoor();
|
||||
|
||||
protected:
|
||||
CanOpenDoorReason canOpenDoor(DoorTable::Entry &) override;
|
||||
void cantOpenDoor(CanOpenDoorReason) override;
|
||||
int16 getStaticCompassAngle(const RoomID, const DirectionConstant) override;
|
||||
void startExitMovie(const ExitTable::Entry &) override;
|
||||
void startZoomMovie(const ZoomTable::Entry &) override;
|
||||
void upButton(const Input &) override;
|
||||
void activateHotspots() override;
|
||||
|
||||
void arriveAt(const RoomID, const DirectionConstant) override;
|
||||
virtual void arriveAtNoradElevator();
|
||||
virtual void arriveAtUpperPressureDoorRoom();
|
||||
virtual void arriveAtLowerPressureDoorRoom();
|
||||
virtual void arriveAtSubPlatformRoom();
|
||||
virtual void arriveAtSubControlRoom();
|
||||
void setUpAirMask();
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
virtual bool playingAgainstRobot() { return false; }
|
||||
|
||||
Notification _noradNotification;
|
||||
bool _doneWithPressureDoor;
|
||||
|
||||
RoomID _elevatorUpRoomID;
|
||||
RoomID _elevatorDownRoomID;
|
||||
HotSpotID _elevatorUpSpotID;
|
||||
HotSpotID _elevatorDownSpotID;
|
||||
|
||||
TimeBase _airMaskTimer;
|
||||
NotificationCallBack _airMaskCallBack;
|
||||
|
||||
RoomID _subRoomEntryRoom1;
|
||||
DirectionConstant _subRoomEntryDir1;
|
||||
RoomID _subRoomEntryRoom2;
|
||||
DirectionConstant _subRoomEntryDir2;
|
||||
RoomID _upperPressureDoorRoom;
|
||||
RoomID _lowerPressureDoorRoom;
|
||||
|
||||
HotSpotID _upperPressureDoorUpSpotID;
|
||||
HotSpotID _upperPressureDoorDownSpotID;
|
||||
HotSpotID _upperPressureDoorAbortSpotID;
|
||||
|
||||
HotSpotID _lowerPressureDoorUpSpotID;
|
||||
HotSpotID _lowerPressureDoorDownSpotID;
|
||||
HotSpotID _lowerPressureDoorAbortSpotID;
|
||||
|
||||
TimeValue _pressureSoundIn;
|
||||
TimeValue _pressureSoundOut;
|
||||
TimeValue _equalizeSoundIn;
|
||||
TimeValue _equalizeSoundOut;
|
||||
TimeValue _accessDeniedIn;
|
||||
TimeValue _accessDeniedOut;
|
||||
|
||||
RoomID _platformRoom;
|
||||
RoomID _subControlRoom;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
129
engines/pegasus/neighborhood/norad/noradelevator.cpp
Normal file
129
engines/pegasus/neighborhood/norad/noradelevator.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/neighborhood/norad/constants.h"
|
||||
#include "pegasus/neighborhood/norad/norad.h"
|
||||
#include "pegasus/neighborhood/norad/noradelevator.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// Norad elevator PICTs:
|
||||
static const ResIDType kElevatorLabelID = 200;
|
||||
static const ResIDType kElevatorButtonsID = 201;
|
||||
static const ResIDType kElevatorDownOnID = 202;
|
||||
static const ResIDType kElevatorUpOnID = 203;
|
||||
|
||||
NoradElevator::NoradElevator(Neighborhood *handler, const RoomID upRoom, const RoomID downRoom,
|
||||
const HotSpotID upHotspot, const HotSpotID downHotspot) : GameInteraction(kNoradElevatorInteractionID, handler),
|
||||
_elevatorControls(kNoradElevatorControlsID), _elevatorNotification(kNoradElevatorNotificationID, g_vm) {
|
||||
_timerExpired = false;
|
||||
_upRoom = upRoom;
|
||||
_downRoom = downRoom;
|
||||
_upHotspot = upHotspot;
|
||||
_downHotspot = downHotspot;
|
||||
}
|
||||
|
||||
void NoradElevator::openInteraction() {
|
||||
SpriteFrame *frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, kElevatorLabelID, true);
|
||||
_elevatorControls.addFrame(frame, 0, 0);
|
||||
|
||||
frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, kElevatorButtonsID, true);
|
||||
_elevatorControls.addFrame(frame, 0, 0);
|
||||
|
||||
frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, kElevatorDownOnID, true);
|
||||
_elevatorControls.addFrame(frame, 0, 0);
|
||||
|
||||
frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, kElevatorUpOnID, true);
|
||||
_elevatorControls.addFrame(frame, 0, 0);
|
||||
|
||||
_elevatorControls.setCurrentFrameIndex(0);
|
||||
_elevatorControls.setDisplayOrder(kElevatorControlsOrder);
|
||||
|
||||
Common::Rect r;
|
||||
frame->getSurfaceBounds(r);
|
||||
r.moveTo(kNoradAlphaElevatorControlsLeft, kNoradAlphaElevatorControlsTop);
|
||||
|
||||
_elevatorControls.setBounds(r);
|
||||
_elevatorControls.startDisplaying();
|
||||
_elevatorControls.show();
|
||||
}
|
||||
|
||||
void NoradElevator::initInteraction() {
|
||||
_elevatorTimer.setScale(2);
|
||||
_elevatorTimer.setSegment(0, 1);
|
||||
_elevatorCallBack.initCallBack(&_elevatorTimer, kCallBackAtExtremes);
|
||||
_elevatorCallBack.setCallBackFlag(1);
|
||||
_elevatorCallBack.setNotification(&_elevatorNotification);
|
||||
_elevatorNotification.notifyMe(this, 1, 1);
|
||||
_elevatorCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
_elevatorTimer.start();
|
||||
}
|
||||
|
||||
void NoradElevator::closeInteraction() {
|
||||
_elevatorControls.stopDisplaying();
|
||||
_elevatorControls.discardFrames();
|
||||
_elevatorCallBack.releaseCallBack();
|
||||
}
|
||||
|
||||
void NoradElevator::resetInteraction() {
|
||||
_elevatorControls.setCurrentFrameIndex(1);
|
||||
}
|
||||
|
||||
void NoradElevator::activateHotspots() {
|
||||
GameInteraction::activateHotspots();
|
||||
|
||||
if (_timerExpired) {
|
||||
if (GameState.getCurrentRoom() == _upRoom)
|
||||
g_allHotspots.activateOneHotspot(_downHotspot);
|
||||
else if (GameState.getCurrentRoom() == _downRoom)
|
||||
g_allHotspots.activateOneHotspot(_upHotspot);
|
||||
}
|
||||
}
|
||||
|
||||
void NoradElevator::clickInHotspot(const Input &input, const Hotspot *spot) {
|
||||
HotSpotID id = spot->getObjectID();
|
||||
|
||||
if (id == _upHotspot || id == _downHotspot) {
|
||||
g_neighborhood->moveForward();
|
||||
if (id == _downHotspot)
|
||||
_elevatorControls.setCurrentFrameIndex(2);
|
||||
else
|
||||
_elevatorControls.setCurrentFrameIndex(3);
|
||||
} else {
|
||||
GameInteraction::clickInHotspot(input, spot);
|
||||
}
|
||||
}
|
||||
|
||||
void NoradElevator::receiveNotification(Notification *, const NotificationFlags) {
|
||||
_elevatorControls.setCurrentFrameIndex(1);
|
||||
_timerExpired = true;
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
66
engines/pegasus/neighborhood/norad/noradelevator.h
Normal file
66
engines/pegasus/neighborhood/norad/noradelevator.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_NORADELEVATOR_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_NORADELEVATOR_H
|
||||
|
||||
#include "pegasus/interaction.h"
|
||||
#include "pegasus/notification.h"
|
||||
#include "pegasus/surface.h"
|
||||
#include "pegasus/timers.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class Neighborhood;
|
||||
|
||||
class NoradElevator : public GameInteraction, private NotificationReceiver {
|
||||
public:
|
||||
NoradElevator(Neighborhood *, const RoomID, const RoomID, const HotSpotID, const HotSpotID);
|
||||
~NoradElevator() override {}
|
||||
|
||||
protected:
|
||||
void openInteraction() override;
|
||||
void initInteraction() override;
|
||||
void closeInteraction() override;
|
||||
void resetInteraction() override;
|
||||
|
||||
void activateHotspots() override;
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
|
||||
RoomID _upRoom;
|
||||
RoomID _downRoom;
|
||||
HotSpotID _upHotspot;
|
||||
HotSpotID _downHotspot;
|
||||
Sprite _elevatorControls;
|
||||
TimeBase _elevatorTimer;
|
||||
NotificationCallBack _elevatorCallBack;
|
||||
Notification _elevatorNotification;
|
||||
bool _timerExpired;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
562
engines/pegasus/neighborhood/norad/pressuredoor.cpp
Normal file
562
engines/pegasus/neighborhood/norad/pressuredoor.cpp
Normal file
@@ -0,0 +1,562 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/neighborhood/norad/constants.h"
|
||||
#include "pegasus/neighborhood/norad/norad.h"
|
||||
#include "pegasus/neighborhood/norad/pressuredoor.h"
|
||||
#include "pegasus/neighborhood/norad/delta/noraddelta.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
static const TimeValue kLevelsSplashStart = 0;
|
||||
static const TimeValue kLevelsSplashStop = 1;
|
||||
static const TimeValue kPressureBase = 1;
|
||||
|
||||
static const TimeValue kDoorSealedTime = 0;
|
||||
static const TimeValue kEqualizeTime = 1;
|
||||
static const TimeValue kMaxPressureLoopStart = 2;
|
||||
static const TimeValue kMaxPressureLoopStop = 3;
|
||||
static const TimeValue kOpeningDoorLoopStart = 3;
|
||||
static const TimeValue kOpeningDoorLoopStop = 4;
|
||||
static const TimeValue kIncreasingPressureTime = 4;
|
||||
static const TimeValue kDecreasingPressureTime = 5;
|
||||
static const TimeValue kCautionLoopStart = 6;
|
||||
static const TimeValue kCautionLoopStop = 7;
|
||||
|
||||
static const NotificationFlags kSplashFinished = 1;
|
||||
static const NotificationFlags kPressureDroppingFlag = kSplashFinished << 1;
|
||||
|
||||
static const NotificationFlags kPressureNotificationFlags = kSplashFinished |
|
||||
kPressureDroppingFlag;
|
||||
|
||||
static const NotificationFlags kDoorJumpsUpFlag = 1;
|
||||
static const NotificationFlags kDoorJumpsBackFlag = kDoorJumpsUpFlag << 1;
|
||||
static const NotificationFlags kDoorCrushedFlag = kDoorJumpsBackFlag << 1;
|
||||
|
||||
static const NotificationFlags kUtilityNotificationFlags = kDoorJumpsUpFlag |
|
||||
kDoorJumpsBackFlag |
|
||||
kDoorCrushedFlag;
|
||||
|
||||
enum {
|
||||
kPlayingRobotApproaching,
|
||||
kRobotPunching,
|
||||
kRobotComingThrough,
|
||||
kRobotDying,
|
||||
kRobotDead
|
||||
};
|
||||
|
||||
const short kMaxPunches = 5;
|
||||
|
||||
enum {
|
||||
kPlayingSplash,
|
||||
kPlayingPressureMessage,
|
||||
kPlayingEqualizeMessage,
|
||||
kWaitingForPlayer,
|
||||
kPlayingDoneMessage,
|
||||
kGameOver
|
||||
};
|
||||
|
||||
// Pressure values range from 0 to 11.
|
||||
static const short kMinPressure = 0;
|
||||
static const short kMaxPressure = 11;
|
||||
|
||||
static const TimeScale kNavTimeScale = 600;
|
||||
static const TimeValue kNavFrameRate = 15;
|
||||
static const TimeValue kNavTimePerFrame = kNavTimeScale / kNavFrameRate;
|
||||
|
||||
static const TimeValue kApproachPunchInTime = 122 * kNavTimePerFrame;
|
||||
static const TimeValue kLoopPunchInTime = 38 * kNavTimePerFrame;
|
||||
static const TimeValue kPunchThroughTime = 38 * kNavTimePerFrame;
|
||||
|
||||
// Pressure door PICTs:
|
||||
static const ResIDType kUpperPressureUpOffPICTID = 400;
|
||||
static const ResIDType kUpperPressureUpOnPICTID = 401;
|
||||
static const ResIDType kUpperPressureDownOffPICTID = 402;
|
||||
static const ResIDType kUpperPressureDownOnPICTID = 403;
|
||||
|
||||
static const ResIDType kLowerPressureUpOffPICTID = 404;
|
||||
static const ResIDType kLowerPressureUpOnPICTID = 405;
|
||||
static const ResIDType kLowerPressureDownOffPICTID = 406;
|
||||
static const ResIDType kLowerPressureDownOnPICTID = 407;
|
||||
|
||||
PressureDoor::PressureDoor(Neighborhood *handler, bool isUpperDoor, const HotSpotID upSpotID, const HotSpotID downSpotID,
|
||||
const HotSpotID outSpotID, TimeValue pressureSoundIn, TimeValue pressureSoundOut, TimeValue equalizeSoundIn,
|
||||
TimeValue equalizeSoundOut) : GameInteraction(kNoradPressureDoorInteractionID, handler),
|
||||
_levelsMovie(kPressureDoorLevelsID), _typeMovie(kPressureDoorTypeID), _upButton(kPressureDoorUpButtonID),
|
||||
_downButton(kPressureDoorDownButtonID), _pressureNotification(kNoradPressureNotificationID, g_vm),
|
||||
_doorTracker(this), _utilityNotification(kNoradUtilityNotificationID, g_vm) {
|
||||
_neighborhoodNotification = handler->getNeighborhoodNotification();
|
||||
_upHotspotID = upSpotID;
|
||||
_downHotspotID = downSpotID;
|
||||
_outHotspotID = outSpotID;
|
||||
_pressureSoundIn = pressureSoundIn;
|
||||
_pressureSoundOut = pressureSoundOut;
|
||||
_equalizeSoundIn = equalizeSoundIn;
|
||||
_equalizeSoundOut = equalizeSoundOut;
|
||||
_playingAgainstRobot = false;
|
||||
_isUpperDoor = isUpperDoor;
|
||||
}
|
||||
|
||||
void PressureDoor::openInteraction() {
|
||||
if (_isUpperDoor) {
|
||||
_levelsMovie.initFromMovieFile("Images/Norad Alpha/Upper Levels Movie");
|
||||
_levelsMovie.moveElementTo(kNoradUpperLevelsLeft, kNoradUpperLevelsTop);
|
||||
} else {
|
||||
_levelsMovie.initFromMovieFile("Images/Norad Alpha/Lower Levels Movie");
|
||||
_levelsMovie.moveElementTo(kNoradLowerLevelsLeft, kNoradLowerLevelsTop);
|
||||
}
|
||||
|
||||
_levelsScale = _levelsMovie.getScale();
|
||||
_levelsMovie.setDisplayOrder(kPressureLevelsOrder);
|
||||
_levelsMovie.startDisplaying();
|
||||
_levelsMovie.setSegment(kLevelsSplashStart * _levelsScale, kLevelsSplashStop * _levelsScale);
|
||||
_levelsMovie.setTime(kLevelsSplashStart * _levelsScale);
|
||||
_levelsMovie.redrawMovieWorld();
|
||||
_levelsMovie.show();
|
||||
|
||||
_pressureCallBack.setNotification(&_pressureNotification);
|
||||
_pressureCallBack.initCallBack(&_levelsMovie, kCallBackAtExtremes);
|
||||
_pressureCallBack.setCallBackFlag(kSplashFinished);
|
||||
_pressureCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
|
||||
_pressureNotification.notifyMe(this, kPressureNotificationFlags, kPressureNotificationFlags);
|
||||
|
||||
if (_isUpperDoor) {
|
||||
_typeMovie.initFromMovieFile("Images/Norad Alpha/Upper Type Movie");
|
||||
_typeMovie.moveElementTo(kNoradUpperTypeLeft, kNoradUpperTypeTop);
|
||||
} else {
|
||||
_typeMovie.initFromMovieFile("Images/Norad Alpha/Lower Type Movie");
|
||||
_typeMovie.moveElementTo(kNoradLowerTypeLeft, kNoradLowerTypeTop);
|
||||
}
|
||||
|
||||
_typeScale = _typeMovie.getScale();
|
||||
_typeMovie.setDisplayOrder(kPressureTypeOrder);
|
||||
_typeMovie.startDisplaying();
|
||||
_typeMovie.setTime(kDoorSealedTime * _typeScale);
|
||||
_typeMovie.redrawMovieWorld();
|
||||
|
||||
SpriteFrame *frame = new SpriteFrame();
|
||||
if (_isUpperDoor)
|
||||
frame->initFromPICTResource(g_vm->_resFork, kLowerPressureUpOffPICTID);
|
||||
else
|
||||
frame->initFromPICTResource(g_vm->_resFork, kUpperPressureUpOffPICTID);
|
||||
_upButton.addFrame(frame, 0, 0);
|
||||
|
||||
frame = new SpriteFrame();
|
||||
if (_isUpperDoor)
|
||||
frame->initFromPICTResource(g_vm->_resFork, kLowerPressureUpOnPICTID);
|
||||
else
|
||||
frame->initFromPICTResource(g_vm->_resFork, kUpperPressureUpOnPICTID);
|
||||
_upButton.addFrame(frame, 0, 0);
|
||||
|
||||
_upButton.setCurrentFrameIndex(0);
|
||||
_upButton.setDisplayOrder(kPressureUpOrder);
|
||||
|
||||
Common::Rect r;
|
||||
frame->getSurfaceBounds(r);
|
||||
if (_isUpperDoor)
|
||||
r.moveTo(kNoradUpperUpLeft, kNoradUpperUpTop);
|
||||
else
|
||||
r.moveTo(kNoradLowerUpLeft, kNoradLowerUpTop);
|
||||
|
||||
_upButton.setBounds(r);
|
||||
_upButton.startDisplaying();
|
||||
_upButton.show();
|
||||
|
||||
frame = new SpriteFrame();
|
||||
if (_isUpperDoor)
|
||||
frame->initFromPICTResource(g_vm->_resFork, kLowerPressureDownOffPICTID);
|
||||
else
|
||||
frame->initFromPICTResource(g_vm->_resFork, kUpperPressureDownOffPICTID);
|
||||
_downButton.addFrame(frame, 0, 0);
|
||||
|
||||
frame = new SpriteFrame();
|
||||
if (_isUpperDoor)
|
||||
frame->initFromPICTResource(g_vm->_resFork, kLowerPressureDownOnPICTID);
|
||||
else
|
||||
frame->initFromPICTResource(g_vm->_resFork, kUpperPressureDownOnPICTID);
|
||||
_downButton.addFrame(frame, 0, 0);
|
||||
|
||||
_downButton.setCurrentFrameIndex(0);
|
||||
_downButton.setDisplayOrder(kPressureDownOrder);
|
||||
|
||||
frame->getSurfaceBounds(r);
|
||||
if (_isUpperDoor)
|
||||
r.moveTo(kNoradUpperDownLeft, kNoradUpperDownTop);
|
||||
else
|
||||
r.moveTo(kNoradLowerDownLeft, kNoradLowerDownTop);
|
||||
|
||||
_downButton.setBounds(r);
|
||||
_downButton.startDisplaying();
|
||||
_downButton.show();
|
||||
|
||||
_utilityCallBack.setNotification(&_utilityNotification);
|
||||
_utilityCallBack.initCallBack(&_utilityTimer, kCallBackAtTime);
|
||||
_utilityNotification.notifyMe(this, kUtilityNotificationFlags, kUtilityNotificationFlags);
|
||||
_utilityTimer.setMasterTimeBase(getOwner()->getNavMovie());
|
||||
|
||||
if (_playingAgainstRobot)
|
||||
_neighborhoodNotification->notifyMe(this, kExtraCompletedFlag | kDelayCompletedFlag |
|
||||
kSpotSoundCompletedFlag, kExtraCompletedFlag | kDelayCompletedFlag | kSpotSoundCompletedFlag);
|
||||
else
|
||||
_neighborhoodNotification->notifyMe(this, kDelayCompletedFlag | kSpotSoundCompletedFlag,
|
||||
kDelayCompletedFlag | kSpotSoundCompletedFlag);
|
||||
|
||||
_gameState = kPlayingSplash;
|
||||
}
|
||||
|
||||
void PressureDoor::initInteraction() {
|
||||
_levelsMovie.start();
|
||||
|
||||
if (_playingAgainstRobot) {
|
||||
ExtraTable::Entry entry;
|
||||
_owner->getExtraEntry(kN59RobotApproaches, entry);
|
||||
_utilityTimer.setSegment(entry.movieStart, entry.movieEnd);
|
||||
_utilityCallBack.setCallBackFlag(kDoorJumpsUpFlag);
|
||||
_punchInTime = kApproachPunchInTime + entry.movieStart;
|
||||
_utilityCallBack.scheduleCallBack(kTriggerTimeFwd, _punchInTime, kNavTimeScale);
|
||||
_utilityTimer.setTime(entry.movieStart);
|
||||
_owner->startExtraSequence(kN59RobotApproaches, kExtraCompletedFlag, kFilterAllInput);
|
||||
_utilityTimer.start();
|
||||
_robotState = kPlayingRobotApproaching;
|
||||
}
|
||||
|
||||
_levelsMovie.redrawMovieWorld();
|
||||
}
|
||||
|
||||
void PressureDoor::closeInteraction() {
|
||||
_pressureNotification.cancelNotification(this);
|
||||
_pressureCallBack.releaseCallBack();
|
||||
_utilityNotification.cancelNotification(this);
|
||||
_utilityCallBack.releaseCallBack();
|
||||
_neighborhoodNotification->cancelNotification(this);
|
||||
}
|
||||
|
||||
void PressureDoor::playAgainstRobot() {
|
||||
_playingAgainstRobot = true;
|
||||
}
|
||||
|
||||
void PressureDoor::receiveNotification(Notification *notification, const NotificationFlags flags) {
|
||||
Neighborhood *owner = getOwner();
|
||||
|
||||
if (notification == _neighborhoodNotification) {
|
||||
if (_playingAgainstRobot && (flags & kExtraCompletedFlag) != 0) {
|
||||
ExtraTable::Entry entry;
|
||||
|
||||
switch (_robotState) {
|
||||
case kPlayingRobotApproaching:
|
||||
_utilityTimer.stop();
|
||||
if (GameState.getNoradSubRoomPressure() == kMaxPressure) {
|
||||
owner->getExtraEntry(kN59PlayerWins1, entry);
|
||||
_utilityTimer.setSegment(entry.movieStart, entry.movieEnd);
|
||||
_utilityTimer.setTime(entry.movieStart);
|
||||
_utilityCallBack.setCallBackFlag(kDoorJumpsUpFlag);
|
||||
_punchInTime = kLoopPunchInTime + entry.movieStart;
|
||||
_utilityCallBack.scheduleCallBack(kTriggerTimeFwd, _punchInTime, kNavTimeScale);
|
||||
owner->startExtraSequence(kN59PlayerWins1, kExtraCompletedFlag, kFilterNoInput);
|
||||
_utilityTimer.start();
|
||||
_robotState = kRobotDying;
|
||||
} else {
|
||||
owner->getExtraEntry(kN59RobotPunchLoop, entry);
|
||||
_utilityTimer.setSegment(entry.movieStart, entry.movieEnd);
|
||||
_utilityTimer.setTime(entry.movieStart);
|
||||
_utilityCallBack.setCallBackFlag(kDoorJumpsUpFlag);
|
||||
_punchInTime = kLoopPunchInTime + entry.movieStart;
|
||||
_utilityCallBack.scheduleCallBack(kTriggerTimeFwd, _punchInTime, kNavTimeScale);
|
||||
owner->startSpotLoop(entry.movieStart, entry.movieEnd, kExtraCompletedFlag);
|
||||
_utilityTimer.start();
|
||||
_robotState = kRobotPunching;
|
||||
_punchCount = 1;
|
||||
}
|
||||
break;
|
||||
case kRobotPunching:
|
||||
if (GameState.getNoradSubRoomPressure() == kMaxPressure) {
|
||||
owner->startExtraSequence(kN59PlayerWins1, kExtraCompletedFlag, kFilterNoInput);
|
||||
_robotState = kRobotDying;
|
||||
} else if (++_punchCount >= kMaxPunches) {
|
||||
_robotState = kRobotComingThrough;
|
||||
owner->getExtraEntry(kN59RobotWins, entry);
|
||||
_utilityTimer.stop();
|
||||
_utilityTimer.setSegment(entry.movieStart, entry.movieEnd);
|
||||
_utilityTimer.setTime(entry.movieStart);
|
||||
_utilityCallBack.cancelCallBack();
|
||||
_utilityCallBack.setCallBackFlag(kDoorCrushedFlag);
|
||||
_utilityCallBack.scheduleCallBack(kTriggerTimeFwd, kPunchThroughTime + entry.movieStart, kNavTimeScale);
|
||||
owner->startExtraSequence(kN59RobotWins, kExtraCompletedFlag, kFilterNoInput);
|
||||
_utilityTimer.start();
|
||||
} else {
|
||||
_utilityCallBack.setCallBackFlag(kDoorJumpsUpFlag);
|
||||
_utilityCallBack.scheduleCallBack(kTriggerTimeFwd, _punchInTime, kNavTimeScale);
|
||||
owner->scheduleNavCallBack(kExtraCompletedFlag);
|
||||
}
|
||||
break;
|
||||
case kRobotComingThrough:
|
||||
g_system->delayMillis(2 * 1000);
|
||||
g_vm->die(kDeathRobotThroughNoradDoor);
|
||||
break;
|
||||
case kRobotDying:
|
||||
_robotState = kRobotDead;
|
||||
_levelsMovie.stop();
|
||||
_levelsMovie.setSegment((kNormalSubRoomPressure + kPressureBase) * _levelsScale,
|
||||
(GameState.getNoradSubRoomPressure() + kPressureBase) * _levelsScale + 1);
|
||||
_levelsMovie.setTime((GameState.getNoradSubRoomPressure() + kPressureBase) * _levelsScale);
|
||||
_pressureCallBack.setCallBackFlag(kPressureDroppingFlag);
|
||||
_pressureCallBack.scheduleCallBack(kTriggerAtStart, 0, 0);
|
||||
_typeMovie.stop();
|
||||
_typeMovie.setSegment(0, _typeMovie.getDuration());
|
||||
_typeMovie.setTime(kDecreasingPressureTime * _typeScale);
|
||||
_typeMovie.redrawMovieWorld();
|
||||
_typeMovie.show();
|
||||
_downButton.show();
|
||||
_downButton.setCurrentFrameIndex(1);
|
||||
_gameState = kGameOver;
|
||||
allowInput(false);
|
||||
_levelsMovie.setRate(Common::Rational(-4, 3)); // Should match door tracker.
|
||||
break;
|
||||
case kRobotDead:
|
||||
allowInput(true);
|
||||
((NoradDelta *)owner)->playerBeatRobotWithDoor();
|
||||
owner->requestDeleteCurrentInteraction();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & (kDelayCompletedFlag | kSpotSoundCompletedFlag)) != 0) {
|
||||
switch (_gameState) {
|
||||
case kPlayingPressureMessage:
|
||||
_typeMovie.setTime(kEqualizeTime * _typeScale);
|
||||
_typeMovie.redrawMovieWorld();
|
||||
owner->requestDelay(1, 5, kFilterNoInput, 0);
|
||||
owner->requestSpotSound(_equalizeSoundIn, _equalizeSoundOut, kFilterNoInput, 0);
|
||||
owner->requestDelay(1, 5, kFilterNoInput, kDelayCompletedFlag);
|
||||
_gameState = kPlayingEqualizeMessage;
|
||||
break;
|
||||
case kPlayingEqualizeMessage:
|
||||
_gameState = kWaitingForPlayer;
|
||||
stopChangingPressure();
|
||||
break;
|
||||
case kPlayingDoneMessage:
|
||||
_gameState = kWaitingForPlayer;
|
||||
_typeMovie.stop();
|
||||
_typeMovie.setFlags(0);
|
||||
_typeMovie.hide();
|
||||
if (!_playingAgainstRobot)
|
||||
((Norad *)_owner)->doneWithPressureDoor();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (notification == &_pressureNotification) {
|
||||
switch (flags) {
|
||||
case kSplashFinished:
|
||||
_levelsMovie.stop();
|
||||
_levelsMovie.setSegment(0, _levelsMovie.getDuration());
|
||||
_levelsMovie.setTime((GameState.getNoradSubRoomPressure() + kPressureBase) * _levelsScale);
|
||||
_levelsMovie.redrawMovieWorld();
|
||||
|
||||
if (GameState.getNoradSubRoomPressure() != kNormalSubRoomPressure) {
|
||||
_typeMovie.show();
|
||||
owner->requestDelay(1, 5, kFilterNoInput, 0);
|
||||
owner->requestSpotSound(_pressureSoundIn, _pressureSoundOut, kFilterNoInput, 0);
|
||||
owner->requestDelay(1, 5, kFilterNoInput, kDelayCompletedFlag);
|
||||
_gameState = kPlayingPressureMessage;
|
||||
} else {
|
||||
_gameState = kWaitingForPlayer;
|
||||
}
|
||||
break;
|
||||
case kPressureDroppingFlag:
|
||||
_levelsMovie.stop();
|
||||
_levelsMovie.hide();
|
||||
_typeMovie.stop();
|
||||
_typeMovie.hide();
|
||||
_upButton.hide();
|
||||
_downButton.hide();
|
||||
owner->startExtraSequence(kN59PlayerWins2, kExtraCompletedFlag, kFilterNoInput);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (notification == &_utilityNotification) {
|
||||
switch (flags) {
|
||||
case kDoorJumpsUpFlag:
|
||||
_utilityCallBack.setCallBackFlag(kDoorJumpsBackFlag);
|
||||
_utilityCallBack.scheduleCallBack(kTriggerTimeFwd, _punchInTime + kNavTimePerFrame, kNavTimeScale);
|
||||
_levelsMovie.hide();
|
||||
_typePunched = _typeMovie.isVisible();
|
||||
if (_typePunched == true)
|
||||
_typeMovie.hide();
|
||||
_upButton.hide();
|
||||
_downButton.hide();
|
||||
break;
|
||||
case kDoorJumpsBackFlag:
|
||||
_levelsMovie.show();
|
||||
_upButton.show();
|
||||
_downButton.show();
|
||||
if (_typePunched)
|
||||
_typeMovie.show();
|
||||
break;
|
||||
case kDoorCrushedFlag:
|
||||
_levelsMovie.hide();
|
||||
_typeMovie.hide();
|
||||
_upButton.hide();
|
||||
_downButton.hide();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PressureDoor::activateHotspots() {
|
||||
GameInteraction::activateHotspots();
|
||||
|
||||
switch (_gameState) {
|
||||
case kWaitingForPlayer:
|
||||
g_allHotspots.activateOneHotspot(_upHotspotID);
|
||||
g_allHotspots.activateOneHotspot(_downHotspotID);
|
||||
if (!_playingAgainstRobot)
|
||||
g_allHotspots.activateOneHotspot(_outHotspotID);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PressureDoor::clickInHotspot(const Input &input, const Hotspot *spot) {
|
||||
HotSpotID id = spot->getObjectID();
|
||||
|
||||
if (id == _upHotspotID || id == _downHotspotID) {
|
||||
if (id == _upHotspotID)
|
||||
_doorTracker.setTrackParameters(spot, &_upButton);
|
||||
else
|
||||
_doorTracker.setTrackParameters(spot, &_downButton);
|
||||
|
||||
_doorTracker.startTracking(input);
|
||||
} else {
|
||||
GameInteraction::clickInHotspot(input, spot);
|
||||
}
|
||||
}
|
||||
|
||||
void PressureDoor::incrementPressure(const HotSpotID id) {
|
||||
_typeMovie.stop();
|
||||
_typeMovie.setSegment(0, _typeMovie.getDuration());
|
||||
_typeMovie.setFlags(0);
|
||||
|
||||
if (id == _upHotspotID) {
|
||||
if (GameState.getNoradSubRoomPressure() < kMaxPressure) {
|
||||
GameState.setNoradSubRoomPressure(GameState.getNoradSubRoomPressure() + 1);
|
||||
_levelsMovie.setTime((GameState.getNoradSubRoomPressure() + kPressureBase) * _levelsScale);
|
||||
_levelsMovie.redrawMovieWorld();
|
||||
_typeMovie.setTime(kIncreasingPressureTime * _typeScale);
|
||||
_typeMovie.redrawMovieWorld();
|
||||
_typeMovie.show();
|
||||
g_AIArea->checkMiddleArea();
|
||||
} else {
|
||||
_typeMovie.hide();
|
||||
}
|
||||
} else if (id == _downHotspotID) {
|
||||
if (GameState.getNoradSubRoomPressure() > kMinPressure) {
|
||||
GameState.setNoradSubRoomPressure(GameState.getNoradSubRoomPressure() - 1);
|
||||
_levelsMovie.setTime((GameState.getNoradSubRoomPressure() + kPressureBase) * _levelsScale);
|
||||
_levelsMovie.redrawMovieWorld();
|
||||
_typeMovie.setTime(kDecreasingPressureTime * _typeScale);
|
||||
_typeMovie.redrawMovieWorld();
|
||||
_typeMovie.show();
|
||||
g_AIArea->checkMiddleArea();
|
||||
} else {
|
||||
_typeMovie.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PressureDoor::stopChangingPressure() {
|
||||
Neighborhood *owner;
|
||||
|
||||
switch (GameState.getNoradSubRoomPressure()) {
|
||||
case 11:
|
||||
_typeMovie.setSegment(kMaxPressureLoopStart * _typeScale, kMaxPressureLoopStop * _typeScale);
|
||||
_typeMovie.setFlags(kLoopTimeBase);
|
||||
_typeMovie.show();
|
||||
_typeMovie.start();
|
||||
break;
|
||||
case 10:
|
||||
_typeMovie.setSegment(kCautionLoopStart * _typeScale, kCautionLoopStop * _typeScale);
|
||||
_typeMovie.setFlags(kLoopTimeBase);
|
||||
_typeMovie.show();
|
||||
_typeMovie.start();
|
||||
break;
|
||||
case kNormalSubRoomPressure:
|
||||
owner = getOwner();
|
||||
_typeMovie.setSegment(kOpeningDoorLoopStart * _typeScale, kOpeningDoorLoopStop * _typeScale);
|
||||
_typeMovie.setFlags(kLoopTimeBase);
|
||||
_typeMovie.show();
|
||||
_gameState = kPlayingDoneMessage;
|
||||
owner->requestDelay(2, 1, kFilterNoInput, kDelayCompletedFlag);
|
||||
_typeMovie.start();
|
||||
break;
|
||||
default:
|
||||
_typeMovie.hide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool PressureDoor::canSolve() {
|
||||
if (_playingAgainstRobot)
|
||||
return GameState.getNoradSubRoomPressure() < 11;
|
||||
|
||||
return GameState.getNoradSubRoomPressure() != kNormalSubRoomPressure;
|
||||
}
|
||||
|
||||
void PressureDoor::doSolve() {
|
||||
if (_playingAgainstRobot) {
|
||||
GameState.setNoradSubRoomPressure(11);
|
||||
_levelsMovie.setTime((11 + kPressureBase) * _levelsScale);
|
||||
_levelsMovie.redrawMovieWorld();
|
||||
_typeMovie.setSegment(kMaxPressureLoopStart * _typeScale, kMaxPressureLoopStop * _typeScale);
|
||||
_typeMovie.setFlags(kLoopTimeBase);
|
||||
_typeMovie.show();
|
||||
_typeMovie.start();
|
||||
g_AIArea->checkMiddleArea();
|
||||
} else {
|
||||
GameState.setNoradSubRoomPressure(kNormalSubRoomPressure);
|
||||
_levelsMovie.setTime((kNormalSubRoomPressure + kPressureBase) * _levelsScale);
|
||||
_levelsMovie.redrawMovieWorld();
|
||||
_typeMovie.setSegment(kOpeningDoorLoopStart * _typeScale, kOpeningDoorLoopStop * _typeScale);
|
||||
_typeMovie.setFlags(kLoopTimeBase);
|
||||
_typeMovie.show();
|
||||
Neighborhood *owner = getOwner();
|
||||
owner->requestDelay(2, 1, kFilterNoInput, kDelayCompletedFlag);
|
||||
_gameState = kPlayingDoneMessage;
|
||||
_typeMovie.start();
|
||||
g_AIArea->checkMiddleArea();
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
92
engines/pegasus/neighborhood/norad/pressuredoor.h
Normal file
92
engines/pegasus/neighborhood/norad/pressuredoor.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_PRESSUREDOOR_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_PRESSUREDOOR_H
|
||||
|
||||
#include "pegasus/interaction.h"
|
||||
#include "pegasus/movie.h"
|
||||
#include "pegasus/notification.h"
|
||||
#include "pegasus/neighborhood/norad/pressuretracker.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
static const short kNormalSubRoomPressure = 2;
|
||||
|
||||
class PressureDoor : public GameInteraction, public NotificationReceiver {
|
||||
public:
|
||||
PressureDoor(Neighborhood *, bool isUpperDoor, const HotSpotID, const HotSpotID,
|
||||
const HotSpotID, TimeValue pressureSoundIn, TimeValue pressureSoundOut,
|
||||
TimeValue equalizeSoundIn, TimeValue equalizeSoundOut);
|
||||
~PressureDoor() override {}
|
||||
|
||||
void incrementPressure(const HotSpotID);
|
||||
void stopChangingPressure();
|
||||
|
||||
void playAgainstRobot();
|
||||
|
||||
bool canSolve() override;
|
||||
void doSolve() override;
|
||||
|
||||
protected:
|
||||
void openInteraction() override;
|
||||
void initInteraction() override;
|
||||
void closeInteraction() override;
|
||||
|
||||
void activateHotspots() override;
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
|
||||
Movie _levelsMovie;
|
||||
TimeScale _levelsScale;
|
||||
Movie _typeMovie;
|
||||
TimeScale _typeScale;
|
||||
Sprite _upButton;
|
||||
Sprite _downButton;
|
||||
Notification _pressureNotification;
|
||||
NotificationCallBack _pressureCallBack;
|
||||
Notification *_neighborhoodNotification;
|
||||
int _gameState;
|
||||
HotSpotID _upHotspotID;
|
||||
HotSpotID _downHotspotID;
|
||||
HotSpotID _outHotspotID;
|
||||
PressureTracker _doorTracker;
|
||||
TimeValue _pressureSoundIn;
|
||||
TimeValue _pressureSoundOut;
|
||||
TimeValue _equalizeSoundIn;
|
||||
TimeValue _equalizeSoundOut;
|
||||
bool _isUpperDoor;
|
||||
|
||||
bool _playingAgainstRobot, _typePunched;
|
||||
int _robotState, _punchCount;
|
||||
TimeBase _utilityTimer;
|
||||
Notification _utilityNotification;
|
||||
NotificationCallBack _utilityCallBack;
|
||||
TimeValue _punchInTime;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
87
engines/pegasus/neighborhood/norad/pressuretracker.cpp
Normal file
87
engines/pegasus/neighborhood/norad/pressuretracker.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/hotspot.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/neighborhood/norad/pressuredoor.h"
|
||||
#include "pegasus/neighborhood/norad/pressuretracker.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
PressureTracker::PressureTracker(PressureDoor *pressureDoor) {
|
||||
_pressureDoor = pressureDoor;
|
||||
_trackSpot = nullptr;
|
||||
_trackTime = 0;
|
||||
_trackButton = nullptr;
|
||||
}
|
||||
|
||||
void PressureTracker::setTrackParameters(const Hotspot *trackSpot, Sprite *trackButton) {
|
||||
_trackSpot = trackSpot;
|
||||
_trackButton = trackButton;
|
||||
_trackTime = 0;
|
||||
}
|
||||
|
||||
void PressureTracker::activateHotspots() {
|
||||
Tracker::activateHotspots();
|
||||
|
||||
if (_trackSpot)
|
||||
g_allHotspots.activateOneHotspot(_trackSpot->getObjectID());
|
||||
}
|
||||
|
||||
// For click-hold dragging.
|
||||
bool PressureTracker::stopTrackingInput(const Input &input) {
|
||||
return !JMPPPInput::isPressingInput(input);
|
||||
}
|
||||
|
||||
void PressureTracker::continueTracking(const Input &input) {
|
||||
Common::Point where;
|
||||
input.getInputLocation(where);
|
||||
|
||||
if (g_allHotspots.findHotspot(where) == _trackSpot) {
|
||||
trackPressure();
|
||||
_trackButton->setCurrentFrameIndex(1);
|
||||
} else {
|
||||
_trackButton->setCurrentFrameIndex(0);
|
||||
}
|
||||
}
|
||||
|
||||
void PressureTracker::startTracking(const Input &input) {
|
||||
Tracker::startTracking(input);
|
||||
trackPressure();
|
||||
}
|
||||
|
||||
void PressureTracker::stopTracking(const Input &input) {
|
||||
_trackButton->setCurrentFrameIndex(0);
|
||||
_pressureDoor->stopChangingPressure();
|
||||
Tracker::stopTracking(input);
|
||||
}
|
||||
|
||||
void PressureTracker::trackPressure() {
|
||||
if (g_system->getMillis() - _trackTime > kPressureDoorTrackInterval * 1000 / 60) {
|
||||
_pressureDoor->incrementPressure(_trackSpot->getObjectID());
|
||||
_trackTime = g_system->getMillis();
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
68
engines/pegasus/neighborhood/norad/pressuretracker.h
Normal file
68
engines/pegasus/neighborhood/norad/pressuretracker.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_PRESSURETRACKER_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_PRESSURETRACKER_H
|
||||
|
||||
#include "pegasus/input.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// This class assumes that the globe movie is built at 15 frames per second with a
|
||||
// time scale of 600, yielding 40 time unit per frame.
|
||||
|
||||
enum PressureTrackDirection {
|
||||
kTrackPressureUp,
|
||||
kTrackPressureDown
|
||||
};
|
||||
|
||||
static const int kPressureDoorTrackInterval = 45;
|
||||
|
||||
class PressureDoor;
|
||||
class Sprite;
|
||||
|
||||
class PressureTracker : public Tracker {
|
||||
public:
|
||||
PressureTracker(PressureDoor *);
|
||||
~PressureTracker() override {}
|
||||
|
||||
void setTrackParameters(const Hotspot *, Sprite *);
|
||||
void continueTracking(const Input &) override;
|
||||
void startTracking(const Input &) override;
|
||||
void stopTracking(const Input &) override;
|
||||
void activateHotspots() override;
|
||||
bool stopTrackingInput(const Input &) override;
|
||||
|
||||
protected:
|
||||
void trackPressure();
|
||||
|
||||
PressureDoor *_pressureDoor;
|
||||
const Hotspot *_trackSpot;
|
||||
Sprite *_trackButton;
|
||||
long _trackTime;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
1201
engines/pegasus/neighborhood/norad/subcontrolroom.cpp
Normal file
1201
engines/pegasus/neighborhood/norad/subcontrolroom.cpp
Normal file
File diff suppressed because it is too large
Load Diff
132
engines/pegasus/neighborhood/norad/subcontrolroom.h
Normal file
132
engines/pegasus/neighborhood/norad/subcontrolroom.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_SUBCONTROLROOM_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_SUBCONTROLROOM_H
|
||||
|
||||
#include "pegasus/interaction.h"
|
||||
#include "pegasus/notification.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
static const uint32 kClawAtA = 0;
|
||||
static const uint32 kClawAtB = 1;
|
||||
static const uint32 kClawAtC = 2;
|
||||
static const uint32 kClawAtD = 3;
|
||||
|
||||
static const int kNumClawButtons = 7;
|
||||
|
||||
class Norad;
|
||||
|
||||
class SubControlRoom : public GameInteraction, public NotificationReceiver {
|
||||
public:
|
||||
SubControlRoom(Neighborhood *);
|
||||
~SubControlRoom() override {}
|
||||
|
||||
void playAgainstRobot();
|
||||
|
||||
void setSoundFXLevel(const uint16) override;
|
||||
|
||||
bool canSolve() override;
|
||||
void doSolve() override;
|
||||
|
||||
protected:
|
||||
void openInteraction() override;
|
||||
void initInteraction() override;
|
||||
void closeInteraction() override;
|
||||
|
||||
void activateHotspots() override;
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
|
||||
void robotKillsPlayer(const uint32, Neighborhood *);
|
||||
InputBits getInputFilter() override;
|
||||
|
||||
int findActionIndex(HotSpotID);
|
||||
void dispatchClawAction(const int);
|
||||
void performActionImmediately(const int, const uint32, Neighborhood *);
|
||||
|
||||
void hideEverything();
|
||||
void showButtons();
|
||||
void hideButtons();
|
||||
|
||||
void updateGreenBall();
|
||||
void moveGreenBallToA();
|
||||
void moveGreenBallToB();
|
||||
void moveGreenBallToC();
|
||||
void moveGreenBallToD();
|
||||
|
||||
void setControlMonitorToTime(const TimeValue, const int, const bool);
|
||||
void playControlMonitorSection(const TimeValue, const TimeValue, const NotificationFlags,
|
||||
const int, const bool);
|
||||
|
||||
void updateClawMonitor();
|
||||
void setClawMonitorToTime(const TimeValue);
|
||||
void playClawMonitorSection(const TimeValue, const TimeValue, const NotificationFlags,
|
||||
const int, const bool);
|
||||
|
||||
Movie _subControlMovie;
|
||||
TimeScale _subControlScale;
|
||||
Notification _subControlNotification;
|
||||
NotificationCallBack _subControlCallBack;
|
||||
Movie _clawMonitorMovie;
|
||||
NotificationCallBack _clawMonitorCallBack;
|
||||
int _gameState;
|
||||
uint32 _clawStartPosition;
|
||||
uint32 _clawPosition;
|
||||
uint32 _clawNextPosition;
|
||||
const uint32 *_clawExtraIDs;
|
||||
|
||||
int _currentAction;
|
||||
int _nextAction;
|
||||
|
||||
Sprite *_buttons[kNumClawButtons];
|
||||
Sprite _pinchButton;
|
||||
Sprite _downButton;
|
||||
Sprite _rightButton;
|
||||
Sprite _leftButton;
|
||||
Sprite _upButton;
|
||||
Sprite _ccwButton;
|
||||
Sprite _cwButton;
|
||||
|
||||
Sprite _greenBall;
|
||||
TimeBase _greenBallTimer;
|
||||
Notification _greenBallNotification;
|
||||
NotificationCallBack _greenBallCallBack;
|
||||
|
||||
HotSpotID _outSpotID;
|
||||
HotSpotID _prepSpotID;
|
||||
HotSpotID _clawControlSpotID;
|
||||
HotSpotID _clawButtonSpotIDs[kNumClawButtons];
|
||||
|
||||
Notification *_neighborhoodNotification;
|
||||
|
||||
bool _playingAgainstRobot;
|
||||
int _robotState;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
210
engines/pegasus/neighborhood/norad/subplatform.cpp
Normal file
210
engines/pegasus/neighborhood/norad/subplatform.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/biochips/arthurchip.h"
|
||||
#include "pegasus/neighborhood/norad/constants.h"
|
||||
#include "pegasus/neighborhood/norad/norad.h"
|
||||
#include "pegasus/neighborhood/norad/subplatform.h"
|
||||
#include "pegasus/neighborhood/norad/alpha/noradalpha.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// As usual, times here are in seconds.
|
||||
|
||||
static const TimeValue kNormalSplashStart = 0;
|
||||
static const TimeValue kNormalSplashStop = 5;
|
||||
|
||||
static const TimeValue kPrepSubStart = 5;
|
||||
static const TimeValue kPrepSubStop = 15;
|
||||
|
||||
static const TimeValue kPrepIncompleteStart = 15;
|
||||
static const TimeValue kPrepIncompleteStop = 19;
|
||||
|
||||
static const TimeValue kDamagedStart = 19;
|
||||
static const TimeValue kDamagedStop = 28;
|
||||
|
||||
static const NotificationFlags kNormalSplashFinished = 1;
|
||||
static const NotificationFlags kPrepSubFinished = kNormalSplashFinished << 1;
|
||||
static const NotificationFlags kPrepIncompleteFinished = kPrepSubFinished << 1;
|
||||
static const NotificationFlags kDamagedFinished = kPrepIncompleteFinished << 1;
|
||||
|
||||
static const NotificationFlags kPlatformNotificationFlags = kNormalSplashFinished |
|
||||
kPrepSubFinished |
|
||||
kPrepIncompleteFinished |
|
||||
kDamagedFinished;
|
||||
|
||||
static const uint16 kSubPreppedBit = (1 << 0);
|
||||
static const uint16 kWaitingForPlayerBit = (1 << 1);
|
||||
|
||||
SubPlatform::SubPlatform(Neighborhood *handler) : GameInteraction(kNoradSubPlatformInteractionID, handler),
|
||||
_platformMovie(kPlatformMonitorID), _platformNotification(kNoradSubPlatformNotificationID, g_vm) {
|
||||
_neighborhoodNotification = handler->getNeighborhoodNotification();
|
||||
}
|
||||
|
||||
void SubPlatform::openInteraction() {
|
||||
_stateBits = 0;
|
||||
|
||||
// TODO: These next two lines seem unused?
|
||||
if (GameState.getNoradSubPrepState() == kSubPrepped)
|
||||
_stateBits |= kSubPreppedBit;
|
||||
|
||||
_stateBits |= kWaitingForPlayerBit;
|
||||
_platformMovie.initFromMovieFile("Images/Norad Alpha/Platform Monitor Movie");
|
||||
_platformMovie.setVolume(g_vm->getSoundFXLevel());
|
||||
_platformMovie.moveElementTo(kNoradPlatformLeft, kNoradPlatformTop);
|
||||
_platformScale = _platformMovie.getScale();
|
||||
_platformMovie.setDisplayOrder(kPlatformOrder);
|
||||
_platformMovie.startDisplaying();
|
||||
_platformCallBack.setNotification(&_platformNotification);
|
||||
_platformCallBack.initCallBack(&_platformMovie, kCallBackAtExtremes);
|
||||
|
||||
_platformNotification.notifyMe(this, kPlatformNotificationFlags, kPlatformNotificationFlags);
|
||||
}
|
||||
|
||||
void SubPlatform::initInteraction() {
|
||||
_neighborhoodNotification->notifyMe(this, kExtraCompletedFlag, kExtraCompletedFlag);
|
||||
}
|
||||
|
||||
void SubPlatform::closeInteraction() {
|
||||
_platformNotification.cancelNotification(this);
|
||||
_platformCallBack.releaseCallBack();
|
||||
_neighborhoodNotification->cancelNotification(this);
|
||||
}
|
||||
|
||||
void SubPlatform::setSoundFXLevel(const uint16 fxLevel) {
|
||||
_platformMovie.setVolume(fxLevel);
|
||||
}
|
||||
|
||||
void SubPlatform::receiveNotification(Notification *notification, const NotificationFlags flags) {
|
||||
FaderMoveSpec loop1Spec, loop2Spec;
|
||||
ExtraTable::Entry entry;
|
||||
|
||||
Norad *owner = (Norad *)getOwner();
|
||||
|
||||
if (notification == &_platformNotification) {
|
||||
switch (flags) {
|
||||
case kNormalSplashFinished:
|
||||
_platformMovie.stop();
|
||||
switch (GameState.getNoradSubPrepState()) {
|
||||
case kSubNotPrepped:
|
||||
_platformMovie.setSegment(kPrepIncompleteStart * _platformScale, kPrepIncompleteStop * _platformScale);
|
||||
_platformMovie.setTime(kPrepIncompleteStart * _platformScale);
|
||||
_platformCallBack.setCallBackFlag(kPrepIncompleteFinished);
|
||||
_platformCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
_platformMovie.start();
|
||||
break;
|
||||
case kSubPrepped:
|
||||
_platformMovie.setSegment(kPrepSubStart * _platformScale, kPrepSubStop * _platformScale);
|
||||
_platformMovie.setTime(kPrepSubStart * _platformScale);
|
||||
_platformCallBack.setCallBackFlag(kPrepSubFinished);
|
||||
_platformCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
owner->startExtraSequence(kNorad19PrepSub, 0, kFilterNoInput);
|
||||
_platformMovie.start();
|
||||
break;
|
||||
case kSubDamaged:
|
||||
// Shouldn't happen.
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case kPrepSubFinished:
|
||||
_platformMovie.stop();
|
||||
_platformMovie.stopDisplaying();
|
||||
|
||||
owner->getExtraEntry(kNorad19ExitToSub, entry);
|
||||
|
||||
loop1Spec.makeTwoKnotFaderSpec(kNoradAlphaMovieScale, 0, kNoradWarningVolume,
|
||||
entry.movieEnd - entry.movieStart, 0);
|
||||
loop1Spec.insertFaderKnot(4560, kNoradWarningVolume);
|
||||
loop1Spec.insertFaderKnot(5080, 0);
|
||||
|
||||
loop2Spec.makeTwoKnotFaderSpec(kNoradAlphaMovieScale, 0, kNoradSuckWindVolume,
|
||||
entry.movieEnd - entry.movieStart, 0);
|
||||
loop1Spec.insertFaderKnot(4560, kNoradSuckWindVolume);
|
||||
loop1Spec.insertFaderKnot(5080, 0);
|
||||
|
||||
owner->startExtraSequence(kNorad19ExitToSub, kExtraCompletedFlag, kFilterNoInput);
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA07", kArthurNoradEnteredSub);
|
||||
|
||||
owner->startLoop1Fader(loop1Spec);
|
||||
owner->startLoop2Fader(loop2Spec);
|
||||
break;
|
||||
case kPrepIncompleteFinished:
|
||||
((NoradAlpha *)owner)->setSubPrepFailed(true);
|
||||
g_AIArea->checkMiddleArea();
|
||||
// Fall through...
|
||||
case kDamagedFinished:
|
||||
_platformMovie.stop();
|
||||
_platformMovie.hide();
|
||||
_stateBits |= kWaitingForPlayerBit;
|
||||
allowInput(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (notification == _neighborhoodNotification && !g_vm->isDVD()) {
|
||||
allowInput(true);
|
||||
g_vm->jumpToNewEnvironment(kNoradSubChaseID, kNoRoomID, kNoDirection);
|
||||
GameState.setScoringEnteredSub(true);
|
||||
}
|
||||
}
|
||||
|
||||
void SubPlatform::activateHotspots() {
|
||||
if (_stateBits & kWaitingForPlayerBit)
|
||||
g_allHotspots.activateOneHotspot(kNorad19ActivateMonitorSpotID);
|
||||
|
||||
GameInteraction::activateHotspots();
|
||||
}
|
||||
|
||||
void SubPlatform::clickInHotspot(const Input &input, const Hotspot *spot) {
|
||||
if (spot->getObjectID() == kNorad19ActivateMonitorSpotID) {
|
||||
if (GameState.getNoradSubPrepState() == kSubDamaged) {
|
||||
_platformMovie.setSegment(kDamagedStart * _platformScale, kDamagedStop * _platformScale);
|
||||
_platformMovie.setTime(kDamagedStart * _platformScale);
|
||||
_platformCallBack.setCallBackFlag(kDamagedFinished);
|
||||
} else {
|
||||
_platformMovie.setSegment(kNormalSplashStart * _platformScale, kNormalSplashStop * _platformScale);
|
||||
_platformMovie.setTime(kNormalSplashStart * _platformScale);
|
||||
_platformCallBack.setCallBackFlag(kNormalSplashFinished);
|
||||
}
|
||||
|
||||
_platformCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
|
||||
_platformMovie.show();
|
||||
_platformMovie.start();
|
||||
_platformMovie.redrawMovieWorld();
|
||||
|
||||
_stateBits &= ~kWaitingForPlayerBit;
|
||||
|
||||
allowInput(false);
|
||||
} else {
|
||||
GameInteraction::clickInHotspot(input, spot);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
62
engines/pegasus/neighborhood/norad/subplatform.h
Normal file
62
engines/pegasus/neighborhood/norad/subplatform.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_NORAD_SUBPLATFORM_H
|
||||
#define PEGASUS_NEIGHBORHOOD_NORAD_SUBPLATFORM_H
|
||||
|
||||
#include "pegasus/interaction.h"
|
||||
#include "pegasus/movie.h"
|
||||
#include "pegasus/notification.h"
|
||||
#include "pegasus/timers.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class SubPlatform : public GameInteraction, public NotificationReceiver {
|
||||
public:
|
||||
SubPlatform(Neighborhood *);
|
||||
~SubPlatform() override {}
|
||||
|
||||
void setSoundFXLevel(const uint16) override;
|
||||
|
||||
protected:
|
||||
void openInteraction() override;
|
||||
void initInteraction() override;
|
||||
void closeInteraction() override;
|
||||
|
||||
void activateHotspots() override;
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
|
||||
Movie _platformMovie;
|
||||
TimeScale _platformScale;
|
||||
Notification _platformNotification;
|
||||
NotificationCallBack _platformCallBack;
|
||||
Notification *_neighborhoodNotification;
|
||||
uint16 _stateBits;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user