Hooks
static bool BeforeCvTacticalAI_PerformChosenMoves(CvTacticalAI* self, int iFallbackMoveRange);static void AfterCvTacticalAI_PerformChosenMoves(CvTacticalAI* self, int iFallbackMoveRange);static void ReplaceCvTacticalAI_PerformChosenMoves(void (*original)(CvTacticalAI*, int), CvTacticalAI* self, int iFallbackMoveRange);CivRegisterBefore<CivHooks::CvTacticalAI_PerformChosenMoves>(host, &BeforeCvTacticalAI_PerformChosenMoves);CivRegisterAfter<CivHooks::CvTacticalAI_PerformChosenMoves>(host, &AfterCvTacticalAI_PerformChosenMoves);CivRegisterReplace<CivHooks::CvTacticalAI_PerformChosenMoves>(host, &ReplaceCvTacticalAI_PerformChosenMoves);
Code
10668/// Make and log selected movements10669void CvTacticalAI::PerformChosenMoves(int iFallbackMoveRange)10670{10671 // Make moves up into hexes, starting with units already close to their final destination10672 std::stable_sort(m_ChosenBlocks.begin(), m_ChosenBlocks.end(), TacticalAIHelpers::CvBlockingUnitDistanceSort);1067310674 // First loop through is for units that have a unit moving into their hex. They need to leave first!10675 for(unsigned int iI = 0; iI < m_ChosenBlocks.size(); iI++)10676 {10677 CvUnit* pUnit = m_pPlayer->getUnit(m_ChosenBlocks[iI].GetUnitID());10678 if(pUnit)10679 {10680 if(pUnit->plot() != m_ChosenBlocks[iI].GetPlot() && IsInChosenMoves(pUnit->plot()) && m_ChosenBlocks[iI].GetPlot()->getNumFriendlyUnitsOfType(pUnit) == 0)10681 {10682 bool bMoveWasSafe;10683 MoveToUsingSafeEmbark(pUnit, m_ChosenBlocks[iI].GetPlot(), bMoveWasSafe);1068410685 if(GC.getLogging() && GC.getAILogging())10686 {10687 CvString strMsg;10688 strMsg.Format("Deploying %s (to get out of way), To X: %d, To Y: %d, At X: %d, At Y: %d, Distance Before Move: %d",10689 pUnit->getName().GetCString(), m_ChosenBlocks[iI].GetPlot()->getX(), m_ChosenBlocks[iI].GetPlot()->getY(),10690 pUnit->getX(), pUnit->getY(), m_ChosenBlocks[iI].GetDistanceToTarget());10691 LogTacticalMessage(strMsg);10692 }1069310694 // Use number of choices field to indicate already moved10695 m_ChosenBlocks[iI].SetNumChoices(-1);10696 }10697 }10698 }1069910700 // Second loop is for units moving into their chosen spot normally10701 for(unsigned int iI = 0; iI < m_ChosenBlocks.size(); iI++)10702 {10703 CvUnit* pUnit = m_pPlayer->getUnit(m_ChosenBlocks[iI].GetUnitID());10704 if(pUnit)10705 {10706 if(pUnit->plot() == m_ChosenBlocks[iI].GetPlot())10707 {10708 m_ChosenBlocks[iI].SetNumChoices(-1);10709 }10710 else10711 {10712 // Someone we didn't move above?10713 if(m_ChosenBlocks[iI].GetNumChoices() != -1)10714 {10715 CvPlot* pPlotBeforeMove = pUnit->plot();10716 bool bMoveWasSafe;10717 MoveToUsingSafeEmbark(pUnit, m_ChosenBlocks[iI].GetPlot(), bMoveWasSafe);1071810719 if(GC.getLogging() && GC.getAILogging())10720 {10721 CvString strMsg;10722 strMsg.Format("Deploying %s, To X: %d, To Y: %d, At X: %d, At Y: %d, Distance Before Move: %d",10723 pUnit->getName().GetCString(), m_ChosenBlocks[iI].GetPlot()->getX(), m_ChosenBlocks[iI].GetPlot()->getY(),10724 pUnit->getX(), pUnit->getY(), m_ChosenBlocks[iI].GetDistanceToTarget());10725 LogTacticalMessage(strMsg);10726 }1072710728 // Use number of choices field to indicate already moved10729 if(pPlotBeforeMove != pUnit->plot())10730 {10731 m_ChosenBlocks[iI].SetNumChoices(-1);10732 }10733 }10734 }10735 }10736 }1073710738 // Third loop is for units we still haven't been able to move (other units must be blocking their target for this turn)10739 if (iFallbackMoveRange > 0)10740 {10741 for(unsigned int iI = 0; iI < m_ChosenBlocks.size(); iI++)10742 {10743 CvUnit* pUnit = m_pPlayer->getUnit(m_ChosenBlocks[iI].GetUnitID());10744 if(pUnit)10745 {10746 // Someone we didn't move above?10747 if(m_ChosenBlocks[iI].GetNumChoices() != -1)10748 {10749 CvPlot* pPlotBeforeMove = pUnit->plot();10750 if(MoveToEmptySpaceNearTarget(UnitHandle(pUnit), m_ChosenBlocks[iI].GetPlot(), (pUnit->getDomainType()==DOMAIN_LAND)))10751 {10752 if(GC.getLogging() && GC.getAILogging())10753 {10754 CvString strMsg;10755 strMsg.Format("Deploying %s to space near target, Target X: %d, Target Y: %d, At X: %d, At Y: %d, Distance Before Move: %d",10756 pUnit->getName().GetCString(), m_ChosenBlocks[iI].GetPlot()->getX(), m_ChosenBlocks[iI].GetPlot()->getY(),10757 pUnit->getX(), pUnit->getY(), m_ChosenBlocks[iI].GetDistanceToTarget());10758 LogTacticalMessage(strMsg);10759 }1076010761 if(pPlotBeforeMove != pUnit->plot())10762 {10763 m_ChosenBlocks[iI].SetNumChoices(-1);10764 }10765 }10766 }10767 }10768 }10769 }1077010771 // Fourth loop let's unit end within 2 of target10772 if (iFallbackMoveRange > 1)10773 {10774 for(unsigned int iI = 0; iI < m_ChosenBlocks.size(); iI++)10775 {10776 CvUnit* pUnit = m_pPlayer->getUnit(m_ChosenBlocks[iI].GetUnitID());10777 if(pUnit)10778 {10779 // Someone we didn't move above?10780 if(m_ChosenBlocks[iI].GetNumChoices() != -1)10781 {10782 if (MoveToEmptySpaceTwoFromTarget(UnitHandle(pUnit), m_ChosenBlocks[iI].GetPlot(), (pUnit->getDomainType()==DOMAIN_LAND)))10783 {10784 if(GC.getLogging() && GC.getAILogging())10785 {10786 CvString strMsg;10787 strMsg.Format("Deploying %s to space within 2 of target, Target X: %d, Target Y: %d, At X: %d, At Y: %d, Distance Before Move: %d",10788 pUnit->getName().GetCString(), m_ChosenBlocks[iI].GetPlot()->getX(), m_ChosenBlocks[iI].GetPlot()->getY(),10789 pUnit->getX(), pUnit->getY(), m_ChosenBlocks[iI].GetDistanceToTarget());10790 LogTacticalMessage(strMsg);10791 }10792 }10793 }10794 }10795 }10796 }1079710798 // Finish moves for all units10799 for(unsigned int iI = 0; iI < m_ChosenBlocks.size(); iI++)10800 {10801 CvUnit* pUnit = m_pPlayer->getUnit(m_ChosenBlocks[iI].GetUnitID());10802 if(!pUnit->isDelayedDeath())10803 {10804 if (pUnit->getMoves() > 0)10805 {10806 if (pUnit->canPillage(pUnit->plot()) && pUnit->getDamage() > 0)10807 {10808 pUnit->PushMission(CvTypes::getMISSION_PILLAGE());10809 if(GC.getLogging() && GC.getAILogging())10810 {10811 CvString strMsg;10812 strMsg.Format("Already in position, will pillage with %s, X: %d, Y: %d", pUnit->getName().GetCString(),10813 m_ChosenBlocks[iI].GetPlot()->getX(), m_ChosenBlocks[iI].GetPlot()->getY());10814 LogTacticalMessage(strMsg);10815 }1081610817 }10818 else if(pUnit->canFortify(pUnit->plot()))10819 {10820 pUnit->PushMission(CvTypes::getMISSION_FORTIFY());10821 if(GC.getLogging() && GC.getAILogging())10822 {10823 CvString strMsg;10824 strMsg.Format("Already in position, will fortify with %s, X: %d, Y: %d", pUnit->getName().GetCString(),10825 m_ChosenBlocks[iI].GetPlot()->getX(), m_ChosenBlocks[iI].GetPlot()->getY());10826 LogTacticalMessage(strMsg);10827 }10828 }10829 else10830 {10831 if(GC.getLogging() && GC.getAILogging())10832 {10833 CvString strMsg;10834 strMsg.Format("Already in position, no move for %s, X: %d, Y: %d", pUnit->getName().GetCString(),10835 m_ChosenBlocks[iI].GetPlot()->getX(), m_ChosenBlocks[iI].GetPlot()->getY());10836 LogTacticalMessage(strMsg);10837 }10838 }10839 pUnit->finishMoves();10840 }10841 UnitProcessed(pUnit->GetID());10842 }10843 }10844}