summaryrefslogtreecommitdiff
path: root/src/game.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game.cpp')
-rw-r--r--src/game.cpp654
1 files changed, 454 insertions, 200 deletions
diff --git a/src/game.cpp b/src/game.cpp
index 942c517c..cf1aa220 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -1,26 +1,24 @@
/*
* The Mana World
- * Copyright 2004 The Mana World Development Team
+ * Copyright (C) 2004 The Mana World Development Team
*
* This file is part of The Mana World.
*
- * The Mana World is free software; you can redistribute it and/or modify
+ * 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.
*
- * The Mana World is distributed in the hope that it will be useful,
+ * 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 The Mana World; if not, write to the Free Software
+ * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "game.h"
-
#include <fstream>
#include <physfs.h>
#include <sstream>
@@ -29,11 +27,16 @@
#include <guichan/exception.hpp>
#include "beingmanager.h"
+#ifdef TMWSERV_SUPPORT
#include "channelmanager.h"
#include "commandhandler.h"
+#endif
#include "configuration.h"
+#include "effectmanager.h"
+#include "emoteshortcut.h"
#include "engine.h"
#include "flooritemmanager.h"
+#include "game.h"
#include "graphics.h"
#include "itemshortcut.h"
#include "joystick.h"
@@ -42,30 +45,29 @@
#include "log.h"
#include "npc.h"
#include "particle.h"
-#include "effectmanager.h"
+#include "player_relations.h"
-#include "gui/buddywindow.h"
#include "gui/buy.h"
#include "gui/buysell.h"
#include "gui/chat.h"
#include "gui/confirm_dialog.h"
#include "gui/debugwindow.h"
+#include "gui/emoteshortcutcontainer.h"
+#include "gui/emotewindow.h"
#include "gui/equipmentwindow.h"
#include "gui/gui.h"
-#include "gui/guildwindow.h"
#include "gui/help.h"
#include "gui/inventorywindow.h"
-#include "gui/itemshortcutwindow.h"
-#include "gui/magic.h"
+#include "gui/shortcutwindow.h"
+#include "gui/itemshortcutcontainer.h"
#include "gui/menuwindow.h"
#include "gui/minimap.h"
#include "gui/ministatus.h"
+#include "gui/npcintegerdialog.h"
#include "gui/npclistdialog.h"
-#include "gui/npcpostdialog.h"
+#include "gui/npcstringdialog.h"
#include "gui/npc_text.h"
#include "gui/ok_dialog.h"
-#include "gui/partywindow.h"
-#include "gui/quitdialog.h"
#include "gui/sdlinput.h"
#include "gui/sell.h"
#include "gui/setup.h"
@@ -73,23 +75,42 @@
#include "gui/status.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"
+#endif
-#include "net/beinghandler.h"
-#include "net/buysellhandler.h"
#include "net/chathandler.h"
-#include "net/guildhandler.h"
-#include "net/inventoryhandler.h"
#include "net/itemhandler.h"
-#include "net/network.h"
#include "net/npchandler.h"
-#include "net/partyhandler.h"
#include "net/playerhandler.h"
#include "net/tradehandler.h"
+#ifdef TMWSERV_SUPPORT
+#include "net/network.h"
+#include "net/beinghandler.h"
+#include "net/buysellhandler.h"
#include "net/effecthandler.h"
+#include "net/guildhandler.h"
+#include "net/inventoryhandler.h"
+#include "net/partyhandler.h"
+#else
+#include "net/ea/network.h"
+#include "net/ea/beinghandler.h"
+#include "net/ea/buysellhandler.h"
+#include "net/ea/equipmenthandler.h"
+#include "net/ea/inventoryhandler.h"
+#include "net/ea/protocol.h"
+#include "net/ea/skillhandler.h"
+#include "net/messageout.h"
+#endif
#include "resources/imagewriter.h"
-extern Graphics *graphics;
+#include "utils/gettext.h"
class Map;
@@ -98,12 +119,17 @@ std::string map_path;
bool done = false;
volatile int tick_time;
volatile int fps = 0, frame = 0;
+
Engine *engine = NULL;
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,34 +140,41 @@ BuyDialog *buyDialog;
SellDialog *sellDialog;
BuySellDialog *buySellDialog;
InventoryWindow *inventoryWindow;
+EmoteWindow *emoteWindow;
+NpcIntegerDialog *npcIntegerDialog;
NpcListDialog *npcListDialog;
NpcTextDialog *npcTextDialog;
-NpcPostDialog *npcPostDialog;
+NpcStringDialog *npcStringDialog;
SkillDialog *skillDialog;
+#ifdef TMWSERV_SUPPORT
+BuddyWindow *buddyWindow;
+GuildWindow *guildWindow;
MagicDialog *magicDialog;
+NpcPostDialog *npcPostDialog;
+PartyWindow *partyWindow;
+#endif
Setup* setupWindow;
Minimap *minimap;
EquipmentWindow *equipmentWindow;
TradeWindow *tradeWindow;
-BuddyWindow *buddyWindow;
-GuildWindow *guildWindow;
HelpWindow *helpWindow;
DebugWindow *debugWindow;
-ItemShortcutWindow *itemShortcutWindow;
-PartyWindow *partyWindow;
+ShortcutWindow *itemShortcutWindow;
+ShortcutWindow *emoteShortcutWindow;
BeingManager *beingManager = NULL;
FloorItemManager *floorItemManager = NULL;
+#ifdef TMWSERV_SUPPORT
ChannelManager *channelManager = NULL;
CommandHandler *commandHandler = NULL;
+#endif
+Particle* particleEngine = NULL;
EffectManager *effectManager = NULL;
-Particle *particleEngine = NULL;
-
const int MAX_TIME = 10000;
/**
- * Listener used for exitting handling.
+ * Listener used for exiting handling.
*/
namespace {
struct ExitListener : public gcn::ActionListener
@@ -151,6 +184,9 @@ namespace {
if (event.getId() == "yes" || event.getId() == "ok") {
done = true;
}
+#ifdef EATHENA_SUPPORT
+ exitConfirm = NULL;
+#endif
disconnectedDialog = NULL;
}
} exitListener;
@@ -173,15 +209,18 @@ Uint32 nextSecond(Uint32 interval, void *param)
{
fps = frame;
frame = 0;
+
return interval;
}
int get_elapsed_time(int start_time)
{
- if (start_time <= tick_time) {
+ if (start_time <= tick_time)
+ {
return (tick_time - start_time) * 10;
}
- else {
+ else
+ {
return (tick_time + (MAX_TIME - start_time)) * 10;
}
}
@@ -189,49 +228,67 @@ 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;
- menuWindow = new MenuWindow();
- statusWindow = new StatusWindow(player_node);
- miniStatusWindow = new MiniStatusWindow();
buyDialog = new BuyDialog;
sellDialog = new SellDialog;
- buySellDialog = new BuySellDialog();
- inventoryWindow = new InventoryWindow();
- npcTextDialog = new NpcTextDialog();
- npcListDialog = new NpcListDialog();
+ tradeWindow = new TradeWindow;
npcPostDialog = new NpcPostDialog();
- skillDialog = new SkillDialog();
magicDialog = new MagicDialog();
- setupWindow = new Setup();
- minimap = new Minimap();
equipmentWindow = new EquipmentWindow(player_node->mEquipment.get());
- tradeWindow = new TradeWindow;
buddyWindow = new BuddyWindow();
guildWindow = new GuildWindow();
- helpWindow = new HelpWindow();
- debugWindow = new DebugWindow();
- itemShortcutWindow = new ItemShortcutWindow();
partyWindow = new PartyWindow();
-
- // Initialize window positions
- //buddyWindow->setPosition(10, minimap->getHeight() + 30);
+#else
+ chatWindow = new ChatWindow(network);
+ buyDialog = new BuyDialog(network);
+ sellDialog = new SellDialog(network);
+ tradeWindow = new TradeWindow(network);
+ equipmentWindow = new EquipmentWindow;
+#endif
+ menuWindow = new MenuWindow;
+ statusWindow = new StatusWindow(player_node);
+ miniStatusWindow = new MiniStatusWindow;
+ buySellDialog = new BuySellDialog;
+ inventoryWindow = new InventoryWindow;
+ emoteWindow = new EmoteWindow;
+ npcTextDialog = new NpcTextDialog;
+ npcIntegerDialog = new NpcIntegerDialog;
+ npcListDialog = new NpcListDialog;
+ npcStringDialog = new NpcStringDialog;
+ skillDialog = new SkillDialog;
+ setupWindow = new Setup;
+ minimap = new Minimap;
+ helpWindow = new HelpWindow;
+ debugWindow = new DebugWindow;
+ itemShortcutWindow = new ShortcutWindow("ItemShortcut",new ItemShortcutContainer);
+ emoteShortcutWindow = new ShortcutWindow("emoteShortcut",new EmoteShortcutContainer);
// Set initial window visibility
chatWindow->setVisible((bool) config.getValue(
chatWindow->getWindowName() + "Visible", true));
miniStatusWindow->setVisible((bool) config.getValue(
- miniStatusWindow->getWindowName() + "Visible",
- true));
+ miniStatusWindow->getWindowName() + "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->getWindowName() + "Visible", true));
itemShortcutWindow->setVisible((bool) config.getValue(
itemShortcutWindow->getWindowName() + "Visible", true));
+ emoteShortcutWindow->setVisible((bool) config.getValue(
+ emoteShortcutWindow->getWindowName() + "Visible", true));
+ minimap->setVisible((bool) config.getValue(
+ minimap->getWindowName() + "Visible", true));
if (config.getValue("logToChat", 0))
{
@@ -244,6 +301,7 @@ void createGuiWindows()
*/
void destroyGuiWindows()
{
+ logger->setChatWindow(NULL);
delete chatWindow;
delete statusWindow;
delete miniStatusWindow;
@@ -252,47 +310,71 @@ void destroyGuiWindows()
delete sellDialog;
delete buySellDialog;
delete inventoryWindow;
+ delete emoteWindow;
+ delete npcIntegerDialog;
delete npcListDialog;
delete npcTextDialog;
+ delete npcStringDialog;
+#ifdef TMWSERV_SUPPORT
delete npcPostDialog;
- delete skillDialog;
delete magicDialog;
+ delete buddyWindow;
+ delete guildWindow;
+ delete partyWindow;
+#endif
+ delete skillDialog;
delete setupWindow;
delete minimap;
delete equipmentWindow;
delete tradeWindow;
- delete buddyWindow;
- delete guildWindow;
delete helpWindow;
delete debugWindow;
delete itemShortcutWindow;
- delete partyWindow;
+ delete emoteShortcutWindow;
}
+#ifdef TMWSERV_SUPPORT
Game::Game():
mBeingHandler(new BeingHandler()),
- mBuySellHandler(new BuySellHandler()),
- mChatHandler(new ChatHandler()),
mGuildHandler(new GuildHandler()),
- mInventoryHandler(new InventoryHandler()),
- mItemHandler(new ItemHandler()),
- mNpcHandler(new NPCHandler()),
mPartyHandler(new PartyHandler()),
- mPlayerHandler(new PlayerHandler()),
- mTradeHandler(new TradeHandler()),
mEffectHandler(new EffectHandler()),
+#else
+Game::Game(Network *network):
+ mNetwork(network),
+ mBeingHandler(new BeingHandler(config.getValue("EnableSync", 0) == 1)),
+ 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),
mLogicCounterId(0), mSecondsCounterId(0)
{
done = false;
+#ifdef TMWSERV_SUPPORT
createGuiWindows();
engine = new Engine;
beingManager = new BeingManager;
- floorItemManager = new FloorItemManager();
+#else
+ createGuiWindows(network);
+ engine = new Engine(network);
+
+ beingManager = new BeingManager(network);
+#endif
+
+ floorItemManager = new FloorItemManager;
+#ifdef TMWSERV_SUPPORT
channelManager = new ChannelManager();
commandHandler = new CommandHandler();
- effectManager = new EffectManager();
+#endif
+ effectManager = new EffectManager;
particleEngine = new Particle(NULL);
particleEngine->setupEngine();
@@ -308,6 +390,9 @@ Game::Game():
// Initialize beings
beingManager->setPlayer(player_node);
+#ifdef EATHENA_SUPPORT
+ player_node->setNetwork(network);
+#endif
Joystick::init();
// TODO: The user should be able to choose which one to use
@@ -315,6 +400,7 @@ Game::Game():
if (Joystick::getNumberOfJoysticks() > 0)
joystick = new Joystick(0);
+#ifdef TMWSERV_SUPPORT
Net::registerHandler(mBeingHandler.get());
Net::registerHandler(mBuySellHandler.get());
Net::registerHandler(mChatHandler.get());
@@ -326,19 +412,50 @@ Game::Game():
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());
+ network->registerHandler(mEquipmentHandler.get());
+ network->registerHandler(mInventoryHandler.get());
+ network->registerHandler(mItemHandler.get());
+ network->registerHandler(mNpcHandler.get());
+ network->registerHandler(mPlayerHandler.get());
+ network->registerHandler(mSkillHandler.get());
+ network->registerHandler(mTradeHandler.get());
+
+ /*
+ * 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
+ */
+ MessageOut msg(mNetwork);
+ msg.writeInt16(CMSG_CLIENT_PING);
+ msg.writeInt32(tick_time);
+
+ engine->changeMap(map_path);
+#endif
}
Game::~Game()
{
+#ifdef TMWSERV_SUPPORT
Net::clearHandlers();
+#endif
delete player_node;
destroyGuiWindows();
delete beingManager;
delete floorItemManager;
+#ifdef TMWSERV_SUPPORT
delete channelManager;
delete commandHandler;
+#endif
delete joystick;
delete particleEngine;
delete engine;
@@ -387,12 +504,12 @@ static bool saveScreenshot()
if (success)
{
std::stringstream chatlogentry;
- chatlogentry << "Screenshot saved to ~/" << filenameSuffix.str();
+ chatlogentry << _("Screenshot saved to ~/") << filenameSuffix.str();
chatWindow->chatLog(chatlogentry.str(), BY_SERVER);
}
else
{
- chatWindow->chatLog("Saving screenshot failed!", BY_SERVER);
+ chatWindow->chatLog(_("Saving screenshot failed!"), BY_SERVER);
logger->log("Error: could not save screenshot.");
}
@@ -438,7 +555,7 @@ void Game::logic()
// Draw a frame if either frames are not limited or enough time has
// passed since the last frame.
if (!mMinFrameTime ||
- get_elapsed_time(mDrawTime / 10) > mMinFrameTime)
+ get_elapsed_time(mDrawTime / 10) > mMinFrameTime)
{
frame++;
gui->draw();
@@ -461,20 +578,25 @@ void Game::logic()
}
// Handle network stuff
+#ifdef TMWSERV_SUPPORT
Net::flush();
-
// TODO: Fix notification when the connection is lost
- if (false /*!mNetwork->isConnected() */)
+#else
+ mNetwork->flush();
+ mNetwork->dispatchMessages();
+
+ if (!mNetwork->isConnected())
{
if (!disconnectedDialog)
{
- disconnectedDialog = new OkDialog("Network Error",
- "The connection to the server was lost, "
- "the program will now quit");
+ disconnectedDialog = new OkDialog(_("Network Error"),
+ _("The connection to the server was lost, "
+ "the program will now quit"));
disconnectedDialog->addActionListener(&exitListener);
disconnectedDialog->requestMoveToTop();
}
}
+#endif
}
}
@@ -495,7 +617,7 @@ void Game::handleInput()
gcn::Window *requestedWindow = NULL;
if (setupWindow->isVisible() &&
- keyboard.getNewKeyIndex() > keyboard.KEY_NO_VALUE)
+ keyboard.getNewKeyIndex() > keyboard.KEY_NO_VALUE)
{
keyboard.setNewKey((int) event.key.keysym.sym);
keyboard.callbackNewKey();
@@ -503,6 +625,7 @@ void Game::handleInput()
return;
}
+#ifdef TMWSERV_SUPPORT
// send straight to gui for certain windows
if (npcPostDialog->isVisible())
{
@@ -517,61 +640,118 @@ void Game::handleInput()
}
return;
}
+#endif
- switch (event.key.keysym.sym)
+ // Mode switch to emotes
+ if (keyboard.isKeyActive(keyboard.KEY_EMOTE))
{
- case SDLK_F1:
- // In-game Help
- if (helpWindow->isVisible())
- {
- helpWindow->setVisible(false);
- }
- else
- {
- helpWindow->loadHelp("index");
- helpWindow->requestMoveToTop();
- }
+ // Emotions
+ int emotion = keyboard.getKeyEmoteOffset(event.key.keysym.sym);
+ if (emotion)
+ {
+ emoteShortcut->useEmote(emotion);
used = true;
- break;
-
- case SDLK_RETURN:
- // Input chat window
- if (chatWindow->isInputFocused() ||
- deathNotice != NULL ||
- weightNotice != NULL)
- {
- break;
- }
+ return;
+ }
+ }
+ if (keyboard.isKeyActive(keyboard.KEY_TOGGLE_CHAT) ||
+ keyboard.isKeyActive(keyboard.KEY_OK))
+ {
+ // Input chat window
+ if (!(chatWindow->isInputFocused() ||
+ deathNotice ||
+ weightNotice))
+ {
+#ifdef TMWSERV_SUPPORT
// Don not focus chat input when quit dialog is active
- if(quitDialog != NULL && quitDialog->isVisible())
- break;
-
+ if (quitDialog != NULL && quitDialog->isVisible())
+ continue;
+#else
+ // Quit by pressing Enter if the exit confirm is there
+ if (exitConfirm &&
+ keyboard.isKeyActive(keyboard.KEY_TOGGLE_CHAT))
+ done = true;
+#endif
// Close the Browser if opened
- if (helpWindow->isVisible())
- {
+ else if (helpWindow->isVisible() &&
+ keyboard.isKeyActive(keyboard.KEY_OK))
helpWindow->setVisible(false);
- }
// Close the config window, cancelling changes if opened
- else if (setupWindow->isVisible())
- {
+ else if (setupWindow->isVisible() &&
+ 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))
+ 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))
+ npcTextDialog->action(gcn::ActionEvent(NULL, "ok"));
+ // Choose the currently highlighted dialogue option
+ else if (npcListDialog->isVisible() &&
+ 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))
+ npcIntegerDialog->action(gcn::ActionEvent(NULL, "ok"));
/*
else if (guildWindow->isVisible())
{
// TODO: Check if a dialog is open and close it if so
}
*/
- // Else, open the chat edit box
- else
+ 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())))
{
chatWindow->requestChatFocus();
used = true;
}
+ }
+ }
+
+ const int tKey = keyboard.getKeyIndex(event.key.keysym.sym);
+ switch (tKey)
+ {
+ case KeyboardConfig::KEY_SCROLL_CHAT_UP:
+ if (chatWindow->isVisible())
+ {
+ chatWindow->scroll(-DEFAULT_CHAT_WINDOW_SCROLL);
+ used = true;
+ }
+ break;
+ case KeyboardConfig::KEY_SCROLL_CHAT_DOWN:
+ if (chatWindow->isVisible())
+ {
+ chatWindow->scroll(DEFAULT_CHAT_WINDOW_SCROLL);
+ used = true;
+ return;
+ }
break;
- // Quitting confirmation dialog
- case SDLK_ESCAPE:
+ case KeyboardConfig::KEY_WINDOW_HELP:
+ // In-game Help
+ if (helpWindow->isVisible())
+ helpWindow->setVisible(false);
+ else
+ {
+ helpWindow->loadHelp("index");
+ helpWindow->requestMoveToTop();
+ }
+ used = true;
+ break;
+ // Quitting confirmation dialog
+ case KeyboardConfig::KEY_QUIT:
+#ifdef TMWSERV_SUPPORT
if (!quitDialog)
{
quitDialog = new QuitDialog(&done, &quitDialog);
@@ -581,37 +761,58 @@ void Game::handleInput()
{
quitDialog->action(gcn::ActionEvent(NULL, "cancel"));
}
+#else
+ if (!exitConfirm)
+ {
+ exitConfirm = new ConfirmDialog(_("Quit"),
+ _("Are you sure you "
+ "want to quit?"));
+ exitConfirm->addActionListener(&exitListener);
+ exitConfirm->requestMoveToTop();
+ }
+ else
+ {
+ exitConfirm->action(gcn::ActionEvent(NULL, _("no")));
+ }
+#endif
break;
-
default:
break;
}
-
if (keyboard.isEnabled() && !chatWindow->isInputFocused()
- && !guildWindow->isWindowFocused())
+ && !npcStringDialog->isInputFocused())
{
const int tKey = keyboard.getKeyIndex(event.key.keysym.sym);
+
// Do not activate shortcuts if tradewindow is visible
if (!tradeWindow->isVisible())
{
// Checks if any item shortcut is pressed.
- for (int i = KeyboardConfig::KEY_SHORTCUT_0;
- i <= KeyboardConfig::KEY_SHORTCUT_9;
- i++)
+ for (int i = KeyboardConfig::KEY_SHORTCUT_1;
+ i <= KeyboardConfig::KEY_SHORTCUT_12;
+ i++)
{
- if (tKey == i && !used) {
+ if (tKey == i && !used)
+ {
itemShortcut->useItem(
- i - KeyboardConfig::KEY_SHORTCUT_0);
+ i - KeyboardConfig::KEY_SHORTCUT_1);
break;
}
}
}
- switch (tKey) {
+
+ switch (tKey)
+ {
case KeyboardConfig::KEY_PICKUP:
{
+#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);
@@ -630,8 +831,8 @@ void Game::handleInput()
default: break;
}
- item =
- floorItemManager->findByCoordinates(x, y);
+ item = floorItemManager->findByCoordinates(
+ x, y);
}
if (item)
@@ -640,35 +841,29 @@ void Game::handleInput()
used = true;
}
break;
-
- case KeyboardConfig::KEY_ATTACK:
- player_node->attack();
- used = true;
- break;
-
case KeyboardConfig::KEY_SIT:
// Player sit action
player_node->toggleSit();
used = true;
break;
-
case KeyboardConfig::KEY_HIDE_WINDOWS:
- // Hide certain windows
+ // Hide certain windows
if (!chatWindow->isInputFocused())
{
statusWindow->setVisible(false);
inventoryWindow->setVisible(false);
+ emoteWindow->setVisible(false);
skillDialog->setVisible(false);
- magicDialog->setVisible(false);
setupWindow->setVisible(false);
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:
requestedWindow = statusWindow;
break;
@@ -682,6 +877,7 @@ void Game::handleInput()
requestedWindow = skillDialog;
break;
case KeyboardConfig::KEY_WINDOW_MINIMAP:
+ minimap->toggle();
requestedWindow = minimap;
break;
case KeyboardConfig::KEY_WINDOW_CHAT:
@@ -696,83 +892,55 @@ void Game::handleInput()
case KeyboardConfig::KEY_WINDOW_DEBUG:
requestedWindow = debugWindow;
break;
- }
- }
-
- if (requestedWindow)
- {
- requestedWindow->setVisible(!requestedWindow->isVisible());
- if (requestedWindow->isVisible())
- {
- requestedWindow->requestMoveToTop();
- }
- used = true;
- }
-
- // Keys pressed together with Alt/Meta
- // Emotions and some internal gui windows
-#ifndef __APPLE__
- if (event.key.keysym.mod & KMOD_LALT)
-#else
- if (event.key.keysym.mod & KMOD_LMETA)
-#endif
- {
- switch (event.key.keysym.sym)
- {
- case SDLK_p:
+ case KeyboardConfig::KEY_WINDOW_EMOTE:
+ requestedWindow = emoteWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_EMOTE_SHORTCUT:
+ requestedWindow = emoteShortcutWindow;
+ break;
+ case KeyboardConfig::KEY_SCREENSHOT:
// Screenshot (picture, hence the p)
saveScreenshot();
used = true;
break;
-
- default:
- break;
-
- case SDLK_f:
+ case KeyboardConfig::KEY_PATHFIND:
// Find path to mouse (debug purpose)
viewport->toggleDebugPath();
used = true;
break;
-
- case SDLK_t:
+ case KeyboardConfig::KEY_TRADE:
// Toggle accepting of incoming trade requests
+ unsigned int deflt = player_relations.getDefault();
+ if (deflt & PlayerRelation::TRADE)
+ {
+ chatWindow->chatLog(
+ _("Ignoring incoming trade requests"),
+ BY_SERVER);
+ deflt &= ~PlayerRelation::TRADE;
+ }
+ else
{
- TradeHandler *th = static_cast<TradeHandler*>(
- mTradeHandler.get());
- th->setAcceptTradeRequests(
- !th->acceptTradeRequests());
+ chatWindow->chatLog(
+ _("Accepting incoming trade requests"),
+ BY_SERVER);
+ deflt |= PlayerRelation::TRADE;
}
+
+ player_relations.setDefault(deflt);
+
used = true;
break;
}
+ }
- // Emotions
- Uint8 emotion;
- switch (event.key.keysym.sym)
- {
- case SDLK_1: emotion = 1; break;
- case SDLK_2: emotion = 2; break;
- case SDLK_3: emotion = 3; break;
- case SDLK_4: emotion = 4; break;
- case SDLK_5: emotion = 5; break;
- case SDLK_6: emotion = 6; break;
- case SDLK_7: emotion = 7; break;
- case SDLK_8: emotion = 8; break;
- case SDLK_9: emotion = 9; break;
- case SDLK_0: emotion = 10; break;
- case SDLK_MINUS: emotion = 11; break;
- case SDLK_EQUALS: emotion = 12; break;
- default: emotion = 0; break;
- }
-
- if (emotion)
- {
- player_node->emote(emotion);
- used = true;
- }
+ if (requestedWindow)
+ {
+ requestedWindow->setVisible(!requestedWindow->isVisible());
+ if (requestedWindow->isVisible())
+ requestedWindow->requestMoveToTop();
+ used = true;
}
}
-
// Quit event
else if (event.type == SDL_QUIT)
{
@@ -801,15 +969,31 @@ void Game::handleInput()
// Moving player around
if (player_node->mAction != Being::DEAD &&
+#ifdef EATHENA_SUPPORT
+ current_npc == 0 &&
+#endif
!chatWindow->isInputFocused())
{
// Get the state of the keyboard keys
keyboard.refreshActiveKeys();
- const Vector &pos = player_node->getPosition();
- Uint16 x = (int) pos.x / 32;
- Uint16 y = (int) pos.y / 32;
+ // Ignore input if either "ignore" key is pressed
+ // Stops the character moving about if the user's window manager
+ // uses "ignore+arrow key" to switch virtual desktops.
+ if (keyboard.isKeyActive(keyboard.KEY_IGNORE_INPUT_1) ||
+ keyboard.isKeyActive(keyboard.KEY_IGNORE_INPUT_2))
+ {
+ 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
@@ -835,6 +1019,7 @@ void Game::handleInput()
direction |= Being::RIGHT;
}
+#ifdef TMWSERV_SUPPORT
// First if player is pressing key for the direction he is already
// going
if (direction == player_node->getWalkingDir())
@@ -854,31 +1039,100 @@ void Game::handleInput()
{
player_node->stopWalking(true);
}
+#else
+ player_node->setWalkingDir(direction);
- // Target the nearest player if 'q' is pressed
- if (keyboard.isKeyActive(keyboard.KEY_TARGET_PLAYER))
+ // Attacking monsters
+ if (keyboard.isKeyActive(keyboard.KEY_ATTACK) ||
+ (joystick && joystick->buttonPressed(0)))
{
- Being *target = beingManager->findNearestLivingBeing(
- player_node, 20, Being::PLAYER);
+ Being *target = beingManager->findNearestLivingBeing(x, y, 20,
+ Being::MONSTER);
- if (target)
+ bool newTarget = !keyboard.isKeyActive(keyboard.KEY_TARGET);
+ // A set target has highest priority
+ if (newTarget || !player_node->getTarget())
{
- player_node->setTarget(target);
+ Uint16 targetX = x, targetY = y;
+
+ switch (player_node->getSpriteDirection())
+ {
+ case DIRECTION_UP : --targetY; break;
+ case DIRECTION_DOWN : ++targetY; break;
+ case DIRECTION_LEFT : --targetX; break;
+ case DIRECTION_RIGHT: ++targetX; break;
+ 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);
}
+
+ 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))
+ if ((keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) ||
+ (joystick && joystick->buttonPressed(3))) &&
+ !keyboard.isKeyActive(keyboard.KEY_TARGET))
{
Being *target = beingManager->findNearestLivingBeing(
x, y, 20, Being::MONSTER);
- if (target)
+ player_node->setTarget(target);
+ }
+
+ // 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);
+
+ player_node->setTarget(target);
+ }
+
+ // Talk to the nearest NPC if 't' pressed
+ if ( keyboard.isKeyActive(keyboard.KEY_TALK) )
+ {
+ if (!npcTextDialog->isVisible() && !npcListDialog->isVisible())
{
- player_node->setTarget(target);
+ Being *target = player_node->getTarget();
+
+ if (!target)
+ {
+ target = beingManager->findNearestLivingBeing(
+ x, y, 20, Being::NPC);
+ }
+
+ if (target)
+ {
+ if (target->getType() == Being::NPC)
+ dynamic_cast<NPC*>(target)->talk();
+ }
}
}
+#ifdef EATHENA_SUPPORT
+ // Stop attacking if shift is pressed
+ if (keyboard.isKeyActive(keyboard.KEY_TARGET))
+ {
+ player_node->stopAttack();
+ }
+#endif
+
if (joystick)
{
if (joystick->buttonPressed(1))