From 64781090e80fa93a43ce37f0705bbb1cf22ed8bf Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 30 Sep 2013 15:01:42 +0300 Subject: move popups into popups directory. --- src/gui/popups/beingpopup.cpp | 211 +++ src/gui/popups/beingpopup.h | 65 + src/gui/popups/itempopup.cpp | 267 ++++ src/gui/popups/itempopup.h | 76 + src/gui/popups/popupmenu.cpp | 2914 +++++++++++++++++++++++++++++++++++++++ src/gui/popups/popupmenu.h | 241 ++++ src/gui/popups/speechbubble.cpp | 97 ++ src/gui/popups/speechbubble.h | 64 + src/gui/popups/spellpopup.cpp | 116 ++ src/gui/popups/spellpopup.h | 69 + src/gui/popups/statuspopup.cpp | 169 +++ src/gui/popups/statuspopup.h | 69 + src/gui/popups/textpopup.cpp | 105 ++ src/gui/popups/textpopup.h | 79 ++ 14 files changed, 4542 insertions(+) create mode 100644 src/gui/popups/beingpopup.cpp create mode 100644 src/gui/popups/beingpopup.h create mode 100644 src/gui/popups/itempopup.cpp create mode 100644 src/gui/popups/itempopup.h create mode 100644 src/gui/popups/popupmenu.cpp create mode 100644 src/gui/popups/popupmenu.h create mode 100644 src/gui/popups/speechbubble.cpp create mode 100644 src/gui/popups/speechbubble.h create mode 100644 src/gui/popups/spellpopup.cpp create mode 100644 src/gui/popups/spellpopup.h create mode 100644 src/gui/popups/statuspopup.cpp create mode 100644 src/gui/popups/statuspopup.h create mode 100644 src/gui/popups/textpopup.cpp create mode 100644 src/gui/popups/textpopup.h (limited to 'src/gui/popups') diff --git a/src/gui/popups/beingpopup.cpp b/src/gui/popups/beingpopup.cpp new file mode 100644 index 000000000..ae16d8eb2 --- /dev/null +++ b/src/gui/popups/beingpopup.cpp @@ -0,0 +1,211 @@ +/* + * The ManaPlus Client + * Copyright (C) 2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "gui/popups/beingpopup.h" + +#include "being/being.h" +#include "being/playerrelations.h" + +#include "gui/gui.h" +#include "gui/sdlfont.h" + +#include "gui/widgets/label.h" + +#include "utils/gettext.h" +#include "utils/stringutils.h" + +#include + +#include "debug.h" + +BeingPopup::BeingPopup() : + Popup("BeingPopup", "beingpopup.xml"), + mBeingName(new Label(this, "A")), + mBeingParty(new Label(this, "A")), + mBeingGuild(new Label(this, "A")), + mBeingRank(new Label(this, "A")), + mBeingComment(new Label(this, "A")) +{ + // Being Name + mBeingName->setFont(boldFont); + mBeingName->setPosition(0, 0); + + const int fontHeight = mBeingName->getHeight(); + + // Being's party + mBeingParty->setPosition(0, fontHeight); + // Being's party + mBeingGuild->setPosition(0, 2 * fontHeight); + mBeingRank->setPosition(0, 3 * fontHeight); + mBeingComment->setPosition(0, 4 * fontHeight); + + mBeingParty->setForegroundColorAll(getThemeColor(Theme::POPUP), + getThemeColor(Theme::POPUP_OUTLINE)); + mBeingGuild->setForegroundColorAll(getThemeColor(Theme::POPUP), + getThemeColor(Theme::POPUP_OUTLINE)); + mBeingRank->setForegroundColorAll(getThemeColor(Theme::POPUP), + getThemeColor(Theme::POPUP_OUTLINE)); + mBeingComment->setForegroundColorAll(getThemeColor(Theme::POPUP), + getThemeColor(Theme::POPUP_OUTLINE)); + + add(mBeingName); + add(mBeingParty); + add(mBeingGuild); + add(mBeingRank); + add(mBeingComment); +} + +BeingPopup::~BeingPopup() +{ +} + +void BeingPopup::show(const int x, const int y, Being *const b) +{ + if (!b) + { + setVisible(false); + return; + } + + Label *label1 = mBeingParty; + Label *label2 = mBeingGuild; + Label *label3 = mBeingRank; + Label *label4 = mBeingComment; + + b->updateComment(); + + if (b->getType() == Being::NPC && b->getComment().empty()) + { + setVisible(false); + return; + } + + mBeingName->setCaption(b->getName() + b->getGenderSignWithSpace()); + if (gui) + { + if (player_relations.isGoodName(b)) + mBeingName->setFont(boldFont); + else + mBeingName->setFont(gui->getSecureFont()); + } + if (b->isAdvanced()) + { + mBeingName->setForegroundColorAll(getThemeColor( + Theme::PLAYER_ADVANCED), getThemeColor( + Theme::PLAYER_ADVANCED_OUTLINE)); + } + else + { + mBeingName->setForegroundColorAll(getThemeColor(Theme::POPUP), + getThemeColor(Theme::POPUP_OUTLINE)); + } + + mBeingName->adjustSize(); + label1->setCaption(""); + label2->setCaption(""); + label3->setCaption(""); + label4->setCaption(""); + + if (!(b->getPartyName().empty())) + { + // TRANSLATORS: being popup label + label1->setCaption(strprintf(_("Party: %s"), + b->getPartyName().c_str())); + label1->adjustSize(); + } + else + { + label4 = label3; + label3 = label2; + label2 = label1; + label1 = nullptr; + } + + if (!(b->getGuildName().empty())) + { + // TRANSLATORS: being popup label + label2->setCaption(strprintf(_("Guild: %s"), + b->getGuildName().c_str())); + label2->adjustSize(); + } + else + { + label4 = label3; + label3 = label2; + label2 = nullptr; + } + + if (b->getPvpRank() > 0) + { + // TRANSLATORS: being popup label + label3->setCaption(strprintf(_("Pvp rank: %u"), b->getPvpRank())); + label3->adjustSize(); + } + else + { + label4 = label3; + label3 = nullptr; + } + + if (!b->getComment().empty()) + { + // TRANSLATORS: being popup label + label4->setCaption(strprintf(_("Comment: %s"), + b->getComment().c_str())); + label4->adjustSize(); + } + else + { + label4 = nullptr; + } + + int minWidth = mBeingName->getWidth(); + if (label1 && label1->getWidth() > minWidth) + minWidth = label1->getWidth(); + if (label2 && label2->getWidth() > minWidth) + minWidth = label2->getWidth(); + if (label3 && label3->getWidth() > minWidth) + minWidth = label3->getWidth(); + if (label4 && label4->getWidth() > minWidth) + minWidth = label4->getWidth(); + + const int height1 = getFont()->getHeight(); + int height = height1; + if (label1) + height += height1; + if (label2) + height += height1; + if (label3) + height += height1; + if (label4) + height += height1; + + setContentSize(minWidth, height); + position(x, y); + return; +} + +#ifdef USE_PROFILER +void BeingPopup::logic() +{ + logicChildren(); +} +#endif diff --git a/src/gui/popups/beingpopup.h b/src/gui/popups/beingpopup.h new file mode 100644 index 000000000..3ac46d30c --- /dev/null +++ b/src/gui/popups/beingpopup.h @@ -0,0 +1,65 @@ +/* + * The ManaPlus Client + * Copyright (C) 2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GUI_BEINGPOPUP_H +#define GUI_BEINGPOPUP_H + +#include "gui/widgets/popup.h" + +class Being; +class Label; + +/** + * A popup that displays information about a being. + */ +class BeingPopup final : public Popup +{ + public: + /** + * Constructor. Initializes the being popup. + */ + BeingPopup(); + + A_DELETE_COPY(BeingPopup) + + /** + * Destructor. Cleans up the being popup on deletion. + */ + ~BeingPopup(); + + /** + * Sets the info to be displayed given a particular player. + */ + void show(const int x, const int y, Being *const b); + +#ifdef USE_PROFILER + void logic(); +#endif + + private: + Label *mBeingName; + Label *mBeingParty; + Label *mBeingGuild; + Label *mBeingRank; + Label *mBeingComment; +}; + +#endif // GUI_BEINGPOPUP_H diff --git a/src/gui/popups/itempopup.cpp b/src/gui/popups/itempopup.cpp new file mode 100644 index 000000000..63fe3628c --- /dev/null +++ b/src/gui/popups/itempopup.cpp @@ -0,0 +1,267 @@ +/* + * The ManaPlus Client + * Copyright (C) 2008 The Legend of Mazzeroth Development Team + * Copyright (C) 2008-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "gui/popups/itempopup.h" + +#include "client.h" +#include "configuration.h" +#include "item.h" +#include "units.h" + +#include "gui/gui.h" +#include "gui/sdlfont.h" + +#include "gui/widgets/icon.h" +#include "gui/widgets/label.h" +#include "gui/widgets/textbox.h" + +#include "utils/gettext.h" + +#include "resources/image.h" +#include "resources/resourcemanager.h" + +#include + +#include "debug.h" + +ItemPopup::ItemPopup() : + Popup("ItemPopup", "itempopup.xml"), + mItemName(new Label(this)), + mItemDesc(new TextBox(this)), + mItemEffect(new TextBox(this)), + mItemWeight(new TextBox(this)), + mItemType(ITEM_UNUSABLE), + mIcon(new Icon(this, nullptr)), + mLastName(), + mLastColor(1) +{ + // Item Name + mItemName->setFont(boldFont); + mItemName->setPosition(0, 0); + + const int fontHeight = getFont()->getHeight(); + + // Item Description + mItemDesc->setEditable(false); + mItemDesc->setPosition(0, fontHeight); + mItemDesc->setForegroundColorAll(getThemeColor(Theme::POPUP), + getThemeColor(Theme::POPUP_OUTLINE)); + + // Item Effect + mItemEffect->setEditable(false); + mItemEffect->setPosition(0, 2 * fontHeight); + mItemEffect->setForegroundColorAll(getThemeColor(Theme::POPUP), + getThemeColor(Theme::POPUP_OUTLINE)); + + // Item Weight + mItemWeight->setEditable(false); + mItemWeight->setPosition(0, 3 * fontHeight); + mItemWeight->setForegroundColorAll(getThemeColor(Theme::POPUP), + getThemeColor(Theme::POPUP_OUTLINE)); + + add(mItemName); + add(mItemDesc); + add(mItemEffect); + add(mItemWeight); + add(mIcon); + + addMouseListener(this); +} + +ItemPopup::~ItemPopup() +{ + if (mIcon) + { + Image *const image = mIcon->getImage(); + if (image) + image->decRef(); + } +} + +void ItemPopup::setItem(const Item *const item, const bool showImage) +{ + if (!item) + return; + + const ItemInfo &ii = item->getInfo(); + setItem(ii, item->getColor(), showImage, item->getId()); + if (item->getRefine() > 0) + { + mLastName = ii.getName(); + mLastColor = item->getColor(); + if (serverVersion > 0) + { + mItemName->setCaption(strprintf("%s (+%d), %d", ii.getName( + item->getColor()).c_str(), item->getRefine(), ii.getId())); + } + else + { + mItemName->setCaption(strprintf("%s (+%d), %d", + ii.getName().c_str(), item->getRefine(), ii.getId())); + } + mItemName->adjustSize(); + const unsigned minWidth = mItemName->getWidth() + 8; + if (static_cast(getWidth()) < minWidth) + setWidth(minWidth); + } +} + +void ItemPopup::setItem(const ItemInfo &item, const unsigned char color, + const bool showImage, int id) +{ + if (!mIcon || (item.getName() == mLastName && color == mLastColor)) + return; + + if (id == -1) + id = item.getId(); + + int space = 0; + + Image *const oldImage = mIcon->getImage(); + if (oldImage) + oldImage->decRef(); + + if (showImage) + { + ResourceManager *const resman = ResourceManager::getInstance(); + Image *const image = resman->getImage(combineDye2( + paths.getStringValue("itemIcons").append( + item.getDisplay().image), item.getDyeColorsString(color))); + + mIcon->setImage(image); + if (image) + { + mIcon->setPosition(0, 0); + space = mIcon->getWidth(); + } + } + else + { + mIcon->setImage(nullptr); + } + + mItemType = item.getType(); + + mLastName = item.getName(); + mLastColor = color; + + if (serverVersion > 0) + { + mItemName->setCaption(strprintf("%s, %d", + item.getName(color).c_str(), id)); + mItemDesc->setTextWrapped(item.getDescription(color), 196); + } + else + { + mItemName->setCaption(strprintf("%s, %d", + item.getName().c_str(), id)); + mItemDesc->setTextWrapped(item.getDescription(), 196); + } + + mItemName->adjustSize(); + setLabelColor(mItemName, mItemType); + mItemName->setPosition(space, 0); + + mItemEffect->setTextWrapped(item.getEffect(), 196); + // TRANSLATORS: popup label + mItemWeight->setTextWrapped(strprintf(_("Weight: %s"), + Units::formatWeight(item.getWeight()).c_str()), 196); + + int minWidth = mItemName->getWidth() + space; + + if (mItemName->getWidth() + space > minWidth) + minWidth = mItemName->getWidth() + space; + if (mItemDesc->getMinWidth() > minWidth) + minWidth = mItemDesc->getMinWidth(); + if (mItemEffect->getMinWidth() > minWidth) + minWidth = mItemEffect->getMinWidth(); + if (mItemWeight->getMinWidth() > minWidth) + minWidth = mItemWeight->getMinWidth(); + + const int numRowsDesc = mItemDesc->getNumberOfRows(); + const int numRowsEffect = mItemEffect->getNumberOfRows(); + const int numRowsWeight = mItemWeight->getNumberOfRows(); + const int height = getFont()->getHeight(); + + if (item.getEffect().empty()) + { + setContentSize(minWidth, (numRowsDesc + 2 + numRowsWeight) * height); + mItemWeight->setPosition(0, (numRowsDesc + 2) * height); + } + else + { + setContentSize(minWidth, (numRowsDesc + numRowsEffect + 2 + + numRowsWeight) * height); + mItemWeight->setPosition(0, (numRowsDesc + numRowsEffect + 2) + * height); + mItemEffect->setPosition(0, (numRowsDesc + 2) * height); + } + + mItemDesc->setPosition(0, 2 * height); +} + +#define caseSetColor(name1, name2) \ + case name1: \ + { \ + return label->setForegroundColorAll(getThemeColor(name2), \ + getThemeColor(name2##_OUTLINE)); \ + } +void ItemPopup::setLabelColor(Label *label, const ItemType type) const +{ + switch (type) + { + caseSetColor(ITEM_UNUSABLE, Theme::GENERIC) + caseSetColor(ITEM_USABLE, Theme::USABLE) + caseSetColor(ITEM_EQUIPMENT_ONE_HAND_WEAPON, Theme::ONEHAND) + caseSetColor(ITEM_EQUIPMENT_TWO_HANDS_WEAPON, Theme::TWOHAND) + caseSetColor(ITEM_EQUIPMENT_TORSO, Theme::TORSO) + caseSetColor(ITEM_EQUIPMENT_ARMS, Theme::ARMS) + caseSetColor(ITEM_EQUIPMENT_HEAD, Theme::HEAD) + caseSetColor(ITEM_EQUIPMENT_LEGS, Theme::LEGS) + caseSetColor(ITEM_EQUIPMENT_SHIELD, Theme::SHIELD) + caseSetColor(ITEM_EQUIPMENT_RING, Theme::RING) + caseSetColor(ITEM_EQUIPMENT_NECKLACE, Theme::NECKLACE) + caseSetColor(ITEM_EQUIPMENT_FEET, Theme::FEET) + caseSetColor(ITEM_EQUIPMENT_AMMO, Theme::AMMO) + caseSetColor(ITEM_EQUIPMENT_CHARM, Theme::CHARM) + caseSetColor(ITEM_SPRITE_RACE, Theme::UNKNOWN_ITEM) + caseSetColor(ITEM_SPRITE_HAIR, Theme::UNKNOWN_ITEM) + default: + { + return label->setForegroundColorAll(getThemeColor( + Theme::UNKNOWN_ITEM), getThemeColor( + Theme::UNKNOWN_ITEM_OUTLINE)); + } + } +} +#undef caseSetColor + +void ItemPopup::mouseMoved(gcn::MouseEvent &event) +{ + Popup::mouseMoved(event); + + // When the mouse moved on top of the popup, hide it + setVisible(false); + mLastName.clear(); + mLastColor = 1; +} diff --git a/src/gui/popups/itempopup.h b/src/gui/popups/itempopup.h new file mode 100644 index 000000000..d0b313e26 --- /dev/null +++ b/src/gui/popups/itempopup.h @@ -0,0 +1,76 @@ +/* + * The ManaPlus Client + * Copyright (C) 2008 The Legend of Mazzeroth Development Team + * Copyright (C) 2008-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef GUI_ITEMPOPUP_H +#define GUI_ITEMPOPUP_H + +#include "gui/widgets/popup.h" + +#include "resources/iteminfo.h" + +class Icon; +class Label; +class TextBox; + +/** + * A popup that displays information about an item. + */ +class ItemPopup final : public Popup +{ + public: + /** + * Constructor. Initializes the item popup. + */ + ItemPopup(); + + A_DELETE_COPY(ItemPopup) + + /** + * Destructor. Cleans up the item popup on deletion. + */ + ~ItemPopup(); + + /** + * Sets the info to be displayed given a particular item. + */ + void setItem(const ItemInfo &item, const unsigned char color, + const bool showImage = false, int id = -1); + + void setItem(const Item *const item, const bool showImage = false); + + void mouseMoved(gcn::MouseEvent &mouseEvent) override; + + private: + Label *mItemName; + TextBox *mItemDesc; + TextBox *mItemEffect; + TextBox *mItemWeight; + ItemType mItemType; + Icon *mIcon; + std::string mLastName; + unsigned char mLastColor; + + void setLabelColor(Label *label, const ItemType type) const; +}; + +#endif // GUI_ITEMPOPUP_H diff --git a/src/gui/popups/popupmenu.cpp b/src/gui/popups/popupmenu.cpp new file mode 100644 index 000000000..6771e7e3e --- /dev/null +++ b/src/gui/popups/popupmenu.cpp @@ -0,0 +1,2914 @@ +/* + * The ManaPlus Client + * Copyright (C) 2004-2009 The Mana World Development Team + * Copyright (C) 2009-2010 The Mana Developers + * Copyright (C) 2011-2013 The ManaPlus Developers + * + * This file is part of The ManaPlus Client. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "gui/popups/popupmenu.h" + +#include "actorspritemanager.h" +#include "commandhandler.h" +#include "configuration.h" +#include "dropshortcut.h" +#include "game.h" +#include "guild.h" +#include "guildmanager.h" +#include "item.h" +#include "maplayer.h" +#include "party.h" +#include "spellmanager.h" + +#include "being/localplayer.h" +#include "being/playerinfo.h" +#include "being/playerrelations.h" + +#include "input/inputmanager.h" + +#include "gui/windows/chatwindow.h" +#include "gui/windows/equipmentwindow.h" +#include "gui/windows/inventorywindow.h" +#include "gui/windows/itemamountwindow.h" +#include "gui/windows/ministatuswindow.h" +#include "gui/windows/npcdialog.h" +#include "gui/windows/outfitwindow.h" +#include "gui/windows/skilldialog.h" +#include "gui/windows/socialwindow.h" +#include "gui/windows/textcommandeditor.h" +#include "gui/windows/textdialog.h" +#include "gui/windows/tradewindow.h" +#include "gui/windowmenu.h" + +#include "gui/viewport.h" + +#include "gui/widgets/browserbox.h" +#include "gui/widgets/chattab.h" +#include "gui/widgets/progressbar.h" +#include "gui/widgets/scrollarea.h" +#include "gui/widgets/textfield.h" +#include "gui/widgets/whispertab.h" + +#include "net/adminhandler.h" +#include "net/beinghandler.h" +#include "net/buysellhandler.h" +#include "net/guildhandler.h" +#include "net/inventoryhandler.h" +#include "net/net.h" +#include "net/npchandler.h" +#include "net/partyhandler.h" +#include "net/tradehandler.h" + +#include "resources/iteminfo.h" + +#include "utils/copynpaste.h" +#include "utils/gettext.h" +#include "utils/process.h" + +#include + +#include "debug.h" + +extern int serverVersion; + +std::string tradePartnerName; + +PopupMenu::PopupMenu() : + Popup("PopupMenu", "popupmenu.xml"), + mBrowserBox(new BrowserBox(this)), + mScrollArea(nullptr), + mBeingId(0), + mFloorItemId(0), + mItem(nullptr), + mItemId(0), + mItemColor(1), + mMapItem(nullptr), + mTab(nullptr), + mSpell(nullptr), + mWindow(nullptr), + mRenameListener(), + mPlayerListener(), + mDialog(nullptr), + mButton(nullptr), + mNick(), + mTextField(nullptr), + mType(static_cast(Being::UNKNOWN)), + mX(0), + mY(0) +{ + mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND); + mBrowserBox->setOpaque(false); + mBrowserBox->setLinkHandler(this); + mRenameListener.setMapItem(nullptr); + mRenameListener.setDialog(nullptr); + mPlayerListener.setNick(""); + mPlayerListener.setDialog(nullptr); + mPlayerListener.setType(static_cast(Being::UNKNOWN)); + mScrollArea = new ScrollArea(mBrowserBox, false); + mScrollArea->setVerticalScrollPolicy(ScrollArea::SHOW_AUTO); + add(mScrollArea); +} + +void PopupMenu::showPopup(const int x, const int y, const Being *const being) +{ + if (!being || !player_node || !actorSpriteManager) + return; + + mBeingId = being->getId(); + mNick = being->getName(); + mType = static_cast(being->getType()); + mBrowserBox->clearRows(); + mX = x; + mY = y; + + const std::string &name = mNick; + mBrowserBox->addRow(name + being->getGenderSignWithSpace()); + + switch (being->getType()) + { + case ActorSprite::PLAYER: + { + // TRANSLATORS: popup menu item + // TRANSLATORS: trade with player + mBrowserBox->addRow("trade", _("Trade")); + // TRANSLATORS: popup menu item + // TRANSLATORS: trade attack player + mBrowserBox->addRow("attack", _("Attack")); + // TRANSLATORS: popup menu item + // TRANSLATORS: send whisper to player + mBrowserBox->addRow("whisper", _("Whisper")); + addGmCommands(); + mBrowserBox->addRow("##3---"); + + // TRANSLATORS: popup menu item + // TRANSLATORS: heal player + mBrowserBox->addRow("heal", _("Heal")); + mBrowserBox->addRow("##3---"); + + addPlayerRelation(name); + mBrowserBox->addRow("##3---"); + + addFollow(); + addParty(being->getPartyName()); + + const Guild *const guild1 = being->getGuild(); + const Guild *const guild2 = player_node->getGuild(); + if (guild2) + { + if (guild1) + { + if (guild1->getId() == guild2->getId()) + { + mBrowserBox->addRow("guild-kick", + // TRANSLATORS: popup menu item + // TRANSLATORS: kick player from guild + _("Kick from guild")); + if (guild2->getServerGuild()) + { + mBrowserBox->addRow(strprintf( + "@@guild-pos|%s >@@", + // TRANSLATORS: popup menu item + // TRANSLATORS: change player position in guild + _("Change pos in guild"))); + } + } + } + else if (guild2->getMember(mNick)) + { + mBrowserBox->addRow("guild-kick", + // TRANSLATORS: popup menu item + // TRANSLATORS: kick player from guild + _("Kick from guild")); + if (guild2->getServerGuild()) + { + mBrowserBox->addRow(strprintf( + "@@guild-pos|%s >@@", + // TRANSLATORS: popup menu item + // TRANSLATORS: change player position in guild + _("Change pos in guild"))); + } + } + else + { + if (guild2->getServerGuild() + || (guildManager && guildManager->havePower())) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: invite player to guild + mBrowserBox->addRow("guild", _("Invite to guild")); + } + } + } + + // TRANSLATORS: popup menu item + // TRANSLATORS: set player invisible for self by id + mBrowserBox->addRow("nuke", _("Nuke")); + // TRANSLATORS: popup menu item + // TRANSLATORS: move to player location + mBrowserBox->addRow("move", _("Move")); + addPlayerMisc(); + addBuySell(being); + break; + } + + case ActorSprite::NPC: + // NPCs can be talked to (single option, candidate for removal + // unless more options would be added) + // TRANSLATORS: popup menu item + // TRANSLATORS: talk with npc + mBrowserBox->addRow("talk", _("Talk")); + // TRANSLATORS: popup menu item + // TRANSLATORS: buy from npc + mBrowserBox->addRow("buy", _("Buy")); + // TRANSLATORS: popup menu item + // TRANSLATORS: sell to npc + mBrowserBox->addRow("sell", _("Sell")); + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: move to npc location + mBrowserBox->addRow("move", _("Move")); + // TRANSLATORS: popup menu item + // TRANSLATORS: add comment to npc + mBrowserBox->addRow("addcomment", _("Add comment")); + break; + + case ActorSprite::MONSTER: + { + // Monsters can be attacked + // TRANSLATORS: popup menu item + // TRANSLATORS: attack monster + mBrowserBox->addRow("attack", _("Attack")); + + if (config.getBoolValue("enableAttackFilter")) + { + mBrowserBox->addRow("##3---"); + if (actorSpriteManager->isInAttackList(name) + || actorSpriteManager->isInIgnoreAttackList(name) + || actorSpriteManager->isInPriorityAttackList(name)) + { + mBrowserBox->addRow("remove attack", + // TRANSLATORS: remove monster from attack list + // TRANSLATORS: popup menu item + _("Remove from attack list")); + } + else + { + mBrowserBox->addRow("add attack priority", + // TRANSLATORS: popup menu item + // TRANSLATORS: add monster to priotiry attack list + _("Add to priority attack list")); + mBrowserBox->addRow("add attack", + // TRANSLATORS: popup menu item + // TRANSLATORS: add monster to attack list + _("Add to attack list")); + mBrowserBox->addRow("add attack ignore", + // TRANSLATORS: popup menu item + // TRANSLATORS: add monster to ignore list + _("Add to ignore list")); + } + } + break; + } + + case ActorSprite::AVATAR: + case ActorSprite::UNKNOWN: + case ActorSprite::FLOOR_ITEM: + case ActorSprite::PORTAL: + case ActorSprite::PET: + default: + /* Other beings aren't interesting... */ + return; + } + // TRANSLATORS: popup menu item + // TRANSLATORS: add being name to chat + mBrowserBox->addRow("name", _("Add name to chat")); + mBrowserBox->addRow("##3---"); + + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + + showPopup(x, y); +} + +void PopupMenu::showPopup(const int x, const int y, + std::vector &beings) +{ + mX = x; + mY = y; + mBrowserBox->clearRows(); + // TRANSLATORS: popup menu header + mBrowserBox->addRow(_("Players")); + FOR_EACH (std::vector::const_iterator, it, beings) + { + const Being *const being = dynamic_cast(*it); + const ActorSprite *const actor = *it; + if (being && !being->getName().empty()) + { + mBrowserBox->addRow(strprintf("@@player_%u|%s >@@", + static_cast(being->getId()), (being->getName() + + being->getGenderSignWithSpace()).c_str())); + } + else if (actor->getType() == ActorSprite::FLOOR_ITEM) + { + const FloorItem *const floorItem + = static_cast(actor); + mBrowserBox->addRow(strprintf("@@flooritem_%u|%s >@@", + static_cast(actor->getId()), + floorItem->getName().c_str())); + } + } + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + showPopup(x, y); +} + +void PopupMenu::showPlayerPopup(const int x, const int y, + const std::string &nick) +{ + if (nick.empty() || !player_node) + return; + + mNick = nick; + mBeingId = 0; + mType = static_cast(Being::PLAYER); + mX = x; + mY = y; + mBrowserBox->clearRows(); + + const std::string &name = mNick; + + mBrowserBox->addRow(name); + + // TRANSLATORS: popup menu item + // TRANSLATORS: send whisper to player + mBrowserBox->addRow("whisper", _("Whisper")); + addGmCommands(); + mBrowserBox->addRow("##3---"); + + addPlayerRelation(name); + mBrowserBox->addRow("##3---"); + + addFollow(); + // TRANSLATORS: popup menu item + // TRANSLATORS: add comment to player + mBrowserBox->addRow("addcomment", _("Add comment")); + + if (player_node->isInParty()) + { + const Party *const party = player_node->getParty(); + if (party) + { + const PartyMember *const member = party->getMember(mNick); + if (member) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: kick player from party + mBrowserBox->addRow("kick party", _("Kick from party")); + mBrowserBox->addRow("##3---"); + const PartyMember *const o = party->getMember( + player_node->getName()); + if (o && member->getMap() == o->getMap()) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: move to player position + mBrowserBox->addRow("move", _("Move")); + } + } + } + } + + const Guild *const guild2 = player_node->getGuild(); + if (guild2) + { + if (guild2->getMember(mNick)) + { + if (guild2->getServerGuild() || (guildManager + && guildManager->havePower())) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: kick player from guild + mBrowserBox->addRow("guild-kick", _("Kick from guild")); + } + if (guild2->getServerGuild()) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: change player position in guild + mBrowserBox->addRow(strprintf( + "@@guild-pos|%s >@@", _("Change pos in guild"))); + } + } + else + { + if (guild2->getServerGuild() || (guildManager + && guildManager->havePower())) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: invite player to guild + mBrowserBox->addRow("guild", _("Invite to guild")); + } + } + } + + addBuySellDefault(); + // TRANSLATORS: popup menu item + // TRANSLATORS: add player name to chat + mBrowserBox->addRow("name", _("Add name to chat")); + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + + showPopup(x, y); +} + +void PopupMenu::showPopup(const int x, const int y, + const FloorItem *const floorItem) +{ + if (!floorItem) + return; + + mFloorItemId = floorItem->getId(); + mX = x; + mY = y; + mType = static_cast(Being::FLOOR_ITEM); + mBrowserBox->clearRows(); + const std::string name = floorItem->getName(); + mNick = name; + + mBrowserBox->addRow(name); + + if (config.getBoolValue("enablePickupFilter")) + { + if (actorSpriteManager->isInPickupList(name) + || (actorSpriteManager->isInPickupList("") + && !actorSpriteManager->isInIgnorePickupList(name))) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: pickup item from ground + mBrowserBox->addRow("pickup", _("Pick up")); + mBrowserBox->addRow("##3---"); + } + addPickupFilter(name); + } + else + { + // TRANSLATORS: popup menu item + // TRANSLATORS: pickup item from ground + mBrowserBox->addRow("pickup", _("Pick up")); + } + addProtection(); + // TRANSLATORS: popup menu item + // TRANSLATORS: add item name to chat + mBrowserBox->addRow("chat", _("Add to chat")); + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + + showPopup(x, y); +} + +void PopupMenu::showPopup(const int x, const int y, MapItem *const mapItem) +{ + if (!mapItem) + return; + + mMapItem = mapItem; + mX = x; + mY = y; + + mBrowserBox->clearRows(); + + // TRANSLATORS: popup menu header + mBrowserBox->addRow(_("Map Item")); + // TRANSLATORS: popup menu item + // TRANSLATORS: rename map item + mBrowserBox->addRow("rename map", _("Rename")); + // TRANSLATORS: popup menu item + // TRANSLATORS: remove map item + mBrowserBox->addRow("remove map", _("Remove")); + + if (player_node && player_node->isGM()) + { + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: warp to map item + mBrowserBox->addRow("warp map", _("Warp")); + } + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + + showPopup(x, y); +} + +void PopupMenu::showMapPopup(const int x, const int y, + const int x2, const int y2) +{ + mX = x2; + mY = y2; + + mBrowserBox->clearRows(); + + // TRANSLATORS: popup menu header + mBrowserBox->addRow(_("Map Item")); + + if (player_node && player_node->isGM()) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: warp to map item + mBrowserBox->addRow("warp map", _("Warp")); + } + // TRANSLATORS: popup menu item + // TRANSLATORS: move to map item + mBrowserBox->addRow("move", _("Move")); + // TRANSLATORS: popup menu item + // TRANSLATORS: move camera to map item + mBrowserBox->addRow("movecamera", _("Move camera")); + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + + showPopup(x, y); +} + +void PopupMenu::showOutfitsPopup(const int x, const int y) +{ + mX = x; + mY = y; + + mBrowserBox->clearRows(); + + // TRANSLATORS: popup menu header + mBrowserBox->addRow(_("Outfits")); + // TRANSLATORS: popup menu item + // TRANSLATORS: clear selected outfit + mBrowserBox->addRow("clear outfit", _("Clear outfit")); + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + + showPopup(x, y); +} + +void PopupMenu::showSpellPopup(const int x, const int y, + TextCommand *const cmd) +{ + if (!cmd) + return; + + mBrowserBox->clearRows(); + + mSpell = cmd; + mX = x; + mY = y; + + // TRANSLATORS: popup menu header + mBrowserBox->addRow(_("Spells")); + // TRANSLATORS: popup menu item + // TRANSLATORS: edit selected spell + mBrowserBox->addRow("edit spell", _("Edit spell")); + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + + showPopup(x, y); +} + +void PopupMenu::showChatPopup(const int x, const int y, ChatTab *const tab) +{ + if (!tab || !actorSpriteManager || !player_node) + return; + + mTab = tab; + mX = x; + mY = y; + + mBrowserBox->clearRows(); + + if (tab->getType() == static_cast(ChatTab::TAB_WHISPER)) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: close chat tab + mBrowserBox->addRow("chat close", _("Close")); + } + + // TRANSLATORS: popup menu item + // TRANSLATORS: remove all text from chat tab + mBrowserBox->addRow("chat clear", _("Clear")); + mBrowserBox->addRow("##3---"); + + if (tab->getAllowHighlight()) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: disable chat tab highlight + mBrowserBox->addRow("disable highlight", _("Disable highlight")); + } + else + { + // TRANSLATORS: popup menu item + // TRANSLATORS: enable chat tab highlight + mBrowserBox->addRow("enable highlight", _("Enable highlight")); + } + if (tab->getRemoveNames()) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: do not remove player names from chat tab + mBrowserBox->addRow("dont remove name", _("Don't remove name")); + } + else + { + // TRANSLATORS: popup menu item + // TRANSLATORS: remove player names from chat tab + mBrowserBox->addRow("remove name", _("Remove name")); + } + if (tab->getNoAway()) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: enable away messages in chat tab + mBrowserBox->addRow("enable away", _("Enable away")); + } + else + { + // TRANSLATORS: popup menu item + // TRANSLATORS: disable away messages in chat tab + mBrowserBox->addRow("disable away", _("Disable away")); + } + mBrowserBox->addRow("##3---"); + if (tab->getType() == static_cast(ChatTab::TAB_PARTY)) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: enable away messages in chat tab + mBrowserBox->addRow("leave party", _("Leave")); + mBrowserBox->addRow("##3---"); + } + // TRANSLATORS: popup menu item + // TRANSLATORS: copy selected text to clipboard + mBrowserBox->addRow("chat clipboard", _("Copy to clipboard")); + mBrowserBox->addRow("##3---"); + + if (tab->getType() == static_cast(ChatTab::TAB_WHISPER)) + { + const WhisperTab *const wTab = static_cast(tab); + std::string name = wTab->getNick(); + + const Being* const being = actorSpriteManager->findBeingByName( + name, Being::PLAYER); + + if (being) + { + mBeingId = being->getId(); + mNick = being->getName(); + mType = static_cast(being->getType()); + + // TRANSLATORS: popup menu item + // TRANSLATORS: trade with player + mBrowserBox->addRow("trade", _("Trade")); + // TRANSLATORS: popup menu item + // TRANSLATORS: attack player + mBrowserBox->addRow("attack", _("Attack")); + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: heal player + mBrowserBox->addRow("heal", _("Heal")); + mBrowserBox->addRow("##3---"); + addPlayerRelation(name); + mBrowserBox->addRow("##3---"); + addFollow(); + // TRANSLATORS: popup menu item + // TRANSLATORS: move to player position + mBrowserBox->addRow("move", _("Move")); + addPlayerMisc(); + addBuySell(being); + mBrowserBox->addRow("##3---"); + + if (player_node->isInParty()) + { + const Party *const party = player_node->getParty(); + if (party) + { + if (!party->isMember(wTab->getNick())) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: invite player to party + mBrowserBox->addRow("party", _("Invite to party")); + } + else + { + // TRANSLATORS: popup menu item + // TRANSLATORS: kick player from party + mBrowserBox->addRow("kick party", + _("Kick from party")); + } + mBrowserBox->addRow("##3---"); + } + } + const Guild *const guild1 = being->getGuild(); + const Guild *const guild2 = player_node->getGuild(); + if (guild2) + { + if (guild1) + { + if (guild1->getId() == guild2->getId()) + { + if (guild2->getServerGuild() || (guildManager + && guildManager->havePower())) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: kick player from guild + mBrowserBox->addRow(strprintf( + "@@guild-kick|%s@@", _("Kick from guild"))); + } + if (guild2->getServerGuild()) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: change player position in guild + mBrowserBox->addRow(strprintf("@@guild-pos|%s >@@", + _("Change pos in guild"))); + } + } + } + else + { + if (guild2->getServerGuild() || (guildManager + && guildManager->havePower())) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: invite player to guild + mBrowserBox->addRow("guild", _("Invite to guild")); + } + } + } + } + else + { + mNick = name; + mType = static_cast(Being::PLAYER); + addPlayerRelation(name); + mBrowserBox->addRow("##3---"); + addFollow(); + + if (player_node->isInParty()) + { + const Party *const party = player_node->getParty(); + if (party) + { + const PartyMember *const m = party->getMember(mNick); + if (m) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: move to player location + mBrowserBox->addRow("move", _("Move")); + } + } + } + addPlayerMisc(); + addBuySellDefault(); + mBrowserBox->addRow("##3---"); + } + } + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + + showPopup(x, y); +} + +void PopupMenu::showChangePos(const int x, const int y) +{ + mBrowserBox->clearRows(); + // TRANSLATORS: popup menu header + mBrowserBox->addRow(_("Change guild position")); + + if (!player_node) + return; + + mX = x; + mY = y; + const Guild *const guild = player_node->getGuild(); + if (guild) + { + const PositionsMap map = guild->getPositions(); + FOR_EACH (PositionsMap::const_iterator, itr, map) + { + mBrowserBox->addRow(strprintf("@@guild-pos-%u|%s@@", + itr->first, itr->second.c_str())); + } + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + + showPopup(x, y); + } + else + { + mBeingId = 0; + mFloorItemId = 0; + mItem = nullptr; + mMapItem = nullptr; + mNick.clear(); + mType = static_cast(Being::UNKNOWN); + mX = 0; + mY = 0; + setVisible(false); + } +} + +void PopupMenu::handleLink(const std::string &link, + gcn::MouseEvent *event A_UNUSED) +{ + Being *being = nullptr; + if (actorSpriteManager) + being = actorSpriteManager->findBeing(mBeingId); + + // Talk To action + if (link == "talk" && being && being->canTalk()) + { + being->talkTo(); + } + // Trade action + else if (link == "trade" && being && + being->getType() == ActorSprite::PLAYER) + { + Net::getTradeHandler()->request(being); + tradePartnerName = being->getName(); + if (tradeWindow) + tradeWindow->clear(); + } + else if (link == "buy" && being && mBeingId != 0) + { + if (being->getType() == Being::NPC) + Net::getNpcHandler()->buy(mBeingId); + else if (being->getType() == Being::PLAYER) + Net::getBuySellHandler()->requestSellList(being->getName()); + } + else if (link == "buy" && !mNick.empty()) + { + Net::getBuySellHandler()->requestSellList(mNick); + } + else if (link == "sell" && being && mBeingId != 0) + { + if (being->getType() == Being::NPC) + Net::getNpcHandler()->sell(mBeingId); + else if (being->getType() == Being::PLAYER) + Net::getBuySellHandler()->requestBuyList(being->getName()); + } + else if (link == "sell" && !mNick.empty()) + { + Net::getBuySellHandler()->requestBuyList(mNick); + } + else if (link == "attack" && being) + { + if (player_node) + player_node->attack(being, true); + } + else if (link == "heal" && being && being->getType() != Being::MONSTER) + { + if (actorSpriteManager) + actorSpriteManager->heal(being); + } + else if (link == "unignore" && being && + being->getType() == ActorSprite::PLAYER) + { + player_relations.setRelation(being->getName(), + PlayerRelation::NEUTRAL); + } + else if (link == "unignore" && !mNick.empty()) + { + player_relations.setRelation(mNick, PlayerRelation::NEUTRAL); + } + else if (link == "ignore" && being && + being->getType() == ActorSprite::PLAYER) + { + player_relations.setRelation(being->getName(), + PlayerRelation::IGNORED); + } + else if (link == "ignore" && !mNick.empty()) + { + player_relations.setRelation(mNick, PlayerRelation::IGNORED); + } + + else if (link == "blacklist" && being && + being->getType() == ActorSprite::PLAYER) + { + player_relations.setRelation(being->getName(), + PlayerRelation::BLACKLISTED); + } + else if (link == "blacklist" && !mNick.empty()) + { + player_relations.setRelation(mNick, PlayerRelation::BLACKLISTED); + } + else if (link == "enemy" && being && + being->getType() == ActorSprite::PLAYER) + { + player_relations.setRelation(being->getName(), + PlayerRelation::ENEMY2); + } + else if (link == "enemy" && !mNick.empty()) + { + player_relations.setRelation(mNick, PlayerRelation::ENEMY2); + } + else if (link == "erase" && being && + being->getType() == ActorSprite::PLAYER) + { + player_relations.setRelation(being->getName(), PlayerRelation::ERASED); + being->updateName(); + } + else if (link == "erase" && !mNick.empty()) + { + player_relations.setRelation(mNick, PlayerRelation::ERASED); + } + else if (link == "disregard" && being && + being->getType() == ActorSprite::PLAYER) + { + player_relations.setRelation(being->getName(), + PlayerRelation::DISREGARDED); + } + else if (link == "disregard" && !mNick.empty()) + { + player_relations.setRelation(mNick, PlayerRelation::DISREGARDED); + } + else if (link == "friend" && being && + being->getType() == ActorSprite::PLAYER) + { + player_relations.setRelation(being->getName(), PlayerRelation::FRIEND); + } + else if (link == "friend" && !mNick.empty()) + { + player_relations.setRelation(mNick, PlayerRelation::FRIEND); + } + // Guild action + else if (link == "guild" && !mNick.empty()) + { + if (player_node) + { + const Guild *const guild = player_node->getGuild(); + if (guild) + { + if (guild->getServerGuild()) + Net::getGuildHandler()->invite(guild->getId(), mNick); + else if (guildManager) + guildManager->invite(mNick); + } + } + } + else if (link == "nuke" && being) + { + if (actorSpriteManager) + { + actorSpriteManager->addBlock(static_cast( + being->getId())); + actorSpriteManager->destroy(being); + } + } + // Follow Player action + else if (link == "follow" && !mNick.empty()) + { + if (player_node) + player_node->setFollow(mNick); + } + else if (link == "imitation" && !mNick.empty()) + { + if (player_node) + player_node->setImitate(mNick); + } + // Pick Up Floor Item action + else if ((link == "pickup") && mFloorItemId) + { + if (player_node && actorSpriteManager) + { + FloorItem *const item = actorSpriteManager->findItem( + mFloorItemId); + if (item) + player_node->pickUp(item); + } + } + else if (link == "use" && mItemId) + { + if (mItemId < SPELL_MIN_ID) + { + const Inventory *const inv = PlayerInfo::getInventory(); + if (inv) + { + const Item *const item = inv->findItem(mItemId, mItemColor); + if (item) + { + if (item->isEquipment()) + { + if (item->isEquipped()) + Net::getInventoryHandler()->unequipItem(item); + else + Net::getInventoryHandler()->equipItem(item); + } + else + { + if (!PlayerInfo::isItemProtected(item->getId())) + Net::getInventoryHandler()->useItem(item); + } + } + } + } + else if (mItemId < SKILL_MIN_ID && spellManager) + { + spellManager->useItem(mItemId); + } + else if (skillDialog) + { + skillDialog->useItem(mItemId); + } + } + else if (link == "chat") + { + if (chatWindow) + { + if (mItem) + { + if (serverVersion > 0) + { + chatWindow->addItemText(mItem->getInfo().getName( + mItem->getColor())); + } + else + { + chatWindow->addItemText(mItem->getInfo().getName()); + } + } + else if (mFloorItemId && actorSpriteManager) + { + const FloorItem *const item = actorSpriteManager->findItem( + mFloorItemId); + + if (item) + { + if (serverVersion > 0) + { + chatWindow->addItemText(item->getInfo().getName( + item->getColor())); + } + else + { + chatWindow->addItemText(item->getInfo().getName()); + } + } + } + } + } + else if (link == "whisper" && !mNick.empty() && chatWindow) + { + if (chatWindow) + { + if (config.getBoolValue("whispertab")) + { + chatWindow->localChatInput("/q " + mNick); + } + else + { + chatWindow->addInputText(std::string("/w \"").append( + mNick).append("\" ")); + } + } + } + else if (link == "move" && !mNick.empty()) + { + if (player_node) + { + if (being) + { + player_node->navigateTo(being->getTileX(), being->getTileY()); + } + else if (player_node->isInParty()) + { + const Party *const party = player_node->getParty(); + if (party) + { + const PartyMember *const m = party->getMember(mNick); + const PartyMember *const o = party->getMember( + player_node->getName()); + if (m && o && m->getMap() == o->getMap()) + player_node->navigateTo(m->getX(), m->getY()); + } + } + } + } + else if (link == "move" && (mX || mY)) + { + if (player_node) + player_node->navigateTo(mX, mY); + } + else if (link == "movecamera" && (mX || mY)) + { + if (viewport) + viewport->moveCameraToPosition(mX * 32, mY * 32); + } + else if (link == "split" && mItem) + { + ItemAmountWindow::showWindow(ItemAmountWindow::ItemSplit, + inventoryWindow, mItem); + } + else if (link == "drop" && mItem) + { + if (!PlayerInfo::isItemProtected(mItem->getId())) + { + ItemAmountWindow::showWindow(ItemAmountWindow::ItemDrop, + inventoryWindow, mItem); + } + } + else if (link == "drop all" && mItem) + { + if (!PlayerInfo::isItemProtected(mItem->getId())) + Net::getInventoryHandler()->dropItem(mItem, mItem->getQuantity()); + } + else if (link == "store" && mItem) + { + ItemAmountWindow::showWindow(ItemAmountWindow::StoreAdd, + inventoryWindow, mItem); + } + else if (link == "store 10" && mItem) + { + int cnt = 10; + if (cnt > mItem->getQuantity()) + cnt = mItem->getQuantity(); + Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY, + mItem->getInvIndex(), cnt, + Inventory::STORAGE); + } + else if (link == "store half" && mItem) + { + Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY, + mItem->getInvIndex(), mItem->getQuantity() / 2, + Inventory::STORAGE); + } + else if (link == "store all-1" && mItem) + { + Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY, + mItem->getInvIndex(), mItem->getQuantity() - 1, + Inventory::STORAGE); + } + else if (link == "store all" && mItem) + { + Net::getInventoryHandler()->moveItem2(Inventory::INVENTORY, + mItem->getInvIndex(), mItem->getQuantity(), + Inventory::STORAGE); + } + else if (link == "addtrade" && mItem) + { + if (!PlayerInfo::isItemProtected(mItem->getId())) + { + ItemAmountWindow::showWindow(ItemAmountWindow::TradeAdd, + tradeWindow, mItem); + } + } + else if (link == "addtrade 10" && mItem) + { + if (tradeWindow && !PlayerInfo::isItemProtected(mItem->getId())) + { + int cnt = 10; + if (cnt > mItem->getQuantity()) + cnt = mItem->getQuantity(); + tradeWindow->tradeItem(mItem, cnt, true); + } + } + else if (link == "addtrade half" && mItem) + { + if (tradeWindow && !PlayerInfo::isItemProtected(mItem->getId())) + tradeWindow->tradeItem(mItem, mItem->getQuantity() / 2, true); + } + else if (link == "addtrade all-1" && mItem) + { + if (tradeWindow && !PlayerInfo::isItemProtected(mItem->getId())) + tradeWindow->tradeItem(mItem, mItem->getQuantity() - 1, true); + } + else if (link == "addtrade all" && mItem) + { + if (tradeWindow && !PlayerInfo::isItemProtected(mItem->getId())) + tradeWindow->tradeItem(mItem, mItem->getQuantity(), true); + } + else if (link == "retrieve" && mItem) + { + ItemAmountWindow::showWindow(ItemAmountWindow::StoreRemove, + mWindow, mItem); + } + else if (link == "retrieve 10" && mItem) + { + int cnt = 10; + if (cnt > mItem->getQuantity()) + cnt = mItem->getQuantity(); + Net::getInventoryHandler()->moveItem2(Inventory::STORAGE, + mItem->getInvIndex(), cnt, + Inventory::INVENTORY); + } + else if (link == "retrieve half" && mItem) + { + Net::getInventoryHandler()->moveItem2(Inventory::STORAGE, + mItem->getInvIndex(), mItem->getQuantity() / 2, + Inventory::INVENTORY); + } + else if (link == "retrieve all-1" && mItem) + { + Net::getInventoryHandler()->moveItem2(Inventory::STORAGE, + mItem->getInvIndex(), mItem->getQuantity() - 1, + Inventory::INVENTORY); + } + else if (link == "retrieve all" && mItem) + { + Net::getInventoryHandler()->moveItem2(Inventory::STORAGE, + mItem->getInvIndex(), mItem->getQuantity(), + Inventory::INVENTORY); + } + else if (link == "protect item" && mItemId) + { + PlayerInfo::protectItem(mItemId); + } + else if (link == "unprotect item" && mItemId) + { + PlayerInfo::unprotectItem(mItemId); + } + else if (link == "party" && being && + being->getType() == ActorSprite::PLAYER) + { + Net::getPartyHandler()->invite(being); + } + else if (link == "kick party" && being + && being->getType() == Being::PLAYER) + { + Net::getPartyHandler()->kick(being); + } + else if (link == "kick party" && !mNick.empty()) + { + if (player_node && player_node->getParty()) + { + const PartyMember *const member = player_node-> + getParty()->getMember(mNick); + if (member) + Net::getPartyHandler()->kick(mNick); + } + } + else if (link == "name" && !mNick.empty()) + { + const std::string &name = mNick; + if (chatWindow) + chatWindow->addInputText(name); + } + else if (link == "admin-kick" && being && + (being->getType() == ActorSprite::PLAYER || + being->getType() == ActorSprite::MONSTER)) + { + Net::getAdminHandler()->kick(being->getId()); + } + else if (link == "chat close" && mTab) + { + if (commandHandler) + commandHandler->invokeCommand("close", "", mTab); + } + else if (link == "leave party" && mTab) + { + Net::getPartyHandler()->leave(); + } + else if (link == "chat clear" && mTab) + { + if (chatWindow) + chatWindow->clearTab(); + } + else if (link == "warp map" && mMapItem) + { + if (Game::instance()) + { + Net::getAdminHandler()->warp(Game::instance()->getCurrentMapName(), + mMapItem->getX(), mMapItem->getY()); + } + } + else if (link == "warp map" && (mX || mY)) + { + if (Game::instance()) + { + Net::getAdminHandler()->warp(Game::instance()->getCurrentMapName(), + mX, mY); + } + } + else if (link == "remove map" && mMapItem) + { + if (viewport) + { + const Map *const map = viewport->getMap(); + if (map) + { + SpecialLayer *const specialLayer = map->getSpecialLayer(); + if (specialLayer) + { + const bool isHome = (mMapItem->getType() + == static_cast(MapItem::HOME)); + const int x = static_cast(mMapItem->getX()); + const int y = static_cast(mMapItem->getY()); + specialLayer->setTile(x, y, + static_cast(MapItem::EMPTY)); + if (socialWindow) + socialWindow->removePortal(x, y); + if (isHome && player_node) + { + player_node->removeHome(); + player_node->saveHomes(); + } + } + } + } + } + else if (link == "rename map" && mMapItem) + { + mRenameListener.setMapItem(mMapItem); + // TRANSLATORS: number of chars in string should be near original + mDialog = new TextDialog(_("Rename map sign "), + // TRANSLATORS: number of chars in string should be near original + _("Name: ")); + mRenameListener.setDialog(mDialog); + mDialog->setText(mMapItem->getComment()); + mDialog->setActionEventId("ok"); + mDialog->addActionListener(&mRenameListener); + } + else if (link == "clear drops") + { + if (dropShortcut) + dropShortcut->clear(); + } + else if (link == "edit spell" && mSpell) + { + new TextCommandEditor(mSpell); + } + else if (link == "undress" && being) + { + Net::getBeingHandler()->undress(being); + } + else if (link == "addcomment" && !mNick.empty()) + { + // TRANSLATORS: number of chars in string should be near original + TextDialog *const dialog = new TextDialog( + _("Player comment "), + // TRANSLATORS: number of chars in string should be near original + _("Comment: ")); + mPlayerListener.setDialog(dialog); + mPlayerListener.setNick(mNick); + mPlayerListener.setType(mType); + + if (being) + { + being->updateComment(); + dialog->setText(being->getComment()); + } + else + { + dialog->setText(Being::loadComment(mNick, mType)); + } + dialog->setActionEventId("ok"); + dialog->addActionListener(&mPlayerListener); + } + else if (link == "guild-kick" && !mNick.empty()) + { + if (player_node) + { + const Guild *const guild = player_node->getGuild(); + if (guild) + { + if (guild->getServerGuild()) + Net::getGuildHandler()->kick(guild->getMember(mNick), ""); + else if (guildManager) + guildManager->kick(mNick); + } + } + } + else if (link == "enable highlight" && mTab) + { + if (commandHandler) + commandHandler->invokeCommand(COMMAND_ENABLEHIGHLIGHT, mTab); + } + else if (link == "disable highlight" && mTab) + { + if (commandHandler) + commandHandler->invokeCommand(COMMAND_DISABLEHIGHLIGHT, mTab); + } + else if (link == "dont remove name" && mTab) + { + if (commandHandler) + commandHandler->invokeCommand(COMMAND_DONTREMOVENAME, mTab); + } + else if (link == "remove name" && mTab) + { + if (commandHandler) + commandHandler->invokeCommand(COMMAND_REMOVENAME, mTab); + } + else if (link == "disable away" && mTab) + { + if (commandHandler) + commandHandler->invokeCommand(COMMAND_DISABLEAWAY, mTab); + } + else if (link == "enable away" && mTab) + { + if (commandHandler) + commandHandler->invokeCommand(COMMAND_ENABLEAWAY, mTab); + } + else if (link == "chat clipboard" && mTab) + { + if (chatWindow) + chatWindow->copyToClipboard(mX, mY); + } + else if (link == "npc clipboard" && mBeingId) + { + NpcDialog::copyToClipboard(mBeingId, mX, mY); + } + else if (link == "remove attack" && being) + { + if (actorSpriteManager && being->getType() == Being::MONSTER) + { + actorSpriteManager->removeAttackMob(being->getName()); + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + else if (link == "add attack" && being) + { + if (actorSpriteManager && being->getType() == Being::MONSTER) + { + actorSpriteManager->addAttackMob(being->getName()); + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + else if (link == "add attack priority" && being) + { + if (actorSpriteManager && being->getType() == Being::MONSTER) + { + actorSpriteManager->addPriorityAttackMob(being->getName()); + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + else if (link == "add attack ignore" && being) + { + if (actorSpriteManager && being->getType() == Being::MONSTER) + { + actorSpriteManager->addIgnoreAttackMob(being->getName()); + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + else if (link == "remove pickup" && !mNick.empty()) + { + if (actorSpriteManager) + { + actorSpriteManager->removePickupItem(mNick); + if (socialWindow) + socialWindow->updatePickupFilter(); + } + } + else if (link == "add pickup" && !mNick.empty()) + { + if (actorSpriteManager) + { + actorSpriteManager->addPickupItem(mNick); + if (socialWindow) + socialWindow->updatePickupFilter(); + } + } + else if (link == "add pickup ignore" && !mNick.empty()) + { + if (actorSpriteManager) + { + actorSpriteManager->addIgnorePickupItem(mNick); + if (socialWindow) + socialWindow->updatePickupFilter(); + } + } + else if (link == "attack moveup") + { + if (actorSpriteManager) + { + const int idx = actorSpriteManager->getAttackMobIndex(mNick); + if (idx > 0) + { + std::list mobs + = actorSpriteManager->getAttackMobs(); + std::list::iterator it = mobs.begin(); + std::list::iterator it2 = mobs.begin(); + while (it != mobs.end()) + { + if (*it == mNick) + { + -- it2; + mobs.splice(it2, mobs, it); + actorSpriteManager->setAttackMobs(mobs); + actorSpriteManager->rebuildAttackMobs(); + break; + } + ++ it; + ++ it2; + } + + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + } + else if (link == "priority moveup") + { + if (actorSpriteManager) + { + const int idx = actorSpriteManager-> + getPriorityAttackMobIndex(mNick); + if (idx > 0) + { + std::list mobs + = actorSpriteManager->getPriorityAttackMobs(); + std::list::iterator it = mobs.begin(); + std::list::iterator it2 = mobs.begin(); + while (it != mobs.end()) + { + if (*it == mNick) + { + -- it2; + mobs.splice(it2, mobs, it); + actorSpriteManager->setPriorityAttackMobs(mobs); + actorSpriteManager->rebuildPriorityAttackMobs(); + break; + } + ++ it; + ++ it2; + } + + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + } + else if (link == "attack movedown") + { + if (actorSpriteManager) + { + const int idx = actorSpriteManager->getAttackMobIndex(mNick); + const int size = actorSpriteManager->getAttackMobsSize(); + if (idx + 1 < size) + { + std::list mobs + = actorSpriteManager->getAttackMobs(); + std::list::iterator it = mobs.begin(); + std::list::iterator it2 = mobs.begin(); + while (it != mobs.end()) + { + if (*it == mNick) + { + ++ it2; + if (it2 == mobs.end()) + break; + + mobs.splice(it, mobs, it2); + actorSpriteManager->setAttackMobs(mobs); + actorSpriteManager->rebuildAttackMobs(); + break; + } + ++ it; + ++ it2; + } + + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + } + else if (link == "priority movedown") + { + if (player_node) + { + const int idx = actorSpriteManager + ->getPriorityAttackMobIndex(mNick); + const int size = actorSpriteManager->getPriorityAttackMobsSize(); + if (idx + 1 < size) + { + std::list mobs + = actorSpriteManager->getPriorityAttackMobs(); + std::list::iterator it = mobs.begin(); + std::list::iterator it2 = mobs.begin(); + while (it != mobs.end()) + { + if (*it == mNick) + { + ++ it2; + if (it2 == mobs.end()) + break; + + mobs.splice(it, mobs, it2); + actorSpriteManager->setPriorityAttackMobs(mobs); + actorSpriteManager->rebuildPriorityAttackMobs(); + break; + } + ++ it; + ++ it2; + } + + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + } + else if (link == "attack remove") + { + if (actorSpriteManager) + { + if (mNick.empty()) + { + if (actorSpriteManager->isInAttackList(mNick)) + { + actorSpriteManager->removeAttackMob(mNick); + actorSpriteManager->addIgnoreAttackMob(mNick); + } + else + { + actorSpriteManager->removeAttackMob(mNick); + actorSpriteManager->addAttackMob(mNick); + } + } + else + { + actorSpriteManager->removeAttackMob(mNick); + } + if (socialWindow) + socialWindow->updateAttackFilter(); + } + } + else if (link == "pickup remove") + { + if (actorSpriteManager) + { + if (mNick.empty()) + { + if (actorSpriteManager->isInPickupList(mNick)) + { + actorSpriteManager->removePickupItem(mNick); + actorSpriteManager->addIgnorePickupItem(mNick); + } + else + { + actorSpriteManager->removePickupItem(mNick); + actorSpriteManager->addPickupItem(mNick); + } + } + else + { + actorSpriteManager->removePickupItem(mNick); + } + if (socialWindow) + socialWindow->updatePickupFilter(); + } + } + else if (link == "reset yellow") + { + if (player_node) + player_node->resetYellowBar(); + } + else if (link == "bar to chat" && !mNick.empty()) + { + if (chatWindow) + chatWindow->addInputText(mNick); + } + else if (link == "items" && being) + { + if (being == player_node) + { + if (equipmentWindow && !equipmentWindow->isWindowVisible()) + equipmentWindow->setVisible(true); + } + else + { + if (beingEquipmentWindow) + { + beingEquipmentWindow->setBeing(being); + beingEquipmentWindow->setVisible(true); + } + } + } + else if (link == "undress item" && being && mItemId) + { + being->undressItemById(mItemId); + } + else if (link == "guild-pos" && !mNick.empty()) + { + showChangePos(getX(), getY()); + return; + } + else if (link == "clear outfit") + { + if (outfitWindow) + outfitWindow->clearCurrentOutfit(); + } + else if (link == "clipboard copy") + { + if (mTextField) + mTextField->handleCopy(); + } + else if (link == "clipboard paste") + { + if (mTextField) + mTextField->handlePaste(); + } + else if (link == "open link" && !mNick.empty()) + { + openBrowser(mNick); + } + else if (link == "clipboard link" && !mNick.empty()) + { + sendBuffer(mNick); + } + else if (link == "goto" && !mNick.empty()) + { + Net::getAdminHandler()->gotoName(mNick); + } + else if (link == "recall" && !mNick.empty()) + { + Net::getAdminHandler()->recallName(mNick); + } + else if (link == "revive" && !mNick.empty()) + { + Net::getAdminHandler()->reviveName(mNick); + } + else if (link == "ipcheck" && !mNick.empty()) + { + Net::getAdminHandler()->ipcheckName(mNick); + } + else if (link == "gm" && !mNick.empty()) + { + showGMPopup(); + return; + } + else if (!link.compare(0, 10, "guild-pos-")) + { + if (player_node) + { + const int num = atoi(link.substr(10).c_str()); + const Guild *const guild = player_node->getGuild(); + if (guild) + { + Net::getGuildHandler()->changeMemberPostion( + guild->getMember(mNick), num); + } + } + } + else if (!link.compare(0, 7, "player_")) + { + if (actorSpriteManager) + { + mBeingId = atoi(link.substr(7).c_str()); + being = actorSpriteManager->findBeing(mBeingId); + if (being) + { + showPopup(getX(), getY(), being); + return; + } + } + } + else if (!link.compare(0, 10, "flooritem_")) + { + if (actorSpriteManager) + { + const int id = atoi(link.substr(10).c_str()); + if (id) + { + const FloorItem *const item = actorSpriteManager->findItem(id); + if (item) + { + mFloorItemId = item->getId(); + showPopup(getX(), getY(), item); + return; + } + } + } + } + else if (!link.compare(0, 12, "hide button_")) + { + if (windowMenu) + windowMenu->showButton(link.substr(12), false); + } + else if (!link.compare(0, 12, "show button_")) + { + if (windowMenu) + windowMenu->showButton(link.substr(12), true); + } + else if (!link.compare(0, 9, "hide bar_")) + { + if (miniStatusWindow) + miniStatusWindow->showBar(link.substr(9), false); + } + else if (!link.compare(0, 9, "show bar_")) + { + if (miniStatusWindow) + miniStatusWindow->showBar(link.substr(9), true); + } + else if (!link.compare(0, 12, "show window_")) + { + const int id = atoi(link.substr(12).c_str()); + if (id >= 0) + inputManager.executeAction(id); + } + // Unknown actions + else if (link != "cancel") + { + logger->log("PopupMenu: Warning, unknown action '%s'", link.c_str()); + } + + setVisible(false); + + mBeingId = 0; + mFloorItemId = 0; + mItem = nullptr; + mItemId = 0; + mItemColor = 1; + mMapItem = nullptr; + mTab = nullptr; + mSpell = nullptr; + mWindow = nullptr; + mDialog = nullptr; + mButton = nullptr; + mNick.clear(); + mTextField = nullptr; + mType = static_cast(Being::UNKNOWN); + mX = 0; + mY = 0; +} + +void PopupMenu::showPopup(Window *const parent, const int x, const int y, + Item *const item, const bool isInventory) +{ + if (!item) + return; + + mItem = item; + mItemId = item->getId(); + mItemColor = item->getColor(); + mWindow = parent; + mX = x; + mY = y; + mNick.clear(); + mBrowserBox->clearRows(); + + const int cnt = item->getQuantity(); + const bool isProtected = PlayerInfo::isItemProtected(mItemId); + + if (isInventory) + { + if (tradeWindow && tradeWindow->isWindowVisible() && !isProtected) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: add item to trade + mBrowserBox->addRow("addtrade", _("Add to trade")); + if (cnt > 1) + { + if (cnt > 10) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: add 10 item amount to trade + mBrowserBox->addRow("addtrade 10", _("Add to trade 10")); + } + // TRANSLATORS: popup menu item + // TRANSLATORS: add half item amount to trade + mBrowserBox->addRow("addtrade half", _("Add to trade half")); + // TRANSLATORS: popup menu item + // TRANSLATORS: add all amount except one item to trade + mBrowserBox->addRow("addtrade all-1", _("Add to trade all-1")); + // TRANSLATORS: popup menu item + // TRANSLATORS: add all amount item to trade + mBrowserBox->addRow("addtrade all", _("Add to trade all")); + } + mBrowserBox->addRow("##3---"); + } + if (InventoryWindow::isStorageActive()) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: add item to storage + mBrowserBox->addRow("store", _("Store")); + if (cnt > 1) + { + if (cnt > 10) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: add 10 item amount to storage + mBrowserBox->addRow("store 10", _("Store 10")); + } + // TRANSLATORS: popup menu item + // TRANSLATORS: add half item amount to storage + mBrowserBox->addRow("store half", _("Store half")); + // TRANSLATORS: popup menu item + // TRANSLATORS: add all except one item amount to storage + mBrowserBox->addRow("store all-1", _("Store all-1")); + // TRANSLATORS: popup menu item + // TRANSLATORS: add all item amount to storage + mBrowserBox->addRow("store all", _("Store all")); + } + mBrowserBox->addRow("##3---"); + } + + addUseDrop(item, isProtected); + } + // Assume in storage for now + else + { + // TRANSLATORS: popup menu item + // TRANSLATORS: get item from storage + mBrowserBox->addRow("retrieve", _("Retrieve")); + if (cnt > 1) + { + if (cnt > 10) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: get 10 item amount from storage + mBrowserBox->addRow("retrieve 10", _("Retrieve 10")); + } + // TRANSLATORS: popup menu item + // TRANSLATORS: get half item amount from storage + mBrowserBox->addRow("retrieve half", _("Retrieve half")); + // TRANSLATORS: popup menu item + // TRANSLATORS: get all except one item amount from storage + mBrowserBox->addRow("retrieve all-1", _("Retrieve all-1")); + // TRANSLATORS: popup menu item + // TRANSLATORS: get all item amount from storage + mBrowserBox->addRow("retrieve all", _("Retrieve all")); + } + } + addProtection(); + if (config.getBoolValue("enablePickupFilter")) + { + mNick = item->getName(); + mBrowserBox->addRow("##3---"); + addPickupFilter(mNick); + } + // TRANSLATORS: popup menu item + // TRANSLATORS: add item name to chat + mBrowserBox->addRow("chat", _("Add to chat")); + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + + showPopup(x, y); +} + +void PopupMenu::showItemPopup(const int x, const int y, const int itemId, + const unsigned char color) +{ + const Inventory *const inv = PlayerInfo::getInventory(); + if (!inv) + return; + + Item *const item = inv->findItem(itemId, color); + if (item) + { + showItemPopup(x, y, item); + } + else + { + mItem = nullptr; + mItemId = itemId; + mItemColor = color; + mX = x; + mY = y; + mBrowserBox->clearRows(); + + if (!PlayerInfo::isItemProtected(mItemId)) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: use item + mBrowserBox->addRow("use", _("Use")); + } + addProtection(); + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + + showPopup(x, y); + } +} + +void PopupMenu::showItemPopup(const int x, const int y, Item *const item) +{ + mItem = item; + mX = x; + mY = y; + if (item) + { + mItemId = item->getId(); + mItemColor = item->getColor(); + } + else + { + mItemId = 0; + mItemColor = 1; + } + mNick.clear(); + mBrowserBox->clearRows(); + + if (item) + { + const bool isProtected = PlayerInfo::isItemProtected(mItemId); + addUseDrop(item, isProtected); + if (InventoryWindow::isStorageActive()) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: add item to storage + mBrowserBox->addRow("store", _("Store")); + } + // TRANSLATORS: popup menu item + // TRANSLATORS: add item name to chat + mBrowserBox->addRow("chat", _("Add to chat")); + + if (config.getBoolValue("enablePickupFilter")) + { + mNick = item->getName(); + + mBrowserBox->addRow("##3---"); + addPickupFilter(mNick); + } + } + addProtection(); + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + + showPopup(x, y); +} + +void PopupMenu::showDropPopup(const int x, const int y, Item *const item) +{ + mItem = item; + mX = x; + mY = y; + mNick.clear(); + mBrowserBox->clearRows(); + + if (item) + { + mItemId = item->getId(); + mItemColor = item->getColor(); + const bool isProtected = PlayerInfo::isItemProtected(mItemId); + addUseDrop(item, isProtected); + if (InventoryWindow::isStorageActive()) + { + // TRANSLATORS: popup menu item + // TRANSLATORS: add item to storage + mBrowserBox->addRow("store", _("Store")); + } + addProtection(); + // TRANSLATORS: popup menu item + // TRANSLATORS: add item name to chat + mBrowserBox->addRow("chat", _("Add to chat")); + if (config.getBoolValue("enablePickupFilter")) + { + mNick = item->getName(); + mBrowserBox->addRow("##3---"); + addPickupFilter(mNick); + } + } + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + mBrowserBox->addRow("clear drops", _("Clear drop window")); + mBrowserBox->addRow("##3---"); + // TRANSLATORS: popup menu item + // TRANSLATORS: close menu + mBrowserBox->addRow("cancel", _("Cancel")); + + showPopup(x, y); +} + +void PopupMenu::showPopup(const int x, const int y, Button *const button) +{ + if (!button || !windowMenu) + return; + + mButton = button; + mX = x; + mY = y; + + mBrowserBox->clearRows(); + std::vector