summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2011-05-22 00:23:08 +0300
committerAndrei Karas <akaras@inbox.ru>2011-05-22 04:19:02 +0300
commit7c34adebb068549ca6a56bdf1b211398a0b1de11 (patch)
tree04a1e1ba87fa2005fc32c2358b2747390d1cd9d0
parent54f8367afe9d30c21bcda057872439199c7dd9c1 (diff)
downloadplus-7c34adebb068549ca6a56bdf1b211398a0b1de11.tar.gz
plus-7c34adebb068549ca6a56bdf1b211398a0b1de11.tar.bz2
plus-7c34adebb068549ca6a56bdf1b211398a0b1de11.tar.xz
plus-7c34adebb068549ca6a56bdf1b211398a0b1de11.zip
Allow show equipment from other players from context menu "show items".
Also allow undress separate items from players locally.
-rw-r--r--src/actorspritemanager.cpp8
-rw-r--r--src/being.cpp80
-rw-r--r--src/being.h28
-rw-r--r--src/game.cpp7
-rw-r--r--src/gui/equipmentwindow.cpp73
-rw-r--r--src/gui/equipmentwindow.h15
-rw-r--r--src/gui/popupmenu.cpp48
-rw-r--r--src/gui/popupmenu.h2
-rw-r--r--src/gui/viewport.cpp5
-rw-r--r--src/gui/viewport.h2
-rw-r--r--src/net/tmwa/inventoryhandler.h6
11 files changed, 256 insertions, 18 deletions
diff --git a/src/actorspritemanager.cpp b/src/actorspritemanager.cpp
index e7c28fd1e..9be75e0db 100644
--- a/src/actorspritemanager.cpp
+++ b/src/actorspritemanager.cpp
@@ -30,6 +30,7 @@
#include "playerrelations.h"
#include "gui/chatwindow.h"
+#include "gui/equipmentwindow.h"
#include "gui/killstats.h"
#include "gui/skilldialog.h"
#include "gui/socialwindow.h"
@@ -578,7 +579,12 @@ void ActorSpriteManager::logic()
it != it_end; ++it)
{
if ((*it) && (*it)->getType() == Being::PLAYER)
- static_cast<Being*>(*it)->addToCache();
+ {
+ Being *being = static_cast<Being*>(*it);
+ being->addToCache();
+ if (beingEquipmentWindow)
+ beingEquipmentWindow->resetBeing(being);
+ }
if (player_node)
{
if (player_node->getTarget() == *it)
diff --git a/src/being.cpp b/src/being.cpp
index 6c0d3d679..df698cf30 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -29,6 +29,7 @@
#include "effectmanager.h"
#include "graphics.h"
#include "guild.h"
+#include "item.h"
#include "localplayer.h"
#include "log.h"
#include "map.h"
@@ -43,6 +44,7 @@
#include "gui/buydialog.h"
#include "gui/buyselldialog.h"
+#include "gui/equipmentwindow.h"
#include "gui/gui.h"
#include "gui/npcdialog.h"
#include "gui/npcpostdialog.h"
@@ -55,6 +57,7 @@
#include "net/charhandler.h"
#include "net/gamehandler.h"
+#include "net/inventoryhandler.h"
#include "net/net.h"
#include "net/npchandler.h"
#include "net/playerhandler.h"
@@ -1574,6 +1577,9 @@ void Being::setSprite(unsigned int slot, int id, std::string color,
if (slot >= mSpriteColors.size())
mSpriteColors.resize(slot + 1, "");
+ if (slot >= mSpriteColorsIds.size())
+ mSpriteColorsIds.resize(slot + 1, 1);
+
// id = 0 means unequip
if (id == 0)
{
@@ -1613,7 +1619,10 @@ void Being::setSprite(unsigned int slot, int id, std::string color,
{
mSpriteIDs[slot] = id;
mSpriteColors[slot] = color;
+ mSpriteColorsIds[slot] = colorId;
recalcSpritesOrder();
+ if (beingEquipmentWindow)
+ beingEquipmentWindow->updateBeing(this);
}
}
@@ -2179,4 +2188,73 @@ void Being::updateHit(int amount)
if (amount != mCriticalHit && (!mMaxHit || amount > mMaxHit))
mMaxHit = amount;
}
-} \ No newline at end of file
+}
+
+Equipment *Being::getEquipment()
+{
+ Equipment *eq = new Equipment();
+ Equipment::Backend *bk = new BeingEquipBackend(this);
+ eq->setBackend(bk);
+ return eq;
+}
+
+void Being::undressItemById(int id)
+{
+ int sz = mSpriteIDs.size();
+
+ for (int f = 0; f < sz; f ++)
+ {
+ if (id == mSpriteIDs[f])
+ {
+ setSprite(f, 0);
+ break;
+ }
+ }
+}
+
+BeingEquipBackend::BeingEquipBackend(Being *being):
+ mBeing(being)
+{
+ memset(mEquipment, 0, sizeof(mEquipment));
+ if (being)
+ {
+ int sz = being->mSpriteIDs.size();
+
+ for (int f = 0; f < sz; f ++)
+ {
+ int idx = Net::getInventoryHandler()->convertFromServerSlot(f);
+ int id = being->mSpriteIDs[f];
+ if (id > 0 && idx >= 0 && idx < EQUIPMENT_SIZE)
+ {
+ mEquipment[idx] = new Item(id, 1, 0,
+ being->mSpriteColorsIds[f], true, true);
+ }
+ }
+ }
+}
+
+BeingEquipBackend::~BeingEquipBackend()
+{
+ clear();
+}
+
+void BeingEquipBackend::clear()
+{
+ for (int i = 0; i < EQUIPMENT_SIZE; i++)
+ {
+ delete mEquipment[i];
+ mEquipment[i] = 0;
+ }
+}
+
+void BeingEquipBackend::setEquipment(int index, Item *item)
+{
+ mEquipment[index] = item;
+}
+
+Item *BeingEquipBackend::getEquipment(int index) const
+{
+ if (index < 0 || index >= EQUIPMENT_SIZE)
+ return 0;
+ return mEquipment[index];
+}
diff --git a/src/being.h b/src/being.h
index 199cb4dc2..91cafa69a 100644
--- a/src/being.h
+++ b/src/being.h
@@ -31,6 +31,7 @@
#include "actorsprite.h"
#include "configlistener.h"
+#include "equipment.h"
#include "map.h"
#include "particlecontainer.h"
#include "position.h"
@@ -53,9 +54,11 @@
class AnimatedSprite;
class BeingCacheEntry;
+class Being;
class BeingInfo;
class FlashText;
class Guild;
+class Inventory;
class ItemInfo;
class Item;
class Particle;
@@ -74,9 +77,29 @@ enum Gender
GENDER_UNSPECIFIED = 2
};
+class BeingEquipBackend : public Equipment::Backend
+{
+ public:
+ BeingEquipBackend(Being *being);
+
+ virtual ~BeingEquipBackend();
+
+ Item *getEquipment(int index) const;
+
+ void clear();
+
+ void setEquipment(int index, Item *item);
+
+ private:
+ Item *mEquipment[EQUIPMENT_SIZE];
+ Being *mBeing;
+};
+
class Being : public ActorSprite, public ConfigListener
{
public:
+ friend class BeingEquipBackend;
+
/**
* Action the being is currently performing
* WARNING: Has to be in sync with the same enum in the Being class
@@ -687,6 +710,10 @@ class Being : public ActorSprite, public ConfigListener
void updateHit(int amount);
+ Equipment *getEquipment();
+
+ void undressItemById(int id);
+
protected:
/**
* Sets the new path for this being.
@@ -747,6 +774,7 @@ class Being : public ActorSprite, public ConfigListener
std::vector<int> mSpriteIDs;
std::vector<std::string> mSpriteColors;
+ std::vector<int> mSpriteColorsIds;
Gender mGender;
// Character guild information
diff --git a/src/game.cpp b/src/game.cpp
index 999a89664..82a77c0bb 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -126,6 +126,7 @@ ShopWindow *shopWindow = NULL;
SkillDialog *skillDialog = NULL;
Minimap *minimap = NULL;
EquipmentWindow *equipmentWindow = NULL;
+EquipmentWindow *beingEquipmentWindow = NULL;
TradeWindow *tradeWindow = NULL;
HelpWindow *helpWindow = NULL;
DebugWindow *debugWindow = NULL;
@@ -189,7 +190,10 @@ static void createGuiWindows()
// Create dialogs
chatWindow = new ChatWindow;
tradeWindow = new TradeWindow;
- equipmentWindow = new EquipmentWindow(PlayerInfo::getEquipment());
+ equipmentWindow = new EquipmentWindow(PlayerInfo::getEquipment(),
+ player_node);
+ beingEquipmentWindow = new EquipmentWindow(0, 0, true);
+ beingEquipmentWindow->setVisible(false);
statusWindow = new StatusWindow;
miniStatusWindow = new MiniStatusWindow;
inventoryWindow = new InventoryWindow(PlayerInfo::getInventory());
@@ -292,6 +296,7 @@ static void destroyGuiWindows()
del_0(skillDialog)
del_0(minimap)
del_0(equipmentWindow)
+ del_0(beingEquipmentWindow)
del_0(tradeWindow)
del_0(helpWindow)
del_0(debugWindow)
diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp
index d5bfa4ddc..2a0ad96bb 100644
--- a/src/gui/equipmentwindow.cpp
+++ b/src/gui/equipmentwindow.cpp
@@ -20,15 +20,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "gui/equipmentwindow.h"
+
#include "gui/widgets/button.h"
+#include "being.h"
#include "equipment.h"
#include "graphics.h"
#include "inventory.h"
#include "item.h"
#include "localplayer.h"
-#include "gui/equipmentwindow.h"
#include "gui/itempopup.h"
#include "gui/theme.h"
#include "gui/setup.h"
@@ -69,21 +71,28 @@ static const int boxPosition[][2] =
{ 129, 123 }, // EQUIP_EVOL_RING2_SLOT
};
-EquipmentWindow::EquipmentWindow(Equipment *equipment):
+EquipmentWindow::EquipmentWindow(Equipment *equipment, Being *being,
+ bool foring):
Window(_("Equipment")),
mEquipment(equipment),
- mSelected(-1)
+ mSelected(-1),
+ mForing(foring)
{
+ mBeing = being;
mItemPopup = new ItemPopup;
if (setupWindow)
setupWindow->registerWindowForReset(this);
// Control that shows the Player
- PlayerBox *playerBox = new PlayerBox;
- playerBox->setDimension(gcn::Rectangle(50, 80, 74, 168));
- playerBox->setPlayer(player_node);
+ mPlayerBox = new PlayerBox;
+ mPlayerBox->setDimension(gcn::Rectangle(50, 80, 74, 168));
+ mPlayerBox->setPlayer(being);
+
+ if (foring)
+ setWindowName("Being equipment");
+ else
+ setWindowName("Equipment");
- setWindowName("Equipment");
setCloseButton(true);
setSaveVisible(true);
setDefaultSize(180, 345, ImageRect::CENTER);
@@ -95,7 +104,7 @@ EquipmentWindow::EquipmentWindow(Equipment *equipment):
area.height - mUnequip->getHeight() - 5);
mUnequip->setEnabled(false);
- add(playerBox);
+ add(mPlayerBox);
add(mUnequip);
for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
@@ -138,6 +147,9 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
g->drawRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY,
BOX_WIDTH, BOX_HEIGHT));
+ if (!mEquipment)
+ continue;
+
Item *item = mEquipment->getEquipment(i);
if (item)
{
@@ -165,6 +177,9 @@ void EquipmentWindow::draw(gcn::Graphics *graphics)
void EquipmentWindow::action(const gcn::ActionEvent &event)
{
+ if (!mEquipment)
+ return;
+
if (event.getId() == "unequip" && mSelected > -1)
{
Item *item = mEquipment->getEquipment(mSelected);
@@ -175,6 +190,9 @@ void EquipmentWindow::action(const gcn::ActionEvent &event)
Item *EquipmentWindow::getItem(int x, int y) const
{
+ if (!mEquipment)
+ return 0;
+
for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
{
gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY,
@@ -190,11 +208,16 @@ void EquipmentWindow::mousePressed(gcn::MouseEvent& mouseEvent)
{
Window::mousePressed(mouseEvent);
+ if (!mEquipment)
+ return;
+
const int x = mouseEvent.getX();
const int y = mouseEvent.getY();
if (mouseEvent.getButton() == gcn::MouseEvent::LEFT)
{
+ if (mForing)
+ return;
// Checks if any of the presses were in the equip boxes.
for (int i = 0; i < Equipment::EQUIP_VECTOREND; i++)
{
@@ -216,7 +239,12 @@ void EquipmentWindow::mousePressed(gcn::MouseEvent& mouseEvent)
const int mx = x + getX();
const int my = y + getY();
if (viewport)
- viewport->showPopup(this, mx, my, item, true);
+ {
+ if (mForing)
+ viewport->showUndressPopup(mx, my, mBeing, item);
+ else
+ viewport->showPopup(this, mx, my, item, true);
+ }
}
}
}
@@ -259,3 +287,30 @@ void EquipmentWindow::setSelected(int index)
if (mUnequip)
mUnequip->setEnabled(mSelected != -1);
}
+
+void EquipmentWindow::setBeing(Being *being)
+{
+ mPlayerBox->setPlayer(being);
+ mBeing = being;
+ if (!being)
+ {
+ delete mEquipment;
+ mEquipment = 0;
+ return;
+ }
+ mEquipment = being->getEquipment();
+ if (!mEquipment)
+ return;
+}
+
+void EquipmentWindow::updateBeing(Being *being)
+{
+ if (being == mBeing)
+ setBeing(being);
+}
+
+void EquipmentWindow::resetBeing(Being *being)
+{
+ if (being == mBeing)
+ setBeing(0);
+}
diff --git a/src/gui/equipmentwindow.h b/src/gui/equipmentwindow.h
index ccb0332df..75118707d 100644
--- a/src/gui/equipmentwindow.h
+++ b/src/gui/equipmentwindow.h
@@ -36,9 +36,11 @@
#define _UNUSED_
#endif
+class Being;
class Inventory;
class Item;
class ItemPopup;
+class PlayerBox;
/**
* Equipment dialog.
@@ -51,7 +53,8 @@ class EquipmentWindow : public Window, public gcn::ActionListener
/**
* Constructor.
*/
- EquipmentWindow(Equipment *equipment);
+ EquipmentWindow(Equipment *equipment, Being *being,
+ bool mCloseOnHide = false);
/**
* Destructor.
@@ -70,6 +73,12 @@ class EquipmentWindow : public Window, public gcn::ActionListener
Item* getEquipment(int i)
{ return mEquipment ? mEquipment->getEquipment(i) : 0; }
+ void setBeing(Being *being);
+
+ void updateBeing(Being *being);
+
+ void resetBeing(Being *being);
+
private:
void mouseExited(gcn::MouseEvent &event);
void mouseMoved(gcn::MouseEvent &event);
@@ -92,11 +101,15 @@ class EquipmentWindow : public Window, public gcn::ActionListener
EquipBox mEquipBox[Equipment::EQUIP_VECTOREND]; /**<Equipment Boxes. */
ItemPopup *mItemPopup;
+ PlayerBox *mPlayerBox;
gcn::Button *mUnequip;
int mSelected; /**< Index of selected item. */
+ bool mForing;
+ Being *mBeing;
};
extern EquipmentWindow *equipmentWindow;
+extern EquipmentWindow *beingEquipmentWindow;
#endif
diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp
index 9577d6107..7063d9ce4 100644
--- a/src/gui/popupmenu.cpp
+++ b/src/gui/popupmenu.cpp
@@ -40,6 +40,7 @@
#include "gui/buydialog.h"
#include "gui/chatwindow.h"
+#include "gui/equipmentwindow.h"
#include "gui/inventorywindow.h"
#include "gui/itemamountwindow.h"
#include "gui/ministatus.h"
@@ -233,6 +234,8 @@ void PopupMenu::showPopup(int x, int y, Being *being)
}
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")));
if (player_relations.getDefault() & PlayerRelation::TRADE)
@@ -633,6 +636,7 @@ void PopupMenu::showChatPopup(int x, int y, ChatTab *tab)
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")));
if (player_relations.getDefault() & PlayerRelation::TRADE)
@@ -1380,7 +1384,29 @@ void PopupMenu::handleLink(const std::string &link,
}
else if (link == "reset yellow")
{
- player_node->resetYellowBar();
+ if (player_node)
+ player_node->resetYellowBar();
+ }
+ else if (link == "items" && being)
+ {
+ if (being == player_node)
+ {
+ if (equipmentWindow && !equipmentWindow->isVisible())
+ equipmentWindow->setVisible(true);
+ }
+ else
+ {
+ Equipment *eq = being->getEquipment();
+ if (eq && beingEquipmentWindow)
+ {
+ beingEquipmentWindow->setBeing(being);
+ beingEquipmentWindow->setVisible(true);
+ }
+ }
+ }
+ else if (link == "undress item" && being && mItemId)
+ {
+ being->undressItemById(mItemId);
}
else if (link == "guild-pos" && !mNick.empty())
{
@@ -1788,6 +1814,26 @@ void PopupMenu::showAttackMonsterPopup(int x, int y, std::string name,
showPopup(x, y);
}
+void PopupMenu::showUndressPopup(int x, int y, Being *being, Item *item)
+{
+ if (!being || !item)
+ return;
+
+ mBeingId = being->getId();
+ mItem = item;
+ mItemId = item->getId();
+
+ mBrowserBox->clearRows();
+
+ mBrowserBox->addRow(strprintf("@@undress item|%s@@", _("Undress")));
+
+ mBrowserBox->addRow("##3---");
+ mBrowserBox->addRow(strprintf("@@cancel|%s@@", _("Cancel")));
+
+ showPopup(x, y);
+
+}
+
void PopupMenu::showPopup(int x, int y)
{
setContentSize(mBrowserBox->getWidth() + 8, mBrowserBox->getHeight() + 8);
diff --git a/src/gui/popupmenu.h b/src/gui/popupmenu.h
index 208652083..e16a9fb4f 100644
--- a/src/gui/popupmenu.h
+++ b/src/gui/popupmenu.h
@@ -120,6 +120,8 @@ class PopupMenu : public Popup, public LinkHandler
void showAttackMonsterPopup(int x, int y, std::string name,
int type);
+ void showUndressPopup(int x, int y, Being *being, Item *item);
+
/**
* Shows the related popup menu when right click on the chat
* at the specified mouse coordinates.
diff --git a/src/gui/viewport.cpp b/src/gui/viewport.cpp
index 1f2d06894..09fc7d24c 100644
--- a/src/gui/viewport.cpp
+++ b/src/gui/viewport.cpp
@@ -649,6 +649,11 @@ void Viewport::showAttackMonsterPopup(std::string name, int type)
name, type);
}
+void Viewport::showUndressPopup(int x, int y, Being *being, Item *item)
+{
+ mPopupMenu->showUndressPopup(x, y, being, item);
+}
+
void Viewport::closePopupMenu()
{
if (mPopupMenu)
diff --git a/src/gui/viewport.h b/src/gui/viewport.h
index d3a3bfe4b..7cd12365b 100644
--- a/src/gui/viewport.h
+++ b/src/gui/viewport.h
@@ -173,6 +173,8 @@ class Viewport : public WindowContainer, public gcn::MouseListener,
*/
void showChatPopup(ChatTab *tab);
+ void showUndressPopup(int x, int y, Being *being, Item *item);
+
/**
* Closes the popup menu. Needed for when the player dies or switching
* maps.
diff --git a/src/net/tmwa/inventoryhandler.h b/src/net/tmwa/inventoryhandler.h
index 5f674eab0..c6c680b13 100644
--- a/src/net/tmwa/inventoryhandler.h
+++ b/src/net/tmwa/inventoryhandler.h
@@ -25,6 +25,7 @@
#include "equipment.h"
#include "inventory.h"
+#include "log.h"
#include "playerinfo.h"
#include "gui/inventorywindow.h"
@@ -58,9 +59,8 @@ class EquipBackend : public Equipment::Backend
{
int invyIndex = mEquipment[index];
if (invyIndex == -1)
- {
return NULL;
- }
+
return PlayerInfo::getInventory()->getItem(invyIndex);
}
@@ -72,9 +72,7 @@ class EquipBackend : public Equipment::Backend
{
Item* item = PlayerInfo::getInventory()->getItem(i);
if (item)
- {
item->setEquipped(false);
- }
}
mEquipment[i] = -1;