1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

- implements level limit (Mantis #1620)

- added workaround to weird bug where vcmi fails to find objects for
win/loss conditions
This commit is contained in:
Ivan Savenko 2014-01-01 16:12:53 +00:00
parent cd8a0c01e4
commit 2b9e074d54
2 changed files with 46 additions and 3 deletions

View File

@ -312,9 +312,30 @@ const CGObjectInstance * CMap::getObjectiveObjectFrom(int3 pos, Obj::EObj type)
if (object->ID == type)
return object;
}
// possibly may trigger for empty placeholders in campaigns
logGlobal->warnStream() << "Failed to find object of type " << int(type) << " at " << pos;
return nullptr;
// There is weird bug because of which sometimes heroes will not be found properly despite having correct position
// Try to workaround that and find closest object that we can use
logGlobal->errorStream() << "Failed to find object of type " << int(type) << " at " << pos;
logGlobal->errorStream() << "Will try to find closest matching object";
CGObjectInstance * bestMatch = nullptr;
for (CGObjectInstance * object : objects)
{
if (object->ID == type)
{
if (bestMatch == nullptr)
bestMatch = object;
else
{
if (object->pos.dist2d(pos) < bestMatch->pos.dist2d(pos))
bestMatch = object;// closer than one we already found
}
}
}
assert(bestMatch != nullptr); // if this happens - victory conditions or map itself is very, very broken
logGlobal->errorStream() << "Will use " << bestMatch->getHoverText() << " from " << bestMatch->pos;
return bestMatch;
}
void CMap::checkForObjectives()

View File

@ -373,6 +373,27 @@ void CGameHandler::expGiven(const CGHeroInstance *hero)
void CGameHandler::changePrimSkill(const CGHeroInstance * hero, PrimarySkill::PrimarySkill which, si64 val, bool abs)
{
if (which == PrimarySkill::EXPERIENCE) // Check if scenario limit reached
{
if (gs->map->levelLimit != 0)
{
TExpType expLimit = VLC->heroh->reqExp(gs->map->levelLimit);
TExpType resultingExp = abs ? val : hero->exp + val;
if (resultingExp > expLimit)
{
// set given experience to max possible, but don't decrease if hero already over top
abs = true;
val = std::max(expLimit, hero->exp);
InfoWindow iw;
iw.player = hero->tempOwner;
iw.text.addTxt(MetaString::GENERAL_TXT, 1); //can gain no more XP
iw.text.addReplacement(hero->name);
sendAndApply(&iw);
}
}
}
SetPrimSkill sps;
sps.id = hero->id;
sps.which = which;
@ -385,6 +406,7 @@ void CGameHandler::changePrimSkill(const CGHeroInstance * hero, PrimarySkill::Pr
{
if(hero->commander && hero->commander->alive)
{
//FIXME: trim experience according to map limit?
SetCommanderProperty scp;
scp.heroid = hero->id;
scp.which = SetCommanderProperty::EXPERIENCE;