mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
ULTIMA1: Split TransportOnFoot into a separate TransportPlayer class for cities & castles
This commit is contained in:
committed by
Paul Gilbert
parent
0ce4d68d04
commit
ae06eaeeb6
@@ -87,6 +87,7 @@ MODULE_OBJS += \
|
||||
ultima1/widgets/person.o \
|
||||
ultima1/widgets/princess.o \
|
||||
ultima1/widgets/transport.o \
|
||||
ultima1/widgets/urban_player.o \
|
||||
ultima1/widgets/wench.o \
|
||||
ultima1/game.o
|
||||
endif
|
||||
|
||||
@@ -61,7 +61,7 @@ void Map::MapBase::synchronize(Common::Serializer &s) {
|
||||
for (uint idx = 0; idx < _widgets.size(); ++idx) {
|
||||
if (_widgets[idx]->getClassName())
|
||||
++size;
|
||||
if (_currentTransport == _widgets[idx].get())
|
||||
if (_playerWidget == _widgets[idx].get())
|
||||
transportIndex = (int)idx;
|
||||
}
|
||||
assert(transportIndex >= 0);
|
||||
@@ -89,7 +89,7 @@ void Map::MapBase::synchronize(Common::Serializer &s) {
|
||||
}
|
||||
|
||||
s.syncAsUint16LE(transportIndex);
|
||||
_currentTransport = _widgets[transportIndex].get();
|
||||
_playerWidget = _widgets[transportIndex].get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ void Map::MapBase::setDimensions(const Point &size) {
|
||||
}
|
||||
|
||||
Point Map::MapBase::getDirectionDelta() const {
|
||||
switch (_currentTransport->_direction) {
|
||||
switch (_playerWidget->_direction) {
|
||||
case DIR_LEFT:
|
||||
return Point(-1, 0);
|
||||
case DIR_RIGHT:
|
||||
@@ -114,7 +114,7 @@ Point Map::MapBase::getDirectionDelta() const {
|
||||
}
|
||||
|
||||
Point Map::MapBase::getDeltaPosition(const Point &delta) {
|
||||
return _currentTransport->_position + delta;
|
||||
return _playerWidget->_position + delta;
|
||||
}
|
||||
|
||||
void Map::MapBase::resetViewport() {
|
||||
@@ -127,8 +127,8 @@ Point Map::MapBase::getViewportPosition(const Point &viewportSize) {
|
||||
|
||||
if (!_viewportPos.isValid() || _viewportPos._size != viewportSize) {
|
||||
// Calculate the new position
|
||||
topLeft.x = _currentTransport->_position.x - (viewportSize.x - 1) / 2;
|
||||
topLeft.y = _currentTransport->_position.y - (viewportSize.y - 1) / 2;
|
||||
topLeft.x = _playerWidget->_position.x - (viewportSize.x - 1) / 2;
|
||||
topLeft.y = _playerWidget->_position.y - (viewportSize.y - 1) / 2;
|
||||
|
||||
// Fixed maps, so constrain top left corner so the map fills the viewport.
|
||||
// This will accomodate future renderings with more tiles, or greater tile size
|
||||
@@ -189,19 +189,19 @@ void Map::MapBase::update() {
|
||||
}
|
||||
|
||||
Point Map::MapBase::getPosition() const {
|
||||
return _currentTransport->_position;
|
||||
return _playerWidget->_position;
|
||||
}
|
||||
|
||||
void Map::MapBase::setPosition(const Point &pt) {
|
||||
_currentTransport->_position = pt;
|
||||
_playerWidget->_position = pt;
|
||||
}
|
||||
|
||||
Direction Map::MapBase::getDirection() const {
|
||||
return _currentTransport->_direction;
|
||||
return _playerWidget->_direction;
|
||||
}
|
||||
|
||||
void Map::MapBase::setDirection(Shared::Direction dir) {
|
||||
_currentTransport->_direction = dir;
|
||||
_playerWidget->_direction = dir;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
|
||||
@@ -173,14 +173,14 @@ public:
|
||||
Point _size; // X, Y size of the map
|
||||
Point _tilesPerOrigTile; // For enhanced modes, number of tiles per original game tile
|
||||
Common::String _name; // Name of map, if applicable
|
||||
MapWidget *_currentTransport; // Current means of transport, even if on foot
|
||||
MapWidget *_playerWidget; // Current means of transport, even if on foot
|
||||
Common::Array<MapWidgetPtr> _widgets; // Party, monsteres, transports, etc.
|
||||
Common::Array<MapCellsRow> _data; // Data for the map
|
||||
public:
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
MapBase(Game *game, Map *map) : _game(game), _map(map), _currentTransport(nullptr), _mapId(0), _mapIndex(0),
|
||||
MapBase(Game *game, Map *map) : _game(game), _map(map), _playerWidget(nullptr), _mapId(0), _mapIndex(0),
|
||||
_mapStyle(0) {}
|
||||
|
||||
/**
|
||||
@@ -444,11 +444,11 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently active transport on the map
|
||||
* Returns the currently active widget that the player is controlling
|
||||
*/
|
||||
MapWidget *getCurrentTransport() const {
|
||||
MapWidget *getPlayerWidget() const {
|
||||
assert(_mapArea);
|
||||
return _mapArea->_currentTransport;
|
||||
return _mapArea->_playerWidget;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,302 +0,0 @@
|
||||
/* 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.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/debug-channels.h"
|
||||
#include "common/system.h"
|
||||
#include "common/translation.h"
|
||||
#include "graphics/thumbnail.h"
|
||||
#include "graphics/scaler.h"
|
||||
#include "gui/saveload.h"
|
||||
#include "ultima/ultima.h"
|
||||
#include "ultima/debugger.h"
|
||||
#include "ultima/events.h"
|
||||
#include "ultima/core/resources.h"
|
||||
#include "ultima/core/mouse_cursor.h"
|
||||
#include "ultima/gfx/screen.h"
|
||||
#include "ultima/games/ultima1/game.h"
|
||||
|
||||
namespace Ultima {
|
||||
|
||||
UltimaEngine *g_vm;
|
||||
|
||||
UltimaEngine::UltimaEngine(OSystem *syst, const UltimaGameDescription *gameDesc) :
|
||||
Engine(syst), _gameDescription(gameDesc), _randomSource("Ultima") {
|
||||
g_vm = this;
|
||||
_debugger = nullptr;
|
||||
_events = nullptr;
|
||||
_game = nullptr;
|
||||
_mouseCursor = nullptr;
|
||||
_screen = nullptr;
|
||||
}
|
||||
|
||||
UltimaEngine::~UltimaEngine() {
|
||||
delete _debugger;
|
||||
delete _events;
|
||||
delete _game;
|
||||
delete _mouseCursor;
|
||||
delete _screen;
|
||||
}
|
||||
|
||||
GameId UltimaEngine::getGameID() const {
|
||||
return _gameDescription->gameId;
|
||||
}
|
||||
|
||||
Common::Language UltimaEngine::getLanguage() const {
|
||||
return _gameDescription->desc.language;
|
||||
}
|
||||
|
||||
uint32 UltimaEngine::getFeatures() const {
|
||||
return _gameDescription->features;
|
||||
}
|
||||
|
||||
bool UltimaEngine::isVGAEnhanced() const {
|
||||
return getFeatures() & GF_VGA_ENHANCED;
|
||||
}
|
||||
|
||||
bool UltimaEngine::hasFeature(EngineFeature f) const {
|
||||
return
|
||||
(f == kSupportsRTL) ||
|
||||
(f == kSupportsLoadingDuringRuntime) ||
|
||||
(f == kSupportsSavingDuringRuntime);
|
||||
}
|
||||
|
||||
bool UltimaEngine::initialize() {
|
||||
DebugMan.addDebugChannel(kDebugLevelScript, "scripts", "Script debug level");
|
||||
|
||||
// Set up the resources datafile
|
||||
Resources *res = new Resources();
|
||||
if (!res->open()) {
|
||||
GUIErrorMessage("Could not find correct ultima.dat datafile");
|
||||
return false;
|
||||
}
|
||||
SearchMan.add("ultima", res);
|
||||
|
||||
_debugger = Debugger::init(this);
|
||||
_events = new Events();
|
||||
_screen = new Gfx::Screen();
|
||||
_mouseCursor = new MouseCursor();
|
||||
|
||||
// Create the game, and signal to it that the game is starting
|
||||
_game = createGame();
|
||||
_events->addTarget(_game);
|
||||
|
||||
// If requested, load a savegame instead of showing the intro
|
||||
if (ConfMan.hasKey("save_slot")) {
|
||||
int saveSlot = ConfMan.getInt("save_slot");
|
||||
if (saveSlot >= 0 && saveSlot <= 999) {
|
||||
_game->starting(true);
|
||||
loadGameState(saveSlot);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
_game->starting(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void UltimaEngine::deinitialize() {
|
||||
}
|
||||
|
||||
Common::Error UltimaEngine::run() {
|
||||
// Initialize the engine and play the game
|
||||
if (initialize())
|
||||
playGame();
|
||||
|
||||
// Deinitialize and free the engine
|
||||
deinitialize();
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
void UltimaEngine::playGame() {
|
||||
while (!shouldQuit()) {
|
||||
_events->pollEventsAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
Shared::Game *UltimaEngine::createGame() const {
|
||||
switch (getGameID()) {
|
||||
case GAME_ULTIMA1:
|
||||
return new Ultima1::Ultima1Game();
|
||||
default:
|
||||
error("Unknown game");
|
||||
}
|
||||
}
|
||||
|
||||
void UltimaEngine::GUIError(const char *msg, ...) {
|
||||
char buffer[STRINGBUFLEN];
|
||||
va_list va;
|
||||
|
||||
// Generate the full error message
|
||||
va_start(va, msg);
|
||||
vsnprintf(buffer, STRINGBUFLEN, msg, va);
|
||||
va_end(va);
|
||||
|
||||
GUIErrorMessage(buffer);
|
||||
}
|
||||
|
||||
Common::Error UltimaEngine::loadGameState(int slot) {
|
||||
Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading(
|
||||
Common::String::format("%s.%.3d", _targetName.c_str(), slot));
|
||||
if (!saveFile)
|
||||
return Common::kReadingFailed;
|
||||
|
||||
// Load the savaegame header
|
||||
UltimaSavegameHeader header;
|
||||
if (!readSavegameHeader(saveFile, header, false))
|
||||
return Common::kReadingFailed;
|
||||
|
||||
if (header._gameId != getGameID() || header._language != getLanguage()
|
||||
|| header._videoMode != (isVGAEnhanced() ? 9 : 0))
|
||||
return Common::kReadingFailed;
|
||||
|
||||
// Set the total play time
|
||||
_events->setFrameCounter(header._totalFrames);
|
||||
|
||||
// Read in the game's data
|
||||
Common::Serializer s(saveFile, nullptr);
|
||||
_game->synchronize(s);
|
||||
|
||||
delete saveFile;
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
Common::Error UltimaEngine::saveGameState(int slot, const Common::String &desc) {
|
||||
Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(
|
||||
Common::String::format("%s.%.3d", _targetName.c_str(), slot));
|
||||
if (!saveFile)
|
||||
return Common::kCreatingFileFailed;
|
||||
|
||||
// Write the savegame header
|
||||
writeSavegameHeader(saveFile, desc);
|
||||
|
||||
// Write out the game's data
|
||||
Common::Serializer s(nullptr, saveFile);
|
||||
_game->synchronize(s);
|
||||
|
||||
saveFile->finalize();
|
||||
delete saveFile;
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
bool UltimaEngine::canLoadGameStateCurrently() {
|
||||
return _game->canLoadGameStateCurrently();
|
||||
}
|
||||
|
||||
bool UltimaEngine::canSaveGameStateCurrently() {
|
||||
return _game->canSaveGameStateCurrently();
|
||||
}
|
||||
|
||||
static const uint32 SAVEGAME_IDENT = MKTAG('U', 'L', 'T', 'S');
|
||||
static const int SAVEGAME_VERSION = 1;
|
||||
|
||||
bool UltimaEngine::readSavegameHeader(Common::InSaveFile *in, UltimaSavegameHeader &header, bool skipThumbnail) {
|
||||
// Validate the header Id
|
||||
if (in->readUint32BE() != SAVEGAME_IDENT)
|
||||
return false;
|
||||
|
||||
header._version = in->readByte();
|
||||
if (header._version > SAVEGAME_VERSION)
|
||||
return false;
|
||||
|
||||
// Read in game, version and language fields
|
||||
header._gameId = in->readByte();
|
||||
header._language = in->readByte();
|
||||
header._videoMode = in->readByte();
|
||||
|
||||
// Read in the string
|
||||
header._saveName.clear();
|
||||
char ch;
|
||||
while ((ch = (char)in->readByte()) != '\0')
|
||||
header._saveName += ch;
|
||||
|
||||
// Get the thumbnail
|
||||
if (!Graphics::loadThumbnail(*in, header._thumbnail, skipThumbnail)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Read in save date/time
|
||||
header._year = in->readSint16LE();
|
||||
header._month = in->readSint16LE();
|
||||
header._day = in->readSint16LE();
|
||||
header._hour = in->readSint16LE();
|
||||
header._minute = in->readSint16LE();
|
||||
header._totalFrames = in->readUint32LE();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void UltimaEngine::writeSavegameHeader(Common::OutSaveFile *out, const Common::String &saveName) {
|
||||
out->writeUint32BE(SAVEGAME_IDENT);
|
||||
out->writeByte(SAVEGAME_VERSION);
|
||||
out->writeByte(getGameID());
|
||||
out->writeByte(getLanguage());
|
||||
out->writeByte(isVGAEnhanced() ? 9 : 0);
|
||||
out->writeString(saveName);
|
||||
out->writeByte(0);
|
||||
|
||||
// Write a thumbnail of the screen
|
||||
uint8 thumbPalette[PALETTE_SIZE];
|
||||
_screen->getPalette(thumbPalette);
|
||||
Graphics::Surface saveThumb;
|
||||
::createThumbnail(&saveThumb, (const byte *)_screen->getPixels(),
|
||||
_screen->w, _screen->h, thumbPalette);
|
||||
Graphics::saveThumbnail(*out, saveThumb);
|
||||
saveThumb.free();
|
||||
|
||||
// Write out the save date/time
|
||||
TimeDate td;
|
||||
g_system->getTimeAndDate(td);
|
||||
out->writeSint16LE(td.tm_year + 1900);
|
||||
out->writeSint16LE(td.tm_mon + 1);
|
||||
out->writeSint16LE(td.tm_mday);
|
||||
out->writeSint16LE(td.tm_hour);
|
||||
out->writeSint16LE(td.tm_min);
|
||||
out->writeUint32LE(_events->getFrameCounter());
|
||||
}
|
||||
|
||||
bool UltimaEngine::saveGame() {
|
||||
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true);
|
||||
int slotNum = dialog->runModalWithCurrentTarget();
|
||||
Common::String saveName = dialog->getResultString();
|
||||
delete dialog;
|
||||
|
||||
if (slotNum != -1)
|
||||
saveGameState(slotNum, saveName);
|
||||
|
||||
return slotNum != -1;
|
||||
}
|
||||
|
||||
bool UltimaEngine::loadGame() {
|
||||
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Load game:"), _("Load"), false);
|
||||
int slotNum = dialog->runModalWithCurrentTarget();
|
||||
delete dialog;
|
||||
|
||||
if (slotNum != -1)
|
||||
loadGameState(slotNum);
|
||||
|
||||
return slotNum != -1;
|
||||
}
|
||||
|
||||
} // End of namespace Ultima
|
||||
@@ -53,8 +53,8 @@ bool Move::MoveMsg(CMoveMsg &msg) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
Widgets::Transport *transport = dynamic_cast<Widgets::Transport *>(map->getCurrentTransport());
|
||||
assert(transport);
|
||||
Shared::MapWidget *player = map->getPlayerWidget();
|
||||
assert(player);
|
||||
|
||||
// Figure out the new position
|
||||
Point delta;
|
||||
@@ -73,14 +73,14 @@ bool Move::MoveMsg(CMoveMsg &msg) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if the given transport type can move to the new position
|
||||
// Check if the player's widget type can move to the new position
|
||||
Point newPos = map->getDeltaPosition(delta);
|
||||
if (transport->canMoveTo(newPos)) {
|
||||
if (player->canMoveTo(newPos)) {
|
||||
// Shift the viewport
|
||||
map->shiftViewport(delta);
|
||||
|
||||
// Move to the new position
|
||||
transport->moveTo(newPos);
|
||||
player->moveTo(newPos);
|
||||
addInfoMsg(getRes()->DIRECTION_NAMES[msg._direction - 1]);
|
||||
} else {
|
||||
// Nope, so show a blocked message
|
||||
@@ -164,10 +164,10 @@ void Move::dungeonTurnAround() {
|
||||
void Move::dungeonMoveForward() {
|
||||
Map::Ultima1Map *map = getMap();
|
||||
Point delta = map->getDirectionDelta();
|
||||
Shared::MapWidget *widget = map->getCurrentTransport();
|
||||
assert(widget);
|
||||
Shared::MapWidget *player = map->getPlayerWidget();
|
||||
assert(player);
|
||||
|
||||
if (widget->canMoveTo(map->getPosition() + delta)) {
|
||||
if (player->canMoveTo(map->getPosition() + delta)) {
|
||||
map->setPosition(map->getPosition() + delta);
|
||||
} else {
|
||||
playFX(0);
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include "ultima/ultima1/widgets/overworld_monster.h"
|
||||
#include "ultima/ultima1/widgets/princess.h"
|
||||
#include "ultima/ultima1/widgets/transport.h"
|
||||
#include "ultima/ultima1/widgets/urban_player.h"
|
||||
#include "ultima/ultima1/widgets/wench.h"
|
||||
#include "ultima/shared/core/file.h"
|
||||
#include "ultima/shared/early/ultima_early.h"
|
||||
@@ -217,6 +218,7 @@ Shared::MapWidget *Ultima1Map::createWidget(Shared::Map::MapBase *map, const Com
|
||||
REGISTER_WIDGET(OverworldMonster);
|
||||
REGISTER_WIDGET(Princess);
|
||||
REGISTER_WIDGET(TransportOnFoot);
|
||||
REGISTER_WIDGET(UrbanPlayer);
|
||||
REGISTER_WIDGET(Wench);
|
||||
|
||||
error("Unknown widget type '%s'", name.c_str());
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
*/
|
||||
|
||||
#include "ultima/ultima1/map/map_city_castle.h"
|
||||
#include "ultima/ultima1/widgets/transport.h"
|
||||
#include "ultima/ultima1/core/resources.h"
|
||||
#include "ultima/ultima1/game.h"
|
||||
#include "ultima/ultima1/widgets/urban_player.h"
|
||||
#include "ultima/ultima1/widgets/bard.h"
|
||||
#include "ultima/ultima1/widgets/guard.h"
|
||||
#include "ultima/ultima1/widgets/king.h"
|
||||
@@ -50,8 +50,8 @@ void MapCityCastle::clear() {
|
||||
|
||||
void MapCityCastle::loadWidgets() {
|
||||
// Set up widget for the player
|
||||
_currentTransport = new Widgets::TransportOnFoot(_game, this);
|
||||
addWidget(_currentTransport);
|
||||
_playerWidget = new Widgets::UrbanPlayer(_game, this);
|
||||
addWidget(_playerWidget);
|
||||
|
||||
for (int idx = 0; idx < 15; ++idx) {
|
||||
const int *lp = _game->_res->LOCATION_PEOPLE[_mapStyle * 15 + idx];
|
||||
@@ -92,8 +92,8 @@ Point MapCityCastle::getViewportPosition(const Point &viewportSize) {
|
||||
|
||||
if (!_viewportPos.isValid() || _viewportPos._size != viewportSize) {
|
||||
// Calculate the new position
|
||||
topLeft.x = _currentTransport->_position.x - (viewportSize.x - 1) / 2;
|
||||
topLeft.y = _currentTransport->_position.y - (viewportSize.y - 1) / 2;
|
||||
topLeft.x = _playerWidget->_position.x - (viewportSize.x - 1) / 2;
|
||||
topLeft.y = _playerWidget->_position.y - (viewportSize.y - 1) / 2;
|
||||
|
||||
// Fixed maps, so constrain top left corner so the map fills the viewport. This will accomodate
|
||||
// future renderings with more tiles, or greater tile size
|
||||
|
||||
@@ -38,7 +38,7 @@ void MapDungeon::load(Shared::MapId mapId) {
|
||||
_dungeonLevel = 1;
|
||||
|
||||
changeLevel(0);
|
||||
_currentTransport->moveTo(Point(1, 1), Shared::DIR_SOUTH);
|
||||
_playerWidget->moveTo(Point(1, 1), Shared::DIR_SOUTH);
|
||||
}
|
||||
|
||||
bool MapDungeon::changeLevel(int delta) {
|
||||
@@ -54,8 +54,8 @@ bool MapDungeon::changeLevel(int delta) {
|
||||
|
||||
if (_widgets.empty()) {
|
||||
// Set up widget for the player
|
||||
_currentTransport = new Widgets::DungeonPlayer(_game, this);
|
||||
addWidget(_currentTransport);
|
||||
_playerWidget = new Widgets::DungeonPlayer(_game, this);
|
||||
addWidget(_playerWidget);
|
||||
} else {
|
||||
_widgets.resize(1);
|
||||
}
|
||||
|
||||
@@ -53,13 +53,13 @@ void MapOverworld::loadWidgets() {
|
||||
// the initial "on foot" transport the first time
|
||||
if (_widgets.empty()) {
|
||||
// Set up widget for the player
|
||||
_currentTransport = new Widgets::TransportOnFoot(_game, this);
|
||||
addWidget(_currentTransport);
|
||||
_playerWidget = new Widgets::TransportOnFoot(_game, this);
|
||||
addWidget(_playerWidget);
|
||||
}
|
||||
}
|
||||
|
||||
Point MapOverworld::getDeltaPosition(const Point &delta) {
|
||||
Point pt = _currentTransport->_position + delta;
|
||||
Point pt = _playerWidget->_position + delta;
|
||||
|
||||
if (pt.x < 0)
|
||||
pt.x += _size.x;
|
||||
@@ -78,8 +78,8 @@ Point MapOverworld::getViewportPosition(const Point &viewportSize) {
|
||||
|
||||
if (!_viewportPos.isValid() || _viewportPos._size != viewportSize) {
|
||||
// Calculate the new position
|
||||
topLeft.x = _currentTransport->_position.x - (viewportSize.x - 1) / 2;
|
||||
topLeft.y = _currentTransport->_position.y - (viewportSize.y - 1) / 2;
|
||||
topLeft.x = _playerWidget->_position.x - (viewportSize.x - 1) / 2;
|
||||
topLeft.y = _playerWidget->_position.y - (viewportSize.y - 1) / 2;
|
||||
|
||||
// Non-fixed map, so it wraps around the edges if necessary
|
||||
if (topLeft.x < 0)
|
||||
|
||||
@@ -32,7 +32,7 @@ void Bard::movement() {
|
||||
if (areGuardsHostile())
|
||||
return;
|
||||
|
||||
Point playerPos = _map->_currentTransport->_position;
|
||||
Point playerPos = _map->_playerWidget->_position;
|
||||
bool stolen = false;
|
||||
|
||||
// Choose a new random position to move to
|
||||
|
||||
@@ -51,7 +51,7 @@ void DungeonMonster::draw(Shared::DungeonSurface &s, uint distance) {
|
||||
|
||||
void DungeonMonster::update(bool isPreUpdate) {
|
||||
assert(isPreUpdate);
|
||||
Point playerPos = _map->_currentTransport->_position;
|
||||
Point playerPos = _map->_playerWidget->_position;
|
||||
Point delta = playerPos - _position;
|
||||
int distance = ABS(delta.x) + ABS(delta.y);
|
||||
|
||||
@@ -67,7 +67,7 @@ void DungeonMonster::movement() {
|
||||
// Dungeon monsters don't move if they're already in attack range
|
||||
return;
|
||||
|
||||
Point playerPos = _map->_currentTransport->_position;
|
||||
Point playerPos = _map->_playerWidget->_position;
|
||||
Point delta = playerPos - _position;
|
||||
|
||||
if (delta.x != 0 && canMoveTo(Point(_position.x + SGN(delta.x), _position.y)))
|
||||
@@ -103,7 +103,7 @@ bool DungeonMonster::canMoveTo(Shared::Map::MapBase *map, MapWidget *widget, con
|
||||
|
||||
void DungeonMonster::attack() {
|
||||
Ultima1Game *game = static_cast<Ultima1Game *>(_game);
|
||||
Point playerPos = _map->_currentTransport->_position;
|
||||
Point playerPos = _map->_playerWidget->_position;
|
||||
//Point delta = playerPos - _position;
|
||||
Shared::Character *c = _game->_party._currentCharacter;
|
||||
uint threshold, damage;
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace Ultima1 {
|
||||
namespace Widgets {
|
||||
|
||||
uint Guard::attackDistance() const {
|
||||
Point diff = _position - _map->_currentTransport->_position;
|
||||
Point diff = _position - _map->_playerWidget->_position;
|
||||
return areGuardsHostile() && ABS(diff.x) < 2 && ABS(diff.y) < 2 ? 1 : 0;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ void Guard::movement() {
|
||||
if (!areGuardsHostile() || attackDistance())
|
||||
return;
|
||||
|
||||
Point diff = _position - _map->_currentTransport->_position;
|
||||
Point diff = _position - _map->_playerWidget->_position;
|
||||
Point delta(SGN(diff.x), SGN(diff.y));
|
||||
int totalDiff = ABS(diff.x) + ABS(diff.y);
|
||||
if (totalDiff >= 13)
|
||||
|
||||
@@ -47,7 +47,7 @@ void OverworldMonster::synchronize(Common::Serializer &s) {
|
||||
}
|
||||
|
||||
uint OverworldMonster::attackDistance() const {
|
||||
Point playerPos = _map->_currentTransport->_position;
|
||||
Point playerPos = _map->_playerWidget->_position;
|
||||
Point diff = playerPos - _position;
|
||||
|
||||
int threshold = _tileNum == 23 || _tileNum == 25 || _tileNum == 31 || _tileNum == 47 ? 3 : 1;
|
||||
@@ -61,7 +61,7 @@ void OverworldMonster::movement() {
|
||||
|
||||
void OverworldMonster::attack() {
|
||||
Ultima1Game *game = dynamic_cast<Ultima1Game *>(_game);
|
||||
Point playerPos = _map->_currentTransport->_position;
|
||||
Point playerPos = _map->_playerWidget->_position;
|
||||
Point diff = playerPos - _position;
|
||||
Point delta(SGN(diff.x), SGN(diff.y));
|
||||
Point tempDiff;
|
||||
|
||||
@@ -33,7 +33,7 @@ void Princess::movement() {
|
||||
Wench::movement();
|
||||
} else {
|
||||
// When the guards are hostile, keep the princess moving towards the player
|
||||
Point playerPos = _map->_currentTransport->_position;
|
||||
Point playerPos = _map->_playerWidget->_position;
|
||||
Point delta(SGN(_position.x - playerPos.x), SGN(_position.y - playerPos.y));
|
||||
bool moved = false;
|
||||
|
||||
|
||||
@@ -42,30 +42,7 @@ Map::Ultima1Map::MapBase *Transport::getMap() const {
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
uint TransportOnFoot::getTileNum() const {
|
||||
Map::Ultima1Map::MapBase *map = getMap();
|
||||
return dynamic_cast<Map::MapOverworld *>(map) ? 8 : 18;
|
||||
}
|
||||
|
||||
void TransportOnFoot::moveTo(const Point &destPos, Shared::Direction dir) {
|
||||
Transport::moveTo(destPos, dir);
|
||||
Shared::Map *map = getGame()->getMap();
|
||||
|
||||
if (destPos.x < 0 || destPos.y < 0 || destPos.x >= (int)map->width() || destPos.y >= (int)map->height()) {
|
||||
// Handling for leaving locations by walking off the edge of the map
|
||||
if (isPrincessSaved())
|
||||
princessSaved();
|
||||
|
||||
// Load the overworld map
|
||||
map->load(Map::MAP_OVERWORLD);
|
||||
}
|
||||
}
|
||||
|
||||
bool TransportOnFoot::isPrincessSaved() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void TransportOnFoot::princessSaved() {
|
||||
// TODO
|
||||
return 8;
|
||||
}
|
||||
|
||||
} // End of namespace Widgets
|
||||
|
||||
@@ -56,16 +56,6 @@ public:
|
||||
};
|
||||
|
||||
class TransportOnFoot : public Transport {
|
||||
private:
|
||||
/**
|
||||
* Checks for whether a princess has been saved from a castle being left
|
||||
*/
|
||||
bool isPrincessSaved() const;
|
||||
|
||||
/**
|
||||
* Called for a princess being saved
|
||||
*/
|
||||
void princessSaved();
|
||||
public:
|
||||
DECLARE_WIDGET(TransportOnFoot)
|
||||
|
||||
@@ -83,14 +73,6 @@ public:
|
||||
* Get the tile for the transport method
|
||||
*/
|
||||
virtual uint getTileNum() const override;
|
||||
|
||||
/**
|
||||
* Moves to a given position
|
||||
* @param destPos Specified new position
|
||||
* @param dir Optional explicit direction to set. If not specified,
|
||||
* the direction will be set relative to the position moved from
|
||||
*/
|
||||
virtual void moveTo(const Point &destPos, Shared::Direction dir = Shared::DIR_NONE) override;
|
||||
};
|
||||
|
||||
} // End of namespace Widgets
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/* 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.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ultima/ultima1/widgets/urban_player.h"
|
||||
#include "ultima/ultima1/map/map.h"
|
||||
#include "ultima/ultima1/game.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima1 {
|
||||
namespace Widgets {
|
||||
|
||||
void UrbanPlayer::moveTo(const Point &destPos, Shared::Direction dir) {
|
||||
Creature::moveTo(destPos, dir);
|
||||
Shared::Map *map = _game->getMap();
|
||||
|
||||
if (destPos.x < 0 || destPos.y < 0 || destPos.x >= (int)map->width() || destPos.y >= (int)map->height()) {
|
||||
// Handling for leaving locations by walking off the edge of the map
|
||||
if (isPrincessSaved())
|
||||
princessSaved();
|
||||
|
||||
// Load the overworld map
|
||||
map->load(Map::MAP_OVERWORLD);
|
||||
}
|
||||
}
|
||||
|
||||
bool UrbanPlayer::isPrincessSaved() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void UrbanPlayer::princessSaved() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
} // End of namespace Widgets
|
||||
} // End of namespace Ultima1
|
||||
} // End of namespace Ultima
|
||||
@@ -0,0 +1,67 @@
|
||||
/* 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.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ULTIMA_ULTIMA1_URBAN_PLAYER_H
|
||||
#define ULTIMA_ULTIMA1_URBAN_PLAYER_H
|
||||
|
||||
#include "ultima/ultima1/widgets/person.h"
|
||||
|
||||
namespace Ultima {
|
||||
namespace Ultima1 {
|
||||
namespace Widgets {
|
||||
|
||||
/**
|
||||
* Specialized player class for within cities and castles
|
||||
*/
|
||||
class UrbanPlayer : public Person {
|
||||
private:
|
||||
/**
|
||||
* Checks for whether a princess has been saved from a castle being left
|
||||
*/
|
||||
bool isPrincessSaved() const;
|
||||
|
||||
/**
|
||||
* Called for a princess being saved
|
||||
*/
|
||||
void princessSaved();
|
||||
public:
|
||||
DECLARE_WIDGET(UrbanPlayer)
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
UrbanPlayer(Ultima1Game *game, Map::Ultima1Map::MapBase *map) : Person(game, map, 18) {}
|
||||
|
||||
/**
|
||||
* Moves to a given position
|
||||
* @param destPos Specified new position
|
||||
* @param dir Optional explicit direction to set. If not specified,
|
||||
* the direction will be set relative to the position moved from
|
||||
*/
|
||||
virtual void moveTo(const Point &destPos, Shared::Direction dir = Shared::DIR_NONE) override;
|
||||
};
|
||||
|
||||
} // End of namespace Widgets
|
||||
} // End of namespace Ultima1
|
||||
} // End of namespace Ultima
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user