diff options
Diffstat (limited to 'src/game.cpp')
-rw-r--r-- | src/game.cpp | 104 |
1 files changed, 90 insertions, 14 deletions
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); +} |