Bazaar developer reference

IgnoreUnitsCost(CvAStarNode *, CvAStarNode *, int, const void *, CvAStar *)

Defined in
CvAStar.cpp, line 1705
Hook name
CivHooks::IgnoreUnitsCost

Hooks

static bool BeforeIgnoreUnitsCost(CvAStarNode* parent, CvAStarNode* node, int data, const void* pointer, CvAStar* finder, int& result);static void AfterIgnoreUnitsCost(CvAStarNode* parent, CvAStarNode* node, int data, const void* pointer, CvAStar* finder, int& result);static int ReplaceIgnoreUnitsCost(int (*original)(CvAStarNode*, CvAStarNode*, int, const void*, CvAStar*), CvAStarNode* parent, CvAStarNode* node, int data, const void* pointer, CvAStar* finder);CivRegisterBefore<CivHooks::IgnoreUnitsCost>(host, &BeforeIgnoreUnitsCost);CivRegisterAfter<CivHooks::IgnoreUnitsCost>(host, &AfterIgnoreUnitsCost);CivRegisterReplace<CivHooks::IgnoreUnitsCost>(host, &ReplaceIgnoreUnitsCost);

Code

1704/// Ignore units path finder - compute cost of a path1705int IgnoreUnitsCost(CvAStarNode* parent, CvAStarNode* node, int data, const void* pointer, CvAStar* finder)1706{1707	CvUnit* pUnit;1708	int iCost;1709	int iMax;17101711	CvMap& kMap = GC.getMap();1712	int iFromPlotX = parent->m_iX;1713	int iFromPlotY = parent->m_iY;1714	CvPlot* pFromPlot = kMap.plotUnchecked(iFromPlotX, iFromPlotY);17151716	int iToPlotX = node->m_iX;1717	int iToPlotY = node->m_iY;1718	CvPlot* pToPlot = kMap.plotUnchecked(iToPlotX, iToPlotY);17191720	pUnit = ((CvUnit*)pointer);1721	const UnitPathCacheData* pCacheData = reinterpret_cast<const UnitPathCacheData*>(finder->GetScratchBuffer());17221723	CvAssertMsg(pUnit->getDomainType() != DOMAIN_AIR, "pUnit->getDomainType() is not expected to be equal with DOMAIN_AIR");17241725	if(parent->m_iData1 > 0)1726	{1727		iMax = parent->m_iData1;1728	}1729	else1730	{1731		iMax = pCacheData->baseMoves((pToPlot->isWater() && !pToPlot->IsAllowsWalkWater()) ? DOMAIN_SEA : DOMAIN_LAND) * GC.getMOVE_DENOMINATOR();1732	}17331734	// Get the cost of moving to the new plot, passing in our max moves or the moves we have left, in case the movementCost 1735	// method wants to burn all our remaining moves.  This is needed because our remaining moves for this segment of the path1736	// may be larger or smaller than the baseMoves if some moves have already been used or if the starting domain (LAND/SEA)1737	// of the path segment is different from the destination plot.1738	iCost = CvUnitMovement::MovementCostNoZOC(pUnit, pFromPlot, pToPlot, pCacheData->baseMoves((pToPlot->isWater() || pCacheData->isEmbarked())?DOMAIN_SEA:pCacheData->getDomainType()), pCacheData->maxMoves(), iMax);17391740	TeamTypes eUnitTeam = pUnit->getTeam();17411742	int iMovesLeft = iMax - iCost;1743	// Is the cost greater than our max?1744	if (iMovesLeft < 0)1745	{1746		// Yes, we will still let the move happen, but that is the end of the turn.1747		iCost = iMax;1748		iMovesLeft = 0;1749	}17501751	if(iMovesLeft == 0)1752	{1753		iCost = (PATH_MOVEMENT_WEIGHT * iCost);17541755#if defined(MOD_PATHFINDER_TERRAFIRMA)1756		bool bFromTerraFirma = pFromPlot->isTerraFirma(pUnit);1757		bool bToWater = !pToPlot->isTerraFirma(pUnit);1758		if(bFromTerraFirma && bToWater && !pUnit->canEmbarkOnto(*pFromPlot, *pToPlot, true))1759#else1760		if(!pFromPlot->isWater() && pToPlot->isWater() && !pUnit->canEmbarkOnto(*pFromPlot, *pToPlot, true))1761#endif1762		{1763			iCost += PATH_INCORRECT_EMBARKING_WEIGHT;1764		}17651766		if(pToPlot->getTeam() != eUnitTeam)1767		{1768			iCost += PATH_TERRITORY_WEIGHT;1769		}17701771		if(finder->GetInfo() & MOVE_MAXIMIZE_EXPLORE)1772		{1773			if(!pToPlot->isHills())1774			{1775				iCost += PATH_EXPLORE_NON_HILL_WEIGHT;1776			}1777		}17781779		// Damage caused by features (mods)1780		if(0 != GC.getPATH_DAMAGE_WEIGHT())1781		{1782			if(pToPlot->getFeatureType() != NO_FEATURE)1783			{1784#if defined(MOD_UNITS_MAX_HP)1785			// We don't have the specific unit, so we'll just use the generic MAX_HIT_POINTS value1786#endif1787#if defined(MOD_API_PLOT_BASED_DAMAGE)1788				if (MOD_API_PLOT_BASED_DAMAGE) {1789					iCost += (GC.getPATH_DAMAGE_WEIGHT() * std::max(0, pToPlot->getTurnDamage(pUnit->ignoreTerrainDamage(), pUnit->ignoreFeatureDamage(), pUnit->extraTerrainDamage(), pUnit->extraFeatureDamage()))) / GC.getMAX_HIT_POINTS();1790				} else {1791#endif1792					iCost += (GC.getPATH_DAMAGE_WEIGHT() * std::max(0, GC.getFeatureInfo(pToPlot->getFeatureType())->getTurnDamage())) / GC.getMAX_HIT_POINTS();1793#if defined(MOD_API_PLOT_BASED_DAMAGE)1794				}1795#endif1796			}17971798			if(pToPlot->getExtraMovePathCost() > 0)1799			{1800				iCost += (PATH_MOVEMENT_WEIGHT * pToPlot->getExtraMovePathCost());1801			}1802		}18031804		if(pToPlot->getPlotCity() && !(pToPlot->getX() == finder->GetDestX() && pToPlot->getY() == finder->GetDestY()))1805		{1806			iCost += PATH_CITY_AVOID_WEIGHT; // slewis - this should be zeroed out currently1807		}1808	}1809	else1810	{1811		iCost = (PATH_MOVEMENT_WEIGHT * iCost);1812	}18131814	if(finder->GetInfo() & MOVE_MAXIMIZE_EXPLORE)1815	{1816		int iUnseenPlots = pToPlot->getNumAdjacentNonrevealed(eUnitTeam);1817		if(!pToPlot->isRevealed(eUnitTeam))1818		{1819			iUnseenPlots += 1;1820		}18211822		iCost += (7 - iUnseenPlots) * PATH_EXPLORE_NON_REVEAL_WEIGHT;1823	}18241825	// If we are a land unit and we are moving through the water, make the cost a little higher so that1826	// we favor staying on land or getting back to land as quickly as possible because it is dangerous to1827	// be on the water.  Don't add this penalty if the unit is human controlled however, we will assume they want1828	// the best path, rather than the safest.1829	if(pCacheData->getDomainType() == DOMAIN_LAND && (pToPlot->isWater() && !pToPlot->IsAllowsWalkWater()) && (!pCacheData->isHuman() || pUnit->IsAutomated()))1830	{1831		iCost += PATH_THROUGH_WATER;1832	}18331834	if(pUnit->IsCombatUnit())1835	{1836		if(iMovesLeft == 0)1837		{1838			iCost += (PATH_DEFENSE_WEIGHT * std::max(0, (200 - ((pUnit->noDefensiveBonus()) ? 0 : pToPlot->defenseModifier(eUnitTeam, false)))));1839		}18401841		if(pCacheData->IsAutomated())1842		{1843			if(pCacheData->IsCanAttack())1844			{1845				if(finder->IsPathDest(pToPlot->getX(), pToPlot->getY()))1846				{1847					if(pToPlot->isVisibleEnemyDefender(pUnit))1848					{1849						iCost += (PATH_DEFENSE_WEIGHT * std::max(0, (200 - ((pUnit->noDefensiveBonus()) ? 0 : pFromPlot->defenseModifier(eUnitTeam, false)))));18501851						// I guess we may as well be the garrison1852						if(!(pFromPlot->isCity()))1853						{1854							iCost += PATH_CITY_WEIGHT;1855						}18561857						if(!(pUnit->isRiverCrossingNoPenalty()))1858						{1859							if(pFromPlot->isRiverCrossing(directionXY(pFromPlot, pToPlot)))1860							{1861								iCost += (PATH_RIVER_WEIGHT * -(GC.getRIVER_ATTACK_MODIFIER()));1862								iCost += (PATH_MOVEMENT_WEIGHT * iMovesLeft);1863							}1864						}1865					}1866				}1867			}1868		}1869	}18701871	FAssert(iCost != MAX_INT);18721873	iCost += PATH_STEP_WEIGHT;18741875	FAssert(iCost > 0);18761877	return iCost;1878}

Calls

Called by