|
@@ -5418,50 +5418,89 @@ void CGameHandler::visitObjectOnTile(const TerrainTile &t, const CGHeroInstance
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-bool CGameHandler::sacrificeCreatures(const IMarket *market, const CGHeroInstance *hero, SlotID slot, ui32 count)
|
|
|
+bool CGameHandler::sacrificeCreatures(const IMarket *market, const CGHeroInstance *hero, std::vector<SlotID> slot, std::vector<ui32> count)
|
|
|
{
|
|
|
if (!hero)
|
|
|
COMPLAIN_RET("You need hero to sacrifice creature!");
|
|
|
|
|
|
- int oldCount = hero->getStackCount(slot);
|
|
|
+ int expSum = 0;
|
|
|
+ auto finish = [this, &hero, &expSum]()
|
|
|
+ {
|
|
|
+ changePrimSkill(hero, PrimarySkill::EXPERIENCE, hero->calculateXp(expSum));
|
|
|
+ };
|
|
|
+
|
|
|
+ for (int i = 0; i < slot.size(); ++i)
|
|
|
+ {
|
|
|
+ int oldCount = hero->getStackCount(slot[i]);
|
|
|
+
|
|
|
+ if (oldCount < count[i])
|
|
|
+ {
|
|
|
+ finish();
|
|
|
+ COMPLAIN_RET("Not enough creatures to sacrifice!")
|
|
|
+ }
|
|
|
+ else if (oldCount == count[i] && hero->stacksCount() == 1 && hero->needsLastStack())
|
|
|
+ {
|
|
|
+ finish();
|
|
|
+ COMPLAIN_RET("Cannot sacrifice last creature!");
|
|
|
+ }
|
|
|
|
|
|
- if (oldCount < count)
|
|
|
- COMPLAIN_RET("Not enough creatures to sacrifice!")
|
|
|
- else if (oldCount == count && hero->stacksCount() == 1 && hero->needsLastStack())
|
|
|
- COMPLAIN_RET("Cannot sacrifice last creature!");
|
|
|
+ int crid = hero->getStack(slot[i]).type->idNumber;
|
|
|
|
|
|
- int crid = hero->getStack(slot).type->idNumber;
|
|
|
+ changeStackCount(StackLocation(hero, slot[i]), -count[i]);
|
|
|
|
|
|
- changeStackCount(StackLocation(hero, slot), -count);
|
|
|
+ int dump, exp;
|
|
|
+ market->getOffer(crid, 0, dump, exp, EMarketMode::CREATURE_EXP);
|
|
|
+ exp *= count[i];
|
|
|
+ expSum += exp;
|
|
|
+ }
|
|
|
|
|
|
- int dump, exp;
|
|
|
- market->getOffer(crid, 0, dump, exp, EMarketMode::CREATURE_EXP);
|
|
|
- exp *= count;
|
|
|
- changePrimSkill(hero, PrimarySkill::EXPERIENCE, hero->calculateXp(exp));
|
|
|
+ finish();
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-bool CGameHandler::sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, ArtifactPosition slot)
|
|
|
+bool CGameHandler::sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, std::vector<ArtifactPosition> slot)
|
|
|
{
|
|
|
if (!hero)
|
|
|
COMPLAIN_RET("You need hero to sacrifice artifact!");
|
|
|
|
|
|
- ArtifactLocation al(hero, slot);
|
|
|
- const CArtifactInstance *a = al.getArt();
|
|
|
+ int expSum = 0;
|
|
|
+ auto finish = [this, &hero, &expSum]()
|
|
|
+ {
|
|
|
+ changePrimSkill(hero, PrimarySkill::EXPERIENCE, expSum);
|
|
|
+ };
|
|
|
+
|
|
|
+ for (int i = 0; i < slot.size(); ++i)
|
|
|
+ {
|
|
|
+ ArtifactLocation al(hero, slot[i]);
|
|
|
+ const CArtifactInstance *a = al.getArt();
|
|
|
+
|
|
|
+ if (!a)
|
|
|
+ {
|
|
|
+ finish();
|
|
|
+ COMPLAIN_RET("Cannot find artifact to sacrifice!");
|
|
|
+ }
|
|
|
+
|
|
|
+ const CArtifactInstance * art = hero->getArt(slot[i]);
|
|
|
+
|
|
|
+ if (!art)
|
|
|
+ {
|
|
|
+ finish();
|
|
|
+ COMPLAIN_RET("No artifact at position to sacrifice!");
|
|
|
+ }
|
|
|
+
|
|
|
+ si32 typId = art->artType->id;
|
|
|
+ int dmp, expToGive;
|
|
|
|
|
|
- COMPLAIN_RET_FALSE_IF(!a,"Cannot find artifact to sacrifice!");
|
|
|
+ m->getOffer(typId, 0, dmp, expToGive, EMarketMode::ARTIFACT_EXP);
|
|
|
|
|
|
- int dmp, expToGive;
|
|
|
- const CArtifactInstance * art = hero->getArt(slot);
|
|
|
- COMPLAIN_RET_FALSE_IF((!art), "No artifact at position to sacrifice!");
|
|
|
+ expSum += expToGive;
|
|
|
|
|
|
- si32 typId = art->artType->id;
|
|
|
+ removeArtifact(al);
|
|
|
+ }
|
|
|
|
|
|
- m->getOffer(typId, 0, dmp, expToGive, EMarketMode::ARTIFACT_EXP);
|
|
|
+ finish();
|
|
|
|
|
|
- removeArtifact(al);
|
|
|
- changePrimSkill(hero, PrimarySkill::EXPERIENCE, expToGive);
|
|
|
return true;
|
|
|
}
|
|
|
|