Bazaar developer reference

CvTacticalAI::PlotDestroyUnitMoves(AITacticalTargetType, bool, bool)

Defined in
CvTacticalAI.cpp, line 2299
Class
CvTacticalAI
Hook name
CivHooks::CvTacticalAI_PlotDestroyUnitMoves

Hooks

static bool BeforeCvTacticalAI_PlotDestroyUnitMoves(CvTacticalAI* self, AITacticalTargetType targetType, bool bMustBeAbleToKill, bool bAttackAtPoorOdds);static void AfterCvTacticalAI_PlotDestroyUnitMoves(CvTacticalAI* self, AITacticalTargetType targetType, bool bMustBeAbleToKill, bool bAttackAtPoorOdds);static void ReplaceCvTacticalAI_PlotDestroyUnitMoves(void (*original)(CvTacticalAI*, AITacticalTargetType, bool, bool), CvTacticalAI* self, AITacticalTargetType targetType, bool bMustBeAbleToKill, bool bAttackAtPoorOdds);CivRegisterBefore<CivHooks::CvTacticalAI_PlotDestroyUnitMoves>(host, &BeforeCvTacticalAI_PlotDestroyUnitMoves);CivRegisterAfter<CivHooks::CvTacticalAI_PlotDestroyUnitMoves>(host, &AfterCvTacticalAI_PlotDestroyUnitMoves);CivRegisterReplace<CivHooks::CvTacticalAI_PlotDestroyUnitMoves>(host, &ReplaceCvTacticalAI_PlotDestroyUnitMoves);

Code

2298/// Assign a group of units to attack each unit we think we can destroy2299void CvTacticalAI::PlotDestroyUnitMoves(AITacticalTargetType targetType, bool bMustBeAbleToKill, bool bAttackAtPoorOdds)2300{2301	int iRequiredDamage;2302	int iExpectedDamage;23032304	// See how many moves of this type we can execute2305	CvTacticalTarget* pTarget = GetFirstZoneTarget(targetType);2306	while(pTarget != NULL)2307	{2308		bool bUnitCanAttack = false;2309		bool bCityCanAttack = false;23102311		// See what units we have who can reach targets this turn2312		CvPlot* pPlot = GC.getMap().plot(pTarget->GetTargetX(), pTarget->GetTargetY());2313		UnitHandle pDefender = pPlot->getVisibleEnemyDefender(m_pPlayer->GetID());2314		if(pDefender)2315		{2316			bUnitCanAttack = FindUnitsWithinStrikingDistance(pPlot, 1, 0, false /* bNoRangedUnits */);2317			bCityCanAttack = FindCitiesWithinStrikingDistance(pPlot);2318			if(bUnitCanAttack || bCityCanAttack)2319			{2320				iExpectedDamage = ComputeTotalExpectedDamage(pTarget, pPlot);2321				iExpectedDamage += ComputeTotalExpectedBombardDamage(pDefender);2322				iRequiredDamage = pDefender->GetCurrHitPoints();2323				pTarget->SetAuxIntData(iRequiredDamage);23242325				if(!bMustBeAbleToKill)2326				{2327					// Put in any attacks where we'll inflict at least equal damage2328					if(GC.getLogging() && GC.getAILogging())2329					{2330						CvString strLogString;23312332						CvString strPlayerName = GET_PLAYER(pDefender->getOwner()).getCivilizationShortDescription();23332334						CvUnitEntry* pkUnitInfo = GC.getUnitInfo(pDefender->getUnitType());2335						CvString strTemp = (pkUnitInfo != NULL)? pkUnitInfo->GetDescription() : "Unknown Unit Type";23362337						switch(targetType)2338						{2339						case AI_TACTICAL_TARGET_HIGH_PRIORITY_UNIT:2340							strLogString.Format("Looking at damaging high priority %s, X: %d, Y: %d,", strTemp.GetCString(),2341							                    pDefender->getX(), pDefender->getY());2342							break;2343						case AI_TACTICAL_TARGET_MEDIUM_PRIORITY_UNIT:2344							strLogString.Format("Looking at damaging medium priority %s, X: %d, Y: %d,", strTemp.GetCString(),2345							                    pDefender->getX(), pDefender->getY());2346							break;2347						case AI_TACTICAL_TARGET_LOW_PRIORITY_UNIT:2348							strLogString.Format("Looking at damaging low priority %s, X: %d, Y: %d,", strTemp.GetCString(),2349							                    pDefender->getX(), pDefender->getY());2350							break;2351						}2352						strLogString += strPlayerName;2353						LogTacticalMessage(strLogString);2354					}23552356					// Attack no matter what2357					if(bAttackAtPoorOdds)2358					{2359						ExecuteAttack(pTarget, pPlot, false, false);2360					}2361					// If we can at least knock the defender to 40% strength with our combined efforts, go ahead even if each individual attack isn't favorable2362					else2363					{2364						bool bMustInflictWhatWeTake = true;2365						if (iExpectedDamage >= (iRequiredDamage * 40) / 100)2366						{2367							bMustInflictWhatWeTake = false;2368						}2369						ExecuteAttack(pTarget, pPlot, bMustInflictWhatWeTake, true);2370					}2371				}23722373				// Do we have enough firepower to destroy it?2374				else2375				{2376					if(iExpectedDamage > iRequiredDamage)2377					{2378						// If so, execute enough moves to destroy it2379						if(GC.getLogging() && GC.getAILogging())2380						{2381							CvString strLogString, strTemp, strPlayerName;2382							strPlayerName = GET_PLAYER(pDefender->getOwner()).getCivilizationShortDescription();2383							strTemp = GC.getUnitInfo(pDefender->getUnitType())->GetDescription();2384							switch(targetType)2385							{2386							case AI_TACTICAL_TARGET_HIGH_PRIORITY_UNIT:2387								strLogString.Format("Looking at killing high priority %s, X: %d, Y: %d,", strTemp.GetCString(),2388								                    pDefender->getX(), pDefender->getY());2389								break;2390							case AI_TACTICAL_TARGET_MEDIUM_PRIORITY_UNIT:2391								strLogString.Format("Looking at killing medium priority %s, X: %d, Y: %d,", strTemp.GetCString(),2392								                    pDefender->getX(), pDefender->getY());2393								break;2394							case AI_TACTICAL_TARGET_LOW_PRIORITY_UNIT:2395								strLogString.Format("Looking at killing low priority %s, X: %d, Y: %d,", strTemp.GetCString(),2396								                    pDefender->getX(), pDefender->getY());2397								break;2398							}2399							strLogString += strPlayerName;2400							LogTacticalMessage(strLogString);2401						}2402						ExecuteAttack(pTarget, pPlot, false, (targetType != AI_TACTICAL_TARGET_HIGH_PRIORITY_UNIT));2403					}2404				}2405			}2406		}2407		pTarget = GetNextZoneTarget();2408	}2409}

Calls

Called by