/*
* The ManaPlus Client
* Copyright (C) 2004-2009 The Mana World Development Team
* Copyright (C) 2009-2010 The Mana Developers
* Copyright (C) 2011 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/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/buydialog.h"
#include "gui/chatwindow.h"
#include "gui/equipmentwindow.h"
#include "gui/inventorywindow.h"
#include "gui/itemamountwindow.h"
#include "gui/ministatus.h"
#include "gui/outfitwindow.h"
#include "gui/selldialog.h"
#include "gui/socialwindow.h"
#include "gui/textcommandeditor.h"
#include "gui/textdialog.h"
#include "gui/tradewindow.h"
#include "gui/viewport.h"
#include "gui/windowmenu.h"
#include "gui/widgets/browserbox.h"
#include "gui/widgets/button.h"
#include "gui/widgets/chattab.h"
#include "gui/widgets/progressbar.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
#include "debug.h"
std::string tradePartnerName("");
PopupMenu::PopupMenu():
Popup("PopupMenu"),
mBeingId(0),
mFloorItem(0),
mItem(0),
mItemId(0),
mItemColor(1),
mMapItem(0),
mTab(0),
mSpell(0),
mDialog(0),
mButton(0),
mNick("")
{
mBrowserBox = new BrowserBox;
mBrowserBox->setPosition(4, 4);
mBrowserBox->setHighlightMode(BrowserBox::BACKGROUND);
mBrowserBox->setOpaque(false);
mBrowserBox->setLinkHandler(this);
mRenameListener.setMapItem(0);
mRenameListener.setDialog(0);
mPlayerListener.setNick("");
mPlayerListener.setDialog(0);
add(mBrowserBox);
}
void PopupMenu::showPopup(int x, int y, Being *being)
{
if (!being || !player_node || !actorSpriteManager)
return;
mBeingId = being->getId();
mNick = being->getName();
mBrowserBox->clearRows();
const std::string &name = mNick;
mBrowserBox->addRow(name + being->getGenderSignWithSpace());
switch (being->getType())
{
case ActorSprite::PLAYER:
{
mBrowserBox->addRow(strprintf("@@trade|%s@@", _("Trade")));
mBrowserBox->addRow(strprintf("@@attack|%s@@", _("Attack")));
mBrowserBox->addRow(strprintf("@@whisper|%s@@", _("Whisper")));
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@heal|%s@@", _("Heal")));
mBrowserBox->addRow("##3---");
switch (player_relations.getRelation(name))
{
case PlayerRelation::NEUTRAL:
mBrowserBox->addRow(strprintf(
"@@friend|%s@@", _("Be friend")));
mBrowserBox->addRow(strprintf(
"@@disregard|%s@@", _("Disregard")));
mBrowserBox->addRow(strprintf(
"@@ignore|%s@@", _("Ignore")));
mBrowserBox->addRow(strprintf(
"@@erase|%s@@", _("Erase")));
break;
case PlayerRelation::FRIEND:
mBrowserBox->addRow(strprintf(
"@@disregard|%s@@", _("Disregard")));
mBrowserBox->addRow(strprintf(
"@@ignore|%s@@", _("Ignore")));
mBrowserBox->addRow(strprintf(
"@@erase|%s@@", _("Erase")));
break;
case PlayerRelation::DISREGARDED:
mBrowserBox->addRow(strprintf(
"@@unignore|%s@@", _("Unignore")));
mBrowserBox->addRow(strprintf(
"@@ignore|%s@@", _("Completely ignore")));
mBrowserBox->addRow(strprintf(
"@@erase|%s@@", _("Erase")));
break;
case PlayerRelation::IGNORED:
mBrowserBox->addRow(strprintf(
"@@unignore|%s@@", _("Unignore")));
mBrowserBox->addRow(strprintf(
"@@erase|%s@@", _("Erase")));
break;
case PlayerRelation::ERASED:
mBrowserBox->addRow(strprintf(
"@@unignore|%s@@", _("Unignore")));
mBrowserBox->addRow(strprintf(
"@@disregard|%s@@", _("Disregard")));
mBrowserBox->addRow(strprintf(
"@@ignore|%s@@", _("Completely ignore")));
break;
default:
break;
}
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@follow|%s@@", _("Follow")));
mBrowserBox->addRow(strprintf(
"@@imitation|%s@@", _("Imitation")));
if (player_node->isInParty())
{
if (player_node->getParty())
{
if (player_node->getParty()->getName()
!= being->getPartyName())
{
mBrowserBox->addRow(strprintf(
"@@party|%s@@", _("Invite to party")));
}
else
{
mBrowserBox->addRow(strprintf(
"@@kick party|%s@@", _("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(strprintf(
"@@guild-kick|%s@@", _("Kick from guild")));
mBrowserBox->addRow(strprintf("@@guild-pos|%s >@@",
_("Change pos in guild")));
}
}
else
{
mBrowserBox->addRow(strprintf(
"@@guild|%s@@", _("Invite to guild")));
}
}
if (player_node->isGM())
{
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf(
"@@admin-kick|%s@@", _("Kick player")));
}
mBrowserBox->addRow(strprintf("@@nuke|%s@@", _("Nuke")));
mBrowserBox->addRow(strprintf("@@move|%s@@", _("Move")));
mBrowserBox->addRow(strprintf("@@items|%s@@",
_("Show Items")));
mBrowserBox->addRow(strprintf("@@undress|%s@@", _("Undress")));
mBrowserBox->addRow(strprintf(
"@@addcomment|%s@@", _("Add comment")));
if (player_relations.getDefault() & PlayerRelation::TRADE)
{
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@buy|%s@@", _("Buy")));
mBrowserBox->addRow(strprintf("@@sell|%s@@", _("Sell")));
}
}
break;
case ActorSprite::NPC:
// NPCs can be talked to (single option, candidate for removal
// unless more options would be added)
mBrowserBox->addRow(strprintf("@@talk|%s@@", _("Talk")));
mBrowserBox->addRow(strprintf("@@buy|%s@@", _("Buy")));
mBrowserBox->addRow(strprintf("@@sell|%s@@", _("Sell")));
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@move|%s@@", _("Move")));
break;
case ActorSprite::MONSTER:
{
// Monsters can be attacked
mBrowserBox->addRow(strprintf("@@attack|%s@@", _("Attack")));
if (player_node->isGM())
{
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf(
"@@admin-kick|%s@@", _("Kick")));
}
if (config.getBoolValue("enableAttackFilter"))
{
mBrowserBox->addRow("##3---");
if (actorSpriteManager->isInAttackList(name)
|| actorSpriteManager->isInIgnoreAttackList(name)
|| actorSpriteManager->isInPriorityAttackList(name))
{
mBrowserBox->addRow(strprintf("@@remove attack|%s@@",
_("Remove from attack list")));
}
else
{
mBrowserBox->addRow(strprintf(
"@@add attack priority|%s@@",
_("Add to priority attack list")));
mBrowserBox->addRow(strprintf(
"@@add attack|%s@@", _("Add to attack list")));
mBrowserBox->addRow(strprintf(
"@@add attack ignore|%s@@",
_("Add to ignore list")));
}
}
}
break;
case ActorSprite::UNKNOWN:
case ActorSprite::FLOOR_ITEM:
case ActorSprite::PORTAL:
default:
/* Other beings aren't interesting... */
return;
}
mBrowserBox->addRow(strprintf("@@name|%s@@", _("Add name to chat")));
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
showPopup(x, y);
}
void PopupMenu::showPopup(int x, int y, std::list &beings)
{
mBrowserBox->clearRows();
mBrowserBox->addRow("Players");
std::list::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()
+ being->getGenderSignWithSpace()).c_str()));
}
}
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("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(strprintf("@@whisper|%s@@", _("Whisper")));
mBrowserBox->addRow("##3---");
switch (player_relations.getRelation(name))
{
case PlayerRelation::NEUTRAL:
mBrowserBox->addRow(strprintf("@@friend|%s@@", _("Be friend")));
mBrowserBox->addRow(strprintf(
"@@disregard|%s@@", _("Disregard")));
mBrowserBox->addRow(strprintf("@@ignore|%s@@", _("Ignore")));
mBrowserBox->addRow(strprintf("@@erase|%s@@", _("Erase")));
break;
case PlayerRelation::FRIEND:
mBrowserBox->addRow(strprintf("@@disregard|%s@@", _("Disregard")));
mBrowserBox->addRow(strprintf("@@ignore|%s@@", _("Ignore")));
mBrowserBox->addRow(strprintf("@@erase|%s@@", _("Erase")));
break;
case PlayerRelation::DISREGARDED:
mBrowserBox->addRow(strprintf("@@unignore|%s@@", _("Unignore")));
mBrowserBox->addRow(strprintf(
"@@ignore|%s@@", _("Completely ignore")));
mBrowserBox->addRow(strprintf("@@erase|%s@@", _("Erase")));
break;
case PlayerRelation::IGNORED:
mBrowserBox->addRow(strprintf("@@unignore|%s@@", _("Unignore")));
mBrowserBox->addRow(strprintf("@@erase|%s@@", _("Erase")));
break;
case PlayerRelation::ERASED:
mBrowserBox->addRow(strprintf("@@unignore|%s@@", _("Unignore")));
mBrowserBox->addRow(strprintf("@@disregard|%s@@", _("Disregard")));
mBrowserBox->addRow(strprintf(
"@@ignore|%s@@", _("Completely ignore")));
break;
default:
break;
}
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@follow|%s@@", _("Follow")));
mBrowserBox->addRow(strprintf("@@imitation|%s@@", _("Imitation")));
mBrowserBox->addRow(strprintf("@@addcomment|%s@@", _("Add comment")));
if (player_node->isInParty() && player_node->getParty())
{
PartyMember *member = player_node->getParty()->getMember(mNick);
if (member)
{
mBrowserBox->addRow(strprintf(
"@@kick party|%s@@", _("Kick from party")));
mBrowserBox->addRow("##3---");
}
}
Guild *guild2 = player_node->getGuild();
if (guild2)
{
if (guild2->getMember(mNick))
{
mBrowserBox->addRow(strprintf(
"@@guild-kick|%s@@", _("Kick from guild")));
mBrowserBox->addRow(strprintf(
"@@guild-pos|%s >@@", _("Change pos in guild")));
}
else
{
mBrowserBox->addRow(strprintf(
"@@guild|%s@@", _("Invite to guild")));
}
}
mBrowserBox->addRow("##3---");
if (player_relations.getDefault() & PlayerRelation::TRADE)
{
mBrowserBox->addRow(strprintf("@@buy|%s@@", _("Buy")));
mBrowserBox->addRow(strprintf("@@sell|%s@@", _("Sell")));
}
mBrowserBox->addRow(strprintf("@@name|%s@@", _("Add name to chat")));
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
showPopup(x, y);
}
void PopupMenu::showPopup(int x, int y, FloorItem *floorItem)
{
if (!floorItem)
return;
mFloorItem = floorItem;
ItemInfo info = floorItem->getInfo();
mBrowserBox->clearRows();
std::string name;
// Floor item can be picked up (single option, candidate for removal)
if (serverVersion > 0)
name = info.getName(floorItem->getColor());
else
name = info.getName();
mBrowserBox->addRow(name);
mBrowserBox->addRow(strprintf("@@pickup|%s@@", _("Pick up")));
mBrowserBox->addRow(strprintf("@@chat|%s@@", _("Add to chat")));
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("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(strprintf("@@rename map|%s@@", _("Rename")));
mBrowserBox->addRow(strprintf("@@remove map|%s@@", _("Remove")));
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
showPopup(x, y);
}
void PopupMenu::showOutfitsPopup(int x, int y)
{
mBrowserBox->clearRows();
mBrowserBox->addRow(_("Outfits"));
mBrowserBox->addRow(strprintf(
"@@load old outfits|%s@@", _("Load old outfits")));
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("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(strprintf(
"@@load old spells|%s@@", _("Load old spells")));
mBrowserBox->addRow(strprintf("@@edit spell|%s@@", _("Edit spell")));
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("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(strprintf("@@chat close|%s@@", _("Close")));
mBrowserBox->addRow(strprintf("@@chat clear|%s@@", _("Clear")));
mBrowserBox->addRow("##3---");
if (tab->getAllowHighlight())
{
mBrowserBox->addRow(strprintf("@@disable highlight|%s@@",
_("Disable highlight")));
}
else
{
mBrowserBox->addRow(strprintf("@@enable highlight|%s@@",
_("Enable highlight")));
}
if (tab->getRemoveNames())
{
mBrowserBox->addRow(strprintf("@@dont remove name|%s@@",
_("Dont remove name")));
}
else
{
mBrowserBox->addRow(strprintf("@@remove name|%s@@",
_("Remove name")));
}
if (tab->getNoAway())
{
mBrowserBox->addRow(strprintf("@@enable away|%s@@",
_("Enable away")));
}
else
{
mBrowserBox->addRow(strprintf("@@disable away|%s@@",
_("Disable away")));
}
mBrowserBox->addRow("##3---");
if (tab->getType() == ChatTab::TAB_PARTY)
{
mBrowserBox->addRow(strprintf("@@leave party|%s@@", _("Leave")));
mBrowserBox->addRow("##3---");
}
if (tab->getType() == ChatTab::TAB_WHISPER)
{
WhisperTab *wTab = static_cast(tab);
std::string name = wTab->getNick();
Being* being = actorSpriteManager->findBeingByName(
name, Being::PLAYER);
if (being)
{
mBeingId = being->getId();
mNick = being->getName();
mBrowserBox->addRow(strprintf("@@trade|%s@@", _("Trade")));
mBrowserBox->addRow(strprintf("@@attack|%s@@", _("Attack")));
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@heal|%s@@", _("Heal")));
mBrowserBox->addRow("##3---");
switch (player_relations.getRelation(name))
{
case PlayerRelation::NEUTRAL:
mBrowserBox->addRow(strprintf(
"@@friend|%s@@", _("Be friend")));
mBrowserBox->addRow(strprintf(
"@@disregard|%s@@", _("Disregard")));
mBrowserBox->addRow(strprintf(
"@@ignore|%s@@", _("Ignore")));
mBrowserBox->addRow(strprintf("@@erase|%s@@", _("Erase")));
break;
case PlayerRelation::FRIEND:
mBrowserBox->addRow(strprintf(
"@@disregard|%s@@", _("Disregard")));
mBrowserBox->addRow(strprintf(
"@@ignore|%s@@", _("Ignore")));
mBrowserBox->addRow(strprintf("@@erase|%s@@", _("Erase")));
break;
case PlayerRelation::DISREGARDED:
mBrowserBox->addRow(strprintf(
"@@unignore|%s@@", _("Unignore")));
mBrowserBox->addRow(strprintf(
"@@ignore|%s@@", _("Completely ignore")));
mBrowserBox->addRow(strprintf("@@erase|%s@@", _("Erase")));
break;
case PlayerRelation::IGNORED:
mBrowserBox->addRow(strprintf(
"@@unignore|%s@@", _("Unignore")));
mBrowserBox->addRow(strprintf("@@erase|%s@@", _("Erase")));
break;
case PlayerRelation::ERASED:
mBrowserBox->addRow(strprintf(
"@@unignore|%s@@", _("Unignore")));
mBrowserBox->addRow(strprintf(
"@@disregard|%s@@", _("Disregard")));
mBrowserBox->addRow(strprintf(
"@@ignore|%s@@", _("Completely ignore")));
break;
default:
break;
}
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@follow|%s@@", _("Follow")));
mBrowserBox->addRow(strprintf("@@imitation|%s@@", _("Imitation")));
mBrowserBox->addRow(strprintf("@@move|%s@@", _("Move")));
mBrowserBox->addRow(strprintf("@@items|%s@@", _("Show Items")));
mBrowserBox->addRow(strprintf("@@undress|%s@@", _("Undress")));
mBrowserBox->addRow(strprintf(
"@@addcomment|%s@@", _("Add comment")));
if (player_relations.getDefault() & PlayerRelation::TRADE)
{
mBrowserBox->addRow("##3---");
mBrowserBox->addRow(strprintf("@@buy|%s@@", _("Buy")));
mBrowserBox->addRow(strprintf("@@sell|%s@@", _("Sell")));
}
mBrowserBox->addRow("##3---");
if (player_node->isInParty())
{
if (player_node->getParty())
{
if (!player_node->getParty()->isMember(wTab->getNick()))
{
mBrowserBox->addRow(
strprintf("@@party|%s@@", _("Invite to party")));
}
else
{
mBrowserBox->addRow(strprintf(
"@@kick party|%s@@", _("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(strprintf(
"@@guild-kick|%s@@", _("Kick from guild")));
mBrowserBox->addRow(strprintf(
"@@guild-pos|%s >@@", _("Change pos in guild")));
}
}
else
{
mBrowserBox->addRow(strprintf(
"@@guild|%s@@", _("Invite to guild")));
}
}
}
else
{
mBrowserBox->addRow(strprintf(
"@@addcomment|%s@@", _("Add comment")));
mBrowserBox->addRow("##3---");
}
}
mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("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|%s@@", _("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, mItemColor);
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)
{
if (serverVersion > 0)
{
chatWindow->addItemText(mItem->getInfo().getName(
mItem->getColor()));
}
else
{
chatWindow->addItemText(mItem->getInfo().getName());
}
}
else if (mFloorItem)
{
if (serverVersion > 0)
{
chatWindow->addItemText(mFloorItem->getInfo().getName(
mFloorItem->getColor()));
}
else
{
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 == "drop all" && mItem)
{
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()->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 == "addtrade" && mItem)
{
ItemAmountWindow::showWindow(ItemAmountWindow::TradeAdd,
tradeWindow, mItem);
}
else if (link == "addtrade 10" && mItem)
{
if (tradeWindow)
{
int cnt = 10;
if (cnt > mItem->getQuantity())
cnt = mItem->getQuantity();
tradeWindow->tradeItem(mItem, cnt);
}
}
else if (link == "addtrade half" && mItem)
{
if (tradeWindow)
tradeWindow->tradeItem(mItem, mItem->getQuantity() / 2);
}
else if (link == "addtrade all" && mItem)
{
if (tradeWindow)
tradeWindow->tradeItem(mItem, mItem->getQuantity());
}
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 == "kick party" && !mNick.empty())
{
if (player_node && player_node->getParty())
{
PartyMember *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)
{
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)
{
bool isHome = (mMapItem->getType() == MapItem::HOME);
const int x = mMapItem->getX();
const int y = mMapItem->getY();
specialLayer->setTile(x, y, 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 == "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 == "addcomment" && !mNick.empty())
{
// TRANSLATORS: number of chars in string should be near original
TextDialog *dialog = new TextDialog(_("Player comment "),
// TRANSLATORS: number of chars in string should be near original
_("Comment: "));
mPlayerListener.setDialog(dialog);
mPlayerListener.setNick(mNick);
if (being)
{
being->updateComment();
dialog->setText(being->getComment());
}
else
{
dialog->setText(Being::loadComment(mNick));
}
dialog->setActionEventId("ok");
dialog->addActionListener(&mPlayerListener);
}
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 == "dont remove name" && mTab)
{
mTab->setRemoveNames(false);
}
else if (link == "remove name" && mTab)
{
mTab->setRemoveNames(true);
}
else if (link == "disable away" && mTab)
{
mTab->setNoAway(true);
}
else if (link == "enable away" && mTab)
{
mTab->setNoAway(false);
}
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 == "attack moveup")
{
if (actorSpriteManager)
{
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)
{
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)
{
int idx = actorSpriteManager->getAttackMobIndex(mNick);
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)
{
int idx = actorSpriteManager->getPriorityAttackMobIndex(mNick);
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 == "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->isVisible())
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.compare(0, 10, "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.compare(0, 7, "player_"))
{
mBeingId = atoi(link.substr(7).c_str());
Being *being = actorSpriteManager->findBeing(mBeingId);
if (being)
{
showPopup(getX(), getY(), being);
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);
}
// 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;
mItemColor = 1;
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 (tradeWindow && tradeWindow->isVisible())
{
mBrowserBox->addRow(strprintf("@@addtrade|%s@@",
_("Add to trade")));
if (cnt > 1)
{
if (cnt > 10)
{
mBrowserBox->addRow(strprintf("@@addtrade 10|%s@@",
_("Add to trade 10")));
}
mBrowserBox->addRow(strprintf("@@addtrade half|%s@@",
_("Add to trade half")));
mBrowserBox->addRow(strprintf("@@addtrade all|%s@@",
_("Add to trade all")));
}
mBrowserBox->addRow("##3---");
}
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")));
}
mBrowserBox->addRow("##3---");
}
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...")));
mBrowserBox->addRow(strprintf("@@drop all|%s@@", _("Drop all")));
}
else
{
mBrowserBox->addRow(strprintf("@@drop|%s@@", _("Drop")));
}
if (Net::getInventoryHandler()->canSplit(item))
mBrowserBox->addRow(strprintf("@@split|%s@@", _("Split")));
}
// 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, unsigned char color)
{
Inventory *inv = PlayerInfo::getInventory();
if (!inv)
return;
Item *item = inv->findItem(itemId, color);
if (item)
{
showItemPopup(x, y, item);
}
else
{
mItem = 0;
mItemId = itemId;
mItemColor = color;
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();
mItemColor = item->getColor();
}
else
{
mItemId = 0;
mItemColor = 1;
}
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...")));
mBrowserBox->addRow(strprintf("@@drop all|%s@@", _("Drop all")));
}
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...")));
mBrowserBox->addRow(strprintf("@@drop all|%s@@", _("Drop all")));
}
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, int y, Button *button)
{
if (!button || !windowMenu)
return;
mButton = button;
mBrowserBox->clearRows();
std::list names = windowMenu->getButtons();
std::list ::iterator it, it_end;
for (it = names.begin(), it_end = names.end(); it != it_end; ++ it)
{
Button *btn = dynamic_cast