From 520f690d35a869a268ca7237afa581bcb176ebd2 Mon Sep 17 00:00:00 2001 From: Ivan Savenko Date: Tue, 28 May 2024 14:21:29 +0000 Subject: [PATCH] Fix transfer of non-first artifacts in backpack if hero does not transfers as well --- lib/gameState/CGameStateCampaign.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/gameState/CGameStateCampaign.cpp b/lib/gameState/CGameStateCampaign.cpp index e044d345b..ea4f6d72e 100644 --- a/lib/gameState/CGameStateCampaign.cpp +++ b/lib/gameState/CGameStateCampaign.cpp @@ -111,19 +111,19 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(const CampaignTravel & tr //trimming artifacts for(auto & hero : campaignHeroReplacements) { - const auto & checkAndRemoveArtifact = [&](const ArtifactPosition & artifactPosition) + const auto & checkAndRemoveArtifact = [&](const ArtifactPosition & artifactPosition) -> bool { if(artifactPosition == ArtifactPosition::SPELLBOOK) - return; // do not handle spellbook this way + return false; // do not handle spellbook this way const ArtSlotInfo *info = hero.hero->getSlot(artifactPosition); if(!info) - return; + return false; // TODO: why would there be nullptr artifacts? const CArtifactInstance *art = info->artifact; if(!art) - return; + return false; bool takeable = travelOptions.artifactsKeptByHero.count(art->artType->getId()); @@ -132,7 +132,11 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(const CampaignTravel & tr ArtifactLocation al(hero.hero->id, artifactPosition); if(!takeable && !hero.hero->getSlot(al.slot)->locked) //don't try removing locked artifacts -> it crashes #1719 + { hero.hero->getArt(al.slot)->removeFrom(*hero.hero, al.slot); + return true; + } + return false; }; // process on copy - removal of artifact will invalidate container @@ -140,9 +144,13 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(const CampaignTravel & tr for(const auto & art : artifactsWorn) checkAndRemoveArtifact(art.first); - // process in reverse - removal of artifact will shift all artifacts after this one - for(int slotNumber = hero.hero->artifactsInBackpack.size() - 1; slotNumber >= 0; slotNumber--) - checkAndRemoveArtifact(ArtifactPosition::BACKPACK_START + slotNumber); + for (int slotNumber = 0; slotNumber < hero.hero->artifactsInBackpack.size();) + { + if (checkAndRemoveArtifact(ArtifactPosition::BACKPACK_START + slotNumber)) + continue; // artifact was removed and backpack slots were shifted -> test this slot again + else + slotNumber++; // artifact was kept for transfer -> test next slot + }; } }