1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-06 09:09:40 +02:00

Fix possible overflow errors on leveling up beyond int64_t limit

- added separate giveExperience method instead of weird changePrimSkill
- experience is now always used in form of int64_t
- max supported level reduced from 201 to 197 to fit into int64_t
- fixed undefined behavior in experience calculation
This commit is contained in:
Ivan Savenko
2024-01-04 23:57:36 +02:00
parent ceea341bb0
commit edb2ecd751
12 changed files with 87 additions and 59 deletions

View File

@@ -117,7 +117,7 @@ void Rewardable::Interface::grantRewardBeforeLevelup(IGameCallback * cb, const R
for(int i=0; i< info.reward.primary.size(); i++)
cb->changePrimSkill(hero, static_cast<PrimarySkill>(i), info.reward.primary[i], false);
si64 expToGive = 0;
TExpType expToGive = 0;
if (info.reward.heroLevel > 0)
expToGive += VLC->heroh->reqExp(hero->level+info.reward.heroLevel) - VLC->heroh->reqExp(hero->level);
@@ -126,7 +126,7 @@ void Rewardable::Interface::grantRewardBeforeLevelup(IGameCallback * cb, const R
expToGive += hero->calculateXp(info.reward.heroExperience);
if(expToGive)
cb->changePrimSkill(hero, PrimarySkill::EXPERIENCE, expToGive);
cb->giveExperience(hero, expToGive);
}
void Rewardable::Interface::grantRewardAfterLevelup(IGameCallback * cb, const Rewardable::VisitInfo & info, const CArmedInstance * army, const CGHeroInstance * hero) const