Hooks
static bool BeforeCvUnitMovement_GetCostsForMove(const CvUnit* pUnit, const CvPlot* pFromPlot, const CvPlot* pToPlot, int iBaseMoves, int& iRegularCost, int& iRouteCost, int& iRouteFlatCost);static void AfterCvUnitMovement_GetCostsForMove(const CvUnit* pUnit, const CvPlot* pFromPlot, const CvPlot* pToPlot, int iBaseMoves, int& iRegularCost, int& iRouteCost, int& iRouteFlatCost);static void ReplaceCvUnitMovement_GetCostsForMove(void (*original)(const CvUnit*, const CvPlot*, const CvPlot*, int, int&, int&, int&), const CvUnit* pUnit, const CvPlot* pFromPlot, const CvPlot* pToPlot, int iBaseMoves, int& iRegularCost, int& iRouteCost, int& iRouteFlatCost);CivRegisterBefore<CivHooks::CvUnitMovement_GetCostsForMove>(host, &BeforeCvUnitMovement_GetCostsForMove);CivRegisterAfter<CivHooks::CvUnitMovement_GetCostsForMove>(host, &AfterCvUnitMovement_GetCostsForMove);CivRegisterReplace<CivHooks::CvUnitMovement_GetCostsForMove>(host, &ReplaceCvUnitMovement_GetCostsForMove);
Code
9void CvUnitMovement::GetCostsForMove(const CvUnit* pUnit, const CvPlot* pFromPlot, const CvPlot* pToPlot, int iBaseMoves, int& iRegularCost, int& iRouteCost, int& iRouteFlatCost)10{11 CvPlayerAI& kPlayer = GET_PLAYER(pUnit->getOwner());12 CvPlayerTraits* pTraits = kPlayer.GetPlayerTraits();13 bool bFasterAlongRiver = pTraits->IsFasterAlongRiver();14 bool bFasterInHills = pTraits->IsFasterInHills();15 bool bIgnoreTerrainCost = pUnit->ignoreTerrainCost();16 //int iBaseMoves = pUnit->baseMoves(isWater()?DOMAIN_SEA:NO_DOMAIN);17 TeamTypes eUnitTeam = pUnit->getTeam();18 CvTeam& kUnitTeam = GET_TEAM(eUnitTeam);19 int iMoveDenominator = GC.getMOVE_DENOMINATOR();20 bool bRiverCrossing = pFromPlot->isRiverCrossing(directionXY(pFromPlot, pToPlot));21 FeatureTypes eFeature = pToPlot->getFeatureType();22 CvFeatureInfo* pFeatureInfo = (eFeature > NO_FEATURE) ? GC.getFeatureInfo(eFeature) : 0;23 TerrainTypes eTerrain = pToPlot->getTerrainType();24 CvTerrainInfo* pTerrainInfo = (eTerrain > NO_TERRAIN) ? GC.getTerrainInfo(eTerrain) : 0;2526 if(bIgnoreTerrainCost || (bFasterAlongRiver && pToPlot->isRiver()) || (bFasterInHills && pToPlot->isHills()))27 {28 iRegularCost = 1;29 }30 else31 {32 iRegularCost = ((eFeature == NO_FEATURE) ? (pTerrainInfo ? pTerrainInfo->getMovementCost() : 0) : (pFeatureInfo ? pFeatureInfo->getMovementCost() : 0));3334 // Hill cost, except for when a City is present here, then it just counts as flat land35 if((PlotTypes)pToPlot->getPlotType() == PLOT_HILLS && !pToPlot->isCity())36 {37 iRegularCost += GC.getHILLS_EXTRA_MOVEMENT();38 }3940 if(iRegularCost > 0)41 {42 iRegularCost = std::max(1, (iRegularCost - pUnit->getExtraMoveDiscount()));43 }44 }4546 // Is a unit's movement consumed for entering rough terrain?47 if(pToPlot->isRoughGround() && pUnit->IsRoughTerrainEndsTurn())48 {49 iRegularCost = INT_MAX;50 }5152 else53 {54 if(!(bIgnoreTerrainCost || bFasterAlongRiver) && bRiverCrossing)55 {56 iRegularCost += GC.getRIVER_EXTRA_MOVEMENT();57 }5859 iRegularCost *= iMoveDenominator;6061 if(pToPlot->isHills() && pUnit->isHillsDoubleMove())62 {63 iRegularCost /= 2;64 }6566 else if((eFeature == NO_FEATURE) ? pUnit->isTerrainDoubleMove(eTerrain) : pUnit->isFeatureDoubleMove(eFeature))67 {68 iRegularCost /= 2;69 }7071#if defined(MOD_PROMOTIONS_HALF_MOVE)72 else if((pToPlot->getFeatureType() == NO_FEATURE) ? pUnit->isTerrainHalfMove(pToPlot->getTerrainType()) : pUnit->isFeatureHalfMove(pToPlot->getFeatureType()))73 {74 iRegularCost *= 2;75 }76#endif77 }7879 iRegularCost = std::min(iRegularCost, (iBaseMoves * iMoveDenominator));8081 if(pFromPlot->isValidRoute(pUnit) && pToPlot->isValidRoute(pUnit) && ((kUnitTeam.isBridgeBuilding() || !(pFromPlot->isRiverCrossing(directionXY(pFromPlot, pToPlot))))))82 {83 CvRouteInfo* pFromRouteInfo = GC.getRouteInfo(pFromPlot->getRouteType());84 CvAssert(pFromRouteInfo != NULL);8586 int iFromMovementCost = (pFromRouteInfo != NULL)? pFromRouteInfo->getMovementCost() : 0;87 int iFromFlatMovementCost = (pFromRouteInfo != NULL)? pFromRouteInfo->getFlatMovementCost() : 0;8889 CvRouteInfo* pRouteInfo = GC.getRouteInfo(pToPlot->getRouteType());90 CvAssert(pRouteInfo != NULL);9192 int iMovementCost = (pRouteInfo != NULL)? pRouteInfo->getMovementCost() : 0;93 int iFlatMovementCost = (pRouteInfo != NULL)? pRouteInfo->getFlatMovementCost() : 0;9495 iRouteCost = std::max(iFromMovementCost + kUnitTeam.getRouteChange(pFromPlot->getRouteType()), iMovementCost + kUnitTeam.getRouteChange(pToPlot->getRouteType()));96 iRouteFlatCost = std::max(iFromFlatMovementCost * iBaseMoves, iFlatMovementCost * iBaseMoves);97 }98 else if(pUnit->getOwner() == pToPlot->getOwner() && (eFeature == FEATURE_FOREST || eFeature == FEATURE_JUNGLE) && pTraits->IsMoveFriendlyWoodsAsRoad())99 {100 CvRouteInfo* pRoadInfo = GC.getRouteInfo(ROUTE_ROAD);101 iRouteCost = pRoadInfo->getMovementCost();102 iRouteFlatCost = pRoadInfo->getFlatMovementCost() * iBaseMoves;103 }104 else105 {106 iRouteCost = INT_MAX;107 iRouteFlatCost = INT_MAX;108 }109110 TeamTypes eTeam = pToPlot->getTeam();111 if(eTeam != NO_TEAM)112 {113 CvTeam* pPlotTeam = &GET_TEAM(eTeam);114 CvPlayer* pPlotPlayer = &GET_PLAYER(pToPlot->getOwner());115116 // Great Wall increases movement cost by 1117 if(pPlotTeam->isBorderObstacle() || pPlotPlayer->isBorderObstacle())118 {119 if(!pToPlot->isWater() && pUnit->getDomainType() == DOMAIN_LAND)120 {121 // Don't apply penalty to OUR team or teams we've given open borders to122 if(eUnitTeam != eTeam && !pPlotTeam->IsAllowsOpenBordersToTeam(eUnitTeam))123 {124 iRegularCost += iMoveDenominator;125 }126 }127 }128 }129}