From 79982c4ad45bc1f27c187a433a6fa93c58173315 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 9 May 2023 16:48:52 +0300 Subject: [PATCH] Fix broken bonuses due to calling PutArtifact before NewArtifact --- lib/NetPacksLib.cpp | 3 +++ server/CGameHandler.cpp | 28 +++++++++++++++++++--------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 04ddb1088..64b1b8b49 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -1793,6 +1793,9 @@ void BulkSmartRebalanceStacks::applyGs(CGameState * gs) void PutArtifact::applyGs(CGameState *gs) { assert(art->canBePutAt(al)); + // Ensure that artifact has been correctly added via NewArtifact pack + assert(vstd::contains(gs->map->artInstances, art)); + assert(!art->getParentNodes().empty()); art->putAt(al); //al.hero->putArtifact(al.slot, art); } diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 7234863ed..d97bc623f 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -6793,8 +6793,21 @@ void CGameHandler::putArtifact(const ArtifactLocation &al, const CArtifactInstan bool CGameHandler::giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact * artType, ArtifactPosition pos) { assert(artType); - if(pos != ArtifactPosition::FIRST_AVAILABLE && !ArtifactUtils::isSlotBackpack(pos)) + + if(pos == ArtifactPosition::FIRST_AVAILABLE) + { + if(!artType->canBePutAt(h, ArtifactUtils::getArtAnyPosition(h, artType->getId()))) + COMPLAIN_RET("Cannot put artifact in that slot!"); + } + else if(ArtifactUtils::isSlotBackpack(pos)) + { + if(!artType->canBePutAt(h, ArtifactUtils::getArtBackpackPosition(h, artType->getId()))) + COMPLAIN_RET("Cannot put artifact in that slot!"); + } + else + { COMPLAIN_RET_FALSE_IF(!artType->canBePutAt(h, pos, false), "Cannot put artifact in that slot!"); + } CArtifactInstance * newArtInst = nullptr; if(artType->canBeDisassembled()) @@ -6803,18 +6816,15 @@ bool CGameHandler::giveHeroNewArtifact(const CGHeroInstance * h, const CArtifact newArtInst = new CArtifactInstance(); newArtInst->artType = artType; // *NOT* via settype -> all bonus-related stuff must be done by NewArtifact apply + + NewArtifact na; + na.art = newArtInst; + sendAndApply(&na); // -> updates a!!!, will create a on other machines + if(giveHeroArtifact(h, newArtInst, pos)) - { - NewArtifact na; - na.art = newArtInst; - sendAndApply(&na); // -> updates a!!!, will create a on other machines return true; - } else - { - delete newArtInst; return false; - } } void CGameHandler::setBattleResult(BattleResult::EResult resultType, int victoriusSide)