Bazaar developer reference

CvGame::GetRandomUniqueUnitType(bool, bool, bool, bool)

Defined in
CvGame.cpp, line 8096
Class
CvGame
Hook name
CivHooks::CvGame_GetRandomUniqueUnitType

Hooks

static bool BeforeCvGame_GetRandomUniqueUnitType(CvGame* self, bool bIncludeCivsInGame, bool bIncludeStartEra, bool bIncludeOldEras, bool bIncludeRanged, UnitTypes& result);static void AfterCvGame_GetRandomUniqueUnitType(CvGame* self, bool bIncludeCivsInGame, bool bIncludeStartEra, bool bIncludeOldEras, bool bIncludeRanged, UnitTypes& result);static UnitTypes ReplaceCvGame_GetRandomUniqueUnitType(UnitTypes (*original)(CvGame*, bool, bool, bool, bool), CvGame* self, bool bIncludeCivsInGame, bool bIncludeStartEra, bool bIncludeOldEras, bool bIncludeRanged);CivRegisterBefore<CivHooks::CvGame_GetRandomUniqueUnitType>(host, &BeforeCvGame_GetRandomUniqueUnitType);CivRegisterAfter<CivHooks::CvGame_GetRandomUniqueUnitType>(host, &AfterCvGame_GetRandomUniqueUnitType);CivRegisterReplace<CivHooks::CvGame_GetRandomUniqueUnitType>(host, &ReplaceCvGame_GetRandomUniqueUnitType);

Code

8096UnitTypes CvGame::GetRandomUniqueUnitType(bool bIncludeCivsInGame, bool bIncludeStartEra, bool bIncludeOldEras, bool bIncludeRanged)8097{8098	// Find the unique units that have already been assigned8099	std::set<UnitTypes> setUniquesAlreadyAssigned;8100	for(int iMinorLoop = MAX_MAJOR_CIVS; iMinorLoop < MAX_CIV_PLAYERS; iMinorLoop++)8101	{8102		PlayerTypes eMinorLoop = (PlayerTypes) iMinorLoop;8103		CvPlayer* pMinorLoop = &GET_PLAYER(eMinorLoop);8104		if(pMinorLoop && pMinorLoop->isEverAlive())8105		{8106			UnitTypes eUniqueUnit = pMinorLoop->GetMinorCivAI()->GetUniqueUnit();8107			if(eUniqueUnit != NO_UNIT)8108			{8109				setUniquesAlreadyAssigned.insert(eUniqueUnit);8110			}8111		}8112	}8113	8114	CvWeightedVector<UnitTypes, SAFE_ESTIMATE_NUM_UNITS, true> veUnitRankings;81158116	// Loop through all Unit Classes8117	for(int iUnitLoop = 0; iUnitLoop < GC.getNumUnitInfos(); iUnitLoop++)8118	{8119		const UnitTypes eLoopUnit = (UnitTypes) iUnitLoop;8120		CvUnitEntry* pkUnitInfo = GC.getUnitInfo(eLoopUnit);8121		if(pkUnitInfo == NULL)8122		{8123			continue;8124		}81258126#if defined(MOD_GLOBAL_EXCLUDE_FROM_GIFTS)8127		if (MOD_GLOBAL_EXCLUDE_FROM_GIFTS) {8128			if (pkUnitInfo->IsNoMinorGifts()) {8129				continue;8130			}8131		}8132#endif81338134		bool bValid = (pkUnitInfo->GetCombat() > 0);81358136		// Unit has combat strength, make sure it isn't only defensive (and with no ranged combat ability)8137		if(bValid && pkUnitInfo->GetRange() == 0)8138		{8139			for(int iPromotionLoop = 0; iPromotionLoop < GC.getNumPromotionInfos(); iPromotionLoop++)8140			{8141				const PromotionTypes ePromotion = (PromotionTypes) iPromotionLoop;8142				CvPromotionEntry* pkPromotionInfo = GC.getPromotionInfo(ePromotion);8143				if(pkPromotionInfo)8144				{8145					if(pkUnitInfo->GetFreePromotions(iPromotionLoop))8146					{8147						if(pkPromotionInfo->IsOnlyDefensive())8148						{8149							bValid = false;8150							break;8151						}8152					}8153				}8154			}8155		}8156		if(!bValid)8157			continue;81588159		UnitClassTypes eLoopUnitClass = (UnitClassTypes) pkUnitInfo->GetUnitClassType();8160		CvUnitClassInfo* pkUnitClassInfo = GC.getUnitClassInfo(eLoopUnitClass);81618162		if(pkUnitClassInfo == NULL)8163		{8164			CvAssertMsg(false, "UnitClassInfo is NULL. Please send Anton your save file and version.");8165			continue;8166		}81678168		// We only want unique units8169		if(eLoopUnit == pkUnitClassInfo->getDefaultUnitIndex())8170			continue;81718172		// Is it a unique unit from a civ that is in our game?8173		if (!bIncludeCivsInGame)8174		{8175			for(int iMajorLoop = 0; iMajorLoop < MAX_PLAYERS; iMajorLoop++)  // MAX_PLAYERS so that we look at Barbarian UUs (ie. Brute) as well8176			{8177				PlayerTypes eMajorLoop = (PlayerTypes) iMajorLoop;8178				if(GET_PLAYER(eMajorLoop).isAlive())8179				{8180					UnitTypes eUniqueUnitInGame = (UnitTypes) GET_PLAYER(eMajorLoop).getCivilizationInfo().getCivilizationUnits(eLoopUnitClass);8181					if(eLoopUnit == eUniqueUnitInGame)8182					{8183						bValid = false;8184						break;8185					}8186				}8187			}8188		}8189		if(!bValid)8190			continue;81918192		// Avoid Recon units8193		if(pkUnitInfo->GetDefaultUnitAIType() == UNITAI_EXPLORE)8194			continue;81958196		// No Ranged units?8197		if(!bIncludeRanged && pkUnitInfo->GetRangedCombat() > 0)8198			continue;81998200		// Must be land Unit8201		if(pkUnitInfo->GetDomainType() != DOMAIN_LAND)8202			continue;82038204		// Technology level8205		TechTypes ePrereqTech = (TechTypes) pkUnitInfo->GetPrereqAndTech();8206		EraTypes ePrereqEra = NO_ERA;8207		if (ePrereqTech != NO_TECH)8208		{8209			CvTechEntry* pkTechInfo = GC.getTechInfo(ePrereqTech);8210			CvAssertMsg(pkTechInfo, "Tech info not found when picking unique unit for minor civ. Please send Anton your save file and version!");8211			if (pkTechInfo)8212			{8213				ePrereqEra = (EraTypes) pkTechInfo->GetEra();8214			}8215		}82168217		if (ePrereqEra == getStartEra())8218		{8219			if (!bIncludeStartEra)8220				continue;8221		}8222		else if (ePrereqEra < getStartEra()) // Assumption: NO_ERA < 08223		{8224			if (!bIncludeOldEras)8225				continue;8226		}82278228		// Is this Unit already assigned to another minor civ?8229		if (setUniquesAlreadyAssigned.count(eLoopUnit) > 0)8230			continue;82318232		veUnitRankings.push_back(eLoopUnit, 1);8233	}82348235	UnitTypes eChosenUnit = NO_UNIT;82368237	if (veUnitRankings.size() > 0)8238	{8239		veUnitRankings.SortItems();8240		RandomNumberDelegate randFn = MakeDelegate(&GC.getGame(), &CvGame::getJonRandNum);8241		eChosenUnit = veUnitRankings.ChooseByWeight(&randFn, "Choosing random unique unit for minor civ");8242	}82438244	return eChosenUnit;8245}

Calls

Called by