From ae06eaeeb60b3d1bb9dbcaa5af7a50b3fa1ab5af Mon Sep 17 00:00:00 2001 From: dreammaster Date: Tue, 21 Jan 2020 05:41:42 +0000 Subject: [PATCH] ULTIMA1: Split TransportOnFoot into a separate TransportPlayer class for cities & castles --- engines/ultima/module.mk | 1 + engines/ultima/shared/core/map.cpp | 20 +- engines/ultima/shared/core/map.h | 10 +- engines/ultima/ultima.cpp | 302 ------------------ engines/ultima/ultima1/actions/move.cpp | 16 +- engines/ultima/ultima1/map/map.cpp | 2 + .../ultima/ultima1/map/map_city_castle.cpp | 10 +- engines/ultima/ultima1/map/map_dungeon.cpp | 6 +- engines/ultima/ultima1/map/map_overworld.cpp | 10 +- engines/ultima/ultima1/widgets/bard.cpp | 2 +- .../ultima1/widgets/dungeon_monster.cpp | 6 +- engines/ultima/ultima1/widgets/guard.cpp | 4 +- .../ultima1/widgets/overworld_monster.cpp | 4 +- engines/ultima/ultima1/widgets/princess.cpp | 2 +- engines/ultima/ultima1/widgets/transport.cpp | 25 +- engines/ultima/ultima1/widgets/transport.h | 18 -- .../ultima/ultima1/widgets/urban_player.cpp | 55 ++++ engines/ultima/ultima1/widgets/urban_player.h | 67 ++++ 18 files changed, 171 insertions(+), 389 deletions(-) delete mode 100644 engines/ultima/ultima.cpp create mode 100644 engines/ultima/ultima1/widgets/urban_player.cpp create mode 100644 engines/ultima/ultima1/widgets/urban_player.h diff --git a/engines/ultima/module.mk b/engines/ultima/module.mk index c873bae2223..3ca197ef6ca 100644 --- a/engines/ultima/module.mk +++ b/engines/ultima/module.mk @@ -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 diff --git a/engines/ultima/shared/core/map.cpp b/engines/ultima/shared/core/map.cpp index 42c8e31859b..7ad4b46a8a5 100644 --- a/engines/ultima/shared/core/map.cpp +++ b/engines/ultima/shared/core/map.cpp @@ -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; } /*------------------------------------------------------------------------*/ diff --git a/engines/ultima/shared/core/map.h b/engines/ultima/shared/core/map.h index a713a6a4527..85e3969c992 100644 --- a/engines/ultima/shared/core/map.h +++ b/engines/ultima/shared/core/map.h @@ -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 _widgets; // Party, monsteres, transports, etc. Common::Array _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; } /** diff --git a/engines/ultima/ultima.cpp b/engines/ultima/ultima.cpp deleted file mode 100644 index a5667759e2c..00000000000 --- a/engines/ultima/ultima.cpp +++ /dev/null @@ -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 diff --git a/engines/ultima/ultima1/actions/move.cpp b/engines/ultima/ultima1/actions/move.cpp index fc17945b1ff..830ed09c5e1 100644 --- a/engines/ultima/ultima1/actions/move.cpp +++ b/engines/ultima/ultima1/actions/move.cpp @@ -53,8 +53,8 @@ bool Move::MoveMsg(CMoveMsg &msg) { break; } } else { - Widgets::Transport *transport = dynamic_cast(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); diff --git a/engines/ultima/ultima1/map/map.cpp b/engines/ultima/ultima1/map/map.cpp index ccdf5299207..2da081e4fae 100644 --- a/engines/ultima/ultima1/map/map.cpp +++ b/engines/ultima/ultima1/map/map.cpp @@ -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()); diff --git a/engines/ultima/ultima1/map/map_city_castle.cpp b/engines/ultima/ultima1/map/map_city_castle.cpp index 769923c6a69..7b0c9fe5754 100644 --- a/engines/ultima/ultima1/map/map_city_castle.cpp +++ b/engines/ultima/ultima1/map/map_city_castle.cpp @@ -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 diff --git a/engines/ultima/ultima1/map/map_dungeon.cpp b/engines/ultima/ultima1/map/map_dungeon.cpp index 9aa7a9ef05b..470896ee54d 100644 --- a/engines/ultima/ultima1/map/map_dungeon.cpp +++ b/engines/ultima/ultima1/map/map_dungeon.cpp @@ -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); } diff --git a/engines/ultima/ultima1/map/map_overworld.cpp b/engines/ultima/ultima1/map/map_overworld.cpp index 18eabe84f4b..d009f5a8c17 100644 --- a/engines/ultima/ultima1/map/map_overworld.cpp +++ b/engines/ultima/ultima1/map/map_overworld.cpp @@ -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) diff --git a/engines/ultima/ultima1/widgets/bard.cpp b/engines/ultima/ultima1/widgets/bard.cpp index 78fa40880dd..8456188cd8a 100644 --- a/engines/ultima/ultima1/widgets/bard.cpp +++ b/engines/ultima/ultima1/widgets/bard.cpp @@ -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 diff --git a/engines/ultima/ultima1/widgets/dungeon_monster.cpp b/engines/ultima/ultima1/widgets/dungeon_monster.cpp index 138683a0da6..781934d0494 100644 --- a/engines/ultima/ultima1/widgets/dungeon_monster.cpp +++ b/engines/ultima/ultima1/widgets/dungeon_monster.cpp @@ -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(_game); - Point playerPos = _map->_currentTransport->_position; + Point playerPos = _map->_playerWidget->_position; //Point delta = playerPos - _position; Shared::Character *c = _game->_party._currentCharacter; uint threshold, damage; diff --git a/engines/ultima/ultima1/widgets/guard.cpp b/engines/ultima/ultima1/widgets/guard.cpp index 2198643e6b4..e4613564de8 100644 --- a/engines/ultima/ultima1/widgets/guard.cpp +++ b/engines/ultima/ultima1/widgets/guard.cpp @@ -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) diff --git a/engines/ultima/ultima1/widgets/overworld_monster.cpp b/engines/ultima/ultima1/widgets/overworld_monster.cpp index aaf62db4965..b23ac64d1d6 100644 --- a/engines/ultima/ultima1/widgets/overworld_monster.cpp +++ b/engines/ultima/ultima1/widgets/overworld_monster.cpp @@ -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(_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; diff --git a/engines/ultima/ultima1/widgets/princess.cpp b/engines/ultima/ultima1/widgets/princess.cpp index 9f031c68336..16e2aa65ac1 100644 --- a/engines/ultima/ultima1/widgets/princess.cpp +++ b/engines/ultima/ultima1/widgets/princess.cpp @@ -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; diff --git a/engines/ultima/ultima1/widgets/transport.cpp b/engines/ultima/ultima1/widgets/transport.cpp index 5e086fd7916..8eb8a3bb9c7 100644 --- a/engines/ultima/ultima1/widgets/transport.cpp +++ b/engines/ultima/ultima1/widgets/transport.cpp @@ -42,30 +42,7 @@ Map::Ultima1Map::MapBase *Transport::getMap() const { /*-------------------------------------------------------------------*/ uint TransportOnFoot::getTileNum() const { - Map::Ultima1Map::MapBase *map = getMap(); - return dynamic_cast(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 diff --git a/engines/ultima/ultima1/widgets/transport.h b/engines/ultima/ultima1/widgets/transport.h index 63b5704ed1e..9cb047231f6 100644 --- a/engines/ultima/ultima1/widgets/transport.h +++ b/engines/ultima/ultima1/widgets/transport.h @@ -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 diff --git a/engines/ultima/ultima1/widgets/urban_player.cpp b/engines/ultima/ultima1/widgets/urban_player.cpp new file mode 100644 index 00000000000..aaf455bfa53 --- /dev/null +++ b/engines/ultima/ultima1/widgets/urban_player.cpp @@ -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 diff --git a/engines/ultima/ultima1/widgets/urban_player.h b/engines/ultima/ultima1/widgets/urban_player.h new file mode 100644 index 00000000000..4e6938b56e7 --- /dev/null +++ b/engines/ultima/ultima1/widgets/urban_player.h @@ -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