Hooks
static bool BeforeCvMilitaryAI_WillAirUnitRebase(const CvMilitaryAI* self, CvUnit* pUnit, bool& result);static void AfterCvMilitaryAI_WillAirUnitRebase(const CvMilitaryAI* self, CvUnit* pUnit, bool& result);static bool ReplaceCvMilitaryAI_WillAirUnitRebase(bool (*original)(const CvMilitaryAI*, CvUnit*), const CvMilitaryAI* self, CvUnit* pUnit);CivRegisterBefore<CivHooks::CvMilitaryAI_WillAirUnitRebase>(host, &BeforeCvMilitaryAI_WillAirUnitRebase);CivRegisterAfter<CivHooks::CvMilitaryAI_WillAirUnitRebase>(host, &AfterCvMilitaryAI_WillAirUnitRebase);CivRegisterReplace<CivHooks::CvMilitaryAI_WillAirUnitRebase>(host, &ReplaceCvMilitaryAI_WillAirUnitRebase);
Code
3739/// Do we want to move this air unit to a new base?3740bool CvMilitaryAI::WillAirUnitRebase(CvUnit* pUnit) const3741{3742 CvPlot* pUnitPlot = pUnit->plot();37433744 CvPlot* pBestPlot = NULL;37453746 // Is this unit in a base in danger?3747 bool bNeedsToMove = false;3748 if (pUnitPlot->isCity())3749 {3750#if defined(MOD_AI_SMART_V3)3751 // Don't force move from a city only because has 20% + damage, wait until damage more than half...3752 int iDivisor = MOD_AI_SMART_V3 ? 2 : 5;3753 if (pUnitPlot->getPlotCity()->getDamage() > (pUnitPlot->getPlotCity()->GetMaxHitPoints() / iDivisor))3754#else3755 if (pUnitPlot->getPlotCity()->getDamage() > (pUnitPlot->getPlotCity()->GetMaxHitPoints() / 5))3756#endif3757 {3758 bNeedsToMove = true;3759 }3760 }3761 else3762 {3763 CvUnit *pCarrier = pUnit->getTransportUnit();3764 if (pCarrier)3765 {3766#if defined(MOD_AI_SMART_V3)3767 // don't force moving out if carrier still in decent shape...3768 int iDivisor = MOD_AI_SMART_V3 ? 3 : 5;3769#if defined(MOD_UNITS_MAX_HP)3770 if (pCarrier->getDamage() > (pCarrier->GetMaxHitPoints() / iDivisor))3771#else3772 if (pCarrier->getDamage() > (GC.getMAX_HIT_POINTS() / iDivisor))3773#endif3774#else3775#if defined(MOD_UNITS_MAX_HP)3776 if (pCarrier->getDamage() > (pCarrier->GetMaxHitPoints() / 5))3777#else3778 if (pCarrier->getDamage() > (GC.getMAX_HIT_POINTS() / 5))3779#endif3780#endif3781 {3782 bNeedsToMove = true;3783 }3784 }3785 }37863787 // Is this a fighter that doesn't have any useful missions nearby3788 if (pUnit->canAirPatrol(NULL) || pUnit->canAirSweep())3789 {3790#if defined(MOD_AI_SMART_V3)3791 int iNumNearbyEnemyAirUnits = MOD_AI_SMART_V3 ? pUnit->EnemyScoreAtRange(pUnit->plot(), true) : GetNumEnemyAirUnitsInRange(pUnitPlot, pUnit->GetRange(), true /*bCountFighters*/, true /*bCountBombers*/);3792#else3793 int iNumNearbyEnemyAirUnits = GetNumEnemyAirUnitsInRange(pUnitPlot, pUnit->GetRange(), true /*bCountFighters*/, true /*bCountBombers*/);3794#endif3795 if (iNumNearbyEnemyAirUnits == 0 && !GetBestAirSweepTarget(pUnit))3796 {3797 bNeedsToMove = true;3798 }3799 }38003801 if (!bNeedsToMove)3802 {3803 return false;3804 }38053806 // first look for open carrier slots in carriers within operations3807 int iLoopUnit = 0;3808 for(CvUnit* pLoopUnit = m_pPlayer->firstUnit(&iLoopUnit); pLoopUnit != NULL; pLoopUnit = m_pPlayer->nextUnit(&iLoopUnit))3809 {3810 CvPlot* pLoopUnitPlot = pLoopUnit->plot();38113812#if defined(MOD_AI_SMART_V3)3813 int iDivisor = MOD_AI_SMART_V3 ? 4 : 5;3814#if defined(MOD_UNITS_MAX_HP)3815 if(pLoopUnit->getDamage() > (pLoopUnit->GetMaxHitPoints() / iDivisor)) // this might not be a good place to land3816#else3817 if(pLoopUnit->getDamage() > (GC.getMAX_HIT_POINTS() / iDivisor)) // this might not be a good place to land3818#endif3819#else3820#if defined(MOD_UNITS_MAX_HP)3821 if(pLoopUnit->getDamage() > (pLoopUnit->GetMaxHitPoints() / 5)) // this might not be a good place to land3822#else3823 if(pLoopUnit->getDamage() > (GC.getMAX_HIT_POINTS() / 5)) // this might not be a good place to land3824#endif3825#endif3826 {3827 continue;3828 }38293830 if (pLoopUnit->getArmyID() == FFreeList::INVALID_INDEX)3831 {3832 continue;3833 }38343835 if(pBestPlot != pUnitPlot && !pUnit->canRebaseAt(pUnitPlot, pLoopUnitPlot->getX(),pLoopUnitPlot->getY()))3836 {3837 continue;3838 }38393840 if(!pUnit->canLoadUnit(*pLoopUnit, *pLoopUnitPlot))3841 {3842 continue;3843 }3844 3845 // Found somewhere to rebase to3846 return true;3847 }38483849 // then look for open carrier slots in carriers NOT in operations3850 for(CvUnit* pLoopUnit = m_pPlayer->firstUnit(&iLoopUnit); pLoopUnit != NULL; pLoopUnit = m_pPlayer->nextUnit(&iLoopUnit))3851 {3852 CvPlot* pLoopUnitPlot = pLoopUnit->plot();38533854#if defined(MOD_AI_SMART_V3)3855 int iDivisor = MOD_AI_SMART_V3 ? 4 : 5;3856#if defined(MOD_UNITS_MAX_HP)3857 if(pLoopUnit->getDamage() > (pLoopUnit->GetMaxHitPoints() / iDivisor)) // this might not be a good place to land3858#else3859 if(pLoopUnit->getDamage() > (GC.getMAX_HIT_POINTS() / iDivisor)) // this might not be a good place to land3860#endif3861#else3862#if defined(MOD_UNITS_MAX_HP)3863 if(pLoopUnit->getDamage() > (pLoopUnit->GetMaxHitPoints() / 5)) // this might not be a good place to land3864#else3865 if(pLoopUnit->getDamage() > (GC.getMAX_HIT_POINTS() / 5)) // this might not be a good place to land3866#endif3867#endif3868 {3869 continue;3870 }38713872 if (pLoopUnit->getArmyID() != FFreeList::INVALID_INDEX)3873 {3874 continue;3875 }38763877 if(pBestPlot != pUnitPlot && !pUnit->canRebaseAt(pUnitPlot, pLoopUnitPlot->getX(),pLoopUnitPlot->getY()))3878 {3879 continue;3880 }38813882 if(!pUnit->canLoadUnit(*pLoopUnit, *pLoopUnitPlot))3883 {3884 continue;3885 }38863887 // Found somewhere to rebase to3888 return true;3889 }38903891 CvCity* pLoopCity;3892 int iLoopCity = 0;3893 for(pLoopCity = m_pPlayer->firstCity(&iLoopCity); pLoopCity != NULL; pLoopCity = m_pPlayer->nextCity(&iLoopCity))3894 {3895 CvPlot* pTarget = pLoopCity->plot();38963897#if defined(MOD_AI_SMART_V3)3898 int iDivisor = MOD_AI_SMART_V3 ? 3 : 5;3899 if(pLoopCity->getDamage() > (pLoopCity->GetMaxHitPoints() / iDivisor))3900#else3901 if(pLoopCity->getDamage() > (pLoopCity->GetMaxHitPoints() / 5))3902#endif3903 {3904 continue;3905 }39063907 if (pTarget != pUnitPlot && !pUnit->canRebaseAt(pUnitPlot, pTarget->getX(),pTarget->getY()))3908 {3909 continue;3910 }39113912 // Found somewhere to rebase to3913 return true;3914 }39153916 return false;3917}