diff --git a/client/widgets/CGarrisonInt.cpp b/client/widgets/CGarrisonInt.cpp index 0b5b30ba7..5d1eafa74 100644 --- a/client/widgets/CGarrisonInt.cpp +++ b/client/widgets/CGarrisonInt.cpp @@ -185,20 +185,17 @@ bool CGarrisonSlot::highlightOrDropArtifact() bool artSelected = false; if (CWindowWithArtifacts* chw = dynamic_cast(GH.topInt().get())) //dirty solution { - std::shared_ptr 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()) { diff --git a/client/windows/CHeroWindow.cpp b/client/windows/CHeroWindow.cpp index fe8563541..3a91a0ede 100644 --- a/client/windows/CHeroWindow.cpp +++ b/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 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(Point(-65, -8), true); + arts = std::make_shared(Point(-65, -8)); arts->setHero(curHero); addSet(arts); } @@ -354,25 +355,23 @@ void CHeroWindow::dismissCurrent() void CHeroWindow::commanderWindow() { - //bool artSelected = false; - std::shared_ptr 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); } diff --git a/client/windows/CHeroWindow.h b/client/windows/CHeroWindow.h index 263b50009..de9b5ec40 100644 --- a/client/windows/CHeroWindow.h +++ b/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 formations; std::shared_ptr garr; - std::shared_ptr arts; + std::shared_ptr arts; std::vector> labels; diff --git a/client/windows/CKingdomInterface.cpp b/client/windows/CKingdomInterface.cpp index 8ad3bb8ee..1a8d514fe 100644 --- a/client/windows/CKingdomInterface.cpp +++ b/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(arts, backpack->arts, backpack->btnLeft, backpack->btnRight, true); + heroArts = std::make_shared(arts, backpack->arts, backpack->btnLeft, backpack->btnRight); heroArts->setHero(hero); artsTabs = std::make_shared(std::bind(&CHeroItem::onTabSelected, this, _1)); diff --git a/client/windows/CKingdomInterface.h b/client/windows/CKingdomInterface.h index 9d8448a71..10b106df8 100644 --- a/client/windows/CKingdomInterface.h +++ b/client/windows/CKingdomInterface.h @@ -309,7 +309,7 @@ class CHeroItem : public CIntObject, public CGarrisonHolder std::shared_ptr onTabSelected(size_t index); public: - std::shared_ptr heroArts; + std::shared_ptr heroArts; void updateGarrisons() override; diff --git a/client/windows/CTradeWindow.cpp b/client/windows/CTradeWindow.cpp index 0c16f51f4..1ebb09272 100644 --- a/client/windows/CTradeWindow.cpp +++ b/client/windows/CTradeWindow.cpp @@ -179,24 +179,26 @@ void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState) if(type == ARTIFACT_PLACEHOLDER) { CAltarWindow *aw = static_cast(mw); - if(const CArtifactInstance *movedArt = aw->arts->commonInfo->src.art) + const auto pickedArtInst = aw->getPickedArtifact(); + + auto artifactsOfHero = std::dynamic_pointer_cast(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(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(Point(xOffset, yOffset)); + artifactsOfHero->selectArtCallback = std::bind(&CTradeWindow::artifactSelected, this, _1); + artifactsOfHero->setHero(hero); + addSet(artifactsOfHero); + arts = artifactsOfHero; + } + else + { + auto artifactsOfHero = std::make_shared(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 positions; - for(const CArtifactInstance *art : arts->artifactsOnAltar) //sacrifice each artifact on the list + auto artifactsOfHero = std::dynamic_pointer_cast(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(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(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 toOmmit = arts->artifactsOnAltar; - - for (auto & elem : hero->artifactsInBackpack) + auto artsAltar = std::dynamic_pointer_cast(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(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(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 altarSlot, const C market->getOffer(art->artType->getId(), 0, dmp, val, EMarketMode::ARTIFACT_EXP); val = static_cast(hero->calculateXp(val)); - arts->artifactsOnAltar.insert(art); + auto artsAltar = std::dynamic_pointer_cast(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 altarSlot, const C return true; } -void CAltarWindow::moveFromSlotToAltar(ArtifactPosition slotID, std::shared_ptr altarSlot, const CArtifactInstance *art) +void CAltarWindow::moveArtToAltar(std::shared_ptr 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(); } } diff --git a/client/windows/CTradeWindow.h b/client/windows/CTradeWindow.h index 49bc5e74c..c1f236cda 100644 --- a/client/windows/CTradeWindow.h +++ b/client/windows/CTradeWindow.h @@ -67,7 +67,7 @@ public: const IMarket * market; const CGHeroInstance * hero; - std::shared_ptr arts; + std::shared_ptr arts; //all indexes: 1 = left, 0 = right std::array>, 2> items; @@ -186,5 +186,5 @@ public: void artifactPicked(); int firstFreeSlot(); - void moveFromSlotToAltar(ArtifactPosition slotID, std::shared_ptr, const CArtifactInstance * art); + void moveArtToAltar(std::shared_ptr, const CArtifactInstance * art); }; diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index cd714fbb7..7f65add98 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -909,13 +909,9 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2, portraits[0] = std::make_shared("PortraitsLarge", heroInst[0]->portrait, 0, 257, 13); portraits[1] = std::make_shared("PortraitsLarge", heroInst[1]->portrait, 0, 485, 13); - artifs[0] = std::make_shared(Point(-334, 150)); - artifs[0]->commonInfo = std::make_shared(); - artifs[0]->commonInfo->participants.insert(artifs[0].get()); + artifs[0] = std::make_shared(Point(-334, 150)); artifs[0]->setHero(heroInst[0]); - artifs[1] = std::make_shared(Point(96, 150)); - artifs[1]->commonInfo = artifs[0]->commonInfo; - artifs[1]->commonInfo->participants.insert(artifs[1].get()); + artifs[1] = std::make_shared(Point(98, 150)); artifs[1]->setHero(heroInst[1]); addSet(artifs[0]); diff --git a/client/windows/GUIClasses.h b/client/windows/GUIClasses.h index f676305f2..0168e5491 100644 --- a/client/windows/GUIClasses.h +++ b/client/windows/GUIClasses.h @@ -327,7 +327,7 @@ class CExchangeWindow : public CStatusbarWindow, public CGarrisonHolder, public public: std::array heroInst; - std::array, 2> artifs; + std::array, 2> artifs; void updateGarrisons() override;