/*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "gui/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/chatwindow.h"
#include "gui/equipmentwindow.h"
#include "gui/inventorywindow.h"
#include "gui/itemamountwindow.h"
#include "gui/ministatuswindow.h"
#include "gui/npcdialog.h"
#include "gui/outfitwindow.h"
#include "gui/skilldialog.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/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 <guichan/listmodel.hpp>
#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<int>(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<int>(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<int>(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
mBrowserBox->addRow("trade", _("Trade"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("attack", _("Attack"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("whisper", _("Whisper"));
addGmCommands();
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
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
_("Kick from guild"));
if (guild2->getServerGuild())
{
mBrowserBox->addRow(strprintf(
"@@guild-pos|%s >@@",
// TRANSLATORS: popup menu item
_("Change pos in guild")));
}
}
}
else if (guild2->getMember(mNick))
{
mBrowserBox->addRow("guild-kick",
// TRANSLATORS: popup menu item
_("Kick from guild"));
if (guild2->getServerGuild())
{
mBrowserBox->addRow(strprintf(
"@@guild-pos|%s >@@",
// TRANSLATORS: popup menu item
_("Change pos in guild")));
}
}
else
{
if (guild2->getServerGuild()
|| (guildManager && guildManager->havePower()))
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("guild", _("Invite to guild"));
}
}
}
// TRANSLATORS: popup menu item
mBrowserBox->addRow("nuke", _("Nuke"));
// TRANSLATORS: popup menu item
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
mBrowserBox->addRow("talk", _("Talk"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("buy", _("Buy"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("sell", _("Sell"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("move", _("Move"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("addcomment", _("Add comment"));
break;
case ActorSprite::MONSTER:
{
// Monsters can be attacked
// TRANSLATORS: popup menu item
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: popup menu item
_("Remove from attack list"));
}
else
{
mBrowserBox->addRow("add attack priority",
// TRANSLATORS: popup menu item
_("Add to priority attack list"));
mBrowserBox->addRow("add attack",
// TRANSLATORS: popup menu item
_("Add to attack list"));
mBrowserBox->addRow("add attack ignore",
// TRANSLATORS: popup menu item
_("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
mBrowserBox->addRow("name", _("Add name to chat"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("cancel", _("Cancel"));
showPopup(x, y);
}
void PopupMenu::showPopup(const int x, const int y,
std::vector<ActorSprite*> &beings)
{
mX = x;
mY = y;
mBrowserBox->clearRows();
// TRANSLATORS: popup menu header
mBrowserBox->addRow(_("Players"));
FOR_EACH (std::vector<ActorSprite*>::const_iterator, it, beings)
{
const Being *const being = dynamic_cast<Being*>(*it);
const ActorSprite *const actor = *it;
if (being && !being->getName().empty())
{
mBrowserBox->addRow(strprintf("@@player_%u|%s >@@",
static_cast<unsigned>(being->getId()), (being->getName()
+ being->getGenderSignWithSpace()).c_str()));
}
else if (actor->getType() == ActorSprite::FLOOR_ITEM)
{
const FloorItem *const floorItem
= static_cast<const FloorItem*>(actor);
mBrowserBox->addRow(strprintf("@@flooritem_%u|%s >@@",
static_cast<unsigned>(actor->getId()),
floorItem->getName().c_str()));
}
}
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
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<int>(Being::PLAYER);
mX = x;
mY = y;
mBrowserBox->clearRows();
const std::string &name = mNick;
mBrowserBox->addRow(name);
// TRANSLATORS: popup menu item
mBrowserBox->addRow("whisper", _("Whisper"));
addGmCommands();
mBrowserBox->addRow("##3---");
addPlayerRelation(name);
mBrowserBox->addRow("##3---");
addFollow();
// TRANSLATORS: popup menu item
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
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
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
mBrowserBox->addRow("guild-kick", _("Kick from guild"));
}
if (guild2->getServerGuild())
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow(strprintf(
"@@guild-pos|%s >@@", _("Change pos in guild")));
}
}
else
{
if (guild2->getServerGuild() || (guildManager
&& guildManager->havePower()))
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("guild", _("Invite to guild"));
}
}
}
addBuySellDefault();
// TRANSLATORS: popup menu item
mBrowserBox->addRow("name", _("Add name to chat"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
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<int>(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
mBrowserBox->addRow("pickup", _("Pick up"));
mBrowserBox->addRow("##3---");
}
addPickupFilter(name);
}
else
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("pickup", _("Pick up"));
}
addProtection();
// TRANSLATORS: popup menu item
mBrowserBox->addRow("chat", _("Add to chat"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
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
mBrowserBox->addRow("rename map", _("Rename"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("remove map", _("Remove"));
if (player_node && player_node->isGM())
{
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("warp map", _("Warp"));
}
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
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
mBrowserBox->addRow("warp map", _("Warp"));
}
// TRANSLATORS: popup menu item
mBrowserBox->addRow("move", _("Move"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("movecamera", _("Move camera"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
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
mBrowserBox->addRow("clear outfit", _("Clear outfit"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
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
mBrowserBox->addRow("edit spell", _("Edit spell"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
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<int>(ChatTab::TAB_WHISPER))
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("chat close", _("Close"));
}
// TRANSLATORS: popup menu item
mBrowserBox->addRow("chat clear", _("Clear"));
mBrowserBox->addRow("##3---");
if (tab->getAllowHighlight())
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("disable highlight", _("Disable highlight"));
}
else
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("enable highlight", _("Enable highlight"));
}
if (tab->getRemoveNames())
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("dont remove name", _("Don't remove name"));
}
else
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("remove name", _("Remove name"));
}
if (tab->getNoAway())
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("enable away", _("Enable away"));
}
else
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("disable away", _("Disable away"));
}
mBrowserBox->addRow("##3---");
if (tab->getType() == static_cast<int>(ChatTab::TAB_PARTY))
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("leave party", _("Leave"));
mBrowserBox->addRow("##3---");
}
// TRANSLATORS: popup menu item
mBrowserBox->addRow("chat clipboard", _("Copy to clipboard"));
mBrowserBox->addRow("##3---");
if (tab->getType() == static_cast<int>(ChatTab::TAB_WHISPER))
{
const WhisperTab *const wTab = static_cast<WhisperTab*>(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<int>(being->getType());
// TRANSLATORS: popup menu item
mBrowserBox->addRow("trade", _("Trade"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("attack", _("Attack"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("heal", _("Heal"));
mBrowserBox->addRow("##3---");
addPlayerRelation(name);
mBrowserBox->addRow("##3---");
addFollow();
// TRANSLATORS: popup menu item
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
mBrowserBox->addRow("party", _("Invite to party"));
}
else
{
// TRANSLATORS: popup menu item
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
mBrowserBox->addRow(strprintf(
"@@guild-kick|%s@@", _("Kick from guild")));
}
if (guild2->getServerGuild())
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow(strprintf("@@guild-pos|%s >@@",
_("Change pos in guild")));
}
}
}
else
{
if (guild2->getServerGuild() || (guildManager
&& guildManager->havePower()))
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("guild", _("Invite to guild"));
}
}
}
}
else
{
mNick = name;
mType = static_cast<int>(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
mBrowserBox->addRow("move", _("Move"));
}
}
}
addPlayerMisc();
addBuySellDefault();
mBrowserBox->addRow("##3---");
}
}
// TRANSLATORS: popup menu item
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)
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow(strprintf("@@guild-pos-%u|%s@@",
itr->first, itr->second.c_str()));
}
// TRANSLATORS: popup menu item
mBrowserBox->addRow("cancel", _("Cancel"));
showPopup(x, y);
}
else
{
mBeingId = 0;
mFloorItemId = 0;
mItem = nullptr;
mMapItem = nullptr;
mNick.clear();
mType = static_cast<int>(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<uint32_t>(
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<int>(MapItem::HOME));
const int x = static_cast<const int>(mMapItem->getX());
const int y = static_cast<const int>(mMapItem->getY());
specialLayer->setTile(x, y,
static_cast<int>(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<std::string> mobs
= actorSpriteManager->getAttackMobs();
std::list<std::string>::iterator it = mobs.begin();
std::list<std::string>::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<std::string> mobs
= actorSpriteManager->getPriorityAttackMobs();
std::list<std::string>::iterator it = mobs.begin();
std::list<std::string>::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<std::string> mobs
= actorSpriteManager->getAttackMobs();
std::list<std::string>::iterator it = mobs.begin();
std::list<std::string>::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<std::string> mobs
= actorSpriteManager->getPriorityAttackMobs();
std::list<std::string>::iterator it = mobs.begin();
std::list<std::string>::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<int>(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
mBrowserBox->addRow("addtrade", _("Add to trade"));
if (cnt > 1)
{
if (cnt > 10)
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("addtrade 10", _("Add to trade 10"));
}
// TRANSLATORS: popup menu item
mBrowserBox->addRow("addtrade half", _("Add to trade half"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("addtrade all-1", _("Add to trade all-1"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("addtrade all", _("Add to trade all"));
}
mBrowserBox->addRow("##3---");
}
if (InventoryWindow::isStorageActive())
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("store", _("Store"));
if (cnt > 1)
{
if (cnt > 10)
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("store 10", _("Store 10"));
}
// TRANSLATORS: popup menu item
mBrowserBox->addRow("store half", _("Store half"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("store all-1", _("Store all-1"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("store all", _("Store all"));
}
mBrowserBox->addRow("##3---");
}
addUseDrop(item, isProtected);
}
// Assume in storage for now
else
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("retrieve", _("Retrieve"));
if (cnt > 1)
{
if (cnt > 10)
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("retrieve 10", _("Retrieve 10"));
}
// TRANSLATORS: popup menu item
mBrowserBox->addRow("retrieve half", _("Retrieve half"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("retrieve all-1", _("Retrieve all-1"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("retrieve all", _("Retrieve all"));
}
}
addProtection();
if (config.getBoolValue("enablePickupFilter"))
{
mNick = item->getName();
mBrowserBox->addRow("##3---");
addPickupFilter(mNick);
}
// TRANSLATORS: popup menu item
mBrowserBox->addRow("chat", _("Add to chat"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
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
mBrowserBox->addRow("use", _("Use"));
}
addProtection();
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
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
mBrowserBox->addRow("store", _("Store"));
}
// TRANSLATORS: popup menu item
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
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
mBrowserBox->addRow("store", _("Store"));
}
addProtection();
// TRANSLATORS: popup menu item
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
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<Button *> names = windowMenu->getButtons();
for (std::vector<Button *>::const_iterator it = names.begin(),
it_end = names.end(); it != it_end; ++ it)
{
const Button *const btn = dynamic_cast<Button*>(*it);
if (!btn || btn->getActionEventId() == "SET")
continue;
if (btn->isVisible())
{
mBrowserBox->addRow(strprintf("@@hide button_%s|%s %s (%s)@@",
// TRANSLATORS: popup menu item
btn->getActionEventId().c_str(), _("Hide"),
btn->getDescription().c_str(), btn->getCaption().c_str()));
}
else
{
mBrowserBox->addRow(strprintf("@@show button_%s|%s %s (%s)@@",
// TRANSLATORS: popup menu item
btn->getActionEventId().c_str(), _("Show"),
btn->getDescription().c_str(), btn->getCaption().c_str()));
}
}
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("cancel", _("Cancel"));
showPopup(x, y);
}
void PopupMenu::showPopup(const int x, const int y, const ProgressBar *const b)
{
if (!b || !miniStatusWindow)
return;
mNick = b->text();
mX = x;
mY = y;
mBrowserBox->clearRows();
std::vector <ProgressBar*> bars = miniStatusWindow->getBars();
ProgressBar *onlyBar = nullptr;
int cnt = 0;
// search for alone visible bar
for (std::vector <ProgressBar*>::const_iterator it = bars.begin(),
it_end = bars.end(); it != it_end; ++it)
{
ProgressBar *const bar = *it;
if (!bar)
continue;
if (bar->isVisible())
{
cnt ++;
onlyBar = bar;
}
}
if (cnt > 1)
onlyBar = nullptr;
for (std::vector <ProgressBar*>::const_iterator it = bars.begin(),
it_end = bars.end(); it != it_end; ++it)
{
ProgressBar *const bar = *it;
if (!bar || bar == onlyBar)
continue;
if (bar->isVisible())
{
mBrowserBox->addRow(strprintf("@@hide bar_%s|%s %s@@",
// TRANSLATORS: popup menu item
bar->getActionEventId().c_str(), _("Hide"),
bar->getId().c_str()));
}
else
{
mBrowserBox->addRow(strprintf("@@show bar_%s|%s %s@@",
// TRANSLATORS: popup menu item
bar->getActionEventId().c_str(), _("Show"),
bar->getId().c_str()));
}
}
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("reset yellow", _("Reset yellow bar"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("bar to chat", _("Copy to chat"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("cancel", _("Cancel"));
showPopup(x, y);
}
void PopupMenu::showAttackMonsterPopup(const int x, const int y,
const std::string &name, const int type)
{
if (!player_node || !actorSpriteManager)
return;
mNick = name;
mType = static_cast<int>(Being::MONSTER);
mX = x;
mY = y;
mBrowserBox->clearRows();
if (name.empty())
{
// TRANSLATORS: popup menu header
mBrowserBox->addRow(_("(default)"));
}
else
{
mBrowserBox->addRow(name);
}
switch (type)
{
case MapItem::ATTACK:
{
const int idx = actorSpriteManager->getAttackMobIndex(name);
const int size = actorSpriteManager->getAttackMobsSize();
if (idx > 0)
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("attack moveup", _("Move up"));
}
if (idx + 1 < size)
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("attack movedown", _("Move down"));
}
break;
}
case MapItem::PRIORITY:
{
const int idx = actorSpriteManager->
getPriorityAttackMobIndex(name);
const int size = actorSpriteManager->getPriorityAttackMobsSize();
if (idx > 0)
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("priority moveup", _("Move up"));
}
if (idx + 1 < size)
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("priority movedown", _("Move down"));
}
break;
}
case MapItem::IGNORE_:
break;
default:
break;
}
// TRANSLATORS: popup menu item
mBrowserBox->addRow("attack remove", _("Remove"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("cancel", _("Cancel"));
showPopup(x, y);
}
void PopupMenu::showPickupItemPopup(const int x, const int y, std::string name)
{
if (!player_node || !actorSpriteManager)
return;
mNick = name;
mType = static_cast<int>(Being::FLOOR_ITEM);
mX = x;
mY = y;
mBrowserBox->clearRows();
if (name.empty())
{
// TRANSLATORS: popup menu header
mBrowserBox->addRow(_("(default)"));
}
else
{
mBrowserBox->addRow(name);
}
// TRANSLATORS: popup menu item
mBrowserBox->addRow("pickup remove", _("Remove"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("cancel", _("Cancel"));
showPopup(x, y);
}
void PopupMenu::showUndressPopup(const int x, const int y,
const Being *const being, Item *const item)
{
if (!being || !item)
return;
mBeingId = being->getId();
mItem = item;
mItemId = item->getId();
mItemColor = item->getColor();
mX = x;
mY = y;
mBrowserBox->clearRows();
// TRANSLATORS: popup menu item
mBrowserBox->addRow("undress item", _("Undress"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("cancel", _("Cancel"));
showPopup(x, y);
}
void PopupMenu::showTextFieldPopup(int x, int y, TextField *const input)
{
mX = x;
mY = y;
mTextField = input;
mBrowserBox->clearRows();
// TRANSLATORS: popup menu item
mBrowserBox->addRow("clipboard copy", _("Copy"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("clipboard paste", _("Paste"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("cancel", _("Cancel"));
showPopup(x, y);
}
void PopupMenu::showLinkPopup(const int x, const int y,
const std::string &link)
{
mX = x;
mY = y;
mNick = link;
mBrowserBox->clearRows();
// TRANSLATORS: popup menu item
mBrowserBox->addRow("open link", _("Open link"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("clipboard link", _("Copy to clipboard"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("cancel", _("Cancel"));
showPopup(x, y);
}
void PopupMenu::showWindowsPopup(const int x, const int y)
{
mX = x;
mY = y;
mBrowserBox->clearRows();
const std::vector<ButtonText*> &names = windowMenu->getButtonTexts();
// TRANSLATORS: popup menu header
mBrowserBox->addRow(_("Show window"));
FOR_EACH (std::vector<ButtonText*>::const_iterator, it, names)
{
const ButtonText *const btn = *it;
if (!btn)
continue;
mBrowserBox->addRow(strprintf("show window_%d", btn->key),
btn->text.c_str());
}
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("cancel", _("Cancel"));
showPopup(x, y);
}
void PopupMenu::showNpcDialogPopup(const int npcId, const int x, const int y)
{
mBeingId = npcId;
mX = x;
mY = y;
mBrowserBox->clearRows();
// TRANSLATORS: popup menu item
mBrowserBox->addRow("npc clipboard", _("Copy to clipboard"));
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("cancel", _("Cancel"));
showPopup(x, y);
}
void PopupMenu::showPopup(int x, int y)
{
const int pad2 = 2 * mPadding;
const int bPad2 = 2 * mBrowserBox->getPadding();
mBrowserBox->setPosition(mPadding, mPadding);
mScrollArea->setPosition(mPadding, mPadding);
// add padding to initial size before draw browserbox
int height = mBrowserBox->getHeight();
if (height + pad2 >= mainGraphics->getHeight())
{
height = mainGraphics->getHeight() - bPad2 - pad2;
mBrowserBox->setWidth(mBrowserBox->getWidth() + bPad2 + 5);
mScrollArea->setWidth(mBrowserBox->getWidth() + pad2 + 10);
setContentSize(mBrowserBox->getWidth() + pad2 + 20,
height + pad2);
}
else
{
mBrowserBox->setWidth(mBrowserBox->getWidth() + bPad2);
mScrollArea->setWidth(mBrowserBox->getWidth() + pad2);
setContentSize(mBrowserBox->getWidth() + pad2,
height + pad2);
}
if (mainGraphics->mWidth < (x + getWidth() + 5))
x = mainGraphics->mWidth - getWidth();
if (mainGraphics->mHeight < (y + getHeight() + 5))
y = mainGraphics->mHeight - getHeight();
mScrollArea->setHeight(height);
setPosition(x, y);
setVisible(true);
requestMoveToTop();
}
void PopupMenu::addPlayerRelation(const std::string &name)
{
switch (player_relations.getRelation(name))
{
case PlayerRelation::NEUTRAL:
// TRANSLATORS: popup menu item
mBrowserBox->addRow("friend", _("Be friend"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("disregard", _("Disregard"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("ignore", _("Ignore"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("blacklist", _("Black list"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("enemy", _("Set as enemy"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("erase", _("Erase"));
break;
case PlayerRelation::FRIEND:
// TRANSLATORS: popup menu item
mBrowserBox->addRow("disregard", _("Disregard"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("ignore", _("Ignore"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("blacklist", _("Black list"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("enemy", _("Set as enemy"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("erase", _("Erase"));
break;
case PlayerRelation::BLACKLISTED:
// TRANSLATORS: popup menu item
mBrowserBox->addRow("unignore", _("Unignore"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("disregard", _("Disregard"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("ignore", _("Ignore"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("enemy", _("Set as enemy"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("erase", _("Erase"));
break;
case PlayerRelation::DISREGARDED:
// TRANSLATORS: popup menu item
mBrowserBox->addRow("unignore", _("Unignore"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("ignore", _("Completely ignore"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("erase", _("Erase"));
break;
case PlayerRelation::IGNORED:
// TRANSLATORS: popup menu item
mBrowserBox->addRow("unignore", _("Unignore"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("erase", _("Erase"));
break;
case PlayerRelation::ENEMY2:
// TRANSLATORS: popup menu item
mBrowserBox->addRow("unignore", _("Unignore"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("disregard", _("Disregard"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("ignore", _("Ignore"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("blacklist", _("Black list"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("erase", _("Erase"));
break;
case PlayerRelation::ERASED:
// TRANSLATORS: popup menu item
mBrowserBox->addRow("unignore", _("Unignore"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("disregard", _("Disregard"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("ignore", _("Completely ignore"));
break;
default:
break;
}
}
void PopupMenu::addFollow()
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("follow", _("Follow"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("imitation", _("Imitation"));
}
void PopupMenu::addBuySell(const Being *const being)
{
if (player_relations.getDefault() & PlayerRelation::TRADE)
{
mBrowserBox->addRow("##3---");
if (being->isAdvanced())
{
if (being->isShopEnabled())
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("buy", _("Buy"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("sell", _("Sell"));
}
}
else
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("buy", _("Buy (?)"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("sell", _("Sell (?)"));
}
}
}
void PopupMenu::addBuySellDefault()
{
if (player_relations.getDefault() & PlayerRelation::TRADE)
{
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("buy", _("Buy (?)"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("sell", _("Sell (?)"));
}
}
void PopupMenu::addParty(const std::string &partyName)
{
if (player_node->isInParty())
{
if (player_node->getParty())
{
if (player_node->getParty()->getName() != partyName)
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("party", _("Invite to party"));
}
else
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("kick party", _("Kick from party"));
}
mBrowserBox->addRow("##3---");
}
}
}
void PopupMenu::addPlayerMisc()
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("items", _("Show Items"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("undress", _("Undress"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("addcomment", _("Add comment"));
}
void PopupMenu::addPickupFilter(const std::string &name)
{
if (actorSpriteManager->isInPickupList(name)
|| actorSpriteManager->isInIgnorePickupList(name))
{
mBrowserBox->addRow("remove pickup",
// TRANSLATORS: popup menu item
_("Remove from pickup list"));
}
else
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("add pickup", _("Add to pickup list"));
mBrowserBox->addRow("add pickup ignore",
// TRANSLATORS: popup menu item
_("Add to ignore list"));
}
}
void PopupMenu::showPopup(const int x, const int y,
gcn::ListModel *const model)
{
if (!model)
return;
mBrowserBox->clearRows();
for (int f = 0, sz = model->getNumberOfElements(); f < sz; f ++)
{
mBrowserBox->addRow(strprintf("dropdown_%d", f),
model->getElementAt(f).c_str());
}
// TRANSLATORS: popup menu item
mBrowserBox->addRow("cancel", _("Cancel"));
showPopup(x, y);
}
void PopupMenu::clear()
{
if (mDialog)
{
mDialog->close();
mDialog = nullptr;
}
mItem = nullptr;
mMapItem = nullptr;
mTab = nullptr;
mSpell = nullptr;
mWindow = nullptr;
mButton = nullptr;
mTextField = nullptr;
}
void PopupMenu::addProtection()
{
if (PlayerInfo::isItemProtected(mItemId))
{
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("unprotect item", _("Unprotect item"));
}
else
{
if (mItemId < SPELL_MIN_ID)
{
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("protect item", _("Protect item"));
}
}
}
void PopupMenu::addUseDrop(const Item *const item, const bool isProtected)
{
if (item->isEquipment())
{
if (item->isEquipped())
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("use", _("Unequip"));
}
else
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("use", _("Equip"));
}
}
else
{
if (!isProtected)
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("use", _("Use"));
}
}
if (!isProtected)
{
mBrowserBox->addRow("##3---");
if (item->getQuantity() > 1)
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("drop", _("Drop..."));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("drop all", _("Drop all"));
}
else
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("drop", _("Drop"));
}
}
if (Net::getInventoryHandler()->canSplit(item))
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("split", _("Split"));
}
}
void PopupMenu::addGmCommands()
{
if (player_node->isGM())
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("gm", _("GM..."));
}
}
void PopupMenu::showGMPopup()
{
mBrowserBox->clearRows();
// TRANSLATORS: popup menu header
mBrowserBox->addRow(_("GM commands"));
if (player_node->isGM())
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("ipcheck", _("Check ip"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("goto", _("Goto"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("recall", _("Recall"));
// TRANSLATORS: popup menu item
mBrowserBox->addRow("revive", _("Revive"));
if (mBeingId)
{
// TRANSLATORS: popup menu item
mBrowserBox->addRow("admin-kick", _("Kick"));
}
}
mBrowserBox->addRow("##3---");
// TRANSLATORS: popup menu item
mBrowserBox->addRow("cancel", _("Cancel"));
showPopup(getX(), getY());
}
RenameListener::RenameListener() :
gcn::ActionListener(),
mMapItemX(0),
mMapItemY(0),
mDialog(nullptr)
{
}
void RenameListener::setMapItem(MapItem *const mapItem)
{
if (mapItem)
{
mMapItemX = mapItem->getX();
mMapItemY = mapItem->getY();
}
else
{
mMapItemX = 0;
mMapItemY = 0;
}
}
void RenameListener::action(const gcn::ActionEvent &event)
{
if (event.getId() == "ok" && viewport && mDialog)
{
Map *const map = viewport->getMap();
if (!map)
return;
SpecialLayer *const sl = map->getSpecialLayer();
MapItem *item = nullptr;
if (sl)
{
item = sl->getTile(mMapItemX, mMapItemY);
if (item)
item->setComment(mDialog->getText());
}
item = map->findPortalXY(mMapItemX, mMapItemY);
if (item)
item->setComment(mDialog->getText());
if (socialWindow)
socialWindow->updatePortalNames();
}
mDialog = nullptr;
}
PlayerListener::PlayerListener() :
ActionListener(),
mNick(),
mDialog(nullptr),
mType(static_cast<int>(Being::UNKNOWN))
{
}
void PlayerListener::action(const gcn::ActionEvent &event)
{
if (event.getId() == "ok" && !mNick.empty() && mDialog)
{
std::string comment = mDialog->getText();
Being *const being = actorSpriteManager->findBeingByName(
mNick, static_cast<ActorSprite::Type>(mType));
if (being)
being->setComment(comment);
Being::saveComment(mNick, comment, mType);
}
mDialog = nullptr;
}