Hooks
static bool BeforeCvBarbarians_DoSpawnBarbarianUnit(CvPlot* pPlot, bool bIgnoreMaxBarbarians, bool bFinishMoves);static void AfterCvBarbarians_DoSpawnBarbarianUnit(CvPlot* pPlot, bool bIgnoreMaxBarbarians, bool bFinishMoves);static void ReplaceCvBarbarians_DoSpawnBarbarianUnit(void (*original)(CvPlot*, bool, bool), CvPlot* pPlot, bool bIgnoreMaxBarbarians, bool bFinishMoves);CivRegisterBefore<CivHooks::CvBarbarians_DoSpawnBarbarianUnit>(host, &BeforeCvBarbarians_DoSpawnBarbarianUnit);CivRegisterAfter<CivHooks::CvBarbarians_DoSpawnBarbarianUnit>(host, &AfterCvBarbarians_DoSpawnBarbarianUnit);CivRegisterReplace<CivHooks::CvBarbarians_DoSpawnBarbarianUnit>(host, &ReplaceCvBarbarians_DoSpawnBarbarianUnit);
Code
728/// Spawn a Barbarian Unit somewhere adjacent to pPlot729void CvBarbarians::DoSpawnBarbarianUnit(CvPlot* pPlot, bool bIgnoreMaxBarbarians, bool bFinishMoves)730{731 int iNumNearbyUnits;732 int iNearbyUnitLoop;733 int iRange = GC.getMAX_BARBARIANS_FROM_CAMP_NEARBY_RANGE();734 int iX;735 int iY;736 CvPlot* pNearbyPlot;737 DirectionTypes eDirection;738739 CvGame& kGame = GC.getGame();740741 if (pPlot == 0)742 return;743744 // is this camp empty - first priority is to fill it745 if (pPlot && pPlot->GetNumCombatUnits() == 0)746 {747 UnitTypes eUnit;748#if defined(MOD_EVENTS_BARBARIANS)749 eUnit = GetRandomBarbarianUnitType(pPlot, UNITAI_FAST_ATTACK);750#else751 eUnit = GetRandomBarbarianUnitType(GC.getMap().getArea(pPlot->getArea()), UNITAI_FAST_ATTACK);752#endif753754 if (eUnit != NO_UNIT)755 {756 CvUnit* pUnit = GET_PLAYER(BARBARIAN_PLAYER).initUnit(eUnit, pPlot->getX(), pPlot->getY(), UNITAI_FAST_ATTACK);757 pUnit->finishMoves();758 759#if defined(MOD_EVENTS_BARBARIANS)760 if (MOD_EVENTS_BARBARIANS) {761 GAMEEVENTINVOKE_HOOK(GAMEEVENT_BarbariansSpawnedUnit, pPlot->getX(), pPlot->getY(), eUnit);762 }763#endif764765 return;766 }767 }768769 m_aeValidBarbSpawnDirections.clear();770771 // Look at nearby Plots to see if there are already too many Barbs nearby772 iNumNearbyUnits = 0;773774 for(iX = -iRange; iX <= iRange; iX++)775 {776 for(iY = -iRange; iY <= iRange; iY++)777 {778 // Cut off the corners of the area we're looking at that we don't want779 pNearbyPlot = plotXYWithRangeCheck(pPlot->getX(), pPlot->getY(), iX, iY, iRange);780781 if(pNearbyPlot != NULL)782 {783 if(pNearbyPlot->getNumUnits() > 0)784 {785 for(iNearbyUnitLoop = 0; iNearbyUnitLoop < pNearbyPlot->getNumUnits(); iNearbyUnitLoop++)786 {787 const CvUnit* const unit = pNearbyPlot->getUnitByIndex(iNearbyUnitLoop);788 if(unit && pNearbyPlot->getUnitByIndex(iNearbyUnitLoop)->isBarbarian())789 {790 iNumNearbyUnits++;791 }792 }793 }794 }795 }796 }797798 if(iNumNearbyUnits <= /*2*/ GC.getMAX_BARBARIANS_FROM_CAMP_NEARBY() || bIgnoreMaxBarbarians)799 {800 CvPlot* pLoopPlot;801802 // Barbs only get boats after some period of time has passed803 bool bCanSpawnBoats = kGame.getElapsedGameTurns() > /*30*/ GC.getBARBARIAN_NAVAL_UNIT_START_TURN_SPAWN();804805 // Look to see if adjacent Tiles are valid locations to spawn a Unit806 for(int iDirectionLoop = 0; iDirectionLoop < NUM_DIRECTION_TYPES; iDirectionLoop++)807 {808 eDirection = (DirectionTypes) iDirectionLoop;809 pLoopPlot = plotDirection(pPlot->getX(), pPlot->getY(), eDirection);810811 if(pLoopPlot != NULL)812 {813 if(pLoopPlot->getNumUnits() == 0)814 {815 if(!pLoopPlot->isImpassable() && !pLoopPlot->isMountain())816 {817 if(!pLoopPlot->isCity())818 {819 if(!pLoopPlot->isLake())820 {821 // Water Tiles are only valid when the Barbs have the proper Tech822 if(!pLoopPlot->isWater() || bCanSpawnBoats)823 {824 m_aeValidBarbSpawnDirections.push_back(eDirection);825 }826 }827 }828 }829 }830 }831 }832833 // Any valid locations?834 if(m_aeValidBarbSpawnDirections.size() > 0)835 {836 int iIndex = kGame.getJonRandNum(m_aeValidBarbSpawnDirections.size(), "Barb Unit Location Spawn Roll");837 eDirection = (DirectionTypes) m_aeValidBarbSpawnDirections[iIndex];838 CvPlot* pSpawnPlot = plotDirection(pPlot->getX(), pPlot->getY(), eDirection);839 UnitAITypes eUnitAI;840 UnitTypes eUnit;841842 // Naval Barbs843 if(pSpawnPlot->isWater())844 {845 eUnitAI = UNITAI_ATTACK_SEA;846 }847 // Land Barbs848 else849 {850 eUnitAI = UNITAI_FAST_ATTACK;851 }852853#if defined(MOD_EVENTS_BARBARIANS)854 eUnit = GetRandomBarbarianUnitType(pSpawnPlot, eUnitAI);855#else856 eUnit = GetRandomBarbarianUnitType(GC.getMap().getArea(pSpawnPlot->getArea()), eUnitAI);857#endif858859 if(eUnit != NO_UNIT)860 {861 CvUnit* pUnit = GET_PLAYER(BARBARIAN_PLAYER).initUnit(eUnit, pSpawnPlot->getX(), pSpawnPlot->getY(), eUnitAI);862 if (bFinishMoves)863 {864 pUnit->finishMoves();865 }866867#if defined(MOD_BUGFIX_MINOR)868 // Stop units from plundered trade routes ending up in the ocean869 if (!pUnit->jumpToNearestValidPlot())870 {871 pUnit->kill(false); // Could not find a valid spot!872 pUnit = NULL;873 }874#endif875876#if defined(MOD_EVENTS_BARBARIANS)877 if (pUnit != NULL && MOD_EVENTS_BARBARIANS) {878 GAMEEVENTINVOKE_HOOK(GAMEEVENT_BarbariansSpawnedUnit, pSpawnPlot->getX(), pSpawnPlot->getY(), eUnit);879 }880#endif881 }882 }883 }884}