diff options
Diffstat (limited to 'src/game.cpp')
-rw-r--r-- | src/game.cpp | 498 |
1 files changed, 356 insertions, 142 deletions
diff --git a/src/game.cpp b/src/game.cpp index 7f0186d1..91d8fa3a 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1,9 +1,8 @@ /* - * Aethyra + * The Mana World * Copyright (C) 2004 The Mana World Development Team * - * This file is part of Aethyra based on original code - * from The Mana World. + * 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 @@ -28,6 +27,8 @@ #include <guichan/exception.hpp> #include "beingmanager.h" +#include "channelmanager.h" +#include "commandhandler.h" #include "configuration.h" #include "effectmanager.h" #include "emoteshortcut.h" @@ -42,8 +43,12 @@ #include "log.h" #include "npc.h" #include "particle.h" +#ifdef EATHENA_SUPPORT +#include "party.h" +#endif #include "player_relations.h" +#include "gui/widgets/chattab.h" #include "gui/buy.h" #include "gui/buysell.h" #include "gui/chat.h" @@ -70,23 +75,47 @@ #include "gui/setup.h" #include "gui/skill.h" #include "gui/status.h" -#include "gui/storagewindow.h" #include "gui/trade.h" #include "gui/viewport.h" +#ifdef TMWSERV_SUPPORT +#include "gui/buddywindow.h" +#include "gui/guildwindow.h" +#include "gui/magic.h" +#include "gui/npcpostdialog.h" +#include "gui/partywindow.h" +#include "gui/quitdialog.h" +#else +#include "gui/storagewindow.h" +#endif -#include "net/beinghandler.h" -#include "net/buysellhandler.h" -#include "net/chathandler.h" -#include "net/equipmenthandler.h" -#include "net/inventoryhandler.h" -#include "net/itemhandler.h" +#ifdef TMWSERV_SUPPORT +#include "net/tmwserv/chathandler.h" +#include "net/tmwserv/itemhandler.h" +#include "net/tmwserv/npchandler.h" +#include "net/tmwserv/playerhandler.h" +#include "net/tmwserv/tradehandler.h" +#include "net/tmwserv/network.h" +#include "net/tmwserv/beinghandler.h" +#include "net/tmwserv/buysellhandler.h" +#include "net/tmwserv/effecthandler.h" +#include "net/tmwserv/guildhandler.h" +#include "net/tmwserv/inventoryhandler.h" +#include "net/tmwserv/partyhandler.h" +#else +#include "net/ea/network.h" +#include "net/ea/chathandler.h" +#include "net/ea/beinghandler.h" +#include "net/ea/buysellhandler.h" +#include "net/ea/equipmenthandler.h" +#include "net/ea/inventoryhandler.h" +#include "net/ea/itemhandler.h" +#include "net/ea/npchandler.h" +#include "net/ea/playerhandler.h" +#include "net/ea/tradehandler.h" +#include "net/ea/protocol.h" +#include "net/ea/skillhandler.h" #include "net/messageout.h" -#include "net/network.h" -#include "net/npchandler.h" -#include "net/playerhandler.h" -#include "net/protocol.h" -#include "net/skillhandler.h" -#include "net/tradehandler.h" +#endif #include "resources/imagewriter.h" @@ -105,7 +134,11 @@ Joystick *joystick = NULL; extern Window *weightNotice; extern Window *deathNotice; +#ifdef TMWSERV_SUPPORT +QuitDialog *quitDialog = NULL; +#else ConfirmDialog *exitConfirm = NULL; +#endif OkDialog *disconnectedDialog = NULL; ChatWindow *chatWindow; @@ -114,7 +147,9 @@ StatusWindow *statusWindow; MiniStatusWindow *miniStatusWindow; BuyDialog *buyDialog; SellDialog *sellDialog; +#ifdef EATHENA_SUPPORT BuySellDialog *buySellDialog; +#endif InventoryWindow *inventoryWindow; EmoteWindow *emoteWindow; NpcIntegerDialog *npcIntegerDialog; @@ -122,6 +157,15 @@ NpcListDialog *npcListDialog; NpcTextDialog *npcTextDialog; NpcStringDialog *npcStringDialog; SkillDialog *skillDialog; +#ifdef TMWSERV_SUPPORT +BuddyWindow *buddyWindow; +GuildWindow *guildWindow; +MagicDialog *magicDialog; +NpcPostDialog *npcPostDialog; +PartyWindow *partyWindow; +#else +StorageWindow *storageWindow; +#endif Minimap *minimap; EquipmentWindow *equipmentWindow; TradeWindow *tradeWindow; @@ -129,13 +173,19 @@ HelpWindow *helpWindow; DebugWindow *debugWindow; ShortcutWindow *itemShortcutWindow; ShortcutWindow *emoteShortcutWindow; -StorageWindow *storageWindow; BeingManager *beingManager = NULL; FloorItemManager *floorItemManager = NULL; -Particle* particleEngine = NULL; +ChannelManager *channelManager = NULL; +CommandHandler *commandHandler = NULL; +Particle *particleEngine = NULL; EffectManager *effectManager = NULL; +ChatTab *localChatTab = NULL; +#ifdef EATHENA_SUPPORT +Party *playerParty = NULL; +#endif + const int MAX_TIME = 10000; /** @@ -149,7 +199,9 @@ namespace { if (event.getId() == "yes" || event.getId() == "ok") done = true; +#ifdef EATHENA_SUPPORT exitConfirm = NULL; +#endif disconnectedDialog = NULL; } } exitListener; @@ -187,33 +239,56 @@ int get_elapsed_time(int start_time) /** * Create all the various globally accessible gui windows */ +#ifdef TMWSERV_SUPPORT +void createGuiWindows() +#else void createGuiWindows(Network *network) +#endif { // Create dialogs +#ifdef TMWSERV_SUPPORT + chatWindow = new ChatWindow; + buyDialog = new BuyDialog; + sellDialog = new SellDialog; + tradeWindow = new TradeWindow; + npcTextDialog = new NpcTextDialog; + npcIntegerDialog = new NpcIntegerDialog; + npcListDialog = new NpcListDialog; + npcStringDialog = new NpcStringDialog; + npcPostDialog = new NpcPostDialog(); + magicDialog = new MagicDialog(); + equipmentWindow = new EquipmentWindow(player_node->mEquipment.get()); + buddyWindow = new BuddyWindow(); + guildWindow = new GuildWindow(); + partyWindow = new PartyWindow(); +#else chatWindow = new ChatWindow(network); - menuWindow = new MenuWindow(); - statusWindow = new StatusWindow(player_node); - miniStatusWindow = new MiniStatusWindow(); buyDialog = new BuyDialog(network); sellDialog = new SellDialog(network); buySellDialog = new BuySellDialog(network); - inventoryWindow = new InventoryWindow(); - emoteWindow = new EmoteWindow(); + tradeWindow = new TradeWindow(network); + equipmentWindow = new EquipmentWindow; npcTextDialog = new NpcTextDialog(network); npcIntegerDialog = new NpcIntegerDialog(network); npcListDialog = new NpcListDialog(network); npcStringDialog = new NpcStringDialog(network); - skillDialog = new SkillDialog(); - minimap = new Minimap(); - equipmentWindow = new EquipmentWindow(); - tradeWindow = new TradeWindow(network); - helpWindow = new HelpWindow(); - debugWindow = new DebugWindow(); + storageWindow = new StorageWindow(network); +#endif + menuWindow = new MenuWindow; + statusWindow = new StatusWindow(player_node); + miniStatusWindow = new MiniStatusWindow; + inventoryWindow = new InventoryWindow; + emoteWindow = new EmoteWindow; + skillDialog = new SkillDialog; + minimap = new Minimap; + helpWindow = new HelpWindow; + debugWindow = new DebugWindow; itemShortcutWindow = new ShortcutWindow("ItemShortcut", new ItemShortcutContainer); emoteShortcutWindow = new ShortcutWindow("emoteShortcut", new EmoteShortcutContainer); - storageWindow = new StorageWindow(network); + + localChatTab = new ChatTab(_("General")); // Set initial window visibility chatWindow->setVisible((bool) config.getValue( @@ -222,6 +297,8 @@ void createGuiWindows(Network *network) miniStatusWindow->getPopupName() + "Visible", true)); buyDialog->setVisible(false); sellDialog->setVisible(false); + minimap->setVisible((bool) config.getValue( + minimap->getWindowName() + "Visible", true)); tradeWindow->setVisible(false); menuWindow->setVisible((bool) config.getValue( menuWindow->getPopupName() + "Visible", true)); @@ -231,12 +308,21 @@ void createGuiWindows(Network *network) emoteShortcutWindow->getWindowName() + "Visible", true)); minimap->setVisible((bool) config.getValue( minimap->getWindowName() + "Visible", true)); +#ifdef EATHENA_SUPPORT buySellDialog->setVisible(false); +#endif npcTextDialog->setVisible(false); npcIntegerDialog->setVisible(false); npcListDialog->setVisible(false); npcStringDialog->setVisible(false); +#ifdef EATHENA_SUPPORT storageWindow->setVisible(false); +#endif + + if (config.getValue("logToChat", 0)) + { + logger->setChatWindow(chatWindow); + } } /** @@ -245,19 +331,29 @@ void createGuiWindows(Network *network) void destroyGuiWindows() { logger->setChatWindow(NULL); + delete localChatTab; // Need to do this first, so it can remove itself delete chatWindow; delete statusWindow; delete miniStatusWindow; delete menuWindow; delete buyDialog; delete sellDialog; +#ifdef EATHENA_SUPPORT delete buySellDialog; +#endif delete inventoryWindow; delete emoteWindow; delete npcIntegerDialog; delete npcListDialog; delete npcTextDialog; delete npcStringDialog; +#ifdef TMWSERV_SUPPORT + delete npcPostDialog; + delete magicDialog; + delete buddyWindow; + delete guildWindow; + delete partyWindow; +#endif delete skillDialog; delete minimap; delete equipmentWindow; @@ -266,36 +362,61 @@ void destroyGuiWindows() delete debugWindow; delete itemShortcutWindow; delete emoteShortcutWindow; +#ifdef EATHENA_SUPPORT delete storageWindow; +#endif } +#ifdef TMWSERV_SUPPORT +Game::Game(): + mBeingHandler(new BeingHandler()), + mGuildHandler(new GuildHandler()), + mPartyHandler(new PartyHandler()), + mEffectHandler(new EffectHandler()), +#else Game::Game(Network *network): mNetwork(network), mBeingHandler(new BeingHandler(config.getValue("EnableSync", 0) == 1)), - mBuySellHandler(new BuySellHandler()), - mChatHandler(new ChatHandler()), - mEquipmentHandler(new EquipmentHandler()), - mInventoryHandler(new InventoryHandler()), - mItemHandler(new ItemHandler()), - mNpcHandler(new NPCHandler()), - mPlayerHandler(new PlayerHandler()), - mSkillHandler(new SkillHandler()), - mTradeHandler(new TradeHandler()) + mEquipmentHandler(new EquipmentHandler), + mSkillHandler(new SkillHandler), +#endif + mBuySellHandler(new BuySellHandler), + mChatHandler(new ChatHandler), + mInventoryHandler(new InventoryHandler), + mItemHandler(new ItemHandler), + mNpcHandler(new NPCHandler), + mPlayerHandler(new PlayerHandler), + mTradeHandler(new TradeHandler), + mLastTarget(Being::UNKNOWN), + mLogicCounterId(0), mSecondsCounterId(0) { + done = false; + +#ifdef TMWSERV_SUPPORT + createGuiWindows(); + engine = new Engine; + + beingManager = new BeingManager; + commandHandler = new CommandHandler(); +#else createGuiWindows(network); engine = new Engine(network); beingManager = new BeingManager(network); - floorItemManager = new FloorItemManager(); - effectManager = new EffectManager(); + commandHandler = new CommandHandler(network); +#endif + + floorItemManager = new FloorItemManager; + channelManager = new ChannelManager(); + effectManager = new EffectManager; particleEngine = new Particle(NULL); particleEngine->setupEngine(); - // Initialize timers + // Initialize logic and seconds counters tick_time = 0; - SDL_AddTimer(10, nextTick, NULL); // Logic counter - SDL_AddTimer(1000, nextSecond, NULL); // Seconds counter + mLogicCounterId = SDL_AddTimer(10, nextTick, NULL); + mSecondsCounterId = SDL_AddTimer(1000, nextSecond, NULL); // Initialize frame limiting config.addListener("fpslimit", this); @@ -303,7 +424,10 @@ Game::Game(Network *network): // Initialize beings beingManager->setPlayer(player_node); +#ifdef EATHENA_SUPPORT player_node->setNetwork(network); + playerParty = new Party(network); +#endif Joystick::init(); // TODO: The user should be able to choose which one to use @@ -311,6 +435,19 @@ Game::Game(Network *network): if (Joystick::getNumberOfJoysticks() > 0) joystick = new Joystick(0); +#ifdef TMWSERV_SUPPORT + Net::registerHandler(mBeingHandler.get()); + Net::registerHandler(mBuySellHandler.get()); + Net::registerHandler(mChatHandler.get()); + Net::registerHandler(mGuildHandler.get()); + Net::registerHandler(mInventoryHandler.get()); + Net::registerHandler(mItemHandler.get()); + Net::registerHandler(mNpcHandler.get()); + Net::registerHandler(mPartyHandler.get()); + Net::registerHandler(mPlayerHandler.get()); + Net::registerHandler(mTradeHandler.get()); + Net::registerHandler(mEffectHandler.get()); +#else network->registerHandler(mBeingHandler.get()); network->registerHandler(mBuySellHandler.get()); network->registerHandler(mChatHandler.get()); @@ -336,24 +473,38 @@ Game::Game(Network *network): msg.writeInt32(tick_time); engine->changeMap(map_path); +#endif setupWindow->setInGame(true); } Game::~Game() { - delete player_node; +#ifdef TMWSERV_SUPPORT + Net::clearHandlers(); +#else + delete playerParty; +#endif + destroyGuiWindows(); delete beingManager; + delete player_node; delete floorItemManager; + delete channelManager; + delete commandHandler; delete joystick; delete particleEngine; delete engine; + viewport->setMap(NULL); + player_node = NULL; beingManager = NULL; floorItemManager = NULL; joystick = NULL; + + SDL_RemoveTimer(mLogicCounterId); + SDL_RemoveTimer(mSecondsCounterId); } static bool saveScreenshot() @@ -374,11 +525,11 @@ static bool saveScreenshot() filenameSuffix.str(""); filename << PHYSFS_getUserDir(); #if (defined __USE_UNIX98 || defined __FreeBSD__) - filenameSuffix << ".aethyra/"; + filenameSuffix << ".tmw/"; #elif defined __APPLE__ filenameSuffix << "Desktop/"; #endif - filenameSuffix << "Ae_Screenshot_" << screenshotCount << ".png"; + filenameSuffix << "TMW_Screenshot_" << screenshotCount << ".png"; filename << filenameSuffix.str(); testExists.open(filename.str().c_str(), std::ios::in); found = !testExists.is_open(); @@ -391,11 +542,11 @@ static bool saveScreenshot() { std::stringstream chatlogentry; chatlogentry << _("Screenshot saved to ~/") << filenameSuffix.str(); - chatWindow->chatLog(chatlogentry.str(), BY_SERVER); + localChatTab->chatLog(chatlogentry.str(), BY_SERVER); } else { - chatWindow->chatLog(_("Saving screenshot failed!"), BY_SERVER); + localChatTab->chatLog(_("Saving screenshot failed!"), BY_SERVER); logger->log("Error: could not save screenshot."); } @@ -467,6 +618,10 @@ void Game::logic() } // Handle network stuff +#ifdef TMWSERV_SUPPORT + Net::flush(); + // TODO: Fix notification when the connection is lost +#else mNetwork->flush(); mNetwork->dispatchMessages(); @@ -482,6 +637,7 @@ void Game::logic() disconnectedDialog->requestMoveToTop(); } } +#endif } } @@ -510,6 +666,23 @@ void Game::handleInput() return; } +#ifdef TMWSERV_SUPPORT + // send straight to gui for certain windows + if (npcPostDialog->isVisible()) + { + try + { + guiInput->pushInput(event); + } + catch (gcn::Exception e) + { + const char* err = e.getMessage().c_str(); + logger->log("Warning: guichan input exception: %s", err); + } + return; + } +#endif + // Mode switch to emotes if (keyboard.isKeyActive(keyboard.KEY_EMOTE)) { @@ -523,58 +696,54 @@ void Game::handleInput() } } - if (keyboard.isKeyActive(keyboard.KEY_TOGGLE_CHAT) || - keyboard.isKeyActive(keyboard.KEY_OK)) - { - // Input chat window - if (!(chatWindow->isInputFocused() || - deathNotice || - weightNotice)) + if (!(chatWindow->isInputFocused() || deathNotice || weightNotice)) + if (keyboard.isKeyActive(keyboard.KEY_OK)) { - // Quit by pressing Enter if the exit confirm is there +#ifdef TMWSERV_SUPPORT + // Don not focus chat input when quit dialog is active + if (quitDialog != NULL && quitDialog->isVisible()) + continue; +#else if (exitConfirm && keyboard.isKeyActive(keyboard.KEY_TOGGLE_CHAT)) done = true; +#endif // Close the Browser if opened else if (helpWindow->isVisible() && - keyboard.isKeyActive(keyboard.KEY_OK)) + keyboard.isKeyActive(keyboard.KEY_OK)) helpWindow->setVisible(false); // Close the config window, cancelling changes if opened else if (setupWindow->isVisible() && - keyboard.isKeyActive(keyboard.KEY_OK)) + keyboard.isKeyActive(keyboard.KEY_OK)) setupWindow->action(gcn::ActionEvent(NULL, "cancel")); // Submits the text and proceeds to the next dialog else if (npcStringDialog->isVisible() && - keyboard.isKeyActive(keyboard.KEY_OK)) + keyboard.isKeyActive(keyboard.KEY_OK)) npcStringDialog->action(gcn::ActionEvent(NULL, "ok")); // Proceed to the next dialog option, or close the window else if (npcTextDialog->isVisible() && - keyboard.isKeyActive(keyboard.KEY_OK)) + keyboard.isKeyActive(keyboard.KEY_OK)) npcTextDialog->action(gcn::ActionEvent(NULL, "ok")); // Choose the currently highlighted dialogue option else if (npcListDialog->isVisible() && - keyboard.isKeyActive(keyboard.KEY_OK)) + keyboard.isKeyActive(keyboard.KEY_OK)) npcListDialog->action(gcn::ActionEvent(NULL, "ok")); // Submits the text and proceeds to the next dialog else if (npcIntegerDialog->isVisible() && - keyboard.isKeyActive(keyboard.KEY_OK)) + keyboard.isKeyActive(keyboard.KEY_OK)) npcIntegerDialog->action(gcn::ActionEvent(NULL, "ok")); - else if (!(keyboard.getKeyValue( - KeyboardConfig::KEY_TOGGLE_CHAT) == - keyboard.getKeyValue( - KeyboardConfig::KEY_OK) && - (helpWindow->isVisible() || - setupWindow->isVisible() || - npcStringDialog->isVisible() || - npcTextDialog->isVisible() || - npcListDialog->isVisible() || - npcIntegerDialog->isVisible()))) + /* + else if (guildWindow->isVisible()) { - chatWindow->requestChatFocus(); - used = true; + // TODO: Check if a dialog is open and close it if so } + */ + } + if (keyboard.isKeyActive(keyboard.KEY_TOGGLE_CHAT)) + { + if (chatWindow->requestChatFocus()) + used = true; } - } const int tKey = keyboard.getKeyIndex(event.key.keysym.sym); switch (tKey) @@ -607,6 +776,17 @@ void Game::handleInput() break; // Quitting confirmation dialog case KeyboardConfig::KEY_QUIT: +#ifdef TMWSERV_SUPPORT + if (!quitDialog) + { + quitDialog = new QuitDialog(&done, &quitDialog); + quitDialog->requestMoveToTop(); + } + else + { + quitDialog->action(gcn::ActionEvent(NULL, "cancel")); + } +#else if (!exitConfirm) { exitConfirm = new ConfirmDialog(_("Quit"), @@ -619,6 +799,7 @@ void Game::handleInput() { exitConfirm->action(gcn::ActionEvent(NULL, _("no"))); } +#endif break; default: break; @@ -649,25 +830,34 @@ void Game::handleInput() { case KeyboardConfig::KEY_PICKUP: { - FloorItem *item = floorItemManager->findByCoordinates( - player_node->mX, - player_node->mY); +#ifdef TMWSERV_SUPPORT + const Vector &pos = player_node->getPosition(); + Uint16 x = (int) pos.x / 32; + Uint16 y = (int) pos.y / 32; +#else + Uint16 x = player_node->mX; + Uint16 y = player_node->mY; +#endif + FloorItem *item = + floorItemManager->findByCoordinates(x, y); // If none below the player, try the tile in front // of the player if (!item) { - Uint16 x = player_node->mX; - Uint16 y = player_node->mY; - if (player_node->getDirection() & Being::UP) - y--; - if (player_node->getDirection() & Being::DOWN) - y++; - if (player_node->getDirection() & Being::LEFT) - x--; - if (player_node->getDirection() & Being::RIGHT) - x++; - item = floorItemManager->findByCoordinates(x, y); + // 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) @@ -693,6 +883,10 @@ void Game::handleInput() equipmentWindow->setVisible(false); helpWindow->setVisible(false); debugWindow->setVisible(false); +#ifdef TMWSERV_SUPPORT + guildWindow->setVisible(false); + buddyWindow->setVisible(false); +#endif } break; case KeyboardConfig::KEY_WINDOW_STATUS: @@ -744,16 +938,16 @@ void Game::handleInput() unsigned int deflt = player_relations.getDefault(); if (deflt & PlayerRelation::TRADE) { - chatWindow->chatLog( - _("Ignoring incoming trade requests"), - BY_SERVER); + localChatTab->chatLog( + _("Ignoring incoming trade requests"), + BY_SERVER); deflt &= ~PlayerRelation::TRADE; } else { - chatWindow->chatLog( - _("Accepting incoming trade requests"), - BY_SERVER); + localChatTab->chatLog( + _("Accepting incoming trade requests"), + BY_SERVER); deflt |= PlayerRelation::TRADE; } @@ -791,6 +985,7 @@ void Game::handleInput() logger->log("Warning: guichan input exception: %s", err); } } + } // End while // If the user is configuring the keys then don't respond. @@ -799,7 +994,10 @@ void Game::handleInput() // Moving player around if (player_node->mAction != Being::DEAD && - current_npc == 0 && !chatWindow->isInputFocused()) +#ifdef EATHENA_SUPPORT + current_npc == 0 && +#endif + !chatWindow->isInputFocused()) { // Get the state of the keyboard keys keyboard.refreshActiveKeys(); @@ -813,41 +1011,67 @@ void Game::handleInput() return; } +#ifdef TMWSERV_SUPPORT + const Vector &pos = player_node->getPosition(); + const Uint16 x = (int) pos.x / 32; + const Uint16 y = (int) pos.y / 32; +#else const Uint16 x = player_node->mX; const Uint16 y = player_node->mY; +#endif unsigned char direction = 0; // Translate pressed keys to movement and direction if (keyboard.isKeyActive(keyboard.KEY_MOVE_UP) || - (joystick && joystick->isUp())) + (joystick && joystick->isUp())) { direction |= Being::UP; } else if (keyboard.isKeyActive(keyboard.KEY_MOVE_DOWN) || - (joystick && joystick->isDown())) + (joystick && joystick->isDown())) { direction |= Being::DOWN; } if (keyboard.isKeyActive(keyboard.KEY_MOVE_LEFT) || - (joystick && joystick->isLeft())) + (joystick && joystick->isLeft())) { direction |= Being::LEFT; } else if (keyboard.isKeyActive(keyboard.KEY_MOVE_RIGHT) || - (joystick && joystick->isRight())) + (joystick && joystick->isRight())) { direction |= Being::RIGHT; } +#ifdef TMWSERV_SUPPORT + // First if player is pressing key for the direction he is already + // going + if (direction == player_node->getWalkingDir()) + { + player_node->setWalkingDir(direction); + } + // Else if he is pressing a key, and its different from what he has + // been pressing, stop (do not send this stop to the server) and + // start in the new direction + else if (direction && direction != player_node->getWalkingDir()) + { + player_node->stopWalking(false); + player_node->setWalkingDir(direction); + } + // Else, he is not pressing a key, stop (sending to server) + else + { + player_node->stopWalking(true); + } +#else player_node->setWalkingDir(direction); // Attacking monsters if (keyboard.isKeyActive(keyboard.KEY_ATTACK) || (joystick && joystick->buttonPressed(0))) { - Being *target = beingManager->findNearestLivingBeing(x, y, 20, - Being::MONSTER); + Being *target = NULL; bool newTarget = !keyboard.isKeyActive(keyboard.KEY_TARGET); // A set target has highest priority @@ -864,47 +1088,41 @@ void Game::handleInput() default: break; } - // Attack priorioty is: Monster, Player, auto target - target = beingManager->findBeing(targetX, targetY, - Being::MONSTER); - if (!target) - target = beingManager->findBeing(targetX, targetY, - Being::PLAYER); + // Only auto target Monsters + target = beingManager->findNearestLivingBeing(targetX, targetY, + 20, Being::MONSTER); } player_node->attack(target, newTarget); } +#endif - // Target the nearest player if 'q' is pressed - if ( keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER) && - !keyboard.isKeyActive(keyboard.KEY_TARGET) ) - { - Being *target = beingManager->findNearestLivingBeing(player_node, - 20, Being::PLAYER); - - player_node->setTarget(target); - } - - // Target the nearest monster if 'a' pressed - if ((keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) || - (joystick && joystick->buttonPressed(3))) && - !keyboard.isKeyActive(keyboard.KEY_TARGET)) + // Target the nearest player/monster/npc + if ((keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER) || + keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) || + keyboard.isKeyActive(keyboard.KEY_TARGET_NPC) || + (joystick && joystick->buttonPressed(3))) && + !keyboard.isKeyActive(keyboard.KEY_TARGET)) { - Being *target = beingManager->findNearestLivingBeing( - x, y, 20, Being::MONSTER); - - player_node->setTarget(target); - } + Being::Type currentTarget = Being::UNKNOWN; + if (keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) || + (joystick && joystick->buttonPressed(3))) + currentTarget = Being::MONSTER; + else if (keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER)) + currentTarget = Being::PLAYER; + else if (keyboard.isKeyActive(keyboard.KEY_TARGET_NPC)) + currentTarget = Being::NPC; - // Target the nearest npc if 'n' pressed - if ( keyboard.isKeyActive(keyboard.KEY_TARGET_NPC) && - !keyboard.isKeyActive(keyboard.KEY_TARGET) ) - { - Being *target = beingManager->findNearestLivingBeing( - x, y, 20, Being::NPC); + Being *target = beingManager->findNearestLivingBeing(player_node, + 20, currentTarget); - player_node->setTarget(target); - } + if (target && (target != player_node->getTarget() || + currentTarget != mLastTarget)) + { + player_node->setTarget(target); + mLastTarget = currentTarget; + } + } else mLastTarget = Being::UNKNOWN; // Reset last target // Talk to the nearest NPC if 't' pressed if ( keyboard.isKeyActive(keyboard.KEY_TALK) ) @@ -914,12 +1132,6 @@ void Game::handleInput() { Being *target = player_node->getTarget(); - if (!target) - { - target = beingManager->findNearestLivingBeing( - x, y, 20, Being::NPC); - } - if (target) { if (target->getType() == Being::NPC) @@ -928,11 +1140,13 @@ void Game::handleInput() } } +#ifdef EATHENA_SUPPORT // Stop attacking if shift is pressed if (keyboard.isKeyActive(keyboard.KEY_TARGET)) { player_node->stopAttack(); } +#endif if (joystick) { |