From 2e3e6b1553de8ce91de07134a141a7a31df39c60 Mon Sep 17 00:00:00 2001 From: SoundSSGood <87084363+SoundSSGood@users.noreply.github.com> Date: Tue, 20 Aug 2024 17:15:50 +0300 Subject: [PATCH] market->getObjInstanceID() --- AI/Nullkiller/AIGateway.cpp | 2 +- AI/VCAI/VCAI.cpp | 2 +- CCallback.cpp | 8 ++++---- CCallback.h | 9 ++++----- client/CPlayerInterface.cpp | 13 +++++++++++-- client/NetPacksClient.cpp | 4 ++-- client/widgets/markets/CAltarArtifacts.cpp | 8 +++----- client/widgets/markets/CAltarCreatures.cpp | 4 ++-- client/widgets/markets/CArtifactsBuying.cpp | 2 +- client/widgets/markets/CArtifactsSelling.cpp | 3 ++- client/widgets/markets/CFreelancerGuild.cpp | 4 ++-- client/widgets/markets/CMarketResources.cpp | 4 ++-- client/widgets/markets/CTransferResources.cpp | 3 ++- client/windows/CMarketWindow.cpp | 7 ++----- client/windows/GUIClasses.cpp | 4 ++-- lib/CGameInfoCallback.cpp | 9 +++++++++ lib/CGameInfoCallback.h | 2 ++ lib/IGameCallback.cpp | 2 +- lib/mapObjects/CGMarket.cpp | 14 +++++--------- lib/mapObjects/CGMarket.h | 2 +- lib/mapObjects/CGTownInstance.cpp | 5 +++++ lib/mapObjects/CGTownInstance.h | 2 +- lib/mapObjects/IMarket.cpp | 4 ++-- lib/mapObjects/IMarket.h | 1 + server/CGameHandler.cpp | 10 ++++------ server/NetPacksServer.cpp | 4 ++-- test/spells/effects/CatapultTest.cpp | 6 +++--- 27 files changed, 77 insertions(+), 61 deletions(-) diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index 1a105d5f8..915b85b33 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/AI/Nullkiller/AIGateway.cpp @@ -1490,7 +1490,7 @@ void AIGateway::tryRealize(Goals::Trade & g) //trade //TODO trade only as much as needed if (toGive) //don't try to sell 0 resources { - cb->trade(m, EMarketMode::RESOURCE_RESOURCE, res, GameResID(g.resID), toGive); + cb->trade(m->getObjInstanceID(), EMarketMode::RESOURCE_RESOURCE, res, GameResID(g.resID), toGive); acquiredResources = static_cast(toGet * (it->resVal / toGive)); logAi->debug("Traded %d of %s for %d of %s at %s", toGive, res, acquiredResources, g.resID, obj->getObjectName()); } diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index e00a119c9..4372fb951 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -2130,7 +2130,7 @@ void VCAI::tryRealize(Goals::Trade & g) //trade //TODO trade only as much as needed if (toGive) //don't try to sell 0 resources { - cb->trade(m, EMarketMode::RESOURCE_RESOURCE, res, GameResID(g.resID), toGive); + cb->trade(m->getObjInstanceID(), EMarketMode::RESOURCE_RESOURCE, res, GameResID(g.resID), toGive); acquiredResources = static_cast(toGet * (it->resVal / toGive)); logAi->debug("Traded %d of %s for %d of %s at %s", toGive, res, acquiredResources, g.resID, obj->getObjectName()); } diff --git a/CCallback.cpp b/CCallback.cpp index 1be655bc5..d8a8fac99 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -266,15 +266,15 @@ void CCallback::buyArtifact(const CGHeroInstance *hero, ArtifactID aid) sendRequest(&pack); } -void CCallback::trade(const IMarket * market, EMarketMode mode, TradeItemSell id1, TradeItemBuy id2, ui32 val1, const CGHeroInstance * hero) +void CCallback::trade(const ObjectInstanceID marketId, EMarketMode mode, TradeItemSell id1, TradeItemBuy id2, ui32 val1, const CGHeroInstance * hero) { - trade(market, mode, std::vector(1, id1), std::vector(1, id2), std::vector(1, val1), hero); + trade(marketId, mode, std::vector(1, id1), std::vector(1, id2), std::vector(1, val1), hero); } -void CCallback::trade(const IMarket * market, EMarketMode mode, const std::vector & id1, const std::vector & id2, const std::vector & val1, const CGHeroInstance * hero) +void CCallback::trade(const ObjectInstanceID marketId, EMarketMode mode, const std::vector & id1, const std::vector & id2, const std::vector & val1, const CGHeroInstance * hero) { TradeOnMarketplace pack; - pack.marketId = dynamic_cast(market)->id; + pack.marketId = marketId; pack.heroId = hero ? hero->id : ObjectInstanceID(); pack.mode = mode; pack.r1 = id1; diff --git a/CCallback.h b/CCallback.h index 7da23128d..fc7f336c2 100644 --- a/CCallback.h +++ b/CCallback.h @@ -34,7 +34,6 @@ class IBattleEventsReceiver; class IGameEventsReceiver; struct ArtifactLocation; class BattleStateInfoForRetreat; -class IMarket; VCMI_LIB_NAMESPACE_END @@ -81,8 +80,8 @@ public: virtual bool upgradeCreature(const CArmedInstance *obj, SlotID stackPos, CreatureID newID=CreatureID::NONE)=0; //if newID==-1 then best possible upgrade will be made virtual void swapGarrisonHero(const CGTownInstance *town)=0; - virtual void trade(const IMarket * market, EMarketMode mode, TradeItemSell id1, TradeItemBuy id2, ui32 val1, const CGHeroInstance * hero = nullptr)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce - virtual void trade(const IMarket * market, EMarketMode mode, const std::vector & id1, const std::vector & id2, const std::vector & val1, const CGHeroInstance * hero = nullptr)=0; + virtual void trade(const ObjectInstanceID marketId, EMarketMode mode, TradeItemSell id1, TradeItemBuy id2, ui32 val1, const CGHeroInstance * hero = nullptr)=0; //mode==0: sell val1 units of id1 resource for id2 resiurce + virtual void trade(const ObjectInstanceID marketId, EMarketMode mode, const std::vector & id1, const std::vector & id2, const std::vector & val1, const CGHeroInstance * hero = nullptr)=0; virtual int selectionMade(int selection, QueryID queryID) =0; virtual int sendQueryReply(std::optional reply, QueryID queryID) =0; @@ -190,8 +189,8 @@ public: void endTurn() override; void swapGarrisonHero(const CGTownInstance *town) override; void buyArtifact(const CGHeroInstance *hero, ArtifactID aid) override; - void trade(const IMarket * market, EMarketMode mode, TradeItemSell id1, TradeItemBuy id2, ui32 val1, const CGHeroInstance * hero = nullptr) override; - void trade(const IMarket * market, EMarketMode mode, const std::vector & id1, const std::vector & id2, const std::vector & val1, const CGHeroInstance * hero = nullptr) override; + void trade(const ObjectInstanceID marketId, EMarketMode mode, TradeItemSell id1, TradeItemBuy id2, ui32 val1, const CGHeroInstance * hero = nullptr) override; + void trade(const ObjectInstanceID marketId, EMarketMode mode, const std::vector & id1, const std::vector & id2, const std::vector & val1, const CGHeroInstance * hero = nullptr) override; void setFormation(const CGHeroInstance * hero, EArmyFormation mode) override; void recruitHero(const CGObjectInstance *townOrTavern, const CGHeroInstance *hero, const HeroTypeID & nextHero=HeroTypeID::NONE) override; void save(const std::string &fname) override; diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index d4ef5d599..8bace1648 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -1654,8 +1654,17 @@ void CPlayerInterface::showMarketWindow(const IMarket * market, const CGHeroInst GH.windows().createAndPushWindow(market, visitor, onWindowClosed, EMarketMode::CREATURE_EXP); else if(market->allowsTrade(EMarketMode::CREATURE_UNDEAD)) GH.windows().createAndPushWindow(market, visitor, onWindowClosed); - else if(vstd::contains(market->availableModes(), EMarketMode::RESOURCE_RESOURCE)) - GH.windows().createAndPushWindow(market, visitor, onWindowClosed, EMarketMode::RESOURCE_RESOURCE); + else if (!market->availableModes().empty()) + for(auto mode = EMarketMode::RESOURCE_RESOURCE; mode != EMarketMode::MARKET_AFTER_LAST_PLACEHOLDER; mode = vstd::next(mode, 1)) + { + if(vstd::contains(market->availableModes(), mode)) + { + GH.windows().createAndPushWindow(market, visitor, onWindowClosed, mode); + break; + } + } + else + onWindowClosed(); } void CPlayerInterface::showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor, QueryID queryID) diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index c4379e3d7..05e94d915 100644 --- a/client/NetPacksClient.cpp +++ b/client/NetPacksClient.cpp @@ -999,7 +999,7 @@ void ApplyClientNetPackVisitor::visitOpenWindow(OpenWindow & pack) case EOpenWindowMode::UNIVERSITY_WINDOW: { //displays University window (when hero enters University on adventure map) - const auto * market = dynamic_cast(cl.getObj(ObjectInstanceID(pack.object))); + const auto * market = cl.getMarket(ObjectInstanceID(pack.object)); const CGHeroInstance *hero = cl.getHero(ObjectInstanceID(pack.visitor)); callInterfaceIfPresent(cl, hero->tempOwner, &IGameEventsReceiver::showUniversityWindow, market, hero, pack.queryID); } @@ -1009,7 +1009,7 @@ void ApplyClientNetPackVisitor::visitOpenWindow(OpenWindow & pack) //displays Thieves' Guild window (when hero enters Den of Thieves) const CGObjectInstance *obj = cl.getObj(ObjectInstanceID(pack.object)); const CGHeroInstance *hero = cl.getHero(ObjectInstanceID(pack.visitor)); - const auto *market = dynamic_cast(obj); + const auto market = cl.getMarket(pack.object); callInterfaceIfPresent(cl, cl.getTile(obj->visitablePos())->visitableObjects.back()->tempOwner, &IGameEventsReceiver::showMarketWindow, market, hero, pack.queryID); } break; diff --git a/client/widgets/markets/CAltarArtifacts.cpp b/client/widgets/markets/CAltarArtifacts.cpp index 45a23a9cd..78c4ff87a 100644 --- a/client/widgets/markets/CAltarArtifacts.cpp +++ b/client/widgets/markets/CAltarArtifacts.cpp @@ -24,7 +24,7 @@ #include "../../../lib/networkPacks/ArtifactLocation.h" #include "../../../lib/texts/CGeneralTextHandler.h" #include "../../../lib/mapObjects/CGHeroInstance.h" -#include "../../../lib/mapObjects/CGMarket.h" +#include "../../../lib/mapObjects/IMarket.h" CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance * hero) : CMarketBase(market, hero) @@ -50,9 +50,7 @@ CAltarArtifacts::CAltarArtifacts(const IMarket * market, const CGHeroInstance * // Hero's artifacts heroArts = std::make_shared(Point(-365, -11)); heroArts->setHero(hero); - const auto mapObj = dynamic_cast(market); - assert(mapObj); - heroArts->altarId = mapObj->id; + heroArts->altarId = market->getObjInstanceID(); // Altar offerTradePanel = std::make_shared([this](const std::shared_ptr & altarSlot) @@ -105,7 +103,7 @@ void CAltarArtifacts::makeDeal() { positions.push_back(artInst->getId()); } - LOCPLINT->cb->trade(market, EMarketMode::ARTIFACT_EXP, positions, std::vector(), std::vector(), hero); + LOCPLINT->cb->trade(market->getObjInstanceID(), EMarketMode::ARTIFACT_EXP, positions, std::vector(), std::vector(), hero); deselect(); } diff --git a/client/widgets/markets/CAltarCreatures.cpp b/client/widgets/markets/CAltarCreatures.cpp index e168335d0..896e0644b 100644 --- a/client/widgets/markets/CAltarCreatures.cpp +++ b/client/widgets/markets/CAltarCreatures.cpp @@ -23,7 +23,7 @@ #include "../../../lib/texts/CGeneralTextHandler.h" #include "../../../lib/mapObjects/CGHeroInstance.h" -#include "../../../lib/mapObjects/CGMarket.h" +#include "../../../lib/mapObjects/IMarket.h" CAltarCreatures::CAltarCreatures(const IMarket * market, const CGHeroInstance * hero) : CMarketBase(market, hero) @@ -157,7 +157,7 @@ void CAltarCreatures::makeDeal() } } - LOCPLINT->cb->trade(market, EMarketMode::CREATURE_EXP, ids, {}, toSacrifice, hero); + LOCPLINT->cb->trade(market->getObjInstanceID(), EMarketMode::CREATURE_EXP, ids, {}, toSacrifice, hero); for(int & units : unitsOnAltar) units = 0; diff --git a/client/widgets/markets/CArtifactsBuying.cpp b/client/widgets/markets/CArtifactsBuying.cpp index 16e5ba3db..853bc848b 100644 --- a/client/widgets/markets/CArtifactsBuying.cpp +++ b/client/widgets/markets/CArtifactsBuying.cpp @@ -68,7 +68,7 @@ void CArtifactsBuying::makeDeal() { if(ArtifactID(offerTradePanel->getSelectedItemId()).toArtifact()->canBePutAt(hero)) { - LOCPLINT->cb->trade(market, EMarketMode::RESOURCE_ARTIFACT, GameResID(bidTradePanel->getSelectedItemId()), + LOCPLINT->cb->trade(market->getObjInstanceID(), EMarketMode::RESOURCE_ARTIFACT, GameResID(bidTradePanel->getSelectedItemId()), ArtifactID(offerTradePanel->getSelectedItemId()), offerQty, hero); CMarketTraderText::makeDeal(); deselect(); diff --git a/client/widgets/markets/CArtifactsSelling.cpp b/client/widgets/markets/CArtifactsSelling.cpp index 6b9d6ee10..dbbe41278 100644 --- a/client/widgets/markets/CArtifactsSelling.cpp +++ b/client/widgets/markets/CArtifactsSelling.cpp @@ -78,7 +78,8 @@ void CArtifactsSelling::makeDeal() { const auto art = hero->getArt(selectedHeroSlot); assert(art); - LOCPLINT->cb->trade(market, EMarketMode::ARTIFACT_RESOURCE, art->getId(), GameResID(offerTradePanel->getSelectedItemId()), offerQty, hero); + LOCPLINT->cb->trade(market->getObjInstanceID(), EMarketMode::ARTIFACT_RESOURCE, art->getId(), + GameResID(offerTradePanel->getSelectedItemId()), offerQty, hero); CMarketTraderText::makeDeal(); } diff --git a/client/widgets/markets/CFreelancerGuild.cpp b/client/widgets/markets/CFreelancerGuild.cpp index 1a2ab31b7..19c138d1b 100644 --- a/client/widgets/markets/CFreelancerGuild.cpp +++ b/client/widgets/markets/CFreelancerGuild.cpp @@ -23,7 +23,7 @@ #include "../../../lib/texts/CGeneralTextHandler.h" #include "../../../lib/mapObjects/CGHeroInstance.h" -#include "../../../lib/mapObjects/CGMarket.h" +#include "../../../lib/mapObjects/IMarket.h" CFreelancerGuild::CFreelancerGuild(const IMarket * market, const CGHeroInstance * hero) : CMarketBase(market, hero) @@ -69,7 +69,7 @@ void CFreelancerGuild::makeDeal() { if(auto toTrade = offerSlider->getValue(); toTrade != 0) { - LOCPLINT->cb->trade(market, EMarketMode::CREATURE_RESOURCE, SlotID(bidTradePanel->highlightedSlot->serial), GameResID(offerTradePanel->getSelectedItemId()), bidQty * toTrade, hero); + LOCPLINT->cb->trade(market->getObjInstanceID(), EMarketMode::CREATURE_RESOURCE, SlotID(bidTradePanel->highlightedSlot->serial), GameResID(offerTradePanel->getSelectedItemId()), bidQty * toTrade, hero); CMarketTraderText::makeDeal(); deselect(); } diff --git a/client/widgets/markets/CMarketResources.cpp b/client/widgets/markets/CMarketResources.cpp index be8e2a92a..4233d2f2a 100644 --- a/client/widgets/markets/CMarketResources.cpp +++ b/client/widgets/markets/CMarketResources.cpp @@ -22,7 +22,7 @@ #include "../../../CCallback.h" #include "../../../lib/texts/CGeneralTextHandler.h" -#include "../../../lib/mapObjects/CGMarket.h" +#include "../../../lib/mapObjects/IMarket.h" CMarketResources::CMarketResources(const IMarket * market, const CGHeroInstance * hero) : CMarketBase(market, hero) @@ -60,7 +60,7 @@ void CMarketResources::makeDeal() { if(auto toTrade = offerSlider->getValue(); toTrade != 0) { - LOCPLINT->cb->trade(market, EMarketMode::RESOURCE_RESOURCE, GameResID(bidTradePanel->getSelectedItemId()), + LOCPLINT->cb->trade(market->getObjInstanceID(), EMarketMode::RESOURCE_RESOURCE, GameResID(bidTradePanel->getSelectedItemId()), GameResID(offerTradePanel->highlightedSlot->id), bidQty * toTrade, hero); CMarketTraderText::makeDeal(); deselect(); diff --git a/client/widgets/markets/CTransferResources.cpp b/client/widgets/markets/CTransferResources.cpp index 04e3cf545..f2871c869 100644 --- a/client/widgets/markets/CTransferResources.cpp +++ b/client/widgets/markets/CTransferResources.cpp @@ -22,6 +22,7 @@ #include "../../../CCallback.h" #include "../../../lib/texts/CGeneralTextHandler.h" +#include "../../../lib/mapObjects/IMarket.h" #include "../../../lib/texts/MetaString.h" CTransferResources::CTransferResources(const IMarket * market, const CGHeroInstance * hero) @@ -63,7 +64,7 @@ void CTransferResources::makeDeal() { if(auto toTrade = offerSlider->getValue(); toTrade != 0) { - LOCPLINT->cb->trade(market, EMarketMode::RESOURCE_PLAYER, GameResID(bidTradePanel->getSelectedItemId()), + LOCPLINT->cb->trade(market->getObjInstanceID(), EMarketMode::RESOURCE_PLAYER, GameResID(bidTradePanel->getSelectedItemId()), PlayerColor(offerTradePanel->getSelectedItemId()), toTrade, hero); CMarketTraderText::makeDeal(); deselect(); diff --git a/client/windows/CMarketWindow.cpp b/client/windows/CMarketWindow.cpp index 8d569bd4c..dc90ea077 100644 --- a/client/windows/CMarketWindow.cpp +++ b/client/windows/CMarketWindow.cpp @@ -187,9 +187,7 @@ void CMarketWindow::createArtifactsBuying(const IMarket * market, const CGHeroIn OBJECT_CONSTRUCTION; background = createBg(ImagePath::builtin("TPMRKABS.bmp"), PLAYER_COLORED); - const auto mapObj = dynamic_cast(market); - assert(market); - marketWidget = std::make_shared(market, hero, LOCPLINT->cb->getTown(mapObj->id) ? + marketWidget = std::make_shared(market, hero, LOCPLINT->cb->getTown(market->getObjInstanceID()) ? VLC->generaltexth->translate("building.core.conflux.special1.name") : CGI->generaltexth->allTexts[349]); initWidgetInternals(EMarketMode::RESOURCE_ARTIFACT, CGI->generaltexth->zelp[600]); } @@ -202,8 +200,7 @@ void CMarketWindow::createArtifactsSelling(const IMarket * market, const CGHeroI // Create image that copies part of background containing slot MISC_1 into position of slot MISC_5 artSlotBack = std::make_shared(background->getSurface(), Rect(20, 187, 47, 47), 0, 0); artSlotBack->moveTo(pos.topLeft() + Point(18, 339)); - const auto mapObj = dynamic_cast(market); - assert(market); + const auto mapObj = LOCPLINT->cb->getObj(market->getObjInstanceID()); auto artsSellingMarket = std::make_shared(market, hero, LOCPLINT->cb->getTown(mapObj->id) ? VLC->generaltexth->translate("building.core.conflux.special1.name") : mapObj->getObjectName()); artSets.clear(); diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index b5994d914..bc11501e7 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -819,7 +819,7 @@ void CTransformerWindow::makeDeal() for(auto & elem : items) { if(!elem->left) - LOCPLINT->cb->trade(market, EMarketMode::CREATURE_UNDEAD, SlotID(elem->id), {}, {}, hero); + LOCPLINT->cb->trade(market->getObjInstanceID(), EMarketMode::CREATURE_UNDEAD, SlotID(elem->id), {}, {}, hero); } } @@ -1005,7 +1005,7 @@ void CUniversityWindow::updateSecondarySkills() void CUniversityWindow::makeDeal(SecondarySkill skill) { - LOCPLINT->cb->trade(market, EMarketMode::RESOURCE_SKILL, GameResID(GameResID::GOLD), skill, 1, hero); + LOCPLINT->cb->trade(market->getObjInstanceID(), EMarketMode::RESOURCE_SKILL, GameResID(GameResID::GOLD), skill, 1, hero); } CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, SecondarySkill SKILL, bool available) diff --git a/lib/CGameInfoCallback.cpp b/lib/CGameInfoCallback.cpp index 156c3fde5..76a7f6f29 100644 --- a/lib/CGameInfoCallback.cpp +++ b/lib/CGameInfoCallback.cpp @@ -174,6 +174,15 @@ const CGTownInstance* CGameInfoCallback::getTown(ObjectInstanceID objid) const return nullptr; } +const IMarket * CGameInfoCallback::getMarket(ObjectInstanceID objid) const +{ + const CGObjectInstance * obj = getObj(objid, false); + if(obj) + return dynamic_cast(obj); + else + return nullptr; +} + void CGameInfoCallback::fillUpgradeInfo(const CArmedInstance *obj, SlotID stackPos, UpgradeInfo &out) const { //boost::shared_lock lock(*gs->mx); diff --git a/lib/CGameInfoCallback.h b/lib/CGameInfoCallback.h index 6b9f251a5..dd21492f0 100644 --- a/lib/CGameInfoCallback.h +++ b/lib/CGameInfoCallback.h @@ -48,6 +48,7 @@ class CGHeroInstance; class CGDwelling; class CGTeleport; class CGTownInstance; +class IMarket; class DLL_LINKAGE IGameInfoCallback : boost::noncopyable { @@ -189,6 +190,7 @@ public: virtual std::vector getFlaggableObjects(int3 pos) const; virtual const CGObjectInstance * getTopObj (int3 pos) const; virtual PlayerColor getOwner(ObjectInstanceID heroID) const; + virtual const IMarket * getMarket(ObjectInstanceID objid) const; //map virtual int3 guardingCreaturePosition (int3 pos) const; diff --git a/lib/IGameCallback.cpp b/lib/IGameCallback.cpp index 06d500b16..aeaa569f6 100644 --- a/lib/IGameCallback.cpp +++ b/lib/IGameCallback.cpp @@ -287,7 +287,7 @@ CArtifactSet * CNonConstInfoCallback::getArtSet(const ArtifactLocation & loc) return hero; } } - else if(auto market = dynamic_cast(getObjInstance(loc.artHolder))) + else if(auto market = getMarket(loc.artHolder)) { if(auto artSet = market->getArtifactsStorage()) return artSet.get(); diff --git a/lib/mapObjects/CGMarket.cpp b/lib/mapObjects/CGMarket.cpp index 9ae871bc6..a160f7803 100644 --- a/lib/mapObjects/CGMarket.cpp +++ b/lib/mapObjects/CGMarket.cpp @@ -23,6 +23,11 @@ VCMI_LIB_NAMESPACE_BEGIN +ObjectInstanceID CGMarket::getObjInstanceID() const +{ + return id; +} + void CGMarket::initObj(vstd::RNG & rand) { getObjectHandler()->configureObject(this, rand); @@ -43,13 +48,6 @@ int CGMarket::availableUnits(EMarketMode mode, int marketItemSerial) const return -1; } -std::vector CGMarket::availableItemsIds(EMarketMode mode) const -{ - if(allowsTrade(mode)) - return IMarket::availableItemsIds(mode); - return std::vector(); -} - CGMarket::CGMarket(IGameCallback *cb): CGObjectInstance(cb) {} @@ -58,8 +56,6 @@ std::vector CGBlackMarket::availableItemsIds(EMarketMode mode) con { switch(mode) { - case EMarketMode::ARTIFACT_RESOURCE: - return IMarket::availableItemsIds(mode); case EMarketMode::RESOURCE_ARTIFACT: { std::vector ret; diff --git a/lib/mapObjects/CGMarket.h b/lib/mapObjects/CGMarket.h index ae0b0c5c3..19cb235c7 100644 --- a/lib/mapObjects/CGMarket.h +++ b/lib/mapObjects/CGMarket.h @@ -26,9 +26,9 @@ public: void initObj(vstd::RNG & rand) override;//set skills for trade ///IMarket + ObjectInstanceID getObjInstanceID() const override; int getMarketEfficiency() const override; int availableUnits(EMarketMode mode, int marketItemSerial) const override; //-1 if unlimited - std::vector availableItemsIds(EMarketMode mode) const override; template void serialize(Handler &h) { diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index 18fc2ff3c..2c9a25c5c 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -710,6 +710,11 @@ std::vector CGTownInstance::availableItemsIds(EMarketMode mode) co return IMarket::availableItemsIds(mode); } +ObjectInstanceID CGTownInstance::getObjInstanceID() const +{ + return id; +} + void CGTownInstance::updateAppearance() { auto terrain = cb->gameState()->getTile(visitablePos())->terType->getId(); diff --git a/lib/mapObjects/CGTownInstance.h b/lib/mapObjects/CGTownInstance.h index 8ecf31add..fec18bf9a 100644 --- a/lib/mapObjects/CGTownInstance.h +++ b/lib/mapObjects/CGTownInstance.h @@ -155,7 +155,7 @@ public: const IObjectInterface * getObject() const override; int getMarketEfficiency() const override; //=market count std::vector availableItemsIds(EMarketMode mode) const override; - + ObjectInstanceID getObjInstanceID() const override; void updateAppearance(); ////////////////////////////////////////////////////////////////////////// diff --git a/lib/mapObjects/IMarket.cpp b/lib/mapObjects/IMarket.cpp index ed9f7e58c..c6ebf71ed 100644 --- a/lib/mapObjects/IMarket.cpp +++ b/lib/mapObjects/IMarket.cpp @@ -22,7 +22,7 @@ VCMI_LIB_NAMESPACE_BEGIN bool IMarket::allowsTrade(const EMarketMode mode) const { - return marketModes.count(mode) > 0; + return vstd::contains(marketModes, mode); } bool IMarket::getOffer(int id1, int id2, int &val1, int &val2, EMarketMode mode) const @@ -180,7 +180,7 @@ std::vector IMarket::availableItemsIds(const EMarketMode mode) con case EMarketMode::RESOURCE_RESOURCE: case EMarketMode::ARTIFACT_RESOURCE: case EMarketMode::CREATURE_RESOURCE: - for (auto res : GameResID::ALL_RESOURCES()) + for(const auto & res : GameResID::ALL_RESOURCES()) ret.push_back(res); } return ret; diff --git a/lib/mapObjects/IMarket.h b/lib/mapObjects/IMarket.h index 236974245..e50c19753 100644 --- a/lib/mapObjects/IMarket.h +++ b/lib/mapObjects/IMarket.h @@ -24,6 +24,7 @@ public: ArtBearer::ArtBearer bearerType() const override {return ArtBearer::ALTAR;}; }; + virtual ObjectInstanceID getObjInstanceID() const = 0; // The market is always an object on the map virtual int getMarketEfficiency() const = 0; virtual bool allowsTrade(const EMarketMode mode) const; virtual int availableUnits(const EMarketMode mode, const int marketItemSerial) const; //-1 if unlimited diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 6e06ff615..b41df6293 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -3560,9 +3560,9 @@ bool CGameHandler::isAllowedExchange(ObjectInstanceID id1, ObjectInstanceID id2) return true; } - auto market = dynamic_cast(o1); + auto market = getMarket(id1); if(market == nullptr) - market = dynamic_cast(o2); + market = getMarket(id2); if(market) return market->allowsTrade(EMarketMode::ARTIFACT_EXP); @@ -3917,9 +3917,7 @@ bool CGameHandler::sacrificeArtifact(const IMarket * market, const CGHeroInstanc COMPLAIN_RET("Evil hero can't sacrifice artifact!"); assert(market); - const auto mapObj = dynamic_cast(market); - assert(mapObj); - const auto artSet = getArtSet(mapObj->id); + const auto artSet = market->getArtifactsStorage(); int expSum = 0; auto finish = [this, &hero, &expSum]() @@ -3937,7 +3935,7 @@ bool CGameHandler::sacrificeArtifact(const IMarket * market, const CGHeroInstanc int expToGive; market->getOffer(art->getTypeId(), 0, dmp, expToGive, EMarketMode::ARTIFACT_EXP); expSum += expToGive; - removeArtifact(ArtifactLocation(mapObj->id, artSet->getArtPos(art))); + removeArtifact(ArtifactLocation(market->getObjInstanceID(), artSet->getArtPos(art))); } else { diff --git a/server/NetPacksServer.cpp b/server/NetPacksServer.cpp index 17217dac6..d1ebbf895 100644 --- a/server/NetPacksServer.cpp +++ b/server/NetPacksServer.cpp @@ -184,7 +184,7 @@ void ApplyGhNetPackVisitor::visitExchangeArtifacts(ExchangeArtifacts & pack) void ApplyGhNetPackVisitor::visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) { - if(dynamic_cast(gh.getObj(pack.srcHero)) == nullptr) + if(gh.getMarket(pack.srcHero) == nullptr) gh.throwIfWrongOwner(&pack, pack.srcHero); if(pack.swap) gh.throwIfWrongOwner(&pack, pack.dstHero); @@ -250,7 +250,7 @@ void ApplyGhNetPackVisitor::visitTradeOnMarketplace(TradeOnMarketplace & pack) { const CGObjectInstance * object = gh.getObj(pack.marketId); const CGHeroInstance * hero = gh.getHero(pack.heroId); - const auto * market = dynamic_cast(object); + const auto * market = gh.getMarket(pack.marketId); gh.throwIfWrongPlayer(&pack); gh.throwIfPlayerNotActive(&pack); diff --git a/test/spells/effects/CatapultTest.cpp b/test/spells/effects/CatapultTest.cpp index a67e9204a..9743f9378 100644 --- a/test/spells/effects/CatapultTest.cpp +++ b/test/spells/effects/CatapultTest.cpp @@ -64,7 +64,7 @@ TEST_F(CatapultTest, NotApplicableInVillage) TEST_F(CatapultTest, NotApplicableForDefenderIfSmart) { auto fakeTown = std::make_shared(nullptr); - fakeTown->builtBuildings.insert(BuildingID::FORT); + fakeTown->addBuilding(BuildingID::FORT); mechanicsMock.casterSide = BattleSide::DEFENDER; EXPECT_CALL(*battleFake, getDefendedTown()).WillRepeatedly(Return(fakeTown.get())); @@ -78,7 +78,7 @@ TEST_F(CatapultTest, NotApplicableForDefenderIfSmart) TEST_F(CatapultTest, DISABLED_ApplicableInTown) { auto fakeTown = std::make_shared(nullptr); - fakeTown->builtBuildings.insert(BuildingID::FORT); + fakeTown->addBuilding(BuildingID::FORT); EXPECT_CALL(*battleFake, getDefendedTown()).WillRepeatedly(Return(fakeTown.get())); EXPECT_CALL(mechanicsMock, adaptProblem(_, _)).Times(0); @@ -108,7 +108,7 @@ protected: { EffectFixture::setUp(); fakeTown = std::make_shared(nullptr); - fakeTown->builtBuildings.insert(BuildingID::FORT); + fakeTown->addBuilding(BuildingID::FORT); } private: std::shared_ptr fakeTown;