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

Creatures trade panel

This commit is contained in:
SoundSSGood
2023-12-03 17:08:30 +02:00
parent 791ee78cc4
commit 50a5c72d1b
7 changed files with 154 additions and 254 deletions

View File

@@ -44,6 +44,10 @@ CAltar::CAltar(const IMarket * market, const CGHeroInstance * hero)
void CAltar::deselect() void CAltar::deselect()
{ {
if(hLeft)
hLeft->selection->selectSlot(false);
if(hRight)
hRight->selection->selectSlot(false);
hLeft = hRight = nullptr; hLeft = hRight = nullptr;
deal->block(true); deal->block(true);
} }
@@ -251,35 +255,36 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
Point(393, 520), AnimationPath::builtin("ALTARMY.DEF"), CGI->generaltexth->zelp[579], std::bind(&CAltar::sacrificeAll, this)); Point(393, 520), AnimationPath::builtin("ALTARMY.DEF"), CGI->generaltexth->zelp[579], std::bind(&CAltar::sacrificeAll, this));
// Creating slots for hero creatures // Creating slots for hero creatures
for(int slotIdx = 0; slotIdx < GameConstants::ARMY_SIZE; slotIdx++) SCreaturesPanel::slotsData slots;
for(auto slotId = SlotID(0); slotId.num < GameConstants::ARMY_SIZE; slotId++)
{ {
CreatureID creatureId = CreatureID::NONE; if(const auto & creature = hero->getCreature(slotId))
if(const auto & creature = hero->getCreature(SlotID(slotIdx))) slots.emplace_back(std::make_tuple(creature->getId(), slotId, hero->getStackCount(slotId)));
creatureId = creature->getId();
else
continue;
auto heroSlot = std::make_shared<CTradeableItem>(posSlotsHero[slotIdx], EType::CREATURE, creatureId.num, true, slotIdx);
heroSlot->clickPressedCallback = [this](std::shared_ptr<CTradeableItem> altarSlot) -> void
{
onSlotClickPressed(altarSlot, items[0], hLeft, hRight);
};
heroSlot->subtitle = std::to_string(hero->getStackCount(SlotID(slotIdx)));
items[1].emplace_back(heroSlot);
} }
leftTradePanel = std::make_shared<SCreaturesPanel>([this](std::shared_ptr<CTradeableItem> altarSlot) -> void
{
onSlotClickPressed(altarSlot, rightTradePanel, hLeft, hRight);
}, slots);
leftTradePanel->moveBy(Point(45, 110));
leftTradePanel->updateSlotsCallback = [this]() -> void
{
for(auto & heroSlot : leftTradePanel->slots)
heroSlot->subtitle = std::to_string(this->hero->getStackCount(SlotID(heroSlot->serial)));
};
// Creating slots for creatures on altar // Creating slots for creatures on altar
assert(items[1].size() <= posSlotsAltar.size()); for(auto & slot : slots)
for(const auto & heroSlot : items[1]) std::get<2>(slot) = 0;
{ rightTradePanel = std::make_shared<SCreaturesPanel>([this](std::shared_ptr<CTradeableItem> altarSlot) -> void
auto altarSlot = std::make_shared<CTradeableItem>(posSlotsAltar[heroSlot->serial], EType::CREATURE_PLACEHOLDER, heroSlot->id, false, heroSlot->serial); {
altarSlot->pos.w = heroSlot->pos.w; altarSlot->pos.h = heroSlot->pos.h; onSlotClickPressed(altarSlot, leftTradePanel, hRight, hLeft);
altarSlot->clickPressedCallback = [this](std::shared_ptr<CTradeableItem> altarSlot) -> void }, slots);
{ rightTradePanel->moveBy(Point(334, 110));
onSlotClickPressed(altarSlot, items[1], hRight, hLeft);
}; leftTradePanel->deleteSlotsCheck = rightTradePanel->deleteSlotsCheck = [this](std::shared_ptr<CTradeableItem> & slot) -> bool
items[0].emplace_back(altarSlot); {
} return this->hero->getStackCount(SlotID(slot->serial)) == 0 ? true : false;
};
readExpValues(); readExpValues();
calcExpAltarForHero(); calcExpAltarForHero();
@@ -289,7 +294,7 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
void CAltarCreatures::readExpValues() void CAltarCreatures::readExpValues()
{ {
int dump; int dump;
for(auto heroSlot : items[1]) for(auto heroSlot : leftTradePanel->slots)
{ {
if(heroSlot->id >= 0) if(heroSlot->id >= 0)
market->getOffer(heroSlot->id, 0, dump, expPerUnit[heroSlot->serial], EMarketMode::CREATURE_EXP); market->getOffer(heroSlot->id, 0, dump, expPerUnit[heroSlot->serial], EMarketMode::CREATURE_EXP);
@@ -340,14 +345,13 @@ void CAltarCreatures::updateSubtitlesForSelected()
rSubtitle->setText(""); rSubtitle->setText("");
} }
void CAltarCreatures::updateGarrison() void CAltarCreatures::updateSlots()
{ {
std::set<std::shared_ptr<CTradeableItem>> empty; rightTradePanel->deleteSlots();
getEmptySlots(empty); leftTradePanel->deleteSlots();
removeItems(empty); assert(leftTradePanel->slots.size() == rightTradePanel->slots.size());
readExpValues(); readExpValues();
for(auto & heroSlot : items[1]) leftTradePanel->updateSlots();
heroSlot->subtitle = std::to_string(hero->getStackCount(SlotID(heroSlot->serial)));
} }
void CAltarCreatures::deselect() void CAltarCreatures::deselect()
@@ -392,17 +396,17 @@ void CAltarCreatures::makeDeal()
for(int & units : unitsOnAltar) for(int & units : unitsOnAltar)
units = 0; units = 0;
for(auto heroSlot : items[0]) for(auto heroSlot : rightTradePanel->slots)
{ {
heroSlot->setType(CREATURE_PLACEHOLDER); heroSlot->setType(CREATURE_PLACEHOLDER);
heroSlot->subtitle = ""; heroSlot->subtitle.clear();
} }
} }
void CAltarCreatures::sacrificeAll() void CAltarCreatures::sacrificeAll()
{ {
std::optional<SlotID> lastSlot; std::optional<SlotID> lastSlot;
for(auto heroSlot : items[1]) for(auto heroSlot : leftTradePanel->slots)
{ {
auto stackCount = hero->getStackCount(SlotID(heroSlot->serial)); auto stackCount = hero->getStackCount(SlotID(heroSlot->serial));
if(stackCount > unitsOnAltar[heroSlot->serial]) if(stackCount > unitsOnAltar[heroSlot->serial])
@@ -417,7 +421,7 @@ void CAltarCreatures::sacrificeAll()
if(hRight) if(hRight)
unitsSlider->scrollTo(unitsOnAltar[hRight->serial]); unitsSlider->scrollTo(unitsOnAltar[hRight->serial]);
for(auto altarSlot : items[0]) for(auto altarSlot : rightTradePanel->slots)
updateAltarSlot(altarSlot); updateAltarSlot(altarSlot);
updateSubtitlesForSelected(); updateSubtitlesForSelected();
@@ -443,18 +447,21 @@ void CAltarCreatures::onUnitsSliderMoved(int newVal)
updateSubtitlesForSelected(); updateSubtitlesForSelected();
} }
void CAltarCreatures::onSlotClickPressed(std::shared_ptr<CTradeableItem> altarSlot, void CAltarCreatures::onSlotClickPressed(std::shared_ptr<CTradeableItem> altarSlot, std::shared_ptr<STradePanel> & oppositePanel,
std::vector<std::shared_ptr<CTradeableItem>> & oppositeSlots,
std::shared_ptr<CTradeableItem> & hCurSide, std::shared_ptr<CTradeableItem> & hOppSide) std::shared_ptr<CTradeableItem> & hCurSide, std::shared_ptr<CTradeableItem> & hOppSide)
{ {
std::shared_ptr<CTradeableItem> oppositeSlot; std::shared_ptr<CTradeableItem> oppositeSlot;
for(const auto & slot : oppositeSlots) for(const auto & slot : oppositePanel->slots)
if(slot->serial == altarSlot->serial) if(slot->serial == altarSlot->serial)
{ {
oppositeSlot = slot; oppositeSlot = slot;
break; break;
} }
if(hCurSide)
hCurSide->selection->selectSlot(false);
if(hOppSide)
hOppSide->selection->selectSlot(false);
if(hCurSide != altarSlot && oppositeSlot) if(hCurSide != altarSlot && oppositeSlot)
{ {
hCurSide = altarSlot; hCurSide = altarSlot;
@@ -463,4 +470,7 @@ void CAltarCreatures::onSlotClickPressed(std::shared_ptr<CTradeableItem> altarSl
updateSubtitlesForSelected(); updateSubtitlesForSelected();
redraw(); redraw();
} }
hCurSide->selection->selectSlot(true);
hOppSide->selection->selectSlot(true);
redraw();
} }

View File

@@ -66,7 +66,7 @@ class CAltarCreatures : public CAltar
{ {
public: public:
CAltarCreatures(const IMarket * market, const CGHeroInstance * hero); CAltarCreatures(const IMarket * market, const CGHeroInstance * hero);
void updateGarrison(); void updateSlots();
void deselect() override; void deselect() override;
TExpType calcExpAltarForHero() override; TExpType calcExpAltarForHero() override;
void makeDeal() override; void makeDeal() override;
@@ -80,24 +80,10 @@ private:
std::vector<int> expPerUnit; std::vector<int> expPerUnit;
std::shared_ptr<CLabel> lSubtitle, rSubtitle; std::shared_ptr<CLabel> lSubtitle, rSubtitle;
const std::vector<Point> posSlotsAltar =
{
Point(334, 110), Point(417, 110), Point(500, 110),
Point(334, 208), Point(417, 208), Point(500, 208),
Point(417, 306)
};
const std::vector<Point> posSlotsHero =
{
Point(45, 110), Point(128, 110), Point(211, 110),
Point(45, 208), Point(128, 208), Point(211, 208),
Point(128, 306)
};
void readExpValues(); void readExpValues();
void updateControls(); void updateControls();
void updateSubtitlesForSelected(); void updateSubtitlesForSelected();
void onUnitsSliderMoved(int newVal); void onUnitsSliderMoved(int newVal);
void onSlotClickPressed(std::shared_ptr<CTradeableItem> altarSlot, void onSlotClickPressed(std::shared_ptr<CTradeableItem> altarSlot, std::shared_ptr<STradePanel> & oppositePanel,
std::vector<std::shared_ptr<CTradeableItem>> & oppositeSlots,
std::shared_ptr<CTradeableItem> & hCurSide, std::shared_ptr<CTradeableItem> & hOppSide); std::shared_ptr<CTradeableItem> & hCurSide, std::shared_ptr<CTradeableItem> & hOppSide);
}; };

View File

@@ -280,44 +280,51 @@ void STradePanel::clearSubtitles()
slot->subtitle.clear(); slot->subtitle.clear();
} }
void STradePanel::updateOffer(int slotIdx, int cost, int qty) void STradePanel::updateOffer(CTradeableItem & slot, int cost, int qty)
{ {
slots[slotIdx]->subtitle = std::to_string(qty); slot.subtitle = std::to_string(qty);
if(cost != 1) if(cost != 1)
slots[slotIdx]->subtitle += "/" + std::to_string(cost); slot.subtitle += "/" + std::to_string(cost);
} }
SResourcesPanel::SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updateSlotsFunctor updateSubtitles) void STradePanel::deleteSlots()
{
if(deleteSlotsCheck)
slots.erase(std::remove_if(slots.begin(), slots.end(), deleteSlotsCheck), slots.end());
}
SResourcesPanel::SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles)
{ {
assert(resourcesForTrade.size() == slotsPos.size()); assert(resourcesForTrade.size() == slotsPos.size());
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
for(const auto & res : resourcesForTrade) for(const auto & res : resourcesForTrade)
{ {
slots.emplace_back(std::make_shared<CTradeableItem>(slotsPos[res.num], EType::RESOURCE, res.num, true, res.num)); auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(slotsPos[res.num], EType::RESOURCE, res.num, true, res.num));
slots.back()->clickPressedCallback = clickPressedCallback; slot->clickPressedCallback = clickPressedCallback;
slots.back()->pos.w = 69; slots.back()->pos.h = 66; slot->pos.w = 69; slots.back()->pos.h = 66;
slots.back()->selection = std::make_unique<SelectableSlot>(Rect(slotsPos[res.num], slots.back()->pos.dimensions()), slot->selection = std::make_unique<SelectableSlot>(Rect(slotsPos[res.num], slots.back()->pos.dimensions()), Point(1, 1), selectionWidth);
Point(1, 1), selectionWidth);
} }
updateSlotsCallback = updateSubtitles; updateSlotsCallback = updateSubtitles;
} }
SArtifactsPanel::SArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updateSlotsFunctor updateSubtitles, SArtifactsPanel::SArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles,
std::vector<TradeItemBuy> & arts) std::vector<TradeItemBuy> & arts)
{ {
assert(artifactsForTrade == slotsPos.size()); assert(slotsForTrade == slotsPos.size());
assert(artifactsForTrade == arts.size()); assert(slotsForTrade == arts.size());
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
slots.resize(artifactsForTrade); for(auto slotIdx = 0; slotIdx < slotsForTrade; slotIdx++)
int slotNum = 0;
for(auto & slot : slots)
{ {
slot = std::make_shared<CTradeableItem>(slotsPos[slotNum], EType::ARTIFACT_TYPE, arts[slotNum].getNum(), false, slotNum); auto artType = arts[slotIdx].getNum();
slot->clickPressedCallback = clickPressedCallback; if(artType != ArtifactID::NONE)
slot->pos.w = 69; slot->pos.h = 66; {
slot->selection = std::make_unique<SelectableSlot>(Rect(slotsPos[slotNum++], slot->pos.dimensions()), Point(1, 1), selectionWidth); auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(slotsPos[slotIdx], EType::ARTIFACT_TYPE, artType, false, slotIdx));
slot->clickPressedCallback = clickPressedCallback;
slot->pos.w = 69; slot->pos.h = 66;
slot->selection = std::make_unique<SelectableSlot>(Rect(slotsPos[slotIdx], slot->pos.dimensions()), Point(1, 1), selectionWidth);
}
} }
updateSlotsCallback = updateSubtitles; updateSlotsCallback = updateSubtitles;
} }
@@ -345,6 +352,26 @@ SPlayersPanel::SPlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCal
} }
} }
SCreaturesPanel::SCreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, slotsData & initialSlots)
{
assert(initialSlots.size() <= GameConstants::ARMY_SIZE);
assert(slotsPos.size() <= GameConstants::ARMY_SIZE);
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
for(const auto & slotData : initialSlots)
{
auto slotId = std::get<1>(slotData);
auto creaturesNum = std::get<2>(slotData);
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(slotsPos[slotId.num],
creaturesNum == 0 ? EType::CREATURE_PLACEHOLDER : EType::CREATURE, std::get<0>(slotData).num, true, slotId));
slot->clickPressedCallback = clickPressedCallback;
if(creaturesNum != 0)
slot->subtitle = std::to_string(std::get<2>(slotData));
slot->pos.w = 58; slots.back()->pos.h = 64;
slot->selection = std::make_unique<SelectableSlot>(Rect(slotsPos[slotId.num], slots.back()->pos.dimensions()), Point(1, 1), selectionWidth);
}
}
CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero) CTradeBase::CTradeBase(const IMarket * market, const CGHeroInstance * hero)
: market(market) : market(market)
, hero(hero) , hero(hero)
@@ -359,7 +386,7 @@ void CTradeBase::removeItems(const std::set<std::shared_ptr<CTradeableItem>> & t
void CTradeBase::removeItem(std::shared_ptr<CTradeableItem> item) void CTradeBase::removeItem(std::shared_ptr<CTradeableItem> item)
{ {
items[item->left] -= item; rightTradePanel->slots.erase(std::remove(rightTradePanel->slots.begin(), rightTradePanel->slots.end(), item));
if(hRight == item) if(hRight == item)
hRight.reset(); hRight.reset();
@@ -367,7 +394,7 @@ void CTradeBase::removeItem(std::shared_ptr<CTradeableItem> item)
void CTradeBase::getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove) void CTradeBase::getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove)
{ {
for(auto item : items[1]) for(auto item : leftTradePanel->slots)
if(!hero->getStackCount(SlotID(item->serial))) if(!hero->getStackCount(SlotID(item->serial)))
toRemove.insert(item); toRemove.insert(item);
} }

View File

@@ -67,17 +67,20 @@ public:
struct STradePanel : public CIntObject struct STradePanel : public CIntObject
{ {
using updateSlotsFunctor = std::function<void()>; using UpdateSlotsFunctor = std::function<void()>;
using DeleteSlotsCheck = std::function<bool(std::shared_ptr<CTradeableItem> & slot)>;
std::vector<std::shared_ptr<CTradeableItem>> slots; std::vector<std::shared_ptr<CTradeableItem>> slots;
std::function<void()> updateSlotsCallback; UpdateSlotsFunctor updateSlotsCallback;
DeleteSlotsCheck deleteSlotsCheck;
std::shared_ptr<CTradeableItem> selected; std::shared_ptr<CTradeableItem> selected;
const int selectionWidth = 2; const int selectionWidth = 2;
virtual void updateSlots(); virtual void updateSlots();
virtual void deselect(); virtual void deselect();
virtual void clearSubtitles(); virtual void clearSubtitles();
void updateOffer(int slotIdx, int, int); void updateOffer(CTradeableItem & slot, int, int);
void deleteSlots();
}; };
struct SResourcesPanel : public STradePanel struct SResourcesPanel : public STradePanel
@@ -95,7 +98,7 @@ struct SResourcesPanel : public STradePanel
Point(83, 158) Point(83, 158)
}; };
SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updateSlotsFunctor updateSubtitles); SResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles);
}; };
struct SArtifactsPanel : public STradePanel struct SArtifactsPanel : public STradePanel
@@ -106,9 +109,9 @@ struct SArtifactsPanel : public STradePanel
Point(0, 79), Point(83, 79), Point(166, 79), Point(0, 79), Point(83, 79), Point(166, 79),
Point(83, 158) Point(83, 158)
}; };
const size_t artifactsForTrade = 7; const size_t slotsForTrade = 7;
SArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, updateSlotsFunctor updateSubtitles, SArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles,
std::vector<TradeItemBuy> & arts); std::vector<TradeItemBuy> & arts);
}; };
@@ -123,6 +126,19 @@ struct SPlayersPanel : public STradePanel
SPlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback); SPlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback);
}; };
struct SCreaturesPanel : public STradePanel
{
using slotsData = std::vector<std::tuple<CreatureID, SlotID, int>>;
const std::vector<Point> slotsPos =
{
Point(0, 0), Point(83, 0), Point(166, 0),
Point(0, 98), Point(83, 98), Point(166, 98),
Point(83, 196)
};
SCreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, slotsData & initialSlots);
};
class CTradeBase class CTradeBase
{ {
public: public:

View File

@@ -48,7 +48,7 @@ void CAltarWindow::updateExpToLevel()
void CAltarWindow::updateGarrisons() void CAltarWindow::updateGarrisons()
{ {
if(auto altarCreatures = std::static_pointer_cast<CAltarCreatures>(altar)) if(auto altarCreatures = std::static_pointer_cast<CAltarCreatures>(altar))
altarCreatures->updateGarrison(); altarCreatures->updateSlots();
} }
bool CAltarWindow::holdsGarrison(const CArmedInstance * army) bool CAltarWindow::holdsGarrison(const CArmedInstance * army)
@@ -130,12 +130,10 @@ void CAltarWindow::showAll(Canvas & to)
if(altar->hRight) if(altar->hRight)
{ {
to.drawBorder(Rect::createAround(altar->hRight->pos, 1), Colors::BRIGHT_YELLOW, 2);
altar->hRight->showAllAt(altar->pos.topLeft() + Point(396, 423), "", to); altar->hRight->showAllAt(altar->pos.topLeft() + Point(396, 423), "", to);
} }
if(altar->hLeft) if(altar->hLeft)
{ {
to.drawBorder(Rect::createAround(altar->hLeft->pos, 1), Colors::BRIGHT_YELLOW, 2);
altar->hLeft->showAllAt(altar->pos.topLeft() + Point(150, 423), "", to); altar->hLeft->showAllAt(altar->pos.topLeft() + Point(150, 423), "", to);
} }
} }

View File

@@ -92,7 +92,7 @@ void CTradeWindow::initItems(bool Left)
int h1, h2; //hlp variables for getting offer int h1, h2; //hlp variables for getting offer
market->getOffer(hLeft->id, slot->id, h1, h2, mode); market->getOffer(hLeft->id, slot->id, h1, h2, mode);
rightTradePanel->updateOffer(slot->serial, h1, h2); rightTradePanel->updateOffer(*slot, h1, h2);
} }
else else
rightTradePanel->clearSubtitles(); rightTradePanel->clearSubtitles();
@@ -111,7 +111,22 @@ void CTradeWindow::initItems(bool Left)
selectionChanged(left); selectionChanged(left);
}; };
if(Left && (mode == EMarketMode::RESOURCE_RESOURCE || mode == EMarketMode::RESOURCE_ARTIFACT || mode == EMarketMode::RESOURCE_PLAYER)) if(Left && mode == EMarketMode::CREATURE_RESOURCE)
{
SCreaturesPanel::slotsData slots;
for(auto slotId = SlotID(0); slotId.num < GameConstants::ARMY_SIZE; slotId++)
{
if(const auto & creature = hero->getCreature(slotId))
slots.emplace_back(std::make_tuple(creature->getId(), slotId, hero->getStackCount(slotId)));
}
leftTradePanel = std::make_shared<SCreaturesPanel>(std::bind(clickPressedTradePanel, _1, true), slots);
leftTradePanel->moveBy(Point(45, 123));
leftTradePanel->deleteSlotsCheck = [this](std::shared_ptr<CTradeableItem> & slot) -> bool
{
return this->hero->getStackCount(SlotID(slot->serial)) == 0 ? true : false;
};
}
else if(Left && (mode == EMarketMode::RESOURCE_RESOURCE || mode == EMarketMode::RESOURCE_ARTIFACT || mode == EMarketMode::RESOURCE_PLAYER))
{ {
leftTradePanel = std::make_shared<SResourcesPanel>(std::bind(clickPressedTradePanel, _1, true), leftTradePanel = std::make_shared<SResourcesPanel>(std::bind(clickPressedTradePanel, _1, true),
[this]() -> void [this]() -> void
@@ -121,9 +136,8 @@ void CTradeWindow::initItems(bool Left)
}); });
leftTradePanel->moveBy(Point(39, 182)); leftTradePanel->moveBy(Point(39, 182));
leftTradePanel->updateSlots(); leftTradePanel->updateSlots();
return;
} }
if(!Left && mode == EMarketMode::RESOURCE_RESOURCE) else if(!Left && mode == EMarketMode::RESOURCE_RESOURCE)
{ {
rightTradePanel = std::make_shared<SResourcesPanel>(std::bind(clickPressedTradePanel, _1, false), rightTradePanel = std::make_shared<SResourcesPanel>(std::bind(clickPressedTradePanel, _1, false),
[this, updRightSub]() -> void [this, updRightSub]() -> void
@@ -133,153 +147,28 @@ void CTradeWindow::initItems(bool Left)
rightTradePanel->slots[hLeft->serial]->subtitle = CGI->generaltexth->allTexts[164]; // n/a rightTradePanel->slots[hLeft->serial]->subtitle = CGI->generaltexth->allTexts[164]; // n/a
}); });
rightTradePanel->moveBy(Point(327, 181)); rightTradePanel->moveBy(Point(327, 181));
return;
} }
if(!Left && (mode == EMarketMode::ARTIFACT_RESOURCE || mode == EMarketMode::CREATURE_RESOURCE)) else if(!Left && (mode == EMarketMode::ARTIFACT_RESOURCE || mode == EMarketMode::CREATURE_RESOURCE))
{ {
rightTradePanel = std::make_shared<SResourcesPanel>(std::bind(clickPressedTradePanel, _1, false), rightTradePanel = std::make_shared<SResourcesPanel>(std::bind(clickPressedTradePanel, _1, false),
std::bind(updRightSub, EMarketMode::ARTIFACT_RESOURCE)); std::bind(updRightSub, EMarketMode::ARTIFACT_RESOURCE));
rightTradePanel->moveBy(Point(327, 181)); rightTradePanel->moveBy(Point(327, 181));
return;
} }
if(!Left && mode == EMarketMode::RESOURCE_ARTIFACT) else if(!Left && mode == EMarketMode::RESOURCE_ARTIFACT)
{ {
rightTradePanel = std::make_shared<SArtifactsPanel>(std::bind(clickPressedTradePanel, _1, false), rightTradePanel = std::make_shared<SArtifactsPanel>(std::bind(clickPressedTradePanel, _1, false),
std::bind(updRightSub, EMarketMode::RESOURCE_ARTIFACT), market->availableItemsIds(mode)); std::bind(updRightSub, EMarketMode::RESOURCE_ARTIFACT), market->availableItemsIds(mode));
rightTradePanel->moveBy(Point(327, 181)); rightTradePanel->moveBy(Point(327, 181));
return; rightTradePanel->deleteSlotsCheck = [this](std::shared_ptr<CTradeableItem> & slot) -> bool
{
return vstd::contains(market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT), ArtifactID(slot->id)) ? false : true;
};
} }
if(!Left && mode == EMarketMode::RESOURCE_PLAYER) else if(!Left && mode == EMarketMode::RESOURCE_PLAYER)
{ {
rightTradePanel = std::make_shared<SPlayersPanel>(std::bind(clickPressedTradePanel, _1, false)); rightTradePanel = std::make_shared<SPlayersPanel>(std::bind(clickPressedTradePanel, _1, false));
rightTradePanel->moveBy(Point(333, 83)); rightTradePanel->moveBy(Point(333, 83));
return;
} }
std::vector<int> *ids = getItemsIds(Left);
std::vector<Rect> pos;
int amount = -1;
getPositionsFor(pos, Left, itemsType[Left]);
if(Left || !ids)
amount = 7;
else
amount = static_cast<int>(ids->size());
if(ids)
vstd::amin(amount, ids->size());
for(int j=0; j<amount; j++)
{
int id = (ids && ids->size()>j) ? (*ids)[j] : j;
if(id < 0 && mode != EMarketMode::ARTIFACT_EXP) //when sacrificing artifacts we need to prepare empty slots
continue;
auto item = std::make_shared<CTradeableItem>(pos[j].topLeft(), itemsType[Left], id, Left, j);
item->pos = pos[j] + this->pos.topLeft();
if(mode != EMarketMode::ARTIFACT_EXP)
item->clickPressedCallback = [this](std::shared_ptr<CTradeableItem> altarSlot) -> void
{
if(altarSlot->left)
{
if(hLeft != altarSlot)
hLeft = altarSlot;
else
return;
}
else
{
if(hRight != altarSlot)
hRight = altarSlot;
else
return;
}
selectionChanged(altarSlot->left);
};
items[Left].push_back(item);
}
vstd::clear_pointer(ids);
initSubs(Left);
}
}
std::vector<int> *CTradeWindow::getItemsIds(bool Left)
{
std::vector<int> *ids = nullptr;
if(Left)
{
switch(itemsType[1])
{
case CREATURE:
ids = new std::vector<int>;
for(int i = 0; i < 7; i++)
{
if(const CCreature *c = hero->getCreature(SlotID(i)))
ids->push_back(c->getId());
else
ids->push_back(-1);
}
break;
}
}
else
{
switch(itemsType[0])
{
case PLAYER:
ids = new std::vector<int>;
for(int i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++)
if(PlayerColor(i) != LOCPLINT->playerID && LOCPLINT->cb->getPlayerStatus(PlayerColor(i)) == EPlayerStatus::INGAME)
ids->push_back(i);
break;
}
}
return ids;
}
void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType type) const
{
//seven boxes:
// X X X
// X X X
// X
int h = 0, w = 0, x = 0, y = 0, dx = 0, dy = 0;
switch(type)
{
case CREATURE://45,123
x = 45;
y = 123;
w = 58;
h = 64;
dx = 83;
dy = 98;
assert(Left);
break;
}
int leftToRightOffset = 289;
const std::vector<Rect> tmp =
{
Rect(Point(x + 0 * dx, y + 0 * dx), Point(w, h) ),
Rect(Point(x + 1 * dx, y + 0 * dx), Point(w, h) ),
Rect(Point(x + 2 * dx, y + 0 * dx), Point(w, h) ),
Rect(Point(x + 0 * dx, y + 1 * dy), Point(w, h) ),
Rect(Point(x + 1 * dx, y + 1 * dy), Point(w, h) ),
Rect(Point(x + 2 * dx, y + 1 * dy), Point(w, h) ),
Rect(Point(x + 1 * dx, y + 2 * dy), Point(w, h) )
};
vstd::concatenate(poss, tmp);
if(!Left)
{
for(Rect &r : poss)
r.x += leftToRightOffset;
} }
} }
@@ -293,19 +182,6 @@ void CTradeWindow::initSubs(bool Left)
rightTradePanel->updateSlots(); rightTradePanel->updateSlots();
return; return;
} }
for(auto item : items[Left])
{
if(Left)
{
switch(itemsType[1])
{
case CREATURE:
item->subtitle = std::to_string(hero->getStackCount(SlotID(item->serial)));
break;
}
}
}
} }
void CTradeWindow::showAll(Canvas & to) void CTradeWindow::showAll(Canvas & to)
@@ -660,10 +536,8 @@ void CMarketplaceWindow::updateGarrison()
if(mode != EMarketMode::CREATURE_RESOURCE) if(mode != EMarketMode::CREATURE_RESOURCE)
return; return;
std::set<std::shared_ptr<CTradeableItem>> toRemove; leftTradePanel->deleteSlots();
getEmptySlots(toRemove); leftTradePanel->updateSlots();
removeItems(toRemove);
initSubs(true);
} }
void CMarketplaceWindow::artifactsChanged(bool Left) void CMarketplaceWindow::artifactsChanged(bool Left)
@@ -672,16 +546,7 @@ void CMarketplaceWindow::artifactsChanged(bool Left)
if(mode != EMarketMode::RESOURCE_ARTIFACT) if(mode != EMarketMode::RESOURCE_ARTIFACT)
return; return;
std::vector<TradeItemBuy> available = market->availableItemsIds(mode); rightTradePanel->deleteSlots();
std::set<std::shared_ptr<CTradeableItem>> toRemove;
for(auto item : items[0])
if(!vstd::contains(available, ArtifactID(item->id)))
toRemove.insert(item);
removeItems(toRemove);
// clear set to erase final instance of shared_ptr - we want to redraw screen only after it has been deleted
toRemove.clear();
redraw(); redraw();
} }

View File

@@ -36,8 +36,6 @@ public:
void initSubs(bool Left); void initSubs(bool Left);
void initTypes(); void initTypes();
void initItems(bool Left); void initItems(bool Left);
std::vector<int> *getItemsIds(bool Left); //nullptr if default
void getPositionsFor(std::vector<Rect> &poss, bool Left, EType type) const;
void setMode(EMarketMode Mode); //mode setter void setMode(EMarketMode Mode); //mode setter
void artifactSelected(CArtPlace * slot); //used when selling artifacts -> called when user clicked on artifact slot void artifactSelected(CArtPlace * slot); //used when selling artifacts -> called when user clicked on artifact slot