Hooks
static bool BeforeCvTacticalAI_ScoreFormationPlots(CvTacticalAI* self, CvArmyAI* pArmy, CvPlot* pForwardTarget, CvPlot * pCurrentCOM, int iNumUnits, bool& result);static void AfterCvTacticalAI_ScoreFormationPlots(CvTacticalAI* self, CvArmyAI* pArmy, CvPlot* pForwardTarget, CvPlot * pCurrentCOM, int iNumUnits, bool& result);static bool ReplaceCvTacticalAI_ScoreFormationPlots(bool (*original)(CvTacticalAI*, CvArmyAI*, CvPlot*, CvPlot *, int), CvTacticalAI* self, CvArmyAI* pArmy, CvPlot* pForwardTarget, CvPlot * pCurrentCOM, int iNumUnits);CivRegisterBefore<CivHooks::CvTacticalAI_ScoreFormationPlots>(host, &BeforeCvTacticalAI_ScoreFormationPlots);CivRegisterAfter<CivHooks::CvTacticalAI_ScoreFormationPlots>(host, &AfterCvTacticalAI_ScoreFormationPlots);CivRegisterReplace<CivHooks::CvTacticalAI_ScoreFormationPlots>(host, &ReplaceCvTacticalAI_ScoreFormationPlots);
Code
5494/// Pick best hexes for deploying our army (mostly based on keeping a tight formation that is moving toward the target). Returns false if insufficient free plots.5495bool CvTacticalAI::ScoreFormationPlots(CvArmyAI* pArmy, CvPlot* pForwardTarget, CvPlot *pCurrentCOM, int iNumUnits)5496{5497 int iDX, iDY;5498 int iScore;5499 CvPlot* pPlot;5500 CvTacticalAnalysisCell* pCell;5501 int iNumDeployPlotsFound = 0;5502 CvTacticalTarget target;5503 bool bForcedToUseWater;55045505 // We'll store the hexes we've found here5506 m_TempTargets.clear();55075508 int iRange = 3;5509 for(iDX = -(iRange); iDX <= iRange; iDX++)5510 {5511 for(iDY = -(iRange); iDY <= iRange; iDY++)5512 {5513 pPlot = plotXY(pForwardTarget->getX(), pForwardTarget->getY(), iDX, iDY);5514 if(pPlot != NULL)5515 {5516 bForcedToUseWater = false;55175518 int iPlotDistance = plotDistance(pPlot->getX(), pPlot->getY(), pForwardTarget->getX(), pForwardTarget->getY());5519 if(iPlotDistance <= iRange)5520 {5521 int iPlotIndex = GC.getMap().plotNum(pPlot->getX(), pPlot->getY());5522 pCell = m_pMap->GetCell(iPlotIndex);5523 CvAIOperation* pOperation = m_pPlayer->getAIOperation(pArmy->GetOperationID());55245525 bool bValid = false;5526 if(pOperation->IsMixedLandNavalOperation() && pCell->CanUseForOperationGatheringCheckWater(true /*bWater*/))5527 {5528 bValid = true;5529 }55305531 else if(pOperation->IsAllNavalOperation() && pCell->CanUseForOperationGatheringCheckWater(true /*bWater*/))5532 {5533 bValid = true;5534 }55355536 else if((!pOperation->IsAllNavalOperation() && !pOperation->IsMixedLandNavalOperation()) && (pCell->CanUseForOperationGatheringCheckWater(false /*bWater*/) || GC.getMap().GetAIMapHint() & 1))5537 {5538 bValid = true;5539 if (pCell->IsWater())5540 {5541 bForcedToUseWater = true;5542 }5543 }55445545 if(pOperation->IsMixedLandNavalOperation() || pOperation->IsAllNavalOperation())5546 {5547 if(!pArmy->IsAllOceanGoing() && pCell->IsOcean())5548 {5549 bValid = false;5550 }5551 }55525553 if(bValid)5554 {5555 // Skip this plot if friendly unit that isn't in this army5556 CvUnit* pFriendlyUnit;5557 pFriendlyUnit = pCell->GetFriendlyMilitaryUnit();5558 if(pFriendlyUnit != NULL)5559 {5560 if(pFriendlyUnit->getArmyID() != pArmy->GetID())5561 {5562 continue;5563 }5564 }55655566 iNumDeployPlotsFound++;55675568 // Score plots close to COM and turn target highest5569 int iPlotDistanceFromCOM;5570 if (pForwardTarget == pCurrentCOM)5571 {5572 iPlotDistanceFromCOM = iPlotDistance;5573 }5574 else5575 {5576 iPlotDistanceFromCOM = plotDistance(pPlot->getX(), pPlot->getY(), pCurrentCOM->getX(), pCurrentCOM->getY());5577 }55785579 iScore = 800 - (iPlotDistance * 100) - (iPlotDistanceFromCOM * 100);55805581 if(pPlot->isCity() && pPlot->getOwner() == m_pPlayer->GetID())5582 {5583 iScore += 100;5584 }5585 else5586 {5587 iScore += pCell->GetDefenseModifier() * 2;5588 }5589 if (bForcedToUseWater)5590 {5591 iScore = 10;5592 }55935594 // Safe if closer to rear, or if forward target and COM are the same5595 bool bSafeForDeployment = iPlotDistanceFromCOM < iPlotDistance || pForwardTarget == pCurrentCOM;5596 pCell->SetSafeForDeployment(bSafeForDeployment);55975598 // Reduce score if safe for ranged (so these don't get picked first)5599 if (bSafeForDeployment)5600 {5601 iScore -= 200;5602 }56035604 pCell->SetDeploymentScore(iScore);56055606 // Save this in our list of potential targets5607 target.SetTargetX(pPlot->getX());5608 target.SetTargetY(pPlot->getY());5609 target.SetAuxIntData(iScore);5610 // A bit of a hack -- use high priority targets to indicate safe plots for ranged units5611 if(bSafeForDeployment)5612 {5613 target.SetTargetType(AI_TACTICAL_TARGET_HIGH_PRIORITY_UNIT);5614 }5615 else5616 {5617 target.SetTargetType(AI_TACTICAL_TARGET_LOW_PRIORITY_UNIT);5618 }5619 m_TempTargets.push_back(target);5620 }5621 }5622 }5623 }5624 }56255626 // Make sure we found enough5627 if(iNumDeployPlotsFound < iNumUnits)5628 {5629 return false;5630 }56315632 return true;5633}