1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-15 20:03:15 +02:00

Resources trade panel

This commit is contained in:
SoundSSGood
2023-11-19 02:05:10 +02:00
parent ae79c5e953
commit 6c828d1be9
3 changed files with 167 additions and 79 deletions

View File

@@ -20,7 +20,7 @@
#include "../../lib/CGeneralTextHandler.h" #include "../../lib/CGeneralTextHandler.h"
#include "../../lib/mapObjects/CGHeroInstance.h" #include "../../lib/mapObjects/CGHeroInstance.h"
CTradeBase::CTradeableItem::CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial) CTradeableItem::CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial)
: CIntObject(LCLICK | HOVER | SHOW_POPUP, pos) : CIntObject(LCLICK | HOVER | SHOW_POPUP, pos)
, type(EType(-1)) // set to invalid, will be corrected in setType , type(EType(-1)) // set to invalid, will be corrected in setType
, id(ID) , id(ID)
@@ -38,7 +38,7 @@ CTradeBase::CTradeableItem::CTradeableItem(Point pos, EType Type, int ID, bool L
} }
} }
void CTradeBase::CTradeableItem::setType(EType newType) void CTradeableItem::setType(EType newType)
{ {
if(type != newType) if(type != newType)
{ {
@@ -57,7 +57,7 @@ void CTradeBase::CTradeableItem::setType(EType newType)
} }
} }
void CTradeBase::CTradeableItem::setID(int newID) void CTradeableItem::setID(int newID)
{ {
if(id != newID) if(id != newID)
{ {
@@ -76,7 +76,7 @@ void CTradeBase::CTradeableItem::setID(int newID)
} }
} }
AnimationPath CTradeBase::CTradeableItem::getFilename() AnimationPath CTradeableItem::getFilename()
{ {
switch(type) switch(type)
{ {
@@ -95,7 +95,7 @@ AnimationPath CTradeBase::CTradeableItem::getFilename()
} }
} }
int CTradeBase::CTradeableItem::getIndex() int CTradeableItem::getIndex()
{ {
if(id < 0) if(id < 0)
return -1; return -1;
@@ -116,7 +116,7 @@ int CTradeBase::CTradeableItem::getIndex()
} }
} }
void CTradeBase::CTradeableItem::showAll(Canvas & to) void CTradeableItem::showAll(Canvas & to)
{ {
Point posToBitmap; Point posToBitmap;
Point posToSubCenter; Point posToSubCenter;
@@ -154,13 +154,13 @@ void CTradeBase::CTradeableItem::showAll(Canvas & to)
to.drawText(pos.topLeft() + posToSubCenter, FONT_SMALL, Colors::WHITE, ETextAlignment::CENTER, subtitle); to.drawText(pos.topLeft() + posToSubCenter, FONT_SMALL, Colors::WHITE, ETextAlignment::CENTER, subtitle);
} }
void CTradeBase::CTradeableItem::clickPressed(const Point& cursorPosition) void CTradeableItem::clickPressed(const Point & cursorPosition)
{ {
if(clickPressedCallback) if(clickPressedCallback)
clickPressedCallback(shared_from_this()); clickPressedCallback(shared_from_this());
} }
void CTradeBase::CTradeableItem::showAllAt(const Point& dstPos, const std::string& customSub, Canvas& to) void CTradeableItem::showAllAt(const Point & dstPos, const std::string & customSub, Canvas & to)
{ {
Rect oldPos = pos; Rect oldPos = pos;
std::string oldSub = subtitle; std::string oldSub = subtitle;
@@ -175,7 +175,7 @@ void CTradeBase::CTradeableItem::showAllAt(const Point& dstPos, const std::strin
subtitle = oldSub; subtitle = oldSub;
} }
void CTradeBase::CTradeableItem::hover(bool on) void CTradeableItem::hover(bool on)
{ {
if(!on) if(!on)
{ {
@@ -198,7 +198,7 @@ void CTradeBase::CTradeableItem::hover(bool on)
} }
} }
void CTradeBase::CTradeableItem::showPopupWindow(const Point& cursorPosition) void CTradeableItem::showPopupWindow(const Point & cursorPosition)
{ {
switch(type) switch(type)
{ {
@@ -214,7 +214,7 @@ void CTradeBase::CTradeableItem::showPopupWindow(const Point& cursorPosition)
} }
} }
std::string CTradeBase::CTradeableItem::getName(int number) const std::string CTradeableItem::getName(int number) const
{ {
switch(type) switch(type)
{ {
@@ -235,7 +235,7 @@ std::string CTradeBase::CTradeableItem::getName(int number) const
return ""; return "";
} }
const CArtifactInstance* CTradeBase::CTradeableItem::getArtInstance() const const CArtifactInstance * CTradeableItem::getArtInstance() const
{ {
switch(type) switch(type)
{ {
@@ -247,7 +247,7 @@ const CArtifactInstance* CTradeBase::CTradeableItem::getArtInstance() const
} }
} }
void CTradeBase::CTradeableItem::setArtInstance(const CArtifactInstance * art) void CTradeableItem::setArtInstance(const CArtifactInstance * art)
{ {
assert(type == ARTIFACT_PLACEHOLDER || type == ARTIFACT_INSTANCE); assert(type == ARTIFACT_PLACEHOLDER || type == ARTIFACT_INSTANCE);
hlp = art; hlp = art;
@@ -257,6 +257,26 @@ void CTradeBase::CTradeableItem::setArtInstance(const CArtifactInstance * art)
setID(-1); setID(-1);
} }
SResourcesPanel::SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updatePanelFunctor updateSubtitles)
: updateSubtitles(updateSubtitles)
{
assert(resourcesForTrade.size() == slotsPos.size());
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
for(const auto & res : resourcesForTrade)
{
slots.emplace_back(std::make_shared<CTradeableItem>(slotsPos[res.num], EType::RESOURCE, res.num, true, res.num));
slots.back()->clickPressedCallback = clickPressedCallback;
slots.back()->pos.w = 69; slots.back()->pos.h = 66;
}
}
void SResourcesPanel::updateSlots()
{
if(updateSubtitles)
updateSubtitles();
}
CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero) CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero)
: market(market) : market(market)
, hero(hero) , hero(hero)

View File

@@ -23,32 +23,31 @@ VCMI_LIB_NAMESPACE_END
class CButton; class CButton;
class CTextBox; class CTextBox;
class CTradeBase enum EType
{ {
public:
enum EType
{
RESOURCE, PLAYER, ARTIFACT_TYPE, CREATURE, CREATURE_PLACEHOLDER, ARTIFACT_PLACEHOLDER, ARTIFACT_INSTANCE RESOURCE, PLAYER, ARTIFACT_TYPE, CREATURE, CREATURE_PLACEHOLDER, ARTIFACT_PLACEHOLDER, ARTIFACT_INSTANCE
}; };
class CTradeableItem : public CIntObject, public std::enable_shared_from_this<CTradeableItem> class CTradeableItem : public CIntObject, public std::enable_shared_from_this<CTradeableItem>
{ {
std::shared_ptr<CAnimImage> image; std::shared_ptr<CAnimImage> image;
AnimationPath getFilename(); AnimationPath getFilename();
int getIndex(); int getIndex();
public: public:
using ClickPressedFunctor = std::function<void(std::shared_ptr<CTradeableItem>)>;
const CArtifactInstance * hlp; //holds ptr to artifact instance id type artifact const CArtifactInstance * hlp; //holds ptr to artifact instance id type artifact
EType type; EType type;
int id; int id;
const int serial; const int serial;
const bool left; const bool left;
std::string subtitle; //empty if default std::string subtitle; //empty if default
std::function<void(std::shared_ptr<CTradeableItem> altarSlot)> clickPressedCallback; ClickPressedFunctor clickPressedCallback;
void setType(EType newType); void setType(EType newType);
void setID(int newID); void setID(int newID);
const CArtifactInstance* getArtInstance() const; const CArtifactInstance * getArtInstance() const;
void setArtInstance(const CArtifactInstance * art); void setArtInstance(const CArtifactInstance * art);
CFunctionList<void()> callback; CFunctionList<void()> callback;
@@ -62,13 +61,41 @@ public:
void clickPressed(const Point & cursorPosition) override; void clickPressed(const Point & cursorPosition) override;
std::string getName(int number = -1) const; std::string getName(int number = -1) const;
CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial); CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial);
}; };
struct SResourcesPanel : public CIntObject
{
using updatePanelFunctor = std::function<void()>;
const std::vector<GameResID> resourcesForTrade =
{
GameResID::WOOD, GameResID::MERCURY, GameResID::ORE,
GameResID::SULFUR, GameResID::CRYSTAL, GameResID::GEMS,
GameResID::GOLD
};
const std::vector<Point> slotsPos =
{
Point(0, 0), Point(83, 0), Point(166, 0),
Point(0, 79), Point(83, 79), Point(166, 79),
Point(83, 158)
};
std::vector<std::shared_ptr<CTradeableItem>> slots;
std::function<void()> updateSubtitles;
SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updatePanelFunctor updateSubtitles);
void updateSlots();
};
class CTradeBase
{
public:
const IMarket * market; const IMarket * market;
const CGHeroInstance * hero; const CGHeroInstance * hero;
//all indexes: 1 = left, 0 = right //all indexes: 1 = left, 0 = right
std::array<std::vector<std::shared_ptr<CTradeableItem>>, 2> items; std::array<std::vector<std::shared_ptr<CTradeableItem>>, 2> items;
std::shared_ptr<SResourcesPanel> resoursesPanelPlayer;
std::shared_ptr<SResourcesPanel> resoursesPanelMarket;
//highlighted items (nullptr if no highlight) //highlighted items (nullptr if no highlight)
std::shared_ptr<CTradeableItem> hLeft; std::shared_ptr<CTradeableItem> hLeft;

View File

@@ -84,6 +84,66 @@ void CTradeWindow::initItems(bool Left)
} }
else else
{ {
if(Left && itemsType[1] == RESOURCE)
{
resoursesPanelPlayer = std::make_shared<SResourcesPanel>(
[this](std::shared_ptr<CTradeableItem> marketSlot) -> void
{
if(hLeft != marketSlot)
hLeft = marketSlot;
else
return;
selectionChanged(true);
},
[this]() -> void
{
for(auto & slot : resoursesPanelPlayer->slots)
slot->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(slot->serial)));
});
resoursesPanelPlayer->moveBy(Point(39, 182));
resoursesPanelPlayer->updateSlots();
return;
}
if(!Left && itemsType[0] == RESOURCE)
{
resoursesPanelMarket = std::make_shared<SResourcesPanel>(
[this](std::shared_ptr<CTradeableItem> marketSlot) -> void
{
if(hRight != marketSlot)
hRight = marketSlot;
else
return;
selectionChanged(false);
initSubs(false);
},
[this]() -> void
{
for(auto & slot : resoursesPanelMarket->slots)
{
if(hLeft) //artifact, creature
{
int h1, h2; //hlp variables for getting offer
market->getOffer(hLeft->id, slot->id, h1, h2, mode);
if(slot->id != hLeft->id || mode != EMarketMode::RESOURCE_RESOURCE) //don't allow exchanging same resources
{
std::ostringstream oss;
oss << h2;
if(h1 != 1)
oss << "/" << h1;
slot->subtitle = oss.str();
}
else
slot->subtitle = CGI->generaltexth->allTexts[164]; // n/a
}
else
slot->subtitle = "";
}
});
resoursesPanelMarket->moveBy(Point(327, 182));
return;
}
std::vector<int> *ids = getItemsIds(Left); std::vector<int> *ids = getItemsIds(Left);
std::vector<Rect> pos; std::vector<Rect> pos;
int amount = -1; int amount = -1;
@@ -185,14 +245,6 @@ void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType typ
switch(type) switch(type)
{ {
case RESOURCE:
dx = 82;
dy = 79;
x = 39;
y = 180;
h = 68;
w = 70;
break;
case PLAYER: case PLAYER:
dx = 83; dx = 83;
dy = 118; dy = 118;
@@ -244,6 +296,15 @@ void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType typ
void CTradeWindow::initSubs(bool Left) void CTradeWindow::initSubs(bool Left)
{ {
if(itemsType[Left] == RESOURCE)
{
if(Left)
resoursesPanelPlayer->updateSlots();
else
resoursesPanelMarket->updateSlots();
return;
}
for(auto item : items[Left]) for(auto item : items[Left])
{ {
if(Left) if(Left)
@@ -253,9 +314,6 @@ void CTradeWindow::initSubs(bool Left)
case CREATURE: case CREATURE:
item->subtitle = std::to_string(hero->getStackCount(SlotID(item->serial))); item->subtitle = std::to_string(hero->getStackCount(SlotID(item->serial)));
break; break;
case RESOURCE:
item->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(item->serial)));
break;
} }
} }
else //right side else //right side
@@ -264,23 +322,6 @@ void CTradeWindow::initSubs(bool Left)
{ {
item->subtitle = CGI->generaltexth->capColors[item->id]; item->subtitle = CGI->generaltexth->capColors[item->id];
} }
else if(hLeft)//artifact, creature
{
int h1, h2; //hlp variables for getting offer
market->getOffer(hLeft->id, item->id, h1, h2, mode);
if(item->id != hLeft->id || mode != EMarketMode::RESOURCE_RESOURCE) //don't allow exchanging same resources
{
std::ostringstream oss;
oss << h2;
if(h1!=1)
oss << "/" << h1;
item->subtitle = oss.str();
}
else
item->subtitle = CGI->generaltexth->allTexts[164]; // n/a
}
else
item->subtitle = "";
} }
} }
} }