//compares the vector (start,destA) with (start,destB). returns a value between 0 (perfect agreement) and 60 (polar opposite direction) int angularDeviation(int iStartX, int iStartY, int iDestAX, int iDestAY, int iDestBX, int iDestBY) { //undefined if (iStartX==iDestAX && iStartY==iDestAY) return 0; if (iStartX==iDestBX && iStartY==iDestBY) return 0; int iStartXHex = xToHexspaceX(iStartX,iStartY); int iDestAXHex = xToHexspaceX(iDestAX,iDestAY); int iDestBXHex = xToHexspaceX(iDestBX,iDestBY); int iDXA = dxWrap(iDestAXHex - iStartXHex); int iDYA = dyWrap(iDestAY - iStartY); int iDXB = dxWrap(iDestBXHex - iStartXHex); int iDYB = dyWrap(iDestBY - iStartY); //reconstruct the Z coordinate int iStartZ = -iStartXHex-iStartY; int iDestAZ = -iDestAXHex-iDestAY; int iDestBZ = -iDestBXHex-iDestBY; int iDZA = iDestAZ - iStartZ; int iDZB = iDestBZ - iStartZ; float fRawDotProduct = (float) iDXA *iDXB + iDYA * iDYB + iDZA * iDZB; float fNormA2 = (float) iDXA*iDXA + iDYA*iDYA + iDZA*iDZA; float fNormB2 = (float) iDXB*iDXB + iDYB*iDYB + iDZB*iDZB; //this should be between -1 and +1 float fNormDotProduct = fRawDotProduct / sqrtf( fNormA2*fNormB2 ); //this should be between 0 and 60 return (int)((fNormDotProduct-1)*(-30)); }
int plotCityXY(const CvCity* pCity, const CvPlot* pPlot) { int iDX; int iWrappedDX = dxWrap(pPlot->getX() - pCity->getX()); int iWrappedDY = dyWrap(pPlot->getY() - pCity->getY()); int iDY = iWrappedDY; // convert to hex-space coordinates - the coordinate system axes are E and NE (not orthogonal) int iCityHexX = xToHexspaceX(pCity->getX(), pCity->getY()); int iPlotHexX = xToHexspaceX(pCity->getX() + iWrappedDX, pCity->getY() + iWrappedDY); iDX = dxWrap(iPlotHexX - iCityHexX); #if defined(MOD_GLOBAL_CITY_WORKING) if(hexDistance(iDX, iDY) > pCity->getWorkPlotDistance()) #else if(hexDistance(iDX, iDY) > CITY_PLOTS_RADIUS) #endif { return -1; } else { #if defined(MOD_GLOBAL_CITY_WORKING) // Regardless of the working radius, we need to offset into the array by the maximum radius return GC.getXYCityPlot((iDX + MAX_CITY_RADIUS), (iDY + MAX_CITY_RADIUS)); #else return GC.getXYCityPlot((iDX + CITY_PLOTS_RADIUS), (iDY + CITY_PLOTS_RADIUS)); #endif } }
int plotDistance(int iX1, int iY1, int iX2, int iY2) { int iX1H = xToHexspaceX(iX1,iY1); int iX2H = xToHexspaceX(iX2,iY2); //reconstruct the Z coordinate int iZ1H = -iX1H-iY1; int iZ2H = -iX2H-iY2; int iDX = dxWrap(iX2H - iX1H); int iDY = dyWrap(iY2 - iY1); int iDZ = dxWrap(iZ2H - iZ1H); //this is by design, dx and dz have the same range return (abs(iDX) + abs(iDY) + abs(iDZ)) / 2; }
int getRingIterationIndex(const CvPlot* pCenter, const CvPlot* pPlot) { int iWrappedDX = dxWrap(pPlot->getX() - pCenter->getX()); int iWrappedDY = dyWrap(pPlot->getY() - pCenter->getY()); // convert to hex-space coordinates - the coordinate system axes are E and NE (not orthogonal) int iCenterHexX = xToHexspaceX(pCenter->getX(), pCenter->getY()); int iPlotHexX = xToHexspaceX(pCenter->getX() + iWrappedDX, pCenter->getY() + iWrappedDY); int iDX = dxWrap(iPlotHexX - iCenterHexX); int iDY = iWrappedDY; // Regardless of the working radius, we need to offset into the array by the maximum radius return GC.getRingIterationIndexHex((iDX + MAX_CITY_RADIUS), (iDY + MAX_CITY_RADIUS)); }
DirectionTypes estimateDirection(int iStartX, int iStartY, int iDestX, int iDestY) { int iStartXHex = xToHexspaceX(iStartX,iStartY); int iDestXHex = xToHexspaceX(iDestX,iDestY); int iDX = dxWrap(iDestXHex - iStartXHex); int iDY = dyWrap(iDestY - iStartY); //undefined if (iDX==0 && iDY==0) return NO_DIRECTION; //reconstruct the Z coordinate int iStartZ = -iStartXHex-iStartY; int iDestZ = -iDestXHex-iDestY; int iDZ = iDestZ - iStartZ; float maximum = 0; int maximumIndex = -1; for(int i=0; i<6; i++) { float dotProduct = iDX * hexspaceDirections[i][0] + iDY * hexspaceDirections[i][1] + iDZ * hexspaceDirections[i][2]; if(dotProduct > maximum) { maximum = dotProduct; maximumIndex = i; } } return (DirectionTypes)maximumIndex; }
int plotCityXY(const CvCity* pCity, const CvPlot* pPlot) { int iDX; int iWrappedDX = dxWrap(pPlot->getX() - pCity->getX()); int iWrappedDY = dyWrap(pPlot->getY() - pCity->getY()); int iDY = iWrappedDY; // convert to hex-space coordinates - the coordinate system axes are E and NE (not orthogonal) int iCityHexX = xToHexspaceX(pCity->getX(), pCity->getY()); int iPlotHexX = xToHexspaceX(pCity->getX() + iWrappedDX, pCity->getY() + iWrappedDY); iDX = dxWrap(iPlotHexX - iCityHexX); if(hexDistance(iDX, iDY) > CITY_PLOTS_RADIUS) { return -1; } else { return GC.getXYCityPlot((iDX + CITY_PLOTS_RADIUS), (iDY + CITY_PLOTS_RADIUS)); } }
///TKs Med CvCity* CvMap::findCity(int iX, int iY, PlayerTypes eOwner, TeamTypes eTeam, bool bSameArea, bool bCoastalOnly, TeamTypes eTeamAtWarWith, DirectionTypes eDirection, CvCity* pSkipCity, bool bRandom) { int iBestValue = MAX_INT; CvCity* pBestCity = NULL; std::vector<CvCity*> aCitys; for (int iI = 0; iI < MAX_PLAYERS; iI++) { if (GET_PLAYER((PlayerTypes)iI).isAlive()) { if ((eOwner == NO_PLAYER) || (iI == eOwner)) { if ((eTeam == NO_TEAM) || (GET_PLAYER((PlayerTypes)iI).getTeam() == eTeam)) { int iLoop; for (CvCity* pLoopCity = GET_PLAYER((PlayerTypes)iI).firstCity(&iLoop); pLoopCity != NULL; pLoopCity = GET_PLAYER((PlayerTypes)iI).nextCity(&iLoop)) { if (!bSameArea || (pLoopCity->area() == plotINLINE(iX, iY)->area()) || (bCoastalOnly && (pLoopCity->waterArea() == plotINLINE(iX, iY)->area()))) { if (!bCoastalOnly || pLoopCity->isCoastal(GC.getMIN_WATER_SIZE_FOR_OCEAN())) { if ((eTeamAtWarWith == NO_TEAM) || atWar(GET_PLAYER((PlayerTypes)iI).getTeam(), eTeamAtWarWith)) { if ((eDirection == NO_DIRECTION) || (estimateDirection(dxWrap(pLoopCity->getX_INLINE() - iX), dyWrap(pLoopCity->getY_INLINE() - iY)) == eDirection)) { if ((pSkipCity == NULL) || (pLoopCity != pSkipCity)) { if (!bRandom) { int iValue = plotDistance(iX, iY, pLoopCity->getX_INLINE(), pLoopCity->getY_INLINE()); if (iValue < iBestValue) { iBestValue = iValue; pBestCity = pLoopCity; } } else { aCitys.push_back(pLoopCity); } } } } } } } } } } } if (bRandom) { int iRandom = aCitys.size(); if (iRandom >= 1) { iRandom = GC.getGameINLINE().getSorenRandNum(iRandom, "Random Find City"); return aCitys[iRandom]; } else { return NULL; } } return pBestCity; }
int cyDxWrap(int iDX) { return dxWrap(iDX); }