Hooks
static bool BeforeCvTacticalAI_ClearEnemiesNearArmy(CvTacticalAI* self, CvArmyAI* pArmy);static void AfterCvTacticalAI_ClearEnemiesNearArmy(CvTacticalAI* self, CvArmyAI* pArmy);static void ReplaceCvTacticalAI_ClearEnemiesNearArmy(void (*original)(CvTacticalAI*, CvArmyAI*), CvTacticalAI* self, CvArmyAI* pArmy);CivRegisterBefore<CivHooks::CvTacticalAI_ClearEnemiesNearArmy>(host, &BeforeCvTacticalAI_ClearEnemiesNearArmy);CivRegisterAfter<CivHooks::CvTacticalAI_ClearEnemiesNearArmy>(host, &AfterCvTacticalAI_ClearEnemiesNearArmy);CivRegisterReplace<CivHooks::CvTacticalAI_ClearEnemiesNearArmy>(host, &ReplaceCvTacticalAI_ClearEnemiesNearArmy);
Code
4977/// Queues up attacks on enemy units on or adjacent to army's desired center4978void CvTacticalAI::ClearEnemiesNearArmy(CvArmyAI* pArmy)4979{4980 bool bEnemyNear = false;4981 CvPlot* pPlot;4982 int iRange = 1;4983 bool bAttackUnderway;4984 bool bAttackMade = false;4985 UnitHandle pUnit;49864987 // Loop through all appropriate targets to see if any is of concern4988 for(unsigned int iI = 0; iI < m_AllTargets.size(); iI++)4989 {4990 // Is the target of an appropriate type?4991 if(m_AllTargets[iI].GetTargetType() == AI_TACTICAL_TARGET_HIGH_PRIORITY_UNIT ||4992 m_AllTargets[iI].GetTargetType() == AI_TACTICAL_TARGET_MEDIUM_PRIORITY_UNIT ||4993 m_AllTargets[iI].GetTargetType() == AI_TACTICAL_TARGET_LOW_PRIORITY_UNIT)4994 {4995 // Is this unit near enough?4996 if(plotDistance(pArmy->GetX(), pArmy->GetY(), m_AllTargets[iI].GetTargetX(), m_AllTargets[iI].GetTargetY()) <= iRange)4997 {4998 bEnemyNear = true;4999 break;5000 }5001 }5002 }50035004 if(bEnemyNear)5005 {5006 // Add units from army to tactical AI for this turn5007 pUnit = pArmy->GetFirstUnit();5008 while(pUnit)5009 {5010 if(!pUnit->TurnProcessed() && !pUnit->isDelayedDeath() && pUnit->canMove())5011 {5012 if(std::find(m_CurrentTurnUnits.begin(), m_CurrentTurnUnits.end(), pUnit->GetID()) == m_CurrentTurnUnits.end())5013 {5014 m_CurrentTurnUnits.push_back(pUnit->GetID());5015 }5016 }5017 pUnit = pArmy->GetNextUnit();5018 }50195020 // Now attack these targets5021 for(unsigned int iI = 0; iI < m_AllTargets.size(); iI++)5022 {5023 // Is the target of an appropriate type?5024 if(m_AllTargets[iI].GetTargetType() == AI_TACTICAL_TARGET_HIGH_PRIORITY_UNIT ||5025 m_AllTargets[iI].GetTargetType() == AI_TACTICAL_TARGET_MEDIUM_PRIORITY_UNIT ||5026 m_AllTargets[iI].GetTargetType() == AI_TACTICAL_TARGET_LOW_PRIORITY_UNIT)5027 {5028 if(m_AllTargets[iI].IsTargetStillAlive(m_pPlayer->GetID()))5029 {5030 // Is this unit near enough?5031 if(plotDistance(pArmy->GetX(), pArmy->GetY(), m_AllTargets[iI].GetTargetX(), m_AllTargets[iI].GetTargetY()) <= iRange)5032 {5033 pPlot = GC.getMap().plot(m_AllTargets[iI].GetTargetX(), m_AllTargets[iI].GetTargetY());50345035 m_pMap->ClearDynamicFlags();5036 m_pMap->SetTargetBombardCells(pPlot, m_pMap->GetBestFriendlyRange(), m_pMap->CanIgnoreLOS());50375038 bAttackUnderway = ExecuteSafeBombards(m_AllTargets[iI]);5039 if(m_AllTargets[iI].IsTargetStillAlive(m_pPlayer->GetID()))5040 {5041 bAttackMade = ExecuteProtectedBombards(m_AllTargets[iI], bAttackUnderway);5042 }5043 if(bAttackMade)5044 {5045 bAttackUnderway = true;5046 }5047 if(m_AllTargets[iI].IsTargetStillAlive(m_pPlayer->GetID()))5048 {5049 UnitHandle pDefender = pPlot->getVisibleEnemyDefender(m_pPlayer->GetID());5050 if(pDefender)5051 {5052 m_AllTargets[iI].SetAuxIntData(pDefender->GetCurrHitPoints());5053 m_CurrentMoveCities.clear();5054 if(FindUnitsWithinStrikingDistance(pPlot, 1, 0, false /* bNoRangedUnits */))5055 {5056 ComputeTotalExpectedDamage(&m_AllTargets[iI], pPlot);5057 ExecuteAttack(&m_AllTargets[iI], pPlot, true /*bInflictWhatWeTake*/, true /*bMustSurviveAttack*/);5058 }5059 }5060 }5061 }5062 }5063 }5064 }5065 }5066}