Hooks
static bool BeforeCvTacticalAI_ExecuteCloseOnTarget(CvTacticalAI* self, CvTacticalTarget& kTarget, CvTacticalDominanceZone* pZone);static void AfterCvTacticalAI_ExecuteCloseOnTarget(CvTacticalAI* self, CvTacticalTarget& kTarget, CvTacticalDominanceZone* pZone);static void ReplaceCvTacticalAI_ExecuteCloseOnTarget(void (*original)(CvTacticalAI*, CvTacticalTarget&, CvTacticalDominanceZone*), CvTacticalAI* self, CvTacticalTarget& kTarget, CvTacticalDominanceZone* pZone);CivRegisterBefore<CivHooks::CvTacticalAI_ExecuteCloseOnTarget>(host, &BeforeCvTacticalAI_ExecuteCloseOnTarget);CivRegisterAfter<CivHooks::CvTacticalAI_ExecuteCloseOnTarget>(host, &AfterCvTacticalAI_ExecuteCloseOnTarget);CivRegisterReplace<CivHooks::CvTacticalAI_ExecuteCloseOnTarget>(host, &ReplaceCvTacticalAI_ExecuteCloseOnTarget);
Code
8407/// Move forces in toward our target8408void CvTacticalAI::ExecuteCloseOnTarget(CvTacticalTarget& kTarget, CvTacticalDominanceZone* pZone)8409{8410 CvOperationUnit unit;8411 int iDistance;8412 CvPlot* pTargetPlot;8413 int iRangedUnits = 0;8414 int iMeleeUnits = 0;8415 int iGenerals = 0;8416 list<int>::iterator it;8417 int iTacticalRadius = GC.getGame().GetTacticalAnalysisMap()->GetTacticalRange();84188419 pTargetPlot = GC.getMap().plot(kTarget.GetTargetX(), kTarget.GetTargetY());8420 m_OperationUnits.clear();8421 m_GeneralsToMove.clear();84228423 for(it = m_CurrentTurnUnits.begin(); it != m_CurrentTurnUnits.end(); it++)8424 {8425 UnitHandle pUnit = m_pPlayer->getUnit(*it);8426 if(pUnit)8427 {8428 // If not naval invasion, proper domain of unit?8429 if(pZone->IsNavalInvasion() ||8430 (pZone->IsWater() && pUnit->getDomainType() == DOMAIN_SEA || !pZone->IsWater() && pUnit->getDomainType() == DOMAIN_LAND))8431 {8432 // Find units really close to target or somewhat close that just came out of an operation8433 iDistance = plotDistance(pUnit->getX(), pUnit->getY(), kTarget.GetTargetX(), kTarget.GetTargetY());8434 if(iDistance <= iTacticalRadius || (iDistance <= (GC.getAI_OPERATIONAL_CITY_ATTACK_DEPLOY_RANGE() * 3) && pUnit->GetDeployFromOperationTurn() + GC.getAI_TACTICAL_MAP_TEMP_ZONE_TURNS() >= GC.getGame().getGameTurn()))8435 {8436 unit.SetUnitID(pUnit->GetID());84378438 if(pUnit->IsCanAttackRanged())8439 {8440#if defined(MOD_AI_SMART_V3)8441 if (MOD_AI_SMART_V3)8442 {8443 if (pUnit->GetRange() > 1)8444 unit.SetPosition((MultiunitPositionTypes)m_CachedInfoTypes[eMUPOSITION_BOMBARD]);8445 else8446 unit.SetPosition((MultiunitPositionTypes)m_CachedInfoTypes[eMUPOSITION_FRONT_LINE]);8447 } else8448#endif8449 unit.SetPosition((MultiunitPositionTypes)m_CachedInfoTypes[eMUPOSITION_BOMBARD]);8450 iRangedUnits++;8451 m_OperationUnits.push_back(unit);84528453 }8454 else if(pUnit->IsGreatGeneral() || pUnit->IsGreatAdmiral())8455 {8456 unit.SetPosition((MultiunitPositionTypes)m_CachedInfoTypes[eMUPOSITION_CIVILIAN_SUPPORT]);8457 iGenerals++;8458 m_GeneralsToMove.push_back(unit);8459 }8460 else8461 {8462 unit.SetPosition((MultiunitPositionTypes)m_CachedInfoTypes[eMUPOSITION_FRONT_LINE]);8463 iMeleeUnits++;8464 m_OperationUnits.push_back(unit);8465 }8466 }8467 }8468 }8469 }84708471 // If have any units to move...8472 if(m_OperationUnits.size() > 0)8473 {8474 /* Land only unless invasion or no enemy naval presence */8475 bool bLandOnly = true;8476 if (pZone->IsNavalInvasion() || pZone->GetEnemyNavalUnitCount() == 0)8477 {8478 bLandOnly = false;8479 }8480 ScoreCloseOnPlots(pTargetPlot, bLandOnly);84818482 // Compute the moves to get the best deployment8483 std::stable_sort(m_TempTargets.begin(), m_TempTargets.end());8484 m_PotentialBlocks.clear();84858486 int iRangedUnitsToPlace = iRangedUnits;8487 int iMeleeUnitsToPlace = iMeleeUnits;84888489 // First loop for ranged unit spots8490 bool bDone = false;8491 for(unsigned int iI = 0; iI < m_TempTargets.size() && !bDone; iI++)8492 {8493 AITacticalTargetType eTargetType = m_TempTargets[iI].GetTargetType();8494 if (eTargetType == AI_TACTICAL_TARGET_HIGH_PRIORITY_UNIT)8495 {8496 CvPlot* pLoopPlot = GC.getMap().plot(m_TempTargets[iI].GetTargetX(), m_TempTargets[iI].GetTargetY());8497 if(FindClosestOperationUnit(pLoopPlot, true /*bSafeForRanged*/, true /*bMustBeRangedUnit*/))8498 {8499 for(unsigned int jJ = 0; jJ < m_CurrentMoveUnits.size(); jJ++)8500 {8501 CvBlockingUnit block;8502 block.SetUnitID(m_CurrentMoveUnits[jJ].GetID());8503 block.SetPlot(pLoopPlot);8504 block.SetNumChoices((int)m_CurrentMoveUnits.size());8505 block.SetDistanceToTarget(m_CurrentMoveUnits[jJ].GetMovesToTarget());8506 m_PotentialBlocks.push_back(block);8507 }85088509 iRangedUnitsToPlace--;8510 if(iRangedUnitsToPlace == 0)8511 {8512 bDone = true;8513 }8514 }8515 }8516 }8517 AssignDeployingUnits(iRangedUnits - iRangedUnitsToPlace);8518 PerformChosenMoves();85198520 // Second loop for everyone else (including remaining ranged units)8521 m_PotentialBlocks.clear();8522 iMeleeUnits += iRangedUnitsToPlace;8523 iMeleeUnitsToPlace += iRangedUnitsToPlace;8524 bDone = false;8525 for(unsigned int iI = 0; iI < m_TempTargets.size() && !bDone; iI++)8526 {8527 AITacticalTargetType eTargetType = m_TempTargets[iI].GetTargetType();8528 if (eTargetType != AI_TACTICAL_TARGET_HIGH_PRIORITY_UNIT)8529 {8530 CvPlot* pLoopPlot = GC.getMap().plot(m_TempTargets[iI].GetTargetX(), m_TempTargets[iI].GetTargetY());8531 if(FindClosestOperationUnit(pLoopPlot, true /*bSafeForRanged*/, false /*bMustBeRangedUnit*/))8532 {8533 for(unsigned int jJ = 0; jJ < m_CurrentMoveUnits.size(); jJ++)8534 {8535 CvBlockingUnit block;8536 block.SetUnitID(m_CurrentMoveUnits[jJ].GetID());8537 block.SetPlot(pLoopPlot);8538 block.SetNumChoices((int)m_CurrentMoveUnits.size());8539 block.SetDistanceToTarget(m_CurrentMoveUnits[jJ].GetMovesToTarget());8540 m_PotentialBlocks.push_back(block);8541 }85428543 iMeleeUnitsToPlace--;8544 if(iMeleeUnitsToPlace == 0)8545 {8546 bDone = true;8547 }8548 }8549 }8550 }8551 AssignDeployingUnits(iMeleeUnits - iMeleeUnitsToPlace);8552 PerformChosenMoves();8553 }85548555 if(m_GeneralsToMove.size() > 0)8556 {8557 MoveGreatGeneral();8558 }8559}