Bazaar developer reference

CvArmyAI::GetCenterOfMass(DomainTypes)

Defined in
CvArmyAI.cpp, line 218
Class
CvArmyAI
Hook name
CivHooks::CvArmyAI_GetCenterOfMass

Hooks

static bool BeforeCvArmyAI_GetCenterOfMass(CvArmyAI* self, DomainTypes eDomainRequired, CvPlot*& result);static void AfterCvArmyAI_GetCenterOfMass(CvArmyAI* self, DomainTypes eDomainRequired, CvPlot*& result);static CvPlot* ReplaceCvArmyAI_GetCenterOfMass(CvPlot* (*original)(CvArmyAI*, DomainTypes), CvArmyAI* self, DomainTypes eDomainRequired);CivRegisterBefore<CivHooks::CvArmyAI_GetCenterOfMass>(host, &BeforeCvArmyAI_GetCenterOfMass);CivRegisterAfter<CivHooks::CvArmyAI_GetCenterOfMass>(host, &AfterCvArmyAI_GetCenterOfMass);CivRegisterReplace<CivHooks::CvArmyAI_GetCenterOfMass>(host, &ReplaceCvArmyAI_GetCenterOfMass);

Code

217/// Get center of mass of units in army (account for world wrap!)218CvPlot* CvArmyAI::GetCenterOfMass(DomainTypes eDomainRequired)219{220	CvPlot* pRtnValue = NULL;221	int iTotalX = 0;222	int iTotalY = 0;223	int iNumUnits = 0;224	UnitHandle pUnit;225	int iReferenceUnitX = -1;226	int iWorldWidth = GC.getMap().getGridWidth();227228	pUnit = GetFirstUnit();229	if(pUnit)230	{231		iReferenceUnitX = pUnit->getX();232	}233234	while(pUnit)235	{236		int iUnitX = pUnit->getX();237238		bool bWorldWrapAdjust = false;239		int iDiff = iUnitX - iReferenceUnitX;240		if(abs(iDiff) > (iWorldWidth / 2))241		{242			bWorldWrapAdjust = true;243		}244245		if(bWorldWrapAdjust)246		{247			iTotalX += iUnitX + iWorldWidth;248		}249		else250		{251			iTotalX += iUnitX;252		}253		iTotalY += pUnit->getY();254		iNumUnits++;255		pUnit = GetNextUnit();256	}257258	if(iNumUnits > 0)259	{260		int iAverageX = (iTotalX + (iNumUnits / 2)) / iNumUnits;261		if(iAverageX >= iWorldWidth)262		{263			iAverageX = iAverageX - iWorldWidth;264		}265		int iAverageY = (iTotalY + (iNumUnits / 2)) / iNumUnits;266		pRtnValue = GC.getMap().plot(iAverageX, iAverageY);267	}268269	// Domain check270	if (eDomainRequired != NO_DOMAIN && pRtnValue)271	{272		if (pRtnValue->isWater() && eDomainRequired == DOMAIN_LAND || !pRtnValue->isWater() && eDomainRequired == DOMAIN_SEA)273		{274			// Find an adjacent plot that works275			for (int iI = 0; iI < NUM_DIRECTION_TYPES; iI++)276			{277				CvPlot *pLoopPlot = plotDirection(pRtnValue->getX(), pRtnValue->getY(), ((DirectionTypes)iI));278				if (pLoopPlot != NULL)279				{280					if (pLoopPlot->isWater() && eDomainRequired == DOMAIN_SEA || !pLoopPlot->isWater() && eDomainRequired == DOMAIN_LAND)281					{282						return pLoopPlot;283					}284				}285			}286287			// Try two plots out if really having problems288			for (int iDX = -2; iDX <= 2; iDX++)289			{290				for (int iDY = -2; iDY <= 2; iDY++)291				{292					CvPlot *pLoopPlot = plotXYWithRangeCheck(pRtnValue->getX(), pRtnValue->getY(), iDX, iDY, 2);293					if (pLoopPlot)294					{295						if (plotDistance(pRtnValue->getX(), pRtnValue->getY(), pLoopPlot->getX(), pLoopPlot->getY()) == 2)296						{297							if (pLoopPlot->isWater() && eDomainRequired == DOMAIN_SEA || !pLoopPlot->isWater() && eDomainRequired == DOMAIN_LAND)298							{299								return pLoopPlot;300							}301						}302					}303				}304			}305306			// Give up - just use location of first unit307			pUnit = GetFirstUnit();308			pRtnValue = pUnit->plot();309		}310	}311312	return pRtnValue;313}

Calls

Called by