Bazaar developer reference

CvMinorCivAI::CalculateBullyMetric(PlayerTypes, bool, CvString *)

Defined in
CvMinorCivAI.cpp, line 8981
Class
CvMinorCivAI
Hook name
CivHooks::CvMinorCivAI_CalculateBullyMetric

Hooks

static bool BeforeCvMinorCivAI_CalculateBullyMetric(CvMinorCivAI* self, PlayerTypes eBullyPlayer, bool bForUnit, CvString* sTooltipSink, int& result);static void AfterCvMinorCivAI_CalculateBullyMetric(CvMinorCivAI* self, PlayerTypes eBullyPlayer, bool bForUnit, CvString* sTooltipSink, int& result);static int ReplaceCvMinorCivAI_CalculateBullyMetric(int (*original)(CvMinorCivAI*, PlayerTypes, bool, CvString*), CvMinorCivAI* self, PlayerTypes eBullyPlayer, bool bForUnit, CvString* sTooltipSink);CivRegisterBefore<CivHooks::CvMinorCivAI_CalculateBullyMetric>(host, &BeforeCvMinorCivAI_CalculateBullyMetric);CivRegisterAfter<CivHooks::CvMinorCivAI_CalculateBullyMetric>(host, &AfterCvMinorCivAI_CalculateBullyMetric);CivRegisterReplace<CivHooks::CvMinorCivAI_CalculateBullyMetric>(host, &ReplaceCvMinorCivAI_CalculateBullyMetric);

Code

8978// Calculates a basic score for whether the major can bully this minor based on many factors.8979// Negative score if bully attempt is a failure, zero or positive if success.8980// May be modified after return, if the task is easier or harder (ex. bully a worker vs. bully gold)8981int CvMinorCivAI::CalculateBullyMetric(PlayerTypes eBullyPlayer, bool bForUnit, CvString* sTooltipSink)8982{8983	CvString sFactors = "";89848985	int iScore = 0;8986	const int iFailScore = -300;89878988	CvAssertMsg(GetPlayer()->GetID() != eBullyPlayer, "Minor civ and bully civ not expected to have the same ID!");8989	if(GetPlayer()->GetID() == eBullyPlayer)8990		return iFailScore;89918992	CvAssertMsg(eBullyPlayer >= 0, "eBullyPlayer is expected to be non-negative (invalid Index)");8993	CvAssertMsg(eBullyPlayer < MAX_MAJOR_CIVS, "eBullyPlayer is expected to be within maximum bounds (invalid Index)");8994	if(eBullyPlayer < 0 || eBullyPlayer >= MAX_MAJOR_CIVS)8995		return iFailScore;89968997	// Can't bully the dead8998	if(!GetPlayer()->isAlive())8999		return iFailScore;90009001	// **************************9002	// Global military power ranking of major9003	//9004	// +0 ~ +759005	// **************************9006	CvWeightedVector<PlayerTypes, MAX_MAJOR_CIVS, true> veMilitaryRankings;9007	PlayerTypes eMajorLoop;9008	int iGlobalMilitaryScore = 0;9009	for(int iMajorLoop = 0; iMajorLoop < MAX_MAJOR_CIVS; iMajorLoop++)9010	{9011		eMajorLoop = (PlayerTypes) iMajorLoop;9012		if(GET_PLAYER(eMajorLoop).isAlive() && !GET_PLAYER(eMajorLoop).isMinorCiv())9013		{9014			veMilitaryRankings.push_back(eMajorLoop, GET_PLAYER(eMajorLoop).GetMilitaryMight()); // Don't recalculate within a turn, can cause inconsistency9015		}9016	}9017	CvAssertMsg(veMilitaryRankings.size() > 0, "WeightedVector of military might rankings not expected to be size 0");9018	veMilitaryRankings.SortItems();9019	for(int iRanking = 0; iRanking < veMilitaryRankings.size(); iRanking++)9020	{9021		if(veMilitaryRankings.GetElement(iRanking) == eBullyPlayer)9022		{9023			float fRankRatio = (float)(veMilitaryRankings.size() - iRanking) / (float)(veMilitaryRankings.size());9024			iGlobalMilitaryScore = (int)(fRankRatio * 75); // A score between 75*(1 / num majors alive) and 75, with the highest rank major getting 759025			iScore += iGlobalMilitaryScore;9026			break;9027		}9028	}9029	9030	if (sTooltipSink)9031	{9032		Localization::String strPositiveFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_POSITIVE");9033		strPositiveFactor << iGlobalMilitaryScore;9034		strPositiveFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_GLOBAL_MILITARY";9035		sFactors += strPositiveFactor.toUTF8();9036	}90379038	// **************************9039	// Local military power comparison9040	//9041	// +0 ~ +1259042	// **************************9043	int iComparisonRadius = std::max(GC.getMap().getGridWidth() / 10, 5);9044	CvCity* pMinorCapital = GetPlayer()->getCapitalCity();9045	if(pMinorCapital == NULL)9046		return iFailScore;9047	CvPlot* pMinorCapitalPlot = pMinorCapital->plot();9048	if(pMinorCapitalPlot == NULL)9049		return iFailScore;9050	int iMinorCapitalX = pMinorCapitalPlot->getX();9051	int iMinorCapitalY = pMinorCapitalPlot->getY();9052	int iMinorLocalPower = 0;9053	int iBullyLocalPower = 0;9054	CvPlot* pLoopPlot;9055	IDInfo* pUnitNode;9056	CvUnit* pLoopUnit;90579058	// Include the minor's city power9059	iMinorLocalPower += pMinorCapital->GetPower();90609061	for(int iDX = -iComparisonRadius; iDX <= iComparisonRadius; iDX++)9062	{9063		for(int iDY = -iComparisonRadius; iDY <= iComparisonRadius; iDY++)9064		{9065			pLoopPlot = ::plotXYWithRangeCheck(iMinorCapitalX, iMinorCapitalY, iDX, iDY, iComparisonRadius);90669067			if(pLoopPlot != NULL)9068			{9069				// If there are Units here, loop through them9070				if(pLoopPlot->getNumUnits() > 0)9071				{9072					pUnitNode = pLoopPlot->headUnitNode();90739074					while(pUnitNode != NULL)9075					{9076						pLoopUnit = ::getUnit(*pUnitNode);9077						pUnitNode = pLoopPlot->nextUnitNode(pUnitNode);90789079						// Is a combat unit9080						if(pLoopUnit && pLoopUnit->IsCombatUnit())9081						{9082							if(pLoopUnit->getOwner() == eBullyPlayer)9083							{9084								iBullyLocalPower += pLoopUnit->GetPower();9085							}9086							else if(pLoopUnit->getOwner() == GetPlayer()->GetID())9087							{9088								iMinorLocalPower += pLoopUnit->GetPower();9089							}9090						}9091					}9092				}90939094			}9095		}9096	}9097	float fLocalPowerRatio = (float)iBullyLocalPower / (float)iMinorLocalPower;9098	int iLocalPowerScore = 0;9099	if(fLocalPowerRatio >= 3.0)9100	{9101		iLocalPowerScore += 125;9102	}9103	else if(fLocalPowerRatio >= 2.0)9104	{9105		iLocalPowerScore += 100;9106	}9107	else if(fLocalPowerRatio >= 1.5)9108	{9109		iLocalPowerScore += 75;9110	}9111	else if(fLocalPowerRatio >= 1.0)9112	{9113		iLocalPowerScore += 50;9114	}9115	else if(fLocalPowerRatio >= 0.5)9116	{9117		iLocalPowerScore += 25;9118	}9119	iScore += iLocalPowerScore;9120	9121	if (sTooltipSink)9122	{9123		Localization::String strPositiveFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_POSITIVE");9124		strPositiveFactor << iLocalPowerScore;9125		strPositiveFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_MILITARY_PRESENCE";9126		sFactors += strPositiveFactor.toUTF8();9127	}91289129	// **************************9130	// Social Policies9131	//9132	// Modifier to positive scores9133	// **************************9134	int iPoliciesScore = 0;9135	int iPoliciesMod = GET_PLAYER(eBullyPlayer).GetPlayerPolicies()->GetNumericModifier(POLICYMOD_MINOR_BULLY_SCORE_MODIFIER);9136	if (iPoliciesMod != 0)9137	{9138		iPoliciesScore += iGlobalMilitaryScore;9139		iPoliciesScore += iLocalPowerScore;91409141		iPoliciesScore *= iPoliciesMod;9142		iPoliciesScore /= 100;9143	}9144	if (sTooltipSink && iPoliciesScore != 0)9145	{9146		Localization::String strPositiveFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_POSITIVE");9147		strPositiveFactor << iPoliciesScore;9148		strPositiveFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_GUNBOAT_DIPLOMACY";9149		sFactors += strPositiveFactor.toUTF8();9150	}9151	iScore += iPoliciesScore;91529153	// **************************9154	// Base Reluctance9155	//9156	// -1109157	// **************************9158	const int iBaseReluctanceScore = -110;9159	9160	if (sTooltipSink)9161	{9162		Localization::String strNegativeFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_NEGATIVE");9163		strNegativeFactor << iBaseReluctanceScore;9164		strNegativeFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_BASE_RELUCTANCE";9165		sFactors += strNegativeFactor.toUTF8();9166	}91679168	iScore += iBaseReluctanceScore;91699170	// **************************9171	// Current influence of major9172	//9173	// -999 ~ -09174	// **************************9175	if(GetEffectiveFriendshipWithMajor(eBullyPlayer) < GC.getFRIENDSHIP_THRESHOLD_CAN_BULLY())9176	{9177		int iInfluenceScore = iFailScore;9178		iScore += iInfluenceScore;9179		if (sTooltipSink)9180		{9181			Localization::String strNegativeFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_NEGATIVE");9182			strNegativeFactor << iInfluenceScore;9183			strNegativeFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_LOW_INFLUENCE";9184			sFactors += strNegativeFactor.toUTF8();9185		}9186	}91879188	// **************************9189	// Previous bully attempts9190	//9191	// -300 ~ -09192	// **************************9193	int iLastBullyTurn = GetTurnLastBulliedByMajor(eBullyPlayer);9194	if(iLastBullyTurn >= 0)9195	{9196		if(iLastBullyTurn + 10 >= GC.getGame().getGameTurn())9197		{9198			int iBulliedVeryRecentlyScore = iFailScore;9199			iScore += iBulliedVeryRecentlyScore;9200			if (sTooltipSink)9201			{9202				Localization::String strNegativeFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_NEGATIVE");9203				strNegativeFactor << iBulliedVeryRecentlyScore;9204				strNegativeFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_BULLIED_VERY_RECENTLY";9205				sFactors += strNegativeFactor.toUTF8();9206			}9207		}9208		else if(iLastBullyTurn + 20 >= GC.getGame().getGameTurn())9209		{9210			int iBulliedRecentlyScore = -40;9211			iScore += iBulliedRecentlyScore;9212			if (sTooltipSink)9213			{9214				Localization::String strNegativeFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_NEGATIVE");9215				strNegativeFactor << iBulliedRecentlyScore;9216				strNegativeFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_BULLIED_RECENTLY";9217				sFactors += strNegativeFactor.toUTF8();9218			}9219		}9220	}92219222	// **************************9223	// Tribute type9224	//9225	// -30 ~ -09226	// **************************9227	if (bForUnit)9228	{9229		int iUnitScore = -30;9230		iScore += iUnitScore;9231		if (sTooltipSink)9232		{9233			Localization::String strNegativeFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_NEGATIVE");9234			strNegativeFactor << iUnitScore;9235			strNegativeFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_UNIT_RELUCTANCE";9236			sFactors += strNegativeFactor.toUTF8();9237		}9238	}92399240	// **************************9241	// City-State population9242	//9243	// -300 ~ -09244	// **************************9245	if (bForUnit)9246	{9247		if (GetPlayer()->getCapitalCity() == NULL || GetPlayer()->getCapitalCity()->getPopulation() < 4)9248		{9249			int iPopulationScore = iFailScore;9250			iScore += iPopulationScore;9251			if (sTooltipSink)9252			{9253				Localization::String strNegativeFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_NEGATIVE");9254				strNegativeFactor << iPopulationScore;9255				strNegativeFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_LOW_POPULATION";9256				sFactors += strNegativeFactor.toUTF8();9257			}9258		}9259	}92609261	// **************************9262	// Passive Support from other majors9263	//9264	// -10 ~ -09265	// **************************9266	if(GetAlly() != NO_PLAYER && GetAlly() != eBullyPlayer)9267	{9268		int iAllyScore = -10;9269		iScore += iAllyScore;9270		if (sTooltipSink)9271		{9272			Localization::String strNegativeFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_NEGATIVE");9273			strNegativeFactor << iAllyScore;9274			strNegativeFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_ALLIES";9275			sFactors += strNegativeFactor.toUTF8();9276		}9277	}92789279	// **************************9280	// Pledges of Protection from other majors9281	//9282	// -20 ~ -09283	// **************************9284	for(int iMajorLoop = 0; iMajorLoop < MAX_MAJOR_CIVS; iMajorLoop++)9285	{9286		int iProtectionScore = 0;9287		eMajorLoop = (PlayerTypes) iMajorLoop;9288		if(eMajorLoop != eBullyPlayer && IsProtectedByMajor(eMajorLoop))9289		{9290			iProtectionScore += -20;9291			iScore += iProtectionScore;9292			if (sTooltipSink)9293			{9294				Localization::String strNegativeFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_NEGATIVE");9295				strNegativeFactor << iProtectionScore;9296				strNegativeFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_PLEDGES_TO_PROTECT";9297				sFactors += strNegativeFactor.toUTF8();9298			}9299			break;9300		}9301	}93029303	// **************************9304	// Minor Civ Type9305	//9306	// -20 ~ -09307	// **************************9308	if(GetPersonality() == MINOR_CIV_PERSONALITY_HOSTILE)9309	{9310		int iHostileScore = -10;9311		iScore += iHostileScore;9312		if (sTooltipSink)9313		{9314			Localization::String strNegativeFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_NEGATIVE");9315			strNegativeFactor << iHostileScore;9316			strNegativeFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_HOSTILE";9317			sFactors += strNegativeFactor.toUTF8();9318		}9319	}9320	if(GetTrait() == MINOR_CIV_TRAIT_MILITARISTIC)9321	{9322		int iMilitaristicScore = -10;9323		iScore += iMilitaristicScore;9324		if (sTooltipSink)9325		{9326			Localization::String strNegativeFactor = Localization::Lookup("TXT_KEY_POP_CSTATE_BULLY_FACTOR_NEGATIVE");9327			strNegativeFactor << iMilitaristicScore;9328			strNegativeFactor << "TXT_KEY_POP_CSTATE_BULLY_FACTOR_MILITARISTIC";9329			sFactors += strNegativeFactor.toUTF8();9330		}9331	}93329333	if (sTooltipSink != NULL)9334	{9335		(*sTooltipSink) += sFactors;9336	}93379338	return iScore;9339}

Calls

Called by