Bazaar developer reference

CvWonderProductionAI::ChooseWonder(bool, bool, int &)

Defined in
CvWonderProductionAI.cpp, line 200
Class
CvWonderProductionAI
Hook name
CivHooks::CvWonderProductionAI_ChooseWonder

Hooks

static bool BeforeCvWonderProductionAI_ChooseWonder(CvWonderProductionAI* self, bool bUseAsyncRandom, bool bAdjustForOtherPlayers, int& iWonderWeight, BuildingTypes& result);static void AfterCvWonderProductionAI_ChooseWonder(CvWonderProductionAI* self, bool bUseAsyncRandom, bool bAdjustForOtherPlayers, int& iWonderWeight, BuildingTypes& result);static BuildingTypes ReplaceCvWonderProductionAI_ChooseWonder(BuildingTypes (*original)(CvWonderProductionAI*, bool, bool, int&), CvWonderProductionAI* self, bool bUseAsyncRandom, bool bAdjustForOtherPlayers, int& iWonderWeight);CivRegisterBefore<CivHooks::CvWonderProductionAI_ChooseWonder>(host, &BeforeCvWonderProductionAI_ChooseWonder);CivRegisterAfter<CivHooks::CvWonderProductionAI_ChooseWonder>(host, &AfterCvWonderProductionAI_ChooseWonder);CivRegisterReplace<CivHooks::CvWonderProductionAI_ChooseWonder>(host, &ReplaceCvWonderProductionAI_ChooseWonder);

Code

199/// Recommend highest-weighted wonder, also return total weight of all buildable wonders200BuildingTypes CvWonderProductionAI::ChooseWonder(bool bUseAsyncRandom, bool bAdjustForOtherPlayers, int& iWonderWeight)201{202	int iBldgLoop;203	int iWeight;204	int iTurnsRequired;205	int iEstimatedProductionPerTurn;206	int iCityLoop;207	RandomNumberDelegate fcn;208	BuildingTypes eSelection;209210	// Use the asynchronous random number generate if "no random" is set211	if(bUseAsyncRandom)212	{213		fcn = MakeDelegate(&GC.getGame(), &CvGame::getAsyncRandNum);214	}215	else216	{217		fcn = MakeDelegate(&GC.getGame(), &CvGame::getJonRandNum);218	}219220	// Reset list of all the possible wonders221	m_Buildables.clear();222223	// Guess which city will be producing this (doesn't matter that much since weights are all relative)224	CvCity* pWonderCity = m_pPlayer->GetCitySpecializationAI()->GetWonderBuildCity();225	if(pWonderCity == NULL)226	{227		pWonderCity = m_pPlayer->firstCity(&iCityLoop);228	}229230	CvAssertMsg(pWonderCity, "Trying to choose the next wonder to build and the player has no cities!");231	if(pWonderCity == NULL)232		return NO_BUILDING;233234	iEstimatedProductionPerTurn = pWonderCity->getCurrentProductionDifference(true, false);235	if(iEstimatedProductionPerTurn < 1)236	{237		iEstimatedProductionPerTurn = 1;238	}239240	// Loop through adding the available wonders241	for(iBldgLoop = 0; iBldgLoop < GC.GetGameBuildings()->GetNumBuildings(); iBldgLoop++)242	{243		const BuildingTypes eBuilding = static_cast<BuildingTypes>(iBldgLoop);244		CvBuildingEntry* pkBuildingInfo = m_pBuildings->GetEntry(eBuilding);245		if(pkBuildingInfo)246		{247			CvBuildingEntry& kBuilding = *pkBuildingInfo;248			const CvBuildingClassInfo& kBuildingClassInfo = kBuilding.GetBuildingClassInfo();249250			// Make sure this wonder can be built now251#if defined(MOD_AI_SMART_V3)252			bool bWonder = MOD_AI_SMART_V3 ? IsWonderNotNationalUnique(kBuilding) : IsWonder(kBuilding);253			if(bWonder && HaveCityToBuild((BuildingTypes)iBldgLoop))254#else255			if(IsWonder(kBuilding) && HaveCityToBuild((BuildingTypes)iBldgLoop))256#endif257			{258				iTurnsRequired = std::max(1, kBuilding.GetProductionCost() / iEstimatedProductionPerTurn);259260				// if we are forced to restart a wonder, give one that has been started already a huge bump261				bool bAlreadyStarted = pWonderCity->GetCityBuildings()->GetBuildingProduction(eBuilding) > 0;262				int iTempWeight = bAlreadyStarted ? m_WonderAIWeights.GetWeight(iBldgLoop) * 25 : m_WonderAIWeights.GetWeight(iBldgLoop);263264				// Don't build the UN if you aren't going for the diplo victory265				if(pkBuildingInfo->IsDiplomaticVoting())266				{267					int iVotesNeededToWin = GC.getGame().GetVotesNeededForDiploVictory();268					int iSecuredVotes = 0;269					TeamTypes myTeamID = m_pPlayer->getTeam();270					PlayerTypes myPlayerID = m_pPlayer->GetID();271272					// Loop through Players to see if they'll vote for this player273					PlayerTypes eLoopPlayer;274					TeamTypes eLoopTeam;275					for(int iPlayerLoop = 0; iPlayerLoop < MAX_CIV_PLAYERS; iPlayerLoop++)276					{277						eLoopPlayer = (PlayerTypes) iPlayerLoop;278279						if(GET_PLAYER(eLoopPlayer).isAlive())280						{281							eLoopTeam = GET_PLAYER(eLoopPlayer).getTeam();282283							// Liberated?284							if(GET_TEAM(eLoopTeam).GetLiberatedByTeam() == myTeamID)285							{286								iSecuredVotes++;287							}288289							// Minor civ?290							else if(GET_PLAYER(eLoopPlayer).isMinorCiv())291							{292								// Best Relations?293								if(GET_PLAYER(eLoopPlayer).GetMinorCivAI()->GetAlly() == myPlayerID)294								{295									iSecuredVotes++;296								}297							}298						}299					}300301					int iNumberOfPlayersWeNeedToBuyOff = MAX(0, iVotesNeededToWin - iSecuredVotes);302303					if(!m_pPlayer->GetDiplomacyAI() || !m_pPlayer->GetDiplomacyAI()->IsGoingForDiploVictory() || m_pPlayer->GetTreasury()->GetGold() < iNumberOfPlayersWeNeedToBuyOff * 500 )304					{305						iTempWeight = 0;306					}307				}308309				iWeight = CityStrategyAIHelpers::ReweightByTurnsLeft(iTempWeight, iTurnsRequired);310311				if(bAdjustForOtherPlayers && ::isWorldWonderClass(kBuildingClassInfo))312				{313					// Adjust weight for this wonder down based on number of other players currently working on it314					int iNumOthersConstructing = 0;315					for(int iPlayerLoop = 0; iPlayerLoop < MAX_MAJOR_CIVS; iPlayerLoop++)316					{317						PlayerTypes eLoopPlayer = (PlayerTypes) iPlayerLoop;318						if(GET_PLAYER(eLoopPlayer).getBuildingClassMaking((BuildingClassTypes)kBuilding.GetBuildingClassType()) > 0)319						{320							iNumOthersConstructing++;321						}322					}323					iWeight = iWeight / (1 + iNumOthersConstructing);324				}325326				m_Buildables.push_back(iBldgLoop, iWeight);327			}328		}329	}330331	// Sort items and grab the first one332	if(m_Buildables.size() > 0)333	{334		m_Buildables.SortItems();335		LogPossibleWonders();336337		if(m_Buildables.GetTotalWeight() > 0)338		{339			int iNumChoices = GC.getGame().getHandicapInfo().GetCityProductionNumOptions();340			eSelection = (BuildingTypes)m_Buildables.ChooseFromTopChoices(iNumChoices, &fcn, "Choosing wonder from Top Choices");341			iWonderWeight = m_Buildables.GetTotalWeight();342			return eSelection;343		}344345		// Nothing with any weight346		else347		{348			return NO_BUILDING;349		}350	}351352	// Unless we didn't find any353	else354	{355		return NO_BUILDING;356	}357}

Calls

Called by