1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +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/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)
, type(EType(-1)) // set to invalid, will be corrected in setType
, 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)
{
@@ -57,7 +57,7 @@ void CTradeBase::CTradeableItem::setType(EType newType)
}
}
void CTradeBase::CTradeableItem::setID(int newID)
void CTradeableItem::setID(int newID)
{
if(id != newID)
{
@@ -76,7 +76,7 @@ void CTradeBase::CTradeableItem::setID(int newID)
}
}
AnimationPath CTradeBase::CTradeableItem::getFilename()
AnimationPath CTradeableItem::getFilename()
{
switch(type)
{
@@ -95,7 +95,7 @@ AnimationPath CTradeBase::CTradeableItem::getFilename()
}
}
int CTradeBase::CTradeableItem::getIndex()
int CTradeableItem::getIndex()
{
if(id < 0)
return -1;
@@ -116,7 +116,7 @@ int CTradeBase::CTradeableItem::getIndex()
}
}
void CTradeBase::CTradeableItem::showAll(Canvas & to)
void CTradeableItem::showAll(Canvas & to)
{
Point posToBitmap;
Point posToSubCenter;
@@ -154,13 +154,13 @@ void CTradeBase::CTradeableItem::showAll(Canvas & to)
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)
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;
std::string oldSub = subtitle;
@@ -175,7 +175,7 @@ void CTradeBase::CTradeableItem::showAllAt(const Point& dstPos, const std::strin
subtitle = oldSub;
}
void CTradeBase::CTradeableItem::hover(bool on)
void CTradeableItem::hover(bool 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)
{
@@ -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)
{
@@ -235,7 +235,7 @@ std::string CTradeBase::CTradeableItem::getName(int number) const
return "";
}
const CArtifactInstance* CTradeBase::CTradeableItem::getArtInstance() const
const CArtifactInstance * CTradeableItem::getArtInstance() const
{
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);
hlp = art;
@@ -257,6 +257,26 @@ void CTradeBase::CTradeableItem::setArtInstance(const CArtifactInstance * art)
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)
: market(market)
, hero(hero)

View File

@@ -23,32 +23,31 @@ VCMI_LIB_NAMESPACE_END
class CButton;
class CTextBox;
class CTradeBase
enum EType
{
public:
enum EType
{
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;
AnimationPath getFilename();
int getIndex();
public:
public:
using ClickPressedFunctor = std::function<void(std::shared_ptr<CTradeableItem>)>;
const CArtifactInstance * hlp; //holds ptr to artifact instance id type artifact
EType type;
int id;
const int serial;
const bool left;
std::string subtitle; //empty if default
std::function<void(std::shared_ptr<CTradeableItem> altarSlot)> clickPressedCallback;
ClickPressedFunctor clickPressedCallback;
void setType(EType newType);
void setID(int newID);
const CArtifactInstance* getArtInstance() const;
const CArtifactInstance * getArtInstance() const;
void setArtInstance(const CArtifactInstance * art);
CFunctionList<void()> callback;
@@ -62,13 +61,41 @@ public:
void clickPressed(const Point & cursorPosition) override;
std::string getName(int number = -1) const;
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 CGHeroInstance * hero;
//all indexes: 1 = left, 0 = right
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)
std::shared_ptr<CTradeableItem> hLeft;

View File

@@ -84,6 +84,66 @@ void CTradeWindow::initItems(bool Left)
}
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<Rect> pos;
int amount = -1;
@@ -185,14 +245,6 @@ void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType typ
switch(type)
{
case RESOURCE:
dx = 82;
dy = 79;
x = 39;
y = 180;
h = 68;
w = 70;
break;
case PLAYER:
dx = 83;
dy = 118;
@@ -244,6 +296,15 @@ void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType typ
void CTradeWindow::initSubs(bool Left)
{
if(itemsType[Left] == RESOURCE)
{
if(Left)
resoursesPanelPlayer->updateSlots();
else
resoursesPanelMarket->updateSlots();
return;
}
for(auto item : items[Left])
{
if(Left)
@@ -253,9 +314,6 @@ void CTradeWindow::initSubs(bool Left)
case CREATURE:
item->subtitle = std::to_string(hero->getStackCount(SlotID(item->serial)));
break;
case RESOURCE:
item->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(item->serial)));
break;
}
}
else //right side
@@ -264,23 +322,6 @@ void CTradeWindow::initSubs(bool Left)
{
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 = "";
}
}
}