mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +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:
		| @@ -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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user