PEGASUS: Implement some more neighborhood code

This commit is contained in:
Matthew Hoops 2011-09-01 12:54:00 -04:00
parent 8263f5a7b5
commit 3239002dae
7 changed files with 202 additions and 49 deletions

View File

@ -24,7 +24,7 @@ MODULE_OBJS = \
neighborhood/door.o \
neighborhood/exit.o \
neighborhood/extra.o \
neighborhood/hotspot.o \
neighborhood/hotspotinfo.o \
neighborhood/neighborhood.o \
neighborhood/spot.o \
neighborhood/turn.o \

View File

@ -27,11 +27,11 @@
#include "common/stream.h"
#include "common/textconsole.h"
#include "pegasus/neighborhood/hotspot.h"
#include "pegasus/neighborhood/hotspotinfo.h"
namespace Pegasus {
void HotspotTable::loadFromStream(Common::SeekableReadStream *stream) {
void HotspotInfoTable::loadFromStream(Common::SeekableReadStream *stream) {
uint32 count = stream->readUint32BE();
_entries.resize(count);
@ -50,11 +50,11 @@ void HotspotTable::loadFromStream(Common::SeekableReadStream *stream) {
}
}
void HotspotTable::clear() {
void HotspotInfoTable::clear() {
_entries.clear();
}
HotspotTable::Entry HotspotTable::findEntry(tHotSpotID hotspot) {
HotspotInfoTable::Entry HotspotInfoTable::findEntry(tHotSpotID hotspot) {
for (uint32 i = 0; i < _entries.size(); i++)
if (_entries[i].hotspot == hotspot)
return _entries[i];

View File

@ -23,8 +23,8 @@
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_HOTSPOT_H
#define PEGASUS_NEIGHBORHOOD_HOTSPOT_H
#ifndef PEGASUS_NEIGHBORHOOD_HOTSPOTINFO_H
#define PEGASUS_NEIGHBORHOOD_HOTSPOTINFO_H
#include "common/array.h"
#include "common/endian.h"
@ -37,10 +37,10 @@ namespace Common {
namespace Pegasus {
class HotspotTable {
class HotspotInfoTable {
public:
HotspotTable() {}
~HotspotTable() {}
HotspotInfoTable() {}
~HotspotInfoTable() {}
static const uint32 getResTag() { return MKTAG('H', 'S', 'I', 'n'); }

View File

@ -27,11 +27,14 @@
#include "common/stream.h"
#include "pegasus/pegasus.h"
#include "pegasus/game_shell/CGameState.h"
#include "pegasus/neighborhood/neighborhood.h"
namespace Pegasus {
Neighborhood::Neighborhood(PegasusEngine *vm, const Common::String &resName) : _vm(vm), _resName(resName) {
Neighborhood::Neighborhood(PegasusEngine *vm, const Common::String &resName, tNeighborhoodID id) : _vm(vm), _resName(resName) {
CGameState::SetOpenDoorLocation(kNoRoomID, kNoDirection);
_currentAlternate = 0;
}
Neighborhood::~Neighborhood() {
@ -58,10 +61,10 @@ void Neighborhood::init() {
_extraTable.loadFromStream(stream);
delete stream;
stream = _vm->_resFork->getResource(_hotspotTable.getResTag(), _resName);
stream = _vm->_resFork->getResource(_hotspotInfoTable.getResTag(), _resName);
if (!stream)
error("Failed to load hotspots");
_hotspotTable.loadFromStream(stream);
error("Failed to load hotspot info");
_hotspotInfoTable.loadFromStream(stream);
delete stream;
stream = _vm->_resFork->getResource(_spotTable.getResTag(), _resName);
@ -91,4 +94,133 @@ void Neighborhood::init() {
// TODO: AI, movies, notifications, buncha other stuff
}
void Neighborhood::start() {
CGameState::SetCurrentRoom(CGameState::GetLastRoom());
CGameState::SetCurrentDirection(CGameState::GetLastDirection());
arriveAt(CGameState::GetNextRoom(), CGameState::GetNextDirection());
}
void Neighborhood::arriveAt(tRoomID room, tDirectionConstant direction) {
// TODO
}
// These functions can be overridden to tweak the exact frames used.
void Neighborhood::getExitEntry(const tRoomID room, const tDirectionConstant direction, ExitTable::Entry &entry) {
entry = _exitTable.findEntry(room, direction, _currentAlternate);
if (entry.isEmpty())
entry = _exitTable.findEntry(room, direction, kNoAlternateID);
}
TimeValue Neighborhood::getViewTime(const tRoomID room, const tDirectionConstant direction) {
if (CGameState::GetOpenDoorRoom() == room && CGameState::GetOpenDoorDirection() == direction) {
// If we get here, the door entry for this location must exist.
DoorTable::Entry doorEntry = _doorTable.findEntry(room, direction, _currentAlternate);
if (doorEntry.isEmpty())
doorEntry = _doorTable.findEntry(room, direction, kNoAlternateID);
return doorEntry.movieEnd - 1;
}
ViewTable::Entry viewEntry = _viewTable.findEntry(room, direction, _currentAlternate);
if (viewEntry.isEmpty())
viewEntry = _viewTable.findEntry(room, direction, kNoAlternateID);
return viewEntry.time;
}
void Neighborhood::getDoorEntry(const tRoomID room, const tDirectionConstant direction, DoorTable::Entry &doorEntry) {
doorEntry = _doorTable.findEntry(room, direction, _currentAlternate);
if (doorEntry.isEmpty())
doorEntry = _doorTable.findEntry(room, direction, kNoAlternateID);
}
tDirectionConstant Neighborhood::getTurnEntry(const tRoomID room, const tDirectionConstant direction, const tTurnDirection turn) {
TurnTable::Entry turnEntry = _turnTable.findEntry(room, direction, turn, _currentAlternate);
if (turnEntry.isEmpty())
turnEntry = _turnTable.findEntry(room, direction, turn, kNoAlternateID);
return turnEntry.turnDirection;
}
void Neighborhood::findSpotEntry(const tRoomID room, const tDirectionConstant direction, tSpotFlags flags, SpotTable::Entry &spotEntry) {
spotEntry = _spotTable.findEntry(room, direction, flags, _currentAlternate);
if (spotEntry.isEmpty())
spotEntry = _spotTable.findEntry(room, direction, flags, kNoAlternateID);
}
void Neighborhood::getZoomEntry(const tHotSpotID id, ZoomTable::Entry &zoomEntry) {
zoomEntry = _zoomTable.findEntry(id);
}
void Neighborhood::getHotspotEntry(const tHotSpotID id, HotspotInfoTable::Entry &hotspotEntry) {
hotspotEntry = _hotspotInfoTable.findEntry(id);
}
void Neighborhood::getExtraEntry(const uint32 id, ExtraTable::Entry &extraEntry) {
extraEntry = _extraTable.findEntry(id);
}
/////////////////////////////////////////////
//
// "Can" functions: Called to see whether or not a user is allowed to do something
tCanMoveForwardReason Neighborhood::canMoveForward(ExitTable::Entry &entry) {
DoorTable::Entry door;
getExitEntry(CGameState::GetCurrentRoom(), CGameState::GetCurrentDirection(), entry);
getDoorEntry(CGameState::GetCurrentRoom(), CGameState::GetCurrentDirection(), door);
// Fixed this so that doors that don't lead anywhere can be opened, but not walked
// through.
if (door.flags & kDoorPresentMask) {
if (CGameState::IsCurrentDoorOpen()) {
if (entry.exitRoom == kNoRoomID)
return kCantMoveBlocked;
else
return kCanMoveForward;
} else if (door.flags & kDoorLockedMask) {
return kCantMoveDoorLocked;
} else {
return kCantMoveDoorClosed;
}
} else if (entry.exitRoom == kNoRoomID) {
return kCantMoveBlocked;
}
return kCanMoveForward;
}
tCanTurnReason Neighborhood::canTurn(tTurnDirection turn, tDirectionConstant &nextDir) {
nextDir = getTurnEntry(CGameState::GetCurrentRoom(), CGameState::GetCurrentDirection(), turn);
if (nextDir == kNoDirection)
return kCantTurnNoTurn;
return kCanTurn;
}
tCanOpenDoorReason Neighborhood::canOpenDoor(DoorTable::Entry &entry) {
getDoorEntry(CGameState::GetCurrentRoom(), CGameState::GetCurrentDirection(), entry);
if (entry.flags & kDoorPresentMask) {
if (CGameState::IsCurrentDoorOpen())
return kCantOpenAlreadyOpen;
if (entry.flags & kDoorLockedMask)
return kCantOpenLocked;
return kCanOpenDoor;
}
return kCantOpenNoDoor;
}
} // End of namespace Pegasus

View File

@ -31,7 +31,7 @@
#include "pegasus/neighborhood/door.h"
#include "pegasus/neighborhood/exit.h"
#include "pegasus/neighborhood/extra.h"
#include "pegasus/neighborhood/hotspot.h"
#include "pegasus/neighborhood/hotspotinfo.h"
#include "pegasus/neighborhood/spot.h"
#include "pegasus/neighborhood/turn.h"
#include "pegasus/neighborhood/view.h"
@ -41,25 +41,58 @@ namespace Pegasus {
class PegasusEngine;
// Pegasus Prime neighborhood id's
const tNeighborhoodID kCaldoriaID = 0;
const tNeighborhoodID kFullTSAID = 1;
const tNeighborhoodID kFinalTSAID = 2;
const tNeighborhoodID kTinyTSAID = 3;
const tNeighborhoodID kPrehistoricID = 4;
const tNeighborhoodID kMarsID = 5;
const tNeighborhoodID kWSCID = 6;
const tNeighborhoodID kNoradAlphaID = 7;
const tNeighborhoodID kNoradDeltaID = 8;
// The sub chase is not really a neighborhood, but we define a constant that is used
// to allow an easy transition out of Norad Alpha.
const tNeighborhoodID kNoradSubChaseID = 1000;
class Neighborhood {
public:
Neighborhood(PegasusEngine *vm, const Common::String &resName);
Neighborhood(PegasusEngine *vm, const Common::String &resName, tNeighborhoodID id);
virtual ~Neighborhood();
virtual void init();
void start();
private:
void arriveAt(tRoomID room, tDirectionConstant direction);
virtual void getExitEntry(const tRoomID room, const tDirectionConstant direction, ExitTable::Entry &entry);
virtual TimeValue getViewTime(const tRoomID room, const tDirectionConstant direction);
virtual void getDoorEntry(const tRoomID room, const tDirectionConstant direction, DoorTable::Entry &doorEntry);
virtual tDirectionConstant getTurnEntry(const tRoomID room, const tDirectionConstant direction, const tTurnDirection turn);
virtual void findSpotEntry(const tRoomID room, const tDirectionConstant direction, tSpotFlags flags, SpotTable::Entry &spotEntry);
virtual void getZoomEntry(const tHotSpotID id, ZoomTable::Entry &zoomEntry);
virtual void getHotspotEntry(const tHotSpotID id, HotspotInfoTable::Entry &hotspotEntry);
virtual void getExtraEntry(const uint32 id, ExtraTable::Entry &extraEntry);
tCanMoveForwardReason canMoveForward(ExitTable::Entry &entry);
tCanTurnReason canTurn(tTurnDirection turn, tDirectionConstant &nextDir);
tCanOpenDoorReason canOpenDoor(DoorTable::Entry &entry);
protected:
PegasusEngine *_vm;
Common::String _resName;
tNeighborhoodID _neighborhoodID;
DoorTable _doorTable;
ExitTable _exitTable;
ExtraTable _extraTable;
HotspotTable _hotspotTable;
HotspotInfoTable _hotspotInfoTable;
SpotTable _spotTable;
TurnTable _turnTable;
ViewTable _viewTable;
ZoomTable _zoomTable;
tAlternateID _currentAlternate;
};
} // End of namespace Pegasus

View File

@ -141,10 +141,8 @@ Common::Error PegasusEngine::run() {
runMainMenu();
break;
case kMainGameMode:
if (isDemo())
changeLocation(kLocPrehistoric);
else
changeLocation(kLocCaldoria);
// NOTE: Prehistoric will be our testing location
changeLocation(kPrehistoricID);
mainGameLoop();
break;
case kQuitMode:
@ -233,19 +231,19 @@ void PegasusEngine::mainGameLoop() {
_video->playMovieCentered("Images/Caldoria/Pullback.movie");
drawInterface();
Common::String navMovie = Common::String::format("Images/%s/%s.movie", getTimeZoneFolder(_timeZone).c_str(), getTimeZoneDesc(_timeZone).c_str());
Common::String navMovie = Common::String::format("Images/%s/%s.movie", getTimeZoneFolder(_neighborhood).c_str(), getTimeZoneDesc(_neighborhood).c_str());
_video->playMovie(navMovie, kViewScreenOffset, kViewScreenOffset);
_gameMode = kQuitMode;
}
void PegasusEngine::changeLocation(TimeZone timeZone) {
_timeZone = timeZone;
void PegasusEngine::changeLocation(tNeighborhoodID neighborhood) {
_neighborhood = neighborhood;
// Just a test...
Neighborhood *neighborhood = new Neighborhood(this, getTimeZoneDesc(_timeZone));
neighborhood->init();
delete neighborhood;
Neighborhood *neighborhoodPtr = new Neighborhood(this, getTimeZoneDesc(_neighborhood), _neighborhood);
neighborhoodPtr->init();
delete neighborhoodPtr;
}
void PegasusEngine::showLoadDialog() {
@ -267,16 +265,16 @@ void PegasusEngine::showLoadDialog() {
slc.close();
}
Common::String PegasusEngine::getTimeZoneDesc(TimeZone timeZone) {
static const char *names[] = { "Prehistoric", "Mars", "WSC", "Tiny TSA", "Full TSA", "Norad Alpha", "Caldoria", "Norad Delta" };
return names[timeZone];
Common::String PegasusEngine::getTimeZoneDesc(tNeighborhoodID neighborhood) {
static const char *names[] = { "Caldoria", "Full TSA", "Full TSA", "Tiny TSA", "Prehistoric", "Mars", "WSC", "Norad Alpha", "Norad Delta" };
return names[neighborhood];
}
Common::String PegasusEngine::getTimeZoneFolder(TimeZone timeZone) {
if (timeZone == kLocFullTSA || timeZone == kLocTinyTSA)
Common::String PegasusEngine::getTimeZoneFolder(tNeighborhoodID neighborhood) {
if (neighborhood == kFullTSAID || neighborhood == kTinyTSAID || neighborhood == kFinalTSAID)
return "TSA";
return getTimeZoneDesc(timeZone);
return getTimeZoneDesc(neighborhood);
}
GUI::Debugger *PegasusEngine::getDebugger() {

View File

@ -33,6 +33,7 @@
#include "pegasus/graphics.h"
#include "pegasus/video.h"
#include "pegasus/neighborhood/neighborhood.h"
namespace Video {
class Video::QuickTimeDecoder;
@ -105,17 +106,6 @@ struct OverviewHotspot {
uint32 time;
};
enum TimeZone {
kLocPrehistoric = 0,
kLocMars = 1,
kLocWSC = 2,
kLocTinyTSA = 3,
kLocFullTSA = 4,
kLocNoradAlpha = 5,
kLocCaldoria = 6,
kLocNoradDelta = 7
};
// Taken from JMP PP Resources
enum Item {
kAIBiochip = 128,
@ -198,16 +188,16 @@ private:
// Main Game Functions
void mainGameLoop();
void loadItemLocationData();
void changeLocation(TimeZone timeZone);
void changeLocation(tNeighborhoodID neighborhood);
// Misc Functions
static Common::String getTimeZoneFolder(TimeZone timeZone);
static Common::String getTimeZoneDesc(TimeZone timeZone);
static Common::String getTimeZoneFolder(tNeighborhoodID neighborhood);
static Common::String getTimeZoneDesc(tNeighborhoodID neighborhood);
// Game Variables
bool _adventureMode;
GameMode _gameMode;
TimeZone _timeZone;
tNeighborhoodID _neighborhood;
Common::Array<ItemLocationData> _itemLocationData;
// Console