summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game.cpp886
-rw-r--r--src/keyboardconfig.cpp29
-rw-r--r--src/keyboardconfig.h7
3 files changed, 460 insertions, 462 deletions
diff --git a/src/game.cpp b/src/game.cpp
index 1b84833c..f886f859 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -470,488 +470,454 @@ void Game::logic()
void Game::handleInput()
{
if (joystick)
- joystick->update();
+ joystick->update();
// Events
SDL_Event event;
while (SDL_PollEvent(&event))
{
- bool used = false;
-
- // Keyboard events (for discontinuous keys)
- if (event.type == SDL_KEYDOWN)
- {
- gcn::Window *requestedWindow = NULL;
-
- if (setupWindow->isVisible() &&
- keyboard.getNewKeyIndex() > keyboard.KEY_NO_VALUE)
- {
- keyboard.setNewKey((int) event.key.keysym.sym);
- keyboard.callbackNewKey();
- keyboard.setNewKeyIndex(keyboard.KEY_NO_VALUE);
- return;
- }
- // 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:
- // Screenshot (picture, hence the p)
- saveScreenshot();
- used = true;
- break;
-
- default:
- break;
-
- case SDLK_f:
- // Find path to mouse (debug purpose)
- viewport->toggleDebugPath();
- used = true;
- break;
-
- case SDLK_t:
- // 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 {
- chatWindow->chatLog(
- "Accepting incoming trade requests",
- BY_SERVER);
- deflt |= PlayerRelation::TRADE;
- }
-
- player_relations.setDefault(deflt);
- }
- used = true;
- break;
- }
- }
+ bool used = false;
+
+ // Keyboard events (for discontinuous keys)
+ if (event.type == SDL_KEYDOWN)
+ {
+ gcn::Window *requestedWindow = NULL;
+
+ if (setupWindow->isVisible() &&
+ keyboard.getNewKeyIndex() > keyboard.KEY_NO_VALUE)
+ {
+ keyboard.setNewKey((int) event.key.keysym.sym);
+ keyboard.callbackNewKey();
+ keyboard.setNewKeyIndex(keyboard.KEY_NO_VALUE);
+ return;
+ }
+ // 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:
+ // Screenshot (picture, hence the p)
+ saveScreenshot();
+ used = true;
+ break;
+
+ default:
+ break;
+
+ case SDLK_f:
+ // Find path to mouse (debug purpose)
+ viewport->toggleDebugPath();
+ used = true;
+ break;
+
+ case SDLK_t:
+ // 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 {
+ chatWindow->chatLog(
+ "Accepting incoming trade requests",
+ BY_SERVER);
+ deflt |= PlayerRelation::TRADE;
+ }
+
+ player_relations.setDefault(deflt);
+ }
+ used = true;
+ break;
+ }
+ }
- // Smilie
- if (keyboard.isKeyActive(keyboard.KEY_SMILIE))
+ // Smilie
+ if (keyboard.isKeyActive(keyboard.KEY_SMILIE))
+ {
+ // Emotions
+ Uint8 emotion=keyboard.getKeySmilieOffset(event.key.keysym.sym);
+ /**
+ * Later here: increase the size of emotion,
+ * and get the entry from the smiley
+ * shortcut object
+ */
+ if (emotion)
{
- // Emotions
- Uint8 emotion;
- /**
- *
- * Might be simpler to perform as follow
- * emotion=0;
- * const int tKey = keyboard.getKeyIndex(event.key.keysym.sym);
- * if ((tKey <=KeyboardConfig::KEY_SMILEY_12)
- * &&(tKey >=KeyboardConfig::KEY_SMILEY_1)
- * )
- * {
- * emotion= 1+tKey-KeyboardConfig::KEY_SMILEY_1;
- * }
- *
- * But this add constraints over KEY_SMILEY_* allocation
- * (ordering, consecutive positive values)
- * Old story... compiler optimisation
- * or code complexity for update, which one is better ?
- * I won't rely on enum allocation, let's keep the switch,
- * it does not add such undocumented constraints on that enum.
- *
- * Speed consideration ? not even sure!
- */
- const int tKey = keyboard.getKeyIndex(event.key.keysym.sym);
- switch (tKey)
+ player_node->emote(emotion);
+ used = true;
+ }
+ }
+ switch (event.key.keysym.sym)
+ {
+ case SDLK_PAGEUP:
+ if (chatWindow->isVisible())
+ {
+ chatWindow->scroll(-DEFAULT_CHAT_WINDOW_SCROLL);
+ used = true;
+ }
+ break;
+
+ case SDLK_PAGEDOWN:
+ if (chatWindow->isVisible())
+ {
+ chatWindow->scroll(DEFAULT_CHAT_WINDOW_SCROLL);
+ used = true;
+ return;
+ }
+ break;
+
+ case SDLK_F1:
+ // In-game Help
+ if (helpWindow->isVisible())
+ {
+ helpWindow->setVisible(false);
+ }
+ else
+ {
+ helpWindow->loadHelp("index");
+ helpWindow->requestMoveToTop();
+ }
+ used = true;
+ break;
+
+ case SDLK_RETURN:
+ // Input chat window
+ if (chatWindow->isInputFocused() ||
+ deathNotice != NULL ||
+ weightNotice != NULL)
+ {
+ break;
+ }
+
+ // Quit by pressing Enter if the exit confirm is there
+ if (exitConfirm)
+ {
+ done = true;
+ }
+ // Close the Browser if opened
+ else if (helpWindow->isVisible())
+ {
+ helpWindow->setVisible(false);
+ }
+ // Close the config window, cancelling changes if opened
+ else if (setupWindow->isVisible())
+ {
+ setupWindow->action(gcn::ActionEvent(NULL, "cancel"));
+ }
+ // Proceed to the next dialog option, or close the window
+ else if (npcTextDialog->isVisible())
+ {
+ npcTextDialog->action(gcn::ActionEvent(NULL, "ok"));
+ }
+ // Choose the currently highlighted dialogue option
+ else if (npcListDialog->isVisible())
+ {
+ npcListDialog->action(gcn::ActionEvent(NULL, "ok"));
+ }
+ // Else, open the chat edit box
+ else
+ {
+ chatWindow->requestChatFocus();
+ used = true;
+ }
+ break;
+ // Quitting confirmation dialog
+ case SDLK_ESCAPE:
+ 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"));
+ }
+ break;
+
+ default:
+ break;
+ }
+ if (keyboard.isEnabled() && !chatWindow->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++)
+ {
+ if (tKey == i && !used) {
+ itemShortcut->useItem(
+ i - KeyboardConfig::KEY_SHORTCUT_0);
+ break;
+ }
+ }
+ }
+ switch (tKey) {
+ case KeyboardConfig::KEY_PICKUP:
{
- case KeyboardConfig::KEY_SMILEY_1: emotion = 1; break;
- case KeyboardConfig::KEY_SMILEY_2: emotion = 2; break;
- case KeyboardConfig::KEY_SMILEY_3: emotion = 3; break;
- case KeyboardConfig::KEY_SMILEY_4: emotion = 4; break;
- case KeyboardConfig::KEY_SMILEY_5: emotion = 5; break;
- case KeyboardConfig::KEY_SMILEY_6: emotion = 6; break;
- case KeyboardConfig::KEY_SMILEY_7: emotion = 7; break;
- case KeyboardConfig::KEY_SMILEY_8: emotion = 8; break;
- case KeyboardConfig::KEY_SMILEY_9: emotion = 9; break;
- case KeyboardConfig::KEY_SMILEY_10: emotion = 10; break;
- case KeyboardConfig::KEY_SMILEY_11: emotion = 11; break;
- case KeyboardConfig::KEY_SMILEY_12: emotion = 12; break;
- default: emotion = 0; break;
+ FloorItem *item =
+ floorItemManager->findByCoordinates(
+ player_node->mX, player_node->mY);
+
+ // 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);
+ }
+
+ if (item)
+ player_node->pickUp(item);
+
+ used = true;
}
-
- if (emotion)
+ break;
+ case KeyboardConfig::KEY_SIT:
+ // Player sit action
+ player_node->toggleSit();
+ used = true;
+ break;
+ case KeyboardConfig::KEY_HIDE_WINDOWS:
+ // Hide certain windows
+ if (!chatWindow->isInputFocused())
{
- player_node->emote(emotion);
- used = true;
+ statusWindow->setVisible(false);
+ inventoryWindow->setVisible(false);
+ skillDialog->setVisible(false);
+ setupWindow->setVisible(false);
+ equipmentWindow->setVisible(false);
+ helpWindow->setVisible(false);
+ debugWindow->setVisible(false);
}
+ break;
+
+ case KeyboardConfig::KEY_WINDOW_STATUS:
+ requestedWindow = statusWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_INVENTORY:
+ requestedWindow = inventoryWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_EQUIPMENT:
+ requestedWindow = equipmentWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_SKILL:
+ requestedWindow = skillDialog;
+ break;
+ case KeyboardConfig::KEY_WINDOW_MINIMAP:
+ requestedWindow = minimap;
+ break;
+ case KeyboardConfig::KEY_WINDOW_CHAT:
+ requestedWindow = chatWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_SHORTCUT:
+ requestedWindow = itemShortcutWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_SETUP:
+ requestedWindow = setupWindow;
+ break;
+ case KeyboardConfig::KEY_WINDOW_DEBUG:
+ requestedWindow = debugWindow;
+ break;
}
- switch (event.key.keysym.sym)
- {
- case SDLK_PAGEUP:
- if (chatWindow->isVisible())
- {
- chatWindow->scroll(-DEFAULT_CHAT_WINDOW_SCROLL);
- used = true;
- }
- break;
-
- case SDLK_PAGEDOWN:
- if (chatWindow->isVisible())
- {
- chatWindow->scroll(DEFAULT_CHAT_WINDOW_SCROLL);
- used = true;
- return;
- }
- break;
-
- case SDLK_F1:
- // In-game Help
- if (helpWindow->isVisible())
- {
- helpWindow->setVisible(false);
- }
- else
- {
- helpWindow->loadHelp("index");
- helpWindow->requestMoveToTop();
- }
- used = true;
- break;
-
- case SDLK_RETURN:
- // Input chat window
- if (chatWindow->isInputFocused() ||
- deathNotice != NULL ||
- weightNotice != NULL)
- {
- break;
- }
-
- // Quit by pressing Enter if the exit confirm is there
- if (exitConfirm)
- {
- done = true;
- }
- // Close the Browser if opened
- else if (helpWindow->isVisible())
- {
- helpWindow->setVisible(false);
- }
- // Close the config window, cancelling changes if opened
- else if (setupWindow->isVisible())
- {
- setupWindow->action(gcn::ActionEvent(NULL, "cancel"));
- }
- // Proceed to the next dialog option, or close the window
- else if (npcTextDialog->isVisible())
- {
- npcTextDialog->action(gcn::ActionEvent(NULL, "ok"));
- }
- // Choose the currently highlighted dialogue option
- else if (npcListDialog->isVisible())
- {
- npcListDialog->action(gcn::ActionEvent(NULL, "ok"));
- }
- // Else, open the chat edit box
- else
- {
- chatWindow->requestChatFocus();
- used = true;
- }
- break;
- // Quitting confirmation dialog
- case SDLK_ESCAPE:
- 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"));
- }
- break;
-
- default:
- break;
- }
- if (keyboard.isEnabled() && !chatWindow->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++)
- {
- if (tKey == i && !used) {
- itemShortcut->useItem(
- i - KeyboardConfig::KEY_SHORTCUT_0);
- break;
- }
- }
- }
- switch (tKey) {
- case KeyboardConfig::KEY_PICKUP:
- {
- FloorItem *item =
- floorItemManager->findByCoordinates(
- player_node->mX, player_node->mY);
-
- // 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);
- }
-
- if (item)
- player_node->pickUp(item);
-
- used = true;
- }
- break;
- case KeyboardConfig::KEY_SIT:
- // Player sit action
- player_node->toggleSit();
- used = true;
- break;
- case KeyboardConfig::KEY_HIDE_WINDOWS:
- // Hide certain windows
- if (!chatWindow->isInputFocused())
- {
- statusWindow->setVisible(false);
- inventoryWindow->setVisible(false);
- skillDialog->setVisible(false);
- setupWindow->setVisible(false);
- equipmentWindow->setVisible(false);
- helpWindow->setVisible(false);
- debugWindow->setVisible(false);
- }
- break;
-
- case KeyboardConfig::KEY_WINDOW_STATUS:
- requestedWindow = statusWindow;
- break;
- case KeyboardConfig::KEY_WINDOW_INVENTORY:
- requestedWindow = inventoryWindow;
- break;
- case KeyboardConfig::KEY_WINDOW_EQUIPMENT:
- requestedWindow = equipmentWindow;
- break;
- case KeyboardConfig::KEY_WINDOW_SKILL:
- requestedWindow = skillDialog;
- break;
- case KeyboardConfig::KEY_WINDOW_MINIMAP:
- requestedWindow = minimap;
- break;
- case KeyboardConfig::KEY_WINDOW_CHAT:
- requestedWindow = chatWindow;
- break;
- case KeyboardConfig::KEY_WINDOW_SHORTCUT:
- requestedWindow = itemShortcutWindow;
- break;
- case KeyboardConfig::KEY_WINDOW_SETUP:
- requestedWindow = setupWindow;
- break;
- case KeyboardConfig::KEY_WINDOW_DEBUG:
- requestedWindow = debugWindow;
- break;
- }
- }
-
- if (requestedWindow)
- {
- requestedWindow->setVisible(!requestedWindow->isVisible());
- if (requestedWindow->isVisible())
- {
- requestedWindow->requestMoveToTop();
- }
- used = true;
- }
-
- }
-
- // Quit event
- else if (event.type == SDL_QUIT)
- {
- done = true;
- }
+ }
- // Push input to GUI when not used
- if (!used)
- {
- try
- {
- guiInput->pushInput(event);
- }
- catch (gcn::Exception e)
- {
- const char* err = e.getMessage().c_str();
- logger->log("Warning: guichan input exception: %s", err);
- }
- }
+ if (requestedWindow)
+ {
+ requestedWindow->setVisible(!requestedWindow->isVisible());
+ if (requestedWindow->isVisible())
+ {
+ requestedWindow->requestMoveToTop();
+ }
+ used = true;
+ }
+
+ }
+
+ // Quit event
+ else if (event.type == SDL_QUIT)
+ {
+ done = true;
+ }
+
+ // Push input to GUI when not used
+ if (!used)
+ {
+ try
+ {
+ guiInput->pushInput(event);
+ }
+ catch (gcn::Exception e)
+ {
+ const char* err = e.getMessage().c_str();
+ logger->log("Warning: guichan input exception: %s", err);
+ }
+ }
} // End while
// If the user is configuring the keys then don't respond.
if (!keyboard.isEnabled())
- return;
+ return;
// Moving player around
if (player_node->mAction != Being::DEAD &&
- current_npc == 0 &&
- !chatWindow->isInputFocused())
+ current_npc == 0 &&
+ !chatWindow->isInputFocused())
{
- // Get the state of the keyboard keys
- keyboard.refreshActiveKeys();
-
- const Uint16 x = player_node->mX;
- const Uint16 y = player_node->mY;
- unsigned char direction = 0;
-
- // Translate pressed keys to movement and direction
- if (keyboard.isKeyActive(keyboard.KEY_MOVE_UP) ||
- (joystick && joystick->isUp()))
- {
- direction |= Being::UP;
- }
- else if (keyboard.isKeyActive(keyboard.KEY_MOVE_DOWN) ||
- (joystick && joystick->isDown()))
- {
- direction |= Being::DOWN;
- }
-
- if (keyboard.isKeyActive(keyboard.KEY_MOVE_LEFT) ||
- (joystick && joystick->isLeft()))
- {
- direction |= Being::LEFT;
- }
- else if (keyboard.isKeyActive(keyboard.KEY_MOVE_RIGHT) ||
- (joystick && joystick->isRight()))
- {
- direction |= Being::RIGHT;
- }
-
- 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);
-
- bool newTarget = !keyboard.isKeyActive(keyboard.KEY_TARGET);
- // A set target has highest priority
- if (newTarget || !player_node->getTarget())
- {
- 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);
- }
-
- // 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))
- {
- Being *target = beingManager->findNearestLivingBeing(
- x, y, 20, Being::MONSTER);
-
- 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())
- {
- 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();
- }
- }
- }
-
- // Stop attacking if shift is pressed
- if (keyboard.isKeyActive(keyboard.KEY_TARGET))
- {
- player_node->stopAttack();
- }
+ // Get the state of the keyboard keys
+ keyboard.refreshActiveKeys();
+
+ const Uint16 x = player_node->mX;
+ const Uint16 y = player_node->mY;
+ unsigned char direction = 0;
+
+ // Translate pressed keys to movement and direction
+ if (keyboard.isKeyActive(keyboard.KEY_MOVE_UP) ||
+ (joystick && joystick->isUp()))
+ {
+ direction |= Being::UP;
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_MOVE_DOWN) ||
+ (joystick && joystick->isDown()))
+ {
+ direction |= Being::DOWN;
+ }
+
+ if (keyboard.isKeyActive(keyboard.KEY_MOVE_LEFT) ||
+ (joystick && joystick->isLeft()))
+ {
+ direction |= Being::LEFT;
+ }
+ else if (keyboard.isKeyActive(keyboard.KEY_MOVE_RIGHT) ||
+ (joystick && joystick->isRight()))
+ {
+ direction |= Being::RIGHT;
+ }
+
+ 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);
+
+ bool newTarget = !keyboard.isKeyActive(keyboard.KEY_TARGET);
+ // A set target has highest priority
+ if (newTarget || !player_node->getTarget())
+ {
+ 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;
+ }
- if (joystick)
- {
- if (joystick->buttonPressed(1))
- {
- FloorItem *item = floorItemManager->findByCoordinates(x, y);
+ // 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);
+ }
+
+ // 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))
+ {
+ Being *target = beingManager->findNearestLivingBeing(
+ x, y, 20, Being::MONSTER);
+
+ 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())
+ {
+ Being *target = player_node->getTarget();
+
+ if (!target)
+ {
+ target = beingManager->findNearestLivingBeing(
+ x, y, 20, Being::NPC);
+ }
- if (item)
- player_node->pickUp(item);
- }
- else if (joystick->buttonPressed(2))
- {
- player_node->toggleSit();
- }
- }
+ if (target)
+ {
+ if (target->getType() == Being::NPC)
+ dynamic_cast<NPC*>(target)->talk();
+ }
+ }
+ }
+
+ // Stop attacking if shift is pressed
+ if (keyboard.isKeyActive(keyboard.KEY_TARGET))
+ {
+ player_node->stopAttack();
+ }
+
+ if (joystick)
+ {
+ if (joystick->buttonPressed(1))
+ {
+ FloorItem *item = floorItemManager->findByCoordinates(x, y);
+
+ if (item)
+ player_node->pickUp(item);
+ }
+ else if (joystick->buttonPressed(2))
+ {
+ player_node->toggleSit();
+ }
+ }
}
}
diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp
index d23410bd..930d8944 100644
--- a/src/keyboardconfig.cpp
+++ b/src/keyboardconfig.cpp
@@ -128,11 +128,24 @@ void KeyboardConfig::makeDefault()
bool KeyboardConfig::hasConflicts()
{
int i, j;
+/**
+ * No need to parse the square matrix: only check one triangle
+ * that's enough to detect conflicts
+ */
for (i = 0; i < KEY_TOTAL; i++)
{
- for (j = 0; j < KEY_TOTAL; j++)
+ for (j = i,j++; j < KEY_TOTAL; j++)
{
- if (i != j && mKey[i].value == mKey[j].value)
+/**
+ * KEY_SMILEY_* are separated from other keys, duplicate in different
+ * area is allowed, but not in same area (of course)
+ * (i.e.: not two identical key for smiley, not two identical for other;
+ * but same key for a smiley and a not-smiley is ok)
+ *
+ */
+ if (!((i<KEY_SMILEY_1)&&(j>=KEY_SMILEY_1))
+ && mKey[i].value == mKey[j].value
+ )
{
return true;
}
@@ -158,6 +171,18 @@ int KeyboardConfig::getKeyIndex(int keyValue) const
return KEY_NO_VALUE;
}
+int KeyboardConfig::getKeySmilieOffset(int keyValue) const
+{
+ for (int i = KEY_SMILEY_1; i <= KEY_SMILEY_12; i++)
+ {
+ if(keyValue == mKey[i].value)
+ {
+ return 1+i-KEY_SMILEY_1;
+ }
+ }
+ return KEY_NO_VALUE;
+}
+
bool KeyboardConfig::isKeyActive(int index)
{
return mActiveKeys[ mKey[index].value];
diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h
index 08c1dba7..a0b67f5d 100644
--- a/src/keyboardconfig.h
+++ b/src/keyboardconfig.h
@@ -102,6 +102,11 @@ class KeyboardConfig
int getKeyIndex(int keyValue) const;
/**
+ * Get the key function index for smiley by providing the offset value.
+ */
+ int getKeySmilieOffset(int keyValue) const;
+
+ /**
* Set the enable flag, which will stop the user from doing actions.
*/
void setEnabled(bool flag)
@@ -141,6 +146,8 @@ class KeyboardConfig
* KEY_TOTAL should always be last (used as a conditional in loops).
* The key assignment view gets arranged according to the order of
* these values.
+ *
+ * KEY_SMILEY_* must be also at the end (just before KEY_TOTAL)
*/
enum KeyAction {
KEY_NO_VALUE = -1,