From 8a81b3013fa7a01e56b5f7f74f4ef7bf1c25d93e Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Mon, 31 Jul 2023 22:06:54 +0300 Subject: [PATCH] Fixed transferring of artifacts from backpack in campaigns --- lib/gameState/CGameStateCampaign.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/gameState/CGameStateCampaign.cpp b/lib/gameState/CGameStateCampaign.cpp index d271f887c..0d8729a94 100644 --- a/lib/gameState/CGameStateCampaign.cpp +++ b/lib/gameState/CGameStateCampaign.cpp @@ -118,28 +118,35 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(std::vectorartifactsInBackpack.size(); - for (size_t i = 0; i < totalArts; i++ ) + auto const & checkAndRemoveArtifact = [&](const ArtifactPosition & artifactPosition ) { - auto artifactPosition = ArtifactPosition((si32)i); if(artifactPosition == ArtifactPosition::SPELLBOOK) - continue; // do not handle spellbook this way + return; // do not handle spellbook this way const ArtSlotInfo *info = hero->getSlot(artifactPosition); if(!info) - continue; + return; // TODO: why would there be nullptr artifacts? const CArtifactInstance *art = info->artifact; if(!art) - continue; + return; bool takeable = travelOptions.artifactsKeptByHero.count(art->artType->getId()); ArtifactLocation al(hero, artifactPosition); if(!takeable && !al.getSlot()->locked) //don't try removing locked artifacts -> it crashes #1719 al.removeArtifact(); - } + }; + + // process on copy - removal of artifact will invalidate container + auto artifactsWorn = hero->artifactsWorn; + for (auto const & art : artifactsWorn) + checkAndRemoveArtifact(art.first); + + // process in reverse - removal of artifact will shift all artifacts after this one + for(int slotNumber = hero->artifactsInBackpack.size() - 1; slotNumber >= 0; slotNumber--) + checkAndRemoveArtifact(ArtifactPosition(GameConstants::BACKPACK_START + slotNumber)); } }