1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

Cleanup & refactoring

This commit is contained in:
SoundSSGood 2024-02-27 13:39:50 +02:00
parent f3fa6714dc
commit 4839891de4
21 changed files with 224 additions and 1007 deletions

View File

@ -145,7 +145,6 @@ set(client_SRCS
windows/CPuzzleWindow.cpp windows/CPuzzleWindow.cpp
windows/CQuestLog.cpp windows/CQuestLog.cpp
windows/CSpellWindow.cpp windows/CSpellWindow.cpp
windows/CTradeWindow.cpp
windows/CTutorialWindow.cpp windows/CTutorialWindow.cpp
windows/CWindowObject.cpp windows/CWindowObject.cpp
windows/CreaturePurchaseCard.cpp windows/CreaturePurchaseCard.cpp
@ -335,7 +334,6 @@ set(client_HEADERS
windows/CPuzzleWindow.h windows/CPuzzleWindow.h
windows/CQuestLog.h windows/CQuestLog.h
windows/CSpellWindow.h windows/CSpellWindow.h
windows/CTradeWindow.h
windows/CTutorialWindow.h windows/CTutorialWindow.h
windows/CWindowObject.h windows/CWindowObject.h
windows/CreaturePurchaseCard.h windows/CreaturePurchaseCard.h

View File

@ -95,6 +95,19 @@ void CLabel::setText(const std::string & Txt)
} }
} }
void CLabel::clear()
{
text.clear();
if(autoRedraw)
{
if(background || !parent)
redraw();
else
parent->redraw();
}
}
void CLabel::setMaxWidth(int width) void CLabel::setMaxWidth(int width)
{ {
maxWidth = width; maxWidth = width;

View File

@ -57,6 +57,7 @@ public:
virtual void setText(const std::string & Txt); virtual void setText(const std::string & Txt);
virtual void setMaxWidth(int width); virtual void setMaxWidth(int width);
virtual void setColor(const ColorRGBA & Color); virtual void setColor(const ColorRGBA & Color);
void clear();
size_t getWidth(); size_t getWidth();
CLabel(int x = 0, int y = 0, EFonts Font = FONT_SMALL, ETextAlignment Align = ETextAlignment::TOPLEFT, CLabel(int x = 0, int y = 0, EFonts Font = FONT_SMALL, ETextAlignment Align = ETextAlignment::TOPLEFT,

View File

@ -57,9 +57,9 @@ CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance *
int slotNum = 0; int slotNum = 0;
for(auto & altarSlotPos : posSlotsAltar) for(auto & altarSlotPos : posSlotsAltar)
{ {
auto altarSlot = std::make_shared<CTradeableItem>(Rect(altarSlotPos, Point(44, 44)), EType::ARTIFACT_PLACEHOLDER, -1, false, slotNum); auto altarSlot = std::make_shared<CTradeableItem>(Rect(altarSlotPos, Point(44, 44)), EType::ARTIFACT_PLACEHOLDER, -1, slotNum);
altarSlot->clickPressedCallback = std::bind(&CAltarArtifacts::onSlotClickPressed, this, _1, hRight); altarSlot->clickPressedCallback = std::bind(&CAltarArtifacts::onSlotClickPressed, this, _1, hRight);
altarSlot->subtitle.clear(); altarSlot->subtitle->clear();
items.front().emplace_back(altarSlot); items.front().emplace_back(altarSlot);
slotNum++; slotNum++;
} }
@ -91,7 +91,7 @@ void CAltarArtifacts::makeDeal()
for(auto item : items[0]) for(auto item : items[0])
{ {
item->setID(-1); item->setID(-1);
item->subtitle.clear(); item->subtitle->clear();
} }
calcExpAltarForHero(); calcExpAltarForHero();
deal->block(tradeSlotsMap.empty()); deal->block(tradeSlotsMap.empty());
@ -135,7 +135,7 @@ void CAltarArtifacts::updateSlots()
if(tradeSlotsMap.find(altarSlot->getArtInstance()) == tradeSlotsMap.end()) if(tradeSlotsMap.find(altarSlot->getArtInstance()) == tradeSlotsMap.end())
{ {
altarSlot->setID(-1); altarSlot->setID(-1);
altarSlot->subtitle.clear(); altarSlot->subtitle->clear();
} }
else else
{ {
@ -148,7 +148,7 @@ void CAltarArtifacts::updateSlots()
assert(tradeSlot.second->id == -1); assert(tradeSlot.second->id == -1);
assert(altarArtifacts->getSlotByInstance(tradeSlot.first) != ArtifactPosition::PRE_FIRST); assert(altarArtifacts->getSlotByInstance(tradeSlot.first) != ArtifactPosition::PRE_FIRST);
tradeSlot.second->setArtInstance(tradeSlot.first); tradeSlot.second->setArtInstance(tradeSlot.first);
tradeSlot.second->subtitle = std::to_string(calcExpCost(tradeSlot.first)); tradeSlot.second->subtitle->setText(std::to_string(calcExpCost(tradeSlot.first)));
} }
for(auto & slotInfo : altarArtifacts->artifactsInBackpack) for(auto & slotInfo : altarArtifacts->artifactsInBackpack)
{ {
@ -158,7 +158,7 @@ void CAltarArtifacts::updateSlots()
if(altarSlot->id == -1) if(altarSlot->id == -1)
{ {
altarSlot->setArtInstance(slotInfo.artifact); altarSlot->setArtInstance(slotInfo.artifact);
altarSlot->subtitle = std::to_string(calcExpCost(slotInfo.artifact)); altarSlot->subtitle->setText(std::to_string(calcExpCost(slotInfo.artifact)));
tradeSlotsMap.try_emplace(slotInfo.artifact, altarSlot); tradeSlotsMap.try_emplace(slotInfo.artifact, altarSlot);
break; break;
} }

View File

@ -27,6 +27,7 @@
CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance * hero) CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance * hero)
: CTradeBase(market, hero) : CTradeBase(market, hero)
, CMarketMisc([this](){return CAltarCreatures::getSelectionParams();})
{ {
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
@ -47,8 +48,8 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
// Hero creatures panel // Hero creatures panel
assert(bidTradePanel); assert(bidTradePanel);
bidTradePanel->moveTo(pos.topLeft() + Point(45, 110)); bidTradePanel->moveTo(pos.topLeft() + Point(45, 110));
bidTradePanel->selectedImage->moveTo(pos.topLeft() + Point(149, 422)); bidTradePanel->selectedSlot->moveTo(pos.topLeft() + Point(149, 422));
bidTradePanel->selectedSubtitle->moveTo(pos.topLeft() + Point(180, 503)); bidTradePanel->selectedSlot->subtitle->moveBy(Point(0, 3));
for(const auto & slot : bidTradePanel->slots) for(const auto & slot : bidTradePanel->slots)
slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot) {CAltarCreatures::onSlotClickPressed(heroSlot, hLeft);}; slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot) {CAltarCreatures::onSlotClickPressed(heroSlot, hLeft);};
@ -58,8 +59,8 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
CAltarCreatures::onSlotClickPressed(altarSlot, hRight); CAltarCreatures::onSlotClickPressed(altarSlot, hRight);
}, bidTradePanel->slots); }, bidTradePanel->slots);
offerTradePanel->moveTo(pos.topLeft() + Point(334, 110)); offerTradePanel->moveTo(pos.topLeft() + Point(334, 110));
offerTradePanel->selectedImage->moveTo(pos.topLeft() + Point(395, 422)); offerTradePanel->selectedSlot->moveTo(pos.topLeft() + Point(395, 422));
offerTradePanel->selectedSubtitle->moveTo(pos.topLeft() + Point(426, 503)); offerTradePanel->selectedSlot->subtitle->moveBy(Point(0, 3));
offerTradePanel->updateSlotsCallback = [this]() offerTradePanel->updateSlotsCallback = [this]()
{ {
for(const auto & altarSlot : offerTradePanel->slots) for(const auto & altarSlot : offerTradePanel->slots)
@ -113,38 +114,9 @@ void CAltarCreatures::updateControls()
maxAmount->block(offerSlider->getAmount() == 0); maxAmount->block(offerSlider->getAmount() == 0);
} }
void CAltarCreatures::updateSelected()
{
std::optional<size_t> lImageIndex = std::nullopt;
std::optional<size_t> rImageIndex = std::nullopt;
if(hLeft)
{
bidTradePanel->selectedSubtitle->setText(std::to_string(offerSlider->getValue()));
lImageIndex = CGI->creatures()->getByIndex(hLeft->id)->getIconIndex();
}
else
{
bidTradePanel->selectedSubtitle->setText("");
}
if(hRight)
{
offerTradePanel->selectedSubtitle->setText(hRight->subtitle);
if(offerSlider->getValue() != 0)
rImageIndex = CGI->creatures()->getByIndex(hRight->id)->getIconIndex();
}
else
{
offerTradePanel->selectedSubtitle->setText("");
}
bidTradePanel->setSelectedFrameIndex(lImageIndex);
offerTradePanel->setSelectedFrameIndex(rImageIndex);
}
void CAltarCreatures::updateSlots() void CAltarCreatures::updateSlots()
{ {
offerTradePanel->updateSlots(); CTradeBase::updateSlots();
CCreaturesSelling::updateSlots();
assert(bidTradePanel->slots.size() == offerTradePanel->slots.size()); assert(bidTradePanel->slots.size() == offerTradePanel->slots.size());
} }
@ -190,10 +162,21 @@ void CAltarCreatures::makeDeal()
for(auto heroSlot : offerTradePanel->slots) for(auto heroSlot : offerTradePanel->slots)
{ {
heroSlot->setType(EType::CREATURE_PLACEHOLDER); heroSlot->setType(EType::CREATURE_PLACEHOLDER);
heroSlot->subtitle.clear(); heroSlot->subtitle->clear();
} }
} }
CMarketMisc::SelectionParams CAltarCreatures::getSelectionParams()
{
std::optional<SelectionParamOneSide> bidSelected = std::nullopt;
std::optional<SelectionParamOneSide> offerSelected = std::nullopt;
if(hLeft)
bidSelected = SelectionParamOneSide {std::to_string(offerSlider->getValue()), CGI->creatures()->getByIndex(hLeft->id)->getIconIndex()};
if(hRight && offerSlider->getValue() > 0)
offerSelected = SelectionParamOneSide {hRight->subtitle->getText(), CGI->creatures()->getByIndex(hRight->id)->getIconIndex()};
return std::make_tuple(bidSelected, offerSelected);
}
void CAltarCreatures::sacrificeAll() void CAltarCreatures::sacrificeAll()
{ {
std::optional<SlotID> lastSlot; std::optional<SlotID> lastSlot;
@ -225,8 +208,8 @@ void CAltarCreatures::updateAltarSlot(const std::shared_ptr<CTradeableItem> & sl
{ {
auto units = unitsOnAltar[slot->serial]; auto units = unitsOnAltar[slot->serial];
slot->setType(units > 0 ? EType::CREATURE : EType::CREATURE_PLACEHOLDER); slot->setType(units > 0 ? EType::CREATURE : EType::CREATURE_PLACEHOLDER);
slot->subtitle = units > 0 ? slot->subtitle->setText(units > 0 ?
boost::str(boost::format(CGI->generaltexth->allTexts[122]) % std::to_string(hero->calculateXp(units * expPerUnit[slot->serial]))) : ""; boost::str(boost::format(CGI->generaltexth->allTexts[122]) % std::to_string(hero->calculateXp(units * expPerUnit[slot->serial]))) : "");
} }
void CAltarCreatures::onOfferSliderMoved(int newVal) void CAltarCreatures::onOfferSliderMoved(int newVal)

View File

@ -11,7 +11,7 @@
#include "CTradeBase.h" #include "CTradeBase.h"
class CAltarCreatures : public CExperienceAltar, public CCreaturesSelling class CAltarCreatures : public CExperienceAltar, public CCreaturesSelling, public CMarketMisc
{ {
public: public:
CAltarCreatures(const IMarket * market, const CGHeroInstance * hero); CAltarCreatures(const IMarket * market, const CGHeroInstance * hero);
@ -25,10 +25,10 @@ private:
std::vector<int> unitsOnAltar; std::vector<int> unitsOnAltar;
std::vector<int> expPerUnit; std::vector<int> expPerUnit;
CMarketMisc::SelectionParams getSelectionParams();
void updateAltarSlot(const std::shared_ptr<CTradeableItem> & slot); void updateAltarSlot(const std::shared_ptr<CTradeableItem> & slot);
void readExpValues(); void readExpValues();
void updateControls(); void updateControls();
void updateSelected();
void onOfferSliderMoved(int newVal); void onOfferSliderMoved(int newVal);
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override; void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override;
}; };

View File

@ -27,6 +27,7 @@
CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance * hero) CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance * hero)
: CTradeBase(market, hero) : CTradeBase(market, hero)
, CResourcesSelling([this](const std::shared_ptr<CTradeableItem> & heroSlot){CArtifactsBuying::onSlotClickPressed(heroSlot, hLeft);})
, CMarketMisc([this](){return CArtifactsBuying::getSelectionParams();}) , CMarketMisc([this](){return CArtifactsBuying::getSelectionParams();})
{ {
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
@ -40,34 +41,16 @@ CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance
// Player's resources // Player's resources
assert(bidTradePanel); assert(bidTradePanel);
std::for_each(bidTradePanel->slots.cbegin(), bidTradePanel->slots.cend(), [this](auto & slot) bidTradePanel->moveTo(pos.topLeft() + Point(39, 184));
{ bidTradePanel->selectedSlot->image->moveTo(pos.topLeft() + Point(141, 454));
slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot)
{
CArtifactsBuying::onSlotClickPressed(heroSlot, hLeft);
};
});
bidTradePanel->moveTo(pos.topLeft() + Point(39, 182));
bidTradePanel->selectedImage->moveTo(pos.topLeft() + Point(141, 453));
// Artifacts panel // Artifacts panel
offerTradePanel = std::make_shared<ArtifactsPanel>([this](const std::shared_ptr<CTradeableItem> & newSlot) offerTradePanel = std::make_shared<ArtifactsPanel>([this](const std::shared_ptr<CTradeableItem> & newSlot)
{ {
CArtifactsBuying::onSlotClickPressed(newSlot, hRight); CArtifactsBuying::onSlotClickPressed(newSlot, hRight);
}, [this]() }, [this]()
{ {
// TODO move to parent CTradeBase::updateSubtitles(EMarketMode::RESOURCE_ARTIFACT);
if(hLeft)
for(const auto & slot : offerTradePanel->slots)
{
int h1, h2; //hlp variables for getting offer
this->market->getOffer(hLeft->id, slot->id, h1, h2, EMarketMode::RESOURCE_ARTIFACT);
offerTradePanel->updateOffer(*slot, h1, h2);
}
else
offerTradePanel->clearSubtitles();
}, market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT)); }, market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT));
offerTradePanel->deleteSlotsCheck = [this](const std::shared_ptr<CTradeableItem> & slot) offerTradePanel->deleteSlotsCheck = [this](const std::shared_ptr<CTradeableItem> & slot)
{ {
@ -75,7 +58,7 @@ CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance
}; };
offerTradePanel->moveTo(pos.topLeft() + Point(328, 182)); offerTradePanel->moveTo(pos.topLeft() + Point(328, 182));
CArtifactsBuying::updateSlots(); CTradeBase::updateSlots();
CMarketMisc::deselect(); CMarketMisc::deselect();
} }
@ -85,12 +68,6 @@ void CArtifactsBuying::makeDeal()
deselect(); deselect();
} }
void CArtifactsBuying::updateSlots()
{
CResourcesSelling::updateSlots();
offerTradePanel->updateSlots();
}
CMarketMisc::SelectionParams CArtifactsBuying::getSelectionParams() CMarketMisc::SelectionParams CArtifactsBuying::getSelectionParams()
{ {
if(hLeft && hRight) if(hLeft && hRight)

View File

@ -16,7 +16,6 @@ class CArtifactsBuying : public CResourcesSelling, public CMarketMisc
public: public:
CArtifactsBuying(const IMarket * market, const CGHeroInstance * hero); CArtifactsBuying(const IMarket * market, const CGHeroInstance * hero);
void makeDeal() override; void makeDeal() override;
void updateSlots() override;
private: private:
CMarketMisc::SelectionParams getSelectionParams(); CMarketMisc::SelectionParams getSelectionParams();

View File

@ -24,15 +24,16 @@
CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero) CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero)
: CTradeBase(market, hero) : CTradeBase(market, hero)
, CResourcesBuying([this](){CArtifactsSelling::updateSubtitles();}) , CResourcesBuying(
[this](const std::shared_ptr<CTradeableItem> & resSlot){CArtifactsSelling::onSlotClickPressed(resSlot, hRight);},
[this](){CTradeBase::updateSubtitles(EMarketMode::ARTIFACT_RESOURCE);})
, CMarketMisc([this](){return CArtifactsSelling::getSelectionParams();}) , CMarketMisc([this](){return CArtifactsSelling::getSelectionParams();})
{ {
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
deal = std::make_shared<CButton>(Point(270, 520), AnimationPath::builtin("TPMRKB.DEF"), deal = std::make_shared<CButton>(Point(270, 520), AnimationPath::builtin("TPMRKB.DEF"),
CGI->generaltexth->zelp[595], [this](){CArtifactsSelling::makeDeal();}); CGI->generaltexth->zelp[595], [this](){CArtifactsSelling::makeDeal();});
selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("artifact"), 10, 0, 136, 470); bidSelectedSlot = std::make_shared<CTradeableItem>(Rect(Point(123, 470), Point(69, 66)), EType::ARTIFACT_TYPE, 0, 0);
bidSelectedSubtitle = std::make_shared<CLabel>(157, 529, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
// Hero's artifacts // Hero's artifacts
heroArts = std::make_shared<CArtifactsOfHeroMarket>(Point(-361, 46)); heroArts = std::make_shared<CArtifactsOfHeroMarket>(Point(-361, 46));
@ -40,11 +41,13 @@ CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstanc
heroArts->selectArtCallback = [this](CArtPlace * artPlace) heroArts->selectArtCallback = [this](CArtPlace * artPlace)
{ {
assert(artPlace); assert(artPlace);
artForTrade = artPlace->getArt(); const auto artForTrade = artPlace->getArt();
assert(artForTrade.has_value()); assert(artForTrade);
bidSelectedSlot->setID(artForTrade->getTypeId().num);
hLeft = bidSelectedSlot;
if(hRight) if(hRight)
{ { // dublicate
this->market->getOffer(artForTrade.value()->getTypeId().num, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE); this->market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE);
deal->block(false); deal->block(false);
} }
CArtifactsSelling::updateSelected(); CArtifactsSelling::updateSelected();
@ -54,20 +57,11 @@ CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstanc
// Market resources panel // Market resources panel
assert(offerTradePanel); assert(offerTradePanel);
std::for_each(offerTradePanel->slots.cbegin(), offerTradePanel->slots.cend(), [this](auto & slot) offerTradePanel->moveTo(pos.topLeft() + Point(326, 184));
{ offerTradePanel->selectedSlot->moveTo(pos.topLeft() + Point(409, 473));
slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & resSlot)
{
CArtifactsSelling::onSlotClickPressed(resSlot, hRight);
};
});
offerTradePanel->selectedImage->moveTo(pos.topLeft() + Point(428, 479));
offerTradePanel->selectedSubtitle->moveTo(pos.topLeft() + Point(445, 526));
offerTradePanel->moveTo(pos.topLeft() + Point(326, 183));
CArtifactsSelling::updateSelected(); CArtifactsSelling::updateSelected();
CArtifactsSelling::deselect(); CMarketMisc::deselect();
} }
void CArtifactsSelling::makeDeal() void CArtifactsSelling::makeDeal()
@ -75,27 +69,21 @@ void CArtifactsSelling::makeDeal()
} }
void CArtifactsSelling::deselect()
{
CTradeBase::deselect();
artForTrade = std::nullopt;
}
void CArtifactsSelling::updateSelected() void CArtifactsSelling::updateSelected()
{ {
CMarketMisc::updateSelected(); CMarketMisc::updateSelected();
if(artForTrade.has_value() && hRight) if(hLeft && hRight)
{ {
bidSelectedSubtitle->setText(std::to_string(bidQty)); bidSelectedSlot->image->enable();
selectedImage->enable(); bidSelectedSlot->image->setFrame(CGI->artifacts()->getByIndex(hLeft->id)->getIconIndex());
selectedImage->setFrame(CGI->artifacts()->getByIndex(artForTrade.value()->getTypeId())->getIconIndex()); bidSelectedSlot->subtitle->setText(std::to_string(bidQty));
} }
else else
{ {
selectedImage->disable(); bidSelectedSlot->image->disable();
selectedImage->setFrame(0); bidSelectedSlot->image->setFrame(0);
bidSelectedSubtitle->setText(""); bidSelectedSlot->subtitle->clear();
} }
} }
@ -106,7 +94,7 @@ std::shared_ptr<CArtifactsOfHeroMarket> CArtifactsSelling::getAOHset() const
CMarketMisc::SelectionParams CArtifactsSelling::getSelectionParams() CMarketMisc::SelectionParams CArtifactsSelling::getSelectionParams()
{ {
if(artForTrade.has_value() && hRight) if(hLeft && hRight)
return std::make_tuple( return std::make_tuple(
std::nullopt, std::nullopt,
SelectionParamOneSide {std::to_string(offerQty), GameResID(hRight->id)} SelectionParamOneSide {std::to_string(offerQty), GameResID(hRight->id)}
@ -115,20 +103,6 @@ CMarketMisc::SelectionParams CArtifactsSelling::getSelectionParams()
return std::make_tuple(std::nullopt, std::nullopt); return std::make_tuple(std::nullopt, std::nullopt);
} }
void CArtifactsSelling::updateSubtitles()
{
if(artForTrade.has_value())
for(const auto & slot : offerTradePanel->slots)
{
int bidQty = 0;
int offerQty = 0;
market->getOffer(artForTrade.value()->getTypeId().num, slot->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE);
offerTradePanel->updateOffer(*slot, bidQty, offerQty);
}
else
offerTradePanel->clearSubtitles();
}
void CArtifactsSelling::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) void CArtifactsSelling::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
{ {
assert(newSlot); assert(newSlot);
@ -136,11 +110,11 @@ void CArtifactsSelling::onSlotClickPressed(const std::shared_ptr<CTradeableItem>
return; return;
CTradeBase::onSlotClickPressed(newSlot, hCurSlot); CTradeBase::onSlotClickPressed(newSlot, hCurSlot);
if(artForTrade.has_value()) if(hLeft)
{ {
if(hRight) if(hRight)
{ {
market->getOffer(artForTrade.value()->getTypeId().num, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE); market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE);
deal->block(false); deal->block(false);
} }
updateSelected(); updateSelected();

View File

@ -17,18 +17,14 @@ class CArtifactsSelling : public CResourcesBuying, public CMarketMisc
public: public:
CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero); CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero);
void makeDeal() override; void makeDeal() override;
void deselect() override;
void updateSelected(); void updateSelected();
std::shared_ptr<CArtifactsOfHeroMarket> getAOHset() const; std::shared_ptr<CArtifactsOfHeroMarket> getAOHset() const;
private: private:
std::shared_ptr<CArtifactsOfHeroMarket> heroArts; std::shared_ptr<CArtifactsOfHeroMarket> heroArts;
std::optional<const CArtifactInstance*> artForTrade;
std::shared_ptr<CAnimImage> selectedImage;
std::shared_ptr<CLabel> selectedSubtitle;
std::shared_ptr<CLabel> bidSelectedSubtitle; std::shared_ptr<CLabel> bidSelectedSubtitle;
std::shared_ptr<CTradeableItem> bidSelectedSlot;
void updateSubtitles();
CMarketMisc::SelectionParams getSelectionParams(); CMarketMisc::SelectionParams getSelectionParams();
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override; void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override;
}; };

View File

@ -28,7 +28,9 @@
CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero) CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero)
: CTradeBase(market, hero) : CTradeBase(market, hero)
, CResourcesBuying([this](){CResourcesBuying::updateSubtitles(EMarketMode::CREATURE_RESOURCE);}) , CResourcesBuying(
[this](const std::shared_ptr<CTradeableItem> & heroSlot){CFreelancerGuild::onSlotClickPressed(heroSlot, hLeft);},
[this](){CTradeBase::updateSubtitles(EMarketMode::CREATURE_RESOURCE);})
, CMarketMisc([this](){return CFreelancerGuild::getSelectionParams();}) , CMarketMisc([this](){return CFreelancerGuild::getSelectionParams();})
{ {
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
@ -49,6 +51,7 @@ CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance
// Hero creatures panel // Hero creatures panel
assert(bidTradePanel); assert(bidTradePanel);
bidTradePanel->moveTo(pos.topLeft() + Point(45, 123)); bidTradePanel->moveTo(pos.topLeft() + Point(45, 123));
bidTradePanel->selectedSlot->subtitle->moveBy(Point(0, -1));
bidTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1); bidTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1);
std::for_each(bidTradePanel->slots.cbegin(), bidTradePanel->slots.cend(), [this](auto & slot) std::for_each(bidTradePanel->slots.cbegin(), bidTradePanel->slots.cend(), [this](auto & slot)
{ {

View File

@ -26,7 +26,10 @@
CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance * hero) CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance * hero)
: CTradeBase(market, hero) : CTradeBase(market, hero)
, CResourcesBuying([this](){CMarketResources::updateSubtitles();}) , CResourcesBuying(
[this](const std::shared_ptr<CTradeableItem> & resSlot){CMarketResources::onSlotClickPressed(resSlot, hRight);},
[this](){CMarketResources::updateSubtitles();})
, CResourcesSelling([this](const std::shared_ptr<CTradeableItem> & heroSlot){CMarketResources::onSlotClickPressed(heroSlot, hLeft);})
, CMarketMisc([this](){return CMarketResources::getSelectionParams();}) , CMarketMisc([this](){return CMarketResources::getSelectionParams();})
{ {
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
@ -43,14 +46,7 @@ CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance
// Player's resources // Player's resources
assert(bidTradePanel); assert(bidTradePanel);
std::for_each(bidTradePanel->slots.cbegin(), bidTradePanel->slots.cend(), [this](auto & slot) bidTradePanel->moveTo(pos.topLeft() + Point(39, 182));
{
slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot)
{
CMarketResources::onSlotClickPressed(heroSlot, hLeft);
};
});
bidTradePanel->moveTo(pos.topLeft() + Point(39, 181));
// Market resources panel // Market resources panel
assert(offerTradePanel); assert(offerTradePanel);
@ -62,7 +58,7 @@ CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance
}; };
}); });
CResourcesSelling::updateSlots(); CTradeBase::updateSlots();
CMarketMisc::deselect(); CMarketMisc::deselect();
} }
@ -121,7 +117,7 @@ void CMarketResources::onSlotClickPressed(const std::shared_ptr<CTradeableItem>
void CMarketResources::updateSubtitles() void CMarketResources::updateSubtitles()
{ {
CResourcesBuying::updateSubtitles(EMarketMode::RESOURCE_RESOURCE); CTradeBase::updateSubtitles(EMarketMode::RESOURCE_RESOURCE);
if(hLeft) if(hLeft)
offerTradePanel->slots[hLeft->serial]->subtitle = CGI->generaltexth->allTexts[164]; // n/a offerTradePanel->slots[hLeft->serial]->subtitle->setText(CGI->generaltexth->allTexts[164]); // n/a
} }

View File

@ -12,6 +12,7 @@
#include "../MiscWidgets.h" #include "../MiscWidgets.h"
#include "../Images.h"
#include "../../gui/CGuiHandler.h" #include "../../gui/CGuiHandler.h"
#include "../../widgets/Buttons.h" #include "../../widgets/Buttons.h"
#include "../../widgets/Slider.h" #include "../../widgets/Slider.h"
@ -81,6 +82,28 @@ void CTradeBase::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newS
newSlot->selectSlot(true); newSlot->selectSlot(true);
} }
void CTradeBase::updateSlots()
{
if(bidTradePanel)
bidTradePanel->updateSlots();
if(offerTradePanel)
offerTradePanel->updateSlots();
}
void CTradeBase::updateSubtitles(EMarketMode marketMode)
{
if(hLeft)
for(const auto & slot : offerTradePanel->slots)
{
int bidQty = 0;
int offerQty = 0;
market->getOffer(hLeft->id, slot->id, bidQty, offerQty, marketMode);
offerTradePanel->updateOffer(*slot, bidQty, offerQty);
}
else
offerTradePanel->clearSubtitles();
};
CExperienceAltar::CExperienceAltar() CExperienceAltar::CExperienceAltar()
{ {
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
@ -116,55 +139,34 @@ bool CCreaturesSelling::slotDeletingCheck(const std::shared_ptr<CTradeableItem>
void CCreaturesSelling::updateSubtitle() void CCreaturesSelling::updateSubtitle()
{ {
for(auto & heroSlot : bidTradePanel->slots) for(auto & heroSlot : bidTradePanel->slots)
heroSlot->subtitle = std::to_string(this->hero->getStackCount(SlotID(heroSlot->serial))); heroSlot->subtitle->setText(std::to_string(this->hero->getStackCount(SlotID(heroSlot->serial))));
} }
void CCreaturesSelling::updateSlots() CResourcesBuying::CResourcesBuying(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
{ const TradePanelBase::UpdateSlotsFunctor & updSlotsCallback)
bidTradePanel->updateSlots();
}
CResourcesBuying::CResourcesBuying(TradePanelBase::UpdateSlotsFunctor callback)
{ {
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
offerTradePanel = std::make_shared<ResourcesPanel>([](const std::shared_ptr<CTradeableItem>&) {}, callback); offerTradePanel = std::make_shared<ResourcesPanel>(clickPressedCallback, updSlotsCallback);
offerTradePanel->moveTo(pos.topLeft() + Point(327, 181)); offerTradePanel->moveTo(pos.topLeft() + Point(327, 182));
labels.emplace_back(std::make_shared<CLabel>(445, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168])); labels.emplace_back(std::make_shared<CLabel>(445, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168]));
} }
void CResourcesBuying::updateSubtitles(EMarketMode marketMode) CResourcesSelling::CResourcesSelling(const CTradeableItem::ClickPressedFunctor & clickPressedCallback)
{
if(hLeft)
for(const auto & slot : offerTradePanel->slots)
{
int h1, h2; //hlp variables for getting offer
market->getOffer(hLeft->id, slot->id, h1, h2, marketMode);
offerTradePanel->updateOffer(*slot, h1, h2);
}
else
offerTradePanel->clearSubtitles();
};
CResourcesSelling::CResourcesSelling()
{ {
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
bidTradePanel = std::make_shared<ResourcesPanel>([](const std::shared_ptr<CTradeableItem>&) {}, [this]() bidTradePanel = std::make_shared<ResourcesPanel>(clickPressedCallback, std::bind(&CResourcesSelling::updateSubtitle, this));
{
for(const auto & slot : bidTradePanel->slots)
slot->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(slot->serial)));
});
labels.emplace_back(std::make_shared<CLabel>(156, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[270])); labels.emplace_back(std::make_shared<CLabel>(156, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[270]));
} }
void CResourcesSelling::updateSlots() void CResourcesSelling::updateSubtitle()
{ {
bidTradePanel->updateSlots(); for(const auto & slot : bidTradePanel->slots)
slot->subtitle->setText(std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(slot->serial))));
} }
CMarketMisc::CMarketMisc(SelectionParamsFunctor callback) CMarketMisc::CMarketMisc(const SelectionParamsFunctor & callback)
: selectionParamsCallback(callback) : selectionParamsCallback(callback)
{ {
} }
@ -184,12 +186,12 @@ void CMarketMisc::updateSelected()
std::optional<size_t> lImageIndex = std::nullopt; std::optional<size_t> lImageIndex = std::nullopt;
if(params.has_value()) if(params.has_value())
{ {
tradePanel->selectedSubtitle->setText(params.value().text); tradePanel->setSelectedSubtitleText(params.value().text);
lImageIndex = params.value().imageIndex; lImageIndex = params.value().imageIndex;
} }
else else
{ {
tradePanel->selectedSubtitle->setText(""); tradePanel->clearSelectedSubtitleText();
} }
tradePanel->setSelectedFrameIndex(lImageIndex); tradePanel->setSelectedFrameIndex(lImageIndex);
}; };

View File

@ -21,7 +21,7 @@ VCMI_LIB_NAMESPACE_END
class CButton; class CButton;
class CSlider; class CSlider;
class CTradeBase class CTradeBase : public CIntObject
{ {
public: public:
const IMarket * market; const IMarket * market;
@ -49,11 +49,12 @@ public:
virtual void makeDeal() = 0; virtual void makeDeal() = 0;
virtual void deselect(); virtual void deselect();
virtual void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot); virtual void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot);
virtual void updateSlots() {}; // TODO make pure virtual virtual void updateSlots();
virtual void updateSubtitles(EMarketMode marketMode);
}; };
// Market subclasses // Market subclasses
class CExperienceAltar : virtual public CTradeBase, virtual public CIntObject class CExperienceAltar : virtual public CTradeBase
{ {
public: public:
std::shared_ptr<CLabel> expToLevel; std::shared_ptr<CLabel> expToLevel;
@ -66,30 +67,29 @@ public:
virtual TExpType calcExpAltarForHero() = 0; virtual TExpType calcExpAltarForHero() = 0;
}; };
class CCreaturesSelling : virtual public CTradeBase, virtual public CIntObject class CCreaturesSelling : virtual public CTradeBase
{ {
public: public:
CCreaturesSelling(); CCreaturesSelling();
bool slotDeletingCheck(const std::shared_ptr<CTradeableItem> & slot); bool slotDeletingCheck(const std::shared_ptr<CTradeableItem> & slot);
void updateSubtitle(); void updateSubtitle();
void updateSlots() override;
}; };
class CResourcesBuying : virtual public CTradeBase, virtual public CIntObject class CResourcesBuying : virtual public CTradeBase
{ {
public: public:
CResourcesBuying(TradePanelBase::UpdateSlotsFunctor callback); CResourcesBuying(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
void updateSubtitles(EMarketMode marketMode); const TradePanelBase::UpdateSlotsFunctor & updSlotsCallback);
}; };
class CResourcesSelling : virtual public CTradeBase, virtual public CIntObject class CResourcesSelling : virtual public CTradeBase
{ {
public: public:
CResourcesSelling(); CResourcesSelling(const CTradeableItem::ClickPressedFunctor & clickPressedCallback);
void updateSlots() override; void updateSubtitle();
}; };
class CMarketMisc : virtual public CTradeBase, virtual public CIntObject class CMarketMisc : virtual public CTradeBase
{ {
public: public:
struct SelectionParamOneSide struct SelectionParamOneSide
@ -98,9 +98,9 @@ public:
int imageIndex; int imageIndex;
}; };
using SelectionParams = std::tuple<std::optional<const SelectionParamOneSide>, std::optional<const SelectionParamOneSide>>; using SelectionParams = std::tuple<std::optional<const SelectionParamOneSide>, std::optional<const SelectionParamOneSide>>;
using SelectionParamsFunctor = std::function<SelectionParams()>; using SelectionParamsFunctor = std::function<const SelectionParams()>;
CMarketMisc(SelectionParamsFunctor callback); CMarketMisc(const SelectionParamsFunctor & callback);
void deselect() override; void deselect() override;
void updateSelected(); void updateSelected();

View File

@ -25,6 +25,7 @@
CTransferResources::CTransferResources(const IMarket * market, const CGHeroInstance * hero) CTransferResources::CTransferResources(const IMarket * market, const CGHeroInstance * hero)
: CTradeBase(market, hero) : CTradeBase(market, hero)
, CResourcesSelling([this](const std::shared_ptr<CTradeableItem> & heroSlot){CTransferResources::onSlotClickPressed(heroSlot, hLeft);})
, CMarketMisc([this](){return CTransferResources::getSelectionParams();}) , CMarketMisc([this](){return CTransferResources::getSelectionParams();})
{ {
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
@ -42,23 +43,16 @@ CTransferResources::CTransferResources(const IMarket * market, const CGHeroInsta
// Player's resources // Player's resources
assert(bidTradePanel); assert(bidTradePanel);
std::for_each(bidTradePanel->slots.cbegin(), bidTradePanel->slots.cend(), [this](auto & slot) bidTradePanel->moveTo(pos.topLeft() + Point(40, 183));
{
slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot)
{
CTransferResources::onSlotClickPressed(heroSlot, hLeft);
};
});
bidTradePanel->moveTo(pos.topLeft() + Point(40, 182));
// Players panel // Players panel
offerTradePanel = std::make_shared<PlayersPanel>([this](const std::shared_ptr<CTradeableItem> & heroSlot) offerTradePanel = std::make_shared<PlayersPanel>([this](const std::shared_ptr<CTradeableItem> & heroSlot)
{ {
CTransferResources::onSlotClickPressed(heroSlot, hRight); CTransferResources::onSlotClickPressed(heroSlot, hRight);
}); });
offerTradePanel->moveTo(pos.topLeft() + Point(333, 83)); offerTradePanel->moveTo(pos.topLeft() + Point(333, 84));
CResourcesSelling::updateSlots(); CTradeBase::updateSlots();
CTransferResources::deselect(); CTransferResources::deselect();
} }

View File

@ -23,14 +23,12 @@
#include "../../../lib/CGeneralTextHandler.h" #include "../../../lib/CGeneralTextHandler.h"
#include "../../../lib/mapObjects/CGHeroInstance.h" #include "../../../lib/mapObjects/CGHeroInstance.h"
CTradeableItem::CTradeableItem(const Rect & area, EType Type, int ID, bool Left, int Serial) CTradeableItem::CTradeableItem(const Rect & area, EType Type, int ID, int Serial)
: SelectableSlot(area, Point(1, 1)) : SelectableSlot(area, Point(1, 2))
, artInstance(nullptr) , artInstance(nullptr)
, 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)
, serial(Serial) , serial(Serial)
, left(Left)
, downSelection(false)
{ {
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
@ -38,6 +36,7 @@ CTradeableItem::CTradeableItem(const Rect & area, EType Type, int ID, bool Left,
addUsedEvents(HOVER); addUsedEvents(HOVER);
addUsedEvents(SHOW_POPUP); addUsedEvents(SHOW_POPUP);
subtitle = std::make_shared<CLabel>(0, 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
setType(Type); setType(Type);
this->pos.w = area.w; this->pos.w = area.w;
@ -60,6 +59,28 @@ void CTradeableItem::setType(EType newType)
{ {
image = std::make_shared<CAnimImage>(getFilename(), getIndex()); image = std::make_shared<CAnimImage>(getFilename(), getIndex());
} }
switch(type)
{
case EType::RESOURCE:
subtitle->moveTo(pos.topLeft() + Point(35, 55));
image->moveTo(pos.topLeft() + Point(19, 8));
break;
case EType::CREATURE_PLACEHOLDER:
case EType::CREATURE:
subtitle->moveTo(pos.topLeft() + Point(30, 77));
break;
case EType::PLAYER:
subtitle->moveTo(pos.topLeft() + Point(31, 76));
break;
case EType::ARTIFACT_PLACEHOLDER:
case EType::ARTIFACT_INSTANCE:
break;
case EType::ARTIFACT_TYPE:
subtitle->moveTo(pos.topLeft() + Point(35, 57));
image->moveTo(pos.topLeft() + Point(13, 0));
break;
}
} }
} }
@ -122,66 +143,12 @@ int CTradeableItem::getIndex()
} }
} }
void CTradeableItem::showAll(Canvas & to)
{
Point posToBitmap;
Point posToSubCenter;
switch(type)
{
case EType::RESOURCE:
posToBitmap = Point(19, 9);
posToSubCenter = Point(35, 57);
break;
case EType::CREATURE_PLACEHOLDER:
case EType::CREATURE:
posToSubCenter = Point(29, 77);
break;
case EType::PLAYER:
posToSubCenter = Point(31, 77);
break;
case EType::ARTIFACT_PLACEHOLDER:
case EType::ARTIFACT_INSTANCE:
posToSubCenter = Point(22, 51);
if (downSelection)
posToSubCenter.y += 8;
break;
case EType::ARTIFACT_TYPE:
posToSubCenter = Point(35, 57);
posToBitmap = Point(13, 0);
break;
}
if(image)
{
image->moveTo(pos.topLeft() + posToBitmap);
CIntObject::showAll(to);
}
to.drawText(pos.topLeft() + posToSubCenter, FONT_SMALL, Colors::WHITE, ETextAlignment::CENTER, subtitle);
}
void CTradeableItem::clickPressed(const Point & cursorPosition) void CTradeableItem::clickPressed(const Point & cursorPosition)
{ {
if(clickPressedCallback) if(clickPressedCallback)
clickPressedCallback(shared_from_this()); clickPressedCallback(shared_from_this());
} }
void CTradeableItem::showAllAt(const Point & dstPos, const std::string & customSub, Canvas & to)
{
Rect oldPos = pos;
std::string oldSub = subtitle;
downSelection = true;
moveTo(dstPos);
subtitle = customSub;
showAll(to);
downSelection = false;
moveTo(oldPos.topLeft());
subtitle = oldSub;
}
void CTradeableItem::hover(bool on) void CTradeableItem::hover(bool on)
{ {
if(!on) if(!on)
@ -228,28 +195,7 @@ void CTradeableItem::showPopupWindow(const Point & cursorPosition)
} }
} }
std::string CTradeableItem::getName(int number) const const CArtifactInstance* CTradeableItem::getArtInstance() const
{
switch(type)
{
case EType::PLAYER:
return CGI->generaltexth->capColors[id];
case EType::RESOURCE:
return CGI->generaltexth->restypes[id];
case EType::CREATURE:
if (number == 1)
return CGI->creh->objects[id]->getNameSingularTranslated();
else
return CGI->creh->objects[id]->getNamePluralTranslated();
case EType::ARTIFACT_TYPE:
case EType::ARTIFACT_INSTANCE:
return CGI->artifacts()->getByIndex(id)->getNameTranslated();
}
logGlobal->error("Invalid trade item type: %d", (int)type);
return "";
}
const CArtifactInstance * CTradeableItem::getArtInstance() const
{ {
switch(type) switch(type)
{ {
@ -289,52 +235,62 @@ void TradePanelBase::deselect()
void TradePanelBase::clearSubtitles() void TradePanelBase::clearSubtitles()
{ {
for(const auto & slot : slots) for(const auto & slot : slots)
slot->subtitle.clear(); slot->subtitle->clear();
} }
void TradePanelBase::updateOffer(CTradeableItem & slot, int cost, int qty) void TradePanelBase::updateOffer(CTradeableItem & slot, int cost, int qty)
{ {
slot.subtitle = std::to_string(qty); std::string subtitle = std::to_string(qty);
if(cost != 1) if(cost != 1)
{ {
slot.subtitle.append("/"); subtitle.append("/");
slot.subtitle.append(std::to_string(cost)); subtitle.append(std::to_string(cost));
} }
slot.subtitle->setText(subtitle);
} }
void TradePanelBase::setSelectedFrameIndex(std::optional<size_t> index) void TradePanelBase::setSelectedFrameIndex(const std::optional<size_t> & index)
{ {
if(index.has_value()) if(index.has_value())
{ {
selectedImage->enable(); selectedSlot->image->enable();
selectedImage->setFrame(index.value()); selectedSlot->image->setFrame(index.value());
} }
else else
{ {
selectedImage->disable(); selectedSlot->image->disable();
selectedImage->setFrame(0); selectedSlot->image->setFrame(0);
} }
} }
ResourcesPanel::ResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles) void TradePanelBase::setSelectedSubtitleText(const std::string & text)
{
selectedSlot->subtitle->setText(text);
}
void TradePanelBase::clearSelectedSubtitleText()
{
selectedSlot->subtitle->clear();
}
ResourcesPanel::ResourcesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
const 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)
{ {
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[res.num], slotDimension), auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[res.num], slotDimension), EType::RESOURCE, res.num, res.num));
EType::RESOURCE, res.num, true, res.num));
slot->clickPressedCallback = clickPressedCallback; slot->clickPressedCallback = clickPressedCallback;
slot->setSelectionWidth(selectionWidth); slot->setSelectionWidth(selectionWidth);
} }
updateSlotsCallback = updateSubtitles; updateSlotsCallback = updateSubtitles;
selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("RESOURCE"), 0, 0, selectedImagePos.x, selectedImagePos.y); selectedSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::RESOURCE, 0, 0);
selectedSubtitle = std::make_shared<CLabel>(selectedSubtitlePos.x, selectedSubtitlePos.y, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
} }
ArtifactsPanel::ArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles, ArtifactsPanel::ArtifactsPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
const std::vector<TradeItemBuy> & arts) const UpdateSlotsFunctor & updateSubtitles, const std::vector<TradeItemBuy> & arts)
{ {
assert(slotsForTrade == slotsPos.size()); assert(slotsForTrade == slotsPos.size());
assert(slotsForTrade == arts.size()); assert(slotsForTrade == arts.size());
@ -346,17 +302,16 @@ ArtifactsPanel::ArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedC
if(artType != ArtifactID::NONE) if(artType != ArtifactID::NONE)
{ {
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[slotIdx], slotDimension), auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[slotIdx], slotDimension),
EType::ARTIFACT_TYPE, artType, false, slotIdx)); EType::ARTIFACT_TYPE, artType, slotIdx));
slot->clickPressedCallback = clickPressedCallback; slot->clickPressedCallback = clickPressedCallback;
slot->setSelectionWidth(selectionWidth); slot->setSelectionWidth(selectionWidth);
} }
} }
updateSlotsCallback = updateSubtitles; updateSlotsCallback = updateSubtitles;
selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("artifact"), 0, 0, selectedImagePos.x, selectedImagePos.y); selectedSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::ARTIFACT_TYPE, 0, 0);
selectedSubtitle = std::make_shared<CLabel>(selectedSubtitlePos.x, selectedSubtitlePos.y, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
} }
PlayersPanel::PlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback) PlayersPanel::PlayersPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback)
{ {
assert(PlayerColor::PLAYER_LIMIT_I <= slotsPos.size() + 1); assert(PlayerColor::PLAYER_LIMIT_I <= slotsPos.size() + 1);
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
@ -372,17 +327,16 @@ PlayersPanel::PlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCallb
int slotNum = 0; int slotNum = 0;
for(auto & slot : slots) for(auto & slot : slots)
{ {
slot = std::make_shared<CTradeableItem>(Rect(slotsPos[slotNum], slotDimension), EType::PLAYER, players[slotNum].num, false, slotNum); slot = std::make_shared<CTradeableItem>(Rect(slotsPos[slotNum], slotDimension), EType::PLAYER, players[slotNum].num, slotNum);
slot->clickPressedCallback = clickPressedCallback; slot->clickPressedCallback = clickPressedCallback;
slot->setSelectionWidth(selectionWidth); slot->setSelectionWidth(selectionWidth);
slot->subtitle = CGI->generaltexth->capColors[players[slotNum].num]; slot->subtitle->setText(CGI->generaltexth->capColors[players[slotNum].num]);
slotNum++; slotNum++;
} }
selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("CREST58"), 0, 0, selectedImagePos.x, selectedImagePos.y); selectedSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::PLAYER, 0, 0);
selectedSubtitle = std::make_shared<CLabel>(selectedSubtitlePos.x, selectedSubtitlePos.y, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
} }
CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, const slotsData & initialSlots) CreaturesPanel::CreaturesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const slotsData & initialSlots)
{ {
assert(initialSlots.size() <= GameConstants::ARMY_SIZE); assert(initialSlots.size() <= GameConstants::ARMY_SIZE);
assert(slotsPos.size() <= GameConstants::ARMY_SIZE); assert(slotsPos.size() <= GameConstants::ARMY_SIZE);
@ -391,17 +345,16 @@ CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedC
for(const auto & [creatureId, slotId, creaturesNum] : initialSlots) for(const auto & [creatureId, slotId, creaturesNum] : initialSlots)
{ {
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[slotId.num], slotDimension), auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[slotId.num], slotDimension),
creaturesNum == 0 ? EType::CREATURE_PLACEHOLDER : EType::CREATURE, creatureId.num, true, slotId)); creaturesNum == 0 ? EType::CREATURE_PLACEHOLDER : EType::CREATURE, creatureId.num, slotId));
slot->clickPressedCallback = clickPressedCallback; slot->clickPressedCallback = clickPressedCallback;
if(creaturesNum != 0) if(creaturesNum != 0)
slot->subtitle = std::to_string(creaturesNum); slot->subtitle->setText(std::to_string(creaturesNum));
slot->setSelectionWidth(selectionWidth); slot->setSelectionWidth(selectionWidth);
} }
selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("TWCRPORT"), 0, 0, selectedImagePos.x, selectedImagePos.y); selectedSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::CREATURE, 0, 0);
selectedSubtitle = std::make_shared<CLabel>(selectedSubtitlePos.x, selectedSubtitlePos.y, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
} }
CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, CreaturesPanel::CreaturesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
const std::vector<std::shared_ptr<CTradeableItem>> & srcSlots, bool emptySlots) const std::vector<std::shared_ptr<CTradeableItem>> & srcSlots, bool emptySlots)
{ {
assert(slots.size() <= GameConstants::ARMY_SIZE); assert(slots.size() <= GameConstants::ARMY_SIZE);
@ -410,11 +363,10 @@ CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedC
for(const auto & srcSlot : srcSlots) for(const auto & srcSlot : srcSlots)
{ {
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[srcSlot->serial], srcSlot->pos.dimensions()), auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[srcSlot->serial], srcSlot->pos.dimensions()),
emptySlots ? EType::CREATURE_PLACEHOLDER : EType::CREATURE, srcSlot->id, true, srcSlot->serial)); emptySlots ? EType::CREATURE_PLACEHOLDER : EType::CREATURE, srcSlot->id, srcSlot->serial));
slot->clickPressedCallback = clickPressedCallback; slot->clickPressedCallback = clickPressedCallback;
slot->subtitle = emptySlots ? "" : srcSlot->subtitle; slot->subtitle->setText(emptySlots ? "" : srcSlot->subtitle->getText());
slot->setSelectionWidth(selectionWidth); slot->setSelectionWidth(selectionWidth);
} }
selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("TWCRPORT"), 0, 0, selectedImagePos.x, selectedImagePos.y); selectedSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::CREATURE, 0, 0);
selectedSubtitle = std::make_shared<CLabel>(selectedSubtitlePos.x, selectedSubtitlePos.y, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
} }

View File

@ -31,8 +31,7 @@ public:
EType type; EType type;
int id; int id;
const int serial; const int serial;
const bool left; std::shared_ptr<CLabel> subtitle;
std::string subtitle;
ClickPressedFunctor clickPressedCallback; ClickPressedFunctor clickPressedCallback;
void setType(EType newType); void setType(EType newType);
@ -41,16 +40,10 @@ public:
const CArtifactInstance * getArtInstance() const; const CArtifactInstance * getArtInstance() const;
void setArtInstance(const CArtifactInstance * art); void setArtInstance(const CArtifactInstance * art);
bool downSelection;
void showAllAt(const Point & dstPos, const std::string & customSub, Canvas & to);
void showPopupWindow(const Point & cursorPosition) override; void showPopupWindow(const Point & cursorPosition) override;
void hover(bool on) override; void hover(bool on) override;
void showAll(Canvas & to) override;
void clickPressed(const Point & cursorPosition) override; void clickPressed(const Point & cursorPosition) override;
std::string getName(int number = -1) const; CTradeableItem(const Rect & area, EType Type, int ID, int Serial);
CTradeableItem(const Rect & area, EType Type, int ID, bool Left, int Serial);
}; };
class TradePanelBase : public CIntObject class TradePanelBase : public CIntObject
@ -64,14 +57,15 @@ public:
DeleteSlotsCheck deleteSlotsCheck; DeleteSlotsCheck deleteSlotsCheck;
std::shared_ptr<CTradeableItem> selected; std::shared_ptr<CTradeableItem> selected;
const int selectionWidth = 2; const int selectionWidth = 2;
std::shared_ptr<CAnimImage> selectedImage; std::shared_ptr<CTradeableItem> selectedSlot;
std::shared_ptr<CLabel> selectedSubtitle;
virtual void updateSlots(); virtual void updateSlots();
virtual void deselect(); virtual void deselect();
virtual void clearSubtitles(); virtual void clearSubtitles();
void updateOffer(CTradeableItem & slot, int, int); void updateOffer(CTradeableItem & slot, int, int);
void setSelectedFrameIndex(std::optional<size_t> index); void setSelectedFrameIndex(const std::optional<size_t> & index);
void setSelectedSubtitleText(const std::string & text);
void clearSelectedSubtitleText();
}; };
class ResourcesPanel : public TradePanelBase class ResourcesPanel : public TradePanelBase
@ -89,11 +83,10 @@ class ResourcesPanel : public TradePanelBase
Point(83, 158) Point(83, 158)
}; };
const Point slotDimension = Point(69, 66); const Point slotDimension = Point(69, 66);
const Point selectedImagePos = Point(101, 276); const Point selectedPos = Point(83, 267);
const Point selectedSubtitlePos = Point(118, 324);
public: public:
ResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles); ResourcesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const UpdateSlotsFunctor & updateSubtitles);
}; };
class ArtifactsPanel : public TradePanelBase class ArtifactsPanel : public TradePanelBase
@ -106,12 +99,11 @@ class ArtifactsPanel : public TradePanelBase
}; };
const size_t slotsForTrade = 7; const size_t slotsForTrade = 7;
const Point slotDimension = Point(69, 66); const Point slotDimension = Point(69, 66);
const Point selectedImagePos = Point(96, 266); const Point selectedPos = Point(83, 266);
const Point selectedSubtitlePos = Point(118, 324);
public: public:
ArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles, ArtifactsPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
const std::vector<TradeItemBuy> & arts); const UpdateSlotsFunctor & updateSubtitles, const std::vector<TradeItemBuy> & arts);
}; };
class PlayersPanel : public TradePanelBase class PlayersPanel : public TradePanelBase
@ -123,11 +115,10 @@ class PlayersPanel : public TradePanelBase
Point(83, 236) Point(83, 236)
}; };
const Point slotDimension = Point(58, 64); const Point slotDimension = Point(58, 64);
const Point selectedImagePos = Point(83, 368); const Point selectedPos = Point(83, 367);
const Point selectedSubtitlePos = Point(112, 443);
public: public:
explicit PlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback); explicit PlayersPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback);
}; };
class CreaturesPanel : public TradePanelBase class CreaturesPanel : public TradePanelBase
@ -138,14 +129,13 @@ class CreaturesPanel : public TradePanelBase
Point(0, 98), Point(83, 98), Point(166, 98), Point(0, 98), Point(83, 98), Point(166, 98),
Point(83, 196) Point(83, 196)
}; };
const Point slotDimension = Point(58, 64); const Point slotDimension = Point(59, 64);
const Point selectedImagePos = Point(83, 327); const Point selectedPos = Point(83, 327);
const Point selectedSubtitlePos = Point(113, 403);
public: public:
using slotsData = std::vector<std::tuple<CreatureID, SlotID, int>>; using slotsData = std::vector<std::tuple<CreatureID, SlotID, int>>;
CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, const slotsData & initialSlots); CreaturesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const slotsData & initialSlots);
CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, CreaturesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
const std::vector<std::shared_ptr<CTradeableItem>> & srcSlots, bool emptySlots = true); const std::vector<std::shared_ptr<CTradeableItem>> & srcSlots, bool emptySlots = true);
}; };

View File

@ -69,6 +69,8 @@ void CMarketWindow::updateGarrisons()
{ {
if(guild) if(guild)
guild->updateSlots(); guild->updateSlots();
if(altar)
altar->updateSlots();
} }
void CMarketWindow::resourceChanged() void CMarketWindow::resourceChanged()
@ -154,17 +156,6 @@ void CMarketWindow::createChangeModeButtons(EMarketMode currentMode, const IMark
} }
} }
void CMarketWindow::createInternals(EMarketMode mode, const IMarket * market, const CGHeroInstance * hero)
{
background->center();
pos = background->pos;
this->market->setRedrawParent(true);
createChangeModeButtons(mode, market, hero);
quitButton = std::make_shared<CButton>(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"),
CGI->generaltexth->zelp[600], [this]() {close(); }, EShortcut::GLOBAL_RETURN);
redraw();
}
void CMarketWindow::createArtifactsBuying(const IMarket * market, const CGHeroInstance * hero) void CMarketWindow::createArtifactsBuying(const IMarket * market, const CGHeroInstance * hero)
{ {
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE); OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);

View File

@ -9,7 +9,8 @@
*/ */
#pragma once #pragma once
#include "CTradeWindow.h" #include "../widgets/markets/CTradeBase.h"
#include "CWindowObject.h"
#include "CAltarWindow.h" #include "CAltarWindow.h"
class CArtifactsBuying; class CArtifactsBuying;
@ -30,7 +31,6 @@ public:
private: private:
void createChangeModeButtons(EMarketMode currentMode, const IMarket * market, const CGHeroInstance * hero); void createChangeModeButtons(EMarketMode currentMode, const IMarket * market, const CGHeroInstance * hero);
void createInternals(EMarketMode mode, const IMarket * market, const CGHeroInstance * hero);
void createArtifactsBuying(const IMarket * market, const CGHeroInstance * hero); void createArtifactsBuying(const IMarket * market, const CGHeroInstance * hero);
void createArtifactsSelling(const IMarket * market, const CGHeroInstance * hero); void createArtifactsSelling(const IMarket * market, const CGHeroInstance * hero);
@ -47,7 +47,6 @@ private:
std::function<void()> windowClosedCallback; std::function<void()> windowClosedCallback;
const Point quitButtonPos = Point(516, 520); const Point quitButtonPos = Point(516, 520);
std::shared_ptr<CMarketplaceWindow> market;
std::shared_ptr<CFreelancerGuild> guild; std::shared_ptr<CFreelancerGuild> guild;
std::shared_ptr<CMarketResources> resRes; std::shared_ptr<CMarketResources> resRes;
std::shared_ptr<CTransferResources> trRes; std::shared_ptr<CTransferResources> trRes;

View File

@ -1,574 +0,0 @@
/*
* CTradeWindow.cpp, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#include "StdInc.h"
#include "CTradeWindow.h"
#include "../gui/CGuiHandler.h"
#include "../gui/CursorHandler.h"
#include "../render/Canvas.h"
#include "../gui/Shortcut.h"
#include "../gui/WindowHandler.h"
#include "../widgets/Buttons.h"
#include "../widgets/Slider.h"
#include "../widgets/TextControls.h"
#include "../CGameInfo.h"
#include "../CPlayerInterface.h"
#include "../../CCallback.h"
#include "../../lib/CGeneralTextHandler.h"
#include "../../lib/CHeroHandler.h"
#include "../../lib/mapObjects/CGHeroInstance.h"
#include "../../lib/mapObjects/CGTownInstance.h"
#include "../../lib/mapObjects/CGMarket.h"
CTradeWindow::CTradeWindow(const ImagePath & bgName, const IMarket *Market, const CGHeroInstance *Hero, const std::function<void()> & onWindowClosed, EMarketMode Mode):
CTradeBase(Market, Hero),
CWindowObject(PLAYER_COLORED, bgName),
onWindowClosed(onWindowClosed),
readyToTrade(false)
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
mode = Mode;
initTypes();
}
void CTradeWindow::initTypes()
{
switch(mode)
{
case EMarketMode::RESOURCE_RESOURCE:
itemsType[1] = EType::RESOURCE;
itemsType[0] = EType::RESOURCE;
break;
case EMarketMode::RESOURCE_PLAYER:
itemsType[1] = EType::RESOURCE;
itemsType[0] = EType::PLAYER;
break;
case EMarketMode::CREATURE_RESOURCE:
itemsType[1] = EType::CREATURE;
itemsType[0] = EType::RESOURCE;
break;
case EMarketMode::RESOURCE_ARTIFACT:
itemsType[1] = EType::RESOURCE;
itemsType[0] = EType::ARTIFACT_TYPE;
break;
case EMarketMode::ARTIFACT_RESOURCE:
itemsType[1] = EType::ARTIFACT_INSTANCE;
itemsType[0] = EType::RESOURCE;
break;
}
}
void CTradeWindow::initItems(bool Left)
{
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE);
if(Left && (itemsType[1] == EType::ARTIFACT_TYPE || itemsType[1] == EType::ARTIFACT_INSTANCE))
{
if(mode == EMarketMode::ARTIFACT_RESOURCE)
{
auto item = std::make_shared<CTradeableItem>(Rect(Point(137, 469), Point()), itemsType[Left], -1, 1, 0);
item->recActions &= ~(UPDATE | SHOWALL);
items[Left].push_back(item);
}
}
else
{
auto updRightSub = [this](EMarketMode marketMode)
{
if(hLeft)
for(const auto & slot : offerTradePanel->slots)
{
int h1, h2; //hlp variables for getting offer
market->getOffer(hLeft->id, slot->id, h1, h2, marketMode);
offerTradePanel->updateOffer(*slot, h1, h2);
}
else
offerTradePanel->clearSubtitles();
};
auto clickPressedTradePanel = [this](const std::shared_ptr<CTradeableItem> & newSlot, bool left)
{
CTradeBase::onSlotClickPressed(newSlot, left ? hLeft : hRight);
selectionChanged(left);
};
if(Left && (mode == EMarketMode::RESOURCE_ARTIFACT || mode == EMarketMode::RESOURCE_PLAYER))
{
bidTradePanel = std::make_shared<ResourcesPanel>(
[clickPressedTradePanel](const std::shared_ptr<CTradeableItem> & newSlot)
{
clickPressedTradePanel(newSlot, true);
},
[this]()
{
for(const auto & slot : bidTradePanel->slots)
slot->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(slot->serial)));
});
bidTradePanel->moveBy(Point(39, 182));
bidTradePanel->updateSlots();
}
else if(!Left && (mode == EMarketMode::ARTIFACT_RESOURCE))
{
offerTradePanel = std::make_shared<ResourcesPanel>(std::bind(clickPressedTradePanel, _1, false),
std::bind(updRightSub, EMarketMode::ARTIFACT_RESOURCE));
offerTradePanel->moveBy(Point(327, 181));
}
else if(!Left && mode == EMarketMode::RESOURCE_ARTIFACT)
{
offerTradePanel = std::make_shared<ArtifactsPanel>(std::bind(clickPressedTradePanel, _1, false),
std::bind(updRightSub, EMarketMode::RESOURCE_ARTIFACT), market->availableItemsIds(mode));
offerTradePanel->moveBy(Point(327, 181));
offerTradePanel->deleteSlotsCheck = [this](const std::shared_ptr<CTradeableItem> & slot)
{
return vstd::contains(market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT), ArtifactID(slot->id)) ? false : true;
};
}
}
}
void CTradeWindow::initSubs(bool Left)
{
if (itemsType[Left] == EType::RESOURCE || itemsType[Left] == EType::ARTIFACT_TYPE)
{
if(Left)
bidTradePanel->updateSlots();
else
offerTradePanel->updateSlots();
return;
}
}
void CTradeWindow::showAll(Canvas & to)
{
CWindowObject::showAll(to);
if(readyToTrade)
{
if(hLeft)
hLeft->showAllAt(pos.topLeft() + selectionOffset(true), updateSlotSubtitle(true), to);
if(hRight)
hRight->showAllAt(pos.topLeft() + selectionOffset(false), updateSlotSubtitle(false), to);
}
}
void CTradeWindow::close()
{
if (onWindowClosed)
onWindowClosed();
CWindowObject::close();
}
void CTradeWindow::setMode(EMarketMode Mode)
{
const IMarket *m = market;
const CGHeroInstance *h = hero;
const auto functor = onWindowClosed;
onWindowClosed = nullptr; // don't call on closing of this window - pass it to next window
close();
}
void CTradeWindow::artifactSelected(CArtPlace * slot)
{
assert(mode == EMarketMode::ARTIFACT_RESOURCE);
items[1][0]->setArtInstance(slot->getArt());
if(slot->getArt())
hLeft = items[1][0];
else
hLeft = nullptr;
selectionChanged(true);
}
ImagePath CMarketplaceWindow::getBackgroundForMode(EMarketMode mode)
{
switch(mode)
{
case EMarketMode::RESOURCE_PLAYER:
return ImagePath::builtin("TPMRKPTS.bmp");
case EMarketMode::RESOURCE_ARTIFACT:
return ImagePath::builtin("TPMRKABS.bmp");
case EMarketMode::ARTIFACT_RESOURCE:
return ImagePath::builtin("TPMRKASS.bmp");
}
assert(0);
return {};
}
CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInstance * Hero, const std::function<void()> & onWindowClosed, EMarketMode Mode)
: CTradeWindow(getBackgroundForMode(Mode), Market, Hero, onWindowClosed, Mode)
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
madeTransaction = false;
bool sliderNeeded = (mode != EMarketMode::RESOURCE_ARTIFACT && mode != EMarketMode::ARTIFACT_RESOURCE);
std::string title;
if(auto * o = dynamic_cast<const CGTownInstance *>(market))
{
switch (mode)
{
case EMarketMode::CREATURE_RESOURCE:
title = (*CGI->townh)[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->getNameTranslated();
break;
case EMarketMode::RESOURCE_ARTIFACT:
title = (*CGI->townh)[o->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
break;
case EMarketMode::ARTIFACT_RESOURCE:
title = (*CGI->townh)[o->getFaction()]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
// create image that copies part of background containing slot MISC_1 into position of slot MISC_5
// this is workaround for bug in H3 files where this slot for ragdoll on this screen is missing
images.push_back(std::make_shared<CPicture>(background->getSurface(), Rect(20, 187, 47, 47), 18, 339 ));
break;
default:
title = CGI->generaltexth->allTexts[158];
break;
}
}
else if(auto * o = dynamic_cast<const CGMarket *>(market))
{
title = o->title;
}
titleLabel = std::make_shared<CLabel>(300, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, title);
if(mode == EMarketMode::ARTIFACT_RESOURCE)
{
//arts = std::make_shared<CArtifactsOfHeroMarket>(Point(-361, 46));
arts->selectArtCallback = std::bind(&CTradeWindow::artifactSelected, this, _1);
arts->setHero(hero);
addSetAndCallbacks(arts);
}
initItems(false);
initItems(true);
deal = std::make_shared<CButton>(Point(307, 520), AnimationPath::builtin("TPMRKB.DEF"), CGI->generaltexth->zelp[595], [&](){ makeDeal(); } );
deal->block(true);
if(sliderNeeded)
{
slider = std::make_shared<CSlider>(Point(231, 490), 137, std::bind(&CMarketplaceWindow::sliderMoved, this, _1), 0, 0, 0, Orientation::HORIZONTAL);
max = std::make_shared<CButton>(Point(229, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596], [&](){ setMax(); });
max->block(true);
}
else
{
deal->moveBy(Point(-30, 0));
}
//left side
switch(Mode)
{
case EMarketMode::RESOURCE_RESOURCE:
case EMarketMode::RESOURCE_PLAYER:
case EMarketMode::RESOURCE_ARTIFACT:
labels.push_back(std::make_shared<CLabel>(154, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[270]));
break;
case EMarketMode::CREATURE_RESOURCE:
break;
case EMarketMode::ARTIFACT_RESOURCE:
//%s's Artifacts
labels.push_back(std::make_shared<CLabel>(152, 56, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->allTexts[271]) % hero->getNameTranslated())));
break;
}
Rect traderTextRect;
//right side
switch(Mode)
{
case EMarketMode::RESOURCE_RESOURCE:
case EMarketMode::CREATURE_RESOURCE:
case EMarketMode::RESOURCE_ARTIFACT:
case EMarketMode::ARTIFACT_RESOURCE:
labels.push_back(std::make_shared<CLabel>(445, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168]));
traderTextRect = Rect(316, 48, 260, 75);
break;
case EMarketMode::RESOURCE_PLAYER:
labels.push_back(std::make_shared<CLabel>(445, 55, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[169]));
traderTextRect = Rect(28, 48, 260, 75);
break;
}
traderText = std::make_shared<CTextBox>("", traderTextRect, 0, FONT_SMALL, ETextAlignment::CENTER);
int specialOffset = mode == EMarketMode::ARTIFACT_RESOURCE ? 35 : 0; //in selling artifacts mode we need to move res-res and art-res buttons down
updateTraderText();
}
CMarketplaceWindow::~CMarketplaceWindow() = default;
void CMarketplaceWindow::setMax()
{
slider->scrollToMax();
}
void CMarketplaceWindow::makeDeal()
{
int sliderValue = 0;
if(slider)
sliderValue = slider->getValue();
else
sliderValue = !deal->isBlocked(); //should always be 1
if(!sliderValue)
return;
bool allowDeal = true;
int leftIdToSend = hLeft->id;
switch (mode)
{
case EMarketMode::CREATURE_RESOURCE:
leftIdToSend = hLeft->serial;
break;
case EMarketMode::ARTIFACT_RESOURCE:
leftIdToSend = hLeft->getArtInstance()->getId().getNum();
break;
case EMarketMode::RESOURCE_ARTIFACT:
if(!ArtifactID(hRight->id).toArtifact()->canBePutAt(hero))
{
LOCPLINT->showInfoDialog(CGI->generaltexth->translate("core.genrltxt.326"));
allowDeal = false;
}
break;
default:
break;
}
if(allowDeal)
{
switch(mode)
{
case EMarketMode::RESOURCE_RESOURCE:
LOCPLINT->cb->trade(market, mode, GameResID(leftIdToSend), GameResID(hRight->id), slider->getValue() * r1, hero);
slider->scrollTo(0);
break;
case EMarketMode::CREATURE_RESOURCE:
LOCPLINT->cb->trade(market, mode, SlotID(leftIdToSend), GameResID(hRight->id), slider->getValue() * r1, hero);
slider->scrollTo(0);
break;
case EMarketMode::RESOURCE_PLAYER:
LOCPLINT->cb->trade(market, mode, GameResID(leftIdToSend), PlayerColor(hRight->id), slider->getValue() * r1, hero);
slider->scrollTo(0);
break;
case EMarketMode::RESOURCE_ARTIFACT:
LOCPLINT->cb->trade(market, mode, GameResID(leftIdToSend), ArtifactID(hRight->id), r2, hero);
break;
case EMarketMode::ARTIFACT_RESOURCE:
LOCPLINT->cb->trade(market, mode, ArtifactInstanceID(leftIdToSend), GameResID(hRight->id), r2, hero);
break;
}
}
madeTransaction = true;
hLeft = nullptr;
hRight = nullptr;
if(bidTradePanel)
bidTradePanel->deselect();
assert(offerTradePanel);
offerTradePanel->deselect();
selectionChanged(true);
}
void CMarketplaceWindow::sliderMoved( int to )
{
redraw();
}
void CMarketplaceWindow::selectionChanged(bool side)
{
readyToTrade = hLeft && hRight;
if(mode == EMarketMode::RESOURCE_RESOURCE)
readyToTrade = readyToTrade && (hLeft->id != hRight->id); //for resource trade, two DIFFERENT resources must be selected
if(mode == EMarketMode::ARTIFACT_RESOURCE && !hLeft)
arts->unmarkSlots();
if(readyToTrade)
{
int soldItemId = hLeft->id;
market->getOffer(soldItemId, hRight->id, r1, r2, mode);
if(slider)
{
int newAmount = -1;
if(itemsType[1] == EType::RESOURCE)
newAmount = LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(soldItemId));
else if(itemsType[1] == EType::CREATURE)
newAmount = hero->getStackCount(SlotID(hLeft->serial)) - (hero->stacksCount() == 1 && hero->needsLastStack());
else
assert(0);
slider->setAmount(newAmount / r1);
slider->scrollTo(0);
max->block(false);
deal->block(false);
}
else if(itemsType[1] == EType::RESOURCE) //buying -> check if we can afford transaction
{
deal->block(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(soldItemId)) < r1);
}
else
deal->block(false);
}
else
{
if(slider)
{
max->block(true);
slider->setAmount(0);
slider->scrollTo(0);
}
deal->block(true);
}
if(side && itemsType[0] != EType::PLAYER) //items[1] selection changed, recalculate offers
initSubs(false);
updateTraderText();
redraw();
}
void CMarketplaceWindow::updateGarrison()
{
}
void CMarketplaceWindow::artifactsChanged(bool Left)
{
}
std::string CMarketplaceWindow::updateSlotSubtitle(bool Left) const
{
if(Left)
{
switch(itemsType[1])
{
case EType::RESOURCE:
case EType::CREATURE:
{
int val = slider
? slider->getValue() * r1
: (((deal->isBlocked())) ? 0 : r1);
return std::to_string(val);
}
case EType::ARTIFACT_INSTANCE:
return ((deal->isBlocked()) ? "0" : "1");
}
}
else
{
switch(itemsType[0])
{
case EType::RESOURCE:
if(slider)
return std::to_string( slider->getValue() * r2 );
else
return std::to_string(r2);
case EType::ARTIFACT_TYPE:
return ((deal->isBlocked()) ? "0" : "1");
case EType::PLAYER:
return (hRight ? CGI->generaltexth->capColors[hRight->id] : "");
}
}
return "???";
}
Point CMarketplaceWindow::selectionOffset(bool Left) const
{
if(Left)
{
switch(itemsType[1])
{
case EType::RESOURCE:
return Point(122, 448);
case EType::CREATURE:
return Point(128, 450);
case EType::ARTIFACT_INSTANCE:
return Point(134, 469);
}
}
else
{
switch(itemsType[0])
{
case EType::RESOURCE:
if(mode == EMarketMode::ARTIFACT_RESOURCE)
return Point(410, 471);
else
return Point(410, 448);
case EType::ARTIFACT_TYPE:
return Point(411, 449);
case EType::PLAYER:
return Point(417, 451);
}
}
assert(0);
return Point(0,0);
}
void CMarketplaceWindow::updateTraderText()
{
if(readyToTrade)
{
if(mode == EMarketMode::RESOURCE_PLAYER)
{
//I can give %s to the %s player.
traderText->setText(boost::str(boost::format(CGI->generaltexth->allTexts[165]) % hLeft->getName() % hRight->getName()));
}
else if(mode == EMarketMode::RESOURCE_ARTIFACT)
{
//I can offer you the %s for %d %s of %s.
traderText->setText(boost::str(boost::format(CGI->generaltexth->allTexts[267]) % hRight->getName() % r1 % CGI->generaltexth->allTexts[160 + (r1==1)] % hLeft->getName()));
}
else if(mode == EMarketMode::RESOURCE_RESOURCE)
{
//I can offer you %d %s of %s for %d %s of %s.
traderText->setText(boost::str(boost::format(CGI->generaltexth->allTexts[157]) % r2 % CGI->generaltexth->allTexts[160 + (r2==1)] % hRight->getName() % r1 % CGI->generaltexth->allTexts[160 + (r1==1)] % hLeft->getName()));
}
else if(mode == EMarketMode::CREATURE_RESOURCE)
{
//I can offer you %d %s of %s for %d %s.
traderText->setText(boost::str(boost::format(CGI->generaltexth->allTexts[269]) % r2 % CGI->generaltexth->allTexts[160 + (r2==1)] % hRight->getName() % r1 % hLeft->getName(r1)));
}
else if(mode == EMarketMode::ARTIFACT_RESOURCE)
{
//I can offer you %d %s of %s for your %s.
traderText->setText(boost::str(boost::format(CGI->generaltexth->allTexts[268]) % r2 % CGI->generaltexth->allTexts[160 + (r2==1)] % hRight->getName() % hLeft->getName(r1)));
}
return;
}
int gnrtxtnr = -1;
if(madeTransaction)
{
if(mode == EMarketMode::RESOURCE_PLAYER)
gnrtxtnr = 166; //Are there any other resources you'd like to give away?
else
gnrtxtnr = 162; //You have received quite a bargain. I expect to make no profit on the deal. Can I interest you in any of my other wares?
}
else
{
if(mode == EMarketMode::RESOURCE_PLAYER)
gnrtxtnr = 167; //If you'd like to give any of your resources to another player, click on the item you wish to give and to whom.
else
gnrtxtnr = 163; //Please inspect our fine wares. If you feel like offering a trade, click on the items you wish to trade with and for.
}
traderText->setText(CGI->generaltexth->allTexts[gnrtxtnr]);
}

View File

@ -1,77 +0,0 @@
/*
* CTradeWindow.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
#include "../widgets/markets/CTradeBase.h"
#include "../widgets/CWindowWithArtifacts.h"
#include "CWindowObject.h"
class CSlider;
class CGStatusBar;
class CTradeWindow : public CTradeBase, public CWindowObject, public CWindowWithArtifacts //base for markets and altar of sacrifice
{
public:
EType itemsType[2];
EMarketMode mode;
std::shared_ptr<CButton> ok;
std::shared_ptr<CButton> max;
std::shared_ptr<CSlider> slider; //for choosing amount to be exchanged
bool readyToTrade;
CTradeWindow(const ImagePath & bgName, const IMarket * Market, const CGHeroInstance * Hero, const std::function<void()> & onWindowClosed, EMarketMode Mode); //c
void showAll(Canvas & to) override;
void close() override;
void initSubs(bool Left);
void initTypes();
void initItems(bool Left);
void setMode(EMarketMode Mode); //mode setter
void artifactSelected(CArtPlace * slot); //used when selling artifacts -> called when user clicked on artifact slot
virtual void selectionChanged(bool side) = 0; //true == left
virtual Point selectionOffset(bool Left) const = 0;
virtual std::string updateSlotSubtitle(bool Left) const = 0;
virtual void updateGarrison() = 0;
virtual void artifactsChanged(bool left) = 0;
protected:
std::function<void()> onWindowClosed;
std::shared_ptr<CGStatusBar> statusBar;
std::vector<std::shared_ptr<CPicture>> images;
};
class CMarketplaceWindow : public CTradeWindow
{
std::shared_ptr<CLabel> titleLabel;
std::shared_ptr<CArtifactsOfHeroMarket> arts;
ImagePath getBackgroundForMode(EMarketMode mode);
public:
int r1, r2; //suggested amounts of traded resources
bool madeTransaction; //if player made at least one transaction
std::shared_ptr<CTextBox> traderText;
void setMax();
void sliderMoved(int to);
void makeDeal() override;
void selectionChanged(bool side) override; //true == left
CMarketplaceWindow(const IMarket * Market, const CGHeroInstance * Hero, const std::function<void()> & onWindowClosed, EMarketMode Mode);
~CMarketplaceWindow();
Point selectionOffset(bool Left) const override;
std::string updateSlotSubtitle(bool Left) const override;
void updateGarrison() override; //removes creatures with count 0 from the list (apparently whole stack has been sold)
void artifactsChanged(bool left) override;
void updateTraderText();
};