Hooks
static bool BeforeCvPlayer_DoUpdateProximityToPlayer(CvPlayer* self, PlayerTypes ePlayer);static void AfterCvPlayer_DoUpdateProximityToPlayer(CvPlayer* self, PlayerTypes ePlayer);static void ReplaceCvPlayer_DoUpdateProximityToPlayer(void (*original)(CvPlayer*, PlayerTypes), CvPlayer* self, PlayerTypes ePlayer);CivRegisterBefore<CivHooks::CvPlayer_DoUpdateProximityToPlayer>(host, &BeforeCvPlayer_DoUpdateProximityToPlayer);CivRegisterAfter<CivHooks::CvPlayer_DoUpdateProximityToPlayer>(host, &AfterCvPlayer_DoUpdateProximityToPlayer);CivRegisterReplace<CivHooks::CvPlayer_DoUpdateProximityToPlayer>(host, &ReplaceCvPlayer_DoUpdateProximityToPlayer);
Code
19184/// Figure out how "close" we are to another player (useful for diplomacy, war planning, etc.)19185void CvPlayer::DoUpdateProximityToPlayer(PlayerTypes ePlayer)19186{19187 CvAssertMsg(ePlayer >= 0, "eIndex is expected to be non-negative (invalid Index)");19188 CvAssertMsg(ePlayer < MAX_PLAYERS, "eIndex is expected to be within maximum bounds (invalid Index)");1918919190 int iSmallestDistanceBetweenCities = GC.getMap().numPlots();19191 int iAverageDistanceBetweenCities = 0;1919219193 int iNumCityConnections = 0;1919419195 CvCity* pLoopMyCity;19196 CvCity* pLoopTheirCity;1919719198 int iMyCityLoop;19199 int iTheirCityLoop;1920019201 int iTempDistance;1920219203 // Loop through all of MY Cities19204 for(pLoopMyCity = firstCity(&iMyCityLoop); pLoopMyCity != NULL; pLoopMyCity = nextCity(&iMyCityLoop))19205 {19206 // Loop through all of THEIR Cities19207 for(pLoopTheirCity = GET_PLAYER(ePlayer).firstCity(&iTheirCityLoop); pLoopTheirCity != NULL; pLoopTheirCity = GET_PLAYER(ePlayer).nextCity(&iTheirCityLoop))19208 {19209 iNumCityConnections++;1921019211 // Different area or couldn't find path - get distance the hard way19212 //if (!bPathFinderSuccess)19213 {19214 iTempDistance = plotDistance(pLoopMyCity->getX(), pLoopMyCity->getY(), pLoopTheirCity->getX(), pLoopTheirCity->getY());19215 }1921619217 // Smallest distance between any two Cities19218 if(iTempDistance < iSmallestDistanceBetweenCities)19219 {19220 iSmallestDistanceBetweenCities = iTempDistance;19221 }1922219223 iAverageDistanceBetweenCities += iTempDistance;19224 }19225 }1922619227 // Seed this value with something reasonable to start. This will be the value assigned if one player has 0 Cities.19228 PlayerProximityTypes eProximity = NO_PLAYER_PROXIMITY;1922919230 if(iNumCityConnections > 0)19231 {19232 iAverageDistanceBetweenCities /= iNumCityConnections;1923319234 // Closest Cities must be within a certain range19235 if(iSmallestDistanceBetweenCities <= /*7*/ GC.getPROXIMITY_NEIGHBORS_CLOSEST_CITY_REQUIREMENT())19236 {19237 eProximity = PLAYER_PROXIMITY_NEIGHBORS;19238 }19239 // If our closest Cities are pretty near one another and our average is less than the max then we can be considered CLOSE (will also look at City average below)19240 else if(iSmallestDistanceBetweenCities <= /*11*/ GC.getPROXIMITY_CLOSE_CLOSEST_CITY_POSSIBILITY())19241 {19242 eProximity = PLAYER_PROXIMITY_CLOSE;19243 }1924419245 // If we've already set ourselves as Neighbors, no need to undo what we just did19246 if(eProximity != PLAYER_PROXIMITY_NEIGHBORS)19247 {19248 int iMapFactor = (GC.getMap().getGridWidth() + GC.getMap().getGridHeight()) / 2;1924919250 // Normally base distance on map size, but cap it at a certain point19251 // Close can't be so big that it sits on Far's turf19252 int iCloseDistance = iMapFactor* /*25*/ GC.getPROXIMITY_CLOSE_DISTANCE_MAP_MULTIPLIER() / 100;19253 if(iCloseDistance > /*20*/ GC.getPROXIMITY_CLOSE_DISTANCE_MAX())19254 {19255 iCloseDistance = /*20*/ GC.getPROXIMITY_CLOSE_DISTANCE_MAX();19256 }19257 // Close also can't be so small that it sits on Neighbor's turf19258 else if(iCloseDistance < /*10*/ GC.getPROXIMITY_CLOSE_DISTANCE_MIN())19259 {19260 iCloseDistance = /*10*/ GC.getPROXIMITY_CLOSE_DISTANCE_MIN();19261 }1926219263 // Far can't be so big that it sits on Distant's turf19264 int iFarDistance = iMapFactor* /*45*/ GC.getPROXIMITY_FAR_DISTANCE_MAP_MULTIPLIER() / 100;19265 if(iFarDistance > /*50*/ GC.getPROXIMITY_FAR_DISTANCE_MAX())19266 {19267 iFarDistance = /*50*/ GC.getPROXIMITY_FAR_DISTANCE_MAX();19268 }19269 // Far also can't be so small that it sits on Close's turf19270 else if(iFarDistance < /*20*/ GC.getPROXIMITY_FAR_DISTANCE_MIN())19271 {19272 iFarDistance = /*20*/ GC.getPROXIMITY_FAR_DISTANCE_MIN();19273 }1927419275 // Close19276 if(eProximity == PLAYER_PROXIMITY_CLOSE && iAverageDistanceBetweenCities <= iCloseDistance)19277 {19278 eProximity = PLAYER_PROXIMITY_CLOSE;19279 }19280 // Far19281 else if(iAverageDistanceBetweenCities <= iFarDistance)19282 {19283 eProximity = PLAYER_PROXIMITY_FAR;19284 }19285 // Distant19286 else19287 {19288 eProximity = PLAYER_PROXIMITY_DISTANT;19289 }19290 }1929119292 // Players NOT on the same landmass - bump up PROXIMITY by one level (unless we're already distant or on a water map)19293 if(eProximity != PLAYER_PROXIMITY_DISTANT && !(GC.getMap().GetAIMapHint() & 1))19294 {19295 // Both players have capitals, so we can check their areas to see if they're separated by water19296 if(getCapitalCity() != NULL && GET_PLAYER(ePlayer).getCapitalCity() != NULL)19297 {19298 if(getCapitalCity()->getArea() != GET_PLAYER(ePlayer).getCapitalCity()->getArea())19299 {19300 eProximity = PlayerProximityTypes(eProximity - 1);19301 }19302 }19303 }19304 }1930519306 int iNumMajorsLeft = GC.getGame().countMajorCivsAlive();1930719308 // Only two players left, the farthest we can be considered is "Close"19309 if(iNumMajorsLeft == 2)19310 eProximity = max(eProximity, PLAYER_PROXIMITY_CLOSE);1931119312 // Four or fewer players left, the farthest we can be considered is "Far"19313 else if(iNumMajorsLeft <= 4)19314 eProximity = max(eProximity, PLAYER_PROXIMITY_FAR);1931519316 SetProximityToPlayer(ePlayer, eProximity);19317}