2
0
SoundSSGood 1 жил өмнө
parent
commit
4d3bf882ed

+ 2 - 0
client/CMakeLists.txt

@@ -126,6 +126,7 @@ set(client_SRCS
 	widgets/markets/CAltarArtifacts.cpp
 	widgets/markets/CAltarArtifacts.cpp
 	widgets/markets/CAltarCreatures.cpp
 	widgets/markets/CAltarCreatures.cpp
 	widgets/markets/CFreelancerGuild.cpp
 	widgets/markets/CFreelancerGuild.cpp
+	widgets/markets/CMarketResources.cpp
 	widgets/markets/CTradeBase.cpp
 	widgets/markets/CTradeBase.cpp
 	widgets/markets/TradePanels.cpp
 	widgets/markets/TradePanels.cpp
 
 
@@ -312,6 +313,7 @@ set(client_HEADERS
 	widgets/markets/CAltarArtifacts.h
 	widgets/markets/CAltarArtifacts.h
 	widgets/markets/CAltarCreatures.h
 	widgets/markets/CAltarCreatures.h
 	widgets/markets/CFreelancerGuild.h
 	widgets/markets/CFreelancerGuild.h
+	widgets/markets/CMarketResources.h
 	widgets/markets/CTradeBase.h
 	widgets/markets/CTradeBase.h
 	widgets/markets/TradePanels.h
 	widgets/markets/TradePanels.h
 
 

+ 4 - 4
client/widgets/markets/CAltarArtifacts.cpp

@@ -39,7 +39,7 @@ CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance *
 		CGI->generaltexth->zelp[585], [this]() {CAltarArtifacts::makeDeal(); });
 		CGI->generaltexth->zelp[585], [this]() {CAltarArtifacts::makeDeal(); });
 	labels.emplace_back(std::make_shared<CLabel>(450, 34, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[477]));
 	labels.emplace_back(std::make_shared<CLabel>(450, 34, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[477]));
 	labels.emplace_back(std::make_shared<CLabel>(302, 423, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[478]));
 	labels.emplace_back(std::make_shared<CLabel>(302, 423, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[478]));
-	lSubtitle = std::make_shared<CLabel>(302, 501, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
+	selectedSubtitle = std::make_shared<CLabel>(302, 501, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
 	selectedArt = std::make_shared<CArtPlace>(Point(280, 442));
 	selectedArt = std::make_shared<CArtPlace>(Point(280, 442));
 
 
 	sacrificeAllButton = std::make_shared<CButton>(Point(393, 520), AnimationPath::builtin("ALTFILL.DEF"),
 	sacrificeAllButton = std::make_shared<CButton>(Point(393, 520), AnimationPath::builtin("ALTFILL.DEF"),
@@ -109,7 +109,7 @@ void CAltarArtifacts::sacrificeBackpack()
 void CAltarArtifacts::setSelectedArtifact(const CArtifactInstance * art)
 void CAltarArtifacts::setSelectedArtifact(const CArtifactInstance * art)
 {
 {
 	selectedArt->setArtifact(art);
 	selectedArt->setArtifact(art);
-	lSubtitle->setText(art == nullptr ? "" : std::to_string(calcExpCost(art)));
+	selectedSubtitle->setText(art == nullptr ? "" : std::to_string(calcExpCost(art)));
 }
 }
 
 
 std::shared_ptr<CArtifactsOfHeroAltar> CAltarArtifacts::getAOHset() const
 std::shared_ptr<CArtifactsOfHeroAltar> CAltarArtifacts::getAOHset() const
@@ -210,8 +210,8 @@ void CAltarArtifacts::onSlotClickPressed(const std::shared_ptr<CTradeableItem> &
 
 
 TExpType CAltarArtifacts::calcExpCost(const CArtifactInstance * art)
 TExpType CAltarArtifacts::calcExpCost(const CArtifactInstance * art)
 {
 {
-	int dmp = 0;
+	int bidQty = 0;
 	int expOfArt = 0;
 	int expOfArt = 0;
-	market->getOffer(art->getTypeId(), 0, dmp, expOfArt, EMarketMode::ARTIFACT_EXP);
+	market->getOffer(art->getTypeId(), 0, bidQty, expOfArt, EMarketMode::ARTIFACT_EXP);
 	return hero->calculateXp(expOfArt);
 	return hero->calculateXp(expOfArt);
 }
 }

+ 1 - 0
client/widgets/markets/CAltarArtifacts.h

@@ -30,6 +30,7 @@ private:
 	ObjectInstanceID altarId;
 	ObjectInstanceID altarId;
 	const CArtifactSet * altarArtifacts;
 	const CArtifactSet * altarArtifacts;
 	std::shared_ptr<CArtPlace> selectedArt;
 	std::shared_ptr<CArtPlace> selectedArt;
+	std::shared_ptr<CLabel> selectedSubtitle;
 	std::shared_ptr<CButton> sacrificeBackpackButton;
 	std::shared_ptr<CButton> sacrificeBackpackButton;
 	std::shared_ptr<CArtifactsOfHeroAltar> heroArts;
 	std::shared_ptr<CArtifactsOfHeroAltar> heroArts;
 	std::map<const CArtifactInstance*, std::shared_ptr<CTradeableItem>> tradeSlotsMap;
 	std::map<const CArtifactInstance*, std::shared_ptr<CTradeableItem>> tradeSlotsMap;

+ 17 - 23
client/widgets/markets/CAltarCreatures.cpp

@@ -36,11 +36,8 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
 		boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated())));
 		boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated())));
 	labels.emplace_back(std::make_shared<CLabel>(450, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[479]));
 	labels.emplace_back(std::make_shared<CLabel>(450, 30, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[479]));
 	texts.emplace_back(std::make_unique<CTextBox>(CGI->generaltexth->allTexts[480], Rect(320, 56, 256, 40), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW));
 	texts.emplace_back(std::make_unique<CTextBox>(CGI->generaltexth->allTexts[480], Rect(320, 56, 256, 40), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::YELLOW));
-	lSubtitle = std::make_shared<CLabel>(180, 503, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
-	rSubtitle = std::make_shared<CLabel>(426, 503, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
-
 	offerSlider = std::make_shared<CSlider>(Point(231, 481), 137, std::bind(&CAltarCreatures::onOfferSliderMoved, this, _1), 0, 0, 0, Orientation::HORIZONTAL);
 	offerSlider = std::make_shared<CSlider>(Point(231, 481), 137, std::bind(&CAltarCreatures::onOfferSliderMoved, this, _1), 0, 0, 0, Orientation::HORIZONTAL);
-	maxUnits = std::make_shared<CButton>(Point(147, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[578], std::bind(&CSlider::scrollToMax, offerSlider));
+	maxAmount = std::make_shared<CButton>(Point(147, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[578], std::bind(&CSlider::scrollToMax, offerSlider));
 
 
 	unitsOnAltar.resize(GameConstants::ARMY_SIZE, 0);
 	unitsOnAltar.resize(GameConstants::ARMY_SIZE, 0);
 	expPerUnit.resize(GameConstants::ARMY_SIZE, 0);
 	expPerUnit.resize(GameConstants::ARMY_SIZE, 0);
@@ -49,9 +46,9 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
 
 
 	// Hero creatures panel
 	// Hero creatures panel
 	assert(leftTradePanel);
 	assert(leftTradePanel);
-	leftTradePanel->selectedImage->moveTo(pos.topLeft() + Point(104, 312));
-
-	leftTradePanel->moveBy(Point(45, 110));
+	leftTradePanel->moveTo(pos.topLeft() + Point(45, 110));
+	leftTradePanel->selectedImage->moveTo(pos.topLeft() + Point(149, 422));
+	leftTradePanel->selectedSubtitle->moveTo(pos.topLeft() + Point(180, 503));
 	for(const auto & slot : leftTradePanel->slots)
 	for(const auto & slot : leftTradePanel->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);};
 
 
@@ -60,22 +57,22 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
 		{
 		{
 			CAltarCreatures::onSlotClickPressed(altarSlot, hRight);
 			CAltarCreatures::onSlotClickPressed(altarSlot, hRight);
 		}, leftTradePanel->slots);
 		}, leftTradePanel->slots);
-	rightTradePanel->selectedImage->moveTo(pos.topLeft() + Point(61, 312));
-	rightTradePanel->moveBy(Point(334, 110));
-
+	rightTradePanel->moveTo(pos.topLeft() + Point(334, 110));
+	rightTradePanel->selectedImage->moveTo(pos.topLeft() + Point(395, 422));
+	rightTradePanel->selectedSubtitle->moveTo(pos.topLeft() + Point(426, 503));
 	leftTradePanel->deleteSlotsCheck = rightTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1);
 	leftTradePanel->deleteSlotsCheck = rightTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1);
+	
 	readExpValues();
 	readExpValues();
-	expForHero->setText(std::to_string(0));
 	CAltarCreatures::deselect();
 	CAltarCreatures::deselect();
 };
 };
 
 
 void CAltarCreatures::readExpValues()
 void CAltarCreatures::readExpValues()
 {
 {
-	int dump;
+	int bidQty = 0;
 	for(auto heroSlot : leftTradePanel->slots)
 	for(auto heroSlot : leftTradePanel->slots)
 	{
 	{
 		if(heroSlot->id >= 0)
 		if(heroSlot->id >= 0)
-			market->getOffer(heroSlot->id, 0, dump, expPerUnit[heroSlot->serial], EMarketMode::CREATURE_EXP);
+			market->getOffer(heroSlot->id, 0, bidQty, expPerUnit[heroSlot->serial], EMarketMode::CREATURE_EXP);
 	}
 	}
 }
 }
 
 
@@ -108,7 +105,7 @@ void CAltarCreatures::updateControls()
 	offerSlider->block(!offerSlider->getAmount());
 	offerSlider->block(!offerSlider->getAmount());
 	if(hLeft)
 	if(hLeft)
 		offerSlider->scrollTo(unitsOnAltar[hLeft->serial]);
 		offerSlider->scrollTo(unitsOnAltar[hLeft->serial]);
-	maxUnits->block(offerSlider->getAmount() == 0);
+	maxAmount->block(offerSlider->getAmount() == 0);
 }
 }
 
 
 void CAltarCreatures::updateSelected()
 void CAltarCreatures::updateSelected()
@@ -118,26 +115,25 @@ void CAltarCreatures::updateSelected()
 
 
 	if(hLeft)
 	if(hLeft)
 	{
 	{
-		lSubtitle->setText(std::to_string(offerSlider->getValue()));
+		leftTradePanel->selectedSubtitle->setText(std::to_string(offerSlider->getValue()));
 		lImageIndex = CGI->creatures()->getByIndex(hLeft->id)->getIconIndex();
 		lImageIndex = CGI->creatures()->getByIndex(hLeft->id)->getIconIndex();
 	}
 	}
 	else
 	else
 	{
 	{
-		lSubtitle->setText("");
+		leftTradePanel->selectedSubtitle->setText("");
 	}
 	}
 	if(hRight)
 	if(hRight)
 	{
 	{
-		rSubtitle->setText(hRight->subtitle);
+		rightTradePanel->selectedSubtitle->setText(hRight->subtitle);
 		if(offerSlider->getValue() != 0)
 		if(offerSlider->getValue() != 0)
 			rImageIndex = CGI->creatures()->getByIndex(hRight->id)->getIconIndex();
 			rImageIndex = CGI->creatures()->getByIndex(hRight->id)->getIconIndex();
 	}
 	}
 	else
 	else
 	{
 	{
-		rSubtitle->setText("");
+		rightTradePanel->selectedSubtitle->setText("");
 	}
 	}
 	leftTradePanel->setSelectedFrameIndex(lImageIndex);
 	leftTradePanel->setSelectedFrameIndex(lImageIndex);
 	rightTradePanel->setSelectedFrameIndex(rImageIndex);
 	rightTradePanel->setSelectedFrameIndex(rImageIndex);
-	rightTradePanel->selectedImage->redraw();
 }
 }
 
 
 void CAltarCreatures::updateSlots()
 void CAltarCreatures::updateSlots()
@@ -151,10 +147,8 @@ void CAltarCreatures::updateSlots()
 void CAltarCreatures::deselect()
 void CAltarCreatures::deselect()
 {
 {
 	CTradeBase::deselect();
 	CTradeBase::deselect();
-	offerSlider->block(true);
-	maxUnits->block(true);
-	offerSlider->scrollTo(0);
 	updateSelected();
 	updateSelected();
+	expForHero->setText(std::to_string(0));
 }
 }
 
 
 TExpType CAltarCreatures::calcExpAltarForHero()
 TExpType CAltarCreatures::calcExpAltarForHero()
@@ -171,7 +165,6 @@ TExpType CAltarCreatures::calcExpAltarForHero()
 void CAltarCreatures::makeDeal()
 void CAltarCreatures::makeDeal()
 {
 {
 	deselect();
 	deselect();
-	expForHero->setText(std::to_string(0));
 
 
 	std::vector<TradeItemSell> ids;
 	std::vector<TradeItemSell> ids;
 	std::vector<ui32> toSacrifice;
 	std::vector<ui32> toSacrifice;
@@ -242,6 +235,7 @@ void CAltarCreatures::onOfferSliderMoved(int newVal)
 	deal->block(calcExpAltarForHero() == 0);
 	deal->block(calcExpAltarForHero() == 0);
 	updateControls();
 	updateControls();
 	updateSelected();
 	updateSelected();
+	redraw();
 }
 }
 
 
 void CAltarCreatures::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
 void CAltarCreatures::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)

+ 0 - 1
client/widgets/markets/CAltarCreatures.h

@@ -23,7 +23,6 @@ public:
 	void updateAltarSlot(std::shared_ptr<CTradeableItem> slot);
 	void updateAltarSlot(std::shared_ptr<CTradeableItem> slot);
 
 
 private:
 private:
-	std::shared_ptr<CButton> maxUnits;
 	std::vector<int> unitsOnAltar;
 	std::vector<int> unitsOnAltar;
 	std::vector<int> expPerUnit;
 	std::vector<int> expPerUnit;
 
 

+ 29 - 36
client/widgets/markets/CFreelancerGuild.cpp

@@ -28,29 +28,27 @@
 
 
 CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero)
 CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero)
 	: CTradeBase(market, hero)
 	: CTradeBase(market, hero)
-	, CResourcesMarket(EMarketMode::CREATURE_RESOURCE)
+	, CResourcesPurchasing([this](){CResourcesPurchasing::updateSubtitles(EMarketMode::CREATURE_RESOURCE);})
 {
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
 	OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
 
 
-	labels.emplace_back(std::make_shared<CLabel>(254, -96, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW,
+	labels.emplace_back(std::make_shared<CLabel>(299, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW,
 		(*CGI->townh)[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->getNameTranslated()));
 		(*CGI->townh)[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->getNameTranslated()));
-	labels.emplace_back(std::make_shared<CLabel>(110, -20, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE,
+	labels.emplace_back(std::make_shared<CLabel>(155, 103, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE,
 		boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated())));
 		boost::str(boost::format(CGI->generaltexth->allTexts[272]) % hero->getNameTranslated())));
-	deal = std::make_shared<CButton>(Point(262, 397), AnimationPath::builtin("ALTSACR.DEF"),
+	deal = std::make_shared<CButton>(Point(306, 520), AnimationPath::builtin("TPMRKB.DEF"),
 		CGI->generaltexth->zelp[595], [this]() {CFreelancerGuild::makeDeal();});
 		CGI->generaltexth->zelp[595], [this]() {CFreelancerGuild::makeDeal();});
-	deal->block(true);
-	maxUnits = std::make_shared<CButton>(Point(183, 397), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596],
+	maxAmount = std::make_shared<CButton>(Point(228, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596],
 		[this]() {offerSlider->scrollToMax();});
 		[this]() {offerSlider->scrollToMax();});
-	maxUnits->block(true);
-	lSubtitle = std::make_shared<CLabel>(113, 403, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
-	rSubtitle = std::make_shared<CLabel>(400, 382, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
+	offerSlider = std::make_shared<CSlider>(Point(232, 489), 137, [this](int newVal)
+		{
+			CFreelancerGuild::onOfferSliderMoved(newVal);
+		}, 0, 0, 0, Orientation::HORIZONTAL);
 
 
 	// Hero creatures panel
 	// Hero creatures panel
 	assert(leftTradePanel);
 	assert(leftTradePanel);
-	leftTradePanel->deleteSlotsCheck = [this, hero](const std::shared_ptr<CTradeableItem> & slot)
-	{
-		return hero->getStackCount(SlotID(slot->serial)) == 0 ? true : false;
-	};
+	leftTradePanel->moveTo(pos.topLeft() + Point(45, 123));
+	leftTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1);
 	std::for_each(leftTradePanel->slots.cbegin(), leftTradePanel->slots.cend(), [this](auto & slot)
 	std::for_each(leftTradePanel->slots.cbegin(), leftTradePanel->slots.cend(), [this](auto & slot)
 		{
 		{
 			slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot)
 			slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot)
@@ -58,11 +56,10 @@ CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance
 				CFreelancerGuild::onSlotClickPressed(heroSlot, hLeft);
 				CFreelancerGuild::onSlotClickPressed(heroSlot, hLeft);
 			};
 			};
 		});
 		});
-	leftTradePanel->selectedImage->moveTo(pos.topLeft() + Point(83, 327));
 
 
 	// Guild resources panel
 	// Guild resources panel
 	assert(rightTradePanel);
 	assert(rightTradePanel);
-	rightTradePanel->moveBy(Point(282, 58));
+	rightTradePanel->moveBy(Point(327, 181));
 	std::for_each(rightTradePanel->slots.cbegin(), rightTradePanel->slots.cend(), [this](auto & slot)
 	std::for_each(rightTradePanel->slots.cbegin(), rightTradePanel->slots.cend(), [this](auto & slot)
 		{
 		{
 			slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot)
 			slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot)
@@ -70,12 +67,6 @@ CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance
 				CFreelancerGuild::onSlotClickPressed(heroSlot, hRight);
 				CFreelancerGuild::onSlotClickPressed(heroSlot, hRight);
 			};
 			};
 		});
 		});
-	rightTradePanel->selectedImage->moveTo(pos.topLeft() + Point(383, 335));
-
-	offerSlider = std::make_shared<CSlider>(Point(187, 366), 137, [this](int newVal)
-		{
-			CFreelancerGuild::onOfferSliderMoved(newVal);
-		}, 0, 0, 0, Orientation::HORIZONTAL);
 
 
 	CFreelancerGuild::deselect();
 	CFreelancerGuild::deselect();
 }
 }
@@ -87,15 +78,15 @@ void CFreelancerGuild::updateSelected()
 	
 	
 	if(hLeft && hRight)
 	if(hLeft && hRight)
 	{
 	{
-		lSubtitle->setText(std::to_string(qtyPerPrice * offerSlider->getValue()));
-		rSubtitle->setText(std::to_string(price * offerSlider->getValue()));
+		leftTradePanel->selectedSubtitle->setText(std::to_string(bidQty * offerSlider->getValue()));
+		rightTradePanel->selectedSubtitle->setText(std::to_string(offerQty * offerSlider->getValue()));
 		lImageIndex = CGI->creatures()->getByIndex(hLeft->id)->getIconIndex();
 		lImageIndex = CGI->creatures()->getByIndex(hLeft->id)->getIconIndex();
 		rImageIndex = hRight->id;
 		rImageIndex = hRight->id;
 	}
 	}
 	else
 	else
 	{
 	{
-		lSubtitle->setText("");
-		rSubtitle->setText("");
+		leftTradePanel->selectedSubtitle->setText("");
+		rightTradePanel->selectedSubtitle->setText("");
 	}
 	}
 	leftTradePanel->setSelectedFrameIndex(lImageIndex);
 	leftTradePanel->setSelectedFrameIndex(lImageIndex);
 	rightTradePanel->setSelectedFrameIndex(rImageIndex);
 	rightTradePanel->setSelectedFrameIndex(rImageIndex);
@@ -103,18 +94,17 @@ void CFreelancerGuild::updateSelected()
 
 
 void CFreelancerGuild::makeDeal()
 void CFreelancerGuild::makeDeal()
 {
 {
-	LOCPLINT->cb->trade(market, EMarketMode::CREATURE_RESOURCE, SlotID(hLeft->serial), GameResID(hRight->id), qtyPerPrice * offerSlider->getValue(), hero);
-	deselect();
+	if(auto toTrade = offerSlider->getValue(); toTrade != 0)
+	{
+		LOCPLINT->cb->trade(market, EMarketMode::CREATURE_RESOURCE, SlotID(hLeft->serial), GameResID(hRight->id), bidQty * toTrade, hero);
+		deselect();
+	}
 }
 }
 
 
 void CFreelancerGuild::deselect()
 void CFreelancerGuild::deselect()
 {
 {
-	CTradeBase::deselect();
-	maxUnits->block(true);
+	CResourcesPurchasing::deselect();
 	updateSelected();
 	updateSelected();
-	qtyPerPrice = 0;
-	price = 0;
-	offerSlider->scrollTo(0);
 }
 }
 
 
 void CFreelancerGuild::onOfferSliderMoved(int newVal)
 void CFreelancerGuild::onOfferSliderMoved(int newVal)
@@ -129,16 +119,19 @@ void CFreelancerGuild::onOfferSliderMoved(int newVal)
 
 
 void CFreelancerGuild::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
 void CFreelancerGuild::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
 {
 {
+	if(newSlot == hCurSlot)
+		return;
+
 	CTradeBase::onSlotClickPressed(newSlot, hCurSlot);
 	CTradeBase::onSlotClickPressed(newSlot, hCurSlot);
-	
 	if(hLeft)
 	if(hLeft)
 	{
 	{
 		if(hRight)
 		if(hRight)
 		{
 		{
-			market->getOffer(hLeft->id, hRight->id, qtyPerPrice, price, EMarketMode::CREATURE_RESOURCE);
-			offerSlider->setAmount((hero->getStackCount(SlotID(hLeft->serial)) - (hero->stacksCount() == 1 && hero->needsLastStack() ? 1 : 0)) / qtyPerPrice);
+			market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::CREATURE_RESOURCE);
+			offerSlider->setAmount((hero->getStackCount(SlotID(hLeft->serial)) - (hero->stacksCount() == 1 && hero->needsLastStack() ? 1 : 0)) / bidQty);
 			offerSlider->scrollTo(0);
 			offerSlider->scrollTo(0);
-			maxUnits->block(false);
+			offerSlider->block(false);
+			maxAmount->block(false);
 			deal->block(false);
 			deal->block(false);
 		}
 		}
 		updateSelected();
 		updateSelected();

+ 1 - 5
client/widgets/markets/CFreelancerGuild.h

@@ -11,7 +11,7 @@
 
 
 #include "CTradeBase.h"
 #include "CTradeBase.h"
 
 
-class CFreelancerGuild : public CCreaturesSelling , public CResourcesMarket
+class CFreelancerGuild : public CCreaturesSelling , public CResourcesPurchasing
 {
 {
 public:
 public:
 	CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero);
 	CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero);
@@ -19,10 +19,6 @@ public:
 	void deselect() override;
 	void deselect() override;
 
 
 private:
 private:
-	std::shared_ptr<CButton> maxUnits;
-	int qtyPerPrice;
-	int price;
-
 	void updateSelected();
 	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;

+ 145 - 0
client/widgets/markets/CMarketResources.cpp

@@ -0,0 +1,145 @@
+/*
+ * CMarketResources.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 "CMarketResources.h"
+
+#include "../../gui/CGuiHandler.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/mapObjects/CGHeroInstance.h"
+#include "../../../lib/mapObjects/CGMarket.h"
+
+CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance * hero)
+	: CTradeBase(market, hero)
+	, CResourcesPurchasing([this](){CMarketResources::updateSubtitles();})
+{
+	OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
+
+	labels.emplace_back(std::make_shared<CLabel>(299, 27, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[158]));
+	deal = std::make_shared<CButton>(Point(306, 520), AnimationPath::builtin("TPMRKB.DEF"),
+		CGI->generaltexth->zelp[595], [this]() {CMarketResources::makeDeal(); });
+	maxAmount = std::make_shared<CButton>(Point(228, 520), AnimationPath::builtin("IRCBTNS.DEF"), CGI->generaltexth->zelp[596],
+		[this]() {offerSlider->scrollToMax(); });
+	offerSlider = std::make_shared<CSlider>(Point(230, 489), 137, [this](int newVal)
+		{
+			CMarketResources::onOfferSliderMoved(newVal);
+		}, 0, 0, 0, Orientation::HORIZONTAL);
+
+	// Player's resources
+	assert(leftTradePanel);
+	std::for_each(leftTradePanel->slots.cbegin(), leftTradePanel->slots.cend(), [this](auto & slot)
+		{
+			slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot)
+			{
+				CMarketResources::onSlotClickPressed(heroSlot, hLeft);
+			};
+		});
+	leftTradePanel->moveTo(pos.topLeft() + Point(39, 181));
+
+	// Market resources panel
+	assert(rightTradePanel);
+	rightTradePanel->moveTo(pos.topLeft() + Point(327, 181));
+	std::for_each(rightTradePanel->slots.cbegin(), rightTradePanel->slots.cend(), [this](auto & slot)
+		{
+			slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & resSlot)
+			{
+				CMarketResources::onSlotClickPressed(resSlot, hRight);
+			};
+		});
+
+	CResourcesSelling::updateSlots();
+	CMarketResources::deselect();
+}
+
+void CMarketResources::makeDeal()
+{
+	if(auto toTrade = offerSlider->getValue(); toTrade != 0)
+	{
+		LOCPLINT->cb->trade(market, EMarketMode::RESOURCE_RESOURCE, GameResID(hLeft->id), GameResID(hRight->id), bidQty * toTrade, hero);
+		deselect();
+	}
+}
+
+void CMarketResources::deselect()
+{
+	CResourcesPurchasing::deselect();
+	updateSelected();
+}
+
+void CMarketResources::updateSelected()
+{
+	std::optional<size_t> lImageIndex = std::nullopt;
+	std::optional<size_t> rImageIndex = std::nullopt;
+
+	if(hLeft && hRight && hLeft->id != hRight->id)
+	{
+		leftTradePanel->selectedSubtitle->setText(std::to_string(bidQty * offerSlider->getValue()));
+		rightTradePanel->selectedSubtitle->setText(std::to_string(offerQty * offerSlider->getValue()));
+		lImageIndex = hLeft->id;
+		rImageIndex = hRight->id;
+	}
+	else
+	{
+		leftTradePanel->selectedSubtitle->setText("");
+		rightTradePanel->selectedSubtitle->setText("");
+	}
+	leftTradePanel->setSelectedFrameIndex(lImageIndex);
+	rightTradePanel->setSelectedFrameIndex(rImageIndex);
+}
+
+void CMarketResources::onOfferSliderMoved(int newVal)
+{
+	if(hLeft && hRight)
+	{
+		offerSlider->scrollTo(newVal);
+		updateSelected();
+		redraw();
+	}
+}
+
+void CMarketResources::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
+{
+	if(newSlot == hCurSlot)
+		return;
+
+	CTradeBase::onSlotClickPressed(newSlot, hCurSlot);
+	if(hLeft)
+	{
+		if(hRight)
+		{
+			market->getOffer(hLeft->id, hRight->id, bidQty, offerQty, EMarketMode::RESOURCE_RESOURCE);
+			offerSlider->setAmount(LOCPLINT->cb->getResourceAmount(GameResID(hLeft->id)) / bidQty);
+			offerSlider->scrollTo(0);
+			const bool isControlsBlocked = hLeft->id != hRight->id ? false : true;
+			offerSlider->block(isControlsBlocked);
+			maxAmount->block(isControlsBlocked);
+			deal->block(isControlsBlocked);
+		}
+		updateSelected();
+		rightTradePanel->updateSlots();
+	}
+	redraw();
+}
+
+void CMarketResources::updateSubtitles()
+{
+	CResourcesPurchasing::updateSubtitles(EMarketMode::RESOURCE_RESOURCE);
+	if(hLeft)
+		rightTradePanel->slots[hLeft->serial]->subtitle = CGI->generaltexth->allTexts[164]; // n/a
+}

+ 26 - 0
client/widgets/markets/CMarketResources.h

@@ -0,0 +1,26 @@
+/*
+ * CMarketResources.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 "CTradeBase.h"
+
+class CMarketResources : public CResourcesSelling, public CResourcesPurchasing
+{
+public:
+	CMarketResources(const IMarket * market, const CGHeroInstance * hero);
+	void makeDeal() override;
+	void deselect() override;
+
+private:
+	void updateSelected();
+	void onOfferSliderMoved(int newVal);
+	void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot);
+	void updateSubtitles();
+};

+ 41 - 7
client/widgets/markets/CTradeBase.cpp

@@ -14,9 +14,13 @@
 
 
 #include "../../gui/CGuiHandler.h"
 #include "../../gui/CGuiHandler.h"
 #include "../../widgets/Buttons.h"
 #include "../../widgets/Buttons.h"
+#include "../../widgets/Slider.h"
 #include "../../widgets/TextControls.h"
 #include "../../widgets/TextControls.h"
 
 
 #include "../../CGameInfo.h"
 #include "../../CGameInfo.h"
+#include "../../CPlayerInterface.h"
+
+#include "../../../CCallback.h"
 
 
 #include "../../../lib/CGeneralTextHandler.h"
 #include "../../../lib/CGeneralTextHandler.h"
 #include "../../../lib/mapObjects/CGHeroInstance.h"
 #include "../../../lib/mapObjects/CGHeroInstance.h"
@@ -57,6 +61,13 @@ void CTradeBase::deselect()
 		hRight->selectSlot(false);
 		hRight->selectSlot(false);
 	hLeft = hRight = nullptr;
 	hLeft = hRight = nullptr;
 	deal->block(true);
 	deal->block(true);
+	if(maxAmount)
+		maxAmount->block(true);
+	if(offerSlider)
+	{
+		offerSlider->scrollTo(0);
+		offerSlider->block(true);
+	}
 }
 }
 
 
 void CTradeBase::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
 void CTradeBase::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
@@ -114,19 +125,18 @@ void CCreaturesSelling::updateSlots()
 	leftTradePanel->updateSlots();
 	leftTradePanel->updateSlots();
 }
 }
 
 
-CResourcesMarket::CResourcesMarket(EMarketMode marketMode)
+CResourcesPurchasing::CResourcesPurchasing(TradePanelBase::UpdateSlotsFunctor callback)
 {
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
 	OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
 
 
-	rightTradePanel = std::make_shared<ResourcesPanel>([](const std::shared_ptr<CTradeableItem>&) {}, [this, marketMode]()
-		{
-			updateSubtitles(marketMode);
-		});
-	labels.emplace_back(std::make_shared<CLabel>(400, 25, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168]));
+	rightTradePanel = std::make_shared<ResourcesPanel>([](const std::shared_ptr<CTradeableItem>&) {}, callback);
+	labels.emplace_back(std::make_shared<CLabel>(445, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168]));
 }
 }
 
 
-void CResourcesMarket::updateSubtitles(EMarketMode marketMode)
+void CResourcesPurchasing::updateSubtitles(EMarketMode marketMode)
 {
 {
+	assert(marketMode == EMarketMode::RESOURCE_RESOURCE || marketMode == EMarketMode::CREATURE_RESOURCE || marketMode == EMarketMode::ARTIFACT_RESOURCE);
+
 	if(hLeft)
 	if(hLeft)
 		for(const auto & slot : rightTradePanel->slots)
 		for(const auto & slot : rightTradePanel->slots)
 		{
 		{
@@ -138,3 +148,27 @@ void CResourcesMarket::updateSubtitles(EMarketMode marketMode)
 	else
 	else
 		rightTradePanel->clearSubtitles();
 		rightTradePanel->clearSubtitles();
 };
 };
+
+void CResourcesPurchasing::deselect()
+{
+	CTradeBase::deselect();
+	bidQty = 0;
+	offerQty = 0;
+}
+
+CResourcesSelling::CResourcesSelling()
+{
+	OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
+
+	leftTradePanel = std::make_shared<ResourcesPanel>([](const std::shared_ptr<CTradeableItem>&) {}, [this]()
+		{
+			for(const auto & slot : leftTradePanel->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]));
+}
+
+void CResourcesSelling::updateSlots()
+{
+	leftTradePanel->updateSlots();
+}

+ 15 - 7
client/widgets/markets/CTradeBase.h

@@ -35,13 +35,11 @@ public:
 	//highlighted items (nullptr if no highlight)
 	//highlighted items (nullptr if no highlight)
 	std::shared_ptr<CTradeableItem> hLeft;
 	std::shared_ptr<CTradeableItem> hLeft;
 	std::shared_ptr<CTradeableItem> hRight;
 	std::shared_ptr<CTradeableItem> hRight;
-	std::shared_ptr<CLabel> lSubtitle;
-	std::shared_ptr<CLabel> rSubtitle;
 	std::shared_ptr<CButton> deal;
 	std::shared_ptr<CButton> deal;
 	std::shared_ptr<CSlider> offerSlider;
 	std::shared_ptr<CSlider> offerSlider;
+	std::shared_ptr<CButton> maxAmount;
 
 
 	std::vector<std::shared_ptr<CLabel>> labels;
 	std::vector<std::shared_ptr<CLabel>> labels;
-	std::vector<std::shared_ptr<CButton>> buttons;
 	std::vector<std::shared_ptr<CTextBox>> texts;
 	std::vector<std::shared_ptr<CTextBox>> texts;
 
 
 	CTradeBase(const IMarket * market, const CGHeroInstance * hero);
 	CTradeBase(const IMarket * market, const CGHeroInstance * hero);
@@ -77,11 +75,21 @@ public:
 	void updateSlots() override;
 	void updateSlots() override;
 };
 };
 
 
-class CResourcesMarket : virtual public CTradeBase, virtual public CIntObject
+class CResourcesPurchasing : virtual public CTradeBase, virtual public CIntObject
 {
 {
 public:
 public:
-	CResourcesMarket(EMarketMode marketMode);
-
-private:
+	CResourcesPurchasing(TradePanelBase::UpdateSlotsFunctor callback);
 	void updateSubtitles(EMarketMode marketMode);
 	void updateSubtitles(EMarketMode marketMode);
+	void deselect() override;
+
+protected:
+	int bidQty;
+	int offerQty;
+};
+
+class CResourcesSelling : virtual public CTradeBase, virtual public CIntObject
+{
+public:
+	CResourcesSelling();
+	void updateSlots() override;
 };
 };

+ 6 - 3
client/widgets/markets/TradePanels.cpp

@@ -325,7 +325,8 @@ ResourcesPanel::ResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedC
 		slot->setSelectionWidth(selectionWidth);
 		slot->setSelectionWidth(selectionWidth);
 	}
 	}
 	updateSlotsCallback = updateSubtitles;
 	updateSlotsCallback = updateSubtitles;
-	selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("RESOURCE"), 0);
+	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);
 }
 }
 
 
 ArtifactsPanel::ArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles,
 ArtifactsPanel::ArtifactsPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles,
@@ -388,7 +389,8 @@ CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedC
 			slot->subtitle = std::to_string(creaturesNum);
 			slot->subtitle = std::to_string(creaturesNum);
 		slot->setSelectionWidth(selectionWidth);
 		slot->setSelectionWidth(selectionWidth);
 	}
 	}
-	selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("TWCRPORT"), 0);
+	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);
 }
 }
 
 
 CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback,
 CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback,
@@ -405,5 +407,6 @@ CreaturesPanel::CreaturesPanel(CTradeableItem::ClickPressedFunctor clickPressedC
 		slot->subtitle = emptySlots ? "" : srcSlot->subtitle;
 		slot->subtitle = emptySlots ? "" : srcSlot->subtitle;
 		slot->setSelectionWidth(selectionWidth);
 		slot->setSelectionWidth(selectionWidth);
 	}
 	}
-	selectedImage = std::make_shared<CAnimImage>(AnimationPath::builtin("TWCRPORT"), 0);
+	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);
 }
 }

+ 5 - 0
client/widgets/markets/TradePanels.h

@@ -65,6 +65,7 @@ public:
 	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<CAnimImage> selectedImage;
+	std::shared_ptr<CLabel> selectedSubtitle;
 
 
 	virtual void updateSlots();
 	virtual void updateSlots();
 	virtual void deselect();
 	virtual void deselect();
@@ -89,6 +90,8 @@ 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(102, 276);
+	const Point selectedSubtitlePos = Point(118, 324);
 
 
 public:
 public:
 	ResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles);
 	ResourcesPanel(CTradeableItem::ClickPressedFunctor clickPressedCallback, UpdateSlotsFunctor updateSubtitles);
@@ -133,6 +136,8 @@ class CreaturesPanel : public TradePanelBase
 		Point(83, 196)
 		Point(83, 196)
 	};
 	};
 	const Point slotDimension = Point(58, 64);
 	const Point slotDimension = Point(58, 64);
+	const Point selectedImagePos = 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>>;

+ 15 - 4
client/windows/CMarketWindow.cpp

@@ -17,6 +17,7 @@
 #include "../widgets/Buttons.h"
 #include "../widgets/Buttons.h"
 #include "../widgets/TextControls.h"
 #include "../widgets/TextControls.h"
 #include "../widgets/markets/CFreelancerGuild.h"
 #include "../widgets/markets/CFreelancerGuild.h"
+#include "../widgets/markets/CMarketResources.h"
 
 
 #include "../CGameInfo.h"
 #include "../CGameInfo.h"
 #include "../CPlayerInterface.h"
 #include "../CPlayerInterface.h"
@@ -69,7 +70,8 @@ void CMarketWindow::updateGarrisons()
 
 
 void CMarketWindow::resourceChanged()
 void CMarketWindow::resourceChanged()
 {
 {
-	//market->initSubs(true);
+	if(resRes)
+		resRes->updateSlots();
 }
 }
 
 
 void CMarketWindow::close()
 void CMarketWindow::close()
@@ -181,8 +183,17 @@ void CMarketWindow::createMarketResources(const IMarket * market, const CGHeroIn
 	OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
 	OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
 
 
 	background = createBg(ImagePath::builtin("TPMRKRES.bmp"), PLAYER_COLORED);
 	background = createBg(ImagePath::builtin("TPMRKRES.bmp"), PLAYER_COLORED);
-	this->market = std::make_shared<CMarketplaceWindow>(market, hero, []() {}, EMarketMode::RESOURCE_RESOURCE);
-	createInternals(EMarketMode::RESOURCE_RESOURCE, market, hero);
+	resRes = std::make_shared<CMarketResources>(market, hero);
+
+	background->center();
+	pos = background->pos;
+	resRes->setRedrawParent(true);
+	resRes->moveTo(pos.topLeft());
+
+	createChangeModeButtons(EMarketMode::RESOURCE_RESOURCE, market, hero);
+	quitButton = std::make_shared<CButton>(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"),
+		CGI->generaltexth->zelp[600], [this]() {close(); }, EShortcut::GLOBAL_RETURN);
+	redraw();
 }
 }
 
 
 void CMarketWindow::createFreelancersGuild(const IMarket * market, const CGHeroInstance * hero)
 void CMarketWindow::createFreelancersGuild(const IMarket * market, const CGHeroInstance * hero)
@@ -195,7 +206,7 @@ void CMarketWindow::createFreelancersGuild(const IMarket * market, const CGHeroI
 	background->center();
 	background->center();
 	pos = background->pos;
 	pos = background->pos;
 	guild->setRedrawParent(true);
 	guild->setRedrawParent(true);
-	guild->moveTo(Point(257, 211));
+	guild->moveTo(pos.topLeft());
 
 
 	createChangeModeButtons(EMarketMode::CREATURE_RESOURCE, market, hero);
 	createChangeModeButtons(EMarketMode::CREATURE_RESOURCE, market, hero);
 	quitButton = std::make_shared<CButton>(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"),
 	quitButton = std::make_shared<CButton>(quitButtonPos, AnimationPath::builtin("IOK6432.DEF"),

+ 2 - 0
client/windows/CMarketWindow.h

@@ -13,6 +13,7 @@
 #include "CAltarWindow.h"
 #include "CAltarWindow.h"
 
 
 class CFreelancerGuild;
 class CFreelancerGuild;
+class CMarketResources;
 
 
 class CMarketWindow : public CStatusbarWindow, public CAltarWindow // TODO remove CAltarWindow
 class CMarketWindow : public CStatusbarWindow, public CAltarWindow // TODO remove CAltarWindow
 {
 {
@@ -45,4 +46,5 @@ private:
 
 
 	std::shared_ptr<CMarketplaceWindow> market;
 	std::shared_ptr<CMarketplaceWindow> market;
 	std::shared_ptr<CFreelancerGuild> guild;
 	std::shared_ptr<CFreelancerGuild> guild;
+	std::shared_ptr<CMarketResources> resRes;
 };
 };

+ 1 - 18
client/windows/CTradeWindow.cpp

@@ -103,7 +103,7 @@ void CTradeWindow::initItems(bool Left)
 			CTradeBase::onSlotClickPressed(newSlot, left ? hLeft : hRight);
 			CTradeBase::onSlotClickPressed(newSlot, left ? hLeft : hRight);
 			selectionChanged(left);
 			selectionChanged(left);
 		};
 		};
-		if(Left && (mode == EMarketMode::RESOURCE_RESOURCE || mode == EMarketMode::RESOURCE_ARTIFACT || mode == EMarketMode::RESOURCE_PLAYER))
+		if(Left && (mode == EMarketMode::RESOURCE_ARTIFACT || mode == EMarketMode::RESOURCE_PLAYER))
 		{
 		{
 			leftTradePanel = std::make_shared<ResourcesPanel>(
 			leftTradePanel = std::make_shared<ResourcesPanel>(
 				[clickPressedTradePanel](const std::shared_ptr<CTradeableItem> & newSlot)
 				[clickPressedTradePanel](const std::shared_ptr<CTradeableItem> & newSlot)
@@ -118,21 +118,6 @@ void CTradeWindow::initItems(bool Left)
 			leftTradePanel->moveBy(Point(39, 182));
 			leftTradePanel->moveBy(Point(39, 182));
 			leftTradePanel->updateSlots();
 			leftTradePanel->updateSlots();
 		}
 		}
-		else if(!Left && mode == EMarketMode::RESOURCE_RESOURCE)
-		{
-			rightTradePanel = std::make_shared<ResourcesPanel>(
-				[clickPressedTradePanel](const std::shared_ptr<CTradeableItem> & newSlot)
-				{
-					clickPressedTradePanel(newSlot, false);
-				},
-				[this, updRightSub]()
-				{
-					updRightSub(EMarketMode::RESOURCE_RESOURCE);
-					if(hLeft)
-						rightTradePanel->slots[hLeft->serial]->subtitle = CGI->generaltexth->allTexts[164]; // n/a
-				});
-			rightTradePanel->moveBy(Point(327, 181));
-		}
 		else if(!Left && (mode == EMarketMode::ARTIFACT_RESOURCE))
 		else if(!Left && (mode == EMarketMode::ARTIFACT_RESOURCE))
 		{
 		{
 			rightTradePanel = std::make_shared<ResourcesPanel>(std::bind(clickPressedTradePanel, _1, false),
 			rightTradePanel = std::make_shared<ResourcesPanel>(std::bind(clickPressedTradePanel, _1, false),
@@ -216,8 +201,6 @@ ImagePath CMarketplaceWindow::getBackgroundForMode(EMarketMode mode)
 {
 {
 	switch(mode)
 	switch(mode)
 	{
 	{
-	case EMarketMode::RESOURCE_RESOURCE:
-		return ImagePath::builtin("TPMRKRES.bmp");
 	case EMarketMode::RESOURCE_PLAYER:
 	case EMarketMode::RESOURCE_PLAYER:
 		return ImagePath::builtin("TPMRKPTS.bmp");
 		return ImagePath::builtin("TPMRKPTS.bmp");
 	case EMarketMode::RESOURCE_ARTIFACT:
 	case EMarketMode::RESOURCE_ARTIFACT: