Forráskód Böngészése

Artifacts selling widget

SoundSSGood 1 éve
szülő
commit
f3fa6714dc

+ 2 - 0
client/CMakeLists.txt

@@ -126,6 +126,7 @@ set(client_SRCS
 	widgets/markets/CAltarArtifacts.cpp
 	widgets/markets/CAltarCreatures.cpp
 	widgets/markets/CArtifactsBuying.cpp
+	widgets/markets/CArtifactsSelling.cpp
 	widgets/markets/CFreelancerGuild.cpp
 	widgets/markets/CMarketResources.cpp
 	widgets/markets/CTransferResources.cpp
@@ -315,6 +316,7 @@ set(client_HEADERS
 	widgets/markets/CAltarArtifacts.h
 	widgets/markets/CAltarCreatures.h
 	widgets/markets/CArtifactsBuying.h
+	widgets/markets/CArtifactsSelling.h
 	widgets/markets/CFreelancerGuild.h
 	widgets/markets/CMarketResources.h
 	widgets/markets/CTransferResources.h

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

@@ -50,6 +50,7 @@ CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance *
 		CGI->generaltexth->zelp[570], std::bind(&CAltarArtifacts::sacrificeBackpack, this));
 	sacrificeBackpackButton->block(hero->artifactsInBackpack.empty());
 
+	// Hero's artifacts
 	heroArts = std::make_shared<CArtifactsOfHeroAltar>(Point(-365, -11));
 	heroArts->setHero(hero);
 

+ 27 - 27
client/widgets/markets/CAltarCreatures.cpp

@@ -45,27 +45,27 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
 		Point(393, 520), AnimationPath::builtin("ALTARMY.DEF"), CGI->generaltexth->zelp[579], std::bind(&CExperienceAltar::sacrificeAll, this));
 
 	// Hero creatures panel
-	assert(leftTradePanel);
-	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)
+	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));
+	for(const auto & slot : bidTradePanel->slots)
 		slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot) {CAltarCreatures::onSlotClickPressed(heroSlot, hLeft);};
 
 	// Altar creatures panel
-	rightTradePanel = std::make_shared<CreaturesPanel>([this](const std::shared_ptr<CTradeableItem> & altarSlot)
+	offerTradePanel = std::make_shared<CreaturesPanel>([this](const std::shared_ptr<CTradeableItem> & altarSlot)
 		{
 			CAltarCreatures::onSlotClickPressed(altarSlot, hRight);
-		}, leftTradePanel->slots);
-	rightTradePanel->moveTo(pos.topLeft() + Point(334, 110));
-	rightTradePanel->selectedImage->moveTo(pos.topLeft() + Point(395, 422));
-	rightTradePanel->selectedSubtitle->moveTo(pos.topLeft() + Point(426, 503));
-	rightTradePanel->updateSlotsCallback = [this]()
+		}, 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->updateSlotsCallback = [this]()
 	{
-		for(const auto & altarSlot : rightTradePanel->slots)
+		for(const auto & altarSlot : offerTradePanel->slots)
 			updateAltarSlot(altarSlot);
 	};
-	leftTradePanel->deleteSlotsCheck = rightTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1);
+	bidTradePanel->deleteSlotsCheck = offerTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1);
 	
 	readExpValues();
 	CAltarCreatures::deselect();
@@ -74,7 +74,7 @@ CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance *
 void CAltarCreatures::readExpValues()
 {
 	int bidQty = 0;
-	for(const auto & heroSlot : leftTradePanel->slots)
+	for(const auto & heroSlot : bidTradePanel->slots)
 	{
 		if(heroSlot->id >= 0)
 			market->getOffer(heroSlot->id, 0, bidQty, expPerUnit[heroSlot->serial], EMarketMode::CREATURE_EXP);
@@ -120,32 +120,32 @@ void CAltarCreatures::updateSelected()
 
 	if(hLeft)
 	{
-		leftTradePanel->selectedSubtitle->setText(std::to_string(offerSlider->getValue()));
+		bidTradePanel->selectedSubtitle->setText(std::to_string(offerSlider->getValue()));
 		lImageIndex = CGI->creatures()->getByIndex(hLeft->id)->getIconIndex();
 	}
 	else
 	{
-		leftTradePanel->selectedSubtitle->setText("");
+		bidTradePanel->selectedSubtitle->setText("");
 	}
 	if(hRight)
 	{
-		rightTradePanel->selectedSubtitle->setText(hRight->subtitle);
+		offerTradePanel->selectedSubtitle->setText(hRight->subtitle);
 		if(offerSlider->getValue() != 0)
 			rImageIndex = CGI->creatures()->getByIndex(hRight->id)->getIconIndex();
 	}
 	else
 	{
-		rightTradePanel->selectedSubtitle->setText("");
+		offerTradePanel->selectedSubtitle->setText("");
 	}
-	leftTradePanel->setSelectedFrameIndex(lImageIndex);
-	rightTradePanel->setSelectedFrameIndex(rImageIndex);
+	bidTradePanel->setSelectedFrameIndex(lImageIndex);
+	offerTradePanel->setSelectedFrameIndex(rImageIndex);
 }
 
 void CAltarCreatures::updateSlots()
 {
-	rightTradePanel->updateSlots();
+	offerTradePanel->updateSlots();
 	CCreaturesSelling::updateSlots();
-	assert(leftTradePanel->slots.size() == rightTradePanel->slots.size());
+	assert(bidTradePanel->slots.size() == offerTradePanel->slots.size());
 }
 
 void CAltarCreatures::deselect()
@@ -187,7 +187,7 @@ void CAltarCreatures::makeDeal()
 	for(int & units : unitsOnAltar)
 		units = 0;
 
-	for(auto heroSlot : rightTradePanel->slots)
+	for(auto heroSlot : offerTradePanel->slots)
 	{
 		heroSlot->setType(EType::CREATURE_PLACEHOLDER);
 		heroSlot->subtitle.clear();
@@ -197,7 +197,7 @@ void CAltarCreatures::makeDeal()
 void CAltarCreatures::sacrificeAll()
 {
 	std::optional<SlotID> lastSlot;
-	for(auto heroSlot : leftTradePanel->slots)
+	for(auto heroSlot : bidTradePanel->slots)
 	{
 		auto stackCount = hero->getStackCount(SlotID(heroSlot->serial));
 		if(stackCount > unitsOnAltar[heroSlot->serial])
@@ -215,7 +215,7 @@ void CAltarCreatures::sacrificeAll()
 
 	if(hRight)
 		offerSlider->scrollTo(unitsOnAltar[hRight->serial]);
-	rightTradePanel->updateSlots();
+	offerTradePanel->updateSlots();
 	updateSelected();
 
 	deal->block(calcExpAltarForHero() == 0);
@@ -247,12 +247,12 @@ void CAltarCreatures::onSlotClickPressed(const std::shared_ptr<CTradeableItem> &
 		return;
 
 	auto * oppositeSlot = &hLeft;
-	auto oppositePanel = leftTradePanel;
+	auto oppositePanel = bidTradePanel;
 	CTradeBase::onSlotClickPressed(newSlot, hCurSlot);
 	if(hCurSlot == hLeft)
 	{
 		oppositeSlot = &hRight;
-		oppositePanel = rightTradePanel;
+		oppositePanel = offerTradePanel;
 	}
 	std::shared_ptr<CTradeableItem> oppositeNewSlot;
 	for(const auto & slot : oppositePanel->slots)

+ 16 - 15
client/widgets/markets/CArtifactsBuying.cpp

@@ -39,19 +39,19 @@ CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance
 	labels.emplace_back(std::make_shared<CLabel>(445, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[168]));
 
 	// Player's resources
-	assert(leftTradePanel);
-	std::for_each(leftTradePanel->slots.cbegin(), leftTradePanel->slots.cend(), [this](auto & slot)
+	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);
 			};
 		});
-	leftTradePanel->moveTo(pos.topLeft() + Point(39, 182));
-	leftTradePanel->selectedImage->moveTo(pos.topLeft() + Point(141, 453));
+	bidTradePanel->moveTo(pos.topLeft() + Point(39, 182));
+	bidTradePanel->selectedImage->moveTo(pos.topLeft() + Point(141, 453));
 
 	// Artifacts panel
-	rightTradePanel = std::make_shared<ArtifactsPanel>([this](const std::shared_ptr<CTradeableItem> & newSlot)
+	offerTradePanel = std::make_shared<ArtifactsPanel>([this](const std::shared_ptr<CTradeableItem> & newSlot)
 		{
 			CArtifactsBuying::onSlotClickPressed(newSlot, hRight);
 		
@@ -59,21 +59,21 @@ CArtifactsBuying::CArtifactsBuying(const IMarket * market, const CGHeroInstance
 		{
 			// TODO move to parent
 			if(hLeft)
-				for(const auto & slot : rightTradePanel->slots)
+				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);
 
-					rightTradePanel->updateOffer(*slot, h1, h2);
+					offerTradePanel->updateOffer(*slot, h1, h2);
 				}
 			else
-				rightTradePanel->clearSubtitles();
+				offerTradePanel->clearSubtitles();
 		}, market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT));
-	rightTradePanel->deleteSlotsCheck = [this](const std::shared_ptr<CTradeableItem> & slot)
+	offerTradePanel->deleteSlotsCheck = [this](const std::shared_ptr<CTradeableItem> & slot)
 	{
 		return vstd::contains(this->market->availableItemsIds(EMarketMode::RESOURCE_ARTIFACT), ArtifactID(slot->id)) ? false : true;
 	};
-	rightTradePanel->moveTo(pos.topLeft() + Point(328, 182));
+	offerTradePanel->moveTo(pos.topLeft() + Point(328, 182));
 
 	CArtifactsBuying::updateSlots();
 	CMarketMisc::deselect();
@@ -88,16 +88,17 @@ void CArtifactsBuying::makeDeal()
 void CArtifactsBuying::updateSlots()
 {
 	CResourcesSelling::updateSlots();
-	rightTradePanel->updateSlots();
+	offerTradePanel->updateSlots();
 }
 
 CMarketMisc::SelectionParams CArtifactsBuying::getSelectionParams()
 {
 	if(hLeft && hRight)
-		return std::make_tuple(std::to_string(deal->isBlocked() ? 0 : bidQty),
-			std::to_string(deal->isBlocked() ? 0 : offerQty), hLeft->id, CGI->artifacts()->getByIndex(hRight->id)->getIconIndex());
+		return std::make_tuple(
+			SelectionParamOneSide {std::to_string(deal->isBlocked() ? 0 : bidQty), hLeft->id},
+			SelectionParamOneSide {std::to_string(deal->isBlocked() ? 0 : offerQty), CGI->artifacts()->getByIndex(hRight->id)->getIconIndex()});
 	else
-		return std::nullopt;
+		return std::make_tuple(std::nullopt, std::nullopt);
 }
 
 void CArtifactsBuying::onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot)
@@ -114,7 +115,7 @@ void CArtifactsBuying::onSlotClickPressed(const std::shared_ptr<CTradeableItem>
 			deal->block(LOCPLINT->cb->getResourceAmount(GameResID(hLeft->id)) >= bidQty ? false : true);
 		}
 		updateSelected();
-		rightTradePanel->updateSlots();
+		offerTradePanel->updateSlots();
 	}
 	redraw();
 }

+ 149 - 0
client/widgets/markets/CArtifactsSelling.cpp

@@ -0,0 +1,149 @@
+/*
+ * CArtifactsSelling.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 "CArtifactsSelling.h"
+
+#include "../../gui/CGuiHandler.h"
+#include "../../widgets/Buttons.h"
+#include "../../widgets/Slider.h"
+#include "../../widgets/TextControls.h"
+
+#include "../../CGameInfo.h"
+
+#include "../../../lib/CArtifactInstance.h"
+#include "../../../lib/CGeneralTextHandler.h"
+#include "../../../lib/mapObjects/CGMarket.h"
+
+CArtifactsSelling::CArtifactsSelling(const IMarket * market, const CGHeroInstance * hero)
+	: CTradeBase(market, hero)
+	, CResourcesBuying([this](){CArtifactsSelling::updateSubtitles();})
+	, 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);
+
+	// Hero's artifacts
+	heroArts = std::make_shared<CArtifactsOfHeroMarket>(Point(-361, 46));
+	heroArts->setHero(hero);
+	heroArts->selectArtCallback = [this](CArtPlace * artPlace)
+	{
+		assert(artPlace);
+		artForTrade = artPlace->getArt();
+		assert(artForTrade.has_value());
+		if(hRight)
+		{
+			this->market->getOffer(artForTrade.value()->getTypeId().num, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE);
+			deal->block(false);
+		}
+		CArtifactsSelling::updateSelected();
+		offerTradePanel->updateSlots();
+		redraw();
+	};
+
+	// 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));
+	
+
+	CArtifactsSelling::updateSelected();
+	CArtifactsSelling::deselect();
+}
+
+void CArtifactsSelling::makeDeal()
+{
+
+}
+
+void CArtifactsSelling::deselect()
+{
+	CTradeBase::deselect();
+	artForTrade = std::nullopt;
+}
+
+void CArtifactsSelling::updateSelected()
+{
+	CMarketMisc::updateSelected();
+
+	if(artForTrade.has_value() && hRight)
+	{
+		bidSelectedSubtitle->setText(std::to_string(bidQty));
+		selectedImage->enable();
+		selectedImage->setFrame(CGI->artifacts()->getByIndex(artForTrade.value()->getTypeId())->getIconIndex());
+	}
+	else
+	{
+		selectedImage->disable();
+		selectedImage->setFrame(0);
+		bidSelectedSubtitle->setText("");
+	}
+}
+
+std::shared_ptr<CArtifactsOfHeroMarket> CArtifactsSelling::getAOHset() const
+{
+	return heroArts;
+}
+
+CMarketMisc::SelectionParams CArtifactsSelling::getSelectionParams()
+{
+	if(artForTrade.has_value() && hRight)
+		return std::make_tuple(
+			std::nullopt,
+			SelectionParamOneSide {std::to_string(offerQty), GameResID(hRight->id)}
+		);
+	else
+		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);
+	if(newSlot == hCurSlot)
+		return;
+
+	CTradeBase::onSlotClickPressed(newSlot, hCurSlot);
+	if(artForTrade.has_value())
+	{
+		if(hRight)
+		{
+			market->getOffer(artForTrade.value()->getTypeId().num, hRight->id, bidQty, offerQty, EMarketMode::ARTIFACT_RESOURCE);
+			deal->block(false);
+		}
+		updateSelected();
+	}
+	redraw();
+}

+ 34 - 0
client/widgets/markets/CArtifactsSelling.h

@@ -0,0 +1,34 @@
+/*
+ * CArtifactsSelling.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 "../CArtifactsOfHeroMarket.h"
+#include "CTradeBase.h"
+
+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;
+
+	void updateSubtitles();
+	CMarketMisc::SelectionParams getSelectionParams();
+	void onSlotClickPressed(const std::shared_ptr<CTradeableItem> & newSlot, std::shared_ptr<CTradeableItem> & hCurSlot) override;
+};

+ 11 - 10
client/widgets/markets/CFreelancerGuild.cpp

@@ -47,10 +47,10 @@ CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance
 		}, 0, 0, 0, Orientation::HORIZONTAL);
 
 	// Hero creatures panel
-	assert(leftTradePanel);
-	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)
+	assert(bidTradePanel);
+	bidTradePanel->moveTo(pos.topLeft() + Point(45, 123));
+	bidTradePanel->deleteSlotsCheck = std::bind(&CCreaturesSelling::slotDeletingCheck, this, _1);
+	std::for_each(bidTradePanel->slots.cbegin(), bidTradePanel->slots.cend(), [this](auto & slot)
 		{
 			slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot)
 			{
@@ -59,8 +59,8 @@ CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance
 		});
 
 	// Guild resources panel
-	assert(rightTradePanel);
-	std::for_each(rightTradePanel->slots.cbegin(), rightTradePanel->slots.cend(), [this](auto & slot)
+	assert(offerTradePanel);
+	std::for_each(offerTradePanel->slots.cbegin(), offerTradePanel->slots.cend(), [this](auto & slot)
 		{
 			slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & heroSlot)
 			{
@@ -83,10 +83,11 @@ void CFreelancerGuild::makeDeal()
 CMarketMisc::SelectionParams CFreelancerGuild::getSelectionParams()
 {
 	if(hLeft && hRight)
-		return std::make_tuple(std::to_string(bidQty * offerSlider->getValue()), std::to_string(offerQty * offerSlider->getValue()),
-			CGI->creatures()->getByIndex(hLeft->id)->getIconIndex(), hRight->id);
+		return std::make_tuple(
+			SelectionParamOneSide {std::to_string(bidQty * offerSlider->getValue()), CGI->creatures()->getByIndex(hLeft->id)->getIconIndex()},
+			SelectionParamOneSide {std::to_string(offerQty * offerSlider->getValue()), hRight->id});
 	else
-		return std::nullopt;
+		return std::make_tuple(std::nullopt, std::nullopt);
 }
 
 void CFreelancerGuild::onOfferSliderMoved(int newVal)
@@ -117,7 +118,7 @@ void CFreelancerGuild::onSlotClickPressed(const std::shared_ptr<CTradeableItem>
 			deal->block(false);
 		}
 		updateSelected();
-		rightTradePanel->updateSlots();
+		offerTradePanel->updateSlots();
 	}
 	redraw();
 }

+ 11 - 10
client/widgets/markets/CMarketResources.cpp

@@ -42,19 +42,19 @@ CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance
 		}, 0, 0, 0, Orientation::HORIZONTAL);
 
 	// Player's resources
-	assert(leftTradePanel);
-	std::for_each(leftTradePanel->slots.cbegin(), leftTradePanel->slots.cend(), [this](auto & slot)
+	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);
 			};
 		});
-	leftTradePanel->moveTo(pos.topLeft() + Point(39, 181));
+	bidTradePanel->moveTo(pos.topLeft() + Point(39, 181));
 
 	// Market resources panel
-	assert(rightTradePanel);
-	std::for_each(rightTradePanel->slots.cbegin(), rightTradePanel->slots.cend(), [this](auto & slot)
+	assert(offerTradePanel);
+	std::for_each(offerTradePanel->slots.cbegin(), offerTradePanel->slots.cend(), [this](auto & slot)
 		{
 			slot->clickPressedCallback = [this](const std::shared_ptr<CTradeableItem> & resSlot)
 			{
@@ -78,10 +78,11 @@ void CMarketResources::makeDeal()
 CMarketMisc::SelectionParams CMarketResources::getSelectionParams()
 {
 	if(hLeft && hRight && hLeft->id != hRight->id)
-		return std::make_tuple(std::to_string(bidQty * offerSlider->getValue()),
-			std::to_string(offerQty * offerSlider->getValue()), hLeft->id, hRight->id);
+		return std::make_tuple(
+			SelectionParamOneSide {std::to_string(bidQty * offerSlider->getValue()), hLeft->id},
+			SelectionParamOneSide {std::to_string(offerQty * offerSlider->getValue()), hRight->id});
 	else
-		return std::nullopt;
+		return std::make_tuple(std::nullopt, std::nullopt);
 }
 
 void CMarketResources::onOfferSliderMoved(int newVal)
@@ -113,7 +114,7 @@ void CMarketResources::onSlotClickPressed(const std::shared_ptr<CTradeableItem>
 			deal->block(isControlsBlocked);
 		}
 		updateSelected();
-		rightTradePanel->updateSlots();
+		offerTradePanel->updateSlots();
 	}
 	redraw();
 }
@@ -122,5 +123,5 @@ void CMarketResources::updateSubtitles()
 {
 	CResourcesBuying::updateSubtitles(EMarketMode::RESOURCE_RESOURCE);
 	if(hLeft)
-		rightTradePanel->slots[hLeft->serial]->subtitle = CGI->generaltexth->allTexts[164]; // n/a
+		offerTradePanel->slots[hLeft->serial]->subtitle = CGI->generaltexth->allTexts[164]; // n/a
 }

+ 33 - 30
client/widgets/markets/CTradeBase.cpp

@@ -40,7 +40,7 @@ void CTradeBase::removeItems(const std::set<std::shared_ptr<CTradeableItem>> & t
 
 void CTradeBase::removeItem(std::shared_ptr<CTradeableItem> item)
 {
-	rightTradePanel->slots.erase(std::remove(rightTradePanel->slots.begin(), rightTradePanel->slots.end(), item));
+	offerTradePanel->slots.erase(std::remove(offerTradePanel->slots.begin(), offerTradePanel->slots.end(), item));
 
 	if(hRight == item)
 		hRight.reset();
@@ -48,7 +48,7 @@ void CTradeBase::removeItem(std::shared_ptr<CTradeableItem> item)
 
 void CTradeBase::getEmptySlots(std::set<std::shared_ptr<CTradeableItem>> & toRemove)
 {
-	for(auto item : leftTradePanel->slots)
+	for(auto item : bidTradePanel->slots)
 		if(!hero->getStackCount(SlotID(item->serial)))
 			toRemove.insert(item);
 }
@@ -104,8 +104,8 @@ CCreaturesSelling::CCreaturesSelling()
 		if(const auto & creature = hero->getCreature(slotId))
 			slots.emplace_back(std::make_tuple(creature->getId(), slotId, hero->getStackCount(slotId)));
 	}
-	leftTradePanel = std::make_shared<CreaturesPanel>(nullptr, slots);
-	leftTradePanel->updateSlotsCallback = std::bind(&CCreaturesSelling::updateSubtitle, this);
+	bidTradePanel = std::make_shared<CreaturesPanel>(nullptr, slots);
+	bidTradePanel->updateSlotsCallback = std::bind(&CCreaturesSelling::updateSubtitle, this);
 }
 
 bool CCreaturesSelling::slotDeletingCheck(const std::shared_ptr<CTradeableItem> & slot)
@@ -115,45 +115,45 @@ bool CCreaturesSelling::slotDeletingCheck(const std::shared_ptr<CTradeableItem>
 
 void CCreaturesSelling::updateSubtitle()
 {
-	for(auto & heroSlot : leftTradePanel->slots)
+	for(auto & heroSlot : bidTradePanel->slots)
 		heroSlot->subtitle = std::to_string(this->hero->getStackCount(SlotID(heroSlot->serial)));
 }
 
 void CCreaturesSelling::updateSlots()
 {
-	leftTradePanel->updateSlots();
+	bidTradePanel->updateSlots();
 }
 
 CResourcesBuying::CResourcesBuying(TradePanelBase::UpdateSlotsFunctor callback)
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
 
-	rightTradePanel = std::make_shared<ResourcesPanel>([](const std::shared_ptr<CTradeableItem>&) {}, callback);
-	rightTradePanel->moveTo(pos.topLeft() + Point(327, 181));
+	offerTradePanel = std::make_shared<ResourcesPanel>([](const std::shared_ptr<CTradeableItem>&) {}, callback);
+	offerTradePanel->moveTo(pos.topLeft() + Point(327, 181));
 	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 : rightTradePanel->slots)
+		for(const auto & slot : offerTradePanel->slots)
 		{
 			int h1, h2; //hlp variables for getting offer
 			market->getOffer(hLeft->id, slot->id, h1, h2, marketMode);
 
-			rightTradePanel->updateOffer(*slot, h1, h2);
+			offerTradePanel->updateOffer(*slot, h1, h2);
 		}
 	else
-		rightTradePanel->clearSubtitles();
+		offerTradePanel->clearSubtitles();
 };
 
 CResourcesSelling::CResourcesSelling()
 {
 	OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE);
 
-	leftTradePanel = std::make_shared<ResourcesPanel>([](const std::shared_ptr<CTradeableItem>&) {}, [this]()
+	bidTradePanel = std::make_shared<ResourcesPanel>([](const std::shared_ptr<CTradeableItem>&) {}, [this]()
 		{
-			for(const auto & slot : leftTradePanel->slots)
+			for(const auto & slot : bidTradePanel->slots)
 				slot->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(slot->serial)));
 		});
 	labels.emplace_back(std::make_shared<CLabel>(156, 148, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->allTexts[270]));
@@ -161,7 +161,7 @@ CResourcesSelling::CResourcesSelling()
 
 void CResourcesSelling::updateSlots()
 {
-	leftTradePanel->updateSlots();
+	bidTradePanel->updateSlots();
 }
 
 CMarketMisc::CMarketMisc(SelectionParamsFunctor callback)
@@ -179,22 +179,25 @@ void CMarketMisc::deselect()
 
 void CMarketMisc::updateSelected()
 {
-	std::optional<size_t> lImageIndex = std::nullopt;
-	std::optional<size_t> rImageIndex = std::nullopt;
+	const auto updateSelectedBody = [](std::shared_ptr<TradePanelBase> & tradePanel, const std::optional<const SelectionParamOneSide> & params)
+	{
+		std::optional<size_t> lImageIndex = std::nullopt;
+		if(params.has_value())
+		{
+			tradePanel->selectedSubtitle->setText(params.value().text);
+			lImageIndex = params.value().imageIndex;
+		}
+		else
+		{
+			tradePanel->selectedSubtitle->setText("");
+		}
+		tradePanel->setSelectedFrameIndex(lImageIndex);
+	};
 
 	assert(selectionParamsCallback);
-	if(auto params = selectionParamsCallback())
-	{
-		leftTradePanel->selectedSubtitle->setText(std::get<0>(params.value()));
-		rightTradePanel->selectedSubtitle->setText(std::get<1>(params.value()));
-		lImageIndex = std::get<2>(params.value());
-		rImageIndex = std::get<3>(params.value());
-	}
-	else
-	{
-		leftTradePanel->selectedSubtitle->setText("");
-		rightTradePanel->selectedSubtitle->setText("");
-	}
-	leftTradePanel->setSelectedFrameIndex(lImageIndex);
-	rightTradePanel->setSelectedFrameIndex(rImageIndex);
+	const auto params = selectionParamsCallback();
+	if(bidTradePanel)
+		updateSelectedBody(bidTradePanel, std::get<0>(params));
+	if(offerTradePanel)
+		updateSelectedBody(offerTradePanel, std::get<1>(params));
 }

+ 8 - 3
client/widgets/markets/CTradeBase.h

@@ -29,8 +29,8 @@ public:
 
 	//all indexes: 1 = left, 0 = right
 	std::array<std::vector<std::shared_ptr<CTradeableItem>>, 2> items;
-	std::shared_ptr<TradePanelBase> leftTradePanel;
-	std::shared_ptr<TradePanelBase> rightTradePanel;
+	std::shared_ptr<TradePanelBase> bidTradePanel;
+	std::shared_ptr<TradePanelBase> offerTradePanel;
 
 	//highlighted items (nullptr if no highlight)
 	std::shared_ptr<CTradeableItem> hLeft;
@@ -92,7 +92,12 @@ public:
 class CMarketMisc : virtual public CTradeBase, virtual public CIntObject
 {
 public:
-	using SelectionParams = std::optional<std::tuple<std::string, std::string, int, int>>;
+	struct SelectionParamOneSide
+	{ 
+		std::string text; 
+		int imageIndex; 
+	};
+	using SelectionParams = std::tuple<std::optional<const SelectionParamOneSide>, std::optional<const SelectionParamOneSide>>;
 	using SelectionParamsFunctor = std::function<SelectionParams()>;
 
 	CMarketMisc(SelectionParamsFunctor callback);

+ 10 - 9
client/widgets/markets/CTransferResources.cpp

@@ -41,22 +41,22 @@ CTransferResources::CTransferResources(const IMarket * market, const CGHeroInsta
 		}, 0, 0, 0, Orientation::HORIZONTAL);
 
 	// Player's resources
-	assert(leftTradePanel);
-	std::for_each(leftTradePanel->slots.cbegin(), leftTradePanel->slots.cend(), [this](auto & slot)
+	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);
 			};
 		});
-	leftTradePanel->moveTo(pos.topLeft() + Point(40, 182));
+	bidTradePanel->moveTo(pos.topLeft() + Point(40, 182));
 
 	// Players panel
-	rightTradePanel = std::make_shared<PlayersPanel>([this](const std::shared_ptr<CTradeableItem> & heroSlot)
+	offerTradePanel = std::make_shared<PlayersPanel>([this](const std::shared_ptr<CTradeableItem> & heroSlot)
 		{
 			CTransferResources::onSlotClickPressed(heroSlot, hRight);
 		});
-	rightTradePanel->moveTo(pos.topLeft() + Point(333, 83));
+	offerTradePanel->moveTo(pos.topLeft() + Point(333, 83));
 
 	CResourcesSelling::updateSlots();
 	CTransferResources::deselect();
@@ -74,10 +74,11 @@ void CTransferResources::makeDeal()
 CMarketMisc::SelectionParams CTransferResources::getSelectionParams()
 {
 	if(hLeft && hRight)
-		return std::make_tuple(std::to_string(offerSlider->getValue()),
-			CGI->generaltexth->capColors[hRight->id], hLeft->id, hRight->id);
+		return std::make_tuple(
+			SelectionParamOneSide {std::to_string(offerSlider->getValue()), hLeft->id},
+			SelectionParamOneSide {CGI->generaltexth->capColors[hRight->id], hRight->id});
 	else
-		return std::nullopt;
+		return std::make_tuple(std::nullopt, std::nullopt);
 }
 
 void CTransferResources::onOfferSliderMoved(int newVal)
@@ -107,7 +108,7 @@ void CTransferResources::onSlotClickPressed(const std::shared_ptr<CTradeableItem
 			deal->block(false);
 		}
 		updateSelected();
-		rightTradePanel->updateSlots();
+		offerTradePanel->updateSlots();
 	}
 	redraw();
 }

+ 17 - 4
client/windows/CMarketWindow.cpp

@@ -17,6 +17,7 @@
 #include "../widgets/Buttons.h"
 #include "../widgets/TextControls.h"
 #include "../widgets/markets/CArtifactsBuying.h"
+#include "../widgets/markets/CArtifactsSelling.h"
 #include "../widgets/markets/CFreelancerGuild.h"
 #include "../widgets/markets/CMarketResources.h"
 #include "../widgets/markets/CTransferResources.h"
@@ -185,10 +186,22 @@ void CMarketWindow::createArtifactsBuying(const IMarket * market, const CGHeroIn
 void CMarketWindow::createArtifactsSelling(const IMarket * market, const CGHeroInstance * hero)
 {
 	OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255 - DISPOSE);
-
+	artsBuy.reset();
 	background = createBg(ImagePath::builtin("TPMRKASS.bmp"), PLAYER_COLORED);
-	this->market = std::make_shared<CMarketplaceWindow>(market, hero, []() {}, EMarketMode::ARTIFACT_RESOURCE);
-	createInternals(EMarketMode::ARTIFACT_RESOURCE, market, hero);
+
+	artsSel = std::make_shared<CArtifactsSelling>(market, hero);
+	artSets.clear();
+	addSetAndCallbacks(artsSel->getAOHset());
+
+	background->center();
+	pos = background->pos;
+	artsSel->setRedrawParent(true);
+	artsSel->moveTo(pos.topLeft());
+
+	createChangeModeButtons(EMarketMode::ARTIFACT_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::createMarketResources(const IMarket * market, const CGHeroInstance * hero)
@@ -253,7 +266,7 @@ void CMarketWindow::createAltarArtifacts(const IMarket * market, const CGHeroIns
 	auto altarArtifacts = std::make_shared<CAltarArtifacts>(market, hero);
 	altar = altarArtifacts;
 	artSets.clear();
-	addSetAndCallbacks(altarArtifacts->getAOHset()); altarArtifacts->putBackArtifacts();
+	addSetAndCallbacks(altarArtifacts->getAOHset());
 
 	background->center();
 	pos = background->pos;

+ 2 - 0
client/windows/CMarketWindow.h

@@ -13,6 +13,7 @@
 #include "CAltarWindow.h"
 
 class CArtifactsBuying;
+class CArtifactsSelling;
 class CFreelancerGuild;
 class CMarketResources;
 class CTransferResources;
@@ -51,4 +52,5 @@ private:
 	std::shared_ptr<CMarketResources> resRes;
 	std::shared_ptr<CTransferResources> trRes;
 	std::shared_ptr<CArtifactsBuying> artsBuy;
+	std::shared_ptr<CArtifactsSelling> artsSel;
 };

+ 19 - 19
client/windows/CTradeWindow.cpp

@@ -87,15 +87,15 @@ void CTradeWindow::initItems(bool Left)
 		auto updRightSub = [this](EMarketMode marketMode)
 		{
 			if(hLeft)
-				for(const auto & slot : rightTradePanel->slots)
+				for(const auto & slot : offerTradePanel->slots)
 				{
 					int h1, h2; //hlp variables for getting offer
 					market->getOffer(hLeft->id, slot->id, h1, h2, marketMode);
 
-					rightTradePanel->updateOffer(*slot, h1, h2);
+					offerTradePanel->updateOffer(*slot, h1, h2);
 				}
 			else
-				rightTradePanel->clearSubtitles();
+				offerTradePanel->clearSubtitles();
 		};
 
 		auto clickPressedTradePanel = [this](const std::shared_ptr<CTradeableItem> & newSlot, bool left)
@@ -105,31 +105,31 @@ void CTradeWindow::initItems(bool Left)
 		};
 		if(Left && (mode == EMarketMode::RESOURCE_ARTIFACT || mode == EMarketMode::RESOURCE_PLAYER))
 		{
-			leftTradePanel = std::make_shared<ResourcesPanel>(
+			bidTradePanel = std::make_shared<ResourcesPanel>(
 				[clickPressedTradePanel](const std::shared_ptr<CTradeableItem> & newSlot)
 				{
 					clickPressedTradePanel(newSlot, true);
 				},
 				[this]()
 				{
-					for(const auto & slot : leftTradePanel->slots)
+					for(const auto & slot : bidTradePanel->slots)
 						slot->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast<EGameResID>(slot->serial)));
 				});
-			leftTradePanel->moveBy(Point(39, 182));
-			leftTradePanel->updateSlots();
+			bidTradePanel->moveBy(Point(39, 182));
+			bidTradePanel->updateSlots();
 		}
 		else if(!Left && (mode == EMarketMode::ARTIFACT_RESOURCE))
 		{
-			rightTradePanel = std::make_shared<ResourcesPanel>(std::bind(clickPressedTradePanel, _1, false),
+			offerTradePanel = std::make_shared<ResourcesPanel>(std::bind(clickPressedTradePanel, _1, false),
 				std::bind(updRightSub, EMarketMode::ARTIFACT_RESOURCE));
-			rightTradePanel->moveBy(Point(327, 181));
+			offerTradePanel->moveBy(Point(327, 181));
 		}
 		else if(!Left && mode == EMarketMode::RESOURCE_ARTIFACT)
 		{
-			rightTradePanel = std::make_shared<ArtifactsPanel>(std::bind(clickPressedTradePanel, _1, false),
+			offerTradePanel = std::make_shared<ArtifactsPanel>(std::bind(clickPressedTradePanel, _1, false),
 				std::bind(updRightSub, EMarketMode::RESOURCE_ARTIFACT), market->availableItemsIds(mode));
-			rightTradePanel->moveBy(Point(327, 181));
-			rightTradePanel->deleteSlotsCheck = [this](const std::shared_ptr<CTradeableItem> & slot)
+			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;
 			};
@@ -142,9 +142,9 @@ void CTradeWindow::initSubs(bool Left)
 	if (itemsType[Left] == EType::RESOURCE || itemsType[Left] == EType::ARTIFACT_TYPE)
 	{ 
 		if(Left)
-			leftTradePanel->updateSlots();
+			bidTradePanel->updateSlots();
 		else
-			rightTradePanel->updateSlots();
+			offerTradePanel->updateSlots();
 		return;
 	}
 }
@@ -247,7 +247,7 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInsta
 	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 = std::make_shared<CArtifactsOfHeroMarket>(Point(-361, 46));
 		arts->selectArtCallback = std::bind(&CTradeWindow::artifactSelected, this, _1);
 		arts->setHero(hero);
 		addSetAndCallbacks(arts);
@@ -377,10 +377,10 @@ void CMarketplaceWindow::makeDeal()
 	madeTransaction = true;
 	hLeft = nullptr;
 	hRight = nullptr;
-	if(leftTradePanel)
-		leftTradePanel->deselect();
-	assert(rightTradePanel);
-	rightTradePanel->deselect();
+	if(bidTradePanel)
+		bidTradePanel->deselect();
+	assert(offerTradePanel);
+	offerTradePanel->deselect();
 	selectionChanged(true);
 }