diff options
Diffstat (limited to 'src')
65 files changed, 742 insertions, 303 deletions
diff --git a/src/actorspritemanager.cpp b/src/actorspritemanager.cpp index 03418a857..827d46f29 100644 --- a/src/actorspritemanager.cpp +++ b/src/actorspritemanager.cpp @@ -177,11 +177,13 @@ ActorSpriteManager::ActorSpriteManager() : mTargetOnlyReachable = config.getBoolValue("targetOnlyReachable"); mCyclePlayers = config.getBoolValue("cyclePlayers"); mCycleMonsters = config.getBoolValue("cycleMonsters"); + mExtMouseTargeting = config.getBoolValue("extMouseTargeting"); config.addListener("targetDeadPlayers", this); config.addListener("targetOnlyReachable", this); config.addListener("cyclePlayers", this); config.addListener("cycleMonsters", this); + config.addListener("extMouseTargeting", this); loadAttackList(); } @@ -192,6 +194,7 @@ ActorSpriteManager::~ActorSpriteManager() config.removeListener("targetOnlyReachable", this); config.removeListener("cyclePlayers", this); config.removeListener("cycleMonsters", this); + config.removeListener("extMouseTargeting", this); storeAttackList(); clear(); } @@ -300,26 +303,81 @@ Being *ActorSpriteManager::findBeingByPixel(int x, int y, return NULL; bool targetDead = mTargetDeadPlayers; - Being *tempBeing = 0; - bool noBeing(false); - for_actors + if (mExtMouseTargeting) { - if (!*it) - continue; + Being *tempBeing = 0; + bool noBeing(false); - if ((*it)->getType() == ActorSprite::FLOOR_ITEM - || (*it)->getType() == ActorSprite::PORTAL) + for_actors { - continue; - } + if (!*it) + continue; - Being *being = static_cast<Being*>(*it); + if ((*it)->getType() == ActorSprite::PORTAL) + continue; - if ((being->isAlive() - || (targetDead && being->getType() == Being::PLAYER)) - && (allPlayers || being != player_node)) + if ((*it)->getType() == ActorSprite::FLOOR_ITEM) + { + if (!noBeing) + { + FloorItem *floor = static_cast<FloorItem*>(*it); + if (!noBeing && (floor->getPixelX() - 32 <= x) && + (floor->getPixelX() + 32 > x) && + (floor->getPixelY() - 64 <= y) && + (floor->getPixelY() + 16 > y)) + { + noBeing = true; + } + } + continue; + } + + Being *being = static_cast<Being*>(*it); + + if ((being->isAlive() + || (targetDead && being->getType() == Being::PLAYER)) + && (allPlayers || being != player_node)) + { + + if ((being->getPixelX() - 16 <= x) && + (being->getPixelX() + 16 > x) && + (being->getPixelY() - 32 <= y) && + (being->getPixelY() > y)) + { + return being; + } + else if (!noBeing && (being->getPixelX() - 32 <= x) && + (being->getPixelX() + 32 > x) && + (being->getPixelY() - 64 <= y) && + (being->getPixelY() + 16 > y)) + { + if (tempBeing) + noBeing = true; + else + tempBeing = being; + } + } + } + + if (noBeing) + return 0; + return tempBeing; + } + else + { + for_actors { + if (!*it) + continue; + + if ((*it)->getType() == ActorSprite::PORTAL || + (*it)->getType() == ActorSprite::FLOOR_ITEM) + { + continue; + } + + Being *being = static_cast<Being*>(*it); if ((being->getPixelX() - 16 <= x) && (being->getPixelX() + 16 > x) && @@ -328,22 +386,9 @@ Being *ActorSpriteManager::findBeingByPixel(int x, int y, { return being; } - else if (!noBeing && (being->getPixelX() - 32 <= x) && - (being->getPixelX() + 32 > x) && - (being->getPixelY() - 64 <= y) && - (being->getPixelY() + 16 > y)) - { - if (tempBeing) - noBeing = true; - else - tempBeing = being; - } } - } - - if (noBeing) return 0; - return tempBeing; + } } void ActorSpriteManager::findBeingsByPixel(std::vector<Being*> &beings, @@ -1285,6 +1330,8 @@ void ActorSpriteManager::optionChanged(const std::string &name) mCyclePlayers = config.getBoolValue("cyclePlayers"); else if (name == "cycleMonsters") mCycleMonsters = config.getBoolValue("cycleMonsters"); + else if (name == "extMouseTargeting") + mExtMouseTargeting = config.getBoolValue("extMouseTargeting"); } void ActorSpriteManager::removeAttackMob(const std::string &name) diff --git a/src/actorspritemanager.h b/src/actorspritemanager.h index bd2ae79fb..d2d9af108 100644 --- a/src/actorspritemanager.h +++ b/src/actorspritemanager.h @@ -318,6 +318,7 @@ class ActorSpriteManager: public ConfigListener bool mTargetOnlyReachable; bool mCyclePlayers; bool mCycleMonsters; + bool mExtMouseTargeting; std::list<std::string> mPriorityAttackMobs; std::list<std::string> mAttackMobs; diff --git a/src/avatar.h b/src/avatar.h index 83f4a586a..6c79dd96a 100644 --- a/src/avatar.h +++ b/src/avatar.h @@ -35,6 +35,9 @@ class Avatar public: Avatar(const std::string &name = ""); + virtual ~Avatar() + { } + /** * Returns the avatar's name. */ diff --git a/src/being.cpp b/src/being.cpp index 532e6e2cf..2ed05449a 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -84,7 +84,6 @@ #include "debug.h" #define CACHE_SIZE 50 -#define HAIR_FILE "hair.xml" static const int DEFAULT_BEING_WIDTH = 32; static const int DEFAULT_BEING_HEIGHT = 32; diff --git a/src/client.cpp b/src/client.cpp index d0348dec5..8497d337b 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -2006,6 +2006,10 @@ void Client::initPacketLimiter() mPacketLimits[PACKET_ATTACK].cntLimit = 1; mPacketLimits[PACKET_ATTACK].cnt = 0; + mPacketLimits[PACKET_STOPATTACK].timeLimit = 2 + 10; + mPacketLimits[PACKET_STOPATTACK].lastTime = 0; + mPacketLimits[PACKET_STOPATTACK].cntLimit = 1; + mPacketLimits[PACKET_STOPATTACK].cnt = 0; if (!mServerConfigDir.empty()) { @@ -2043,7 +2047,7 @@ void Client::initPacketLimiter() mPacketLimits[f].timeLimit = atoi(line); } inPacketFile.close(); - if (ver == 1) + if (ver < 3) writePacketLimits(packetLimitsName); } } @@ -2058,7 +2062,7 @@ void Client::writePacketLimits(std::string packetLimitsName) outPacketFile.close(); return; } - outPacketFile << "2" << std::endl; + outPacketFile << "3" << std::endl; for (int f = 0; f < PACKET_SIZE; f ++) { outPacketFile << toString(mPacketLimits[f].timeLimit) diff --git a/src/client.h b/src/client.h index 08bc1ecbf..776e9aa3d 100644 --- a/src/client.h +++ b/src/client.h @@ -136,6 +136,7 @@ enum PacketTypes PACKET_SIT = 7, PACKET_DIRECTION = 8, PACKET_ATTACK = 9, + PACKET_STOPATTACK = 10, PACKET_SIZE }; diff --git a/src/defaults.cpp b/src/defaults.cpp index 4a82a83a9..d7fa07a07 100644 --- a/src/defaults.cpp +++ b/src/defaults.cpp @@ -218,6 +218,7 @@ DefaultsData* getConfigDefaults() AddDEF(configData, "showip", false); AddDEF(configData, "seflMouseHeal", true); AddDEF(configData, "enableLazyScrolling", true); + AddDEF(configData, "extMouseTargeting", true); return configData; } diff --git a/src/game.cpp b/src/game.cpp index d82f13913..0527e8481 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1148,6 +1148,7 @@ void Game::handleInput() && !NpcDialog::isAnyInputFocused() && (!player_node || !player_node->getAwayMode()) && !keyboard.isKeyActive(keyboard.KEY_TARGET) + && !keyboard.isKeyActive(keyboard.KEY_UNTARGET) && !InventoryWindow::isAnyInputFocused()) { // const int tKey = keyboard.getKeyIndex(event.key.keysym.sym); @@ -1366,11 +1367,9 @@ void Game::handleInput() { // window restore Client::setIsMinimized(false); if (!player_node && !player_node->getAwayMode()) - { fpsLimit = config.getIntValue("fpslimit"); - if (player_node) - player_node->setHalfAway(false); - } + if (player_node) + player_node->setHalfAway(false); } else { // window minimisation @@ -1613,7 +1612,8 @@ void Game::handleInput() keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) || keyboard.isKeyActive(keyboard.KEY_TARGET_NPC) || (joystick && joystick->buttonPressed(3))) && - !keyboard.isKeyActive(keyboard.KEY_TARGET)) + !keyboard.isKeyActive(keyboard.KEY_TARGET) && + !keyboard.isKeyActive(keyboard.KEY_UNTARGET)) { ActorSprite::Type currentTarget = ActorSprite::UNKNOWN; if (keyboard.isKeyActive(keyboard.KEY_TARGET_CLOSEST) || @@ -1665,10 +1665,12 @@ void Game::handleInput() // Stop attacking if the right key is pressed if (!keyboard.isKeyActive(keyboard.KEY_ATTACK) - && keyboard.isKeyActive(keyboard.KEY_TARGET) && !keyboard.isKeyActive(keyboard.KEY_EMOTE)) { - player_node->stopAttack(); + if (keyboard.isKeyActive(keyboard.KEY_TARGET)) + player_node->stopAttack(); + else if (keyboard.isKeyActive(keyboard.KEY_UNTARGET)) + player_node->untarget(); } if (joystick) diff --git a/src/gui/botcheckerwindow.cpp b/src/gui/botcheckerwindow.cpp index 34293e59d..88bc65a78 100644 --- a/src/gui/botcheckerwindow.cpp +++ b/src/gui/botcheckerwindow.cpp @@ -378,11 +378,6 @@ void BotCheckerWindow::update() { } -void BotCheckerWindow::widgetResized(const gcn::Event &event) -{ - Window::widgetResized(event); -} - void BotCheckerWindow::updateList() { if (mTableModel) diff --git a/src/gui/botcheckerwindow.h b/src/gui/botcheckerwindow.h index a69781865..6af9c91d6 100644 --- a/src/gui/botcheckerwindow.h +++ b/src/gui/botcheckerwindow.h @@ -71,8 +71,6 @@ class BotCheckerWindow : public Window, public gcn::ActionListener, void logic(); - void widgetResized(const gcn::Event &event); - void updateList(); void reset(); diff --git a/src/gui/buydialog.cpp b/src/gui/buydialog.cpp index 8628afc6e..7fad622df 100644 --- a/src/gui/buydialog.cpp +++ b/src/gui/buydialog.cpp @@ -22,6 +22,7 @@ #include "gui/buydialog.h" +#include "keyboardconfig.h" #include "shopitem.h" #include "units.h" @@ -29,6 +30,7 @@ #include "gui/tradewindow.h" #include "gui/widgets/button.h" +#include "gui/widgets/inttextfield.h" #include "gui/widgets/label.h" #include "gui/widgets/layout.h" #include "gui/widgets/scrollarea.h" @@ -77,6 +79,9 @@ void BuyDialog::init() setMinHeight(230); setDefaultSize(260, 230, ImageRect::CENTER); + mEnabledKeyboard = keyboard.isEnabled(); + keyboard.setEnabled(false); + mShopItems = new ShopItems; mShopItemList = new ShopListBox(mShopItems, mShopItems); @@ -89,6 +94,15 @@ void BuyDialog::init() mMoneyLabel = new Label(strprintf(_("Price: %s / Total: %s"), "", "")); + mAmountField = new IntTextField(1, 1, 123); + mAmountField->setActionEventId("amount"); + mAmountField->addActionListener(this); + mAmountField->setSendAlwaysEvents(true); + mAmountField->setEnabled(false); + + mAmountLabel = new Label(_("Amount:")); + mAmountLabel->adjustSize(); + // TRANSLATORS: This is a narrow symbol used to denote 'increasing'. // You may change this symbol if your language uses another. mIncreaseButton = new Button(_("+"), "inc", this); @@ -114,15 +128,17 @@ void BuyDialog::init() ContainerPlacer placer; placer = getPlacer(0, 0); - placer(0, 0, mScrollArea, 8, 5).setPadding(3); + placer(0, 0, mScrollArea, 9, 5).setPadding(3); placer(0, 5, mDecreaseButton); - placer(1, 5, mSlider, 3); - placer(4, 5, mIncreaseButton); - placer(5, 5, mQuantityLabel, 2); - placer(7, 5, mAddMaxButton); - placer(0, 6, mMoneyLabel, 8); - placer(6, 7, mBuyButton); - placer(7, 7, mQuitButton); + placer(1, 5, mSlider, 4); + placer(5, 5, mIncreaseButton); + placer(6, 5, mQuantityLabel, 2); + placer(8, 5, mAddMaxButton); + placer(0, 6, mAmountLabel, 2); + placer(2, 6, mAmountField, 2); + placer(0, 7, mMoneyLabel, 8); + placer(7, 8, mBuyButton); + placer(8, 8, mQuitButton); Layout &layout = getLayout(); layout.setRowHeight(0, Layout::AUTO_SET); @@ -188,24 +204,34 @@ void BuyDialog::action(const gcn::ActionEvent &event) if (event.getId() == "slider") { mAmountItems = static_cast<int>(mSlider->getValue()); + mAmountField->setValue(mAmountItems); updateButtonsAndLabels(); } else if (event.getId() == "inc" && mAmountItems < mMaxItems) { mAmountItems++; mSlider->setValue(mAmountItems); + mAmountField->setValue(mAmountItems); updateButtonsAndLabels(); } else if (event.getId() == "dec" && mAmountItems > 1) { mAmountItems--; mSlider->setValue(mAmountItems); + mAmountField->setValue(mAmountItems); updateButtonsAndLabels(); } else if (event.getId() == "max") { mAmountItems = mMaxItems; mSlider->setValue(mAmountItems); + mAmountField->setValue(mAmountItems); + updateButtonsAndLabels(); + } + else if (event.getId() == "amount") + { + mAmountItems = mAmountField->getValue(); + mSlider->setValue(mAmountItems); updateButtonsAndLabels(); } // TODO: Actually we'd have a bug elsewhere if this check for the number @@ -256,6 +282,8 @@ void BuyDialog::valueChanged(const gcn::SelectionEvent &event A_UNUSED) updateButtonsAndLabels(); mSlider->gcn::Slider::setScale(1, mMaxItems); + mAmountField->setRange(1, mMaxItems); + mAmountField->setValue(1); } void BuyDialog::updateButtonsAndLabels() @@ -297,6 +325,7 @@ void BuyDialog::updateButtonsAndLabels() mDecreaseButton->setEnabled(mAmountItems > 1); mBuyButton->setEnabled(mAmountItems > 0); mSlider->setEnabled(mMaxItems > 1); + mAmountField->setEnabled(mAmountItems > 0); // Update quantity and money labels mQuantityLabel->setCaption(strprintf("%d / %d", mAmountItems, mMaxItems)); @@ -326,3 +355,9 @@ void BuyDialog::closeAll() (*it)->close(); } } + +void BuyDialog::scheduleDelete() +{ + keyboard.setEnabled(mEnabledKeyboard); + Window::scheduleDelete(); +} diff --git a/src/gui/buydialog.h b/src/gui/buydialog.h index 0ba2e5cb3..53d20e1e5 100644 --- a/src/gui/buydialog.h +++ b/src/gui/buydialog.h @@ -38,6 +38,7 @@ class ShopItems; class ShopListBox; +class IntTextField; class ListBox; /** @@ -124,6 +125,8 @@ class BuyDialog : public Window, public gcn::ActionListener, */ static void closeAll(); + void scheduleDelete(); + private: typedef std::list<BuyDialog*> DialogList; static DialogList instances; @@ -140,6 +143,8 @@ class BuyDialog : public Window, public gcn::ActionListener, gcn::Label *mMoneyLabel; gcn::Label *mQuantityLabel; gcn::Slider *mSlider; + gcn::Label *mAmountLabel; + IntTextField *mAmountField; ShopItems *mShopItems; @@ -147,6 +152,7 @@ class BuyDialog : public Window, public gcn::ActionListener, int mAmountItems; int mMaxItems; std::string mNick; + bool mEnabledKeyboard; }; #endif diff --git a/src/gui/inventorywindow.cpp b/src/gui/inventorywindow.cpp index cd02a6732..f52151698 100644 --- a/src/gui/inventorywindow.cpp +++ b/src/gui/inventorywindow.cpp @@ -99,7 +99,8 @@ InventoryWindow::InventoryWindow(Inventory *inventory): Window("Inventory", false, 0, "inventory.xml"), mInventory(inventory), mDropButton(0), - mSplit(false) + mSplit(false), + mCompactMode(false) { if (inventory) { @@ -146,7 +147,6 @@ InventoryWindow::InventoryWindow(Inventory *inventory): mSortDropDown->setSelected(0); mFilterLabel = new Label(_("Filter:")); - mSorterLabel = new Label(_("Sort:")); mNameFilter = new TextField("", true, this, "namefilter", true); std::vector<std::string> tags = ItemDB::getTags(); @@ -181,13 +181,12 @@ InventoryWindow::InventoryWindow(Inventory *inventory): place(0, 0, mWeightLabel, 1).setPadding(3); place(1, 0, mWeightBar, 3); place(4, 0, mSlotsLabel, 1).setPadding(3); - place(5, 0, mSlotsBar, 2); - place(7, 0, mSorterLabel, 1); - place(8, 0, mSortDropDown, 3); + mSlotsBarCell = &place(5, 0, mSlotsBar, 3); + mSortDropDownCell = &place(8, 0, mSortDropDown, 3); place(0, 1, mFilterLabel, 1).setPadding(3); - place(1, 1, mFilter, 7).setPadding(3); - place(8, 1, mNameFilter, 3); + mFilterCell = &place(1, 1, mFilter, 8).setPadding(3); + mNameFilterCell = &place(8, 1, mNameFilter, 3); place(0, 2, invenScroll, 11).setPadding(3); place(0, 3, mUseButton); @@ -206,13 +205,12 @@ InventoryWindow::InventoryWindow(Inventory *inventory): mCloseButton = new Button(_("Close"), "close", this); place(0, 0, mSlotsLabel).setPadding(3); - place(1, 0, mSlotsBar, 4); - place(5, 0, mSorterLabel, 1); - place(6, 0, mSortDropDown, 1); + mSlotsBarCell = &place(1, 0, mSlotsBar, 5); + mSortDropDownCell = &place(6, 0, mSortDropDown, 1); place(0, 1, mFilterLabel, 1).setPadding(3); - place(1, 1, mFilter, 5).setPadding(3); - place(6, 1, mNameFilter, 1); + mFilterCell = &place(1, 1, mFilter, 6).setPadding(3); + mNameFilterCell = &place(6, 1, mNameFilter, 1); place(0, 2, invenScroll, 7, 4); place(0, 6, mStoreButton); @@ -240,6 +238,7 @@ InventoryWindow::InventoryWindow(Inventory *inventory): loadWindowState(); slotsChanged(mInventory); + widgetResized(0); if (!isMainInventory()) setVisible(true); } @@ -376,6 +375,13 @@ Item *InventoryWindow::getSelectedItem() const return mItems->getSelectedItem(); } +void InventoryWindow::widgetHidden(const gcn::Event &event) +{ + Window::widgetHidden(event); + if (mItems) + mItems->hidePopup(); +} + void InventoryWindow::mouseClicked(gcn::MouseEvent &event) { Window::mouseClicked(event); @@ -666,3 +672,35 @@ bool InventoryWindow::isAnyInputFocused() } return false; } + +void InventoryWindow::widgetResized(const gcn::Event &event) +{ + Window::widgetResized(event); + + if (!isMainInventory()) + return; + + if (getWidth() < 600) + { + if (!mCompactMode) + { + mSortDropDown->setVisible(false); + mNameFilter->setVisible(false); + mSortDropDownCell->setType(LayoutCell::NONE); + mNameFilterCell->setType(LayoutCell::NONE); + mFilterCell->setWidth(mFilterCell->getWidth() + 3); + mSlotsBarCell->setWidth(mSlotsBarCell->getWidth() + 3); + mCompactMode = true; + } + } + else if (mCompactMode) + { + mSortDropDown->setVisible(true); + mNameFilter->setVisible(true); + mSortDropDownCell->setType(LayoutCell::WIDGET); + mNameFilterCell->setType(LayoutCell::WIDGET); + mFilterCell->setWidth(mFilterCell->getWidth() - 3); + mSlotsBarCell->setWidth(mSlotsBarCell->getWidth() - 3); + mCompactMode = false; + } +} diff --git a/src/gui/inventorywindow.h b/src/gui/inventorywindow.h index c32fd8905..9dadeb5a8 100644 --- a/src/gui/inventorywindow.h +++ b/src/gui/inventorywindow.h @@ -45,6 +45,7 @@ class DropDown; class Item; class ItemContainer; class InventoryFilter; +class LayoutCell; class ProgressBar; class SortListModel; //class TextBox; @@ -84,6 +85,11 @@ class InventoryWindow : public Window, Item* getSelectedItem() const; /** + * Handles closing of the window + */ + void widgetHidden(const gcn::Event &event); + + /** * Handles the mouse clicks. */ void mouseClicked(gcn::MouseEvent &event); @@ -133,6 +139,8 @@ class InventoryWindow : public Window, bool isInputFocused() const; + void widgetResized(const gcn::Event &event); + static bool isAnyInputFocused(); private: @@ -154,15 +162,20 @@ class InventoryWindow : public Window, *mSplitButton, *mOutfitButton, *mShopButton, *mStoreButton, *mRetrieveButton, *mCloseButton; - gcn::Label *mWeightLabel, *mSlotsLabel, *mFilterLabel, *mSorterLabel; + gcn::Label *mWeightLabel, *mSlotsLabel, *mFilterLabel; ProgressBar *mWeightBar, *mSlotsBar; InventoryFilter *mFilter; DropDown *mSortDropDown; SortListModel *mSortModel; TextField *mNameFilter; + LayoutCell *mSortDropDownCell; + LayoutCell *mNameFilterCell; + LayoutCell *mFilterCell; + LayoutCell *mSlotsBarCell; bool mSplit; + bool mCompactMode; }; extern InventoryWindow *inventoryWindow; diff --git a/src/gui/npcdialog.cpp b/src/gui/npcdialog.cpp index 3e1ee46d8..b926d260e 100644 --- a/src/gui/npcdialog.cpp +++ b/src/gui/npcdialog.cpp @@ -404,13 +404,6 @@ void NpcDialog::move(int amount) } } -void NpcDialog::widgetResized(const gcn::Event &event) -{ - Window::widgetResized(event); - -// setText(mText); -} - void NpcDialog::setVisible(bool visible) { Window::setVisible(visible); diff --git a/src/gui/npcdialog.h b/src/gui/npcdialog.h index 2f5a90b5f..7e9ea7e10 100644 --- a/src/gui/npcdialog.h +++ b/src/gui/npcdialog.h @@ -147,13 +147,6 @@ class NpcDialog : public Window, public gcn::ActionListener, void move(int amount); - /** - * Called when resizing the window. - * - * @param event The calling event - */ - void widgetResized(const gcn::Event &event); - void setVisible(bool visible); void optionChanged(const std::string &name); diff --git a/src/gui/serverdialog.h b/src/gui/serverdialog.h index a5f5f3ee0..39c6f94f7 100644 --- a/src/gui/serverdialog.h +++ b/src/gui/serverdialog.h @@ -95,7 +95,11 @@ class TypeListModel : public gcn::ListModel * Used to get number of line in the list */ int getNumberOfElements() +#ifdef MANASERV_SUPPORT + { return 3; } +#else { return 2; } +#endif /** * Used to get an element from the list diff --git a/src/gui/setup_keyboard.cpp b/src/gui/setup_keyboard.cpp index 5125541cf..922d9797b 100644 --- a/src/gui/setup_keyboard.cpp +++ b/src/gui/setup_keyboard.cpp @@ -153,8 +153,17 @@ void Setup_Keyboard::action(const gcn::ActionEvent &event) { if (!mKeySetting) { - mAssignKeyButton->setEnabled(true); - mUnassignKeyButton->setEnabled(true); + int i(mKeyList->getSelected()); + if (keyboard.isSeparator(i)) + { + mAssignKeyButton->setEnabled(false); + mUnassignKeyButton->setEnabled(false); + } + else + { + mAssignKeyButton->setEnabled(true); + mUnassignKeyButton->setEnabled(true); + } } } else if (event.getId() == "assign") @@ -183,11 +192,21 @@ void Setup_Keyboard::action(const gcn::ActionEvent &event) void Setup_Keyboard::refreshAssignedKey(int index) { - std::string caption; - char *temp = SDL_GetKeyName( - static_cast<SDLKey>(keyboard.getKeyValue(index))); - caption = keyboard.getKeyCaption(index) + ": " + toString(temp); - mKeyListModel->setElementAt(index, caption); + if (keyboard.isSeparator(index)) + { + const std::string str = " \342\200\225\342\200\225\342\200\225" + "\342\200\225\342\200\225 "; + mKeyListModel->setElementAt(index, str + + keyboard.getKeyCaption(index) + str); + } + else + { + std::string caption; + char *temp = SDL_GetKeyName( + static_cast<SDLKey>(keyboard.getKeyValue(index))); + caption = keyboard.getKeyCaption(index) + ": " + toString(temp); + mKeyListModel->setElementAt(index, caption); + } } void Setup_Keyboard::newKeyCallback(int index) diff --git a/src/gui/setup_players.cpp b/src/gui/setup_players.cpp index 670fc3635..a6bf5b81c 100644 --- a/src/gui/setup_players.cpp +++ b/src/gui/setup_players.cpp @@ -60,6 +60,9 @@ Setup_Players::Setup_Players() new SetupItemCheckBox(_("Show own name"), "", "showownname", this, "showownnameEvent"); + new SetupItemCheckBox(_("Enable extended mouse targeting"), "", + "extMouseTargeting", this, "extMouseTargetingEvent"); + new SetupItemCheckBox(_("Target dead players"), "", "targetDeadPlayers", this, "targetDeadPlayersEvent"); diff --git a/src/gui/setup_relations.cpp b/src/gui/setup_relations.cpp index 489d5a818..57a51e435 100644 --- a/src/gui/setup_relations.cpp +++ b/src/gui/setup_relations.cpp @@ -228,7 +228,6 @@ public: #define ACTION_OLD "old" #define ACTION_TABLE "table" #define ACTION_STRATEGY "strategy" -#define ACTION_WHISPER_TAB "whisper tab" Setup_Relations::Setup_Relations(): mPlayerTableTitleModel(new StaticTableModel(1, COLUMNS_NR)), diff --git a/src/gui/shortcutwindow.cpp b/src/gui/shortcutwindow.cpp index df21488a5..6d48da197 100644 --- a/src/gui/shortcutwindow.cpp +++ b/src/gui/shortcutwindow.cpp @@ -159,3 +159,22 @@ int ShortcutWindow::getTabIndex() return 0; return mTabs->getSelectedTabIndex(); } + +void ShortcutWindow::widgetHidden(const gcn::Event &event) +{ + if (mItems) + mItems->widgetHidden(event); + if (mTabs) + { + ScrollArea *scroll = static_cast<ScrollArea*>( + mTabs->getCurrentWidget()); + if (scroll) + { + ShortcutContainer *content = static_cast<ShortcutContainer*>( + scroll->getContent()); + + if (content) + content->widgetHidden(event); + } + } +} diff --git a/src/gui/shortcutwindow.h b/src/gui/shortcutwindow.h index 1c91835e8..8627a5dce 100644 --- a/src/gui/shortcutwindow.h +++ b/src/gui/shortcutwindow.h @@ -56,6 +56,8 @@ class ShortcutWindow : public Window int getTabIndex(); + void widgetHidden(const gcn::Event &event); + private: ShortcutWindow(); ShortcutContainer *mItems; diff --git a/src/gui/socialwindow.cpp b/src/gui/socialwindow.cpp index a8d15f36c..ab19e501b 100644 --- a/src/gui/socialwindow.cpp +++ b/src/gui/socialwindow.cpp @@ -1133,7 +1133,7 @@ SocialWindow::SocialWindow() : setMinWidth(120); setMinHeight(55); - setDefaultSize(590, 200, 150, 120); + setDefaultSize(590, 200, 180, 300); setupWindow->registerWindowForReset(this); mCreateButton = new Button(_("Create"), "create", this); diff --git a/src/gui/spellpopup.cpp b/src/gui/spellpopup.cpp index c7d25e257..66d69b197 100644 --- a/src/gui/spellpopup.cpp +++ b/src/gui/spellpopup.cpp @@ -42,14 +42,15 @@ #include "debug.h" SpellPopup::SpellPopup(): - Popup("SpellPopup", "spellpopup.xml") + Popup("SpellPopup", "spellpopup.xml"), + mItemName(new Label), + mItemComment(new Label) { - // Item Name - mItemName = new Label; mItemName->setFont(boldFont); - mItemName->setPosition(getPadding(), getPadding()); add(mItemName); + add(mItemComment); + addMouseListener(this); } @@ -60,17 +61,39 @@ SpellPopup::~SpellPopup() void SpellPopup::setItem(TextCommand *spell) { if (spell) + { mItemName->setCaption(spell->getName()); + mItemComment->setCaption(spell->getComment()); + } else + { mItemName->setCaption("?"); + mItemComment->setCaption(""); + } mItemName->adjustSize(); + mItemComment->adjustSize(); int minWidth = mItemName->getWidth(); + if (mItemComment->getWidth() > minWidth) + minWidth = mItemComment->getWidth(); minWidth += 8; - setWidth(minWidth); + setWidth(minWidth + 2 * getPadding()); - setContentSize(minWidth, getPadding() + getFont()->getHeight()); + mItemName->setPosition(getPadding(), getPadding()); + mItemComment->setPosition(getPadding(), + getPadding() + mItemName->getHeight()); + + if (mItemComment->getCaption() != "") + { + setContentSize(minWidth, getPadding() + + 2 * getFont()->getHeight()); + } + else + { + setContentSize(minWidth, getPadding() + + getFont()->getHeight()); + } } void SpellPopup::view(int x, int y) diff --git a/src/gui/spellpopup.h b/src/gui/spellpopup.h index 69c47bf45..883b2bfe0 100644 --- a/src/gui/spellpopup.h +++ b/src/gui/spellpopup.h @@ -63,6 +63,8 @@ class SpellPopup : public Popup private: gcn::Label *mItemName; + + gcn::Label *mItemComment; }; #endif // SPELLPOPUP_H diff --git a/src/gui/statuswindow.cpp b/src/gui/statuswindow.cpp index 0cad8732a..170fd6ab4 100644 --- a/src/gui/statuswindow.cpp +++ b/src/gui/statuswindow.cpp @@ -133,8 +133,8 @@ StatusWindow::StatusWindow(): setCloseButton(true); setSaveVisible(true); setStickyButtonLock(true); - setDefaultSize((windowContainer->getWidth() - 365) / 2, - (windowContainer->getHeight() - 255) / 2, 365, 275); + setDefaultSize((windowContainer->getWidth() - 480) / 2, + (windowContainer->getHeight() - 500) / 2, 480, 500); // ---------------------- // Status Part @@ -502,7 +502,8 @@ void StatusWindow::updateProgressBar(ProgressBar *bar, int value, int max, if (max == 0) { bar->setText(_("Max")); - bar->setProgress(1.0); + bar->setProgress(1); + bar->setText(toString(value)); } else { diff --git a/src/gui/textcommandeditor.cpp b/src/gui/textcommandeditor.cpp index 282f23ee1..6512f8465 100644 --- a/src/gui/textcommandeditor.cpp +++ b/src/gui/textcommandeditor.cpp @@ -168,7 +168,7 @@ TextCommandEditor::TextCommandEditor(TextCommand *command): Window(_("Command Editor"), false, 0, "commandeditor.xml") { int w = 350; - int h = 350; + int h = 370; mEnabledKeyboard = keyboard.isEnabled(); keyboard.setEnabled(false); @@ -197,6 +197,9 @@ TextCommandEditor::TextCommandEditor(TextCommand *command): mCommandLabel = new Label(_("Command:")); mCommandTextField = new TextField(); + mCommentLabel = new Label(_("Comment:")); + mCommentTextField = new TextField(); + mManaLabel = new Label(_("Mana:")); mManaField = new IntTextField(0); mManaField->setRange(0, 500); @@ -248,6 +251,7 @@ TextCommandEditor::TextCommandEditor(TextCommand *command): mSymbolTextField->setText(command->getSymbol()); mCommandTextField->setText(command->getCommand()); + mCommentTextField->setText(command->getComment()); mManaField->setValue(command->getMana()); mTypeDropDown->setSelected(command->getTargetType()); mMagicLvlField->setValue(command->getBaseLvl()); @@ -263,25 +267,29 @@ TextCommandEditor::TextCommandEditor(TextCommand *command): placer(2, 1, mSymbolTextField, 3).setPadding(3); placer(0, 2, mCommandLabel, 2).setPadding(3); placer(2, 2, mCommandTextField, 4).setPadding(3); - placer(0, 3, mTypeLabel, 2).setPadding(3); - placer(2, 3, mTypeDropDown, 3).setPadding(3); - placer(0, 4, mIconLabel, 2).setPadding(3); - placer(2, 4, mIconDropDown, 3).setPadding(3); + placer(0, 3, mCommentLabel, 2).setPadding(3); + placer(2, 3, mCommentTextField, 4).setPadding(3); + + placer(0, 4, mTypeLabel, 2).setPadding(3); + placer(2, 4, mTypeDropDown, 3).setPadding(3); + + placer(0, 5, mIconLabel, 2).setPadding(3); + placer(2, 5, mIconDropDown, 3).setPadding(3); - placer(0, 5, mManaLabel, 2).setPadding(3); - placer(2, 5, mManaField, 3).setPadding(3); - placer(0, 6, mMagicLvlLabel, 2).setPadding(3); - placer(2, 6, mMagicLvlField, 3).setPadding(3); + placer(0, 6, mManaLabel, 2).setPadding(3); + placer(2, 6, mManaField, 3).setPadding(3); + placer(0, 7, mMagicLvlLabel, 2).setPadding(3); + placer(2, 7, mMagicLvlField, 3).setPadding(3); - placer(0, 7, mSchoolLabel, 2).setPadding(3); - placer(2, 7, mSchoolDropDown, 3).setPadding(3); - placer(0, 8, mSchoolLvlLabel, 2).setPadding(3); - placer(2, 8, mSchoolLvlField, 3).setPadding(3); + placer(0, 8, mSchoolLabel, 2).setPadding(3); + placer(2, 8, mSchoolDropDown, 3).setPadding(3); + placer(0, 9, mSchoolLvlLabel, 2).setPadding(3); + placer(2, 9, mSchoolLvlField, 3).setPadding(3); - placer(0, 9, mSaveButton, 2).setPadding(3); - placer(2, 9, mCancelButton, 2).setPadding(3); - placer(4, 9, mDeleteButton, 2).setPadding(3); + placer(0, 10, mSaveButton, 2).setPadding(3); + placer(2, 10, mCancelButton, 2).setPadding(3); + placer(4, 10, mDeleteButton, 2).setPadding(3); setWidth(w); setHeight(h); @@ -335,11 +343,6 @@ void TextCommandEditor::update() { } -void TextCommandEditor::widgetResized(const gcn::Event &event) -{ - Window::widgetResized(event); -} - void TextCommandEditor::updateList() { } @@ -375,6 +378,7 @@ void TextCommandEditor::save() mCommand->setSymbol(mSymbolTextField->getText()); mCommand->setCommand(mCommandTextField->getText()); + mCommand->setComment(mCommentTextField->getText()); mCommand->setMana(mManaField->getValue()); mCommand->setTargetType( static_cast<SpellTarget>(mTypeDropDown->getSelected())); @@ -392,6 +396,7 @@ void TextCommandEditor::deleteCommand() mCommand->setCommandType(TEXT_COMMAND_TEXT); mCommand->setSymbol(""); mCommand->setCommand(""); + mCommand->setComment(""); mCommand->setMana(0); mCommand->setTargetType(NOTARGET); mCommand->setIcon(""); diff --git a/src/gui/textcommandeditor.h b/src/gui/textcommandeditor.h index 236c42320..d0b2f0a54 100644 --- a/src/gui/textcommandeditor.h +++ b/src/gui/textcommandeditor.h @@ -60,8 +60,6 @@ class TextCommandEditor : public Window, public gcn::ActionListener void update(); - void widgetResized(const gcn::Event &event); - void updateList(); void reset(); @@ -84,6 +82,10 @@ class TextCommandEditor : public Window, public gcn::ActionListener TextField *mSymbolTextField; Label *mCommandLabel; TextField *mCommandTextField; + + Label *mCommentLabel; + TextField *mCommentTextField; + Label *mTypeLabel; DropDown *mTypeDropDown; Label *mIconLabel; diff --git a/src/gui/whoisonline.cpp b/src/gui/whoisonline.cpp index e1f69c2d7..a14e99afc 100644 --- a/src/gui/whoisonline.cpp +++ b/src/gui/whoisonline.cpp @@ -59,23 +59,27 @@ #undef malloc #endif -bool stringCompare(const std::string &left, const std::string &right); -bool stringCompare(const std::string &left, const std::string &right ) +class NameFunctuator { - for (std::string::const_iterator lit = left.begin(), - rit = right.begin(); - lit != left.end() && rit != right.end(); ++lit, ++rit) - { - if (tolower(*lit) < tolower(*rit)) - return true; - else if (tolower(*lit) > tolower(*rit)) + public: + bool operator()(const std::string &left, + const std::string &right) const + { + for (std::string::const_iterator lit = left.begin(), + rit = right.begin(); + lit != left.end() && rit != right.end(); ++lit, ++rit) + { + if (tolower(*lit) < tolower(*rit)) + return true; + else if (tolower(*lit) > tolower(*rit)) + return false; + } + if (left.size() < right.size()) + return true; return false; - } - if (left.size() < right.size()) - return true; - return false; -} + } +} nameCompare; WhoIsOnline::WhoIsOnline(): Window(_("Who Is Online - Updating"), false, 0, "whoisonline.xml"), @@ -297,9 +301,9 @@ void WhoIsOnline::loadList() setCaption(_("Who Is Online - ") + toString(numOnline)); //List the online people - sort(friends.begin(), friends.end(), stringCompare); - sort(neutral.begin(), neutral.end(), stringCompare); - sort(disregard.begin(), disregard.end(), stringCompare); + sort(friends.begin(), friends.end(), nameCompare); + sort(neutral.begin(), neutral.end(), nameCompare); + sort(disregard.begin(), disregard.end(), nameCompare); bool addedFromSection(false); for (int i = 0; i < static_cast<int>(friends.size()); i++) { diff --git a/src/gui/widgets/dropshortcutcontainer.cpp b/src/gui/widgets/dropshortcutcontainer.cpp index b628cf2d4..1fa272448 100644 --- a/src/gui/widgets/dropshortcutcontainer.cpp +++ b/src/gui/widgets/dropshortcutcontainer.cpp @@ -306,5 +306,12 @@ void DropShortcutContainer::mouseMoved(gcn::MouseEvent &event) // Hide ItemTooltip void DropShortcutContainer::mouseExited(gcn::MouseEvent &event A_UNUSED) { - mItemPopup->setVisible(false); + if (mItemPopup) + mItemPopup->setVisible(false); +} + +void DropShortcutContainer::widgetHidden(const gcn::Event &event A_UNUSED) +{ + if (mItemPopup) + mItemPopup->setVisible(false); } diff --git a/src/gui/widgets/dropshortcutcontainer.h b/src/gui/widgets/dropshortcutcontainer.h index b2d63a7dd..348f48567 100644 --- a/src/gui/widgets/dropshortcutcontainer.h +++ b/src/gui/widgets/dropshortcutcontainer.h @@ -76,6 +76,8 @@ class DropShortcutContainer : public ShortcutContainer */ void mouseReleased(gcn::MouseEvent &event); + void widgetHidden(const gcn::Event &event); + private: void mouseExited(gcn::MouseEvent &event); void mouseMoved(gcn::MouseEvent &event); diff --git a/src/gui/widgets/emoteshortcutcontainer.cpp b/src/gui/widgets/emoteshortcutcontainer.cpp index 5aced193f..cc9e8badf 100644 --- a/src/gui/widgets/emoteshortcutcontainer.cpp +++ b/src/gui/widgets/emoteshortcutcontainer.cpp @@ -252,4 +252,10 @@ void EmoteShortcutContainer::mouseExited(gcn::MouseEvent &event A_UNUSED) { if (mEmotePopup) mEmotePopup->setVisible(false); -}
\ No newline at end of file +} + +void EmoteShortcutContainer::widgetHidden(const gcn::Event &event A_UNUSED) +{ + if (mEmotePopup) + mEmotePopup->setVisible(false); +} diff --git a/src/gui/widgets/emoteshortcutcontainer.h b/src/gui/widgets/emoteshortcutcontainer.h index b1cc866d2..06c009f0b 100644 --- a/src/gui/widgets/emoteshortcutcontainer.h +++ b/src/gui/widgets/emoteshortcutcontainer.h @@ -27,6 +27,12 @@ #include <vector> +#ifdef __GNUC__ +#define A_UNUSED __attribute__ ((unused)) +#else +#define A_UNUSED +#endif + class AnimatedSprite; class Image; class TextPopup; @@ -73,6 +79,8 @@ class EmoteShortcutContainer : public ShortcutContainer void mouseExited(gcn::MouseEvent &event); + void widgetHidden(const gcn::Event &event); + private: std::vector<const EmoteSprite*> mEmoteImg; diff --git a/src/gui/widgets/inttextfield.cpp b/src/gui/widgets/inttextfield.cpp index 021340fbe..89544e108 100644 --- a/src/gui/widgets/inttextfield.cpp +++ b/src/gui/widgets/inttextfield.cpp @@ -50,6 +50,9 @@ void IntTextField::keyPressed(gcn::KeyEvent &event) key.getValue() == Key::DELETE) { setText(std::string()); + if (mSendAlwaysEvents) + distributeActionEvent(); + event.consume(); } @@ -62,6 +65,8 @@ void IntTextField::keyPressed(gcn::KeyEvent &event) int i; s >> i; setValue(i); + if (mSendAlwaysEvents) + distributeActionEvent(); } void IntTextField::setRange(int min, int max) diff --git a/src/gui/widgets/itemcontainer.cpp b/src/gui/widgets/itemcontainer.cpp index 2cc80ee8b..9a17d81cd 100644 --- a/src/gui/widgets/itemcontainer.cpp +++ b/src/gui/widgets/itemcontainer.cpp @@ -327,6 +327,12 @@ void ItemContainer::distributeValueChangedEvent() } } +void ItemContainer::hidePopup() +{ + if (mItemPopup) + mItemPopup->setVisible(false); +} + void ItemContainer::keyPressed(gcn::KeyEvent &event A_UNUSED) { /*switch (event.getKey().getValue()) diff --git a/src/gui/widgets/itemcontainer.h b/src/gui/widgets/itemcontainer.h index 845bfb3a9..e4188f54b 100644 --- a/src/gui/widgets/itemcontainer.h +++ b/src/gui/widgets/itemcontainer.h @@ -73,6 +73,8 @@ class ItemContainer : public gcn::Widget, */ virtual ~ItemContainer(); + void hidePopup(); + /** * Necessary for checking how full the inventory is. */ diff --git a/src/gui/widgets/itemshortcutcontainer.cpp b/src/gui/widgets/itemshortcutcontainer.cpp index 79685fe45..560045a29 100644 --- a/src/gui/widgets/itemshortcutcontainer.cpp +++ b/src/gui/widgets/itemshortcutcontainer.cpp @@ -378,6 +378,16 @@ void ItemShortcutContainer::mouseMoved(gcn::MouseEvent &event) // Hide ItemTooltip void ItemShortcutContainer::mouseExited(gcn::MouseEvent &event A_UNUSED) { - mItemPopup->setVisible(false); - mSpellPopup->setVisible(false); + if (mItemPopup) + mItemPopup->setVisible(false); + if (mSpellPopup) + mSpellPopup->setVisible(false); +} + +void ItemShortcutContainer::widgetHidden(const gcn::Event &event A_UNUSED) +{ + if (mItemPopup) + mItemPopup->setVisible(false); + if (mSpellPopup) + mSpellPopup->setVisible(false); } diff --git a/src/gui/widgets/itemshortcutcontainer.h b/src/gui/widgets/itemshortcutcontainer.h index e6b32c6f8..473cef350 100644 --- a/src/gui/widgets/itemshortcutcontainer.h +++ b/src/gui/widgets/itemshortcutcontainer.h @@ -78,6 +78,8 @@ class ItemShortcutContainer : public ShortcutContainer */ void mouseReleased(gcn::MouseEvent &event); + void widgetHidden(const gcn::Event &event); + private: void mouseExited(gcn::MouseEvent &event); void mouseMoved(gcn::MouseEvent &event); diff --git a/src/gui/widgets/layout.h b/src/gui/widgets/layout.h index f5e1f1749..5e3ac4532 100644 --- a/src/gui/widgets/layout.h +++ b/src/gui/widgets/layout.h @@ -261,6 +261,28 @@ class LayoutCell */ void computeSizes(); + void setType(int t) + { mType = t; } + + int getWidth() + { return mExtent[0]; } + + int getHeight() + { return mExtent[1]; } + + void setWidth(int w) + { mExtent[0] = w; } + + void setHeight(int h) + { mExtent[1] = h; } + + enum + { + NONE = 0, + WIDGET, + ARRAY + }; + private: // Copy not allowed, as the cell may own an array. LayoutCell(LayoutCell const &); @@ -272,13 +294,6 @@ class LayoutCell LayoutArray *mArray; }; - enum - { - NONE = 0, - WIDGET, - ARRAY - }; - /** * Returns the embedded array. Creates it if the cell does not contain * anything yet. Aborts if it contains a widget. diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp index 2796d3ab2..3204028dc 100644 --- a/src/gui/widgets/scrollarea.cpp +++ b/src/gui/widgets/scrollarea.cpp @@ -47,6 +47,8 @@ ScrollArea::ScrollArea(): gcn::ScrollArea(), mX(0), mY(0), + mClickX(0), + mClickY(0), mHasMouse(false), mOpaque(true), mVertexes(new GraphicsVertexes()), @@ -64,6 +66,8 @@ ScrollArea::ScrollArea(gcn::Widget *widget): gcn::ScrollArea(widget), mX(0), mY(0), + mClickX(0), + mClickY(0), mHasMouse(false), mOpaque(true), mVertexes(new GraphicsVertexes()), @@ -513,3 +517,56 @@ void ScrollArea::widgetMoved(const gcn::Event& event A_UNUSED) { mRedraw = true; } + +void ScrollArea::mousePressed(gcn::MouseEvent& event) +{ + gcn::ScrollArea::mousePressed(event); + if (event.getButton() == gcn::MouseEvent::LEFT) + { + mClickX = event.getX(); + mClickY = event.getY(); + } +} + +void ScrollArea::mouseReleased(gcn::MouseEvent& event) +{ + if (event.getButton() == gcn::MouseEvent::LEFT && mClickX && mClickY) + { + if (!event.isConsumed()) + { + int dx = event.getX() - mClickX; + int dy = event.getY() - mClickY; + + if ((dx < 10 && dx > 0) || (dx > -10 && dx < 0)) + dx = 0; + + if ((dy < 10 && dy > 0) || (dy > -10 && dy < 0)) + dy = 0; + + if (dx) + { + int s = getHorizontalScrollAmount() + dx; + if (s < 0) + s = 0; + else if (s > getHorizontalMaxScroll()) + s = getHorizontalMaxScroll(); + + setHorizontalScrollAmount(s); + } + if (dy) + { + int s = getVerticalScrollAmount() + dy; + if (s < 0) + s = 0; + else if (s > getVerticalMaxScroll()) + s = getVerticalMaxScroll(); + + setVerticalScrollAmount(s); + } + mClickX = 0; + mClickY = 0; + event.consume(); + } + } + gcn::ScrollArea::mouseReleased(event); +} diff --git a/src/gui/widgets/scrollarea.h b/src/gui/widgets/scrollarea.h index 095010f3c..56e21c58c 100644 --- a/src/gui/widgets/scrollarea.h +++ b/src/gui/widgets/scrollarea.h @@ -112,6 +112,10 @@ class ScrollArea : public gcn::ScrollArea, public gcn::WidgetListener */ void mouseExited(gcn::MouseEvent& event); + void mousePressed(gcn::MouseEvent& event); + + void mouseReleased(gcn::MouseEvent& event); + void widgetResized(const gcn::Event &event); void widgetMoved(const gcn::Event &event); @@ -148,6 +152,7 @@ class ScrollArea : public gcn::ScrollArea, public gcn::WidgetListener static Image *buttons[4][2]; int mX, mY; + int mClickX, mClickY; bool mHasMouse; bool mOpaque; GraphicsVertexes *mVertexes; diff --git a/src/gui/widgets/spellshortcutcontainer.cpp b/src/gui/widgets/spellshortcutcontainer.cpp index 8abe727b5..6317dd56f 100644 --- a/src/gui/widgets/spellshortcutcontainer.cpp +++ b/src/gui/widgets/spellshortcutcontainer.cpp @@ -290,5 +290,12 @@ void SpellShortcutContainer::mouseMoved(gcn::MouseEvent &event) // Hide SpellTooltip void SpellShortcutContainer::mouseExited(gcn::MouseEvent &event A_UNUSED) { - mSpellPopup->setVisible(false); + if (mSpellPopup) + mSpellPopup->setVisible(false); +} + +void SpellShortcutContainer::widgetHidden(const gcn::Event &event A_UNUSED) +{ + if (mSpellPopup) + mSpellPopup->setVisible(false); } diff --git a/src/gui/widgets/spellshortcutcontainer.h b/src/gui/widgets/spellshortcutcontainer.h index 2155e2a8b..88b00338a 100644 --- a/src/gui/widgets/spellshortcutcontainer.h +++ b/src/gui/widgets/spellshortcutcontainer.h @@ -77,6 +77,8 @@ class SpellShortcutContainer : public ShortcutContainer */ void mouseReleased(gcn::MouseEvent &event); + void widgetHidden(const gcn::Event &event); + private: void mouseExited(gcn::MouseEvent &event); void mouseMoved(gcn::MouseEvent &event); diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp index 5d4fbc0b4..6ce4cbf3b 100644 --- a/src/gui/widgets/textfield.cpp +++ b/src/gui/widgets/textfield.cpp @@ -51,11 +51,11 @@ TextField::TextField(const std::string &text, bool loseFocusOnTab, gcn::ActionListener* listener, std::string eventId, bool sendAlwaysEvents): gcn::TextField(text), + mSendAlwaysEvents(sendAlwaysEvents), mNumeric(false), mMinimum(0), mMaximum(0), - mLastEventPaste(false), - mSendAlwaysEvents(sendAlwaysEvents) + mLastEventPaste(false) { setFrameSize(2); diff --git a/src/gui/widgets/textfield.h b/src/gui/widgets/textfield.h index 7e19099e8..93f970168 100644 --- a/src/gui/widgets/textfield.h +++ b/src/gui/widgets/textfield.h @@ -96,6 +96,12 @@ class TextField : public gcn::TextField */ int getValue() const; + void setSendAlwaysEvents(bool b) + { mSendAlwaysEvents = b; } + + protected: + bool mSendAlwaysEvents; + private: void handlePaste(); @@ -109,7 +115,6 @@ class TextField : public gcn::TextField int mMaximum; bool mLoseFocusOnTab; int mLastEventPaste; - bool mSendAlwaysEvents; }; #endif diff --git a/src/gui/widgets/window.h b/src/gui/widgets/window.h index 510a68323..ffc27ab10 100644 --- a/src/gui/widgets/window.h +++ b/src/gui/widgets/window.h @@ -113,14 +113,14 @@ class Window : public gcn::Window, gcn::WidgetListener /** * Called whenever the widget changes size. */ - void widgetResized(const gcn::Event &event); + virtual void widgetResized(const gcn::Event &event); virtual void widgetMoved(const gcn::Event& event); /** * Called whenever the widget is hidden. */ - virtual void widgetHidden(const gcn::Event& event); + virtual void widgetHidden(const gcn::Event &event); /** * Sets whether or not the window has a close button. diff --git a/src/guild.h b/src/guild.h index 62135e9ad..915dda5e7 100644 --- a/src/guild.h +++ b/src/guild.h @@ -65,7 +65,7 @@ protected: class Guild : public AvatarListModel { public: - ~Guild(); + virtual ~Guild(); /** * Set the guild's name. diff --git a/src/keyboardconfig.cpp b/src/keyboardconfig.cpp index ea9f9b90b..fdc8201ca 100644 --- a/src/keyboardconfig.cpp +++ b/src/keyboardconfig.cpp @@ -40,6 +40,7 @@ struct KeyData // keyData must be in same order as enum keyAction. static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = { + {"", 0, N_("Basic Keys"), 0}, {"keyMoveUp", SDLK_UP, N_("Move Up"), KeyboardConfig::GRP_DEFAULT}, {"keyMoveDown", SDLK_DOWN, N_("Move Down"), KeyboardConfig::GRP_DEFAULT}, {"keyMoveLeft", SDLK_LEFT, N_("Move Left"), KeyboardConfig::GRP_DEFAULT}, @@ -58,9 +59,10 @@ static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = { KeyboardConfig::GRP_DEFAULT}, {"keyMoveToPoint", SDLK_RSHIFT, N_("Move to navigation point"), KeyboardConfig::GRP_DEFAULT}, - {"keySmilie", SDLK_LALT, N_("Smilie"), KeyboardConfig::GRP_DEFAULT}, {"keyTalk", SDLK_t, N_("Talk"), KeyboardConfig::GRP_DEFAULT}, {"keyTarget", SDLK_LSHIFT, N_("Stop Attack"), KeyboardConfig::GRP_DEFAULT}, + {"keyUnTarget", KeyboardConfig::KEY_NO_VALUE, + N_("Untarget"), KeyboardConfig::GRP_DEFAULT}, {"keyTargetClosest", SDLK_a, N_("Target Closest"), KeyboardConfig::GRP_DEFAULT}, {"keyTargetNPC", SDLK_n, N_("Target NPC"), KeyboardConfig::GRP_DEFAULT}, @@ -77,6 +79,10 @@ static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = { KeyboardConfig::GRP_DEFAULT}, {"keyPathfind", SDLK_f, N_("Change Map View Mode"), KeyboardConfig::GRP_DEFAULT}, + {"keyOK", SDLK_SPACE, N_("Select OK"), + KeyboardConfig::GRP_DEFAULT | KeyboardConfig::GRP_GUI}, + {"keyQuit", SDLK_ESCAPE, N_("Quit"), KeyboardConfig::GRP_DEFAULT}, + {"", 0, N_("Shortcuts Keys"), 0}, {"keyShortcutsKey", SDLK_MENU, N_("Item Shortcuts Key"), KeyboardConfig::GRP_DEFAULT}, {"keyShortcut1", SDLK_1, strprintf(N_("Item Shortcut %d"), 1), @@ -119,6 +125,7 @@ static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = { strprintf(N_("Item Shortcut %d"), 19), KeyboardConfig::GRP_DEFAULT}, {"keyShortcut20", KeyboardConfig::KEY_NO_VALUE, strprintf(N_("Item Shortcut %d"), 20), KeyboardConfig::GRP_DEFAULT}, + {"", 0, N_("Windows Keys"), 0}, {"keyWindowHelp", SDLK_F1, N_("Help Window"), KeyboardConfig::GRP_DEFAULT | KeyboardConfig::GRP_GUI}, {"keyWindowStatus", SDLK_F2, N_("Status Window"), @@ -165,6 +172,8 @@ static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = { | KeyboardConfig::GRP_GUI}, {"keySocialNextTab", KeyboardConfig::KEY_NO_VALUE, N_("Next Social Tab"), KeyboardConfig::GRP_DEFAULT | KeyboardConfig::GRP_GUI}, + {"", 0, N_("Emotes Keys"), 0}, + {"keySmilie", SDLK_LALT, N_("Smilie"), KeyboardConfig::GRP_DEFAULT}, {"keyEmoteShortcut1", SDLK_1, strprintf(N_("Emote Shortcut %d"), 1), KeyboardConfig::GRP_EMOTION}, {"keyEmoteShortcut2", SDLK_2, strprintf(N_("Emote Shortcut %d"), 2), @@ -258,12 +267,14 @@ static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = { KeyboardConfig::GRP_EMOTION}, {"keyEmoteShortcut44", SDLK_b, strprintf(N_("Emote Shortcut %d"), 44), KeyboardConfig::GRP_EMOTION}, + {"", 0, N_("Outfits Keys"), 0}, {"keyWearOutfit", SDLK_RCTRL, N_("Wear Outfit"), KeyboardConfig::GRP_DEFAULT}, {"keyCopyOutfit", SDLK_RALT, N_("Copy Outfit"), KeyboardConfig::GRP_DEFAULT}, {"keyCopyEquipedOutfit", SDLK_RIGHTBRACKET, N_("Copy equipped to Outfit"), KeyboardConfig::GRP_DEFAULT}, + {"", 0, N_("Chat Keys"), 0}, {"keyChat", SDLK_RETURN, N_("Toggle Chat"), KeyboardConfig::GRP_DEFAULT | KeyboardConfig::GRP_CHAT}, {"keyChatScrollUp", SDLK_PAGEUP, N_("Scroll Chat Up"), @@ -285,9 +296,7 @@ static KeyData const keyData[KeyboardConfig::KEY_TOTAL] = { KeyboardConfig::GRP_CHAT}, {"keyDeActivateChat", SDLK_ESCAPE, N_("Deactivate Chat Input"), KeyboardConfig::GRP_CHAT}, - {"keyOK", SDLK_SPACE, N_("Select OK"), - KeyboardConfig::GRP_DEFAULT | KeyboardConfig::GRP_GUI}, - {"keyQuit", SDLK_ESCAPE, N_("Quit"), KeyboardConfig::GRP_DEFAULT}, + {"", 0, N_("Other Keys"), 0}, {"keyIgnoreInput1", SDLK_LSUPER, N_("Ignore input 1"), KeyboardConfig::GRP_DEFAULT}, {"keyIgnoreInput2", SDLK_RSUPER, N_("Ignore input 2"), @@ -370,15 +379,21 @@ void KeyboardConfig::retrieve() { for (int i = 0; i < KEY_TOTAL; i++) { - mKey[i].value = static_cast<int>(config.getValue( - mKey[i].configField, mKey[i].defaultValue)); + if (*mKey[i].configField) + { + mKey[i].value = static_cast<int>(config.getValue( + mKey[i].configField, mKey[i].defaultValue)); + } } } void KeyboardConfig::store() { for (int i = 0; i < KEY_TOTAL; i++) - config.setValue(mKey[i].configField, mKey[i].value); + { + if (*mKey[i].configField) + config.setValue(mKey[i].configField, mKey[i].value); + } } void KeyboardConfig::makeDefault() @@ -396,7 +411,7 @@ bool KeyboardConfig::hasConflicts() */ for (i = 0; i < KEY_TOTAL; i++) { - if (mKey[i].value == KEY_NO_VALUE) + if (mKey[i].value == KEY_NO_VALUE || !*mKey[i].configField) continue; for (j = i, j++; j < KEY_TOTAL; j++) @@ -405,7 +420,8 @@ bool KeyboardConfig::hasConflicts() // as well as emote and ignore keys, but no other keys if (mKey[j].value != KEY_NO_VALUE && mKey[i].value == mKey[j].value && - ((mKey[i].grp & mKey[j].grp) != 0) + ((mKey[i].grp & mKey[j].grp) != 0 && + *mKey[i].configField) ) { mBindError = strprintf(_("Conflict \"%s\" and \"%s\" keys. " diff --git a/src/keyboardconfig.h b/src/keyboardconfig.h index 43bb1c17f..b322eb6d1 100644 --- a/src/keyboardconfig.h +++ b/src/keyboardconfig.h @@ -78,6 +78,9 @@ class KeyboardConfig int getKeyValue(int index) const { return mKey[index].value; } + bool isSeparator(int index) const + { return !*mKey[index].configField; } + /** * Get the index of the new key to be assigned. */ @@ -157,6 +160,7 @@ class KeyboardConfig enum KeyAction { KEY_NO_VALUE = -1, + KEY_SEPARATOR1, KEY_MOVE_UP, KEY_MOVE_DOWN, KEY_MOVE_LEFT, @@ -168,9 +172,9 @@ class KeyboardConfig KEY_MOVE_TO_HOME, KEY_SET_HOME, KEY_MOVE_TO_POINT, - KEY_EMOTE, KEY_TALK, KEY_TARGET, + KEY_UNTARGET, KEY_TARGET_CLOSEST, KEY_TARGET_NPC, KEY_TARGET_PLAYER, @@ -181,6 +185,9 @@ class KeyboardConfig KEY_SCREENSHOT, KEY_TRADE, KEY_PATHFIND, + KEY_OK, + KEY_QUIT, + KEY_SEPARATOR2, KEY_SHORTCUTS_KEY, KEY_SHORTCUT_1, KEY_SHORTCUT_2, @@ -202,6 +209,7 @@ class KeyboardConfig KEY_SHORTCUT_18, KEY_SHORTCUT_19, KEY_SHORTCUT_20, + KEY_SEPARATOR3, KEY_WINDOW_HELP, KEY_WINDOW_STATUS, KEY_WINDOW_INVENTORY, @@ -224,6 +232,8 @@ class KeyboardConfig KEY_WINDOW_DIDYOUKNOW, KEY_PREV_SOCIAL_TAB, KEY_NEXT_SOCIAL_TAB, + KEY_SEPARATOR4, + KEY_EMOTE, KEY_EMOTE_1, KEY_EMOTE_2, KEY_EMOTE_3, @@ -268,9 +278,11 @@ class KeyboardConfig KEY_EMOTE_42, KEY_EMOTE_43, KEY_EMOTE_44, + KEY_SEPARATOR5, KEY_WEAR_OUTFIT, KEY_COPY_OUTFIT, KEY_COPY_EQUIPED_OUTFIT, + KEY_SEPARATOR6, KEY_TOGGLE_CHAT, KEY_SCROLL_CHAT_UP, KEY_SCROLL_CHAT_DOWN, @@ -281,8 +293,7 @@ class KeyboardConfig KEY_CHAT_NEXT_HISTORY, KEY_AUTOCOMPLETE_CHAT, KEY_DEACTIVATE_CHAT, - KEY_OK, - KEY_QUIT, + KEY_SEPARATOR7, KEY_IGNORE_INPUT_1, KEY_IGNORE_INPUT_2, KEY_DIRECT_UP, diff --git a/src/listener.h b/src/listener.h index 8993c31af..cccc026c6 100644 --- a/src/listener.h +++ b/src/listener.h @@ -32,7 +32,7 @@ namespace Mana class Listener { public: - ~Listener(); + virtual ~Listener(); void listen(Channels channel); diff --git a/src/localplayer.cpp b/src/localplayer.cpp index e17cf09c4..28ffc4cf5 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -171,6 +171,7 @@ LocalPlayer::LocalPlayer(int id, int subtype): mShowJobExp = config.getBoolValue("showJobExp"); mEnableAdvert = config.getBoolValue("enableAdvert"); mTradebot = config.getBoolValue("tradebot"); + mTargetOnlyReachable = config.getBoolValue("targetOnlyReachable"); mPingSendTick = 0; mWaitPing = false; @@ -192,6 +193,7 @@ LocalPlayer::LocalPlayer(int id, int subtype): config.addListener("showJobExp", this); config.addListener("enableAdvert", this); config.addListener("tradebot", this); + config.addListener("targetOnlyReachable", this); setShowName(config.getBoolValue("showownname")); } @@ -209,6 +211,7 @@ LocalPlayer::~LocalPlayer() config.removeListener("showJobExp", this); config.removeListener("enableAdvert", this); config.removeListener("tradebot", this); + config.removeListener("targetOnlyReachable", this); delete mAwayDialog; mAwayDialog = 0; @@ -219,7 +222,7 @@ LocalPlayer::~LocalPlayer() void LocalPlayer::logic() { if (mumbleManager) - mumbleManager->setPos(getTileX(), getTileY(), getDirection()); + mumbleManager->setPos(mX, mY, mDirection); // Actions are allowed once per second if (get_elapsed_time(mLastAction) >= 1000) @@ -236,14 +239,14 @@ void LocalPlayer::logic() dist = 20; if ((mNavigateX || mNavigateY) && - ((mCrossX + dist >= getTileX() && mCrossX <= getTileX() + dist - && mCrossY + dist >= getTileY() && mCrossY <= getTileY() + dist) + ((mCrossX + dist >= mX && mCrossX <= mX + dist + && mCrossY + dist >= mY && mCrossY <= mY + dist) || (!mCrossX && !mCrossY))) { for (Path::const_iterator i = mNavigatePath.begin(), i_end = mNavigatePath.end(); i != i_end; ++i) { - if ((*i).x == getTileX() && (*i).y == getTileY()) + if ((*i).x == mX && (*i).y == mY) { mNavigatePath.pop_front(); break; @@ -813,8 +816,8 @@ void LocalPlayer::nextTile(unsigned char dir A_UNUSED = 0) PartyMember *pm = Party::getParty(1)->getMember(getName()); if (pm) { - pm->setX(getTileX()); - pm->setY(getTileY()); + pm->setX(mX); + pm->setY(mY); } } @@ -925,8 +928,8 @@ bool LocalPlayer::pickUp(FloorItem *item) if (!Client::limitPackets(PACKET_PICKUP)) return false; - int dx = item->getTileX() - getTileX(); - int dy = item->getTileY() - getTileY(); + int dx = item->getTileX() - mX; + int dy = item->getTileY() - mY; int dist = 6; if (mPickUpType >= 4 && mPickUpType <= 6) @@ -1148,7 +1151,7 @@ void LocalPlayer::startWalking(unsigned char dir) else #endif { - Being::setDestination(getTileX(), getTileY()); + Being::setDestination(mX, mY); } return; } @@ -1324,8 +1327,8 @@ void LocalPlayer::attack(Being *target, bool keep, bool dontChangeEquipment) else #endif { - int dist_x = target->getTileX() - getTileX(); - int dist_y = target->getTileY() - getTileY(); + int dist_x = target->getTileX() - mX; + int dist_y = target->getTileY() - mY; // Must be standing or sitting to attack if (mAction != STAND && mAction != SIT) @@ -1380,9 +1383,17 @@ void LocalPlayer::attack(Being *target, bool keep, bool dontChangeEquipment) void LocalPlayer::stopAttack() { + if (!Client::limitPackets(PACKET_STOPATTACK)) + return; + if (mServerAttack && mAction == ATTACK) Net::getPlayerHandler()->stopAttack(); + untarget(); +} + +void LocalPlayer::untarget() +{ if (mAction == ATTACK) setAction(STAND); @@ -1516,8 +1527,8 @@ bool LocalPlayer::withinAttackRange(Being *target, bool fixDistance, else #endif { - dx = static_cast<int>(abs(target->getTileX() - getTileX())); - dy = static_cast<int>(abs(target->getTileY() - getTileY())); + dx = static_cast<int>(abs(target->getTileX() - mX)); + dy = static_cast<int>(abs(target->getTileY() - mY)); } return !(dx > range || dy > range); } @@ -1631,6 +1642,8 @@ void LocalPlayer::optionChanged(const std::string &value) mEnableAdvert = config.getBoolValue("enableAdvert"); else if (value == "tradebot") mTradebot = config.getBoolValue("tradebot"); + else if (value == "targetOnlyReachable") + mTargetOnlyReachable = config.getBoolValue("targetOnlyReachable"); } void LocalPlayer::processEvent(Mana::Channels channel, @@ -1712,7 +1725,7 @@ void LocalPlayer::moveTo(int x, int y) void LocalPlayer::move(int dX, int dY) { mPickUpTarget = 0; - moveTo(getTileX() + dX, getTileY() + dY); + moveTo(mX + dX, mY + dY); } void LocalPlayer::moveToTarget(unsigned int dist) @@ -1811,7 +1824,7 @@ void LocalPlayer::moveToTarget(unsigned int dist) void LocalPlayer::moveToHome() { mPickUpTarget = 0; - if ((getTileX() != mCrossX || getTileY() != mCrossY) && mCrossX && mCrossY) + if ((mX != mCrossX || mY != mCrossY) && mCrossX && mCrossY) { moveTo(mCrossX, mCrossY); } @@ -1823,7 +1836,7 @@ void LocalPlayer::moveToHome() if (iter != mHomes.end()) { Vector pos = mHomes[(*iter).first]; - if (getTileX() == pos.x && getTileY() == pos.y) + if (mX == pos.x && mY == pos.y) { Net::getPlayerHandler()->setDestination( static_cast<int>(pos.x), @@ -1922,8 +1935,8 @@ void LocalPlayer::changeEquipmentBeforeAttack(Being* target) return; bool allowSword = false; - int dx = target->getTileX() - getTileX(); - int dy = target->getTileY() - getTileY(); + int dx = target->getTileX() - mX; + int dy = target->getTileY() - mY; Item *item = NULL; if (dx * dx + dy * dy > 80) @@ -2039,25 +2052,25 @@ void LocalPlayer::crazyMove1() if (!Client::limitPackets(PACKET_DIRECTION)) return; - if (getDirection() == Being::UP) + if (mDirection == Being::UP) { setWalkingDir(Being::UP); setDirection(Being::LEFT); Net::getPlayerHandler()->setDirection(Being::LEFT); } - else if (getDirection() == Being::LEFT) + else if (mDirection == Being::LEFT) { setWalkingDir(Being::LEFT); setDirection(Being::DOWN); Net::getPlayerHandler()->setDirection(Being::DOWN); } - else if (getDirection() == Being::DOWN) + else if (mDirection == Being::DOWN) { setWalkingDir(Being::DOWN); setDirection(Being::RIGHT); Net::getPlayerHandler()->setDirection(Being::RIGHT); } - else if (getDirection() == Being::RIGHT) + else if (mDirection == Being::RIGHT) { setWalkingDir(Being::RIGHT); setDirection(Being::UP); @@ -2073,25 +2086,25 @@ void LocalPlayer::crazyMove2() if (!Client::limitPackets(PACKET_DIRECTION)) return; - if (getDirection() == Being::UP) + if (mDirection == Being::UP) { setWalkingDir(Being::UP | Being::LEFT); setDirection(Being::RIGHT); Net::getPlayerHandler()->setDirection(Being::DOWN | Being::RIGHT); } - else if (getDirection() == Being::RIGHT) + else if (mDirection == Being::RIGHT) { setWalkingDir(Being::UP | Being::RIGHT); setDirection(Being::DOWN); Net::getPlayerHandler()->setDirection(Being::DOWN | Being::LEFT); } - else if (getDirection() == Being::DOWN) + else if (mDirection == Being::DOWN) { setWalkingDir(Being::DOWN | Being::RIGHT); setDirection(Being::LEFT); Net::getPlayerHandler()->setDirection(Being::UP | Being::LEFT); } - else if (getDirection() == Being::LEFT) + else if (mDirection == Being::LEFT) { setWalkingDir(Being::DOWN | Being::LEFT); setDirection(Being::UP); @@ -2272,19 +2285,19 @@ void LocalPlayer::crazyMove8() { 1, 0, -1, 0} //move down }; - if (getDirection() == Being::UP) + if (mDirection == Being::UP) idx = 0; - else if (getDirection() == Being::RIGHT) + else if (mDirection == Being::RIGHT) idx = 1; - else if (getDirection() == Being::DOWN) + else if (mDirection == Being::DOWN) idx = 2; - else if (getDirection() == Being::LEFT) + else if (mDirection == Being::LEFT) idx = 3; int mult = 1; if (mMap->getWalk(mX + movesX[idx][0], - getTileY() + movesY[idx][0], getWalkMask())) + mY + movesY[idx][0], getWalkMask())) { while (mMap->getWalk(mX + movesX[idx][0] * mult, mY + movesY[idx][0] * mult, @@ -2340,7 +2353,7 @@ void LocalPlayer::crazyMove9() switch (mCrazyMoveState) { case 0: - switch (getDirection()) + switch (mDirection) { case UP : dy = -1; break; case DOWN : dy = 1; break; @@ -2412,7 +2425,7 @@ void LocalPlayer::crazyMoveA() move(1, 0); break; case 'f': - switch (getDirection()) + switch (mDirection) { case UP : dy = -1; break; case DOWN : dy = 1; break; @@ -2423,7 +2436,7 @@ void LocalPlayer::crazyMoveA() move(dx, dy); break; case 'b': - switch (getDirection()) + switch (mDirection) { case UP : dy = 1; break; case DOWN : dy = -1; break; @@ -2487,7 +2500,7 @@ void LocalPlayer::crazyMoveA() if (Client::limitPackets(PACKET_DIRECTION)) { Uint8 dir = 0; - switch (getDirection()) + switch (mDirection) { case UP : dir = Being::LEFT; break; case DOWN : dir = Being::RIGHT; break; @@ -2503,7 +2516,7 @@ void LocalPlayer::crazyMoveA() if (Client::limitPackets(PACKET_DIRECTION)) { Uint8 dir = 0; - switch (getDirection()) + switch (mDirection) { case UP : dir = Being::RIGHT; break; case DOWN : dir = Being::LEFT; break; @@ -2519,7 +2532,7 @@ void LocalPlayer::crazyMoveA() if (Client::limitPackets(PACKET_DIRECTION)) { Uint8 dir = 0; - switch (getDirection()) + switch (mDirection) { case UP : dir = Being::DOWN; break; case DOWN : dir = Being::UP; break; @@ -2614,8 +2627,8 @@ bool LocalPlayer::isReachable(int x, int y, int maxCost) if (!mMap) return false; - if (x - 1 <= getTileX() && x + 1 >= getTileX() - && y - 1 <= getTileY() && y + 1 >= getTileY() ) + if (x - 1 <= mX && x + 1 >= mX + && y - 1 <= mY && y + 1 >= mY ) { return true; } @@ -2638,17 +2651,17 @@ bool LocalPlayer::isReachable(Being *being, int maxCost) if (being->isReachable() == Being::REACH_NO) return false; - if (being->getTileX() == getTileX() - && being->getTileY() == getTileY()) + if (being->getTileX() == mX + && being->getTileY() == mY) { being->setDistance(0); being->setIsReachable(Being::REACH_YES); return true; } - else if (being->getTileX() - 1 <= getTileX() - && being->getTileX() + 1 >= getTileX() - && being->getTileY() - 1 <= getTileY() - && being->getTileY() + 1 >= getTileY()) + else if (being->getTileX() - 1 <= mX + && being->getTileX() + 1 >= mX + && being->getTileY() - 1 <= mY + && being->getTileY() + 1 >= mY) { being->setDistance(1); being->setIsReachable(Being::REACH_YES); @@ -2681,8 +2694,8 @@ bool LocalPlayer::pickUpItems(int pickUpType) return false; bool status = false; - int x = getTileX(); - int y = getTileY(); + int x = mX; + int y = mY; // first pick up item on player position FloorItem *item = @@ -2703,7 +2716,7 @@ bool LocalPlayer::pickUpItems(int pickUpType) switch(pickUpType) { case 1: - switch (getDirection()) + switch (mDirection) { case UP : --y; break; case DOWN : ++y; break; @@ -2719,7 +2732,7 @@ bool LocalPlayer::pickUpItems(int pickUpType) } break; case 2: - switch (getDirection()) + switch (mDirection) { case UP : x1 = x - 1; y1 = y - 1; x2 = x + 1; y2 = y; break; case DOWN : x1 = x - 1; y1 = y; x2 = x + 1; y2 = y + 1; break; @@ -2996,8 +3009,8 @@ void LocalPlayer::setHome() static_cast<int>(pos.y)); } - if (iter != mHomes.end() && getTileX() == static_cast<int>(pos.x) - && getTileY() == static_cast<int>(pos.y)) + if (iter != mHomes.end() && mX == static_cast<int>(pos.x) + && mY == static_cast<int>(pos.y)) { mMap->updatePortalTile("", MapItem::EMPTY, static_cast<int>(pos.x), static_cast<int>(pos.y)); @@ -3014,17 +3027,17 @@ void LocalPlayer::setHome() static_cast<int>(pos.y), MapItem::EMPTY); } - pos.x = static_cast<float>(getTileX()); - pos.y = static_cast<float>(getTileY()); + pos.x = static_cast<float>(mX); + pos.y = static_cast<float>(mY); mHomes[key] = pos; mMap->updatePortalTile("home", MapItem::HOME, - getTileX(), getTileY()); - socialWindow->addPortal(getTileX(), getTileY()); + mX, mY); + socialWindow->addPortal(mX, mY); } - MapItem *mapItem = specialLayer->getTile(getTileX(), getTileY()); + MapItem *mapItem = specialLayer->getTile(mX, mY); if (mapItem) { - int idx = socialWindow->getPortalIndex(getTileX(), getTileY()); + int idx = socialWindow->getPortalIndex(mX, mY); mapItem->setName(keyboard.getKeyShortString( outfitWindow->keyName(idx))); } @@ -3032,11 +3045,11 @@ void LocalPlayer::setHome() } else { - MapItem *mapItem = specialLayer->getTile(getTileX(), getTileY()); + MapItem *mapItem = specialLayer->getTile(mX, mY); int type = 0; std::map<std::string, Vector>::iterator iter = mHomes.find(key); - if (iter != mHomes.end() && getTileX() == pos.x && getTileY() == pos.y) + if (iter != mHomes.end() && mX == pos.x && mY == pos.y) { mHomes.erase(key); saveHomes(); @@ -3057,26 +3070,24 @@ void LocalPlayer::setHome() { type = MapItem::EMPTY; } - mMap->updatePortalTile("", type, getTileX(), getTileY()); + mMap->updatePortalTile("", type, mX, mY); if (type != MapItem::EMPTY) { - socialWindow->addPortal(getTileX(), getTileY()); - mapItem = specialLayer->getTile(getTileX(), getTileY()); + socialWindow->addPortal(mX, mY); + mapItem = specialLayer->getTile(mX, mY); if (mapItem) { - int idx = socialWindow->getPortalIndex(getTileX(), getTileY()); + int idx = socialWindow->getPortalIndex(mX, mY); mapItem->setName(keyboard.getKeyShortString( outfitWindow->keyName(idx))); } } else { - specialLayer->setTile(getTileX(), getTileY(), MapItem::EMPTY); - socialWindow->removePortal(getTileX(), getTileY()); + specialLayer->setTile(mX, mY, MapItem::EMPTY); + socialWindow->removePortal(mX, mY); } - -// specialLayer->setTile(getTileX(), getTileY(), type); } } @@ -3234,8 +3245,8 @@ bool LocalPlayer::navigateTo(int x, int y) mShowNavigePath = true; mOldX = static_cast<int>(playerPos.x); mOldY = static_cast<int>(playerPos.y); - mOldTileX = getTileX(); - mOldTileY = getTileY(); + mOldTileX = mX; + mOldTileY = mY; mNavigateX = x; mNavigateY = y; mNavigateId = 0; @@ -3263,8 +3274,8 @@ void LocalPlayer::navigateTo(Being *being) mShowNavigePath = true; mOldX = static_cast<int>(playerPos.x); mOldY = static_cast<int>(playerPos.y); - mOldTileX = getTileX(); - mOldTileY = getTileY(); + mOldTileX = mX; + mOldTileY = mY; mNavigateX = being->getTileX(); mNavigateY = being->getTileY(); @@ -3307,7 +3318,7 @@ void LocalPlayer::updateCoords() const Vector &playerPos = getPosition(); - if (getTileX() != mOldTileX || getTileY() != mOldTileY) + if (mX != mOldTileX || mY != mOldTileY) { if (socialWindow) socialWindow->updatePortals(); @@ -3315,7 +3326,7 @@ void LocalPlayer::updateCoords() viewport->hideBeingPopup(); if (mMap) { - std::string str = mMap->getObjectData(getTileX(), getTileY(), + std::string str = mMap->getObjectData(mX, mY, MapItem::MUSIC); if (str.empty()) str = mMap->getMusicFile(); @@ -3331,7 +3342,7 @@ void LocalPlayer::updateCoords() if (mShowNavigePath) { - if (mMap && (getTileX() != mOldTileX || getTileY() != mOldTileY)) + if (mMap && (mX != mOldTileX || mY != mOldTileY)) { SpecialLayer *tmpLayer = mMap->getTempLayer(); if (!tmpLayer) @@ -3367,7 +3378,7 @@ void LocalPlayer::updateCoords() for (Path::const_iterator i = mNavigatePath.begin(), i_end = mNavigatePath.end(); i != i_end; ++i) { - if ((*i).x == getTileX() && (*i).y == getTileY()) + if ((*i).x == mX && (*i).y == mY) { mNavigatePath.pop_front(); break; @@ -3385,8 +3396,8 @@ void LocalPlayer::updateCoords() } mOldX = static_cast<int>(playerPos.x); mOldY = static_cast<int>(playerPos.y); - mOldTileX = getTileX(); - mOldTileY = getTileY(); + mOldTileX = mX; + mOldTileY = mY; } void LocalPlayer::targetMoved() @@ -3413,12 +3424,40 @@ int LocalPlayer::getPathLength(Being* being) const Vector &playerPos = getPosition(); - Path debugPath = mMap->findPath( - static_cast<int>(playerPos.x - 16) / 32, - static_cast<int>(playerPos.y - 32) / 32, - being->getTileX(), being->getTileY(), - getWalkMask(), 0); - return static_cast<int>(debugPath.size()); + if (being->mX == mX && being->mY == mY) + return 0; + + if (being->mX - 1 <= mX && being->mX + 1 >= mX + && being->mY - 1 <= mY && being->mY + 1 >= mY) + { + return 1; + } + + if (mTargetOnlyReachable) + { + Path debugPath = mMap->findPath( + static_cast<int>(playerPos.x - 16) / 32, + static_cast<int>(playerPos.y - 32) / 32, + being->getTileX(), being->getTileY(), + getWalkMask(), 0); + return static_cast<int>(debugPath.size()); + } + else + { + const int dx = static_cast<int>(abs(being->mX - mX)); + const int dy = static_cast<int>(abs(being->mY - mY)); + if (dx > dy) + return dx; + return dy; + } +} + +int LocalPlayer::getAttackRange2() +{ + int range = getAttackRange(); + if (range == 1) + range = 2; + return range; } void LocalPlayer::attack2(Being *target, bool keep, bool dontChangeEquipment) @@ -3428,7 +3467,7 @@ void LocalPlayer::attack2(Being *target, bool keep, bool dontChangeEquipment) if ((!target || getAttackType() == 0 || getAttackType() == 3) || (withinAttackRange(target, true, 1) - && getPathLength(target) <= getAttackRange() + 1)) + && getPathLength(target) <= getAttackRange2())) { attack(target, keep); if (getAttackType() == 2) @@ -3632,15 +3671,15 @@ void LocalPlayer::followMoveTo(Being *being, int x1, int y1, int x2, int y2) case 1: if (x1 != x2 || y1 != y2) { - setDestination(getTileX() + x2 - x1, getTileY() + y2 - y1); - setNextDest(getTileX() + x2 - x1, getTileY() + y2 - y1); + setDestination(mX + x2 - x1, mY + y2 - y1); + setNextDest(mX + x2 - x1, mY + y2 - y1); } break; case 2: if (x1 != x2 || y1 != y2) { - setDestination(getTileX() + x1 - x2, getTileY() + y1 - y2); - setNextDest(getTileX() + x1 - x2, getTileY() + y1 - y2); + setDestination(mX + x1 - x2, mY + y1 - y2); + setNextDest(mX + x1 - x2, mY + y1 - y2); } break; case 3: @@ -3694,8 +3733,8 @@ void LocalPlayer::fixPos(int maxDist) if (!mCrossX && !mCrossY) return; - int dx = abs(getTileX() - mCrossX); - int dy = abs(getTileY() - mCrossY); + int dx = abs(mX - mCrossX); + int dy = abs(mY - mCrossY); int dest = (dx * dx) + (dy * dy); if (dest > maxDist && mActivityTime diff --git a/src/localplayer.h b/src/localplayer.h index cb23d855e..447306994 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -139,6 +139,8 @@ class LocalPlayer : public Being, public ActorSpriteListener, */ int getAttackRange(); + int getAttackRange2(); + void attack(Being *target = NULL, bool keep = false, bool dontChangeEquipment = false); @@ -152,6 +154,8 @@ class LocalPlayer : public Being, public ActorSpriteListener, void stopAttack(); + void untarget(); + /** * Returns the current target of the player. Returns 0 if no being is * currently targeted. @@ -601,6 +605,7 @@ class LocalPlayer : public Being, public ActorSpriteListener, bool mBlockAdvert; bool mEnableAdvert; bool mTradebot; + bool mTargetOnlyReachable; bool mNextStep; }; diff --git a/src/main.h b/src/main.h index 0348d2700..95a1b1698 100644 --- a/src/main.h +++ b/src/main.h @@ -85,8 +85,8 @@ //define DEBUG_ALPHA_CACHE 1 //define DEBUG_OPENGL_LEAKS 1 -#define SMALL_VERSION "1.1.9.18" -#define CHECK_VERSION "01.01.09.18" +#define SMALL_VERSION "1.1.10.2" +#define CHECK_VERSION "01.01.10.02" #define PACKAGE_EXTENDED_VERSION "ManaPlus (" PACKAGE_OS \ diff --git a/src/net/beinghandler.h b/src/net/beinghandler.h index 07279b148..bc1491ada 100644 --- a/src/net/beinghandler.h +++ b/src/net/beinghandler.h @@ -32,6 +32,9 @@ namespace Net class BeingHandler { public: + virtual ~BeingHandler() + { } + virtual void handleMessage(Net::MessageIn &msg) = 0; virtual void requestNameById(int id) = 0; diff --git a/src/net/buysellhandler.h b/src/net/buysellhandler.h index 213da227d..ad70c2884 100644 --- a/src/net/buysellhandler.h +++ b/src/net/buysellhandler.h @@ -34,6 +34,9 @@ namespace Net class BuySellHandler { public: + virtual ~BuySellHandler() + { } + virtual void handleMessage(Net::MessageIn &msg) = 0; virtual void requestSellList(std::string nick) = 0; virtual void requestBuyList(std::string nick) = 0; diff --git a/src/net/ea/partyhandler.cpp b/src/net/ea/partyhandler.cpp index e006b9c71..36e192ce8 100644 --- a/src/net/ea/partyhandler.cpp +++ b/src/net/ea/partyhandler.cpp @@ -34,8 +34,6 @@ #include "debug.h" -#define PARTY_ID 1 - namespace Ea { diff --git a/src/net/ea/specialhandler.cpp b/src/net/ea/specialhandler.cpp index 4f0f22aed..b78531434 100644 --- a/src/net/ea/specialhandler.cpp +++ b/src/net/ea/specialhandler.cpp @@ -50,8 +50,6 @@ #define BSKILL_CREATECHAT 0x0003 #define BSKILL_JOINPARTY 0x0004 #define BSKILL_SHOUT 0x0005 -#define BSKILL_PK 0x0006 // ?? -#define BSKILL_SETALLIGN 0x0007 // ?? /** reasons why action failed */ #define RFAIL_SKILLDEP 0x00 @@ -64,7 +62,6 @@ #define RFAIL_REDGEM 0x07 #define RFAIL_BLUEGEM 0x08 #define RFAIL_OVERWEIGHT 0x09 -#define RFAIL_GENERIC 0x0a /** should always be zero if failed */ #define SKILL_FAILED 0x00 diff --git a/src/net/tmwa/messagein.cpp b/src/net/tmwa/messagein.cpp index fb1986597..5a9d39211 100644 --- a/src/net/tmwa/messagein.cpp +++ b/src/net/tmwa/messagein.cpp @@ -33,10 +33,6 @@ #include "debug.h" -#define MAKEWORD(low, high) \ - ((unsigned short)(((unsigned char)(low)) | \ - ((unsigned short)((unsigned char)(high))) << 8)) - namespace TmwAthena { diff --git a/src/net/tradehandler.h b/src/net/tradehandler.h index 837c53eeb..f099efe53 100644 --- a/src/net/tradehandler.h +++ b/src/net/tradehandler.h @@ -38,6 +38,9 @@ namespace Net class TradeHandler { public: + virtual ~TradeHandler() + { } + virtual void request(Being *being A_UNUSED) { } // virtual ~TradeHandler() {} diff --git a/src/party.h b/src/party.h index e286a794a..73c45214a 100644 --- a/src/party.h +++ b/src/party.h @@ -167,7 +167,7 @@ private: */ Party(short id); - ~Party(); + virtual ~Party(); MemberList mMembers; std::string mName; diff --git a/src/resources/resourcemanager.cpp b/src/resources/resourcemanager.cpp index ee325e253..fcba17812 100644 --- a/src/resources/resourcemanager.cpp +++ b/src/resources/resourcemanager.cpp @@ -48,8 +48,6 @@ #include "debug.h" -#define THEMES_FOLDER "themes" - ResourceManager *ResourceManager::instance = NULL; ResourceManager::ResourceManager() : diff --git a/src/spellmanager.cpp b/src/spellmanager.cpp index 895ac94f2..9f7aaaa8b 100644 --- a/src/spellmanager.cpp +++ b/src/spellmanager.cpp @@ -68,31 +68,31 @@ void SpellManager::fillSpells() { //id, std::string name, std::string symbol, ST type, int basicLvl, MagicSchool school, int schoolLvl, int mana) - addSpell(new TextCommand(0, "lum", "#lum", ALLOWTARGET, - "", 1, SKILL_MAGIC_LIFE, 0, 6)); - addSpell(new TextCommand(1, "inm", "#inma", NEEDTARGET, + addSpell(new TextCommand(0, "lum", "#lum", "heal with lifestones", + ALLOWTARGET, "", 1, SKILL_MAGIC_LIFE, 0, 6)); + addSpell(new TextCommand(1, "inm", "#inma", "heal", NEEDTARGET, "", 2, SKILL_MAGIC_LIFE, 2, 10)); - addSpell(new TextCommand(2, "fla", "#flar", NOTARGET, + addSpell(new TextCommand(2, "fla", "#flar", "", NOTARGET, "", 1, SKILL_MAGIC_WAR, 0, 10)); - addSpell(new TextCommand(3, "chi", "#chiza", NOTARGET, + addSpell(new TextCommand(3, "chi", "#chiza", "", NOTARGET, "", 1, SKILL_MAGIC_WAR, 0, 9)); - addSpell(new TextCommand(4, "ing", "#ingrav", NOTARGET, + addSpell(new TextCommand(4, "ing", "#ingrav", "", NOTARGET, "", 2, SKILL_MAGIC_WAR, 2, 20)); - addSpell(new TextCommand(5, "fri", "#frillyar", NOTARGET, + addSpell(new TextCommand(5, "fri", "#frillyar", "", NOTARGET, "", 2, SKILL_MAGIC_WAR, 2, 25)); - addSpell(new TextCommand(6, "upm", "#upmarmu", NOTARGET, + addSpell(new TextCommand(6, "upm", "#upmarmu", "", NOTARGET, "", 2, SKILL_MAGIC_WAR, 2, 20)); - addSpell(new TextCommand(7, "ite", "#itenplz", NOTARGET, + addSpell(new TextCommand(7, "ite", "#itenplz", "", NOTARGET, "", 1, SKILL_MAGIC_NATURE, 0, 3)); - addSpell(new TextCommand(8, "bet", "#betsanc", ALLOWTARGET, + addSpell(new TextCommand(8, "bet", "#betsanc", "", ALLOWTARGET, "", 2, SKILL_MAGIC_NATURE, 2, 14)); - addSpell(new TextCommand(9, "abi", "#abizit", NOTARGET, + addSpell(new TextCommand(9, "abi", "#abizit", "", NOTARGET, "", 1, SKILL_MAGIC, 0, 1)); - addSpell(new TextCommand(10, "inw", "#inwilt", NOTARGET, + addSpell(new TextCommand(10, "inw", "#inwilt", "", NOTARGET, "", 2, SKILL_MAGIC, 2, 7)); - addSpell(new TextCommand(11, "hi", "hi", NOTARGET, "")); - addSpell(new TextCommand(12, "hea", "heal", NOTARGET, "")); - addSpell(new TextCommand(13, "@sp", "@spawn maggot 10", NOTARGET, "")); + addSpell(new TextCommand(11, "hi", "hi", "", NOTARGET, "")); + addSpell(new TextCommand(12, "hea", "heal", "", NOTARGET, "")); + addSpell(new TextCommand(13, "@sp", "@spawn maggot 10", "", NOTARGET, "")); for (int f = 12; f < SPELL_SHORTCUT_ITEMS * SPELL_SHORTCUT_TABS; f++) addSpell(new TextCommand(f)); } @@ -269,6 +269,8 @@ void SpellManager::load(bool oldConfig) std::string cmd = cfg->getValue("commandShortcutCmd" + toString(i), ""); + std::string comment = cfg->getValue("commandShortcutComment" + + toString(i), ""); std::string symbol = cfg->getValue("commandShortcutSymbol" + toString(i), ""); std::string icon = cfg->getValue("commandShortcutIcon" @@ -276,13 +278,13 @@ void SpellManager::load(bool oldConfig) if (static_cast<TextCommandType>(commandType) == TEXT_COMMAND_MAGIC) { - addSpell(new TextCommand(i, symbol, cmd, + addSpell(new TextCommand(i, symbol, cmd, comment, static_cast<SpellTarget>(targetType), icon, basicLvl, static_cast<MagicSchool>(school), schoolLvl, mana)); } else { - addSpell(new TextCommand(i, symbol, cmd, + addSpell(new TextCommand(i, symbol, cmd, comment, static_cast<SpellTarget>(targetType), icon)); } } @@ -304,6 +306,15 @@ void SpellManager::save() { serverConfig.deleteKey("commandShortcutCmd" + toString(i)); } + if (spell->getComment() != "") + { + serverConfig.setValue("commandShortcutComment" + toString(i), + spell->getComment()); + } + else + { + serverConfig.deleteKey("commandShortcutComment" + toString(i)); + } if (spell->getSymbol() != "") { serverConfig.setValue("commandShortcutSymbol" + toString(i), diff --git a/src/textcommand.cpp b/src/textcommand.cpp index 1402576d1..30d8c2a4c 100644 --- a/src/textcommand.cpp +++ b/src/textcommand.cpp @@ -31,11 +31,12 @@ #include "debug.h" TextCommand::TextCommand(unsigned int id, std::string symbol, - std::string command, SpellTarget type, - std::string icon, unsigned int basicLvl, - MagicSchool school, unsigned int schoolLvl, - int mana) : + std::string command, std::string comment, + SpellTarget type, std::string icon, + unsigned int basicLvl, MagicSchool school, + unsigned int schoolLvl, int mana) : mCommand(command), + mComment(comment), mSymbol(symbol), mTargetType(type), mIcon(icon), @@ -52,9 +53,10 @@ TextCommand::TextCommand(unsigned int id, std::string symbol, TextCommand::TextCommand(unsigned int id, std::string symbol, - std::string command, SpellTarget type, - std::string icon) : + std::string command, std::string comment, + SpellTarget type, std::string icon) : mCommand(command), + mComment(comment), mSymbol(symbol), mTargetType(type), mIcon(icon), @@ -71,6 +73,7 @@ TextCommand::TextCommand(unsigned int id, std::string symbol, TextCommand::TextCommand(unsigned int id) : mCommand(""), + mComment(""), mSymbol(""), mTargetType(NOTARGET), mIcon(""), diff --git a/src/textcommand.h b/src/textcommand.h index 5ddbe824d..b1af7667d 100644 --- a/src/textcommand.h +++ b/src/textcommand.h @@ -62,18 +62,16 @@ class TextCommand /** * Constructor. */ - TextCommand(unsigned int id, std::string symbol, - std::string command, SpellTarget type, - std::string icon, unsigned int basicLvl, - MagicSchool school = SKILL_MAGIC, + TextCommand(unsigned int id, std::string symbol, std::string command, + std::string comment, SpellTarget type, std::string icon, + unsigned int basicLvl, MagicSchool school = SKILL_MAGIC, unsigned int schoolLvl = 0, int mana = 0); /** * Constructor. */ - TextCommand(unsigned int id, std::string symbol, - std::string command, SpellTarget type, - std::string icon); + TextCommand(unsigned int id, std::string symbol, std::string command, + std::string comment, SpellTarget type, std::string icon); /** * Constructor. @@ -91,6 +89,9 @@ class TextCommand std::string getCommand() const { return mCommand; } + std::string getComment() const + { return mComment; } + std::string getSymbol() const { return mSymbol; } @@ -121,6 +122,9 @@ class TextCommand void setCommand(std::string command) { mCommand = command; } + void setComment(std::string comment) + { mComment = comment; } + void setSymbol(std::string symbol) { mSymbol = symbol; } @@ -159,6 +163,7 @@ class TextCommand protected: std::string mCommand; + std::string mComment; std::string mSymbol; SpellTarget mTargetType; std::string mIcon; diff --git a/src/utils/sha256.cpp b/src/utils/sha256.cpp index 1e7143300..523c021a4 100644 --- a/src/utils/sha256.cpp +++ b/src/utils/sha256.cpp @@ -101,7 +101,7 @@ class SHA256Context #define SHFR(x, n) (x >> n) #define ROTR(x, n) ((x >> n) | (x << ((sizeof(x) << 3) - n))) -#define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n))) +//#define ROTL(x, n) ((x << n) | (x >> ((sizeof(x) << 3) - n))) #define CH(x, y, z) ((x & y) ^ (~x & z)) #define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) |