diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game.cpp | 1297 | ||||
-rw-r--r-- | src/game.h | 8 |
2 files changed, 668 insertions, 637 deletions
diff --git a/src/game.cpp b/src/game.cpp index 042bd2423..683ba418b 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -702,753 +702,599 @@ void Game::resetAdjustLevel() mAdjustLevel = 0; } -/** - * The huge input handling method. - */ -void Game::handleInput() +bool Game::handleOutfitsKeys(SDL_Event &event, bool &used) { - if (joystick) - joystick->update(); - - bool wasDown(false); - // Events - SDL_Event event; - while (SDL_PollEvent(&event)) + if (keyboard.isEnabled() + && !chatWindow->isInputFocused() + && !setupWindow->isVisible() + && !player_node->getAway() + && !NpcDialog::isAnyInputFocused() + && !InventoryWindow::isAnyInputFocused()) { - bool used = false; + bool wearOutfit = false; + bool copyOutfit = false; + if (keyboard.isKeyActive(keyboard.KEY_WEAR_OUTFIT)) + wearOutfit = true; - updateHistory(event); - checkKeys(); + if (keyboard.isKeyActive(keyboard.KEY_COPY_OUTFIT)) + copyOutfit = true; - // Keyboard events (for discontinuous keys) - if (event.type == SDL_KEYDOWN) + if (wearOutfit || copyOutfit) { - wasDown = true; - gcn::Window *requestedWindow = nullptr; + int outfitNum = outfitWindow->keyToNumber( + event.key.keysym.sym); + if (outfitNum >= 0) + { + used = true; + if (wearOutfit) + outfitWindow->wearOutfit(outfitNum); + else if (copyOutfit) + outfitWindow->copyOutfit(outfitNum); + } + else + { + if (keyboard.isKeyActive(keyboard.KEY_MOVE_RIGHT)) + outfitWindow->wearNextOutfit(); + else if (keyboard.isKeyActive(keyboard.KEY_MOVE_LEFT)) + outfitWindow->wearPreviousOutfit(); + } + setValidSpeed(); + return true; + } + else if (keyboard.isKeyActive(keyboard.KEY_MOVE_TO_POINT)) + { + int num = outfitWindow->keyToNumber( + event.key.keysym.sym); + if (socialWindow && num >= 0) + { + socialWindow->selectPortal(num); + return true; + } + } + } + return false; +} - if (setupWindow && setupWindow->isVisible() && - keyboard.getNewKeyIndex() > keyboard.KEY_NO_VALUE) +bool Game::handleSwitchKeys(SDL_Event &event, bool &used) +{ + if ((!chatWindow || !chatWindow->isInputFocused()) + && !gui->getFocusHandler()->getModalFocused() + && !player_node->getAway()) + { + NpcDialog *dialog = NpcDialog::getActive(); + if (keyboard.isKeyActive(keyboard.KEY_OK) + && (!dialog || !dialog->isTextInputFocused())) + { + // Close the Browser if opened + if (helpWindow->isVisible()) + helpWindow->setVisible(false); + // Close the config window, cancelling changes if opened + else if (setupWindow->isVisible()) { - keyboard.setNewKey(static_cast<int>(event.key.keysym.sym)); - keyboard.callbackNewKey(); - keyboard.setNewKeyIndex(keyboard.KEY_NO_VALUE); - return; + setupWindow->action(gcn::ActionEvent( + nullptr, "cancel")); + } + else if (dialog) + { + dialog->action(gcn::ActionEvent(nullptr, "ok")); + } + } + if (chatWindow && keyboard.isKeyActive( + keyboard.KEY_TOGGLE_CHAT)) + { + if (!InventoryWindow::isAnyInputFocused()) + { + if (chatWindow->requestChatFocus()) + used = true; } + } + if (dialog) + { + if (keyboard.isKeyActive(keyboard.KEY_MOVE_UP)) + dialog->move(1); + else if (keyboard.isKeyActive(keyboard.KEY_MOVE_DOWN)) + dialog->move(-1); + } + } - // send straight to gui for certain windows - if (quitDialog || TextDialog::isActive() || - NpcPostDialog::isActive()) + if (chatWindow && ((!chatWindow->isInputFocused() && + !NpcDialog::isAnyInputFocused() && + !InventoryWindow::isAnyInputFocused()) + || (event.key.keysym.mod & KMOD_ALT))) + { + if (keyboard.isKeyActive(keyboard.KEY_PREV_CHAT_TAB)) + { + chatWindow->prevTab(); + return true; + } + else if (keyboard.isKeyActive(keyboard.KEY_NEXT_CHAT_TAB)) + { + chatWindow->nextTab(); + return true; + } + else if (keyboard.isKeyActive(keyboard.KEY_PREV_SOCIAL_TAB)) + { + socialWindow->prevTab(); + return true; + } + else if (keyboard.isKeyActive(keyboard.KEY_NEXT_SOCIAL_TAB)) + { + socialWindow->nextTab(); + return true; + } + else if (keyboard.isKeyActive(keyboard.KEY_CLOSE_CHAT_TAB)) + { + chatWindow->closeTab(); + return true; + } + } + + const int tKey = keyboard.getKeyIndex(event.key.keysym.sym); + switch (tKey) + { + case KeyboardConfig::KEY_SCROLL_CHAT_UP: + if (chatWindow && chatWindow->isVisible()) { - try + chatWindow->scroll(-DEFAULT_CHAT_WINDOW_SCROLL); + used = true; + } + break; + case KeyboardConfig::KEY_SCROLL_CHAT_DOWN: + if (chatWindow && chatWindow->isVisible()) + { + chatWindow->scroll(DEFAULT_CHAT_WINDOW_SCROLL); + used = true; + return true; + } + break; + case KeyboardConfig::KEY_WINDOW_HELP: + // In-game Help + if (helpWindow) + { + if (helpWindow->isVisible()) { - guiInput->pushInput(event); + helpWindow->setVisible(false); } - catch (const gcn::Exception &e) + else { - const char* err = e.getMessage().c_str(); - logger->log("Warning: guichan input exception: %s", err); + helpWindow->loadHelp("index"); + helpWindow->requestMoveToTop(); } - return; - } - - if (chatWindow && !chatWindow->isInputFocused() - && keyboard.isKeyActive(keyboard.KEY_RIGHT_CLICK)) - { - int mouseX, mouseY; - SDL_GetMouseState(&mouseX, &mouseY); - - gcn::MouseEvent event2(viewport, false, false, false, false, - 0, gcn::MouseEvent::RIGHT, mouseX, mouseY, 1); - if (viewport) - viewport->mousePressed(event2); - continue; } - - // Mode switch to emotes - if (keyboard.isKeyActive(keyboard.KEY_EMOTE)) + used = true; + break; + // Quitting confirmation dialog + case KeyboardConfig::KEY_QUIT: + if (!chatWindow || !chatWindow->isInputFocused()) { - // Emotions - int emotion = keyboard.getKeyEmoteOffset(event.key.keysym.sym); - if (emotion) + if (viewport && viewport->isPopupMenuVisible()) { - if (emoteShortcut) - emoteShortcut->useEmote(emotion); - used = true; - setValidSpeed(); - return; + viewport->closePopupMenu(); + } + else + { + quitDialog = new QuitDialog(&quitDialog); + quitDialog->requestMoveToTop(); } + return true; } + break; + default: + break; + } - if (keyboard.isEnabled() - && !chatWindow->isInputFocused() - && !setupWindow->isVisible() - && !player_node->getAway() - && !NpcDialog::isAnyInputFocused() - && !InventoryWindow::isAnyInputFocused()) + if (keyboard.isEnabled() + && (!chatWindow || !chatWindow->isInputFocused()) + && !NpcDialog::isAnyInputFocused() + && (!player_node || !player_node->getAway())) + { + if (!gui->getFocusHandler()->getModalFocused() + && mValidSpeed + && (!setupWindow || !setupWindow->isVisible()) + && !InventoryWindow::isAnyInputFocused()) + { + switch (tKey) { - bool wearOutfit = false; - bool copyOutfit = false; - if (keyboard.isKeyActive(keyboard.KEY_WEAR_OUTFIT)) - wearOutfit = true; + case KeyboardConfig::KEY_QUICK_DROP: + if (dropShortcut) + dropShortcut->dropFirst(); + break; - if (keyboard.isKeyActive(keyboard.KEY_COPY_OUTFIT)) - copyOutfit = true; + case KeyboardConfig::KEY_QUICK_DROPN: + if (dropShortcut) + dropShortcut->dropItems(); + break; - if (wearOutfit || copyOutfit) - { - int outfitNum = outfitWindow->keyToNumber( - event.key.keysym.sym); - if (outfitNum >= 0) + case KeyboardConfig::KEY_SWITCH_QUICK_DROP: + if (player_node) { - used = true; - if (wearOutfit) - outfitWindow->wearOutfit(outfitNum); - else if (copyOutfit) - outfitWindow->copyOutfit(outfitNum); + if (!player_node->getDisableGameModifiers()) + player_node->changeQuickDropCounter(); } - else + break; + + case KeyboardConfig::KEY_MAGIC_INMA1: + if (actorSpriteManager) + actorSpriteManager->healTarget(); + setValidSpeed(); + break; + + case KeyboardConfig::KEY_MAGIC_ITENPLZ: + if (Net::getPlayerHandler()->canUseMagic() + && PlayerInfo::getAttribute(MP) >= 3) { - if (keyboard.isKeyActive(keyboard.KEY_MOVE_RIGHT)) - outfitWindow->wearNextOutfit(); - else if (keyboard.isKeyActive(keyboard.KEY_MOVE_LEFT)) - outfitWindow->wearPreviousOutfit(); + actorSpriteManager->itenplz(); } setValidSpeed(); - continue; - } - else if (keyboard.isKeyActive(keyboard.KEY_MOVE_TO_POINT)) - { - int num = outfitWindow->keyToNumber( - event.key.keysym.sym); - if (socialWindow && num >= 0) + break; + + case KeyboardConfig::KEY_CRAZY_MOVES: + if (player_node) + player_node->crazyMove(); + break; + + case KeyboardConfig::KEY_CHANGE_CRAZY_MOVES_TYPE: + if (player_node) { - socialWindow->selectPortal(num); - continue; + if (!player_node->getDisableGameModifiers()) + player_node->changeCrazyMoveType(); } - } - } + break; - if ((!chatWindow || !chatWindow->isInputFocused()) - && !gui->getFocusHandler()->getModalFocused() - && !player_node->getAway()) - { - NpcDialog *dialog = NpcDialog::getActive(); - if (keyboard.isKeyActive(keyboard.KEY_OK) - && (!dialog || !dialog->isTextInputFocused())) - { - // Close the Browser if opened - if (helpWindow->isVisible()) - helpWindow->setVisible(false); - // Close the config window, cancelling changes if opened - else if (setupWindow->isVisible()) + case KeyboardConfig::KEY_CHANGE_PICKUP_TYPE: + if (player_node) { - setupWindow->action(gcn::ActionEvent( - nullptr, "cancel")); + if (!player_node->getDisableGameModifiers()) + player_node->changePickUpType(); } - else if (dialog) + break; + + case KeyboardConfig::KEY_MOVE_TO_TARGET: + if (player_node) { - dialog->action(gcn::ActionEvent(nullptr, "ok")); + if (!keyboard.isKeyActive( + keyboard.KEY_TARGET_ATTACK) + && !keyboard.isKeyActive(keyboard.KEY_ATTACK)) + { + player_node->moveToTarget(); + } } - } - if (chatWindow && keyboard.isKeyActive( - keyboard.KEY_TOGGLE_CHAT)) - { - if (!InventoryWindow::isAnyInputFocused()) + break; + + case KeyboardConfig::KEY_MOVE_TO_HOME: + if (player_node) { - if (chatWindow->requestChatFocus()) - used = true; + if (!keyboard.isKeyActive( + keyboard.KEY_TARGET_ATTACK) + && !keyboard.isKeyActive(keyboard.KEY_ATTACK)) + { + player_node->moveToHome(); + } + setValidSpeed(); } - } - if (dialog) - { - if (keyboard.isKeyActive(keyboard.KEY_MOVE_UP)) - dialog->move(1); - else if (keyboard.isKeyActive(keyboard.KEY_MOVE_DOWN)) - dialog->move(-1); - } - } + break; - if (chatWindow && ((!chatWindow->isInputFocused() && - !NpcDialog::isAnyInputFocused() && - !InventoryWindow::isAnyInputFocused()) - || (event.key.keysym.mod & KMOD_ALT))) - { - if (keyboard.isKeyActive(keyboard.KEY_PREV_CHAT_TAB)) - { - chatWindow->prevTab(); - return; - } - else if (keyboard.isKeyActive(keyboard.KEY_NEXT_CHAT_TAB)) - { - chatWindow->nextTab(); - return; - } - else if (keyboard.isKeyActive(keyboard.KEY_PREV_SOCIAL_TAB)) - { - socialWindow->prevTab(); - return; - } - else if (keyboard.isKeyActive(keyboard.KEY_NEXT_SOCIAL_TAB)) - { - socialWindow->nextTab(); - return; - } - else if (keyboard.isKeyActive(keyboard.KEY_CLOSE_CHAT_TAB)) - { - chatWindow->closeTab(); - return; - } - } + case KeyboardConfig::KEY_SET_HOME: + if (player_node) + player_node->setHome(); + break; - const int tKey = keyboard.getKeyIndex(event.key.keysym.sym); - switch (tKey) - { - case KeyboardConfig::KEY_SCROLL_CHAT_UP: - if (chatWindow && chatWindow->isVisible()) + case KeyboardConfig::KEY_INVERT_DIRECTION: + if (player_node) { - chatWindow->scroll(-DEFAULT_CHAT_WINDOW_SCROLL); - used = true; + if (!player_node->getDisableGameModifiers()) + player_node->invertDirection(); } break; - case KeyboardConfig::KEY_SCROLL_CHAT_DOWN: - if (chatWindow && chatWindow->isVisible()) + + case KeyboardConfig::KEY_CHANGE_ATTACK_WEAPON_TYPE: + if (player_node) { - chatWindow->scroll(DEFAULT_CHAT_WINDOW_SCROLL); - used = true; - return; + if (!player_node->getDisableGameModifiers()) + player_node->changeAttackWeaponType(); } break; - case KeyboardConfig::KEY_WINDOW_HELP: - // In-game Help - if (helpWindow) + + case KeyboardConfig::KEY_CHANGE_ATTACK_TYPE: + if (player_node) { - if (helpWindow->isVisible()) - { - helpWindow->setVisible(false); - } - else - { - helpWindow->loadHelp("index"); - helpWindow->requestMoveToTop(); - } + if (!player_node->getDisableGameModifiers()) + player_node->changeAttackType(); } - used = true; break; - // Quitting confirmation dialog - case KeyboardConfig::KEY_QUIT: - if (!chatWindow || !chatWindow->isInputFocused()) + + case KeyboardConfig::KEY_CHANGE_FOLLOW_MODE: + if (player_node) { - if (viewport && viewport->isPopupMenuVisible()) - { - viewport->closePopupMenu(); - } - else - { - quitDialog = new QuitDialog(&quitDialog); - quitDialog->requestMoveToTop(); - } - return; + if (!player_node->getDisableGameModifiers()) + player_node->changeFollowMode(); } break; - default: + + case KeyboardConfig::KEY_CHANGE_IMITATION_MODE: + if (player_node) + { + if (!player_node->getDisableGameModifiers()) + player_node->changeImitationMode(); + } break; - } - if (keyboard.isEnabled() && (!chatWindow - || !chatWindow->isInputFocused()) - && !gui->getFocusHandler()->getModalFocused() - && mValidSpeed - && (!setupWindow || !setupWindow->isVisible()) - && (!player_node || !player_node->getAway()) - && !NpcDialog::isAnyInputFocused() - && !InventoryWindow::isAnyInputFocused()) - { - switch (tKey) - { - case KeyboardConfig::KEY_QUICK_DROP: - if (dropShortcut) - dropShortcut->dropFirst(); - break; + case KeyboardConfig::KEY_MAGIC_ATTACK: + if (player_node) + player_node->magicAttack(); + break; - case KeyboardConfig::KEY_QUICK_DROPN: - if (dropShortcut) - dropShortcut->dropItems(); - break; + case KeyboardConfig::KEY_SWITCH_MAGIC_ATTACK: + if (player_node) + { + if (!player_node->getDisableGameModifiers()) + player_node->switchMagicAttack(); + } + break; - case KeyboardConfig::KEY_SWITCH_QUICK_DROP: - if (player_node) - { - if (!player_node->getDisableGameModifiers()) - player_node->changeQuickDropCounter(); - } - break; + case KeyboardConfig::KEY_SWITCH_PVP_ATTACK: + if (player_node) + { + if (!player_node->getDisableGameModifiers()) + player_node->switchPvpAttack(); + } + break; - case KeyboardConfig::KEY_MAGIC_INMA1: - if (actorSpriteManager) - actorSpriteManager->healTarget(); - setValidSpeed(); - break; + case KeyboardConfig::KEY_CHANGE_MOVE_TO_TARGET: + if (player_node) + { + if (!player_node->getDisableGameModifiers()) + player_node->changeMoveToTargetType(); + } + break; - case KeyboardConfig::KEY_MAGIC_ITENPLZ: - if (Net::getPlayerHandler()->canUseMagic() - && PlayerInfo::getAttribute(MP) >= 3) - { - actorSpriteManager->itenplz(); - } - setValidSpeed(); - break; + case KeyboardConfig::KEY_COPY_EQUIPED_OUTFIT: + if (outfitWindow) + outfitWindow->copyFromEquiped(); + break; - case KeyboardConfig::KEY_CRAZY_MOVES: - if (player_node) - player_node->crazyMove(); - break; + case KeyboardConfig::KEY_DISABLE_GAME_MODIFIERS: + if (player_node) + player_node->switchGameModifiers(); + break; - case KeyboardConfig::KEY_CHANGE_CRAZY_MOVES_TYPE: - if (player_node) - { - if (!player_node->getDisableGameModifiers()) - player_node->changeCrazyMoveType(); - } - break; + case KeyboardConfig::KEY_CHANGE_AUDIO: + sound.changeAudio(); + break; - case KeyboardConfig::KEY_CHANGE_PICKUP_TYPE: - if (player_node) - { - if (!player_node->getDisableGameModifiers()) - player_node->changePickUpType(); - } - break; + case KeyboardConfig::KEY_AWAY: + if (player_node) + { + player_node->changeAwayMode(); + setValidSpeed(); + } + break; - case KeyboardConfig::KEY_MOVE_TO_TARGET: - if (player_node) - { - if (!keyboard.isKeyActive( - keyboard.KEY_TARGET_ATTACK) - && !keyboard.isKeyActive(keyboard.KEY_ATTACK)) - { - player_node->moveToTarget(); - } - } - break; + case KeyboardConfig::KEY_CAMERA: + if (player_node && viewport) + { + if (!player_node->getDisableGameModifiers()) + viewport->toggleCameraMode(); + setValidSpeed(); + } + break; - case KeyboardConfig::KEY_MOVE_TO_HOME: - if (player_node) + default: + break; + } + } + + gcn::Window *requestedWindow = nullptr; + + if (!NpcDialog::isAnyInputFocused() + && !keyboard.isKeyActive(keyboard.KEY_TARGET) + && !keyboard.isKeyActive(keyboard.KEY_UNTARGET)) + { + if (setupWindow && setupWindow->isVisible()) + { + if (tKey == KeyboardConfig::KEY_WINDOW_SETUP) + { + setupWindow->doCancel(); + used = true; + } + } + else + { + // Do not activate shortcuts if tradewindow is visible + if (itemShortcutWindow && tradeWindow + && !tradeWindow->isVisible() + && !setupWindow->isVisible()) + { + int num = itemShortcutWindow->getTabIndex(); + if (num >= 0 && num < SHORTCUT_TABS) + { + // Checks if any item shortcut is pressed. + for (int i = KeyboardConfig::KEY_SHORTCUT_1; + i <= KeyboardConfig::KEY_SHORTCUT_20; + i ++) { - if (!keyboard.isKeyActive( - keyboard.KEY_TARGET_ATTACK) - && !keyboard.isKeyActive(keyboard.KEY_ATTACK)) + if (tKey == i && !used) { - player_node->moveToHome(); + itemShortcut[num]->useItem( + i - KeyboardConfig::KEY_SHORTCUT_1); + break; } - setValidSpeed(); } - break; + } + } - case KeyboardConfig::KEY_SET_HOME: + switch (tKey) + { + case KeyboardConfig::KEY_PICKUP: if (player_node) - player_node->setHome(); + player_node->pickUpItems(); + used = true; break; - - case KeyboardConfig::KEY_INVERT_DIRECTION: + case KeyboardConfig::KEY_SIT: + // Player sit action if (player_node) { - if (!player_node->getDisableGameModifiers()) - player_node->invertDirection(); + if (keyboard.isKeyActive(keyboard.KEY_EMOTE)) + player_node->updateSit(); + else + player_node->toggleSit(); } + used = true; break; - - case KeyboardConfig::KEY_CHANGE_ATTACK_WEAPON_TYPE: - if (player_node) + case KeyboardConfig::KEY_HIDE_WINDOWS: + // Hide certain windows + if (!chatWindow || !chatWindow->isInputFocused()) { - if (!player_node->getDisableGameModifiers()) - player_node->changeAttackWeaponType(); + if (statusWindow) + statusWindow->setVisible(false); + if (inventoryWindow) + inventoryWindow->setVisible(false); + if (shopWindow) + shopWindow->setVisible(false); + if (skillDialog) + skillDialog->setVisible(false); + if (setupWindow) + setupWindow->setVisible(false); + if (equipmentWindow) + equipmentWindow->setVisible(false); + if (helpWindow) + helpWindow->setVisible(false); + if (debugWindow) + debugWindow->setVisible(false); + if (outfitWindow) + outfitWindow->setVisible(false); + if (dropShortcutWindow) + dropShortcutWindow->setVisible(false); + if (spellShortcutWindow) + spellShortcutWindow->setVisible(false); + if (botCheckerWindow) + botCheckerWindow->setVisible(false); + if (socialWindow) + socialWindow->setVisible(false); } break; - - case KeyboardConfig::KEY_CHANGE_ATTACK_TYPE: - if (player_node) - { - if (!player_node->getDisableGameModifiers()) - player_node->changeAttackType(); - } + case KeyboardConfig::KEY_WINDOW_STATUS: + requestedWindow = statusWindow; break; - - case KeyboardConfig::KEY_CHANGE_FOLLOW_MODE: - if (player_node) - { - if (!player_node->getDisableGameModifiers()) - player_node->changeFollowMode(); - } + case KeyboardConfig::KEY_WINDOW_INVENTORY: + requestedWindow = inventoryWindow; break; - - case KeyboardConfig::KEY_CHANGE_IMITATION_MODE: - if (player_node) - { - if (!player_node->getDisableGameModifiers()) - player_node->changeImitationMode(); - } + case KeyboardConfig::KEY_WINDOW_SHOP: + requestedWindow = shopWindow; break; - - case KeyboardConfig::KEY_MAGIC_ATTACK: - if (player_node) - player_node->magicAttack(); + case KeyboardConfig::KEY_WINDOW_EQUIPMENT: + requestedWindow = equipmentWindow; break; - - case KeyboardConfig::KEY_SWITCH_MAGIC_ATTACK: - if (player_node) - { - if (!player_node->getDisableGameModifiers()) - player_node->switchMagicAttack(); - } + case KeyboardConfig::KEY_WINDOW_SKILL: + requestedWindow = skillDialog; break; - - case KeyboardConfig::KEY_SWITCH_PVP_ATTACK: - if (player_node) - { - if (!player_node->getDisableGameModifiers()) - player_node->switchPvpAttack(); - } + case KeyboardConfig::KEY_WINDOW_KILLS: + requestedWindow = killStats; break; - - case KeyboardConfig::KEY_CHANGE_MOVE_TO_TARGET: - if (player_node) - { - if (!player_node->getDisableGameModifiers()) - player_node->changeMoveToTargetType(); - } + case KeyboardConfig::KEY_WINDOW_MINIMAP: + minimap->toggle(); break; - - case KeyboardConfig::KEY_COPY_EQUIPED_OUTFIT: - if (outfitWindow) - outfitWindow->copyFromEquiped(); + case KeyboardConfig::KEY_WINDOW_CHAT: + requestedWindow = chatWindow; break; - - case KeyboardConfig::KEY_DISABLE_GAME_MODIFIERS: - if (player_node) - player_node->switchGameModifiers(); + case KeyboardConfig::KEY_WINDOW_SHORTCUT: + requestedWindow = itemShortcutWindow; break; - - case KeyboardConfig::KEY_CHANGE_AUDIO: - sound.changeAudio(); + case KeyboardConfig::KEY_WINDOW_SETUP: + requestedWindow = setupWindow; break; - - case KeyboardConfig::KEY_AWAY: - if (player_node) - { - player_node->changeAwayMode(); - setValidSpeed(); - } + case KeyboardConfig::KEY_WINDOW_DEBUG: + requestedWindow = debugWindow; break; - - case KeyboardConfig::KEY_CAMERA: - if (player_node && viewport) - { - if (!player_node->getDisableGameModifiers()) - viewport->toggleCameraMode(); - setValidSpeed(); - } + case KeyboardConfig::KEY_WINDOW_SOCIAL: + requestedWindow = socialWindow; break; - - default: + case KeyboardConfig::KEY_WINDOW_EMOTE_SHORTCUT: + requestedWindow = emoteShortcutWindow; break; - } - } - - if (keyboard.isEnabled() - && (!chatWindow || !chatWindow->isInputFocused()) - && !NpcDialog::isAnyInputFocused() - && (!player_node || !player_node->getAway()) - && !keyboard.isKeyActive(keyboard.KEY_TARGET) - && !keyboard.isKeyActive(keyboard.KEY_UNTARGET) - && !InventoryWindow::isAnyInputFocused()) - { -// const int tKey = keyboard.getKeyIndex(event.key.keysym.sym); - - if (setupWindow && setupWindow->isVisible()) - { - if (tKey == KeyboardConfig::KEY_WINDOW_SETUP) - { - setupWindow->doCancel(); + case KeyboardConfig::KEY_WINDOW_OUTFIT: + requestedWindow = outfitWindow; + break; + case KeyboardConfig::KEY_WINDOW_DROP: + requestedWindow = dropShortcutWindow; + break; + case KeyboardConfig::KEY_WINDOW_SPELLS: + requestedWindow = spellShortcutWindow; + break; + case KeyboardConfig::KEY_WINDOW_BOT_CHECKER: + requestedWindow = botCheckerWindow; + break; + case KeyboardConfig::KEY_WINDOW_ONLINE: + requestedWindow = whoIsOnline; + break; + case KeyboardConfig::KEY_SCREENSHOT: + // Screenshot (picture, hence the p) + saveScreenshot(); used = true; - } - } - else - { - // Do not activate shortcuts if tradewindow is visible - if (itemShortcutWindow && tradeWindow - && !tradeWindow->isVisible() - && !setupWindow->isVisible()) - { - int num = itemShortcutWindow->getTabIndex(); - if (num >= 0 && num < SHORTCUT_TABS) + break; + case KeyboardConfig::KEY_PATHFIND: + // Find path to mouse (debug purpose) + if (!player_node || !player_node-> + getDisableGameModifiers()) { - // Checks if any item shortcut is pressed. - for (int i = KeyboardConfig::KEY_SHORTCUT_1; - i <= KeyboardConfig::KEY_SHORTCUT_20; - i ++) - { - if (tKey == i && !used) - { - itemShortcut[num]->useItem( - i - KeyboardConfig::KEY_SHORTCUT_1); - break; - } - } + if (viewport) + viewport->toggleDebugPath(); + if (miniStatusWindow) + miniStatusWindow->updateStatus(); + if (mCurrentMap) + mCurrentMap->redrawMap(); + used = true; } - } - - switch (tKey) + break; + case KeyboardConfig::KEY_TRADE: { - case KeyboardConfig::KEY_PICKUP: - if (player_node) - player_node->pickUpItems(); - used = true; - break; - case KeyboardConfig::KEY_SIT: - // Player sit action - if (player_node) - { - if (keyboard.isKeyActive(keyboard.KEY_EMOTE)) - player_node->updateSit(); - else - player_node->toggleSit(); - } - used = true; - break; - case KeyboardConfig::KEY_HIDE_WINDOWS: - // Hide certain windows - if (!chatWindow || !chatWindow->isInputFocused()) - { - if (statusWindow) - statusWindow->setVisible(false); - if (inventoryWindow) - inventoryWindow->setVisible(false); - if (shopWindow) - shopWindow->setVisible(false); - if (skillDialog) - skillDialog->setVisible(false); - if (setupWindow) - setupWindow->setVisible(false); - if (equipmentWindow) - equipmentWindow->setVisible(false); - if (helpWindow) - helpWindow->setVisible(false); - if (debugWindow) - debugWindow->setVisible(false); - if (outfitWindow) - outfitWindow->setVisible(false); - if (dropShortcutWindow) - dropShortcutWindow->setVisible(false); - if (spellShortcutWindow) - spellShortcutWindow->setVisible(false); - if (botCheckerWindow) - botCheckerWindow->setVisible(false); - if (socialWindow) - socialWindow->setVisible(false); - } - break; - case KeyboardConfig::KEY_WINDOW_STATUS: - requestedWindow = statusWindow; - break; - case KeyboardConfig::KEY_WINDOW_INVENTORY: - requestedWindow = inventoryWindow; - break; - case KeyboardConfig::KEY_WINDOW_SHOP: - requestedWindow = shopWindow; - break; - case KeyboardConfig::KEY_WINDOW_EQUIPMENT: - requestedWindow = equipmentWindow; - break; - case KeyboardConfig::KEY_WINDOW_SKILL: - requestedWindow = skillDialog; - break; - case KeyboardConfig::KEY_WINDOW_KILLS: - requestedWindow = killStats; - break; - case KeyboardConfig::KEY_WINDOW_MINIMAP: - minimap->toggle(); - 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; - case KeyboardConfig::KEY_WINDOW_SOCIAL: - requestedWindow = socialWindow; - break; - case KeyboardConfig::KEY_WINDOW_EMOTE_SHORTCUT: - requestedWindow = emoteShortcutWindow; - break; - case KeyboardConfig::KEY_WINDOW_OUTFIT: - requestedWindow = outfitWindow; - break; - case KeyboardConfig::KEY_WINDOW_DROP: - requestedWindow = dropShortcutWindow; - break; - case KeyboardConfig::KEY_WINDOW_SPELLS: - requestedWindow = spellShortcutWindow; - break; - case KeyboardConfig::KEY_WINDOW_BOT_CHECKER: - requestedWindow = botCheckerWindow; - break; - case KeyboardConfig::KEY_WINDOW_ONLINE: - requestedWindow = whoIsOnline; - break; - case KeyboardConfig::KEY_SCREENSHOT: - // Screenshot (picture, hence the p) - saveScreenshot(); - used = true; - break; - case KeyboardConfig::KEY_PATHFIND: - // Find path to mouse (debug purpose) - if (!player_node || !player_node-> - getDisableGameModifiers()) - { - if (viewport) - viewport->toggleDebugPath(); - if (miniStatusWindow) - miniStatusWindow->updateStatus(); - if (mCurrentMap) - mCurrentMap->redrawMap(); - used = true; - } - break; - case KeyboardConfig::KEY_TRADE: + // Toggle accepting of incoming trade requests + unsigned int deflt = player_relations.getDefault(); + if (deflt & PlayerRelation::TRADE) { - // Toggle accepting of incoming trade requests - unsigned int deflt = player_relations.getDefault(); - if (deflt & PlayerRelation::TRADE) + if (localChatTab) { - if (localChatTab) - { - localChatTab->chatLog( - _("Ignoring incoming trade requests"), - BY_SERVER); - } - deflt &= ~PlayerRelation::TRADE; + localChatTab->chatLog( + _("Ignoring incoming trade requests"), + BY_SERVER); } - else + deflt &= ~PlayerRelation::TRADE; + } + else + { + if (localChatTab) { - if (localChatTab) - { - localChatTab->chatLog( - _("Accepting incoming trade requests"), - BY_SERVER); - } - deflt |= PlayerRelation::TRADE; + localChatTab->chatLog( + _("Accepting incoming trade requests"), + BY_SERVER); } - - player_relations.setDefault(deflt); - - used = true; + deflt |= PlayerRelation::TRADE; } - break; - default: - break; - } - } - if (requestedWindow) - { - requestedWindow->setVisible(!requestedWindow->isVisible()); - if (requestedWindow->isVisible()) - requestedWindow->requestMoveToTop(); - used = true; - } - } - } - // Active event - else if (event.type == SDL_ACTIVEEVENT) - { -// logger->log("SDL_ACTIVEEVENT"); -// logger->log("state: %d", (int)event.active.state); -// logger->log("gain: %d", (int)event.active.gain); + player_relations.setDefault(deflt); - int fpsLimit = 0; - if (event.active.state & SDL_APPACTIVE) - { - if (event.active.gain) - { // window restore - Client::setIsMinimized(false); - if (!player_node && !player_node->getAway()) - fpsLimit = config.getIntValue("fpslimit"); - if (player_node) - player_node->setHalfAway(false); - } - else - { // window minimisation - Client::setIsMinimized(true); - if (player_node && !player_node->getAway()) - { - fpsLimit = config.getIntValue("altfpslimit"); - player_node->setHalfAway(true); + used = true; } + break; + default: + break; } - Client::setFramerate(fpsLimit); - } - if (player_node) - player_node->updateName(); - - if (event.active.state & SDL_APPINPUTFOCUS) - Client::setInputFocused(event.active.gain); - if (event.active.state & SDL_APPMOUSEFOCUS) - Client::setMouseFocused(event.active.gain); - - if (player_node && player_node->getAway()) - { - if (Client::getInputFocused() || Client::getMouseFocused()) - fpsLimit = config.getIntValue("fpslimit"); - else - fpsLimit = config.getIntValue("altfpslimit"); - Client::setFramerate(fpsLimit); - } - else - { - fpsLimit = config.getIntValue("fpslimit"); - Client::setFramerate(fpsLimit); } - } - // Quit event - else if (event.type == SDL_QUIT) - { - Client::setState(STATE_EXIT); - } - // Push input to GUI when not used - if (!used) - { - try - { - if (guiInput) - guiInput->pushInput(event); - } - catch (const gcn::Exception &e) + if (requestedWindow) { - const char *err = e.getMessage().c_str(); - logger->log("Warning: guichan input exception: %s", err); + requestedWindow->setVisible(!requestedWindow->isVisible()); + if (requestedWindow->isVisible()) + requestedWindow->requestMoveToTop(); + used = true; } } - - } // End while - - // If the user is configuring the keys then don't respond. - if (!player_node || !keyboard.isEnabled() || player_node->getAway()) - return; - - if (keyboard.isKeyActive(keyboard.KEY_WEAR_OUTFIT) - || keyboard.isKeyActive(keyboard.KEY_COPY_OUTFIT) - || (setupWindow && setupWindow->isVisible())) - { - return; } + return false; +} +void Game::handleMoveAndAttack(SDL_Event &event, bool wasDown) +{ // Moving player around if (player_node->isAlive() && (!Being::isTalking() || keyboard.getKeyIndex(event.key.keysym.sym) @@ -1702,6 +1548,183 @@ void Game::handleInput() } } +void Game::handleActive(SDL_Event &event) +{ +// logger->log("SDL_ACTIVEEVENT"); +// logger->log("state: %d", (int)event.active.state); +// logger->log("gain: %d", (int)event.active.gain); + + int fpsLimit = 0; + if (event.active.state & SDL_APPACTIVE) + { + if (event.active.gain) + { // window restore + Client::setIsMinimized(false); + if (!player_node && !player_node->getAway()) + fpsLimit = config.getIntValue("fpslimit"); + if (player_node) + player_node->setHalfAway(false); + } + else + { // window minimisation + Client::setIsMinimized(true); + if (player_node && !player_node->getAway()) + { + fpsLimit = config.getIntValue("altfpslimit"); + player_node->setHalfAway(true); + } + } + Client::setFramerate(fpsLimit); + } + if (player_node) + player_node->updateName(); + + if (event.active.state & SDL_APPINPUTFOCUS) + Client::setInputFocused(event.active.gain); + if (event.active.state & SDL_APPMOUSEFOCUS) + Client::setMouseFocused(event.active.gain); + + if (player_node && player_node->getAway()) + { + if (Client::getInputFocused() || Client::getMouseFocused()) + fpsLimit = config.getIntValue("fpslimit"); + else + fpsLimit = config.getIntValue("altfpslimit"); + Client::setFramerate(fpsLimit); + } + else + { + fpsLimit = config.getIntValue("fpslimit"); + Client::setFramerate(fpsLimit); + } +} + +/** + * The huge input handling method. + */ +void Game::handleInput() +{ + if (joystick) + joystick->update(); + + bool wasDown(false); + // Events + SDL_Event event; + while (SDL_PollEvent(&event)) + { + bool used = false; + + updateHistory(event); + checkKeys(); + + // Keyboard events (for discontinuous keys) + if (event.type == SDL_KEYDOWN) + { + wasDown = true; + + if (setupWindow && setupWindow->isVisible() && + keyboard.getNewKeyIndex() > keyboard.KEY_NO_VALUE) + { + keyboard.setNewKey(static_cast<int>(event.key.keysym.sym)); + keyboard.callbackNewKey(); + keyboard.setNewKeyIndex(keyboard.KEY_NO_VALUE); + return; + } + + // send straight to gui for certain windows + if (quitDialog || TextDialog::isActive() || + NpcPostDialog::isActive()) + { + try + { + guiInput->pushInput(event); + } + catch (const gcn::Exception &e) + { + const char* err = e.getMessage().c_str(); + logger->log("Warning: guichan input exception: %s", err); + } + return; + } + + if (chatWindow && !chatWindow->isInputFocused() + && keyboard.isKeyActive(keyboard.KEY_RIGHT_CLICK)) + { + int mouseX, mouseY; + SDL_GetMouseState(&mouseX, &mouseY); + + gcn::MouseEvent event2(viewport, false, false, false, false, + 0, gcn::MouseEvent::RIGHT, mouseX, mouseY, 1); + if (viewport) + viewport->mousePressed(event2); + continue; + } + + // Mode switch to emotes + if (keyboard.isKeyActive(keyboard.KEY_EMOTE)) + { + // Emotions + int emotion = keyboard.getKeyEmoteOffset(event.key.keysym.sym); + if (emotion) + { + if (emoteShortcut) + emoteShortcut->useEmote(emotion); + used = true; + setValidSpeed(); + return; + } + } + + if (handleOutfitsKeys(event, used)) + continue; + + if (handleSwitchKeys(event, used)) + return; + + } + // Active event + else if (event.type == SDL_ACTIVEEVENT) + { + handleActive(event); + } + // Quit event + else if (event.type == SDL_QUIT) + { + Client::setState(STATE_EXIT); + } + + // Push input to GUI when not used + if (!used) + { + try + { + if (guiInput) + guiInput->pushInput(event); + } + catch (const 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 (!player_node || !keyboard.isEnabled() || player_node->getAway()) + return; + + // If pressed outfits keys, stop processing keys. + if (keyboard.isKeyActive(keyboard.KEY_WEAR_OUTFIT) + || keyboard.isKeyActive(keyboard.KEY_COPY_OUTFIT) + || (setupWindow && setupWindow->isVisible())) + { + return; + } + + handleMoveAndAttack(event, wasDown); +} + /** * Changes the currently active map. Should only be called while the game is * running. diff --git a/src/game.h b/src/game.h index 2205e30de..4e5337d29 100644 --- a/src/game.h +++ b/src/game.h @@ -78,6 +78,14 @@ class Game void handleInput(); + bool handleOutfitsKeys(SDL_Event &event, bool &used); + + bool handleSwitchKeys(SDL_Event &event, bool &used); + + void handleMoveAndAttack(SDL_Event &event, bool wasDown); + + void handleActive(SDL_Event &event); + void changeMap(const std::string &mapName); /** |