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:
parent
cd8a0c01e4
commit
2b9e074d54
@ -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()
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user