mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-03 13:01:33 +02:00
Cleanup & refactoring
This commit is contained in:
parent
f3fa6714dc
commit
4839891de4
@ -145,7 +145,6 @@ set(client_SRCS
|
||||
windows/CPuzzleWindow.cpp
|
||||
windows/CQuestLog.cpp
|
||||
windows/CSpellWindow.cpp
|
||||
windows/CTradeWindow.cpp
|
||||
windows/CTutorialWindow.cpp
|
||||
windows/CWindowObject.cpp
|
||||
windows/CreaturePurchaseCard.cpp
|
||||
@ -335,7 +334,6 @@ set(client_HEADERS
|
||||
windows/CPuzzleWindow.h
|
||||
windows/CQuestLog.h
|
||||
windows/CSpellWindow.h
|
||||
windows/CTradeWindow.h
|
||||
windows/CTutorialWindow.h
|
||||
windows/CWindowObject.h
|
||||
windows/CreaturePurchaseCard.h
|
||||
|
@ -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)
|
||||
{
|
||||
maxWidth = width;
|
||||
|
@ -57,6 +57,7 @@ public:
|
||||
virtual void setText(const std::string & Txt);
|
||||
virtual void setMaxWidth(int width);
|
||||
virtual void setColor(const ColorRGBA & Color);
|
||||
void clear();
|
||||
size_t getWidth();
|
||||
|
||||
CLabel(int x = 0, int y = 0, EFonts Font = FONT_SMALL, ETextAlignment Align = ETextAlignment::TOPLEFT,
|
||||
|
@ -57,9 +57,9 @@ CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance *
|
||||
int slotNum = 0;
|
||||
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->subtitle.clear();
|
||||
altarSlot->subtitle->clear();
|
||||
items.front().emplace_back(altarSlot);
|
||||
slotNum++;
|
||||
}
|
||||
@ -91,7 +91,7 @@ void CAltarArtifacts::makeDeal()
|
||||
for(auto item : items[0])
|
||||
{
|
||||
item->setID(-1);
|
||||
item->subtitle.clear();
|
||||
item->subtitle->clear();
|
||||
}
|
||||
calcExpAltarForHero();
|
||||
deal->block(tradeSlotsMap.empty());
|
||||
@ -135,7 +135,7 @@ void CAltarArtifacts::updateSlots()
|
||||
if(tradeSlotsMap.find(altarSlot->getArtInstance()) == tradeSlotsMap.end())
|
||||
{
|
||||
altarSlot->setID(-1);
|
||||
altarSlot->subtitle.clear();
|
||||
altarSlot->subtitle->clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -148,7 +148,7 @@ void CAltarArtifacts::updateSlots()
|
||||
assert(tradeSlot.second->id == -1);
|
||||
assert(altarArtifacts->getSlotByInstance(tradeSlot.first) != ArtifactPosition::PRE_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)
|
||||
{
|
||||
@ -158,7 +158,7 @@ void CAltarArtifacts::updateSlots()
|
||||
if(altarSlot->id == -1)
|
||||
{
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance * hero)
|
||||
: CTradeBase(market, hero)
|
||||
, CMarketMisc([this](){return CAltarCreatures::getSelectionParams();})
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
@ -47,8 +48,8 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
|
||||
// Hero creatures panel
|
||||
assert(bidTradePanel);
|
||||
bidTradePanel->moveTo(pos.topLeft() + Point(45, 110));
|
||||
bidTradePanel->selectedImage->moveTo(pos.topLeft() + Point(149, 422));
|
||||
bidTradePanel->selectedSubtitle->moveTo(pos.topLeft() + Point(180, 503));
|
||||
bidTradePanel->selectedSlot->moveTo(pos.topLeft() + Point(149, 422));
|
||||
bidTradePanel->selectedSlot->subtitle->moveBy(Point(0, 3));
|
||||
for(const auto & slot : bidTradePanel->slots)
|
||||
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);
|
||||
}, bidTradePanel->slots);
|
||||
offerTradePanel->moveTo(pos.topLeft() + Point(334, 110));
|
||||
offerTradePanel->selectedImage->moveTo(pos.topLeft() + Point(395, 422));
|
||||
offerTradePanel->selectedSubtitle->moveTo(pos.topLeft() + Point(426, 503));
|
||||
offerTradePanel->selectedSlot->moveTo(pos.topLeft() + Point(395, 422));
|
||||
offerTradePanel->selectedSlot->subtitle->moveBy(Point(0, 3));
|
||||
offerTradePanel->updateSlotsCallback = [this]()
|
||||
{
|
||||
for(const auto & altarSlot : offerTradePanel->slots)
|
||||
@ -113,38 +114,9 @@ void CAltarCreatures::updateControls()
|
||||
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()
|
||||
{
|
||||
offerTradePanel->updateSlots();
|
||||
CCreaturesSelling::updateSlots();
|
||||
CTradeBase::updateSlots();
|
||||
assert(bidTradePanel->slots.size() == offerTradePanel->slots.size());
|
||||
}
|
||||
|
||||
@ -190,10 +162,21 @@ void CAltarCreatures::makeDeal()
|
||||
for(auto heroSlot : offerTradePanel->slots)
|
||||
{
|
||||
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()
|
||||
{
|
||||
std::optional<SlotID> lastSlot;
|
||||
@ -225,8 +208,8 @@ void CAltarCreatures::updateAltarSlot(const std::shared_ptr<CTradeableItem> & sl
|
||||
{
|
||||
auto units = unitsOnAltar[slot->serial];
|
||||
slot->setType(units > 0 ? EType::CREATURE : EType::CREATURE_PLACEHOLDER);
|
||||
slot->subtitle = units > 0 ?
|
||||
boost::str(boost::format(CGI->generaltexth->allTexts[122]) % std::to_string(hero->calculateXp(units * expPerUnit[slot->serial]))) : "";
|
||||
slot->subtitle->setText(units > 0 ?
|
||||
boost::str(boost::format(CGI->generaltexth->allTexts[122]) % std::to_string(hero->calculateXp(units * expPerUnit[slot->serial]))) : "");
|
||||
}
|
||||
|
||||
void CAltarCreatures::onOfferSliderMoved(int newVal)
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include "CTradeBase.h"
|
||||
|
||||
class CAltarCreatures : public CExperienceAltar, public CCreaturesSelling
|
||||
class CAltarCreatures : public CExperienceAltar, public CCreaturesSelling, public CMarketMisc
|
||||
{
|
||||
public:
|
||||
CAltarCreatures(const IMarket * market, const CGHeroInstance * hero);
|
||||
@ -25,10 +25,10 @@ private:
|
||||
std::vector<int> unitsOnAltar;
|
||||
std::vector<int> expPerUnit;
|
||||
|
||||
CMarketMisc::SelectionParams getSelectionParams();
|
||||
void updateAltarSlot(const std::shared_ptr<CTradeableItem> & slot);
|
||||
void readExpValues();
|
||||
void updateControls();
|
||||
void updateSelected();
|
||||
void onOfferSliderMoved(int newVal);
|
||||
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override;
|
||||
};
|
||||
|
@ -27,6 +27,7 @@
|
||||
|
||||
CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance * hero)
|
||||
: CTradeBase(market, hero)
|
||||
, CResourcesSelling([this](const std::shared_ptr<CTradeableItem> & heroSlot){CArtifactsBuying::onSlotClickPressed(heroSlot, hLeft);})
|
||||
, CMarketMisc([this](){return CArtifactsBuying::getSelectionParams();})
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
@ -40,34 +41,16 @@ CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance
|
||||
|
||||
// Player's resources
|
||||
assert(bidTradePanel);
|
||||
std::for_each(bidTradePanel->slots.cbegin(), bidTradePanel->slots.cend(), [this](auto & slot)
|
||||
{
|
||||
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));
|
||||
bidTradePanel->moveTo(pos.topLeft() + Point(39, 184));
|
||||
bidTradePanel->selectedSlot->image->moveTo(pos.topLeft() + Point(141, 454));
|
||||
|
||||
// Artifacts panel
|
||||
offerTradePanel = std::make_shared<ArtifactsPanel>([this](const std::shared_ptr<CTradeableItem> & newSlot)
|
||||
{
|
||||
CArtifactsBuying::onSlotClickPressed(newSlot, hRight);
|
||||
|
||||
}, [this]()
|
||||
{
|
||||
// TODO move to parent
|
||||
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();
|
||||
CTradeBase::updateSubtitles(EMarketMode::RESOURCE_ARTIFACT);
|
||||
}, market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT));
|
||||
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));
|
||||
|
||||
CArtifactsBuying::updateSlots();
|
||||
CTradeBase::updateSlots();
|
||||
CMarketMisc::deselect();
|
||||
}
|
||||
|
||||
@ -85,12 +68,6 @@ void CArtifactsBuying::makeDeal()
|
||||
deselect();
|
||||
}
|
||||
|
||||
void CArtifactsBuying::updateSlots()
|
||||
{
|
||||
CResourcesSelling::updateSlots();
|
||||
offerTradePanel->updateSlots();
|
||||
}
|
||||
|
||||
CMarketMisc::SelectionParams CArtifactsBuying::getSelectionParams()
|
||||
{
|
||||
if(hLeft && hRight)
|
||||
|
@ -16,7 +16,6 @@ class CArtifactsBuying : public CResourcesSelling, public CMarketMisc
|
||||
public:
|
||||
CArtifactsBuying(const IMarket * market, const CGHeroInstance * hero);
|
||||
void makeDeal() override;
|
||||
void updateSlots() override;
|
||||
|
||||
private:
|
||||
CMarketMisc::SelectionParams getSelectionParams();
|
||||
|
@ -24,15 +24,16 @@
|
||||
|
||||
CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstance * 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();})
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
deal = std::make_shared<CButton>(Point(270, 520), AnimationPath::builtin("TPMRKB.DEF"),
|
||||
CGI->generaltexth->zelp[595], [this](){CArtifactsSelling::makeDeal();});
|
||||
selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("artifact"), 10, 0, 136, 470);
|
||||
bidSelectedSubtitle = std::make_shared<CLabel>(157, 529, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
bidSelectedSlot = std::make_shared<CTradeableItem>(Rect(Point(123, 470), Point(69, 66)), EType::ARTIFACT_TYPE, 0, 0);
|
||||
|
||||
// Hero's artifacts
|
||||
heroArts = std::make_shared<CArtifactsOfHeroMarket>(Point(-361, 46));
|
||||
@ -40,11 +41,13 @@ CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstanc
|
||||
heroArts->selectArtCallback = [this](CArtPlace * artPlace)
|
||||
{
|
||||
assert(artPlace);
|
||||
artForTrade = artPlace->getArt();
|
||||
assert(artForTrade.has_value());
|
||||
const auto artForTrade = artPlace->getArt();
|
||||
assert(artForTrade);
|
||||
bidSelectedSlot->setID(artForTrade->getTypeId().num);
|
||||
hLeft = bidSelectedSlot;
|
||||
if(hRight)
|
||||
{
|
||||
this->market->getOffer(artForTrade.value()->getTypeId().num, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE);
|
||||
{ // dublicate
|
||||
this->market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE);
|
||||
deal->block(false);
|
||||
}
|
||||
CArtifactsSelling::updateSelected();
|
||||
@ -54,20 +57,11 @@ CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstanc
|
||||
|
||||
// Market resources panel
|
||||
assert(offerTradePanel);
|
||||
std::for_each(offerTradePanel->slots.cbegin(), offerTradePanel->slots.cend(), [this](auto & slot)
|
||||
{
|
||||
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));
|
||||
offerTradePanel->moveTo(pos.topLeft() + Point(326, 184));
|
||||
offerTradePanel->selectedSlot->moveTo(pos.topLeft() + Point(409, 473));
|
||||
|
||||
|
||||
CArtifactsSelling::updateSelected();
|
||||
CArtifactsSelling::deselect();
|
||||
CMarketMisc::deselect();
|
||||
}
|
||||
|
||||
void CArtifactsSelling::makeDeal()
|
||||
@ -75,27 +69,21 @@ void CArtifactsSelling::makeDeal()
|
||||
|
||||
}
|
||||
|
||||
void CArtifactsSelling::deselect()
|
||||
{
|
||||
CTradeBase::deselect();
|
||||
artForTrade = std::nullopt;
|
||||
}
|
||||
|
||||
void CArtifactsSelling::updateSelected()
|
||||
{
|
||||
CMarketMisc::updateSelected();
|
||||
|
||||
if(artForTrade.has_value() && hRight)
|
||||
if(hLeft && hRight)
|
||||
{
|
||||
bidSelectedSubtitle->setText(std::to_string(bidQty));
|
||||
selectedImage->enable();
|
||||
selectedImage->setFrame(CGI->artifacts()->getByIndex(artForTrade.value()->getTypeId())->getIconIndex());
|
||||
bidSelectedSlot->image->enable();
|
||||
bidSelectedSlot->image->setFrame(CGI->artifacts()->getByIndex(hLeft->id)->getIconIndex());
|
||||
bidSelectedSlot->subtitle->setText(std::to_string(bidQty));
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedImage->disable();
|
||||
selectedImage->setFrame(0);
|
||||
bidSelectedSubtitle->setText("");
|
||||
bidSelectedSlot->image->disable();
|
||||
bidSelectedSlot->image->setFrame(0);
|
||||
bidSelectedSlot->subtitle->clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -106,7 +94,7 @@ std::shared_ptr<CArtifactsOfHeroMarket> CArtifactsSelling::getAOHset() const
|
||||
|
||||
CMarketMisc::SelectionParams CArtifactsSelling::getSelectionParams()
|
||||
{
|
||||
if(artForTrade.has_value() && hRight)
|
||||
if(hLeft && hRight)
|
||||
return std::make_tuple(
|
||||
std::nullopt,
|
||||
SelectionParamOneSide {std::to_string(offerQty), GameResID(hRight->id)}
|
||||
@ -115,20 +103,6 @@ CMarketMisc::SelectionParams CArtifactsSelling::getSelectionParams()
|
||||
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)
|
||||
{
|
||||
assert(newSlot);
|
||||
@ -136,11 +110,11 @@ void CArtifactsSelling::onSlotClickPressed(const std::shared_ptr<CTradeableItem>
|
||||
return;
|
||||
|
||||
CTradeBase::onSlotClickPressed(newSlot, hCurSlot);
|
||||
if(artForTrade.has_value())
|
||||
if(hLeft)
|
||||
{
|
||||
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);
|
||||
}
|
||||
updateSelected();
|
||||
|
@ -17,18 +17,14 @@ class CArtifactsSelling : public CResourcesBuying, public CMarketMisc
|
||||
public:
|
||||
CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero);
|
||||
void makeDeal() override;
|
||||
void deselect() override;
|
||||
void updateSelected();
|
||||
std::shared_ptr<CArtifactsOfHeroMarket> getAOHset() const;
|
||||
|
||||
private:
|
||||
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<CTradeableItem> bidSelectedSlot;
|
||||
|
||||
void updateSubtitles();
|
||||
CMarketMisc::SelectionParams getSelectionParams();
|
||||
void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override;
|
||||
};
|
||||
|
@ -28,7 +28,9 @@
|
||||
|
||||
CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance * 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();})
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
@ -49,6 +51,7 @@ CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance
|
||||
// Hero creatures panel
|
||||
assert(bidTradePanel);
|
||||
bidTradePanel->moveTo(pos.topLeft() + Point(45, 123));
|
||||
bidTradePanel->selectedSlot->subtitle->moveBy(Point(0, -1));
|
||||
bidTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1);
|
||||
std::for_each(bidTradePanel->slots.cbegin(), bidTradePanel->slots.cend(), [this](auto & slot)
|
||||
{
|
||||
|
@ -26,7 +26,10 @@
|
||||
|
||||
CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance * 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();})
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
@ -43,14 +46,7 @@ CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance
|
||||
|
||||
// Player's resources
|
||||
assert(bidTradePanel);
|
||||
std::for_each(bidTradePanel->slots.cbegin(), bidTradePanel->slots.cend(), [this](auto & slot)
|
||||
{
|
||||
slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot)
|
||||
{
|
||||
CMarketResources::onSlotClickPressed(heroSlot, hLeft);
|
||||
};
|
||||
});
|
||||
bidTradePanel->moveTo(pos.topLeft() + Point(39, 181));
|
||||
bidTradePanel->moveTo(pos.topLeft() + Point(39, 182));
|
||||
|
||||
// Market resources panel
|
||||
assert(offerTradePanel);
|
||||
@ -62,7 +58,7 @@ CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance
|
||||
};
|
||||
});
|
||||
|
||||
CResourcesSelling::updateSlots();
|
||||
CTradeBase::updateSlots();
|
||||
CMarketMisc::deselect();
|
||||
}
|
||||
|
||||
@ -121,7 +117,7 @@ void CMarketResources::onSlotClickPressed(const std::shared_ptr<CTradeableItem>
|
||||
|
||||
void CMarketResources::updateSubtitles()
|
||||
{
|
||||
CResourcesBuying::updateSubtitles(EMarketMode::RESOURCE_RESOURCE);
|
||||
CTradeBase::updateSubtitles(EMarketMode::RESOURCE_RESOURCE);
|
||||
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
|
||||
}
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "../MiscWidgets.h"
|
||||
|
||||
#include "../Images.h"
|
||||
#include "../../gui/CGuiHandler.h"
|
||||
#include "../../widgets/Buttons.h"
|
||||
#include "../../widgets/Slider.h"
|
||||
@ -81,6 +82,28 @@ void CTradeBase::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newS
|
||||
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()
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
@ -116,55 +139,34 @@ bool CCreaturesSelling::slotDeletingCheck(const std::shared_ptr<CTradeableItem>
|
||||
void CCreaturesSelling::updateSubtitle()
|
||||
{
|
||||
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()
|
||||
{
|
||||
bidTradePanel->updateSlots();
|
||||
}
|
||||
|
||||
CResourcesBuying::CResourcesBuying(TradePanelBase::UpdateSlotsFunctor callback)
|
||||
CResourcesBuying::CResourcesBuying(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
|
||||
const TradePanelBase::UpdateSlotsFunctor & updSlotsCallback)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
offerTradePanel = std::make_shared<ResourcesPanel>([](const std::shared_ptr<CTradeableItem>&) {}, callback);
|
||||
offerTradePanel->moveTo(pos.topLeft() + Point(327, 181));
|
||||
offerTradePanel = std::make_shared<ResourcesPanel>(clickPressedCallback, updSlotsCallback);
|
||||
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]));
|
||||
}
|
||||
|
||||
void CResourcesBuying::updateSubtitles(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();
|
||||
};
|
||||
|
||||
CResourcesSelling::CResourcesSelling()
|
||||
CResourcesSelling::CResourcesSelling(const CTradeableItem::ClickPressedFunctor & clickPressedCallback)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
bidTradePanel = std::make_shared<ResourcesPanel>([](const std::shared_ptr<CTradeableItem>&) {}, [this]()
|
||||
{
|
||||
for(const auto & slot : bidTradePanel->slots)
|
||||
slot->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(slot->serial)));
|
||||
});
|
||||
bidTradePanel = std::make_shared<ResourcesPanel>(clickPressedCallback, std::bind(&CResourcesSelling::updateSubtitle, this));
|
||||
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)
|
||||
{
|
||||
}
|
||||
@ -184,12 +186,12 @@ void CMarketMisc::updateSelected()
|
||||
std::optional<size_t> lImageIndex = std::nullopt;
|
||||
if(params.has_value())
|
||||
{
|
||||
tradePanel->selectedSubtitle->setText(params.value().text);
|
||||
tradePanel->setSelectedSubtitleText(params.value().text);
|
||||
lImageIndex = params.value().imageIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
tradePanel->selectedSubtitle->setText("");
|
||||
tradePanel->clearSelectedSubtitleText();
|
||||
}
|
||||
tradePanel->setSelectedFrameIndex(lImageIndex);
|
||||
};
|
||||
|
@ -21,7 +21,7 @@ VCMI_LIB_NAMESPACE_END
|
||||
class CButton;
|
||||
class CSlider;
|
||||
|
||||
class CTradeBase
|
||||
class CTradeBase : public CIntObject
|
||||
{
|
||||
public:
|
||||
const IMarket * market;
|
||||
@ -49,11 +49,12 @@ public:
|
||||
virtual void makeDeal() = 0;
|
||||
virtual void deselect();
|
||||
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
|
||||
class CExperienceAltar : virtual public CTradeBase, virtual public CIntObject
|
||||
class CExperienceAltar : virtual public CTradeBase
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<CLabel> expToLevel;
|
||||
@ -66,30 +67,29 @@ public:
|
||||
virtual TExpType calcExpAltarForHero() = 0;
|
||||
};
|
||||
|
||||
class CCreaturesSelling : virtual public CTradeBase, virtual public CIntObject
|
||||
class CCreaturesSelling : virtual public CTradeBase
|
||||
{
|
||||
public:
|
||||
CCreaturesSelling();
|
||||
bool slotDeletingCheck(const std::shared_ptr<CTradeableItem> & slot);
|
||||
void updateSubtitle();
|
||||
void updateSlots() override;
|
||||
};
|
||||
|
||||
class CResourcesBuying : virtual public CTradeBase, virtual public CIntObject
|
||||
class CResourcesBuying : virtual public CTradeBase
|
||||
{
|
||||
public:
|
||||
CResourcesBuying(TradePanelBase::UpdateSlotsFunctor callback);
|
||||
void updateSubtitles(EMarketMode marketMode);
|
||||
CResourcesBuying(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
|
||||
const TradePanelBase::UpdateSlotsFunctor & updSlotsCallback);
|
||||
};
|
||||
|
||||
class CResourcesSelling : virtual public CTradeBase, virtual public CIntObject
|
||||
class CResourcesSelling : virtual public CTradeBase
|
||||
{
|
||||
public:
|
||||
CResourcesSelling();
|
||||
void updateSlots() override;
|
||||
CResourcesSelling(const CTradeableItem::ClickPressedFunctor & clickPressedCallback);
|
||||
void updateSubtitle();
|
||||
};
|
||||
|
||||
class CMarketMisc : virtual public CTradeBase, virtual public CIntObject
|
||||
class CMarketMisc : virtual public CTradeBase
|
||||
{
|
||||
public:
|
||||
struct SelectionParamOneSide
|
||||
@ -98,9 +98,9 @@ public:
|
||||
int imageIndex;
|
||||
};
|
||||
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 updateSelected();
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
CTransferResources::CTransferResources(const IMarket * market, const CGHeroInstance * hero)
|
||||
: CTradeBase(market, hero)
|
||||
, CResourcesSelling([this](const std::shared_ptr<CTradeableItem> & heroSlot){CTransferResources::onSlotClickPressed(heroSlot, hLeft);})
|
||||
, CMarketMisc([this](){return CTransferResources::getSelectionParams();})
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
@ -42,23 +43,16 @@ CTransferResources::CTransferResources(const IMarket * market, const CGHeroInsta
|
||||
|
||||
// Player's resources
|
||||
assert(bidTradePanel);
|
||||
std::for_each(bidTradePanel->slots.cbegin(), bidTradePanel->slots.cend(), [this](auto & slot)
|
||||
{
|
||||
slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot)
|
||||
{
|
||||
CTransferResources::onSlotClickPressed(heroSlot, hLeft);
|
||||
};
|
||||
});
|
||||
bidTradePanel->moveTo(pos.topLeft() + Point(40, 182));
|
||||
bidTradePanel->moveTo(pos.topLeft() + Point(40, 183));
|
||||
|
||||
// Players panel
|
||||
offerTradePanel = std::make_shared<PlayersPanel>([this](const std::shared_ptr<CTradeableItem> & heroSlot)
|
||||
{
|
||||
CTransferResources::onSlotClickPressed(heroSlot, hRight);
|
||||
});
|
||||
offerTradePanel->moveTo(pos.topLeft() + Point(333, 83));
|
||||
offerTradePanel->moveTo(pos.topLeft() + Point(333, 84));
|
||||
|
||||
CResourcesSelling::updateSlots();
|
||||
CTradeBase::updateSlots();
|
||||
CTransferResources::deselect();
|
||||
}
|
||||
|
||||
|
@ -23,14 +23,12 @@
|
||||
#include "../../../lib/CGeneralTextHandler.h"
|
||||
#include "../../../lib/mapObjects/CGHeroInstance.h"
|
||||
|
||||
CTradeableItem::CTradeableItem(const Rect & area, EType Type, int ID, bool Left, int Serial)
|
||||
: SelectableSlot(area, Point(1, 1))
|
||||
CTradeableItem::CTradeableItem(const Rect & area, EType Type, int ID, int Serial)
|
||||
: SelectableSlot(area, Point(1, 2))
|
||||
, artInstance(nullptr)
|
||||
, type(EType(-1)) // set to invalid, will be corrected in setType
|
||||
, id(ID)
|
||||
, serial(Serial)
|
||||
, left(Left)
|
||||
, downSelection(false)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
|
||||
|
||||
@ -38,6 +36,7 @@ CTradeableItem::CTradeableItem(const Rect & area, EType Type, int ID, bool Left,
|
||||
addUsedEvents(HOVER);
|
||||
addUsedEvents(SHOW_POPUP);
|
||||
|
||||
subtitle = std::make_shared<CLabel>(0, 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
setType(Type);
|
||||
|
||||
this->pos.w = area.w;
|
||||
@ -60,6 +59,28 @@ void CTradeableItem::setType(EType newType)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if(clickPressedCallback)
|
||||
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)
|
||||
{
|
||||
if(!on)
|
||||
@ -228,28 +195,7 @@ void CTradeableItem::showPopupWindow(const Point & cursorPosition)
|
||||
}
|
||||
}
|
||||
|
||||
std::string CTradeableItem::getName(int number) 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
|
||||
const CArtifactInstance* CTradeableItem::getArtInstance() const
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
@ -289,52 +235,62 @@ void TradePanelBase::deselect()
|
||||
void TradePanelBase::clearSubtitles()
|
||||
{
|
||||
for(const auto & slot : slots)
|
||||
slot->subtitle.clear();
|
||||
slot->subtitle->clear();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
slot.subtitle.append("/");
|
||||
slot.subtitle.append(std::to_string(cost));
|
||||
subtitle.append("/");
|
||||
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())
|
||||
{
|
||||
selectedImage->enable();
|
||||
selectedImage->setFrame(index.value());
|
||||
selectedSlot->image->enable();
|
||||
selectedSlot->image->setFrame(index.value());
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedImage->disable();
|
||||
selectedImage->setFrame(0);
|
||||
selectedSlot->image->disable();
|
||||
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());
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
||||
for(const auto & res : resourcesForTrade)
|
||||
{
|
||||
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[res.num], slotDimension),
|
||||
EType::RESOURCE, res.num, true, res.num));
|
||||
auto slot = slots.emplace_back(std::make_shared<CTradeableItem>(Rect(slotsPos[res.num], slotDimension), EType::RESOURCE, res.num, res.num));
|
||||
slot->clickPressedCallback = clickPressedCallback;
|
||||
slot->setSelectionWidth(selectionWidth);
|
||||
}
|
||||
updateSlotsCallback = updateSubtitles;
|
||||
selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("RESOURCE"), 0, 0, selectedImagePos.x, selectedImagePos.y);
|
||||
selectedSubtitle = std::make_shared<CLabel>(selectedSubtitlePos.x, selectedSubtitlePos.y, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
selectedSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::RESOURCE, 0, 0);
|
||||
}
|
||||
|
||||
ArtifactsPanel::ArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles,
|
||||
const std::vector<TradeItemBuy> & arts)
|
||||
ArtifactsPanel::ArtifactsPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
|
||||
const UpdateSlotsFunctor & updateSubtitles, const std::vector<TradeItemBuy> & arts)
|
||||
{
|
||||
assert(slotsForTrade == slotsPos.size());
|
||||
assert(slotsForTrade == arts.size());
|
||||
@ -346,17 +302,16 @@ ArtifactsPanel::ArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedC
|
||||
if(artType != ArtifactID::NONE)
|
||||
{
|
||||
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->setSelectionWidth(selectionWidth);
|
||||
}
|
||||
}
|
||||
updateSlotsCallback = updateSubtitles;
|
||||
selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("artifact"), 0, 0, selectedImagePos.x, selectedImagePos.y);
|
||||
selectedSubtitle = std::make_shared<CLabel>(selectedSubtitlePos.x, selectedSubtitlePos.y, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
selectedSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::ARTIFACT_TYPE, 0, 0);
|
||||
}
|
||||
|
||||
PlayersPanel::PlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback)
|
||||
PlayersPanel::PlayersPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback)
|
||||
{
|
||||
assert(PlayerColor::PLAYER_LIMIT_I <= slotsPos.size() + 1);
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
@ -372,17 +327,16 @@ PlayersPanel::PlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCallb
|
||||
int slotNum = 0;
|
||||
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->setSelectionWidth(selectionWidth);
|
||||
slot->subtitle = CGI->generaltexth->capColors[players[slotNum].num];
|
||||
slot->subtitle->setText(CGI->generaltexth->capColors[players[slotNum].num]);
|
||||
slotNum++;
|
||||
}
|
||||
selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("CREST58"), 0, 0, selectedImagePos.x, selectedImagePos.y);
|
||||
selectedSubtitle = std::make_shared<CLabel>(selectedSubtitlePos.x, selectedSubtitlePos.y, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
selectedSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::PLAYER, 0, 0);
|
||||
}
|
||||
|
||||
CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, const slotsData & initialSlots)
|
||||
CreaturesPanel::CreaturesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const slotsData & initialSlots)
|
||||
{
|
||||
assert(initialSlots.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)
|
||||
{
|
||||
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;
|
||||
if(creaturesNum != 0)
|
||||
slot->subtitle = std::to_string(creaturesNum);
|
||||
slot->subtitle->setText(std::to_string(creaturesNum));
|
||||
slot->setSelectionWidth(selectionWidth);
|
||||
}
|
||||
selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("TWCRPORT"), 0, 0, selectedImagePos.x, selectedImagePos.y);
|
||||
selectedSubtitle = std::make_shared<CLabel>(selectedSubtitlePos.x, selectedSubtitlePos.y, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
selectedSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::CREATURE, 0, 0);
|
||||
}
|
||||
|
||||
CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback,
|
||||
CreaturesPanel::CreaturesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
|
||||
const std::vector<std::shared_ptr<CTradeableItem>> & srcSlots, bool emptySlots)
|
||||
{
|
||||
assert(slots.size() <= GameConstants::ARMY_SIZE);
|
||||
@ -410,11 +363,10 @@ CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedC
|
||||
for(const auto & srcSlot : srcSlots)
|
||||
{
|
||||
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->subtitle = emptySlots ? "" : srcSlot->subtitle;
|
||||
slot->subtitle->setText(emptySlots ? "" : srcSlot->subtitle->getText());
|
||||
slot->setSelectionWidth(selectionWidth);
|
||||
}
|
||||
selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("TWCRPORT"), 0, 0, selectedImagePos.x, selectedImagePos.y);
|
||||
selectedSubtitle = std::make_shared<CLabel>(selectedSubtitlePos.x, selectedSubtitlePos.y, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
|
||||
selectedSlot = std::make_shared<CTradeableItem>(Rect(selectedPos, slotDimension), EType::CREATURE, 0, 0);
|
||||
}
|
||||
|
@ -31,8 +31,7 @@ public:
|
||||
EType type;
|
||||
int id;
|
||||
const int serial;
|
||||
const bool left;
|
||||
std::string subtitle;
|
||||
std::shared_ptr<CLabel> subtitle;
|
||||
ClickPressedFunctor clickPressedCallback;
|
||||
|
||||
void setType(EType newType);
|
||||
@ -41,16 +40,10 @@ public:
|
||||
const CArtifactInstance * getArtInstance() const;
|
||||
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 hover(bool on) override;
|
||||
void showAll(Canvas & to) override;
|
||||
void clickPressed(const Point & cursorPosition) override;
|
||||
std::string getName(int number = -1) const;
|
||||
CTradeableItem(const Rect & area, EType Type, int ID, bool Left, int Serial);
|
||||
CTradeableItem(const Rect & area, EType Type, int ID, int Serial);
|
||||
};
|
||||
|
||||
class TradePanelBase : public CIntObject
|
||||
@ -64,14 +57,15 @@ public:
|
||||
DeleteSlotsCheck deleteSlotsCheck;
|
||||
std::shared_ptr<CTradeableItem> selected;
|
||||
const int selectionWidth = 2;
|
||||
std::shared_ptr<CAnimImage> selectedImage;
|
||||
std::shared_ptr<CLabel> selectedSubtitle;
|
||||
std::shared_ptr<CTradeableItem> selectedSlot;
|
||||
|
||||
virtual void updateSlots();
|
||||
virtual void deselect();
|
||||
virtual void clearSubtitles();
|
||||
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
|
||||
@ -89,11 +83,10 @@ class ResourcesPanel : public TradePanelBase
|
||||
Point(83, 158)
|
||||
};
|
||||
const Point slotDimension = Point(69, 66);
|
||||
const Point selectedImagePos = Point(101, 276);
|
||||
const Point selectedSubtitlePos = Point(118, 324);
|
||||
const Point selectedPos = Point(83, 267);
|
||||
|
||||
public:
|
||||
ResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles);
|
||||
ResourcesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const UpdateSlotsFunctor & updateSubtitles);
|
||||
};
|
||||
|
||||
class ArtifactsPanel : public TradePanelBase
|
||||
@ -106,12 +99,11 @@ class ArtifactsPanel : public TradePanelBase
|
||||
};
|
||||
const size_t slotsForTrade = 7;
|
||||
const Point slotDimension = Point(69, 66);
|
||||
const Point selectedImagePos = Point(96, 266);
|
||||
const Point selectedSubtitlePos = Point(118, 324);
|
||||
const Point selectedPos = Point(83, 266);
|
||||
|
||||
public:
|
||||
ArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles,
|
||||
const std::vector<TradeItemBuy> & arts);
|
||||
ArtifactsPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
|
||||
const UpdateSlotsFunctor & updateSubtitles, const std::vector<TradeItemBuy> & arts);
|
||||
};
|
||||
|
||||
class PlayersPanel : public TradePanelBase
|
||||
@ -123,11 +115,10 @@ class PlayersPanel : public TradePanelBase
|
||||
Point(83, 236)
|
||||
};
|
||||
const Point slotDimension = Point(58, 64);
|
||||
const Point selectedImagePos = Point(83, 368);
|
||||
const Point selectedSubtitlePos = Point(112, 443);
|
||||
const Point selectedPos = Point(83, 367);
|
||||
|
||||
public:
|
||||
explicit PlayersPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback);
|
||||
explicit PlayersPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback);
|
||||
};
|
||||
|
||||
class CreaturesPanel : public TradePanelBase
|
||||
@ -138,14 +129,13 @@ class CreaturesPanel : public TradePanelBase
|
||||
Point(0, 98), Point(83, 98), Point(166, 98),
|
||||
Point(83, 196)
|
||||
};
|
||||
const Point slotDimension = Point(58, 64);
|
||||
const Point selectedImagePos = Point(83, 327);
|
||||
const Point selectedSubtitlePos = Point(113, 403);
|
||||
const Point slotDimension = Point(59, 64);
|
||||
const Point selectedPos = Point(83, 327);
|
||||
|
||||
public:
|
||||
using slotsData = std::vector<std::tuple<CreatureID, SlotID, int>>;
|
||||
|
||||
CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, const slotsData & initialSlots);
|
||||
CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback,
|
||||
CreaturesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback, const slotsData & initialSlots);
|
||||
CreaturesPanel(const CTradeableItem::ClickPressedFunctor & clickPressedCallback,
|
||||
const std::vector<std::shared_ptr<CTradeableItem>> & srcSlots, bool emptySlots = true);
|
||||
};
|
||||
|
@ -69,6 +69,8 @@ void CMarketWindow::updateGarrisons()
|
||||
{
|
||||
if(guild)
|
||||
guild->updateSlots();
|
||||
if(altar)
|
||||
altar->updateSlots();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
|
||||
|
@ -9,7 +9,8 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "CTradeWindow.h"
|
||||
#include "../widgets/markets/CTradeBase.h"
|
||||
#include "CWindowObject.h"
|
||||
#include "CAltarWindow.h"
|
||||
|
||||
class CArtifactsBuying;
|
||||
@ -30,7 +31,6 @@ public:
|
||||
|
||||
private:
|
||||
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 createArtifactsSelling(const IMarket * market, const CGHeroInstance * hero);
|
||||
@ -47,7 +47,6 @@ private:
|
||||
std::function<void()> windowClosedCallback;
|
||||
const Point quitButtonPos = Point(516, 520);
|
||||
|
||||
std::shared_ptr<CMarketplaceWindow> market;
|
||||
std::shared_ptr<CFreelancerGuild> guild;
|
||||
std::shared_ptr<CMarketResources> resRes;
|
||||
std::shared_ptr<CTransferResources> trRes;
|
||||
|
@ -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]);
|
||||
}
|
@ -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();
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user