--- Totestra-20120615.py	2012-06-15 23:12:48.000000000 -0500
+++ SandBar.py	2012-06-15 23:10:42.000000000 -0500
@@ -1,6 +1,5 @@
 ##############################################################################
-## File: Totestra.py version 20120615 (June 15, 2012)
-## Note: This is a finished product.  
+## File: SandBar.py version 20120612 (June 12, 2012)
 ## Original file: PerfectWorld.py version 2.06
 ## Author: Rich Marinaccio
 ## Modified by Sam Trenholme; I am assigning all copyright to Rich
@@ -49,13 +48,16 @@
 ##
 ##############################################################################
 ## Version History
-## Totestra - Sam Trenholme's update of PerfectWorld2.py
-##
-## 20120615:
-## 1) One-line bugfix for multi-player maps
+## SandBar - A version of Totestra/PerfectWorld to make maps for
+## Arabian mods (Legends of Ancients Arabia, Rhye's and Fall: 
+## The Sword of Islam, Crossroads of the World, etc.)
+##
+## 20120612: 
+## 1) Made map more Arabia-like: Much bigger tropics, more dry, no snowy peaks
+##    fewer map options, flat square map with roundish island on it which will
+##    probably connect on some parts at the edge of the map.  Lots of sand.
 ##
-## 20120612:
-## 1) Bugfix with rocky maps
+## Totestra - Sam Trenholme's update of PerfectWorld2.py
 ##
 ## 20120603:
 ## 1) The chance of a large continent splitting at the edge of the map
@@ -235,18 +237,19 @@
 import os
 
 # Options
-OPTION_MapSeed = 10
-OPTION_NewWorld = 0
-OPTION_Pangaea = 1
-OPTION_Wrap = 2
-OPTION_IslandFactor = 3
-OPTION_Patience = 4
-OPTION_MapRatio = 5
-OPTION_MapResources = 6
-OPTION_Handicap = 7
-OPTION_NoRotate = 8
-OPTION_SmoothPeaks = 9
-OPTION_MAX = OPTION_MapSeed + 1 # Add 1 because it's 1-indexed
+OPTION_Patience = 11 # Hidden
+OPTION_Huts = 0
+OPTION_MapResources = 1
+OPTION_Handicap = 2
+OPTION_Pangaea = 3 # HIDDEN
+OPTION_MapSeed = 4 # HIDDEN
+OPTION_Wrap = 5 # HIDDEN
+OPTION_NoRotate = 6 # HIDDEN
+OPTION_SmoothPeaks = 7 # HIDDEN
+OPTION_NewWorld = 8 # HIDDEN: Everyone always starts on same land
+OPTION_IslandFactor = 9 # HIDDEN
+OPTION_MapRatio = 10 # HIDDEN
+OPTION_MAX = OPTION_Handicap + 1 # Add 1 because it's 1-indexed
 
 # Setting this to 1 will allow the buggy 1:2 ratio; this ratio has
 # problems because of limitations in Civ 4's engine.  You have been warned.
@@ -317,7 +320,7 @@
 
         #This is the maximum chance for a tree to be placed when rainfall is above jungle level.
         #use a value between 0.0 and 1.0
-        self.MaxTreeChance = 1.0
+        self.MaxTreeChance = 0.3
 
         #How many squares are added to a lake for each unit of drainage flowing
         #into it.
@@ -340,15 +343,15 @@
                 
         #This value is used to decide if enough water has accumulated to form a river.
         #A lower value creates more rivers over the entire map.
-        self.RiverThreshold = 4
+        self.RiverThreshold = 5 # Lowered for Arab
         
         #The percent chance that an oasis may appear in desert. A tile must be desert and
         #surrounded on all sides by desert.
-        self.OasisChance = .08
+        self.OasisChance = .16 # Doubled for Arab map
 
         #This sets the amount of heat lost at the highest altitude. 1.0 loses all heat
         #0.0 loses no heat.
-        self.heatLostAtOne = 1.0
+        self.heatLostAtOne = 0.01 # Arab
         
         #This value is an exponent that controls the curve associated with
         #temperature loss. Higher values create a steeper curve.
@@ -356,13 +359,13 @@
         
         #Degrees latitude for the top and bottom of the map. This allows
         #for more specific climate zones
-        self.topLatitude = 90
-        self.bottomLatitude = -90
+        self.topLatitude = 30
+        self.bottomLatitude = -30
 
         #Horse latitudes and polar fronts plus and minus in case you
         #want some zones to be compressed or emphasized.
-        self.horseLatitude = 30
-        self.polarFrontLatitude = 60
+        self.horseLatitude = 60
+        self.polarFrontLatitude = 80
 
         #Tropics of Cancer and Capricorn plus and minus respectively
         #self.tropicsLatitude = 23
@@ -461,7 +464,7 @@
         #Too many meteors will simply destroy the Earth, and just
         #in case the meteor shower can't break the pangaea, this will also
         #prevent and endless loop.
-        self.maximumMeteorCount = 15
+        self.maximumMeteorCount = 7
         
         #Minimum size for a meteor strike that attemps to break pangaeas.
         #Don't bother to change this it will be overwritten depending on
@@ -547,15 +550,17 @@
         mmap = gc.getMap()
 
         # Sea level comes from preferences
+	# Made lower for Arabian mod ("high" sealevel is "normal" in Totestra)
         try:
             seaLevel = int(mmap.getSeaLevel())
         except:
             seaLevel = 1
-        self.landPercent = 0.29
+	seaLevel = 0 # Arab: Force high sea level
+        self.landPercent = 0.43
         if seaLevel == 0:
-            self.landPercent = 0.43
+            self.landPercent = 0.65 # ARAB SEA LEVEL
         elif seaLevel == 2:
-            self.landPercent = 0.19
+            self.landPercent = 0.29
 
         self.serviceFlags = 0 # Used for concise description of flags
 	if(seaLevel != 0):
@@ -565,7 +570,7 @@
       
         # Have climate affect the maps 
         # This is increased for a "tropical" climate
-        self.tropicsLatitude = 23
+        self.tropicsLatitude = 61 # Arab land is very tropical
  
         # These are increased for "rocky" climates
         #How many land squares will be above peak threshold and thus 'peaks'.
@@ -574,13 +579,13 @@
         #How many land squares will be above hill threshold and thus 'hills' 
         #unless hey are also above peak threshold in which case they will 
         #be 'peaks'.
-        self.HillPercent = 0.35
+        self.HillPercent = 0.23
         
         #In addition to the relative peak and hill generation, there is also a
         #process that changes flats to hills or peaks based on altitude. This tends
         #to randomize the high altitude areas somewhat and improve their appearance.
         #These variables control the frequency of hills and peaks at the highest altitude.
-        self.HillChanceAtOne = .50
+        self.HillChanceAtOne = .43
         self.PeakChanceAtOne = .27
 
         #How many land squares will be below desert rainfall threshold. In this case,
@@ -612,15 +617,16 @@
         # Temperate: 0 Tropical: 1 Arid: 2 Rocky: 3 Cold: 4
         self.iceChance = 1.0 # Chance of having iceberg at top/bottom of map
         self.iceRange = 4 # Number of squares we add icebergs to
-        self.iceSlope = 0.66 # How quickly we reduce icebergs
-        clim = mmap.getClimate() 
+        self.iceSlope = 0 # Very little ice on an Arabian map
+        #clim = mmap.getClimate() 
+	clim = 2 # Always Arid for Arabia
         if clim == 1: # Tropical
-            self.tropicsLatitude = 46
+            self.tropicsLatitude = 61
 	    self.iceSlope = 0.33 # Less ice
         elif clim == 2: # Arid
-            self.DesertPercent = 0.40
-            self.PlainsPercent = 0.82
-	    self.iceSlope = 0.33 # Less ice
+            self.DesertPercent = 0.61
+            self.PlainsPercent = 0.83
+	    self.iceSlope = 0 # Almost no ice
         elif clim == 3: # Rocky
             self.PeakPercent = 0.24
             self.HillPercent = 0.70
@@ -643,6 +649,7 @@
       
         #New World Rules
         selectionID = mmap.getCustomMapOption(OPTION_NewWorld)
+	selectionID = 2 # We always share the continent for LoAA
         self.AllowNewWorld = True
 	self.ShareContinent = False
         if selectionID == 1:
@@ -658,6 +665,7 @@
 
         #Pangaea Rules
         selectionID = mmap.getCustomMapOption(OPTION_Pangaea)
+	selectionID = 0 # Have meteors on Arab maps
         self.AllowPangeas = False
         if selectionID == 1:
             self.AllowPangeas = True
@@ -665,8 +673,11 @@
         self.serviceFlags <<= 1
         self.serviceFlags |= (self.AllowPangeas & 1) # 1 bit; total 7
 
+        self.nohuts = mmap.getCustomMapOption(OPTION_Huts)
+
         # How long are they willing to wait for the map to be made
-        patience = mmap.getCustomMapOption(OPTION_Patience)
+        #patience = mmap.getCustomMapOption(OPTION_Patience)
+	patience = 1 # Sand Bar fixed value
         patience += 1 # Patience at 0 is broken
 
 	# This allows me to have one final usable bit in the service tag
@@ -676,11 +687,10 @@
         # The preset worlds have hard-coded values
         selectionID = mmap.getCustomMapOption(OPTION_MapSeed)
 
-        # Disabled: we will only alter seed (it's now for debugging)
+        # DISABLED; no more Caulixtla!
         #if selectionID != 0:
-            #patience = 2
-            #if selectionID != 3:
-            #    self.landPercent = 0.29 # We will force this here too
+        #    patience = 2
+        #    self.landPercent = 0.29 # We will force this here too
 
         self.patience = patience
         #Size of largest map increment to begin midpoint displacement. Must
@@ -696,41 +706,24 @@
         # slower the map generation process
 
         # X and Y values for the map's aspect ratio
-	ratioValue = mmap.getCustomMapOption(OPTION_MapRatio)
-	if 1 == 2: # Dummy, does nothing, so we don't get elif problems
-		self.ratioX = 3
-		self.ratioY = 2
-        elif ratioValue == 0: # 2:3
-		self.ratioX = 2
-		self.ratioY = 3
-        elif ratioValue == 1: # 1:1
+	# We use OPTION_Wrap here because the map type affects the ratio
+	# Wrapping maps are *always* 3:2; Flat maps are always square
+	ratioValue = mmap.getCustomMapOption(OPTION_Wrap)
+	ratioValue = 0 # Hard-coded in SandBar
+        if ratioValue == 0: # 1:1
 		self.ratioX = 2
 		self.ratioY = 2
-	elif ratioValue == 2: # 3:2
+	elif ratioValue == 1: # 3:2
 		self.ratioX = 3
 		self.ratioY = 2
-	elif ratioValue == 3: # 2:1
-		self.ratioX = 4
-		self.ratioY = 2
-	elif ratioValue == 4: # 7:1, Ringworld 
-		self.ratioX = 7
-		self.ratioY = 1
-	elif ratioValue == 5: # 3:3, Big square (untested)
-		self.ratioX = 3
-		self.ratioY = 3
-        elif ratioValue == 6: # 1:2; down here because it's buggy
-		self.ratioX = 2
-		self.ratioY = 4
-
-	if patience < 2:
-        	self.ratioX = 3 # One less thing to SQA
-        	self.ratioY = 2
 
         self.serviceFlags <<= 3
         self.serviceFlags |= (ratioValue & 7) # 3 bits; total 13
 
         selectionID = mmap.getCustomMapOption(OPTION_IslandFactor)
 
+	selectionID = 0 # We hide this option for Arabian maps
+	# Arabia really wants as few islands as possible
         self.serviceFlags <<= 2
         self.serviceFlags |= (selectionID & 3) # Island factor
 
@@ -750,6 +743,7 @@
          
         #Wrap options
         selectionID = mmap.getCustomMapOption(OPTION_Wrap)
+	selectionID = 0 # No wrap (forced in SandBar)
         wrapString = "Cylindrical"
 	self.WrapX = True
 	self.WrapY = False
@@ -784,16 +778,18 @@
         self.BonusBonus = 1.0
 	self.spreadResources = False 
 	bonus_add = mmap.getCustomMapOption(OPTION_MapResources)
-	if bonus_add == 1: # More evenly spread out
+	if bonus_add == 0: # More evenly spread out
 		self.BonusBonus = 0.7 # Compensate for spread's increase
 		self.spreadResources = True # Increases resources
-	if bonus_add == 2: # Full of resources
+	if bonus_add == 1: # Full of resources
 		self.BonusBonus = 1.5 # Increases resources
 		self.spreadResources = True # Increases resources more
 	self.xtraFlags |= ((bonus_add & 3) << 2)
        
-        self.noRotate = mmap.getCustomMapOption(OPTION_NoRotate)
-	self.smoothPeaks = mmap.getCustomMapOption(OPTION_SmoothPeaks)
+        #self.noRotate = mmap.getCustomMapOption(OPTION_NoRotate)
+        self.noRotate = 0
+	#self.smoothPeaks = mmap.getCustomMapOption(OPTION_SmoothPeaks)
+	self.smoothPeaks = 1 # Forced for Arabian maps
  
         #After generating the heightmap, bands of ocean can be added to the map
         #to allow a more consistent climate generation. These bands are useful
@@ -811,62 +807,27 @@
         self.eastCrop = 0
         self.westCrop = 0
 
-        if selectionID == 1 or selectionID == 3: #Toroidal
-            self.hmHeight -= 1
-            self.WrapY = True
-	    if selectionID == 1:
-                self.iceChance *= 0.1
-            self.northWaterBand = 0
-            self.northCrop = 0
-            self.southWaterBand = 0
-            self.southCrop = 0
-            wrapString = "Toroidal"
-        elif selectionID == 2: #Flat
+        if selectionID == 0: #Flat
             self.hmWidth += 1
             self.WrapX = False
             wrapString = "Flat"
        
         # Random seed options (fixed or random)
         selectionID = mmap.getCustomMapOption(OPTION_MapSeed)
+	selectionID = 0 # Always random for now
         mapRString = "Random"
         self.totestra = 0 
-        if selectionID == 1: # Totestra
-            self.totestra = 8885098498360902 # Fixed map seed
-            #mapRstring = "Totestra"
-            # Ignore most map parameters
-            #self.wrapX = True
-            #self.wrapY = False
-            #wrapString = "Cylindrical"
-            #self.hmWidth = 240
-            #self.hmHeight = 161
-            #heightmap_size_factor = 5
-            #self.AllowPangeas = False
-        elif selectionID == 2: # Cephalo
-            self.totestra = 4316490043753041 # Fixed map seed
-            #mapRstring = "Cephalo"
-            # Ignore most map parameters
-            #self.wrapX = True
-            #self.wrapY = False
-            #wrapString = "Cylindrical"
-            #self.hmWidth = 144
-            #self.hmHeight = 97
-            #heightmap_size_factor = 3
-            #self.AllowPangeas = False
-        elif selectionID == 3: # Caulixtla
+        if selectionID == 1: # Caulixtla
             self.totestra = 8939185639133313 # Fixed map seed
-            #mapRstring = "Caulixtla"
+            mapRstring = "Caulixtla"
             # Ignore most map parameters
-            #self.wrapX = True
-            #self.wrapY = False
-            #wrapString = "Cylindrical"
-            #self.hmWidth = 144
-            #self.hmHeight = 97
-            #heightmap_size_factor = 3
-            #self.AllowPangeas = False
-	elif selectionID == 4: # En Dotter 1
-            self.totestra = 0x8f3d2735334af # En Dotter's low on resources map 
-	elif selectionID == 5:
-	    self.totestra = 0x1fcdc6f76b8c1b# En Dotter's nearby starts map
+            self.wrapX = True
+            self.wrapY = False
+            wrapString = "Cylindrical"
+            self.hmWidth = 144
+            self.hmHeight = 97
+            heightmap_size_factor = 3
+            self.AllowPangeas = False
 
         #Number of tectonic plates
         self.hmNumberOfPlates = int(float(self.hmWidth * self.hmHeight) * 0.0016)
@@ -1080,6 +1041,8 @@
                 fMap[GetIndexGeneral(x,y,width,height)] -= minAlt
     #add minAlt to maxAlt also before scaling entire map
     maxAlt -= minAlt
+    if maxAlt == 0:
+	maxAlt = 1 # Avoid division by 0
     scaler = 1.0/maxAlt
     for y in range(height):
         for x in range(width):
@@ -1489,7 +1452,8 @@
             x,y = peaksSEList[n]
             i = GetHmIndex(x,y)
             self.heightMap[i] = 1.0
-            
+        
+	self.rotateMap(0.8) # LETS HAVE FUN 
         self.printInitialPeaks()
 
         #Now use a diamond-square algorithm(sort of) to generate the rest
@@ -1785,16 +1749,14 @@
 
         NormalizeMap(self.heightMap,mc.hmWidth,mc.hmHeight)
 
-    def rotateMap(self):
-
-	if mc.noRotate != 0:
-		return
+    def rotateMap(self,edgewater):
 
         # This rotates a map east or west so that the map wraps around where
         # the lowest vertical band is on the map
 	low = 0
 	min = 10000.0
 
+
 	# Find the place on the map with the most water (lowest heightfield)
         for x in range(mc.hmWidth):
 		sum = 0.0
@@ -1815,6 +1777,40 @@
 			self.heightMap[GetHmIndex(x,y)] = tempStripe[
 				((x + low) % mc.hmWidth)]
 
+	# Lower the height map near the poles, since it looks weird in
+	# Arabian maps. Also remove land near map edge (again, weird)
+	# on square maps
+        for x in range(mc.hmWidth):
+		for y in range(mc.hmHeight):
+			if mc.WrapX == False: # Square map
+				# Left and right 1/16 percent get lowered
+				factor = float((x + 0.0) / (mc.hmWidth + 0.0))
+				factor -= 0.5
+				if factor < 0:
+					factor = -factor	
+				factor = 0.5 - factor
+				factor *= 2
+				factor += PRand.random() * 0.1
+				if factor > 1:
+					factor = 1
+				q = self.heightMap[GetHmIndex(x,y)]
+				q = (q * edgewater) + (q * 
+					(1.0 - edgewater) * factor)
+				self.heightMap[GetHmIndex(x,y)] = q
+
+			# Top and bottom 1/16 percent get lowered
+			factor = float((y + 0.0) / (mc.hmHeight + 0.0))
+			factor -= 0.5
+			if factor < 0:
+				factor = -factor	
+			factor = 0.5 - factor
+			factor *= 2
+			factor += PRand.random() * 0.1 
+			if factor > 1:
+				factor = 1
+			q = self.heightMap[GetHmIndex(x,y)]
+			q = (q * edgewater) + (q * (1.0 - edgewater) * factor)
+			self.heightMap[GetHmIndex(x,y)] = q
 	# Done
 	return
 
@@ -2129,7 +2125,7 @@
         temperatureList.sort(lambda x,y:cmp(x.order,y.order))
           
         #Drop summer monsoon rains
-        self.dropRain(temperatureList,self.summerTempsMap,False,None)
+        self.DropRain(temperatureList,self.summerTempsMap,False,None)
 
         #clear moisture map
         for i in range(mc.hmHeight*mc.hmWidth):
@@ -2146,7 +2142,7 @@
         temperatureList.sort(lambda x,y:cmp(x.order,y.order))
           
         #Drop winter monsoon rains
-        self.dropRain(temperatureList,self.winterTempsMap,False,None)
+        self.DropRain(temperatureList,self.winterTempsMap,False,None)
 
         #clear moisture map
         for i in range(mc.hmHeight*mc.hmWidth):
@@ -2191,7 +2187,7 @@
         orderList.sort(lambda x,y:cmp(x.order,y.order))
 
         #drop geostrophic rain            
-        self.dropRain(orderList,self.averageTempMap,True,wz)
+        self.DropRain(orderList,self.averageTempMap,True,wz)
         
 
         NormalizeMap(self.rainFallMap,mc.hmWidth,mc.hmHeight)
@@ -2200,7 +2196,7 @@
 ##        self.printRainFallMap(False)
         
                 
-    def dropRain(self,plotList, tempMap, bGeostrophic, windZones):
+    def DropRain(self,plotList, tempMap, bGeostrophic, windZones):
         countRemaining = len(plotList)
         bDebug = False
         for plot in plotList:
@@ -2608,8 +2604,10 @@
                     self.plotMap[i] = mc.LAND
                 elif altDiff < peakHeight:
                     self.plotMap[i] = mc.HILLS
-                else:
+                elif PRand.random() < 0.3: # Arab hack
                     self.plotMap[i] = mc.PEAK
+		else:
+                    self.plotMap[i] = mc.HILLS
 
         #Randomize high altitude areas
         for y in range(mc.height):
@@ -2694,33 +2692,26 @@
 
                 #instead of harsh thresholds, allow a random deviation chance
                 #based on how close to the threshold the rainfall is
+		# Simplified for Arab maps -- Sam
                 elif self.rainFallMap[i] < self.desertThreshold:
-                    if self.averageTempMap[i] < mc.SnowTemp:
-                        self.terrainMap[i] = mc.SNOW
-                    elif self.averageTempMap[i] < mc.TundraTemp:
-                        self.terrainMap[i] = mc.TUNDRA
+                    if PRand.random() < 0.9: # 90% chance of desert
+                        self.terrainMap[i] = mc.DESERT
                     else:
-                        if self.rainFallMap[i] < (PRand.random() * (self.desertThreshold - minRain) + self.desertThreshold - minRain)/2.0 + minRain:
-                            self.terrainMap[i] = mc.DESERT
-                        else:
-                            self.terrainMap[i] = mc.PLAINS
+                        self.terrainMap[i] = mc.PLAINS
                 elif self.rainFallMap[i] < self.plainsThreshold:
-                    if self.averageTempMap[i] < mc.SnowTemp:
-                        self.terrainMap[i] = mc.SNOW
-                    elif self.averageTempMap[i] < mc.TundraTemp:
-                        self.terrainMap[i] = mc.TUNDRA
-                    else:
-                        if self.rainFallMap[i] < ((PRand.random() * (self.plainsThreshold - self.desertThreshold) + self.plainsThreshold - self.desertThreshold))/2.0 + self.desertThreshold: 
+                        if PRand.random() < 0.7: # 70% chance of plains
                             self.terrainMap[i] = mc.PLAINS
+			elif PRand.random() < 0.7: # 10% chance of desert
+                            self.terrainMap[i] = mc.DESERT
                         else:
                             self.terrainMap[i] = mc.GRASS
                 else:
-                    if self.averageTempMap[i] < mc.SnowTemp:
-                        self.terrainMap[i] = mc.SNOW
-                    elif self.averageTempMap[i] < mc.TundraTemp:
-                        self.terrainMap[i] = mc.TUNDRA
-                    else:
-                        self.terrainMap[i] = mc.GRASS
+			if PRand.random() < 0.7: # 70% chance of grass
+                            self.terrainMap[i] = mc.GRASS
+			elif PRand.random() < 0.9: # 20% chance of plains
+                            self.terrainMap[i] = mc.PLAINS
+			else: # 5% chance (roughly)
+			    self.terrainMap[i] = mc.DESERT
 
         #Make sure ice is always higher than tundra, and tundra is always higher than
         #everything else. Also, desert does not blend well with these so change it.
@@ -2865,7 +2856,7 @@
         self.areaMap.defineAreas(isHmWaterMatch)
 ##        self.areaMap.PrintAreaMap()
         meteorCount = 0
-        while not mc.AllowPangeas and self.isPangea() and meteorCount < mc.maximumMeteorCount:
+        while not mc.AllowPangeas and self.isPangea() and meteorCount < mc.maximumMeteorCount: 
             pangeaDetected = True
             x,y = self.getMeteorStrike()
             print "A meteor has struck the Earth at %(x)d, %(y)d!!" % {"x":x,"y":y}
@@ -2881,7 +2872,7 @@
             
         if meteorThrown:
             print "The age of dinosours has come to a cataclysmic end."
-        if meteorCount == 15:
+        if meteorCount >= 7:
             print "Maximum meteor count of %d has been reached. Pangaea may still exist." % meteorCount
         if mc.AllowPangeas:
             print "Pangeas are allowed on this map and will not be suppressed."
@@ -3086,7 +3077,7 @@
         return distance
     def castMeteorUponTheEarth(self,x,y):
 ##        starttime = time.clock()
-        radius = PRand.randint(mc.minimumMeteorSize,max(mc.minimumMeteorSize + 1,mc.hmWidth/16))
+        radius = PRand.randint(mc.minimumMeteorSize,max(mc.minimumMeteorSize + 1,mc.hmWidth/16)) 
         circlePointList = self.getCirclePoints(x,y,radius)
 ##        print "circlePointList"
 ##        print circlePointList
@@ -3099,7 +3090,7 @@
             else:
                 x2 = circlePointList[n].x
                 x1 = circlePointList[n + 1].x
-            self.drawCraterLine(x1,x2,cy)
+            self.drawCraterLine(x1,x2,cy,n,len(circlePointList))
             
 ##        for n in range(0,len(circlePointList),2): not needed since this is happening on heightmap only
 ##            cy = circlePointList[n].y
@@ -3120,13 +3111,28 @@
 ##                i = GetHmIndex(x,y)
 ##                sm.terrainMap[i] = mc.COAST                   
 ##        return
-    def drawCraterLine(self,x1,x2,y):
+    def drawCraterLine(self,x1,x2,y,q,qmax):
+	factorY = float((q + 0.0) / (qmax + 0.0))
+	factorY -= 0.5
+	if factorY < 0:
+		factorY = -factorY
+	factorY *= 2
+	factorY *= factorY
         if y < 0 or y >= mc.hmHeight:
             return
         for x in range(x1,x2 + 1):
+	    delta = x2 + 1 - x1
+	    factorX = float((x + 0.0 - x1) / (delta + 0.0))
+	    factorX -= 0.5
+	    if(factorX < 0):
+		factorX = -factorX
+	    factorX *= 2
+	    factorX *= factorX
             i = GetHmIndex(x,y)
 ##            sm.terrainMap[i] = mc.OCEAN
-            hm.heightMap[i] = 0.0
+            #hm.heightMap[i] = 0.0
+            hm.heightMap[i] *= factorY
+            hm.heightMap[i] *= factorX
 ##            sm.plotMap[i] = mc.OCEAN
         return
 ##    def hasLandNeighbor(self,x,y): not needed since this is happening on heightmap only
@@ -5484,6 +5490,8 @@
             return "Continent amount"
         elif optionID == OPTION_Patience:
             return "Patience amount"
+        elif optionID == OPTION_Huts:
+            return "Tribal huts"
         elif optionID == OPTION_MapRatio:
             return "Map ratio"
         elif optionID == OPTION_Handicap:
@@ -5491,7 +5499,7 @@
 	elif optionID == OPTION_MapResources:
 	    return "Map resources"
 	elif optionID == OPTION_NoRotate:
-	    return "Wrap land"
+	    return "IGNORE"
 	elif optionID == OPTION_SmoothPeaks:
 	    return "Reduce Mountains"
 
@@ -5509,23 +5517,22 @@
         elif optionID == OPTION_Pangaea:
             return 2
         elif optionID == OPTION_Wrap:
-            return 4
+            return 2
         elif optionID == OPTION_MapSeed: # Map world
-            return 6
+            return 2
         elif optionID == OPTION_IslandFactor: # Number continents
             return 4
+	elif optionID == OPTION_Huts:
+	    return 2
         elif optionID == OPTION_Patience: # Speed/quality tradeoff
 	    # Slow but good disabled: Causes infinite loops
             return 2
         elif optionID == OPTION_MapRatio: # Map ratio
-	    if ALLOW_EXTREME_RATIOS == 1:
-	    	return 7 
-	    else:
-                return 6
+	    return 2 
         elif optionID == OPTION_Handicap:
 	    return 4
 	elif optionID == OPTION_MapResources:
-	    return 3
+	    return 2
 	elif optionID == OPTION_NoRotate:
 	    return 2
 	elif optionID == OPTION_SmoothPeaks:
@@ -5554,27 +5561,15 @@
         elif selectionID == 1:
             return "Allow Pangaeas"
     elif optionID == OPTION_Wrap:
-        if selectionID == 0:
+        if selectionID == 1:
             return "Cylindrical"
-        elif selectionID == 1:
-            return "Toroidal"
-        elif selectionID == 2:
+        elif selectionID == 0:
             return "Flat"
-	elif selectionID == 3:
-	    return "Toric w/ ice band"
     elif optionID == OPTION_MapSeed:
         if selectionID == 0:
             return "Random"
         elif selectionID == 1:
-            return "Preset #1 (Totestra)"
-        if selectionID == 2:
-            return "Preset #2 (Cephalo)"
-        elif selectionID == 3:
-            return "Preset #3 (Caulixtla)"
-	elif selectionID == 4:
-	    return "Preset #4 (En Dotter 1)"
-	elif selectionID == 5:
-	    return "Preset #5 (En Dotter 2)"
+            return "Caulixtla"
     elif optionID == OPTION_IslandFactor:
         if selectionID == 0:
             return "Few (faster)"
@@ -5584,6 +5579,11 @@
             return "Many"
         elif selectionID == 3:
             return "Lots (slow)"
+    elif optionID == OPTION_Huts:
+        if selectionID == 0:
+            return "Normal"
+        elif selectionID == 1:
+            return "None"
     elif optionID == OPTION_Patience:
         if selectionID == -1:
             return "Not very (Faster mapgen)"
@@ -5594,20 +5594,10 @@
         elif selectionID == 2:
             return "Extremely (nicer map)"
     elif optionID == OPTION_MapRatio: # Map ratio
-        if selectionID == 0: 
-            return "2:3 (Tall map)" 
-        elif selectionID == 1: 
+        if selectionID == 1: 
             return "1:1 (Square map)"
-        elif selectionID == 2:
+        elif selectionID == 0:
             return "3:2 (Earth-like)"
-        elif selectionID == 3:
-            return "2:1 (Wide map)"
-        elif selectionID == 6: 
-            return "1:2 (BUGGY)" 
-        elif selectionID == 4:
-            return "7:1 (Ringworld)"
-        elif selectionID == 5:
-            return "3:3 (Big square)"
     elif optionID == OPTION_Handicap:
 	if selectionID == 0:
 	    return "None (Player equal to AI)"
@@ -5618,11 +5608,11 @@
 	if selectionID == 3:
 	    return "Lots (Easier for player)"
     elif optionID == OPTION_MapResources:
-	if selectionID == 0:
+	if selectionID == 2:
 	    return "Like Perfect World"
+	if selectionID == 0:
+	    return "Some resources"
 	if selectionID == 1:
-	    return "Resources evenly spread"
-	if selectionID == 2:
 	    return "Full of resources"
     elif optionID == OPTION_NoRotate:
 	if selectionID == 0:
@@ -5647,7 +5637,7 @@
         if argsList[0] == OPTION_Patience:
             return 1 # Slow speed/good quality (Mark's default)
 	elif argsList[0] == OPTION_MapRatio:
-	    return 2 # 3:2 Earthlike map
+	    return 0 # 3:2 Earthlike map
 	elif argsList[0] == OPTION_SmoothPeaks:
 	    return 1 # By default, smooth coastal and other peaks
         else: # Everything else defaults to first choice
@@ -5688,10 +5678,10 @@
         GlobalThisIsAdvanced = 1
 	return 0
 def isClimateMap():
-	return 1
+	return 0 # Arabian maps don't allow climate to be set
 	
 def isSeaLevelMap():
-	return 1
+	return 0 # Sea level is fixed to high on Arab maps
     
 def getTopLatitude():
 	"Default is 90. 75 is past the Arctic Circle"
@@ -5747,12 +5737,15 @@
     hm.performTectonics()
     hm.generateHeightMap()
     hm.combineMaps()
+    hm.rotateMap(0.8) # Once
     hm.calculateSeaLevel()
     hm.fillInLakes()
     pb.breakPangaeas()
 ##    hm.Erode()
 ##    hm.printHeightMap()
-    hm.rotateMap()
+    hm.rotateMap(0.6) # Again
+    hm.calculateSeaLevel() # This also again
+    hm.rotateMap(0.8) # Again
     hm.addWaterBands()
 ##    hm.printHeightMap()
     cm.createClimateMaps()
@@ -6311,15 +6304,17 @@
     for y in range(iceRange):
         for x in range(mc.width):
             plot = mmap.plot(x,y)
-            if plot != 0 and plot.isWater() == True and PRand.random() < iceChance:
+            if (plot != 0 and plot.isWater() == True and 
+			PRand.random() < iceChance and mc.WrapX == True):
                 plot.setFeatureType(featureIce,0)
         iceChance *= iceSlope
     iceChance = mc.iceChance
     for y in range(mc.height - 1,mc.height - 1 - iceRange,-1):
         for x in range(mc.width):
             plot = mmap.plot(x,y)
-            if plot != 0 and plot.isWater() == True and PRand.random() < iceChance:
-                plot.setFeatureType(featureIce,0)
+            if (plot != 0 and plot.isWater() == True and PRand.random() < iceChance):
+		if mc.WrapX == True:
+                	plot.setFeatureType(featureIce,0)
                 if signadded == 0:
 			CyEngine().addSign(plot, -1, mc.serviceString)
 			print "Sign added at %d %d" % (x,y)
@@ -6329,7 +6324,7 @@
     if signadded == 0:
 	plot = mmap.plot(0,0)
 	CyEngine().addSign(plot, -1, mc.serviceString)    
-	print "Sign added at 0 0" % (x,y)
+	print "Sign added at 0 0"
 
 def addBonuses():
     bp.AddBonuses()
@@ -6343,6 +6338,10 @@
     print "Initializing Custom Map Options"
     mc.initInGameOptions()
     mc.initialize()
+def addGoodies(): # We need to be able to control whether the map has huts
+    # Got info from http://forums.civfanatics.com/showthread.php?t=149766
+    if(mc.nohuts != 1):
+	CyPythonMgr().allowDefaultImpl()
 
 ##mc.initialize()
 ##PRand.seed()
