diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/engine.cpp | 123 | ||||
-rw-r--r-- | src/engine.h | 64 | ||||
-rw-r--r-- | src/flooritemmanager.cpp | 14 | ||||
-rw-r--r-- | src/flooritemmanager.h | 6 | ||||
-rw-r--r-- | src/game.cpp | 104 | ||||
-rw-r--r-- | src/game.h | 39 | ||||
-rw-r--r-- | src/gui/debugwindow.cpp | 21 | ||||
-rw-r--r-- | src/gui/debugwindow.h | 1 | ||||
-rw-r--r-- | src/gui/setup_video.cpp | 4 | ||||
-rw-r--r-- | src/main.cpp | 2 | ||||
-rw-r--r-- | src/net/ea/itemhandler.cpp | 25 | ||||
-rw-r--r-- | src/net/ea/playerhandler.cpp | 16 | ||||
-rw-r--r-- | src/net/manaserv/itemhandler.cpp | 4 | ||||
-rw-r--r-- | src/net/manaserv/playerhandler.cpp | 10 |
16 files changed, 172 insertions, 265 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 94ad4d6c..fbf17f49 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -408,8 +408,6 @@ SET(SRCS effectmanager.h emoteshortcut.cpp emoteshortcut.h - engine.cpp - engine.h equipment.h flooritem.cpp flooritem.h diff --git a/src/Makefile.am b/src/Makefile.am index 0a343a78..3b9b711a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -313,8 +313,6 @@ mana_SOURCES = gui/widgets/avatar.cpp \ effectmanager.h \ emoteshortcut.cpp \ emoteshortcut.h \ - engine.cpp \ - engine.h \ equipment.h \ flooritem.cpp \ flooritem.h \ diff --git a/src/engine.cpp b/src/engine.cpp deleted file mode 100644 index 65a9ed83..00000000 --- a/src/engine.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * The Mana World - * Copyright (C) 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * 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 - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "engine.h" - -#include "beingmanager.h" -#include "flooritemmanager.h" -#include "game.h" -#include "localplayer.h" -#include "log.h" -#include "map.h" -#include "particle.h" -#include "sound.h" - -#include "gui/gui.h" -#include "gui/minimap.h" -#include "gui/okdialog.h" -#include "gui/viewport.h" - -#include "net/gamehandler.h" -#include "net/net.h" - -#include "resources/mapreader.h" -#include "resources/monsterdb.h" -#include "resources/resourcemanager.h" - -#include "utils/gettext.h" -#include "utils/stringutils.h" - -#include <assert.h> - -Engine::Engine(): - mCurrentMap(0), mMapName("") -{ -} - -Engine::~Engine() -{ - delete mCurrentMap; - map_path = ""; -} - -void Engine::changeMap(const std::string &mapPath) -{ - // Clean up floor items, beings and particles - floorItemManager->clear(); - beingManager->clear(); - - // Close the popup menu on map change so that invalid options can't be - // executed. - viewport->closePopupMenu(); - - // Unset the map of the player so that its particles are cleared before - // being deleted in the next step - if (player_node) - player_node->setMap(0); - - particleEngine->clear(); - - mMapName = mapPath; - - // Store full map path in global var - map_path = "maps/" + mapPath + ".tmx"; - ResourceManager *resman = ResourceManager::getInstance(); - if (!resman->exists(map_path)) - map_path += ".gz"; - - // Attempt to load the new map - Map *newMap = MapReader::readMap(map_path); - - if (!newMap) - { - logger->log("Error while loading %s", map_path.c_str()); - new OkDialog(_("Could Not Load Map"), - strprintf(_("Error while loading %s"), map_path.c_str())); - } - - // Notify the minimap and beingManager about the map change - minimap->setMap(newMap); - beingManager->setMap(newMap); - particleEngine->setMap(newMap); - viewport->setMap(newMap); - - // Initialize map-based particle effects - if (newMap) - newMap->initializeParticleEffects(particleEngine); - - // Start playing new music file when necessary - std::string oldMusic = mCurrentMap ? mCurrentMap->getMusicFile() : ""; - std::string newMusic = newMap ? newMap->getMusicFile() : ""; - if (newMusic != oldMusic) - sound.playMusic(newMusic); - - delete mCurrentMap; - mCurrentMap = newMap; - - Net::getGameHandler()->mapLoaded(mapPath); -} - -void Engine::logic() -{ - beingManager->logic(); - particleEngine->update(); - gui->logic(); -} diff --git a/src/engine.h b/src/engine.h deleted file mode 100644 index 290cac3c..00000000 --- a/src/engine.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * The Mana World - * Copyright (C) 2004 The Mana World Development Team - * - * This file is part of The Mana World. - * - * 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 - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _ENGINE_H -#define _ENGINE_H - -#include <string> - -class Map; - -/** - * Game engine. Actually hardly does anything anymore except keeping track of - * the current map. - */ -class Engine -{ - public: - Engine(); - - ~Engine(); - - /** - * Returns the currently active map. - */ - Map *getCurrentMap() { return mCurrentMap; } - - const std::string &getCurrentMapName() { return mMapName; } - - /** - * Sets the currently active map. - */ - void changeMap(const std::string &mapName); - - /** - * Performs engine logic. This method is called 100 times per second. - */ - void logic(); - - private: - Map *mCurrentMap; - std::string mMapName; -}; - -extern Engine *engine; - -#endif diff --git a/src/flooritemmanager.cpp b/src/flooritemmanager.cpp index 9bfd02ae..72735d74 100644 --- a/src/flooritemmanager.cpp +++ b/src/flooritemmanager.cpp @@ -22,6 +22,8 @@ #include "flooritemmanager.h" #include "flooritem.h" +#include "game.h" + #include "utils/dtor.h" FloorItemManager::~FloorItemManager() @@ -29,9 +31,9 @@ FloorItemManager::~FloorItemManager() clear(); } -FloorItem *FloorItemManager::create(int id, int itemId, - int x, int y, Map *map) +FloorItem *FloorItemManager::create(int id, int itemId, int x, int y) { + Map *map = Game::instance()->getCurrentMap(); FloorItem *floorItem = new FloorItem(id, itemId, x, y, map); mFloorItems.push_back(floorItem); return floorItem; @@ -49,9 +51,9 @@ void FloorItemManager::clear() mFloorItems.clear(); } -FloorItem *FloorItemManager::findById(int id) +FloorItem *FloorItemManager::findById(int id) const { - FloorItemIterator i; + FloorItems::const_iterator i; for (i = mFloorItems.begin(); i != mFloorItems.end(); i++) { if ((*i)->getId() == id) @@ -63,9 +65,9 @@ FloorItem *FloorItemManager::findById(int id) return NULL; } -FloorItem *FloorItemManager::findByCoordinates(int x, int y) +FloorItem *FloorItemManager::findByCoordinates(int x, int y) const { - FloorItemIterator i; + FloorItems::const_iterator i; for (i = mFloorItems.begin(); i != mFloorItems.end(); i++) { if ((*i)->getX() == x && (*i)->getY() == y) diff --git a/src/flooritemmanager.h b/src/flooritemmanager.h index 704b39fd..725eb10c 100644 --- a/src/flooritemmanager.h +++ b/src/flooritemmanager.h @@ -32,14 +32,14 @@ class FloorItemManager public: ~FloorItemManager(); - FloorItem* create(int id, int itemId, int x, int y, Map *map); + FloorItem *create(int id, int itemId, int x, int y); void destroy(FloorItem *item); void clear(); - FloorItem* findById(int id); - FloorItem* findByCoordinates(int x, int y); + FloorItem *findById(int id) const; + FloorItem *findByCoordinates(int x, int y) const; private: typedef std::list<FloorItem*> FloorItems; diff --git a/src/game.cpp b/src/game.cpp index 83b4708b..1df03d55 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1,6 +1,6 @@ /* * The Mana World - * Copyright (C) 2004 The Mana World Development Team + * Copyright (C) 2004-2010 The Mana World Development Team * * This file is part of The Mana World. * @@ -27,7 +27,6 @@ #include "configuration.h" #include "effectmanager.h" #include "emoteshortcut.h" -#include "engine.h" #include "flooritemmanager.h" #include "graphics.h" #include "itemshortcut.h" @@ -83,6 +82,8 @@ #include "net/playerhandler.h" #include "resources/imagewriter.h" +#include "resources/mapreader.h" +#include "resources/resourcemanager.h" #include "utils/gettext.h" @@ -102,7 +103,6 @@ std::string map_path; volatile int tick_time; volatile int fps = 0, frame = 0; -Engine *engine = NULL; Joystick *joystick = NULL; OkDialog *weightNotice = NULL; @@ -196,8 +196,6 @@ int get_elapsed_time(int start_time) */ static void initEngines() { - engine = new Engine; - beingManager = new BeingManager; commandHandler = new CommandHandler; floorItemManager = new FloorItemManager; @@ -285,10 +283,16 @@ static void destroyGuiWindows() del_0(specialsWindow); } +Game *Game::mInstance = 0; + Game::Game(): mLastTarget(Being::UNKNOWN), - mLogicCounterId(0), mSecondsCounterId(0) + mLogicCounterId(0), mSecondsCounterId(0), + mCurrentMap(0), mMapName("") { + assert(!mInstance); + mInstance = this; + disconnectedDialog = NULL; createGuiWindows(); @@ -308,7 +312,7 @@ Game::Game(): // with the GPMSG_PLAYER_MAP_CHANGE flag. map_path = map_path.substr(0, map_path.rfind(".")); if (!map_path.empty()) - engine->changeMap(map_path); + changeMap(map_path); // Initialize beings beingManager->setPlayer(player_node); @@ -350,9 +354,12 @@ Game::~Game() delete commandHandler; delete joystick; delete particleEngine; - delete engine; viewport->setMap(NULL); + + delete mCurrentMap; + map_path = ""; + player_node = NULL; beingManager = NULL; floorItemManager = NULL; @@ -360,6 +367,8 @@ Game::~Game() SDL_RemoveTimer(mLogicCounterId); SDL_RemoveTimer(mSecondsCounterId); + + mInstance = 0; } void setScreenshotDir(const std::string &dir) @@ -422,15 +431,15 @@ static bool saveScreenshot() void Game::optionChanged(const std::string &name) { - int fpsLimit = (int) config.getValue("fpslimit", 60); - + // Calculate the new minimum time per frame based on the FPS limit + const int fpsLimit = (int) config.getValue("fpslimit", 60); mMinFrameTime = fpsLimit ? 1000 / fpsLimit : 0; // Reset draw time to current time mDrawTime = tick_time * MILLISECONDS_IN_A_TICK; } -void Game::logic() +void Game::exec() { // mDrawTime has a higher granularity than gameTime in order to be able to // work with minimum frame durations in milliseconds. @@ -439,14 +448,17 @@ void Game::logic() while (state == STATE_GAME) { - if (Map *map = engine->getCurrentMap()) - map->update(get_elapsed_time(gameTime)); + if (mCurrentMap) + mCurrentMap->update(get_elapsed_time(gameTime)); // Handle all necessary game logic while (get_elapsed_time(gameTime) > 0) { handleInput(); - engine->logic(); + beingManager->logic(); + particleEngine->update(); + gui->logic(); + gameTime++; } @@ -500,6 +512,9 @@ void Game::logic() } } +/** + * The MONSTER input handling method. + */ void Game::handleInput() { if (joystick) @@ -1058,3 +1073,64 @@ void Game::handleInput() } } } + +/** + * Changes the currently active map. Should only be called while the game is + * running. + */ +void Game::changeMap(const std::string &mapPath) +{ + // Clean up floor items, beings and particles + floorItemManager->clear(); + beingManager->clear(); + + // Close the popup menu on map change so that invalid options can't be + // executed. + viewport->closePopupMenu(); + + // Unset the map of the player so that its particles are cleared before + // being deleted in the next step + if (player_node) + player_node->setMap(0); + + particleEngine->clear(); + + mMapName = mapPath; + + // Store full map path in global var + map_path = "maps/" + mapPath + ".tmx"; + ResourceManager *resman = ResourceManager::getInstance(); + if (!resman->exists(map_path)) + map_path += ".gz"; + + // Attempt to load the new map + Map *newMap = MapReader::readMap(map_path); + + if (!newMap) + { + logger->log("Error while loading %s", map_path.c_str()); + new OkDialog(_("Could Not Load Map"), + strprintf(_("Error while loading %s"), map_path.c_str())); + } + + // Notify the minimap and beingManager about the map change + minimap->setMap(newMap); + beingManager->setMap(newMap); + particleEngine->setMap(newMap); + viewport->setMap(newMap); + + // Initialize map-based particle effects + if (newMap) + newMap->initializeParticleEffects(particleEngine); + + // Start playing new music file when necessary + std::string oldMusic = mCurrentMap ? mCurrentMap->getMusicFile() : ""; + std::string newMusic = newMap ? newMap->getMusicFile() : ""; + if (newMusic != oldMusic) + sound.playMusic(newMusic); + + delete mCurrentMap; + mCurrentMap = newMap; + + Net::getGameHandler()->mapLoaded(mapPath); +} @@ -1,6 +1,6 @@ /* * The Mana World - * Copyright (C) 2004 The Mana World Development Team + * Copyright (C) 2004-2010 The Mana World Development Team * * This file is part of The Mana World. * @@ -30,26 +30,54 @@ extern volatile int fps; extern volatile int tick_time; extern const int MILLISECONDS_IN_A_TICK; +class Map; class WindowMenu; +/** + * The main class responsible for running the game. + */ class Game : public ConfigListener { public: + /** + * Constructs the game, creating all the managers, handlers, engines + * and GUI windows that make up the game. + */ Game(); + /** + * Destructor, cleans up the game. + */ ~Game(); - void logic(); + /** + * Provides access to the game instance. + */ + static Game *instance() { return mInstance; } + + /** + * This method runs the game. It returns when the game stops. + */ + void exec(); void handleInput(); void optionChanged(const std::string &name); + void changeMap(const std::string &mapName); + + /** + * Returns the currently active map. + */ + Map *getCurrentMap() { return mCurrentMap; } + + const std::string &getCurrentMapName() { return mMapName; } + private: /** Used to determine whether to draw the next frame. */ int mDrawTime; - /** The minimum frame time (used for frame limiting). */ + /** The minimum frame time in ms (used for frame limiting). */ int mMinFrameTime; int mLastTarget; @@ -58,6 +86,11 @@ class Game : public ConfigListener SDL_TimerID mSecondsCounterId; WindowMenu *mWindowMenu; + + Map *mCurrentMap; + std::string mMapName; + + static Game *mInstance; }; /** diff --git a/src/gui/debugwindow.cpp b/src/gui/debugwindow.cpp index 2b5616cb..f4f2fd14 100644 --- a/src/gui/debugwindow.cpp +++ b/src/gui/debugwindow.cpp @@ -21,7 +21,6 @@ #include "gui/debugwindow.h" -#include "engine.h" #include "game.h" #include "particle.h" #include "main.h" @@ -93,24 +92,16 @@ void DebugWindow::logic() mFPSLabel->setCaption(strprintf(mFPSText.c_str(), fps)); - mTileMouseLabel->setCaption(strprintf(_("Cursor: (%d, %d)"), mouseTileX, + mTileMouseLabel->setCaption(strprintf(_("Cursor: (%d, %d)"), + mouseTileX, mouseTileY)); - Map *currentMap = engine->getCurrentMap(); - if (currentMap) + if (const Map *map = Game::instance()->getCurrentMap()) { // TODO: Add gettext support below - const std::string music = - "Music: " + currentMap->getProperty("music"); - mMusicFileLabel->setCaption(music); - - const std::string minimap = - "Minimap: " + currentMap->getProperty("minimap"); - mMinimapLabel->setCaption(minimap); - - const std::string map = - "Map: " + currentMap->getProperty("_filename"); - mMapLabel->setCaption(map); + mMusicFileLabel->setCaption("Music: " + map->getProperty("music")); + mMinimapLabel->setCaption("Minimap: " + map->getProperty("minimap")); + mMapLabel->setCaption("Map: " + map->getProperty("_filename")); } mParticleCountLabel->setCaption(strprintf(_("Particle count: %d"), diff --git a/src/gui/debugwindow.h b/src/gui/debugwindow.h index 50a5fc06..1ef32e02 100644 --- a/src/gui/debugwindow.h +++ b/src/gui/debugwindow.h @@ -50,7 +50,6 @@ class DebugWindow : public Window Label *mParticleCountLabel, *mParticleDetailLabel; Label *mAmbientDetailLabel; - std::string mFPSText; }; diff --git a/src/gui/setup_video.cpp b/src/gui/setup_video.cpp index aaa3ea35..f5bff9ba 100644 --- a/src/gui/setup_video.cpp +++ b/src/gui/setup_video.cpp @@ -22,7 +22,7 @@ #include "gui/setup_video.h" #include "configuration.h" -#include "engine.h" +#include "game.h" #include "graphics.h" #include "localplayer.h" #include "log.h" @@ -502,7 +502,7 @@ void Setup_Video::action(const gcn::ActionEvent &event) mParticleEffectsCheckBox->isSelected()); Particle::enabled = mParticleEffectsCheckBox->isSelected(); - if (engine) + if (Game::instance()) { new OkDialog(_("Particle Effect Settings Changed."), _("Changes will take effect on map change.")); diff --git a/src/main.cpp b/src/main.cpp index 6454b123..b1ab8a68 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1117,7 +1117,7 @@ int main(int argc, char *argv[]) logger->log("State: GAME"); game = new Game; - game->logic(); + game->exec(); delete game; game = 0; diff --git a/src/net/ea/itemhandler.cpp b/src/net/ea/itemhandler.cpp index 2f65c064..8b8f2b22 100644 --- a/src/net/ea/itemhandler.cpp +++ b/src/net/ea/itemhandler.cpp @@ -21,7 +21,6 @@ #include "net/ea/itemhandler.h" -#include "engine.h" #include "flooritemmanager.h" #include "net/messagein.h" @@ -43,28 +42,24 @@ ItemHandler::ItemHandler() void ItemHandler::handleMessage(Net::MessageIn &msg) { - Uint32 id; - Uint16 x, y; - int itemId; - switch (msg.getId()) { case SMSG_ITEM_VISIBLE: case SMSG_ITEM_DROPPED: - id = msg.readInt32(); - itemId = msg.readInt16(); - msg.readInt8(); // identify flag - x = msg.readInt16(); - y = msg.readInt16(); - msg.skip(4); // amount,subX,subY / subX,subY,amount + { + int id = msg.readInt32(); + int itemId = msg.readInt16(); + msg.readInt8(); // identify flag + int x = msg.readInt16(); + int y = msg.readInt16(); + msg.skip(4); // amount,subX,subY / subX,subY,amount - floorItemManager->create(id, itemId, x, y, engine->getCurrentMap()); + floorItemManager->create(id, itemId, x, y); + } break; case SMSG_ITEM_REMOVE: - FloorItem *item; - item = floorItemManager->findById(msg.readInt32()); - if (item) + if (FloorItem *item = floorItemManager->findById(msg.readInt32())) floorItemManager->destroy(item); break; } diff --git a/src/net/ea/playerhandler.cpp b/src/net/ea/playerhandler.cpp index 156e8b26..0c290815 100644 --- a/src/net/ea/playerhandler.cpp +++ b/src/net/ea/playerhandler.cpp @@ -21,7 +21,7 @@ #include "net/ea/playerhandler.h" -#include "engine.h" +#include "game.h" #include "localplayer.h" #include "log.h" #include "npc.h" @@ -179,9 +179,8 @@ void PlayerHandler::handleMessage(Net::MessageIn &msg) case SMSG_PLAYER_WARP: { std::string mapPath = msg.readString(16); - bool nearby; - Uint16 x = msg.readInt16(); - Uint16 y = msg.readInt16(); + int x = msg.readInt16(); + int y = msg.readInt16(); logger->log("Warping to %s (%d, %d)", mapPath.c_str(), x, y); @@ -191,17 +190,20 @@ void PlayerHandler::handleMessage(Net::MessageIn &msg) */ player_node->stopAttack(); - nearby = (engine->getCurrentMapName() == mapPath); + Game *game = Game::instance(); + + const std::string ¤tMap = game->getCurrentMapName(); + bool sameMap = (currentMap == mapPath); // Switch the actual map, deleting the previous one if necessary mapPath = mapPath.substr(0, mapPath.rfind(".")); - engine->changeMap(mapPath); + game->changeMap(mapPath); float scrollOffsetX = 0.0f; float scrollOffsetY = 0.0f; /* Scroll if neccessary */ - if (!nearby + if (!sameMap || (abs(x - player_node->getTileX()) > MAP_TELEPORT_SCROLL_DISTANCE) || (abs(y - player_node->getTileY()) > MAP_TELEPORT_SCROLL_DISTANCE)) { diff --git a/src/net/manaserv/itemhandler.cpp b/src/net/manaserv/itemhandler.cpp index 3d89487c..79a0caf0 100644 --- a/src/net/manaserv/itemhandler.cpp +++ b/src/net/manaserv/itemhandler.cpp @@ -21,11 +21,9 @@ #include "net/manaserv/itemhandler.h" -#include "engine.h" #include "flooritemmanager.h" #include "net/manaserv/protocol.h" - #include "net/manaserv/messagein.h" namespace ManaServ { @@ -56,7 +54,7 @@ void ItemHandler::handleMessage(Net::MessageIn &msg) if (itemId) { - floorItemManager->create(id, itemId, x / 32, y / 32, engine->getCurrentMap()); + floorItemManager->create(id, itemId, x / 32, y / 32); } else if (FloorItem *item = floorItemManager->findById(id)) { diff --git a/src/net/manaserv/playerhandler.cpp b/src/net/manaserv/playerhandler.cpp index 9225b765..624a442a 100644 --- a/src/net/manaserv/playerhandler.cpp +++ b/src/net/manaserv/playerhandler.cpp @@ -23,7 +23,7 @@ #include "net/manaserv/beinghandler.h" #include "effectmanager.h" -#include "engine.h" +#include "game.h" #include "localplayer.h" #include "log.h" #include "particle.h" @@ -304,12 +304,14 @@ void PlayerHandler::handleMapChangeMessage(Net::MessageIn &msg) const std::string mapName = msg.readString(); const unsigned short x = msg.readInt16(); const unsigned short y = msg.readInt16(); - const bool nearby = (engine->getCurrentMapName() == mapName); + + Game *game = Game::instance(); + const bool sameMap = (game->getCurrentMapName() == mapName); logger->log("Changing map to %s (%d, %d)", mapName.c_str(), x, y); // Switch the actual map, deleting the previous one - engine->changeMap(mapName); + game->changeMap(mapName); current_npc = 0; @@ -318,7 +320,7 @@ void PlayerHandler::handleMapChangeMessage(Net::MessageIn &msg) float scrollOffsetY = 0.0f; /* Scroll if neccessary */ - if (!nearby + if (!sameMap || (abs(x - (int) playerPos.x) > MAP_TELEPORT_SCROLL_DISTANCE) || (abs(y - (int) playerPos.y) > MAP_TELEPORT_SCROLL_DISTANCE)) { |