From 563a5d53c0e48e98ee1ca9a5f0d5e3fafe3eb336 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Mon, 19 Sep 2016 20:05:57 +0200 Subject: [PATCH 1/2] Update secondary skill handling. Fix issue 2307 Also making secondary skill icon display behavior same as in H3 during popup message. --- lib/mapObjects/CGPandoraBox.cpp | 47 +++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/lib/mapObjects/CGPandoraBox.cpp b/lib/mapObjects/CGPandoraBox.cpp index 8568772d3..a5c3a4fd8 100644 --- a/lib/mapObjects/CGPandoraBox.cpp +++ b/lib/mapObjects/CGPandoraBox.cpp @@ -68,32 +68,51 @@ void CGPandoraBox::giveContentsUpToExp(const CGHeroInstance *h) const if(gainedExp || changesPrimSkill || abilities.size()) { + std::vector unpossessedAbilities; + std::vector unpossessedAbilityLevels; + int abilitiesRequiringSlot = 0; + + //filter out unnecessary secondary skills + for (int i = 0; i < abilities.size(); i++) + { + int curLev = h->getSecSkillLevel(abilities[i]); + bool abilityCanUseSlot = !curLev && ((h->secSkills.size() + abilitiesRequiringSlot) < GameConstants::SKILL_PER_HERO); //limit new abilities to number of slots + + if (abilityCanUseSlot) + abilitiesRequiringSlot++; + + if ( (curLev && curLev < abilityLevels[i]) || abilityCanUseSlot ) + { + unpossessedAbilities.push_back(abilities[i]); + unpossessedAbilityLevels.push_back(abilityLevels[i]); + } + } + TExpType expVal = h->calculateXp(gainedExp); //getText(iw,afterBattle,175,h); //wtf? - iw.text.addTxt(MetaString::ADVOB_TXT, 175); //%s learns something - iw.text.addReplacement(h->name); if(expVal) iw.components.push_back(Component(Component::EXPERIENCE,0,expVal,0)); + for(int i=0; ishowInfoDialog(&iw); + for(int i=0; i 0) //TODO:Create information that box was empty for now, and deliver to CGPandoraBox::giveContentsAfterExp + { + iw.text.addTxt(MetaString::ADVOB_TXT, 175); //%s learns something + iw.text.addReplacement(h->name); + cb->showInfoDialog(&iw); + } //give sec skills - for(int i=0; igetSecSkillLevel(abilities[i]); + for (int i = 0; ichangeSecSkill(h, unpossessedAbilities[i], unpossessedAbilityLevels[i],true); - if( (curLev && curLev < abilityLevels[i]) || (h->canLearnSkill() )) - { - cb->changeSecSkill(h,abilities[i],abilityLevels[i],true); - } - } + assert(h->secSkills.size() <= GameConstants::SKILL_PER_HERO); //give prim skills for(int i=0; i Date: Tue, 20 Sep 2016 12:40:58 +0200 Subject: [PATCH 2/2] Improve pandora box secondary skill handling --- lib/mapObjects/CGPandoraBox.cpp | 54 +++++++++++++++------------------ 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/lib/mapObjects/CGPandoraBox.cpp b/lib/mapObjects/CGPandoraBox.cpp index a5c3a4fd8..b10e818e3 100644 --- a/lib/mapObjects/CGPandoraBox.cpp +++ b/lib/mapObjects/CGPandoraBox.cpp @@ -65,32 +65,32 @@ void CGPandoraBox::giveContentsUpToExp(const CGHeroInstance *h) const break; } } + + std::vector> unpossessedAbilities; //ability + ability level + int abilitiesRequiringSlot = 0; - if(gainedExp || changesPrimSkill || abilities.size()) + //filter out unnecessary secondary skills + for (int i = 0; i < abilities.size(); i++) { - std::vector unpossessedAbilities; - std::vector unpossessedAbilityLevels; - int abilitiesRequiringSlot = 0; + int curLev = h->getSecSkillLevel(abilities[i]); + bool abilityCanUseSlot = !curLev && ((h->secSkills.size() + abilitiesRequiringSlot) < GameConstants::SKILL_PER_HERO); //limit new abilities to number of slots - //filter out unnecessary secondary skills - for (int i = 0; i < abilities.size(); i++) + if (abilityCanUseSlot) + abilitiesRequiringSlot++; + + if ((curLev && curLev < abilityLevels[i]) || abilityCanUseSlot) { - int curLev = h->getSecSkillLevel(abilities[i]); - bool abilityCanUseSlot = !curLev && ((h->secSkills.size() + abilitiesRequiringSlot) < GameConstants::SKILL_PER_HERO); //limit new abilities to number of slots - - if (abilityCanUseSlot) - abilitiesRequiringSlot++; - - if ( (curLev && curLev < abilityLevels[i]) || abilityCanUseSlot ) - { - unpossessedAbilities.push_back(abilities[i]); - unpossessedAbilityLevels.push_back(abilityLevels[i]); - } + unpossessedAbilities.push_back({ abilities[i], abilityLevels[i] }); } - + } + + if(gainedExp || changesPrimSkill || unpossessedAbilities.size()) + { TExpType expVal = h->calculateXp(gainedExp); //getText(iw,afterBattle,175,h); //wtf? - + iw.text.addTxt(MetaString::ADVOB_TXT, 175); //%s learns something + iw.text.addReplacement(h->name); + if(expVal) iw.components.push_back(Component(Component::EXPERIENCE,0,expVal,0)); @@ -98,19 +98,14 @@ void CGPandoraBox::giveContentsUpToExp(const CGHeroInstance *h) const if(primskills[i]) iw.components.push_back(Component(Component::PRIM_SKILL,i,primskills[i],0)); - for(int i=0; i 0) //TODO:Create information that box was empty for now, and deliver to CGPandoraBox::giveContentsAfterExp - { - iw.text.addTxt(MetaString::ADVOB_TXT, 175); //%s learns something - iw.text.addReplacement(h->name); - cb->showInfoDialog(&iw); - } + cb->showInfoDialog(&iw); //give sec skills - for (int i = 0; ichangeSecSkill(h, unpossessedAbilities[i], unpossessedAbilityLevels[i],true); + for (auto abilityData : unpossessedAbilities) + cb->changeSecSkill(h, abilityData.first, abilityData.second, true); assert(h->secSkills.size() <= GameConstants::SKILL_PER_HERO); @@ -125,6 +120,7 @@ void CGPandoraBox::giveContentsUpToExp(const CGHeroInstance *h) const if(expVal) cb->changePrimSkill(h, PrimarySkill::EXPERIENCE, expVal, false); } + //else { } //TODO:Create information that box was empty for now, and deliver to CGPandoraBox::giveContentsAfterExp or refactor if(!cb->isVisitCoveredByAnotherQuery(this, h)) giveContentsAfterExp(h);