diff --git a/CCallback.cpp b/CCallback.cpp index 6805cb936..e58c31480 100644 --- a/CCallback.cpp +++ b/CCallback.cpp @@ -185,6 +185,12 @@ void CCallback::bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dst sendRequest(&bma); } +void CCallback::eraseArtifactByClient(const ArtifactLocation & al) +{ + EraseArtifactByClient ea(al); + sendRequest(&ea); +} + bool CCallback::buildBuilding(const CGTownInstance *town, BuildingID buildingID) { if(town->tempOwner!=player) diff --git a/CCallback.h b/CCallback.h index f8ddf2555..815022fb0 100644 --- a/CCallback.h +++ b/CCallback.h @@ -85,6 +85,7 @@ public: //virtual bool swapArtifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes virtual bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2)=0; virtual bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo)=0; + virtual void eraseArtifactByClient(const ArtifactLocation & al)=0; virtual bool dismissCreature(const CArmedInstance *obj, SlotID stackPos)=0; virtual void endTurn()=0; virtual void buyArtifact(const CGHeroInstance *hero, ArtifactID aid)=0; //used to buy artifacts in towns (including spell book in the guild and war machines in blacksmith) @@ -159,6 +160,7 @@ public: bool swapArtifacts(const ArtifactLocation &l1, const ArtifactLocation &l2) override; bool assembleArtifacts(const CGHeroInstance * hero, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo) override; void bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap) override; + void eraseArtifactByClient(const ArtifactLocation & al) override; bool buildBuilding(const CGTownInstance *town, BuildingID buildingID) override; void recruitCreatures(const CGDwelling * obj, const CArmedInstance * dst, CreatureID ID, ui32 amount, si32 level=-1) override; bool dismissCreature(const CArmedInstance *obj, SlotID stackPos) override; diff --git a/client/widgets/CArtifactHolder.cpp b/client/widgets/CArtifactHolder.cpp index f95090a24..713cd6137 100644 --- a/client/widgets/CArtifactHolder.cpp +++ b/client/widgets/CArtifactHolder.cpp @@ -654,7 +654,7 @@ CArtifactsOfHero::~CArtifactsOfHero() } else { - //TODO remove artifact + LOCPLINT->cb->eraseArtifactByClient(ArtifactLocation(curHero, ArtifactPosition::TRANSITION_POS)); } } } diff --git a/lib/NetPackVisitor.h b/lib/NetPackVisitor.h index 7cef3d188..226b4a18a 100644 --- a/lib/NetPackVisitor.h +++ b/lib/NetPackVisitor.h @@ -126,6 +126,7 @@ public: virtual void visitExchangeArtifacts(ExchangeArtifacts & pack) {} virtual void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) {} virtual void visitAssembleArtifacts(AssembleArtifacts & pack) {} + virtual void visitEraseArtifactByClient(EraseArtifactByClient & pack) {} virtual void visitBuyArtifact(BuyArtifact & pack) {} virtual void visitTradeOnMarketplace(TradeOnMarketplace & pack) {} virtual void visitSetFormation(SetFormation & pack) {} diff --git a/lib/NetPacks.h b/lib/NetPacks.h index 6d57cc17d..724f0605b 100644 --- a/lib/NetPacks.h +++ b/lib/NetPacks.h @@ -2298,6 +2298,24 @@ struct DLL_LINKAGE AssembleArtifacts : public CPackForServer } }; +struct DLL_LINKAGE EraseArtifactByClient : public CPackForServer +{ + EraseArtifactByClient() = default; + EraseArtifactByClient(const ArtifactLocation & al) + : al(al) + { + } + ArtifactLocation al; + + virtual void visitTyped(ICPackVisitor & visitor) override; + + template void serialize(Handler & h, const int version) + { + h & static_cast(*this); + h & al; + } +}; + struct DLL_LINKAGE BuyArtifact : public CPackForServer { BuyArtifact() = default; diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 6c46d04d2..76dfbb9c1 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -593,6 +593,11 @@ void AssembleArtifacts::visitTyped(ICPackVisitor & visitor) visitor.visitAssembleArtifacts(*this); } +void EraseArtifactByClient::visitTyped(ICPackVisitor & visitor) +{ + visitor.visitEraseArtifactByClient(*this); +} + void BuyArtifact::visitTyped(ICPackVisitor & visitor) { visitor.visitBuyArtifact(*this); diff --git a/lib/registerTypes/RegisterTypes.h b/lib/registerTypes/RegisterTypes.h index 58347a5b6..4eca3fe0c 100644 --- a/lib/registerTypes/RegisterTypes.h +++ b/lib/registerTypes/RegisterTypes.h @@ -346,6 +346,7 @@ void registerTypesServerPacks(Serializer &s) s.template registerType(); s.template registerType(); s.template registerType(); + s.template registerType(); } template diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index e7538f1a3..1a4c6cb76 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -4063,6 +4063,23 @@ bool CGameHandler::assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition return true; } +bool CGameHandler::eraseArtifactByClient(const ArtifactLocation & al) +{ + const auto * hero = getHero(al.relatedObj()->id); + if(hero == nullptr) + COMPLAIN_RET("eraseArtifactByClient: wrong hero's ID"); + + const auto * art = al.getArt(); + if(art == nullptr) + COMPLAIN_RET("Cannot remove artifact!"); + + if(al.getArt()->artType->canBePutAt(hero) || al.slot != ArtifactPosition::TRANSITION_POS) + COMPLAIN_RET("Unlegal removing artifact"); + + removeArtifact(al); + return true; +} + bool CGameHandler::buyArtifact(ObjectInstanceID hid, ArtifactID aid) { const CGHeroInstance * hero = getHero(hid); diff --git a/server/CGameHandler.h b/server/CGameHandler.h index a219358c2..7da5dcd57 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -182,6 +182,7 @@ public: void removeArtifact(const ArtifactLocation &al) override; bool moveArtifact(const ArtifactLocation & al1, const ArtifactLocation & al2) override; bool bulkMoveArtifacts(ObjectInstanceID srcHero, ObjectInstanceID dstHero, bool swap); + bool eraseArtifactByClient(const ArtifactLocation & al); void synchronizeArtifactHandlerLists(); void heroVisitCastle(const CGTownInstance * obj, const CGHeroInstance * hero) override; diff --git a/server/CQuery.cpp b/server/CQuery.cpp index cdfd90527..d9a0bebc3 100644 --- a/server/CQuery.cpp +++ b/server/CQuery.cpp @@ -374,6 +374,12 @@ bool CGarrisonDialogQuery::blocksPack(const CPack * pack) const if(auto arts = dynamic_ptr_cast(pack)) return !vstd::contains(ourIds, arts->srcHero) || !vstd::contains(ourIds, arts->dstHero); + if(auto art = dynamic_ptr_cast(pack)) + { + if (auto id = boost::apply_visitor(GetEngagedHeroIds(), art->al.artHolder)) + return !vstd::contains(ourIds, *id); + } + if(auto dismiss = dynamic_ptr_cast(pack)) return !vstd::contains(ourIds, dismiss->heroID); diff --git a/server/NetPacksServer.cpp b/server/NetPacksServer.cpp index def5cbc7c..8c249ba9d 100644 --- a/server/NetPacksServer.cpp +++ b/server/NetPacksServer.cpp @@ -146,6 +146,12 @@ void ApplyGhNetPackVisitor::visitAssembleArtifacts(AssembleArtifacts & pack) result = gh.assembleArtifacts(pack.heroID, pack.artifactSlot, pack.assemble, pack.assembleTo); } +void ApplyGhNetPackVisitor::visitEraseArtifactByClient(EraseArtifactByClient & pack) +{ + gh.throwOnWrongPlayer(&pack, pack.al.owningPlayer()); + result = gh.eraseArtifactByClient(pack.al); +} + void ApplyGhNetPackVisitor::visitBuyArtifact(BuyArtifact & pack) { gh.throwOnWrongOwner(&pack, pack.hid); diff --git a/server/ServerNetPackVisitors.h b/server/ServerNetPackVisitors.h index 47aff3c12..a9ed4595b 100644 --- a/server/ServerNetPackVisitors.h +++ b/server/ServerNetPackVisitors.h @@ -47,6 +47,7 @@ public: virtual void visitExchangeArtifacts(ExchangeArtifacts & pack) override; virtual void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) override; virtual void visitAssembleArtifacts(AssembleArtifacts & pack) override; + virtual void visitEraseArtifactByClient(EraseArtifactByClient & pack) override; virtual void visitBuyArtifact(BuyArtifact & pack) override; virtual void visitTradeOnMarketplace(TradeOnMarketplace & pack) override; virtual void visitSetFormation(SetFormation & pack) override;