浏览代码

fixed init CArtifactsOfHero

SoundSSGood 2 年之前
父节点
当前提交
a8220c551f

+ 5 - 8
client/widgets/CGarrisonInt.cpp

@@ -185,20 +185,17 @@ bool CGarrisonSlot::highlightOrDropArtifact()
 	bool artSelected = false;
 	if (CWindowWithArtifacts* chw = dynamic_cast<CWindowWithArtifacts*>(GH.topInt().get())) //dirty solution
 	{
-		std::shared_ptr<CArtifactsOfHero::SCommonPart> commonInfo = chw->getCommonPart();
-		const CArtifactInstance * art = nullptr;
-		if(commonInfo)
-			art = commonInfo->src.art;
+		const auto pickedArtInst = chw->getPickedArtifact();
 
-		if(art)
+		if(pickedArtInst)
 		{
-			const CGHeroInstance *srcHero = commonInfo->src.AOH->getHero();
+			const auto * srcHero = chw->getHeroPickedArtifact();
 			artSelected = true;
 			if (myStack) // try dropping the artifact only if the slot isn't empty
 			{
-				ArtifactLocation src(srcHero, commonInfo->src.slotID);
+				ArtifactLocation src(srcHero, ArtifactPosition::TRANSITION_POS);
 				ArtifactLocation dst(myStack, ArtifactPosition::CREATURE_SLOT);
-				if (art->canBePutAt(dst, true))
+				if(pickedArtInst->canBePutAt(dst, true))
 				{	//equip clicked stack
 					if(dst.getArt())
 					{

+ 13 - 14
client/windows/CHeroWindow.cpp

@@ -42,9 +42,10 @@ TConstBonusListPtr CHeroWithMaybePickedArtifact::getAllBonuses(const CSelector &
 	TConstBonusListPtr heroBonuses = hero->getAllBonuses(selector, limit, hero, cachingStr);
 	TConstBonusListPtr bonusesFromPickedUpArtifact;
 
-	std::shared_ptr<CArtifactsOfHero::SCommonPart> cp = cww->getCommonPart();
-	if(cp && cp->src.art && cp->src.valid() && cp->src.AOH && cp->src.AOH->getHero() == hero)
-		bonusesFromPickedUpArtifact = cp->src.art->getAllBonuses(selector, limit, hero);
+	const auto pickedArtInst = cww->getPickedArtifact();
+
+	if(pickedArtInst)
+		bonusesFromPickedUpArtifact = pickedArtInst->getAllBonuses(selector, limit, hero);
 	else
 		bonusesFromPickedUpArtifact = TBonusListPtr(new BonusList());
 
@@ -244,7 +245,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded)
 		}
 		if(!arts)
 		{
-			arts = std::make_shared<CArtifactsOfHero>(Point(-65, -8), true);
+			arts = std::make_shared<CArtifactsOfHeroMain>(Point(-65, -8));
 			arts->setHero(curHero);
 			addSet(arts);
 		}
@@ -354,25 +355,23 @@ void CHeroWindow::dismissCurrent()
 
 void CHeroWindow::commanderWindow()
 {
-	//bool artSelected = false;
-	std::shared_ptr<CArtifactsOfHero::SCommonPart> commonInfo = getCommonPart();
+	const auto pickedArtInst = getPickedArtifact();
+	const auto hero = getHeroPickedArtifact();
 
-	if(const CArtifactInstance *art = commonInfo->src.art)
+	if(pickedArtInst)
 	{
-		const CGHeroInstance *srcHero = commonInfo->src.AOH->getHero();
-		//artSelected = true;
-		const auto freeSlot = ArtifactUtils::getArtAnyPosition(curHero->commander, art->artType->getId());
+		const auto freeSlot = ArtifactUtils::getArtAnyPosition(curHero->commander, pickedArtInst->getTypeId());
 		if(freeSlot < ArtifactPosition::COMMANDER_AFTER_LAST) //we don't want to put it in commander's backpack!
 		{
-			ArtifactLocation src(srcHero, commonInfo->src.slotID);
+			ArtifactLocation src(hero, ArtifactPosition::TRANSITION_POS);
 			ArtifactLocation dst(curHero->commander.get(), freeSlot);
 
-			if(art->canBePutAt(dst, true))
+			if(pickedArtInst->canBePutAt(dst, true))
 			{	//equip clicked stack
 				if(dst.getArt())
 				{
-					LOCPLINT->cb->swapArtifacts (dst, ArtifactLocation(srcHero,
-						ArtifactUtils::getArtBackpackPosition(srcHero, art->getTypeId())));
+					LOCPLINT->cb->swapArtifacts(dst, ArtifactLocation(hero,
+						ArtifactUtils::getArtBackpackPosition(hero, pickedArtInst->getTypeId())));
 				}
 				LOCPLINT->cb->swapArtifacts(src, dst);
 			}

+ 2 - 2
client/windows/CHeroWindow.h

@@ -25,7 +25,7 @@ class CHeroWindow;
 class LClickableAreaHero;
 class LRClickableAreaWText;
 class LRClickableAreaWTextComp;
-class CArtifactsOfHero;
+class CArtifactsOfHeroMain;
 class MoraleLuckBox;
 class CToggleButton;
 class CToggleGroup;
@@ -105,7 +105,7 @@ class CHeroWindow : public CStatusbarWindow, public CGarrisonHolder, public CWin
 	std::shared_ptr<CToggleGroup> formations;
 
 	std::shared_ptr<CGarrisonInt> garr;
-	std::shared_ptr<CArtifactsOfHero> arts;
+	std::shared_ptr<CArtifactsOfHeroMain> arts;
 
 	std::vector<std::shared_ptr<CLabel>> labels;
 

+ 2 - 2
client/windows/CKingdomInterface.cpp

@@ -872,7 +872,7 @@ CHeroItem::CHeroItem(const CGHeroInstance * Hero)
 	assert(arts1->arts.size() == 9);
 	assert(arts2->arts.size() == 9);
 
-	CArtifactsOfHero::ArtPlaceMap arts =
+	CArtifactsOfHeroMain::ArtPlaceMap arts =
 	{
 		{ArtifactPosition::HEAD, arts1->arts[0]},
 		{ArtifactPosition::SHOULDERS,arts1->arts[1]},
@@ -896,7 +896,7 @@ CHeroItem::CHeroItem(const CGHeroInstance * Hero)
 	};
 
 
-	heroArts = std::make_shared<CArtifactsOfHero>(arts, backpack->arts, backpack->btnLeft, backpack->btnRight, true);
+	heroArts = std::make_shared<CArtifactsOfHeroKingdom>(arts, backpack->arts, backpack->btnLeft, backpack->btnRight);
 	heroArts->setHero(hero);
 
 	artsTabs = std::make_shared<CTabbedInt>(std::bind(&CHeroItem::onTabSelected, this, _1));

+ 1 - 1
client/windows/CKingdomInterface.h

@@ -309,7 +309,7 @@ class CHeroItem : public CIntObject, public CGarrisonHolder
 	std::shared_ptr<CIntObject> onTabSelected(size_t index);
 
 public:
-	std::shared_ptr<CArtifactsOfHero> heroArts;
+	std::shared_ptr<CArtifactsOfHeroKingdom> heroArts;
 
 	void updateGarrisons() override;
 

+ 64 - 70
client/windows/CTradeWindow.cpp

@@ -179,24 +179,26 @@ void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState)
 		if(type == ARTIFACT_PLACEHOLDER)
 		{
 			CAltarWindow *aw = static_cast<CAltarWindow *>(mw);
-			if(const CArtifactInstance *movedArt = aw->arts->commonInfo->src.art)
+			const auto pickedArtInst = aw->getPickedArtifact();
+
+			auto artifactsOfHero = std::dynamic_pointer_cast<CArtifactsOfHeroAltar>(aw->arts);
+			if(pickedArtInst)
 			{
-				aw->moveFromSlotToAltar(aw->arts->commonInfo->src.slotID, this->shared_from_this(), movedArt);
+				artifactsOfHero->pickedArtMoveToAltar(ArtifactPosition::TRANSITION_POS);
+				aw->moveArtToAltar(this->shared_from_this(), pickedArtInst);
 			}
 			else if(const CArtifactInstance *art = getArtInstance())
 			{
-				aw->arts->commonInfo->src.AOH = aw->arts.get();
-				aw->arts->commonInfo->src.art = art;
-				aw->arts->commonInfo->src.slotID = aw->hero->getArtPos(art);
-				aw->arts->markPossibleSlots(art);
-
-				//aw->arts->commonInfo->dst.AOH = aw->arts;
-				CCS->curh->dragAndDropCursor("artifact", art->artType->getIconIndex());
-
-				aw->arts->artifactsOnAltar.erase(art);
+				const auto hero = artifactsOfHero->getHero();
+				const auto slot = hero->getSlotByInstance(art);
+				assert(slot != ArtifactPosition::PRE_FIRST);
+				LOCPLINT->cb->swapArtifacts(ArtifactLocation(hero, slot),
+					ArtifactLocation(hero, ArtifactPosition::TRANSITION_POS));
+				artifactsOfHero->pickedArtFromSlot = slot;
+				artifactsOfHero->artifactsOnAltar.erase(art);
 				setID(-1);
 				subtitle.clear();
-				aw->deal->block(!aw->arts->artifactsOnAltar.size());
+				aw->deal->block(!artifactsOfHero->artifactsOnAltar.size());
 			}
 
 			aw->calcTotalExp();
@@ -391,14 +393,21 @@ void CTradeWindow::initItems(bool Left)
 			yOffset = -12;
 		}
 
-		arts = std::make_shared<CArtifactsOfHero>(Point(xOffset, yOffset), true);
-		arts->recActions = 255-DISPOSE;
-		arts->setHero(hero);
-		arts->allowedAssembling = false;
-		addSet(arts);
-
 		if(mode == EMarketMode::ARTIFACT_RESOURCE)
-			arts->highlightModeCallback = std::bind(&CTradeWindow::artifactSelected, this, _1);
+		{
+			auto artifactsOfHero = std::make_shared<CArtifactsOfHeroMarket>(Point(xOffset, yOffset));
+			artifactsOfHero->selectArtCallback = std::bind(&CTradeWindow::artifactSelected, this, _1);
+			artifactsOfHero->setHero(hero);
+			addSet(artifactsOfHero);
+			arts = artifactsOfHero;
+		}
+		else
+		{
+			auto artifactsOfHero = std::make_shared<CArtifactsOfHeroAltar>(Point(xOffset, yOffset));
+			artifactsOfHero->setHero(hero);
+			addSet(artifactsOfHero);
+			arts = artifactsOfHero;
+		}
 	}
 	else
 	{
@@ -630,8 +639,8 @@ void CTradeWindow::setMode(EMarketMode::EMarketMode Mode)
 void CTradeWindow::artifactSelected(CHeroArtPlace *slot)
 {
 	assert(mode == EMarketMode::ARTIFACT_RESOURCE);
-	items[1][0]->setArtInstance(slot->ourArt);
-	if(slot->ourArt && !slot->locked)
+	items[1][0]->setArtInstance(slot->getArt());
+	if(slot->getArt())
 		hLeft = items[1][0];
 	else
 		hLeft = nullptr;
@@ -858,7 +867,7 @@ void CMarketplaceWindow::selectionChanged(bool side)
 		readyToTrade = readyToTrade && (hLeft->id != hRight->id); //for resource trade, two DIFFERENT resources must be selected
 
 	if(mode == EMarketMode::ARTIFACT_RESOURCE && !hLeft)
-		arts->unmarkSlots(false);
+		arts->unmarkSlots();
 
 	if(readyToTrade)
 	{
@@ -1250,13 +1259,15 @@ void CAltarWindow::makeDeal()
 	else
 	{
 		std::vector<ui32> positions;
-		for(const CArtifactInstance *art : arts->artifactsOnAltar) //sacrifice each artifact on the list
+		auto artifactsOfHero = std::dynamic_pointer_cast<CArtifactsOfHeroAltar>(arts);
+		for(const CArtifactInstance * art : artifactsOfHero->artifactsOnAltar)
 		{
-			positions.push_back(hero->getArtPos(art));
+			positions.push_back(hero->getSlotByInstance(art));
 		}
+		std::sort(positions.begin(), positions.end(), std::greater<>());
 
 		LOCPLINT->cb->trade(market->o, mode, positions, {}, {}, hero);
-		arts->artifactsOnAltar.clear();
+		artifactsOfHero->artifactsOnAltar.clear();
 
 		for(auto item : items[0])
 		{
@@ -1264,7 +1275,6 @@ void CAltarWindow::makeDeal()
 			item->subtitle = "";
 		}
 
-		arts->commonInfo->reset();
 		//arts->scrollBackpack(0);
 		deal->block(true);
 	}
@@ -1294,12 +1304,13 @@ void CAltarWindow::SacrificeAll()
 	}
 	else
 	{
-		for(auto i = hero->artifactsWorn.cbegin(); i != hero->artifactsWorn.cend(); i++)
+		auto artifactsOfHero = std::dynamic_pointer_cast<CArtifactsOfHeroAltar>(arts);
+		for(const auto & aw : artifactsOfHero->visibleArtSet->artifactsWorn)
 		{
-			if(!i->second.locked) //ignore locks from assembled artifacts
-				moveFromSlotToAltar(i->first, nullptr, i->second.artifact);
+			if(!aw.second.locked)
+				moveArtToAltar(nullptr, aw.second.artifact);
 		}
-
+		artifactsOfHero->updateWornSlots();
 		SacrificeBackpack();
 	}
 	redraw();
@@ -1414,7 +1425,8 @@ void CAltarWindow::calcTotalExp()
 	}
 	else
 	{
-		for(const CArtifactInstance *art : arts->artifactsOnAltar)
+		auto artifactsOfHero = std::dynamic_pointer_cast<CArtifactsOfHeroAltar>(arts);
+		for(const CArtifactInstance * art : artifactsOfHero->artifactsOnAltar)
 		{
 			int dmp, valOfArt;
 			market->getOffer(art->artType->getId(), 0, dmp, valOfArt, mode);
@@ -1458,21 +1470,12 @@ int CAltarWindow::firstFreeSlot()
 
 void CAltarWindow::SacrificeBackpack()
 {
-	std::multiset<const CArtifactInstance *> toOmmit = arts->artifactsOnAltar;
-
-	for (auto & elem : hero->artifactsInBackpack)
+	auto artsAltar = std::dynamic_pointer_cast<CArtifactsOfHeroAltar>(arts);
+	while(!artsAltar->visibleArtSet->artifactsInBackpack.empty())
 	{
-
-		if(vstd::contains(toOmmit, elem.artifact))
-		{
-			toOmmit -= elem.artifact;
-			continue;
-		}
-
-		putOnAltar(nullptr, elem.artifact);
-	}
-
-	arts->scrollBackpack(0);
+		if(!putOnAltar(nullptr, artsAltar->visibleArtSet->artifactsInBackpack[0].artifact))
+			break;
+	};
 	calcTotalExp();
 }
 
@@ -1484,15 +1487,18 @@ void CAltarWindow::artifactPicked()
 void CAltarWindow::showAll(SDL_Surface * to)
 {
 	CTradeWindow::showAll(to);
-	if(mode == EMarketMode::ARTIFACT_EXP && arts && arts->commonInfo->src.art)
+	if(mode == EMarketMode::ARTIFACT_EXP && arts)
 	{
-		artIcon->setFrame(arts->commonInfo->src.art->artType->getIconIndex());
-		artIcon->showAll(to);
+		if(auto pickedArt = arts->getPickedArtifact())
+		{
+			artIcon->setFrame(pickedArt->artType->getIconIndex());
+			artIcon->showAll(to);
 
-		int dmp, val;
-		market->getOffer(arts->commonInfo->src.art->artType->getId(), 0, dmp, val, EMarketMode::ARTIFACT_EXP);
-		val = static_cast<int>(hero->calculateXp(val));
-		printAtMiddleLoc(std::to_string(val), 304, 498, FONT_SMALL, Colors::WHITE, to);
+			int dmp, val;
+			market->getOffer(pickedArt->getTypeId(), 0, dmp, val, EMarketMode::ARTIFACT_EXP);
+			val = static_cast<int>(hero->calculateXp(val));
+			printAtMiddleLoc(std::to_string(val), 304, 498, FONT_SMALL, Colors::WHITE, to);
+		}
 	}
 }
 
@@ -1519,7 +1525,9 @@ bool CAltarWindow::putOnAltar(std::shared_ptr<CTradeableItem> altarSlot, const C
 	market->getOffer(art->artType->getId(), 0, dmp, val, EMarketMode::ARTIFACT_EXP);
 	val = static_cast<int>(hero->calculateXp(val));
 
-	arts->artifactsOnAltar.insert(art);
+	auto artsAltar = std::dynamic_pointer_cast<CArtifactsOfHeroAltar>(arts);
+	artsAltar->artifactsOnAltar.insert(art);
+	artsAltar->deleteFromVisible(art);
 	altarSlot->setArtInstance(art);
 	altarSlot->subtitle = std::to_string(val);
 
@@ -1527,25 +1535,11 @@ bool CAltarWindow::putOnAltar(std::shared_ptr<CTradeableItem> altarSlot, const C
 	return true;
 }
 
-void CAltarWindow::moveFromSlotToAltar(ArtifactPosition slotID, std::shared_ptr<CTradeableItem> altarSlot, const CArtifactInstance *art)
+void CAltarWindow::moveArtToAltar(std::shared_ptr<CTradeableItem> altarSlot, const CArtifactInstance *art)
 {
-	auto freeBackpackSlot = ArtifactPosition((si32)hero->artifactsInBackpack.size() + GameConstants::BACKPACK_START);
-	if(arts->commonInfo->src.art)
-	{
-		arts->commonInfo->dst.slotID = freeBackpackSlot;
-		arts->commonInfo->dst.AOH = arts.get();
-	}
-
 	if(putOnAltar(altarSlot, art))
 	{
-		if(slotID < GameConstants::BACKPACK_START)
-			LOCPLINT->cb->swapArtifacts(ArtifactLocation(hero, slotID), ArtifactLocation(hero, freeBackpackSlot));
-		else
-		{
-			arts->commonInfo->src.clear();
-			arts->commonInfo->dst.clear();
-			CCS->curh->dragAndDropCursor(nullptr);
-			arts->unmarkSlots(false);
-		}
+		CCS->curh->dragAndDropCursor(nullptr);
+		arts->unmarkSlots();
 	}
 }

+ 2 - 2
client/windows/CTradeWindow.h

@@ -67,7 +67,7 @@ public:
 	const IMarket * market;
 	const CGHeroInstance * hero;
 
-	std::shared_ptr<CArtifactsOfHero> arts;
+	std::shared_ptr<CArtifactsOfHeroBase> arts;
 	//all indexes: 1 = left, 0 = right
 	std::array<std::vector<std::shared_ptr<CTradeableItem>>, 2> items;
 
@@ -186,5 +186,5 @@ public:
 
 	void artifactPicked();
 	int firstFreeSlot();
-	void moveFromSlotToAltar(ArtifactPosition slotID, std::shared_ptr<CTradeableItem>, const CArtifactInstance * art);
+	void moveArtToAltar(std::shared_ptr<CTradeableItem>, const CArtifactInstance * art);
 };

+ 2 - 6
client/windows/GUIClasses.cpp

@@ -909,13 +909,9 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
 	portraits[0] = std::make_shared<CAnimImage>("PortraitsLarge", heroInst[0]->portrait, 0, 257, 13);
 	portraits[1] = std::make_shared<CAnimImage>("PortraitsLarge", heroInst[1]->portrait, 0, 485, 13);
 
-	artifs[0] = std::make_shared<CArtifactsOfHero>(Point(-334, 150));
-	artifs[0]->commonInfo = std::make_shared<CArtifactsOfHero::SCommonPart>();
-	artifs[0]->commonInfo->participants.insert(artifs[0].get());
+	artifs[0] = std::make_shared<CArtifactsOfHeroMain>(Point(-334, 150));
 	artifs[0]->setHero(heroInst[0]);
-	artifs[1] = std::make_shared<CArtifactsOfHero>(Point(96, 150));
-	artifs[1]->commonInfo = artifs[0]->commonInfo;
-	artifs[1]->commonInfo->participants.insert(artifs[1].get());
+	artifs[1] = std::make_shared<CArtifactsOfHeroMain>(Point(98, 150));
 	artifs[1]->setHero(heroInst[1]);
 
 	addSet(artifs[0]);

+ 1 - 1
client/windows/GUIClasses.h

@@ -327,7 +327,7 @@ class CExchangeWindow : public CStatusbarWindow, public CGarrisonHolder, public
 
 public:
 	std::array<const CGHeroInstance *, 2> heroInst;
-	std::array<std::shared_ptr<CArtifactsOfHero>, 2> artifs;
+	std::array<std::shared_ptr<CArtifactsOfHeroMain>, 2> artifs;
 
 	void updateGarrisons() override;