Hooks
static bool BeforeCvAIOperation_CheckOnTarget(CvAIOperation* self, bool& result);static void AfterCvAIOperation_CheckOnTarget(CvAIOperation* self, bool& result);static bool ReplaceCvAIOperation_CheckOnTarget(bool (*original)(CvAIOperation*), CvAIOperation* self);CivRegisterBefore<CivHooks::CvAIOperation_CheckOnTarget>(host, &BeforeCvAIOperation_CheckOnTarget);CivRegisterAfter<CivHooks::CvAIOperation_CheckOnTarget>(host, &AfterCvAIOperation_CheckOnTarget);CivRegisterReplace<CivHooks::CvAIOperation_CheckOnTarget>(host, &ReplaceCvAIOperation_CheckOnTarget);
Code
496/// See if armies are ready to hand off units to the tactical AI (and do so if ready)497bool CvAIOperation::CheckOnTarget()498{499 int iUnitID;500 CvUnit* pCivilian;501 CvPlot* pCivilianPlot = NULL;502 CvPlot* pEscortPlot;503504 if(GetFirstArmyID() == -1)505 {506 return false;507 }508509 switch(m_eMoveType)510 {511 {512 case AI_OPERATION_MOVETYPE_SINGLE_HEX:513 CvArmyAI* pThisArmy = GET_PLAYER(m_eOwner).getArmyAI(m_viArmyIDs[0]);514 if(pThisArmy->GetNumSlotsFilled() >= 1)515 {516 iUnitID = pThisArmy->GetFirstUnitID();517 if(iUnitID != -1)518 {519 pCivilian = GET_PLAYER(m_eOwner).getUnit(iUnitID);520 pCivilianPlot = pCivilian->plot();521 }522 if(m_eCurrentState == AI_OPERATION_STATE_MOVING_TO_TARGET && pCivilianPlot == GetTargetPlot())523 {524 ArmyInPosition(pThisArmy);525 return true;526 }527 else if(m_eCurrentState == AI_OPERATION_STATE_GATHERING_FORCES)528 {529 if(pThisArmy->GetNumSlotsFilled() == 1)530 {531 ArmyInPosition(pThisArmy);532 return true;533 }534 else535 {536 pEscortPlot = GET_PLAYER(m_eOwner).getUnit(pThisArmy->GetNextUnitID())->plot();537 if(pCivilianPlot == pEscortPlot)538 {539 ArmyInPosition(pThisArmy);540 return true;541 }542 }543 }544 }545 else546 {547 CvAssertMsg(m_eCurrentState == AI_OPERATION_STATE_RECRUITING_UNITS || m_eCurrentState == AI_OPERATION_STATE_ABORTED || m_eCurrentState == AI_OPERATION_STATE_SUCCESSFUL_FINISH,548 "Found an escort operation with no units in it. Show Ed and send save.");549 }550 break;551 }552553 case AI_OPERATION_MOVETYPE_ENEMY_TERRITORY:554 {555 // Let each army perform its own check556 for(unsigned int uiI = 0; uiI < m_viArmyIDs.size(); uiI++)557 {558 CvArmyAI* pThisArmy = GET_PLAYER(m_eOwner).getArmyAI(m_viArmyIDs[uiI]);559 CvPlot* pCenterOfMass;560561 if(pThisArmy->GetNumSlotsFilled() >= 1)562 {563 switch(m_eCurrentState)564 {565 case AI_OPERATION_STATE_GATHERING_FORCES:566 {567 int iGatherTolerance = GetGatherTolerance(pThisArmy, GetMusterPlot());568 pCenterOfMass = pThisArmy->GetCenterOfMass(IsAllNavalOperation() || IsMixedLandNavalOperation() ? DOMAIN_SEA : DOMAIN_LAND);569 if(pCenterOfMass &&570 plotDistance(pCenterOfMass->getX(), pCenterOfMass->getY(), GetMusterPlot()->getX(), GetMusterPlot()->getY()) <= iGatherTolerance &&571 pThisArmy->GetFurthestUnitDistance(GetMusterPlot()) <= (iGatherTolerance * 3 / 2))572 {573 ArmyInPosition(pThisArmy);574 return true;575 }576 }577 break;578 case AI_OPERATION_STATE_MOVING_TO_TARGET:579 {580 int iTargetTolerance = GC.getAI_OPERATIONAL_CITY_ATTACK_DEPLOY_RANGE();581 pCenterOfMass = pThisArmy->GetCenterOfMass(IsAllNavalOperation() || IsMixedLandNavalOperation() ? DOMAIN_SEA : DOMAIN_LAND);582 if(pCenterOfMass &&583 plotDistance(pCenterOfMass->getX(), pCenterOfMass->getY(), m_iTargetX, m_iTargetY) <= iTargetTolerance &&584 pThisArmy->GetFurthestUnitDistance(GetTargetPlot()) <= (iTargetTolerance * 3 / 2))585 {586 ArmyInPosition(pThisArmy);587 return true;588 }589 }590 break;591 }592 }593 else594 {595 CvAssertMsg(m_eCurrentState == AI_OPERATION_STATE_RECRUITING_UNITS || m_eCurrentState == AI_OPERATION_STATE_ABORTED || m_eCurrentState == AI_OPERATION_STATE_SUCCESSFUL_FINISH,596 "Found an army operation with no units in it. Show Ed and send save.");597 }598 }599 break;600 }601602 case AI_OPERATION_MOVETYPE_NAVAL_ESCORT:603 {604 // Let each army perform its own check605 for(unsigned int uiI = 0; uiI < m_viArmyIDs.size(); uiI++)606 {607 CvArmyAI* pThisArmy = GET_PLAYER(m_eOwner).getArmyAI(m_viArmyIDs[uiI]);608 CvPlot* pCenterOfMass;609610 if(pThisArmy->GetNumSlotsFilled() >= 1)611 {612 switch(m_eCurrentState)613 {614 case AI_OPERATION_STATE_GATHERING_FORCES:615 {616 int iGatherTolerance = GetGatherTolerance(pThisArmy, GetMusterPlot());617 pCenterOfMass = pThisArmy->GetCenterOfMass(DOMAIN_SEA);618 if(pCenterOfMass &&619 plotDistance(pCenterOfMass->getX(), pCenterOfMass->getY(), GetMusterPlot()->getX(), GetMusterPlot()->getY()) <= iGatherTolerance &&620 pThisArmy->GetFurthestUnitDistance(GetMusterPlot()) <= (iGatherTolerance * 3))621 {622 ArmyInPosition(pThisArmy);623 return true;624 }625 }626 break;627 case AI_OPERATION_STATE_MOVING_TO_TARGET:628 {629 int iTargetTolerance = GC.getAI_OPERATIONAL_CITY_ATTACK_DEPLOY_RANGE();630 pCenterOfMass = pThisArmy->GetCenterOfMass(DOMAIN_SEA);631 if(pCenterOfMass &&632 plotDistance(pCenterOfMass->getX(), pCenterOfMass->getY(), m_iTargetX, m_iTargetY) <= (iTargetTolerance * 2) &&633 pThisArmy->GetFurthestUnitDistance(GetTargetPlot()) <= (iTargetTolerance * 3))634 {635 ArmyInPosition(pThisArmy);636 return true;637 }638 }639 break;640 }641 }642 else643 {644 CvAssertMsg(m_eCurrentState == AI_OPERATION_STATE_RECRUITING_UNITS || m_eCurrentState == AI_OPERATION_STATE_ABORTED || m_eCurrentState == AI_OPERATION_STATE_SUCCESSFUL_FINISH,645 "Found an army operation with no units in it. Show Ed and send save.");646 }647 }648 break;649 }650651 case AI_OPERATION_MOVETYPE_FREEFORM_NAVAL:652 {653 // Let each army perform its own check654 for(unsigned int uiI = 0; uiI < m_viArmyIDs.size(); uiI++)655 {656 CvArmyAI* pThisArmy = GET_PLAYER(m_eOwner).getArmyAI(m_viArmyIDs[uiI]);657 CvPlot* pCenterOfMass;658 int iGatherTolerance = GetGatherTolerance(pThisArmy, GetMusterPlot());659660 if(pThisArmy->GetNumSlotsFilled() >= 1)661 {662 switch(m_eCurrentState)663 {664 case AI_OPERATION_STATE_GATHERING_FORCES:665 case AI_OPERATION_STATE_MOVING_TO_TARGET:666667 // We want to recompute a new target each turn. So call ArmyInPosition() regardless of return status668 ArmyInPosition(pThisArmy);669670 pCenterOfMass = pThisArmy->GetCenterOfMass(DOMAIN_SEA);671 if(pCenterOfMass &&672 plotDistance(pCenterOfMass->getX(), pCenterOfMass->getY(), GetTargetPlot()->getX(), GetTargetPlot()->getY()) <= iGatherTolerance &&673 pThisArmy->GetFurthestUnitDistance(GetMusterPlot()) <= (iGatherTolerance * 3 / 2))674 {675 return true;676 }677 break;678 }679 }680 else681 {682 CvAssertMsg(m_eCurrentState == AI_OPERATION_STATE_RECRUITING_UNITS || m_eCurrentState == AI_OPERATION_STATE_ABORTED || m_eCurrentState == AI_OPERATION_STATE_SUCCESSFUL_FINISH,683 "Found an army operation with no units in it. Show Ed and send save.");684 }685 }686 break;687 }688 }689 return false;690}