Hooks
static bool BeforeCvGame_GetCompetitiveSpawnUnitType(CvGame* self, PlayerTypes ePlayer, bool bIncludeUUs, bool bIncludeRanged, bool bIncludeShips, UnitTypes& result);static void AfterCvGame_GetCompetitiveSpawnUnitType(CvGame* self, PlayerTypes ePlayer, bool bIncludeUUs, bool bIncludeRanged, bool bIncludeShips, UnitTypes& result);static UnitTypes ReplaceCvGame_GetCompetitiveSpawnUnitType(UnitTypes (*original)(CvGame*, PlayerTypes, bool, bool, bool), CvGame* self, PlayerTypes ePlayer, bool bIncludeUUs, bool bIncludeRanged, bool bIncludeShips);CivRegisterBefore<CivHooks::CvGame_GetCompetitiveSpawnUnitType>(host, &BeforeCvGame_GetCompetitiveSpawnUnitType);CivRegisterAfter<CivHooks::CvGame_GetCompetitiveSpawnUnitType>(host, &AfterCvGame_GetCompetitiveSpawnUnitType);CivRegisterReplace<CivHooks::CvGame_GetCompetitiveSpawnUnitType>(host, &ReplaceCvGame_GetCompetitiveSpawnUnitType);
Code
7915/// Pick a random a Unit type that is ranked by unit power and restricted to units available to ePlayer's technology7916#if defined(MOD_GLOBAL_CS_GIFT_SHIPS)7917UnitTypes CvGame::GetCompetitiveSpawnUnitType(PlayerTypes ePlayer, bool bIncludeUUs, bool bIncludeRanged, bool bIncludeShips)7918#else7919UnitTypes CvGame::GetCompetitiveSpawnUnitType(PlayerTypes ePlayer, bool bIncludeUUs, bool bIncludeRanged)7920#endif7921{7922 CvAssertMsg(ePlayer >= 0, "ePlayer is expected to be non-negative (invalid Index)");7923 CvAssertMsg(ePlayer < MAX_CIV_PLAYERS, "ePlayer is expected to be within maximum bounds (invalid Index)");79247925 CvWeightedVector<UnitTypes, SAFE_ESTIMATE_NUM_UNITS, true> veUnitRankings;79267927 // Loop through all Unit Classes7928 for(int iUnitLoop = 0; iUnitLoop < GC.getNumUnitInfos(); iUnitLoop++)7929 {7930 const UnitTypes eLoopUnit = (UnitTypes) iUnitLoop;7931 CvUnitEntry* pkUnitInfo = GC.getUnitInfo(eLoopUnit);7932 if(pkUnitInfo == NULL)7933 {7934 continue;7935 }79367937 bool bValid = (pkUnitInfo->GetCombat() > 0);79387939 // Unit has combat strength, make sure it isn't only defensive (and with no ranged combat ability)7940 if(bValid && pkUnitInfo->GetRange() == 0)7941 {7942 for(int iPromotionLoop = 0; iPromotionLoop < GC.getNumPromotionInfos(); iPromotionLoop++)7943 {7944 const PromotionTypes ePromotion = (PromotionTypes) iPromotionLoop;7945 CvPromotionEntry* pkPromotionInfo = GC.getPromotionInfo(ePromotion);7946 if(pkPromotionInfo)7947 {7948 if(pkUnitInfo->GetFreePromotions(iPromotionLoop))7949 {7950 if(pkPromotionInfo->IsOnlyDefensive())7951 {7952 bValid = false;7953 break;7954 }7955 }7956 }7957 }7958 }7959 if(!bValid)7960 continue;79617962 UnitClassTypes eLoopUnitClass = (UnitClassTypes) pkUnitInfo->GetUnitClassType();7963 CvUnitClassInfo* pkUnitClassInfo = GC.getUnitClassInfo(eLoopUnitClass);79647965 if(pkUnitClassInfo == NULL)7966 {7967 CvAssertMsg(false, "UnitClassInfo is NULL. Please send Anton your save file and version.");7968 continue;7969 }79707971 // Default unit7972 if(eLoopUnit == pkUnitClassInfo->getDefaultUnitIndex())7973 {7974 // Allowed, do nothing7975 }7976 // Unique unit7977 else7978 {7979 if(!bIncludeUUs)7980 {7981 continue;7982 }7983 else7984 {7985 // Cannot be a UU from a civ that is in our game7986 for(int iMajorLoop = 0; iMajorLoop < MAX_PLAYERS; iMajorLoop++) // MAX_PLAYERS so that we look at Barbarian UUs (ie. Brute) as well7987 {7988 PlayerTypes eMajorLoop = (PlayerTypes) iMajorLoop;7989 if(GET_PLAYER(eMajorLoop).isAlive())7990 {7991 UnitTypes eUniqueUnitInGame = (UnitTypes) GET_PLAYER(eMajorLoop).getCivilizationInfo().getCivilizationUnits(eLoopUnitClass);7992 if(eLoopUnit == eUniqueUnitInGame)7993 {7994 bValid = false;7995 break;7996 }7997 }7998 }7999 if(!bValid)8000 continue;8001 }8002 }80038004 // Avoid Recon units8005 if(pkUnitInfo->GetDefaultUnitAIType() == UNITAI_EXPLORE)8006 continue;80078008 // No Ranged units?8009 if(!bIncludeRanged && pkUnitInfo->GetRangedCombat() > 0)8010 continue;80118012 // Must be land Unit8013#if defined(MOD_GLOBAL_CS_GIFT_SHIPS)8014 if(!(pkUnitInfo->GetDomainType() == DOMAIN_LAND || (pkUnitInfo->GetDomainType() == DOMAIN_SEA && bIncludeShips && (GC.getMap().GetAIMapHint() & 5) != 0)))8015#else8016 if(pkUnitInfo->GetDomainType() != DOMAIN_LAND)8017#endif8018 continue;80198020 // Must be able to train this thing8021 if(!GET_PLAYER(ePlayer).canTrain(eLoopUnit, false, false, false, /*bIgnoreUniqueUnitStatus*/ true))8022 continue;80238024 veUnitRankings.push_back(eLoopUnit, pkUnitInfo->GetPower());8025 }80268027 // Choose from weighted unit types8028 veUnitRankings.SortItems();8029 int iNumChoices = GC.getUNIT_SPAWN_NUM_CHOICES();8030 RandomNumberDelegate randFn = MakeDelegate(&GC.getGame(), &CvGame::getJonRandNum);8031 UnitTypes eChosenUnit = veUnitRankings.ChooseFromTopChoices(iNumChoices, &randFn, "Choosing competitive unit from top choices");80328033 return eChosenUnit;8034}