diff options
Diffstat (limited to 'src/game.cpp')
-rw-r--r-- | src/game.cpp | 238 |
1 files changed, 128 insertions, 110 deletions
diff --git a/src/game.cpp b/src/game.cpp index 512b8b5f..af9c2c39 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -21,14 +21,15 @@ #include "game.h" -#include "beingmanager.h" +#include "actorspritemanager.h" +#include "actorsprite.h" #include "channelmanager.h" #include "client.h" #include "commandhandler.h" #include "configuration.h" #include "effectmanager.h" +#include "event.h" #include "emoteshortcut.h" -#include "flooritemmanager.h" #include "graphics.h" #include "itemshortcut.h" #include "joystick.h" @@ -36,7 +37,6 @@ #include "localplayer.h" #include "log.h" #include "map.h" -#include "npc.h" #include "particle.h" #include "playerrelations.h" #include "sound.h" @@ -52,7 +52,6 @@ #include "gui/minimap.h" #include "gui/ministatus.h" #include "gui/npcdialog.h" -#include "gui/npcpostdialog.h" #include "gui/okdialog.h" #include "gui/outfitwindow.h" #include "gui/quitdialog.h" @@ -97,7 +96,6 @@ Joystick *joystick = NULL; OkDialog *weightNotice = NULL; OkDialog *deathNotice = NULL; QuitDialog *quitDialog = NULL; -OkDialog *disconnectedDialog = NULL; ChatWindow *chatWindow; StatusWindow *statusWindow; @@ -115,8 +113,7 @@ OutfitWindow *outfitWindow; SpecialsWindow *specialsWindow; SocialWindow *socialWindow; -BeingManager *beingManager = NULL; -FloorItemManager *floorItemManager = NULL; +ActorSpriteManager *actorSpriteManager = NULL; ChannelManager *channelManager = NULL; CommandHandler *commandHandler = NULL; Particle *particleEngine = NULL; @@ -130,14 +127,17 @@ ChatTab *localChatTab = NULL; */ static void initEngines() { - beingManager = new BeingManager; + Event::trigger(Event::GameChannel, Event::EnginesInitializing); + + actorSpriteManager = new ActorSpriteManager; commandHandler = new CommandHandler; - floorItemManager = new FloorItemManager; channelManager = new ChannelManager; effectManager = new EffectManager; particleEngine = new Particle(NULL); particleEngine->setupEngine(); + + Event::trigger(Event::GameChannel, Event::EnginesInitialized); } /** @@ -145,6 +145,8 @@ static void initEngines() */ static void createGuiWindows() { + Event::trigger(Event::GameChannel, Event::GuiWindowsLoading); + setupWindow->clearWindowsForReset(); // Create dialogs @@ -152,9 +154,17 @@ static void createGuiWindows() minimap = new Minimap; chatWindow = new ChatWindow; tradeWindow = new TradeWindow; - equipmentWindow = new EquipmentWindow(player_node->mEquipment.get()); + switch (Net::getNetworkType()) + { + case ServerInfo::TMWATHENA: + case ServerInfo::MANASERV: + default: + equipmentWindow = + new TmwAthena::TaEquipmentWindow(PlayerInfo::getEquipment()); + break; + } statusWindow = new StatusWindow; - inventoryWindow = new InventoryWindow(player_node->getInventory()); + inventoryWindow = new InventoryWindow(PlayerInfo::getInventory()); skillDialog = new SkillDialog; helpWindow = new HelpWindow; debugWindow = new DebugWindow; @@ -168,12 +178,9 @@ static void createGuiWindows() localChatTab = new ChatTab(_("General")); - if (config.getValue("logToChat", 0)) - { - logger->setChatWindow(chatWindow); - } + NpcDialog::setup(); - Net::getGeneralHandler()->guiWindowsLoaded(); + Event::trigger(Event::GameChannel, Event::GuiWindowsLoaded); } #define del_0(X) { delete X; X = 0; } @@ -183,8 +190,8 @@ static void createGuiWindows() */ static void destroyGuiWindows() { - Net::getGeneralHandler()->guiWindowsUnloaded(); - logger->setChatWindow(NULL); + Event::trigger(Event::GameChannel, Event::GuiWindowsUnloading); + del_0(localChatTab) // Need to do this first, so it can remove itself del_0(chatWindow) del_0(statusWindow) @@ -201,19 +208,22 @@ static void destroyGuiWindows() del_0(outfitWindow) del_0(specialsWindow) del_0(socialWindow) + + Event::trigger(Event::NpcChannel, Event::CloseAll); // Cleanup remaining NPC dialogs + + Event::trigger(Event::GameChannel, Event::GuiWindowsUnloaded); } Game *Game::mInstance = 0; Game::Game(): - mLastTarget(Being::UNKNOWN), - mCurrentMap(0), mMapName("") + mLastTarget(ActorSprite::UNKNOWN), + mDisconnected(false), + mCurrentMap(0) { assert(!mInstance); mInstance = this; - disconnectedDialog = NULL; - // Create the viewport viewport = new Viewport; viewport->setDimension(gcn::Rectangle(0, 0, graphics->getWidth(), @@ -230,21 +240,8 @@ Game::Game(): initEngines(); - Net::getGameHandler()->inGame(); - // Initialize beings - beingManager->setPlayer(player_node); - - /* - * To prevent the server from sending data before the client - * has initialized, I've modified it to wait for a "ping" - * from the client to complete its initialization - * - * Note: This only affects the latest eAthena version. This - * packet is handled by the older version, but its response - * is ignored by the client - */ - Net::getGameHandler()->ping(tick_time); + actorSpriteManager->setPlayer(player_node); Joystick::init(); // TODO: The user should be able to choose which one to use @@ -253,18 +250,21 @@ Game::Game(): joystick = new Joystick(0); setupWindow->setInGame(true); + + Event::trigger(Event::GameChannel, Event::Constructed); } Game::~Game() { + Event::trigger(Event::GameChannel, Event::Destructing); + delete mWindowMenu; destroyGuiWindows(); - del_0(beingManager) + del_0(actorSpriteManager) if (Client::getState() != STATE_CHANGE_MAP) del_0(player_node) - del_0(floorItemManager) del_0(channelManager) del_0(commandHandler) del_0(joystick) @@ -273,6 +273,8 @@ Game::~Game() del_0(mCurrentMap) mInstance = 0; + + Event::trigger(Event::GameChannel, Event::Destructed); } static bool saveScreenshot() @@ -284,7 +286,7 @@ static bool saveScreenshot() if (showip) { player_node->setShowIp(false); - beingManager->updatePlayerNames(); + actorSpriteManager->updatePlayerNames(); gui->draw(); } @@ -293,7 +295,7 @@ static bool saveScreenshot() if (showip) { player_node->setShowIp(true); - beingManager->updatePlayerNames(); + actorSpriteManager->updatePlayerNames(); } // Search for an unused screenshot name @@ -311,7 +313,8 @@ static bool saveScreenshot() screenshotDirectory = std::string(PHYSFS_getUserDir()); } - do { + do + { screenshotCount++; filenameSuffix.str(""); filename.str(""); @@ -322,7 +325,8 @@ static bool saveScreenshot() testExists.open(filename.str().c_str(), std::ios::in); found = !testExists.is_open(); testExists.close(); - } while (!found); + } + while (!found); const bool success = ImageWriter::writePNG(screenshot, filename.str()); @@ -331,11 +335,11 @@ static bool saveScreenshot() std::stringstream chatlogentry; // TODO: Make it one complete gettext string below chatlogentry << _("Screenshot saved as ") << filenameSuffix.str(); - localChatTab->chatLog(chatlogentry.str(), BY_SERVER); + SERVER_NOTICE(chatlogentry.str()) } else { - localChatTab->chatLog(_("Saving screenshot failed!"), BY_SERVER); + SERVER_NOTICE(_("Saving screenshot failed!")) logger->log("Error: could not save screenshot."); } @@ -349,7 +353,8 @@ void Game::logic() handleInput(); // Handle all necessary game logic - beingManager->logic(); + ActorSprite::actorLogic(); + actorSpriteManager->logic(); particleEngine->update(); if (mCurrentMap) mCurrentMap->update(); @@ -357,7 +362,7 @@ void Game::logic() cur_time = time(NULL); // Handle network stuff - if (!Net::getGameHandler()->isConnected()) + if (!Net::getGameHandler()->isConnected() && !mDisconnected) { if (Client::getState() == STATE_CHANGE_MAP) return; // Not a problem here @@ -366,14 +371,44 @@ void Game::logic() return; // Disconnect gets handled by STATE_ERROR errorMessage = _("The connection to the server was lost."); + Client::instance()->showOkDialog(_("Network Error"), + errorMessage, + STATE_CHOOSE_SERVER); + mDisconnected = true; + } +} - if (!disconnectedDialog) +/** + * handle item pick up case. + */ +static void handleItemPickUp() +{ + int x = player_node->getTileX(); + int y = player_node->getTileY(); + + // Let's look for items around until you find one. + bool found = false; + for (int xX = x - 1; xX < x + 2; ++xX) + { + for (int yY = y - 1; yY < y + 2; ++yY) { - disconnectedDialog = new OkDialog(_("Network Error"), - errorMessage); - disconnectedDialog->addActionListener(&errorListener); - disconnectedDialog->requestMoveToTop(); + FloorItem *item = actorSpriteManager->findItem(xX, yY); + if (item) + { + found = true; + player_node->pickUp(item); + + // We found it, so set the player + // direction accordingly, + player_node->lookAt( + player_node->getMap()->getTileCenter(xX, yY)); + + // Get out of the loops + break; + } } + if (found) + break; } } @@ -407,7 +442,7 @@ void Game::handleInput() // send straight to gui for certain windows if (quitDialog || TextDialog::isActive() || - NpcPostDialog::isActive()) + PlayerInfo::getNPCPostCount() > 0) { try { @@ -465,7 +500,8 @@ void Game::handleInput() } - if (!chatWindow->isInputFocused() || (event.key.keysym.mod & KMOD_ALT)) + if (!chatWindow->isInputFocused() || (event.key.keysym.mod & + KMOD_ALT)) { if (keyboard.isKeyActive(keyboard.KEY_PREV_CHAT_TAB)) { @@ -583,7 +619,7 @@ void Game::handleInput() break; } if (keyboard.isEnabled() && !chatWindow->isInputFocused() && - !NpcDialog::isAnyInputFocused()) + !NpcDialog::isAnyInputFocused() && !InventoryWindow::isAnyInputFocused()) { const int tKey = keyboard.getKeyIndex(event.key.keysym.sym); @@ -608,33 +644,7 @@ void Game::handleInput() { case KeyboardConfig::KEY_PICKUP: { - int x = player_node->getTileX(); - int y = player_node->getTileY(); - - FloorItem *item = - floorItemManager->findByCoordinates(x, y); - - // If none below the player, try the tile in front - // of the player - if (!item) - { - // Temporary until tile-based picking is - // removed. - switch (player_node->getSpriteDirection()) - { - case DIRECTION_UP : --y; break; - case DIRECTION_DOWN : ++y; break; - case DIRECTION_LEFT : --x; break; - case DIRECTION_RIGHT: ++x; break; - default: break; - } - - item = floorItemManager->findByCoordinates( - x, y); - } - - if (item) - player_node->pickUp(item); + handleItemPickUp(); used = true; } @@ -699,26 +709,17 @@ void Game::handleInput() saveScreenshot(); used = true; break; - case KeyboardConfig::KEY_PATHFIND: - // Find path to mouse (debug purpose) - viewport->toggleDebugPath(); - used = true; - break; case KeyboardConfig::KEY_TRADE: // Toggle accepting of incoming trade requests unsigned int deflt = player_relations.getDefault(); if (deflt & PlayerRelation::TRADE) { - localChatTab->chatLog( - _("Ignoring incoming trade requests"), - BY_SERVER); + SERVER_NOTICE(_("Ignoring incoming trade requests")) deflt &= ~PlayerRelation::TRADE; } else { - localChatTab->chatLog( - _("Accepting incoming trade requests"), - BY_SERVER); + SERVER_NOTICE(_("Accepting incoming trade requests")) deflt |= PlayerRelation::TRADE; } @@ -764,7 +765,7 @@ void Game::handleInput() return; // Moving player around - if (player_node->isAlive() && !NPC::isTalking() && + if (player_node->isAlive() && !PlayerInfo::isTalking() && !chatWindow->isInputFocused() && !quitDialog && !TextDialog::isActive()) { // Get the state of the keyboard keys @@ -835,8 +836,8 @@ void Game::handleInput() if (!player_node->getTarget()) { // Only auto target Monsters - target = beingManager->findNearestLivingBeing(player_node, - 20, Being::MONSTER); + target = actorSpriteManager->findNearestLivingBeing(player_node, + 20, ActorSprite::MONSTER); } player_node->attack(target, newTarget); } @@ -848,16 +849,16 @@ void Game::handleInput() (joystick && joystick->buttonPressed(3))) && !keyboard.isKeyActive(keyboard.KEY_TARGET)) { - Being::Type currentTarget = Being::UNKNOWN; + ActorSprite::Type currentTarget = ActorSprite::UNKNOWN; if (keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) || (joystick && joystick->buttonPressed(3))) - currentTarget = Being::MONSTER; + currentTarget = ActorSprite::MONSTER; else if (keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER)) - currentTarget = Being::PLAYER; + currentTarget = ActorSprite::PLAYER; else if (keyboard.isKeyActive(keyboard.KEY_TARGET_NPC)) - currentTarget = Being::NPC; + currentTarget = ActorSprite::NPC; - Being *target = beingManager->findNearestLivingBeing(player_node, + Being *target = actorSpriteManager->findNearestLivingBeing(player_node, 20, currentTarget); if (target && (target != player_node->getTarget() || @@ -869,7 +870,7 @@ void Game::handleInput() } else { - mLastTarget = Being::UNKNOWN; // Reset last target + mLastTarget = ActorSprite::UNKNOWN; // Reset last target } // Talk to the nearest NPC if 't' pressed @@ -880,8 +881,8 @@ void Game::handleInput() if (target) { - if (target->getType() == Being::NPC) - static_cast<NPC*>(target)->talk(); + if (target->canTalk()) + target->talkTo(); } } @@ -899,7 +900,7 @@ void Game::handleInput() const int x = player_node->getTileX(); const int y = player_node->getTileY(); - FloorItem *item = floorItemManager->findByCoordinates(x, y); + FloorItem *item = actorSpriteManager->findItem(x, y); if (item) player_node->pickUp(item); @@ -919,8 +920,7 @@ void Game::handleInput() void Game::changeMap(const std::string &mapPath) { // Clean up floor items, beings and particles - floorItemManager->clear(); - beingManager->clear(); + actorSpriteManager->clear(); // Close the popup menu on map change so that invalid options can't be // executed. @@ -953,7 +953,7 @@ void Game::changeMap(const std::string &mapPath) // Notify the minimap and beingManager about the map change minimap->setMap(newMap); - beingManager->setMap(newMap); + actorSpriteManager->setMap(newMap); particleEngine->setMap(newMap); viewport->setMap(newMap); @@ -967,13 +967,31 @@ void Game::changeMap(const std::string &mapPath) if (newMusic != oldMusic) { if (newMusic.empty()) - sound.stopMusic(); + sound.fadeOutMusic(); else - sound.playMusic(newMusic); + sound.fadeOutAndPlayMusic(newMusic); } delete mCurrentMap; mCurrentMap = newMap; - Net::getGameHandler()->mapLoaded(mapPath); + Event event(Event::MapLoaded); + event.setString("mapPath", mapPath); + event.trigger(Event::GameChannel); +} + +int Game::getCurrentTileWidth() const +{ + if (mCurrentMap) + return mCurrentMap->getTileWidth(); + + return DEFAULT_TILE_LENGTH; +} + +int Game::getCurrentTileHeight() const +{ + if (mCurrentMap) + return mCurrentMap->getTileHeight(); + + return DEFAULT_TILE_LENGTH; } |