1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-13 19:54:17 +02:00

Artifacts trade panel

This commit is contained in:
SoundSSGood
2023-11-20 00:37:43 +02:00
parent b246e24811
commit f043c417a1
3 changed files with 125 additions and 65 deletions

View File

@@ -258,8 +258,32 @@ void CTradeableItem::setArtInstance(const CArtifactInstance * art)
setID(-1);
}
SResourcesPanel::SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updatePanelFunctor updateSubtitles)
: updateSubtitles(updateSubtitles)
void STradePanel::updateSlots()
{
if(updateSlotsCallback)
updateSlotsCallback();
}
void STradePanel::deselect()
{
for(auto & slot : slots)
slot->selection->selectSlot(false);
}
void STradePanel::clearSubtitles()
{
for(auto & slot : slots)
slot->subtitle.clear();
}
void STradePanel::updateOffer(int slotIdx, int cost, int qty)
{
slots[slotIdx]->subtitle = std::to_string(qty);
if(cost != 1)
slots[slotIdx]->subtitle += "/" + std::to_string(cost);
}
SResourcesPanel::SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updateSlotsFunctor updateSubtitles)
{
assert(resourcesForTrade.size() == slotsPos.size());
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
@@ -271,18 +295,26 @@ SResourcesPanel::SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPresse
slots.back()->pos.w = 69; slots.back()->pos.h = 66;
slots.back()->selection = std::make_unique<SelectableSlot>(Rect(slotsPos[res.num], slots.back()->pos.dimensions()));
}
updateSlotsCallback = updateSubtitles;
}
void SResourcesPanel::updateSlots()
SArtifactsPanel::SArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updateSlotsFunctor updateSubtitles,
std::vector<TradeItemBuy> & arts)
{
if(updateSubtitles)
updateSubtitles();
}
assert(artifactsForTrade == slotsPos.size());
assert(artifactsForTrade == arts.size());
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
void SResourcesPanel::deselect()
{
slots.resize(artifactsForTrade);
int slotNum = 0;
for(auto & slot : slots)
slot->selection->selectSlot(false);
{
slot = std::make_shared<CTradeableItem>(slotsPos[slotNum], EType::ARTIFACT_TYPE, arts[slotNum].getNum(), false, slotNum);
slot->clickPressedCallback = clickPressedCallback;
slot->pos.w = slot->pos.h = 44;
slot->selection = std::make_unique<SelectableSlot>(Rect(slotsPos[slotNum++], slot->pos.dimensions()));
}
updateSlotsCallback = updateSubtitles;
}
CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero)

View File

@@ -11,7 +11,8 @@
#include "Images.h"
#include "../../lib/FunctionList.h"
#include "../lib/FunctionList.h"
#include "../lib/networkPacks/TradeItem.h"
VCMI_LIB_NAMESPACE_BEGIN
@@ -64,10 +65,22 @@ public:
CTradeableItem(Point pos, EType Type, int ID, bool Left, int Serial);
};
struct SResourcesPanel : public CIntObject
struct STradePanel : public CIntObject
{
using updatePanelFunctor = std::function<void()>;
using updateSlotsFunctor = std::function<void()>;
std::vector<std::shared_ptr<CTradeableItem>> slots;
std::function<void()> updateSlotsCallback;
std::shared_ptr<CTradeableItem> selected;
virtual void updateSlots();
virtual void deselect();
virtual void clearSubtitles();
void updateOffer(int slotIdx, int, int);
};
struct SResourcesPanel : public STradePanel
{
const std::vector<GameResID> resourcesForTrade =
{
GameResID::WOOD, GameResID::MERCURY, GameResID::ORE,
@@ -80,12 +93,22 @@ struct SResourcesPanel : public CIntObject
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();
void deselect();
SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updateSlotsFunctor updateSubtitles);
};
struct SArtifactsPanel : public STradePanel
{
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)
};
const size_t artifactsForTrade = 7;
SArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updateSlotsFunctor updateSubtitles,
std::vector<TradeItemBuy> & arts);
};
class CTradeBase
@@ -96,8 +119,7 @@ public:
//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;
std::vector<std::shared_ptr<STradePanel>> tradePanels;
//highlighted items (nullptr if no highlight)
std::shared_ptr<CTradeableItem> hLeft;

View File

@@ -86,7 +86,7 @@ void CTradeWindow::initItems(bool Left)
{
if(Left && itemsType[1] == RESOURCE)
{
resoursesPanelPlayer = std::make_shared<SResourcesPanel>(
tradePanels.emplace_back(std::make_shared<SResourcesPanel>(
[this](std::shared_ptr<CTradeableItem> marketSlot) -> void
{
if(hLeft != marketSlot)
@@ -97,19 +97,19 @@ void CTradeWindow::initItems(bool Left)
hLeft->selection->selectSlot(true);
selectionChanged(true);
}
},
},
[this]() -> void
{
for(auto & slot : resoursesPanelPlayer->slots)
for(auto & slot : tradePanels[1]->slots)
slot->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(slot->serial)));
});
resoursesPanelPlayer->moveBy(Point(39, 182));
resoursesPanelPlayer->updateSlots();
}));
tradePanels.back()->moveBy(Point(39, 182));
tradePanels.back()->updateSlots();
return;
}
if(!Left && itemsType[0] == RESOURCE)
{
resoursesPanelMarket = std::make_shared<SResourcesPanel>(
tradePanels.emplace_back(std::make_shared<SResourcesPanel>(
[this](std::shared_ptr<CTradeableItem> marketSlot) -> void
{
if(hRight != marketSlot)
@@ -124,31 +124,53 @@ void CTradeWindow::initItems(bool Left)
},
[this]() -> void
{
for(auto & slot : resoursesPanelMarket->slots)
{
if(hLeft) //artifact, creature
if(hLeft)
for(auto & slot : tradePanels[0]->slots)
{
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();
}
market->getOffer(hLeft->id, slot->id, h1, h2, EMarketMode::RESOURCE_RESOURCE);
if(slot->id != hLeft->id)
tradePanels[0]->updateOffer(slot->serial, h1, h2);
else
slot->subtitle = CGI->generaltexth->allTexts[164]; // n/a
}
else
slot->subtitle = "";
}
});
resoursesPanelMarket->moveBy(Point(327, 182));
else
tradePanels[0]->clearSubtitles();
}));
tradePanels.back()->moveBy(Point(327, 182));
return;
}
if(!Left && itemsType[0] == ARTIFACT_TYPE)
{
tradePanels.emplace_back(std::make_shared<SArtifactsPanel>(
[this](std::shared_ptr<CTradeableItem> marketSlot) -> void
{
if(hRight != marketSlot)
{
if(hRight)
hRight->selection->selectSlot(false);
hRight = marketSlot;
hRight->selection->selectSlot(true);
selectionChanged(false);
initSubs(false);
}
},
[this]() -> void
{
if(hLeft)
for(auto & slot : tradePanels[0]->slots)
{
int h1, h2; //hlp variables for getting offer
market->getOffer(hLeft->id, slot->id, h1, h2, EMarketMode::RESOURCE_ARTIFACT);
tradePanels[0]->updateOffer(slot->serial, h1, h2);
}
else
tradePanels[0]->clearSubtitles();
}, market->availableItemsIds(mode)));
tradePanels.back()->moveBy(Point(340, 182));
return;
}
std::vector<int> *ids = getItemsIds(Left);
std::vector<Rect> pos;
@@ -229,12 +251,6 @@ std::vector<int> *CTradeWindow::getItemsIds(bool Left)
if(PlayerColor(i) != LOCPLINT->playerID && LOCPLINT->cb->getPlayerStatus(PlayerColor(i)) == EPlayerStatus::INGAME)
ids->push_back(i);
break;
case ARTIFACT_TYPE:
ids = new std::vector<int>;
for (auto const & item : market->availableItemsIds(mode))
ids->push_back(item.getNum());
break;
}
}
@@ -269,14 +285,6 @@ void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType typ
dy = 98;
assert(Left);
break;
case ARTIFACT_TYPE://45,123
x = 340 - 289;
y = 180;
w = 44;
h = 44;
dx = 83;
dy = 79;
break;
}
int leftToRightOffset = 289;
@@ -302,12 +310,12 @@ void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType typ
void CTradeWindow::initSubs(bool Left)
{
if(itemsType[Left] == RESOURCE)
if(itemsType[Left] == RESOURCE || itemsType[Left] == ARTIFACT_TYPE)
{
if(Left)
resoursesPanelPlayer->updateSlots();
tradePanels[1]->updateSlots();
else
resoursesPanelMarket->updateSlots();
tradePanels[0]->updateSlots();
return;
}
@@ -590,10 +598,8 @@ void CMarketplaceWindow::makeDeal()
madeTransaction = true;
hLeft = nullptr;
hRight = nullptr;
if(resoursesPanelPlayer)
resoursesPanelPlayer->deselect();
if(resoursesPanelMarket)
resoursesPanelMarket->deselect();
for(auto & panel : tradePanels)
panel->deselect();
selectionChanged(true);
}