summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2017-08-09 18:47:10 +0300
committerAndrei Karas <akaras@inbox.ru>2017-08-09 18:47:10 +0300
commitb3fa7a53a29a1001935514a38f140af2b816771a (patch)
treea1d9449975a266e64bcc377ca692eb8d04f645e4
parentc0dbb0d20fb321ecf12cdcc22d960b3572e35286 (diff)
downloadmv-b3fa7a53a29a1001935514a38f140af2b816771a.tar.gz
mv-b3fa7a53a29a1001935514a38f140af2b816771a.tar.bz2
mv-b3fa7a53a29a1001935514a38f140af2b816771a.tar.xz
mv-b3fa7a53a29a1001935514a38f140af2b816771a.zip
Allow for each item replace equip/use menu item to custom menu.
Separate menus supproted for inventory, storage, cart.
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/Makefile.am1
-rw-r--r--src/gui/popups/popupmenu.cpp68
-rw-r--r--src/gui/popups/popupmenu.h9
-rw-r--r--src/resources/db/itemdb.cpp103
-rw-r--r--src/resources/iteminfo.cpp3
-rw-r--r--src/resources/iteminfo.h18
-rw-r--r--src/resources/itemmenuitem.h49
8 files changed, 245 insertions, 7 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1c680d668..8eddf51e1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -694,6 +694,7 @@ SET(SRCS
resources/db/languagedb.h
resources/iteminfo.h
resources/iteminfo.cpp
+ resources/itemmenuitem.h
enums/resources/cursor.h
enums/resources/frametype.h
enums/resources/imageposition.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 42342a576..88478e3c5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1449,6 +1449,7 @@ SRC = ${BASE_SRC} \
resources/db/weaponsdb.h \
resources/iteminfo.h \
resources/iteminfo.cpp \
+ resources/itemmenuitem.h \
enums/resources/cursor.h \
enums/resources/frametype.h \
enums/resources/imageposition.h \
diff --git a/src/gui/popups/popupmenu.cpp b/src/gui/popups/popupmenu.cpp
index ba71e8d04..1b9a50c5b 100644
--- a/src/gui/popups/popupmenu.cpp
+++ b/src/gui/popups/popupmenu.cpp
@@ -1660,7 +1660,8 @@ void PopupMenu::showPopup(Window *const parent,
_("Move to craft..."));
}
}
- addUseDrop(item, isProtected);
+ addItemMenu(item, InventoryType::Inventory);
+ addDrop(item, isProtected);
break;
case InventoryType::Storage:
@@ -1688,12 +1689,16 @@ void PopupMenu::showPopup(Window *const parent,
// TRANSLATORS: popup menu item
// TRANSLATORS: get all item amount from storage
_("Retrieve all"));
+ mBrowserBox->addSeparator("##3---");
}
+ addItemMenu(item, InventoryType::Storage);
+ break;
+ case InventoryType::Cart:
+ addItemMenu(item, InventoryType::Cart);
break;
case InventoryType::Trade:
case InventoryType::Npc:
- case InventoryType::Cart:
case InventoryType::Vending:
case InventoryType::Mail:
case InventoryType::Craft:
@@ -1794,7 +1799,8 @@ void PopupMenu::showItemPopup(const int x, const int y,
if (item != nullptr)
{
const bool isProtected = PlayerInfo::isItemProtected(mItemId);
- addUseDrop(item, isProtected);
+ addUse(item);
+ addDrop(item, isProtected);
if (InventoryWindow::isStorageActive())
{
// TRANSLATORS: popup menu item
@@ -1842,7 +1848,8 @@ void PopupMenu::showDropPopup(const int x,
for (int f = 0; f < maxCards; f ++)
mItemCards[f] = item->getCard(f);
const bool isProtected = PlayerInfo::isItemProtected(mItemId);
- addUseDrop(item, isProtected);
+ addUse(item);
+ addDrop(item, isProtected);
if (InventoryWindow::isStorageActive())
{
// TRANSLATORS: popup menu item
@@ -2767,7 +2774,7 @@ void PopupMenu::addProtection()
}
}
-void PopupMenu::addUseDrop(const Item *const item, const bool isProtected)
+void PopupMenu::addUse(const Item *const item)
{
const ItemInfo &info = item->getInfo();
const std::string &str = (item->isEquipment() == Equipm_true
@@ -2784,7 +2791,58 @@ void PopupMenu::addUseDrop(const Item *const item, const bool isProtected)
// TRANSLATORS: popup menu item
mBrowserBox->addRow("/useinv 'INVINDEX'", str.c_str());
}
+}
+
+void PopupMenu::addItemMenu(const Item *const item,
+ const InventoryTypeT type)
+{
+ const ItemInfo &info = item->getInfo();
+ const STD_VECTOR<ItemMenuItem> *menu = nullptr;
+ switch (type)
+ {
+ case InventoryType::Inventory:
+ menu = &info.getInventoryMenuConst();
+ break;
+ case InventoryType::Storage:
+ menu = &info.getStorageMenuConst();
+ break;
+ case InventoryType::Cart:
+ menu = &info.getCartMenuConst();
+ break;
+ case InventoryType::Trade:
+ case InventoryType::Npc:
+ case InventoryType::Vending:
+ case InventoryType::Mail:
+ case InventoryType::Craft:
+ case InventoryType::TypeEnd:
+ default:
+ return;
+ }
+ const bool firstMode = (item->isEquipment() == Equipm_true ?
+ (item->isEquipped() != Equipped_true) :
+ (item->getQuantity() == 1));
+
+ FOR_EACHP (STD_VECTOR<ItemMenuItem>::const_iterator, it, menu)
+ {
+ const ItemMenuItem &menuItem = *it;
+ const std::string &name = firstMode ?
+ menuItem.name1 : menuItem.name2;
+ const std::string &command = firstMode ?
+ menuItem.command1 : menuItem.command2;
+ if (command.empty() ||
+ name.empty())
+ {
+ continue;
+ }
+ mBrowserBox->addRow("/" + command, name.c_str());
+ }
+ mBrowserBox->addSeparator("##3---");
+}
+
+void PopupMenu::addDrop(const Item *const item,
+ const bool isProtected)
+{
if (!isProtected)
{
mBrowserBox->addSeparator("##3---");
diff --git a/src/gui/popups/popupmenu.h b/src/gui/popups/popupmenu.h
index 6d0c141f5..5b554e197 100644
--- a/src/gui/popups/popupmenu.h
+++ b/src/gui/popups/popupmenu.h
@@ -234,8 +234,13 @@ class PopupMenu final : public Popup, public LinkHandler
void addProtection();
- void addUseDrop(const Item *const item,
- const bool isProtected) A_NONNULL(2);
+ void addUse(const Item *const item) A_NONNULL(2);
+
+ void addItemMenu(const Item *const item,
+ const InventoryTypeT type) A_NONNULL(2);
+
+ void addDrop(const Item *const item,
+ const bool isProtected) A_NONNULL(2);
void addGmCommands();
diff --git a/src/resources/db/itemdb.cpp b/src/resources/db/itemdb.cpp
index 6a7ed29eb..93c0e845a 100644
--- a/src/resources/db/itemdb.cpp
+++ b/src/resources/db/itemdb.cpp
@@ -236,6 +236,56 @@ void ItemDB::load()
}
}
+static void loadMenu(XmlNodePtrConst parentNode,
+ STD_VECTOR<ItemMenuItem> &menu)
+{
+ for_each_xml_child_node(node, parentNode)
+ {
+ if (xmlNameEqual(node, "menu"))
+ {
+ const std::string name1 = XML::langProperty(node,
+ "name1", "");
+ const std::string name2 = XML::langProperty(node,
+ "name2", "");
+ const std::string command1 = XML::getProperty(node,
+ "command1", "");
+ const std::string command2 = XML::getProperty(node,
+ "command2", command1);
+ menu.push_back(ItemMenuItem(name1,
+ name2,
+ command1,
+ command2));
+ }
+ }
+}
+
+static bool getIsEquipment(const ItemDbType type)
+{
+ switch (type)
+ {
+ case ItemDbType::EQUIPMENT_ONE_HAND_WEAPON:
+ case ItemDbType::EQUIPMENT_TWO_HANDS_WEAPON:
+ case ItemDbType::EQUIPMENT_TORSO:
+ case ItemDbType::EQUIPMENT_ARMS:
+ case ItemDbType::EQUIPMENT_HEAD:
+ case ItemDbType::EQUIPMENT_LEGS:
+ case ItemDbType::EQUIPMENT_SHIELD:
+ case ItemDbType::EQUIPMENT_RING:
+ case ItemDbType::EQUIPMENT_NECKLACE:
+ case ItemDbType::EQUIPMENT_FEET:
+ case ItemDbType::EQUIPMENT_AMMO:
+ case ItemDbType::EQUIPMENT_CHARM:
+ return true;
+ case ItemDbType::UNUSABLE:
+ case ItemDbType::USABLE:
+ case ItemDbType::CARD:
+ case ItemDbType::SPRITE_RACE:
+ case ItemDbType::SPRITE_HAIR:
+ default:
+ return false;
+ }
+}
+
void ItemDB::loadXmlFile(const std::string &fileName,
int &tagNum,
const SkipError skipError)
@@ -582,6 +632,18 @@ void ItemDB::loadXmlFile(const std::string &fileName,
{
loadOrderSprite(itemInfo, itemChild, false);
}
+ else if (xmlNameEqual(itemChild, "inventory"))
+ {
+ loadMenu(itemChild, itemInfo->getInventoryMenu());
+ }
+ else if (xmlNameEqual(itemChild, "storage"))
+ {
+ loadMenu(itemChild, itemInfo->getStorageMenu());
+ }
+ else if (xmlNameEqual(itemChild, "cart"))
+ {
+ loadMenu(itemChild, itemInfo->getCartMenu());
+ }
}
/*
@@ -643,6 +705,47 @@ void ItemDB::loadXmlFile(const std::string &fileName,
}
}
+ STD_VECTOR<ItemMenuItem> &inventoryMenu = itemInfo->getInventoryMenu();
+
+ if (inventoryMenu.empty())
+ {
+ std::string name1 = itemInfo->getUseButton();
+ std::string name2 = itemInfo->getUseButton2();
+ const bool isEquipment = getIsEquipment(itemInfo->getType());
+
+ if (isEquipment)
+ {
+ if (name1.empty())
+ {
+ // TRANSLATORS: popup menu item
+ name1 = _("Equip");
+ }
+ if (name2.empty())
+ {
+ // TRANSLATORS: popup menu item
+ name2 = _("Unequip");
+ }
+ }
+ else
+ {
+ if (name1.empty())
+ {
+ // TRANSLATORS: popup menu item
+ name1 = _("Use");
+ }
+ if (name2.empty())
+ {
+ // TRANSLATORS: popup menu item
+ name2 = _("Use");
+ }
+ }
+ inventoryMenu.push_back(ItemMenuItem(
+ name1,
+ name2,
+ "useinv 'INVINDEX'",
+ "useinv 'INVINDEX'"));
+ }
+
#define CHECK_PARAM(param) \
if (param.empty()) \
{ \
diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp
index 26cd2dc20..118ce5d71 100644
--- a/src/resources/iteminfo.cpp
+++ b/src/resources/iteminfo.cpp
@@ -63,6 +63,9 @@ ItemInfo::ItemInfo() :
mTags(),
mColorsList(nullptr),
mIconColorsList(nullptr),
+ mInventoryMenu(),
+ mStorageMenu(),
+ mCartMenu(),
mColorsListName(),
mIconColorsListName(),
mCardColor(ItemColor_zero),
diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h
index 92474ff7e..414fa45b8 100644
--- a/src/resources/iteminfo.h
+++ b/src/resources/iteminfo.h
@@ -31,6 +31,7 @@
#include "resources/cursors.h"
#include "resources/itemcolordata.h"
+#include "resources/itemmenuitem.h"
#include "resources/missileinfo.h"
#include "resources/soundinfo.h"
@@ -313,6 +314,20 @@ class ItemInfo final
std::string getIconColorName(const ItemColor idx) const;
std::string getIconColor(const ItemColor idx) const;
+ STD_VECTOR<ItemMenuItem> &getInventoryMenu()
+ { return mInventoryMenu; }
+ STD_VECTOR<ItemMenuItem> &getStorageMenu()
+ { return mStorageMenu; }
+ STD_VECTOR<ItemMenuItem> &getCartMenu()
+ { return mCartMenu; }
+
+ const STD_VECTOR<ItemMenuItem> &getInventoryMenuConst() const A_CONST
+ { return mInventoryMenu; }
+ const STD_VECTOR<ItemMenuItem> &getStorageMenuConst() const A_CONST
+ { return mStorageMenu; }
+ const STD_VECTOR<ItemMenuItem> &getCartMenuConst() const A_CONST
+ { return mCartMenu; }
+
int mDrawBefore[10];
int mDrawAfter[10];
int mDrawPriority[10];
@@ -363,6 +378,9 @@ class ItemInfo final
std::map <int, int> mTags;
const std::map <ItemColor, ItemColorData> *mColorsList;
const std::map <ItemColor, ItemColorData> *mIconColorsList;
+ STD_VECTOR<ItemMenuItem> mInventoryMenu;
+ STD_VECTOR<ItemMenuItem> mStorageMenu;
+ STD_VECTOR<ItemMenuItem> mCartMenu;
std::string mColorsListName;
std::string mIconColorsListName;
ItemColor mCardColor;
diff --git a/src/resources/itemmenuitem.h b/src/resources/itemmenuitem.h
new file mode 100644
index 000000000..0d7dd2950
--- /dev/null
+++ b/src/resources/itemmenuitem.h
@@ -0,0 +1,49 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2012-2017 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/>.
+ */
+
+#ifndef RESOURCES_ITEMMENUITEM_H
+#define RESOURCES_ITEMMENUITEM_H
+
+#include <string>
+
+#include "localconsts.h"
+
+struct ItemMenuItem final
+{
+ ItemMenuItem(const std::string &name01,
+ const std::string &name02,
+ const std::string &command01,
+ const std::string &command02) :
+ name1(name01),
+ name2(name02),
+ command1(command01),
+ command2(command02)
+ {
+ }
+
+ A_DEFAULT_COPY(ItemMenuItem)
+
+ std::string name1;
+ std::string name2;
+ std::string command1;
+ std::string command2;
+};
+
+#endif // RESOURCES_ITEMMENUITEM_H