summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThorbjørn Lindeijer <bjorn@lindeijer.nl>2024-08-22 17:58:31 +0200
committerThorbjørn Lindeijer <bjorn@lindeijer.nl>2024-08-25 22:09:32 +0200
commit221d67c4774bf41e6f2f0f73fb6914030e33bdde (patch)
tree6fbb4de64d172c196ed617176d5346dd4d774c49
parent9e313b385bae45a88338a2dbfb008af7a9e38e7a (diff)
downloadmana-221d67c4774bf41e6f2f0f73fb6914030e33bdde.tar.gz
mana-221d67c4774bf41e6f2f0f73fb6914030e33bdde.tar.bz2
mana-221d67c4774bf41e6f2f0f73fb6914030e33bdde.tar.xz
mana-221d67c4774bf41e6f2f0f73fb6914030e33bdde.zip
Fixed initialization of equipment backend
For new characters (and in general, when logging in with a character that had nothing equipped), the equipment backend wasn't being initialized. This resulted in the equipment not being visible in the Equipment window. Fixes #83
-rw-r--r--NEWS1
-rw-r--r--src/equipment.h18
-rw-r--r--src/gui/equipmentwindow.cpp122
-rw-r--r--src/gui/equipmentwindow.h8
-rw-r--r--src/net/inventoryhandler.h3
-rw-r--r--src/net/manaserv/inventoryhandler.cpp22
-rw-r--r--src/net/manaserv/inventoryhandler.h6
-rw-r--r--src/net/tmwa/inventoryhandler.cpp24
-rw-r--r--src/net/tmwa/inventoryhandler.h40
-rw-r--r--src/playerinfo.cpp10
10 files changed, 110 insertions, 144 deletions
diff --git a/NEWS b/NEWS
index bd3be388..33d1130e 100644
--- a/NEWS
+++ b/NEWS
@@ -44,6 +44,7 @@
- Fixed being popup getting stuck under the mouse
- Fixed item links with empty item name to look up name from Item DB
- Fixed spaces getting added to chat every 50 characters
+- Fixed empty Equipment window on freshly created character
- Updated to tmwAthena protocol changes
- Updated to Manaserv protocol changes (specials, guilds, debug mode, skills, text particles)
- CMake: Use GNUInstallDirs and made PKG_DATADIR / PKG_BINDIR paths modifiable
diff --git a/src/equipment.h b/src/equipment.h
index 726f7f5e..d40ca55d 100644
--- a/src/equipment.h
+++ b/src/equipment.h
@@ -29,8 +29,6 @@ class Item;
class Equipment
{
public:
- Equipment() = default;
-
class Backend {
public:
virtual Item *getEquipment(int slotIndex) const = 0;
@@ -46,13 +44,17 @@ class Equipment
{}
};
+ Equipment(Backend *backend)
+ : mBackend(backend)
+ {}
+
/**
* Get equipment at the given slot.
*/
Item *getEquipment(int slotIndex) const
{ return mBackend ? mBackend->getEquipment(slotIndex) : nullptr; }
- const std::string getSlotName(int slotIndex) const
+ std::string getSlotName(int slotIndex) const
{ return mBackend ? mBackend->getSlotName(slotIndex) : std::string(); }
int getSlotNumber() const
@@ -67,16 +69,8 @@ class Equipment
void clear()
{ if (mBackend) mBackend->clear(); }
- /**
- * Set equipment at the given slot.
- */
- void setEquipment(int index, int id, int quantity = 0);
-
- void setBackend(Backend *backend)
- { mBackend = backend; }
-
private:
- Backend *mBackend = nullptr;
+ Backend *mBackend;
};
#endif
diff --git a/src/gui/equipmentwindow.cpp b/src/gui/equipmentwindow.cpp
index e6230aed..e7eeb048 100644
--- a/src/gui/equipmentwindow.cpp
+++ b/src/gui/equipmentwindow.cpp
@@ -76,28 +76,28 @@ EquipmentWindow::EquipmentWindow(Equipment *equipment):
add(playerBox);
add(mUnequip);
+
+ loadEquipBoxes();
}
void EquipmentWindow::loadEquipBoxes()
{
- delete[] mEquipBox;
-
- // Load equipment boxes.
- mBoxesNumber = mEquipment->getSlotNumber();
- mEquipBox = new EquipBox[mBoxesNumber];
+ mBoxes.resize(mEquipment->getSlotNumber());
- for (int i = 0; i < mBoxesNumber; ++i)
+ for (size_t i = 0; i < mBoxes.size(); ++i)
{
+ auto &box = mBoxes[i];
+
Position boxPosition = Net::getInventoryHandler()->getBoxPosition(i);
- mEquipBox[i].posX = boxPosition.x + getPadding();
- mEquipBox[i].posY = boxPosition.y + getTitleBarHeight();
+ box.posX = boxPosition.x + getPadding();
+ box.posY = boxPosition.y + getTitleBarHeight();
const std::string &backgroundFile =
Net::getInventoryHandler()->getBoxBackground(i);
if (!backgroundFile.empty())
{
- mEquipBox[i].backgroundImage =
+ box.backgroundImage =
Theme::instance()->getImageFromTheme(backgroundFile);
}
}
@@ -106,65 +106,63 @@ void EquipmentWindow::loadEquipBoxes()
EquipmentWindow::~EquipmentWindow()
{
delete mItemPopup;
- delete[] mEquipBox;
}
void EquipmentWindow::draw(gcn::Graphics *graphics)
{
- // Draw window graphics
Window::draw(graphics);
-
Window::drawChildren(graphics);
// Draw equipment boxes
auto *g = static_cast<Graphics*>(graphics);
- for (int i = 0; i < mBoxesNumber; i++)
+ for (size_t i = 0; i < mBoxes.size(); i++)
{
+ const auto &box = mBoxes[i];
+
// When there is a background image, draw it centered in the box:
- if (mEquipBox[i].backgroundImage)
+ if (box.backgroundImage)
{
- int posX = mEquipBox[i].posX
- + (BOX_WIDTH - mEquipBox[i].backgroundImage->getWidth()) / 2;
- int posY = mEquipBox[i].posY
- + (BOX_HEIGHT - mEquipBox[i].backgroundImage->getHeight()) / 2;
- g->drawImage(mEquipBox[i].backgroundImage, posX, posY);
+ int posX = box.posX
+ + (BOX_WIDTH - box.backgroundImage->getWidth()) / 2;
+ int posY = box.posY
+ + (BOX_HEIGHT - box.backgroundImage->getHeight()) / 2;
+ g->drawImage(box.backgroundImage, posX, posY);
}
- if (i == mSelected)
+ const gcn::Rectangle tRect(box.posX, box.posY,
+ BOX_WIDTH, BOX_HEIGHT);
+
+ if (static_cast<int>(i) == mSelected)
{
const gcn::Color color = Theme::getThemeColor(Theme::HIGHLIGHT);
// Set color to the highlight color
g->setColor(gcn::Color(color.r, color.g, color.b, getGuiAlpha()));
- g->fillRectangle(gcn::Rectangle(mEquipBox[i].posX,
- mEquipBox[i].posY,
- BOX_WIDTH, BOX_HEIGHT));
+ g->fillRectangle(tRect);
}
- // Set color black
+ // Draw black box border
g->setColor(gcn::Color(0, 0, 0));
- // Draw box border
- g->drawRectangle(gcn::Rectangle(mEquipBox[i].posX, mEquipBox[i].posY,
- BOX_WIDTH, BOX_HEIGHT));
+ g->drawRectangle(tRect);
- Item *item = mEquipment->getEquipment(i);
- if (item)
+ if (Item *item = mEquipment->getEquipment(i))
{
// Draw Item.
Image *image = item->getImage();
// Ensure the image is drawn with maximum opacity
image->setAlpha(1.0f);
g->drawImage(image,
- mEquipBox[i].posX + 2,
- mEquipBox[i].posY + 2);
+ box.posX + 2,
+ box.posY + 2);
+
if (i == TmwAthena::EQUIP_PROJECTILE_SLOT)
{
g->setColor(Theme::getThemeColor(Theme::TEXT));
graphics->drawText(toString(item->getQuantity()),
- mEquipBox[i].posX + (BOX_WIDTH / 2),
- mEquipBox[i].posY - getFont()->getHeight(),
- gcn::Graphics::CENTER);
+ box.posX + (BOX_WIDTH / 2),
+ box.posY - getFont()->getHeight(),
+ gcn::Graphics::CENTER);
}
}
}
@@ -179,30 +177,35 @@ void EquipmentWindow::action(const gcn::ActionEvent &event)
}
}
-Item *EquipmentWindow::getItem(int x, int y) const
+/**
+ * Returns an index of an equipment box at the given position, or -1 if there
+ * is no box.
+ */
+int EquipmentWindow::getBoxIndex(int x, int y) const
{
- for (int i = 0; i < mBoxesNumber; ++i)
+ for (size_t i = 0; i < mBoxes.size(); ++i)
{
- gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY,
- BOX_WIDTH, BOX_HEIGHT);
+ const auto &box = mBoxes[i];
+ const gcn::Rectangle tRect(box.posX, box.posY,
+ BOX_WIDTH, BOX_HEIGHT);
if (tRect.isPointInRect(x, y))
- return mEquipment->getEquipment(i);
+ return i;
}
- return nullptr;
+
+ return -1;
}
-std::string EquipmentWindow::getSlotName(int x, int y) const
+Item *EquipmentWindow::getItem(int x, int y) const
{
- for (int i = 0; i < mBoxesNumber; ++i)
- {
- gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY,
- BOX_WIDTH, BOX_HEIGHT);
+ const int index = getBoxIndex(x, y);
+ return index != -1 ? mEquipment->getEquipment(index) : nullptr;
+}
- if (tRect.isPointInRect(x, y))
- return mEquipment->getSlotName(i);
- }
- return std::string();
+std::string EquipmentWindow::getSlotName(int x, int y) const
+{
+ const int index = getBoxIndex(x, y);
+ return index != -1 ? mEquipment->getSlotName(index) : std::string();
}
void EquipmentWindow::mousePressed(gcn::MouseEvent& mouseEvent)
@@ -213,18 +216,12 @@ void EquipmentWindow::mousePressed(gcn::MouseEvent& mouseEvent)
const int y = mouseEvent.getY();
Item *item = nullptr;
- // Checks if any of the presses were in the equip boxes.
- for (int i = 0; i < mBoxesNumber; ++i)
+ const int index = getBoxIndex(x, y);
+ if (index != -1)
{
- item = mEquipment->getEquipment(i);
- gcn::Rectangle tRect(mEquipBox[i].posX, mEquipBox[i].posY,
- BOX_WIDTH, BOX_HEIGHT);
-
- if (tRect.isPointInRect(x, y) && item)
- {
- setSelected(i);
- break;
- }
+ item = mEquipment->getEquipment(index);
+ if (item)
+ setSelected(index);
}
if (mouseEvent.getButton() == gcn::MouseEvent::RIGHT)
@@ -252,11 +249,8 @@ void EquipmentWindow::mouseMoved(gcn::MouseEvent &event)
{
mItemPopup->setEquipmentText(slotName);
- Item *item = getItem(x, y);
- if (item)
- {
+ if (Item *item = getItem(x, y))
mItemPopup->setItem(item->getInfo());
- }
else
mItemPopup->setNoItem();
diff --git a/src/gui/equipmentwindow.h b/src/gui/equipmentwindow.h
index 19630e0b..1b63c866 100644
--- a/src/gui/equipmentwindow.h
+++ b/src/gui/equipmentwindow.h
@@ -62,7 +62,7 @@ class EquipmentWindow : public Window, public gcn::ActionListener
/**
* Returns the current selected slot or -1 if none.
*/
- int getSelected()
+ int getSelected() const
{ return mSelected; }
protected:
@@ -76,16 +76,16 @@ class EquipmentWindow : public Window, public gcn::ActionListener
Image *backgroundImage = nullptr;
};
- EquipBox *mEquipBox = nullptr; /**< Equipment Boxes. */
+ std::vector<EquipBox> mBoxes; /**< Equipment boxes. */
- int mSelected = -1; /**< Index of selected item. */
+ int mSelected = -1; /**< Index of selected item. */
Equipment *mEquipment;
- int mBoxesNumber = 0; /**< Number of equipment boxes to display */
private:
void mouseExited(gcn::MouseEvent &event) override;
void mouseMoved(gcn::MouseEvent &event) override;
+ int getBoxIndex(int x, int y) const;
Item *getItem(int x, int y) const;
std::string getSlotName(int x, int y) const;
diff --git a/src/net/inventoryhandler.h b/src/net/inventoryhandler.h
index 497a4ecb..8a67a7db 100644
--- a/src/net/inventoryhandler.h
+++ b/src/net/inventoryhandler.h
@@ -22,6 +22,7 @@
#ifndef INVENTORYHANDLER_H
#define INVENTORYHANDLER_H
+#include "equipment.h"
#include "inventory.h"
#include "item.h"
#include "position.h"
@@ -78,6 +79,8 @@ class InventoryHandler
virtual unsigned int getVisibleSlotsNumber() const
{ return 0; }
+ virtual Equipment::Backend *getEquipmentBackend() = 0;
+
virtual Position getBoxPosition(unsigned int slotIndex) const
{
if (slotIndex < (sizeof(fallBackBoxesPosition)
diff --git a/src/net/manaserv/inventoryhandler.cpp b/src/net/manaserv/inventoryhandler.cpp
index 8898db55..ac3e0f5b 100644
--- a/src/net/manaserv/inventoryhandler.cpp
+++ b/src/net/manaserv/inventoryhandler.cpp
@@ -24,8 +24,6 @@
#include "equipment.h"
#include "inventory.h"
#include "item.h"
-#include "itemshortcut.h"
-#include "localplayer.h"
#include "log.h"
#include "playerinfo.h"
@@ -37,8 +35,6 @@
#include "net/manaserv/messageout.h"
#include "net/manaserv/manaserv_protocol.h"
-#include "resources/iteminfo.h"
-
#include "utils/stringutils.h"
#define EQUIP_FILE "equip.xml"
@@ -279,20 +275,20 @@ void EquipBackend::readBoxNode(xmlNodePtr slotNode)
bool EquipBackend::isWeaponSlot(int slotTypeId) const
{
- for (const auto &slot : mSlots)
+ for (const auto &[_, slot] : mSlots)
{
- if (slot.second.slotTypeId == (unsigned)slotTypeId)
- return slot.second.weaponSlot;
+ if (slot.slotTypeId == (unsigned)slotTypeId)
+ return slot.weaponSlot;
}
return false;
}
bool EquipBackend::isAmmoSlot(int slotTypeId) const
{
- for (const auto &slot : mSlots)
+ for (const auto &[_, slot] : mSlots)
{
- if (slot.second.slotTypeId == (unsigned)slotTypeId)
- return slot.second.ammoSlot;
+ if (slot.slotTypeId == (unsigned)slotTypeId)
+ return slot.ammoSlot;
}
return false;
}
@@ -304,7 +300,7 @@ Position EquipBackend::getBoxPosition(unsigned int slotIndex) const
return Position(0, 0);
}
-const std::string& EquipBackend::getBoxBackground(unsigned int slotIndex) const
+const std::string &EquipBackend::getBoxBackground(unsigned int slotIndex) const
{
if (slotIndex < mBoxesBackgroundFile.size())
return mBoxesBackgroundFile.at(slotIndex);
@@ -332,7 +328,6 @@ void InventoryHandler::handleMessage(MessageIn &msg)
case GPMSG_INVENTORY_FULL:
{
PlayerInfo::clearInventory();
- PlayerInfo::getEquipment()->setBackend(&mEquipBackend);
int count = msg.readInt16();
while (count--)
{
@@ -374,9 +369,6 @@ void InventoryHandler::handleMessage(MessageIn &msg)
it->second.mAmountUsed,
it->first);
}
- // The backend is ready, we can setup the equipment window.
- if (equipmentWindow)
- equipmentWindow->loadEquipBoxes();
}
break;
diff --git a/src/net/manaserv/inventoryhandler.h b/src/net/manaserv/inventoryhandler.h
index 452ccf3e..a0e978cd 100644
--- a/src/net/manaserv/inventoryhandler.h
+++ b/src/net/manaserv/inventoryhandler.h
@@ -22,7 +22,6 @@
#ifndef NET_MANASERV_INVENTORYHANDLER_H
#define NET_MANASERV_INVENTORYHANDLER_H
-#include "equipment.h"
#include "eventlistener.h"
#include "net/inventoryhandler.h"
@@ -63,7 +62,7 @@ class EquipBackend final : public Equipment::Backend, public EventListener
Position getBoxPosition(unsigned int slotIndex) const;
- const std::string& getBoxBackground(unsigned int slotIndex) const;
+ const std::string &getBoxBackground(unsigned int slotIndex) const;
private:
void readEquipFile() override;
@@ -133,6 +132,9 @@ class InventoryHandler final : public MessageHandler, Net::InventoryHandler,
unsigned int getVisibleSlotsNumber() const override
{ return mEquipBackend.getVisibleSlotsNumber(); }
+ Equipment::Backend *getEquipmentBackend() override
+ { return &mEquipBackend; }
+
Position getBoxPosition(unsigned int slotIndex) const override
{ return mEquipBackend.getBoxPosition(slotIndex); }
diff --git a/src/net/tmwa/inventoryhandler.cpp b/src/net/tmwa/inventoryhandler.cpp
index 0bc1f9c0..0fd4e933 100644
--- a/src/net/tmwa/inventoryhandler.cpp
+++ b/src/net/tmwa/inventoryhandler.cpp
@@ -30,8 +30,6 @@
#include "localplayer.h"
#include "log.h"
-#include "gui/equipmentwindow.h"
-
#include "net/tmwa/messagein.h"
#include "net/tmwa/messageout.h"
#include "net/tmwa/protocol.h"
@@ -104,9 +102,6 @@ InventoryHandler::InventoryHandler()
handledMessages = _messages;
inventoryHandler = this;
- mStorage = nullptr;
- mStorageWindow = nullptr;
-
listen(Event::ItemChannel);
}
@@ -127,7 +122,6 @@ void InventoryHandler::handleMessage(MessageIn &msg)
int index, amount, itemId, equipType;
int identified, cards[4], itemType;
Inventory *inventory = PlayerInfo::getInventory();
- PlayerInfo::getEquipment()->setBackend(&mEquips);
switch (msg.getId())
{
@@ -172,8 +166,8 @@ void InventoryHandler::handleMessage(MessageIn &msg)
if (msg.getId() == SMSG_PLAYER_INVENTORY)
inventory->setItem(index, itemId, amount);
else
- mInventoryItems.push_back(InventoryItem(index, itemId,
- amount, false));
+ mInventoryItems.push_back(
+ InventoryItem { index, itemId, amount, false });
}
break;
@@ -203,8 +197,8 @@ void InventoryHandler::handleMessage(MessageIn &msg)
cards[0], cards[1], cards[2], cards[3]);
}
- mInventoryItems.push_back(InventoryItem(index, itemId, amount,
- false));
+ mInventoryItems.push_back(
+ InventoryItem { index, itemId, amount, false });
}
break;
@@ -309,10 +303,8 @@ void InventoryHandler::handleMessage(MessageIn &msg)
if (!mStorage)
mStorage = new Inventory(Inventory::STORAGE, size);
- auto it = mInventoryItems.begin();
- auto it_end = mInventoryItems.end();
- for (; it != it_end; it++)
- mStorage->setItem((*it).slot, (*it).id, (*it).quantity);
+ for (auto &item : mInventoryItems)
+ mStorage->setItem(item.slot, item.id, item.quantity);
mInventoryItems.clear();
if (!mStorageWindow)
@@ -385,10 +377,6 @@ void InventoryHandler::handleMessage(MessageIn &msg)
{
mEquips.setEquipment(getSlot(equipType), index);
}
-
- // Load the equipment boxes
- if (equipmentWindow)
- equipmentWindow->loadEquipBoxes();
}
break;
diff --git a/src/net/tmwa/inventoryhandler.h b/src/net/tmwa/inventoryhandler.h
index 2df5a699..51a0fe51 100644
--- a/src/net/tmwa/inventoryhandler.h
+++ b/src/net/tmwa/inventoryhandler.h
@@ -22,7 +22,6 @@
#ifndef NET_TA_INVENTORYHANDLER_H
#define NET_TA_INVENTORYHANDLER_H
-#include "equipment.h"
#include "eventlistener.h"
#include "inventory.h"
#include "log.h"
@@ -128,8 +127,7 @@ class EquipBackend final : public Equipment::Backend
void triggerUnequip(int slotIndex) const override
{
- Item *item = getEquipment(slotIndex);
- if (item)
+ if (Item *item = getEquipment(slotIndex))
item->doEvent(Event::DoUnequip);
}
@@ -143,21 +141,12 @@ class EquipBackend final : public Equipment::Backend
/**
* Used to cache storage data until we get size data for it.
*/
-class InventoryItem
+struct InventoryItem
{
- public:
- int slot;
- int id;
- int quantity;
- bool equip;
-
- InventoryItem(int slot, int id, int quantity, bool equip)
- {
- this->slot = slot;
- this->id = id;
- this->quantity = quantity;
- this->equip = equip;
- }
+ int slot;
+ int id;
+ int quantity;
+ bool equip;
};
class InventoryHandler final : public MessageHandler, public Net::InventoryHandler,
@@ -184,20 +173,25 @@ class InventoryHandler final : public MessageHandler, public Net::InventoryHandl
// Note the slot type id is equal to the slot Index for tA.
bool isWeaponSlot(unsigned int slotTypeId) const override
{
- return (slotTypeId == EQUIP_FIGHT1_SLOT
- || slotTypeId == EQUIP_FIGHT1_SLOT);
+ return (slotTypeId == EQUIP_FIGHT1_SLOT ||
+ slotTypeId == EQUIP_FIGHT1_SLOT);
}
bool isAmmoSlot(unsigned int slotTypeId) const override
{
- return (slotTypeId == EQUIP_PROJECTILE_SLOT);
+ return slotTypeId == EQUIP_PROJECTILE_SLOT;
+ }
+
+ Equipment::Backend *getEquipmentBackend() override
+ {
+ return &mEquips;
}
private:
EquipBackend mEquips;
- std::list<InventoryItem> mInventoryItems;
- Inventory *mStorage;
- InventoryWindow *mStorageWindow;
+ std::vector<InventoryItem> mInventoryItems;
+ Inventory *mStorage = nullptr;
+ InventoryWindow *mStorageWindow = nullptr;
};
} // namespace TmwAthena
diff --git a/src/playerinfo.cpp b/src/playerinfo.cpp
index 433f4f6b..4d5074ee 100644
--- a/src/playerinfo.cpp
+++ b/src/playerinfo.cpp
@@ -27,6 +27,9 @@
#include "eventlistener.h"
#include "log.h"
+#include "net/inventoryhandler.h"
+#include "net/net.h"
+
namespace PlayerInfo {
class PlayerLogic;
@@ -193,11 +196,6 @@ Item *getEquipment(unsigned int slot)
return mEquipment->getEquipment(slot);
}
-void setEquipmentBackend(Equipment::Backend *backend)
-{
- mEquipment->setBackend(backend);
-}
-
int getStorageCount()
{
return mStorageCount;
@@ -351,7 +349,7 @@ public:
if (mInventory == nullptr)
{
mInventory = new Inventory(Inventory::INVENTORY);
- mEquipment = new Equipment();
+ mEquipment = new Equipment(Net::getInventoryHandler()->getEquipmentBackend());
}
}
}