.. well at least it somewhat changed them . And yes, just about all of them too .
I just had a closer look at the way latitudes are generated by map scripts. There is a method CvPlot::getLatitude(), which generates a value between 0..90 and there are several problems with it. .. well I found two :
1) plot.getLatitude() divides by GridHeight instead of (GridHeight-1), which results into the absence of the northpole. .. or at least the highest row of plots won't have the latitude 90 as would be expected. To illustrate this, here is an example for a map with height 6 (yes it's a very small map):
For heights (0,1,2,3,4,5) plot.getLatitude() generates something like (90,60,30,0,30,60) with a south pole @ 0 and an equator @ 3, but no north pole. What should be generated is (90,54,18,18,54,90) with the equator between 2 and 3 and poles at both ends.
2) Actually what plot.getLatitude() will generate is (90,62,31,0,28,59), because of rounding errors introduced by using only int and multiplying/dividing by 100.
Here is the Python pseudo-code of how it is now
Here is the Python pseudo-code of how it should be
I'm not quite done here as the designers were pretty consistent in the way latitudes are calculated. In CvMapGeneratorUtil.py both, the TerrainGenerator and the FeatureGenerator make the same error of using (getGridWidth()) instead of (getGridWidth()-1). Only two lines need changing though.
Note that unless the mod provides it's own CvMapGeneratorUtil.py, the map generator uses the one in ..civilization 4\warlords\assets\python if installed or ..civilization 4\assets\python - BtS doesn't provide it's own.
Also note that TerrainGenerator deliberately returns a fuzzy result.
Changes in CvMapGeneratorUtil.py
At last a modified fractal.py map script for you to play with (that's what we do, don't we). Start a game and look into '...\My Documents\My Games\Beyond the Sword\Logs\PythonDbg.log' to see the results of different latitude generators.
I just had a closer look at the way latitudes are generated by map scripts. There is a method CvPlot::getLatitude(), which generates a value between 0..90 and there are several problems with it. .. well I found two :
1) plot.getLatitude() divides by GridHeight instead of (GridHeight-1), which results into the absence of the northpole. .. or at least the highest row of plots won't have the latitude 90 as would be expected. To illustrate this, here is an example for a map with height 6 (yes it's a very small map):
For heights (0,1,2,3,4,5) plot.getLatitude() generates something like (90,60,30,0,30,60) with a south pole @ 0 and an equator @ 3, but no north pole. What should be generated is (90,54,18,18,54,90) with the equator between 2 and 3 and poles at both ends.
2) Actually what plot.getLatitude() will generate is (90,62,31,0,28,59), because of rounding errors introduced by using only int and multiplying/dividing by 100.
Here is the Python pseudo-code of how it is now
Spoiler :
Code:
# get latitude 0..90 for given plot - corrects error in build-in plot.getLatitude()
# Precision really should be 10000 or greater!
def getLatitude( plot ):
if CyMap().isWrapX() or (not CyMap().isWrapY()):
iLat = plot.getY() * 100 / CyMap().getGridHeight()
else:
iLat = plot.getX() * 100 / CyMap().getGridWidth()
iLat = iLat * ( CyMap().getTopLatitude() - CyMap().getBottomLatitude() ) / 100
return abs( iLat + CyMap().getBottomLatitude() )
Spoiler :
Code:
# get latitude 0..90 for given plot - corrects error in build-in plot.getLatitude()
# using float - this gives the best results
def floatGetLatitude( plot ):
if CyMap().isWrapX() or (not CyMap().isWrapY()):
iLat = float(plot.getY()) / (CyMap().getGridHeight() - 1)
else:
iLat = float(plot.getX()) / (CyMap().getGridWidth() - 1)
iLat = iLat * ( CyMap().getTopLatitude() - CyMap().getBottomLatitude() )
return abs( int( round( iLat + CyMap().getBottomLatitude() ) ) )
Note that unless the mod provides it's own CvMapGeneratorUtil.py, the map generator uses the one in ..civilization 4\warlords\assets\python if installed or ..civilization 4\assets\python - BtS doesn't provide it's own.
Also note that TerrainGenerator deliberately returns a fuzzy result.
Changes in CvMapGeneratorUtil.py
Spoiler :
Code:
CvMapGeneratorUtil.TerrainGenerator.getLatitudeAtPlot():
# lat = abs((self.iHeight / 2) - iY)/float(self.iHeight/2) # 0.0 = equator, 1.0 = pole
lat = abs( ( (self.iHeight-1)/2.0 ) - iY ) / ( (self.iHeight-1)/2.0 ) # 0.0 = equator, 1.0 = pole
CvMapGeneratorUtil.FeatureGenerator.getLatitudeAtPlot():
# return abs((self.iGridH/2) - iY)/float(self.iGridH/2) # 0.0 = equator, 1.0 = pole
return abs( ( (self.iGridH-1)/2.0 ) - iY ) / ( (self.iGridH-1)/2.0 ) # 0.0 = equator, 1.0 = pole