summaryrefslogtreecommitdiff
path: root/src/gui/popupmenu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/popupmenu.cpp')
-rw-r--r--src/gui/popupmenu.cpp1286
1 files changed, 1286 insertions, 0 deletions
diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp
new file mode 100644
index 000000000..662b184b9
--- /dev/null
+++ b/src/gui/popupmenu.cpp
@@ -0,0 +1,1286 @@
+/*
+ * The Mana Client
+ * Copyright (C) 2004-2009 The Mana World Development Team
+ * Copyright (C) 2009-2010 The Mana Developers
+ *
+ * This file is part of The Mana 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "gui/popupmenu.h"
+
+#include "actorspritemanager.h"
+#include "being.h"
+#include "dropshortcut.h"
+#include "guild.h"
+#include "flooritem.h"
+#include "graphics.h"
+#include "item.h"
+#include "itemshortcut.h"
+#include "localplayer.h"
+#include "log.h"
+#include "map.h"
+#include "party.h"
+#include "playerinfo.h"
+#include "playerrelations.h"
+#include "spellmanager.h"
+
+#include "gui/buy.h"
+#include "gui/chat.h"
+#include "gui/inventorywindow.h"
+#include "gui/itemamount.h"
+#include "gui/outfitwindow.h"
+#include "gui/sell.h"
+#include "gui/socialwindow.h"
+#include "gui/textcommandeditor.h"
+#include "gui/textdialog.h"
+#include "gui/trade.h"
+#include "gui/viewport.h"
+
+#include "gui/widgets/browserbox.h"
+#include "gui/widgets/button.h"
+#include "gui/widgets/chattab.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 "gui/shortcutwindow.h"
+#include "net/tradehandler.h"
+
+#include "resources/itemdb.h"
+#include "resources/iteminfo.h"
+
+#include "utils/gettext.h"
+#include "utils/stringutils.h"
+
+#include <cassert>
+
+std::string tradePartnerName("");
+
+PopupMenu::PopupMenu():
+ Popup("PopupMenu"),
+ mBeingId(0),
+ mFloorItem(0),
+ mItem(0),
+ mItemId(0),
+ mMapItem(0),
+ mTab(0),
+ mSpell(0),
+ mDialog(0),
+ mNick("")
+{
+ mBrowserBox = new BrowserBox;
+ mBrowserBox->setPosition(4, 4);
+ mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND);
+ mBrowserBox->setOpaque(false);
+ mBrowserBox->setLinkHandler(this);
+ add(mBrowserBox);
+}
+
+void PopupMenu::showPopup(int x, int y, Being *being)
+{
+ if (!being || !player_node)
+ return;
+
+ mBeingId = being->getId();
+ mNick = being->getName();
+ mBrowserBox->clearRows();
+
+ const std::string &name = mNick;
+
+ mBrowserBox->addRow(name);
+
+ switch (being->getType())
+ {
+ case ActorSprite::PLAYER:
+ {
+ // Players can be traded with.
+ mBrowserBox->addRow(_("@@trade|Trade@@"));
+ // TRANSLATORS: Attacking a player.
+ mBrowserBox->addRow(_("@@attack|Attack@@"));
+ // TRANSLATORS: Whispering a player.
+ mBrowserBox->addRow(_("@@whisper|Whisper@@"));
+
+ mBrowserBox->addRow("##3---");
+
+ mBrowserBox->addRow(_("@@heal|Heal@@"));
+ mBrowserBox->addRow("##3---");
+
+ switch (player_relations.getRelation(name))
+ {
+ case PlayerRelation::NEUTRAL:
+ mBrowserBox->addRow(_("@@friend|Befriend@@"));
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::FRIEND:
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::DISREGARDED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@ignore|Completely ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::IGNORED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::ERASED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Completely ignore@@"));
+ break;
+
+ default:
+ break;
+ }
+
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@follow|Follow@@"));
+ mBrowserBox->addRow(_("@@imitation|Imitation@@"));
+
+ if (player_node->isInParty())
+ {
+ if (player_node->getParty())
+ {
+ if (player_node->getParty()->getName()
+ != being->getPartyName())
+ {
+ mBrowserBox->addRow(
+ _("@@party|Invite to party@@"));
+ }
+ else
+ {
+ mBrowserBox->addRow(
+ _("@@kick party|Kick from party@@"));
+ }
+ mBrowserBox->addRow("##3---");
+ }
+ }
+
+ Guild *guild1 = being->getGuild();
+ Guild *guild2 = player_node->getGuild();
+ if (guild2)
+ {
+ if (guild1)
+ {
+ if (guild1->getId() == guild2->getId())
+ {
+ mBrowserBox->addRow(
+ _("@@guild-kick|Kick from guild@@"));
+ mBrowserBox->addRow(
+ _("@@guild-pos|Change pos in guild >@@"));
+ }
+ }
+ else
+ {
+ mBrowserBox->addRow(_("@@guild|Invite to guild@@"));
+ }
+ }
+
+ if (player_node->isGM())
+ {
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@admin-kick|Kick player@@"));
+ }
+ mBrowserBox->addRow(_("@@nuke|Nuke@@"));
+ mBrowserBox->addRow(_("@@move|Move@@"));
+ mBrowserBox->addRow(_("@@undress|Undress@@"));
+
+ if (player_relations.getDefault() & PlayerRelation::TRADE)
+ {
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@buy|Buy@@"));
+ mBrowserBox->addRow(_("@@sell|Sell@@"));
+ }
+ }
+ break;
+
+ case ActorSprite::NPC:
+ // NPCs can be talked to (single option, candidate for removal
+ // unless more options would be added)
+ mBrowserBox->addRow(_("@@talk|Talk@@"));
+
+ mBrowserBox->addRow(_("@@buy|Buy@@"));
+ mBrowserBox->addRow(_("@@sell|Sell@@"));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@move|Move@@"));
+ break;
+
+ case ActorSprite::MONSTER:
+ {
+ // Monsters can be attacked
+ mBrowserBox->addRow(_("@@attack|Attack@@"));
+
+ if (player_node->isGM())
+ mBrowserBox->addRow(_("@@admin-kick|Kick@@"));
+ }
+ break;
+
+ default:
+ /* Other beings aren't interesting... */
+ return;
+ }
+ mBrowserBox->addRow(_("@@name|Add name to chat@@"));
+
+ //mBrowserBox->addRow(strprintf("@@look|%s@@", _("Look To")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showPopup(int x, int y, std::list<Being*> &beings)
+{
+ mBrowserBox->clearRows();
+ mBrowserBox->addRow("Players");
+ std::list<Being*>::iterator it, it_end;
+ for (it = beings.begin(), it_end = beings.end(); it != it_end; it++)
+ {
+ Being *being = *it;
+ if (!being->getName().empty())
+ {
+ mBrowserBox->addRow(strprintf(_("@@player_%u|%s >@@"),
+ being->getId(), being->getName().c_str()));
+ }
+ }
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+ showPopup(x, y);
+}
+
+void PopupMenu::showPlayerPopup(int x, int y, std::string nick)
+{
+ if (nick.empty() || !player_node)
+ return;
+
+ mNick = nick;
+ mBeingId = 0;
+ mBrowserBox->clearRows();
+
+ const std::string &name = mNick;
+
+ mBrowserBox->addRow(name);
+
+ mBrowserBox->addRow(_("@@whisper|Whisper@@"));
+ mBrowserBox->addRow("##3---");
+
+ switch (player_relations.getRelation(name))
+ {
+ case PlayerRelation::NEUTRAL:
+ mBrowserBox->addRow(_("@@friend|Befriend@@"));
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::FRIEND:
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::DISREGARDED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@ignore|Completely ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::IGNORED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::ERASED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Completely ignore@@"));
+ break;
+
+ default:
+ break;
+ }
+
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@follow|Follow@@"));
+ mBrowserBox->addRow(_("@@imitation|Imitation@@"));
+
+ Guild *guild2 = player_node->getGuild();
+ if (guild2)
+ {
+ if (guild2->getMember(mNick))
+ {
+ mBrowserBox->addRow(_("@@guild-kick|Kick from guild@@"));
+ mBrowserBox->addRow(_("@@guild-pos|Change pos in guild >@@"));
+ }
+ else
+ {
+ mBrowserBox->addRow(_("@@guild|Invite to guild@@"));
+ }
+ }
+
+ mBrowserBox->addRow("##3---");
+ if (player_relations.getDefault() & PlayerRelation::TRADE)
+ {
+ mBrowserBox->addRow(_("@@buy|Buy@@"));
+ mBrowserBox->addRow(_("@@sell|Sell@@"));
+ }
+
+ mBrowserBox->addRow(_("@@name|Add name to chat@@"));
+
+ //mBrowserBox->addRow(strprintf("@@look|%s@@", _("Look To")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+
+ showPopup(x, y);
+
+}
+
+void PopupMenu::showPopup(int x, int y, FloorItem *floorItem)
+{
+ if (!floorItem)
+ return;
+
+ mFloorItem = floorItem;
+ ItemInfo info = floorItem->getInfo();
+ mBrowserBox->clearRows();
+
+ // Floor item can be picked up (single option, candidate for removal)
+ std::string name = info.getName();
+ mBrowserBox->addRow(name);
+ mBrowserBox->addRow(_("@@pickup|Pick up@@"));
+ mBrowserBox->addRow(_("@@chat|Add to chat@@"));
+
+ //mBrowserBox->addRow(strprintf("@@look|%s@@", _("Look To")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showPopup(int x, int y, MapItem *mapItem)
+{
+ if (!mapItem)
+ return;
+
+ mMapItem = mapItem;
+
+ mBrowserBox->clearRows();
+
+ mBrowserBox->addRow(_("Map Item"));
+ mBrowserBox->addRow(_("@@rename map|Rename@@"));
+ mBrowserBox->addRow(_("@@remove map|Remove@@"));
+
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showOutfitsPopup(int x, int y)
+{
+ mBrowserBox->clearRows();
+
+ mBrowserBox->addRow(_("Outfits"));
+ mBrowserBox->addRow(_("@@load old outfits|Load old outfits@@"));
+
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showSpellPopup(int x, int y, TextCommand *cmd)
+{
+ if (!cmd)
+ return;
+
+ mBrowserBox->clearRows();
+
+ mSpell = cmd;
+ mBrowserBox->addRow(_("Spells"));
+ mBrowserBox->addRow(_("@@load old spells|Load old spells@@"));
+ mBrowserBox->addRow(_("@@edit spell|Edit spell@@"));
+
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@cancel|Cancel@@"));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showChatPopup(int x, int y, ChatTab *tab)
+{
+ if (!tab || !actorSpriteManager || !player_node)
+ return;
+
+ mTab = tab;
+
+ mBrowserBox->clearRows();
+
+ if (tab->getType() == ChatTab::TAB_WHISPER)
+ mBrowserBox->addRow(_("@@chat close|Close@@"));
+
+ mBrowserBox->addRow(strprintf("@@chat clear|%s@@", _("Clear")));
+ mBrowserBox->addRow("##3---");
+
+ if (tab->getAllowHighlight())
+ {
+ mBrowserBox->addRow(strprintf("@@disable highlight|%s@@",
+ _("Disable highlight")));
+ mBrowserBox->addRow("##3---");
+ }
+ else
+ {
+ mBrowserBox->addRow(strprintf("@@enable highlight|%s@@",
+ _("Enable highlight")));
+ mBrowserBox->addRow("##3---");
+ }
+
+ if (tab->getType() == ChatTab::TAB_PARTY)
+ {
+ mBrowserBox->addRow(_("@@leave party|Leave@@"));
+ mBrowserBox->addRow("##3---");
+ }
+
+ if (tab->getType() == ChatTab::TAB_WHISPER)
+ {
+ WhisperTab *wTab = static_cast<WhisperTab*>(tab);
+ std::string name = wTab->getNick();
+
+ Being* being = actorSpriteManager->findBeingByName(
+ name, Being::PLAYER);
+
+ if (being)
+ {
+ mBeingId = being->getId();
+ mNick = being->getName();
+
+ mBrowserBox->addRow(_("@@trade|Trade@@"));
+ mBrowserBox->addRow(_("@@attack|Attack@@"));
+
+ mBrowserBox->addRow("##3---");
+
+ mBrowserBox->addRow(_("@@heal|Heal@@"));
+ mBrowserBox->addRow("##3---");
+
+ switch (player_relations.getRelation(name))
+ {
+ case PlayerRelation::NEUTRAL:
+ mBrowserBox->addRow(_("@@friend|Befriend@@"));
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::FRIEND:
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::DISREGARDED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@ignore|Completely ignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::IGNORED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@erase|Erase@@"));
+ break;
+
+ case PlayerRelation::ERASED:
+ mBrowserBox->addRow(_("@@unignore|Unignore@@"));
+ mBrowserBox->addRow(_("@@disregard|Disregard@@"));
+ mBrowserBox->addRow(_("@@ignore|Completely ignore@@"));
+ break;
+
+ default:
+ break;
+ }
+
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@follow|Follow@@"));
+ mBrowserBox->addRow(_("@@imitation|Imitation@@"));
+ mBrowserBox->addRow(_("@@move|Move@@"));
+ mBrowserBox->addRow(_("@@undress|Undress@@"));
+
+ if (player_relations.getDefault() & PlayerRelation::TRADE)
+ {
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(_("@@buy|Buy@@"));
+ mBrowserBox->addRow(_("@@sell|Sell@@"));
+ }
+
+ mBrowserBox->addRow("##3---");
+
+ if (player_node->isInParty())
+ {
+ if (player_node->getParty())
+ {
+ if (!player_node->getParty()->isMember(wTab->getNick()))
+ {
+ mBrowserBox->addRow(_("@@party|Invite to party@@"));
+ }
+ else
+ {
+ mBrowserBox->addRow(
+ _("@@kick party|Kick from party@@"));
+ }
+ mBrowserBox->addRow("##3---");
+ }
+ }
+ Guild *guild1 = being->getGuild();
+ Guild *guild2 = player_node->getGuild();
+ if (guild2)
+ {
+ if (guild1)
+ {
+ if (guild1->getId() == guild2->getId())
+ {
+ mBrowserBox->addRow(
+ _("@@guild-kick|Kick from guild@@"));
+ mBrowserBox->addRow(
+ _("@@guild-pos|Change pos in guild >@@"));
+ }
+ }
+ else
+ {
+ mBrowserBox->addRow(_("@@guild|Invite to guild@@"));
+ }
+ }
+ }
+ }
+ mBrowserBox->addRow(strprintf(_("@@cancel|Cancel@@")));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showChangePos(int x, int y)
+{
+ mBrowserBox->clearRows();
+ mBrowserBox->addRow(_("Change guild position"));
+
+ if (!player_node)
+ return;
+
+ const Guild *guild = player_node->getGuild();
+ if (guild)
+ {
+ PositionsMap map = guild->getPositions();
+ PositionsMap::iterator itr = map.begin();
+ PositionsMap::iterator itr_end = map.end();
+ for (; itr != itr_end; ++itr)
+ {
+ mBrowserBox->addRow(strprintf(_("@@guild-pos-%d|%s@@"),
+ itr->first, itr->second.c_str()));
+ }
+ mBrowserBox->addRow(strprintf(_("@@cancel|Cancel@@")));
+
+ showPopup(x, y);
+ }
+ else
+ {
+ mBeingId = 0;
+ mFloorItem = 0;
+ mItem = 0;
+ mMapItem = 0;
+ mNick = "";
+ setVisible(false);
+ }
+}
+
+void PopupMenu::handleLink(const std::string &link,
+ gcn::MouseEvent *event _UNUSED_)
+{
+ if (!actorSpriteManager)
+ return;
+
+ Being *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);
+ }
+ // Attack action
+ else if (link == "attack" && being)
+ {
+ if (player_node)
+ player_node->attack(being, true);
+ }
+ else if (link == "heal" && being && being->getType() != Being::MONSTER)
+ {
+ actorSpriteManager->heal(player_node, 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 == "erase" && being &&
+ being->getType() == ActorSprite::PLAYER)
+ {
+ player_relations.setRelation(being->getName(), PlayerRelation::ERASED);
+ }
+ 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 *guild = player_node->getGuild();
+ if (guild)
+ Net::getGuildHandler()->invite(guild->getId(), mNick);
+ }
+ }
+ else if (link == "nuke" && being)
+ {
+ actorSpriteManager->addBlock(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") && mFloorItem)
+ {
+ if (player_node)
+ player_node->pickUp(mFloorItem);
+ }
+ // Look To action
+ else if (link == "look")
+ {
+ }
+ else if (link == "use" && mItem)
+ {
+ if (mItem->isEquipment())
+ {
+ if (mItem->isEquipped())
+ Net::getInventoryHandler()->unequipItem(mItem);
+ else
+ Net::getInventoryHandler()->equipItem(mItem);
+ }
+ else
+ {
+ Net::getInventoryHandler()->useItem(mItem);
+ }
+ }
+ else if (link == "use" && mItemId)
+ {
+ if (mItemId < SPELL_MIN_ID)
+ {
+ Inventory *inv = PlayerInfo::getInventory();
+ if (inv)
+ {
+ Item *item = inv->findItem(mItemId);
+ if (item)
+ {
+ if (item->isEquipment())
+ {
+ if (item->isEquipped())
+ Net::getInventoryHandler()->unequipItem(item);
+ else
+ Net::getInventoryHandler()->equipItem(item);
+ }
+ else
+ {
+ Net::getInventoryHandler()->useItem(item);
+ }
+ }
+ }
+ }
+ else if (spellManager)
+ {
+ spellManager->useItem(mItemId);
+ }
+ }
+ else if (link == "chat")
+ {
+ if (chatWindow)
+ {
+ if (mItem)
+ chatWindow->addItemText(mItem->getInfo().getName());
+ else if (mFloorItem)
+ chatWindow->addItemText(mFloorItem->getInfo().getName());
+ }
+ }
+ else if (link == "whisper" && !mNick.empty() && chatWindow)
+ {
+ if (chatWindow)
+ {
+ if (config.getBoolValue("whispertab"))
+ chatWindow->localChatInput("/q " + mNick);
+ else
+ chatWindow->addInputText("/w \"" + mNick + "\" ");
+ }
+ }
+ else if (link == "move" && being)
+ {
+ if (player_node)
+ player_node->navigateTo(being->getTileX(), being->getTileY());
+ }
+ else if (link == "split" && mItem)
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::ItemSplit,
+ inventoryWindow, mItem);
+ }
+ else if (link == "drop" && mItem)
+ {
+ ItemAmountWindow::showWindow(ItemAmountWindow::ItemDrop,
+ inventoryWindow, mItem);
+ }
+ 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()->moveItem(Inventory::INVENTORY,
+ mItem->getInvIndex(), cnt,
+ Inventory::STORAGE);
+ }
+ else if (link == "store half" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
+ mItem->getInvIndex(), mItem->getQuantity() / 2,
+ Inventory::STORAGE);
+ }
+ else if (link == "store all" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem(Inventory::INVENTORY,
+ mItem->getInvIndex(), mItem->getQuantity(),
+ Inventory::STORAGE);
+ }
+ 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()->moveItem(Inventory::STORAGE,
+ mItem->getInvIndex(), cnt,
+ Inventory::INVENTORY);
+ }
+ else if (link == "retrieve half" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem(Inventory::STORAGE,
+ mItem->getInvIndex(), mItem->getQuantity() / 2,
+ Inventory::INVENTORY);
+ }
+ else if (link == "retrieve all" && mItem)
+ {
+ Net::getInventoryHandler()->moveItem(Inventory::STORAGE,
+ mItem->getInvIndex(), mItem->getQuantity(),
+ Inventory::INVENTORY);
+ }
+ 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 == "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)
+ {
+ mTab->handleCommand("close", "");
+ }
+ else if (link == "leave party" && mTab)
+ {
+ Net::getPartyHandler()->leave();
+ }
+ else if (link == "chat clear" && mTab)
+ {
+ if (chatWindow)
+ chatWindow->clearTab();
+ }
+ else if (link == "remove map" && mMapItem)
+ {
+ if (viewport)
+ {
+ Map *map = viewport->getCurrentMap();
+ if (map)
+ {
+ SpecialLayer *specialLayer = map->getSpecialLayer();
+ if (specialLayer)
+ {
+ const int x = mMapItem->getX();
+ const int y = mMapItem->getY();
+ specialLayer->setTile(x, y, MapItem::EMPTY);
+ if (socialWindow)
+ socialWindow->removePortal(x, y);
+ }
+ }
+ }
+ }
+ else if (link == "rename map" && mMapItem)
+ {
+ mRenameListener.setMapItem(mMapItem);
+ mDialog = new TextDialog(_("Rename map sign "),
+ _("Name: "));
+ mRenameListener.setDialog(mDialog);
+ mDialog->setText(mMapItem->getComment());
+ mDialog->setActionEventId("ok");
+ mDialog->addActionListener(&mRenameListener);
+ }
+ else if (link == "load old outfits")
+ {
+ if (outfitWindow)
+ outfitWindow->load(true);
+ }
+ else if (link == "load old spells")
+ {
+ if (spellManager)
+ {
+ spellManager->load(true);
+ spellManager->save();
+ }
+ }
+ else if (link == "load old item shortcuts")
+ {
+ if (itemShortcutWindow)
+ {
+ int num = itemShortcutWindow->getTabIndex();
+ if (num >= 0 && num < SHORTCUT_TABS && itemShortcut[num])
+ {
+ itemShortcut[num]->load(true);
+ itemShortcut[num]->save();
+ }
+ }
+ }
+ else if (link == "load old drop shortcuts")
+ {
+ if (dropShortcut)
+ {
+ dropShortcut->load(true);
+ dropShortcut->save();
+ }
+ }
+ else if (link == "edit spell" && mSpell)
+ {
+ new TextCommandEditor(mSpell);
+ }
+ else if (link == "undress" && being)
+ {
+ Net::getBeingHandler()->undress(being);
+ }
+ else if (link == "guild-kick" && !mNick.empty())
+ {
+ if (player_node)
+ {
+ const Guild *guild = player_node->getGuild();
+ if (guild)
+ Net::getGuildHandler()->kick(guild->getMember(mNick));
+ }
+ }
+ else if (link == "enable highlight" && mTab)
+ {
+ mTab->setAllowHighlight(true);
+ }
+ else if (link == "disable highlight" && mTab)
+ {
+ mTab->setAllowHighlight(false);
+ }
+ else if (link == "guild-pos" && !mNick.empty())
+ {
+ showChangePos(getX(), getY());
+ return;
+ }
+ else if (!link.find("guild-pos-"))
+ {
+ if (player_node)
+ {
+ int num = atoi(link.substr(10).c_str());
+ const Guild *guild = player_node->getGuild();
+ if (guild)
+ {
+ Net::getGuildHandler()->changeMemberPostion(
+ guild->getMember(mNick), num);
+ }
+ }
+ }
+ else if (!link.find("player_"))
+ {
+ mBeingId = atoi(link.substr(7).c_str());
+ Being *being = actorSpriteManager->findBeing(mBeingId);
+ if (being)
+ {
+ showPopup(getX(), getY(), being);
+ return;
+ }
+ }
+ // Unknown actions
+ else if (link != "cancel")
+ {
+ logger->log("PopupMenu: Warning, unknown action '%s'", link.c_str());
+ }
+
+ setVisible(false);
+
+ mBeingId = 0;
+ mFloorItem = 0;
+ mItem = 0;
+ mItemId = 0;
+ mMapItem = 0;
+ mNick = "";
+}
+
+void PopupMenu::showPopup(Window *parent, int x, int y, Item *item,
+ bool isInventory)
+{
+ if (!item)
+ return;
+
+ mItem = item;
+ mWindow = parent;
+ mBrowserBox->clearRows();
+
+ int cnt = item->getQuantity();
+
+ if (isInventory)
+ {
+ if (item->isEquipment())
+ {
+ if (item->isEquipped())
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Unequip")));
+ else
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Equip")));
+ }
+ else
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Use")));
+
+ if (cnt > 1)
+ mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop...")));
+ else
+ mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop")));
+
+ if (Net::getInventoryHandler()->canSplit(item))
+ mBrowserBox->addRow(strprintf("@@split|%s@@", _("Split")));
+
+ if (InventoryWindow::isStorageActive())
+ {
+ mBrowserBox->addRow(strprintf("@@store|%s@@", _("Store")));
+ if (cnt > 1)
+ {
+ if (cnt > 10)
+ {
+ mBrowserBox->addRow(strprintf("@@store 10|%s@@",
+ _("Store 10")));
+ }
+ mBrowserBox->addRow(strprintf("@@store half|%s@@",
+ _("Store half")));
+ mBrowserBox->addRow(strprintf("@@store all|%s@@",
+ _("Store all")));
+ }
+ }
+ }
+ // Assume in storage for now
+ // TODO: make this whole system more flexible, if needed
+ else
+ {
+ mBrowserBox->addRow(strprintf("@@retrieve|%s@@", _("Retrieve")));
+ if (cnt > 1)
+ {
+ if (cnt > 10)
+ {
+ mBrowserBox->addRow(strprintf("@@retrieve 10|%s@@",
+ _("Retrieve 10")));
+ }
+ mBrowserBox->addRow(strprintf("@@retrieve half|%s@@",
+ _("Retrieve half")));
+ mBrowserBox->addRow(strprintf("@@retrieve all|%s@@",
+ _("Retrieve all")));
+ }
+ }
+ mBrowserBox->addRow(strprintf("@@chat|%s@@", _("Add to chat")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showItemPopup(int x, int y, int itemId)
+{
+ Inventory *inv = PlayerInfo::getInventory();
+ if (!inv)
+ return;
+
+ Item *item = inv->findItem(itemId);
+ if (item)
+ {
+ showItemPopup(x, y, item);
+ }
+ else
+ {
+ mItem = 0;
+ mItemId = itemId;
+ mBrowserBox->clearRows();
+
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Use")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(strprintf("@@load old item shortcuts|%s@@",
+ _("Load old item shortcuts")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
+
+ showPopup(x, y);
+ }
+}
+
+void PopupMenu::showItemPopup(int x, int y, Item *item)
+{
+ mItem = item;
+ if (item)
+ mItemId = item->getId();
+ else
+ mItemId = 0;
+ mBrowserBox->clearRows();
+
+ if (item)
+ {
+ if (item->isEquipment())
+ {
+ if (item->isEquipped())
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Unequip")));
+ else
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Equip")));
+ }
+ else
+ {
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Use")));
+ }
+
+ if (item->getQuantity() > 1)
+ mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop...")));
+ else
+ mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop")));
+
+ if (Net::getInventoryHandler()->canSplit(item))
+ mBrowserBox->addRow(strprintf("@@split|%s@@", _("Split")));
+
+ if (InventoryWindow::isStorageActive())
+ mBrowserBox->addRow(strprintf("@@store|%s@@", _("Store")));
+ mBrowserBox->addRow(strprintf("@@chat|%s@@", _("Add to chat")));
+ mBrowserBox->addRow("##3---");
+ }
+ mBrowserBox->addRow(strprintf("@@load old item shortcuts|%s@@",
+ _("Load old item shortcuts")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showDropPopup(int x, int y, Item *item)
+{
+ mItem = item;
+ mBrowserBox->clearRows();
+
+ if (item)
+ {
+ if (item->isEquipment())
+ {
+ if (item->isEquipped())
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Unequip")));
+ else
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Equip")));
+ }
+ else
+ mBrowserBox->addRow(strprintf("@@use|%s@@", _("Use")));
+
+ if (item->getQuantity() > 1)
+ mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop...")));
+ else
+ mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop")));
+
+ if (Net::getInventoryHandler()->canSplit(item))
+ mBrowserBox->addRow(strprintf("@@split|%s@@", _("Split")));
+
+ if (InventoryWindow::isStorageActive())
+ mBrowserBox->addRow(strprintf("@@store|%s@@", _("Store")));
+ mBrowserBox->addRow(strprintf("@@chat|%s@@", _("Add to chat")));
+ mBrowserBox->addRow("##3---");
+ }
+ mBrowserBox->addRow(strprintf("@@load old drop shortcuts|%s@@",
+ _("Load old drop shortcuts")));
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
+
+ showPopup(x, y);
+}
+
+void PopupMenu::showPopup(int x _UNUSED_, int y _UNUSED_, Button *button)
+{
+ if (!button)
+ return;
+
+}
+
+void PopupMenu::showPopup(int x, int y)
+{
+ setContentSize(mBrowserBox->getWidth() + 8, mBrowserBox->getHeight() + 8);
+ if (graphics->getWidth() < (x + getWidth() + 5))
+ x = graphics->getWidth() - getWidth();
+ if (graphics->getHeight() < (y + getHeight() + 5))
+ y = graphics->getHeight() - getHeight();
+ setPosition(x, y);
+ setVisible(true);
+ requestMoveToTop();
+}
+
+
+void RenameListener::action(const gcn::ActionEvent &event)
+{
+ if (event.getId() == "ok" && mMapItem && viewport && mDialog)
+ {
+ Map *map = viewport->getMap();
+ if (!map)
+ return;
+
+ SpecialLayer *sl = map->getSpecialLayer();
+ MapItem *item = 0;
+ if (sl)
+ {
+ item = sl->getTile(mMapItem->getX(), mMapItem->getY());
+ if (!item)
+ {
+ sl->setTile(mMapItem->getX(), mMapItem->getY(),
+ mMapItem->getType());
+ item = sl->getTile(mMapItem->getX(), mMapItem->getY());
+ }
+ item->setComment(mDialog->getText());
+ }
+ item = map->findPortalXY(mMapItem->getX(), mMapItem->getY());
+ if (item)
+ item->setComment(mDialog->getText());
+
+ if (socialWindow)
+ socialWindow->updatePortalNames();
+ }
+ mDialog = 0;
+}