summaryrefslogtreecommitdiff
path: root/src/gui/windows/equipmentwindow.cpp
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2013-09-30 14:03:48 +0300
committerAndrei Karas <akaras@inbox.ru>2013-09-30 14:03:48 +0300
commit25d77892d72d455f8a89372687db45aefbc61cec (patch)
treede03cb1af09eebf6db853a6585b953884bcca3b2 /src/gui/windows/equipmentwindow.cpp
parent05c22dd1a69fe90da67188c74a6995ee3747e937 (diff)
downloadmv-25d77892d72d455f8a89372687db45aefbc61cec.tar.gz
mv-25d77892d72d455f8a89372687db45aefbc61cec.tar.bz2
mv-25d77892d72d455f8a89372687db45aefbc61cec.tar.xz
mv-25d77892d72d455f8a89372687db45aefbc61cec.zip
move windows classes to windows directory.
Diffstat (limited to 'src/gui/windows/equipmentwindow.cpp')
-rw-r--r--src/gui/windows/equipmentwindow.cpp669
1 files changed, 669 insertions, 0 deletions
diff --git a/src/gui/windows/equipmentwindow.cpp b/src/gui/windows/equipmentwindow.cpp
new file mode 100644
index 000000000..0402115df
--- /dev/null
+++ b/src/gui/windows/equipmentwindow.cpp
@@ -0,0 +1,669 @@
+/*
+ * 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/windows/equipmentwindow.h"
+
+#include "configuration.h"
+#include "dragdrop.h"
+#include "graphicsvertexes.h"
+#include "inventory.h"
+#include "item.h"
+
+#include "being/being.h"
+#include "being/localplayer.h"
+#include "being/playerinfo.h"
+
+#include "gui/itempopup.h"
+#include "gui/viewport.h"
+
+#include "gui/windows/setup.h"
+
+#include "gui/widgets/button.h"
+#include "gui/widgets/playerbox.h"
+
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+
+#include "resources/imageset.h"
+
+#include "utils/dtor.h"
+#include "utils/gettext.h"
+
+#include <guichan/font.hpp>
+
+#include <SDL_mouse.h>
+
+#include "debug.h"
+
+static const int BOX_COUNT = 13;
+
+EquipmentWindow::EquipmentWindow(Equipment *const equipment,
+ Being *const being,
+ const bool foring):
+ // TRANSLATORS: equipment window name
+ Window(_("Equipment"), false, nullptr, "equipment.xml"),
+ gcn::ActionListener(),
+ mEquipment(equipment),
+ mItemPopup(new ItemPopup),
+ mPlayerBox(new PlayerBox("equipment_playerbox.xml",
+ "equipment_selectedplayerbox.xml")),
+ // TRANSLATORS: equipment window button
+ mUnequip(new Button(this, _("Unequip"), "unequip", this)),
+ mSelected(-1),
+ mForing(foring),
+ mImageSet(nullptr),
+ mBeing(being),
+ mBoxes(),
+ mHighlightColor(getThemeColor(Theme::HIGHLIGHT)),
+ mBorderColor(getThemeColor(Theme::BORDER)),
+ mLabelsColor(getThemeColor(Theme::LABEL)),
+ mLabelsColor2(getThemeColor(Theme::LABEL_OUTLINE)),
+ mSlotBackground(),
+ mSlotHighlightedBackground(),
+ mVertexes(new ImageCollection),
+ mItemPadding(getOption("itemPadding")),
+ mBoxSize(getOption("boxSize")),
+ mButtonPadding(getOption("buttonPadding", 5)),
+ mMinX(180),
+ mMinY(345),
+ mMaxX(0),
+ mMaxY(0)
+{
+ if (setupWindow)
+ setupWindow->registerWindowForReset(this);
+
+ if (!mBoxSize)
+ mBoxSize = 36;
+
+ // Control that shows the Player
+ mPlayerBox->setDimension(gcn::Rectangle(50, 80, 74, 168));
+ mPlayerBox->setPlayer(being);
+
+ if (foring)
+ setWindowName("Being equipment");
+ else
+ setWindowName("Equipment");
+
+ setCloseButton(true);
+ setSaveVisible(true);
+ setStickyButtonLock(true);
+
+ mBoxes.reserve(BOX_COUNT);
+ for (int f = 0; f < BOX_COUNT; f ++)
+ mBoxes.push_back(nullptr);
+
+ fillBoxes();
+ recalcSize();
+
+ loadWindowState();
+
+ const gcn::Rectangle &area = getChildrenArea();
+ mUnequip->setPosition(area.width - mUnequip->getWidth() - mButtonPadding,
+ area.height - mUnequip->getHeight() - mButtonPadding);
+ mUnequip->setEnabled(false);
+
+ ImageRect rect;
+ Theme::instance()->loadRect(rect, "equipment_background.xml", "", 0, 1);
+ mSlotBackground = rect.grid[0];
+ mSlotHighlightedBackground = rect.grid[1];
+ add(mPlayerBox);
+ add(mUnequip);
+ enableVisibleSound(true);
+}
+
+EquipmentWindow::~EquipmentWindow()
+{
+ delete mItemPopup;
+ mItemPopup = nullptr;
+ if (this == beingEquipmentWindow)
+ {
+ if (mEquipment)
+ delete mEquipment->getBackend();
+ delete mEquipment;
+ mEquipment = nullptr;
+ }
+ delete_all(mBoxes);
+ mBoxes.clear();
+ if (mImageSet)
+ {
+ mImageSet->decRef();
+ mImageSet = nullptr;
+ }
+ if (mSlotBackground)
+ mSlotBackground->decRef();
+ if (mSlotHighlightedBackground)
+ mSlotHighlightedBackground->decRef();
+ delete mVertexes;
+ mVertexes = nullptr;
+}
+
+void EquipmentWindow::draw(gcn::Graphics *graphics)
+{
+ BLOCK_START("EquipmentWindow::draw")
+ // Draw window graphics
+ Window::draw(graphics);
+ Graphics *const g = static_cast<Graphics*>(graphics);
+
+ int i = 0;
+ gcn::Font *const font = getFont();
+ const int fontHeight = font->getHeight();
+
+ if (openGLMode != RENDER_SAFE_OPENGL)
+ {
+ if (mLastRedraw)
+ {
+ mVertexes->clear();
+ FOR_EACH (std::vector<EquipmentBox*>::const_iterator, it, mBoxes)
+ {
+ const EquipmentBox *const box = *it;
+ if (!box)
+ continue;
+ if (i == mSelected)
+ {
+ g->calcTile(mVertexes, mSlotHighlightedBackground,
+ box->x, box->y);
+ }
+ else
+ {
+ g->calcTile(mVertexes, mSlotBackground, box->x, box->y);
+ }
+ }
+ }
+ g->drawTile(mVertexes);
+ }
+ else
+ {
+ for (std::vector<EquipmentBox*>::const_iterator it = mBoxes.begin(),
+ it_end = mBoxes.end(); it != it_end; ++ it, ++ i)
+ {
+ const EquipmentBox *const box = *it;
+ if (!box)
+ continue;
+ if (i == mSelected)
+ g->drawImage(mSlotHighlightedBackground, box->x, box->y);
+ else
+ g->drawImage(mSlotBackground, box->x, box->y);
+ }
+ }
+
+ if (!mEquipment)
+ {
+ BLOCK_END("EquipmentWindow::draw")
+ return;
+ }
+
+ i = 0;
+ for (std::vector<EquipmentBox*>::const_iterator it = mBoxes.begin(),
+ it_end = mBoxes.end(); it != it_end; ++ it, ++ i)
+ {
+ const EquipmentBox *const box = *it;
+ if (!box)
+ continue;
+ const Item *const item = mEquipment->getEquipment(i);
+ if (item)
+ {
+ // Draw Item.
+ Image *const image = item->getImage();
+ if (image)
+ {
+ image->setAlpha(1.0F); // Ensure the image is drawn
+ // with maximum opacity
+ g->drawImage(image, box->x + mItemPadding,
+ box->y + mItemPadding);
+ if (i == EQUIP_PROJECTILE_SLOT)
+ {
+ g->setColorAll(mLabelsColor, mLabelsColor2);
+ const std::string str = toString(item->getQuantity());
+ font->drawString(g, str,
+ box->x + (mBoxSize - font->getWidth(str)) / 2,
+ box->y - fontHeight);
+ }
+ }
+ }
+ else if (box->image)
+ {
+ g->drawImage(box->image, box->x + mItemPadding,
+ box->y + mItemPadding);
+ }
+ }
+ BLOCK_END("EquipmentWindow::draw")
+}
+
+void EquipmentWindow::action(const gcn::ActionEvent &event)
+{
+ if (!mEquipment)
+ return;
+
+ if (event.getId() == "unequip" && mSelected > -1)
+ {
+ const Item *const item = mEquipment->getEquipment(mSelected);
+ Net::getInventoryHandler()->unequipItem(item);
+ setSelected(-1);
+ }
+}
+
+Item *EquipmentWindow::getItem(const int x, const int y) const
+{
+ if (!mEquipment)
+ return nullptr;
+
+ int i = 0;
+
+ for (std::vector<EquipmentBox*>::const_iterator it = mBoxes.begin(),
+ it_end = mBoxes.end(); it != it_end; ++ it, ++ i)
+ {
+ const EquipmentBox *const box = *it;
+ if (!box)
+ continue;
+ const gcn::Rectangle tRect(box->x, box->y, mBoxSize, mBoxSize);
+
+ if (tRect.isPointInRect(x, y))
+ return mEquipment->getEquipment(i);
+ }
+ return nullptr;
+}
+
+void EquipmentWindow::mousePressed(gcn::MouseEvent& mouseEvent)
+{
+ if (!mEquipment)
+ {
+ Window::mousePressed(mouseEvent);
+ return;
+ }
+
+ const int x = mouseEvent.getX();
+ const int y = mouseEvent.getY();
+
+ if (mouseEvent.getButton() == gcn::MouseEvent::LEFT)
+ {
+ if (mForing)
+ {
+ Window::mousePressed(mouseEvent);
+ return;
+ }
+ // Checks if any of the presses were in the equip boxes.
+ int i = 0;
+
+ bool inBox(false);
+
+ for (std::vector<EquipmentBox*>::const_iterator it = mBoxes.begin(),
+ it_end = mBoxes.end(); it != it_end; ++ it, ++ i)
+ {
+ const EquipmentBox *const box = *it;
+ if (!box)
+ continue;
+ const Item *const item = mEquipment->getEquipment(i);
+ const gcn::Rectangle tRect(box->x, box->y, mBoxSize, mBoxSize);
+
+ if (tRect.isPointInRect(x, y))
+ {
+ inBox = true;
+ if (item)
+ {
+ setSelected(i);
+ dragDrop.dragItem(item, DRAGDROP_SOURCE_EQUIPMENT);
+ return;
+ }
+ }
+ if (inBox)
+ return;
+ }
+ }
+ else if (mouseEvent.getButton() == gcn::MouseEvent::RIGHT)
+ {
+ if (Item *const item = getItem(x, y))
+ {
+ if (mItemPopup)
+ mItemPopup->setVisible(false);
+
+ /* Convert relative to the window coordinates to absolute screen
+ * coordinates.
+ */
+ const int mx = x + getX();
+ const int my = y + getY();
+ if (viewport)
+ {
+ if (mForing)
+ viewport->showUndressPopup(mx, my, mBeing, item);
+ else
+ viewport->showPopup(this, mx, my, item, true);
+ }
+ }
+ }
+ Window::mousePressed(mouseEvent);
+}
+
+void EquipmentWindow::mouseReleased(gcn::MouseEvent &mouseEvent)
+{
+ Window::mouseReleased(mouseEvent);
+ const DragDropSource src = dragDrop.getSource();
+ if (dragDrop.isEmpty() || (src != DRAGDROP_SOURCE_INVENTORY
+ && src != DRAGDROP_SOURCE_EQUIPMENT))
+ {
+ return;
+ }
+ Inventory *const inventory = player_node
+ ? PlayerInfo::getInventory() : nullptr;
+ if (!inventory)
+ return;
+
+ Item *const item = inventory->findItem(dragDrop.getItem(),
+ dragDrop.getItemColor());
+ if (!item)
+ return;
+
+ if (dragDrop.getSource() == DRAGDROP_SOURCE_INVENTORY)
+ {
+ if (item->isEquipment())
+ {
+ if (!item->isEquipped())
+ Net::getInventoryHandler()->equipItem(item);
+ }
+ }
+ else if (dragDrop.getSource() == DRAGDROP_SOURCE_EQUIPMENT)
+ {
+ if (item->isEquipment())
+ {
+ const int x = mouseEvent.getX();
+ const int y = mouseEvent.getY();
+ int i = 0;
+ for (std::vector<EquipmentBox*>::const_iterator
+ it = mBoxes.begin(), it_end = mBoxes.end();
+ it != it_end; ++ it, ++ i)
+ {
+ const EquipmentBox *const box = *it;
+ if (!box)
+ continue;
+ const gcn::Rectangle tRect(box->x, box->y, mBoxSize, mBoxSize);
+
+ if (tRect.isPointInRect(x, y))
+ return;
+ }
+
+ if (item->isEquipped())
+ Net::getInventoryHandler()->unequipItem(item);
+ }
+ }
+ dragDrop.clear();
+ dragDrop.deselect();
+}
+
+// Show ItemTooltip
+void EquipmentWindow::mouseMoved(gcn::MouseEvent &event)
+{
+ Window::mouseMoved(event);
+
+ if (!mItemPopup)
+ return;
+
+ const int x = event.getX();
+ const int y = event.getY();
+
+ const Item *const item = getItem(x, y);
+
+ if (item)
+ {
+ int mouseX, mouseY;
+ SDL_GetMouseState(&mouseX, &mouseY);
+
+ mItemPopup->setItem(item);
+ mItemPopup->position(x + getX(), y + getY());
+ }
+ else
+ {
+ mItemPopup->setVisible(false);
+ }
+}
+
+// Hide ItemTooltip
+void EquipmentWindow::mouseExited(gcn::MouseEvent &event A_UNUSED)
+{
+ if (mItemPopup)
+ mItemPopup->setVisible(false);
+}
+
+void EquipmentWindow::setSelected(const int index)
+{
+ mSelected = index;
+ mRedraw = true;
+ if (mUnequip)
+ mUnequip->setEnabled(mSelected != -1);
+ if (mItemPopup)
+ mItemPopup->setVisible(false);
+}
+
+void EquipmentWindow::setBeing(Being *const being)
+{
+ mPlayerBox->setPlayer(being);
+ mBeing = being;
+ if (mEquipment)
+ delete mEquipment->getBackend();
+ delete mEquipment;
+ if (!being)
+ {
+ mEquipment = nullptr;
+ return;
+ }
+ mEquipment = being->getEquipment();
+}
+
+void EquipmentWindow::updateBeing(Being *const being)
+{
+ if (being == mBeing)
+ setBeing(being);
+}
+
+void EquipmentWindow::resetBeing(const Being *const being)
+{
+ if (being == mBeing)
+ setBeing(nullptr);
+}
+
+void EquipmentWindow::fillBoxes()
+{
+ XML::Document *const doc = new XML::Document(
+ paths.getStringValue("equipmentWindowFile"));
+ const XmlNodePtr root = doc->rootNode();
+ if (!root)
+ {
+ delete doc;
+ fillDefault();
+ return;
+ }
+
+ if (mImageSet)
+ mImageSet->decRef();
+
+ mImageSet = Theme::getImageSetFromTheme(XML::getProperty(
+ root, "image", "equipmentbox.png"), 32, 32);
+
+ for_each_xml_child_node(node, root)
+ {
+ if (xmlNameEqual(node, "playerbox"))
+ loadPlayerBox(node);
+ else if (xmlNameEqual(node, "slot"))
+ loadSlot(node, mImageSet);
+ }
+ delete doc;
+}
+
+void EquipmentWindow::loadPlayerBox(const XmlNodePtr playerBoxNode)
+{
+ mPlayerBox->setDimension(gcn::Rectangle(
+ XML::getProperty(playerBoxNode, "x", 50),
+ XML::getProperty(playerBoxNode, "y", 80),
+ XML::getProperty(playerBoxNode, "width", 74),
+ XML::getProperty(playerBoxNode, "height", 168)));
+}
+
+void EquipmentWindow::loadSlot(const XmlNodePtr slotNode,
+ const ImageSet *const imageset)
+{
+ const int slot = parseSlotName(XML::getProperty(slotNode, "name", ""));
+ if (slot < 0)
+ return;
+
+ const int x = XML::getProperty(slotNode, "x", 0) + getPadding();
+ const int y = XML::getProperty(slotNode, "y", 0) + getTitleBarHeight();
+ const int imageIndex = XML::getProperty(slotNode, "image", -1);
+ Image *image = nullptr;
+
+ if (imageset && imageIndex >= 0 && imageIndex
+ < static_cast<signed>(imageset->size()))
+ {
+ image = imageset->get(imageIndex);
+ }
+
+ if (mBoxes[slot])
+ {
+ EquipmentBox *const box = mBoxes[slot];
+ box->x = x;
+ box->y = y;
+ box->image = image;
+ }
+ else
+ {
+ mBoxes[slot] = new EquipmentBox(x, y, image);
+ }
+ if (x < mMinX)
+ mMinX = x;
+ if (y < mMinY)
+ mMinY = y;
+ if (x + mBoxSize > mMaxX)
+ mMaxX = x + mBoxSize;
+ if (y + mBoxSize > mMaxY)
+ mMaxY = y + mBoxSize;
+}
+
+int EquipmentWindow::parseSlotName(const std::string &name) const
+{
+ int id = -1;
+ if (name == "shoes" || name == "boot" || name == "boots")
+ {
+ id = 4;
+ }
+ else if (name == "bottomclothes" || name == "bottom" || name == "pants")
+ {
+ id = 3;
+ }
+ else if (name == "topclothes" || name == "top"
+ || name == "torso" || name == "body")
+ {
+ id = 0;
+ }
+ else if (name == "misc1" || name == "cape")
+ {
+ id = 5;
+ }
+ else if (name == "misc2" || name == "scarf" || name == "scarfs")
+ {
+ id = 7;
+ }
+ else if (name == "hat" || name == "hats")
+ {
+ id = 2;
+ }
+ else if (name == "wings")
+ {
+ id = 6;
+ }
+ else if (name == "glove" || name == "gloves")
+ {
+ id = 1;
+ }
+ else if (name == "weapon" || name == "weapons")
+ {
+ id = 8;
+ }
+ else if (name == "shield" || name == "shields")
+ {
+ id = 9;
+ }
+ else if (name == "amulet" || name == "amulets")
+ {
+ id = 11;
+ }
+ else if (name == "ring" || name == "rings")
+ {
+ id = 12;
+ }
+ else if (name == "arrow" || name == "arrows" || name == "ammo")
+ {
+ id = 10;
+ }
+
+ return id;
+}
+
+void EquipmentWindow::fillDefault()
+{
+ if (mImageSet)
+ mImageSet->decRef();
+
+ mImageSet = Theme::getImageSetFromTheme(
+ "equipmentbox.png", 32, 32);
+
+ addBox(0, 90, 40, 0); // torso
+ addBox(1, 8, 78, 1); // gloves
+ addBox(2, 70, 0, 2); // hat
+ addBox(3, 50, 253, 3); // pants
+ addBox(4, 90, 253, 4); // boots
+ addBox(5, 8, 213, 5); // FREE
+ addBox(6, 129, 213, 6); // wings
+ addBox(7, 50, 40, 5); // scarf
+ addBox(8, 8, 168, 7); // weapon
+ addBox(9, 129, 168, 8); // shield
+ addBox(10, 129, 78, 9); // ammo
+ addBox(11, 8, 123, 5); // amulet
+ addBox(12, 129, 123, 5); // ring
+}
+
+void EquipmentWindow::addBox(const int idx, int x, int y, const int imageIndex)
+{
+ Image *image = nullptr;
+
+ if (mImageSet && imageIndex >= 0 && imageIndex
+ < static_cast<signed>(mImageSet->size()))
+ {
+ image = mImageSet->get(imageIndex);
+ }
+
+ x += getPadding();
+ y += getTitleBarHeight();
+ mBoxes[idx] = new EquipmentBox(x, y, image);
+
+ if (x < mMinX)
+ mMinX = x;
+ if (y < mMinY)
+ mMinY = y;
+ if (x + mBoxSize > mMaxX)
+ mMaxX = x + mBoxSize;
+ if (y + mBoxSize > mMaxY)
+ mMaxY = y + mBoxSize;
+}
+
+void EquipmentWindow::recalcSize()
+{
+ mMaxX += mMinX;
+ mMaxY += mMinY + mUnequip->getHeight() + mButtonPadding;
+ setDefaultSize(mMaxX, mMaxY, ImageRect::CENTER);
+}