# -*- coding: iso-8859-1 -*-
#
#	ORIGINAL MAP FILES:  Archipelago.py, Continents.py, Custom_Continents.py, Fractal.py, Hub.py, Inland_Sea.py, Islands.py, Lakes.py
#                            Maze.py, Pangaea.py, Ring.py, Shuffle.py, Terra.py, Wheel.py, Big_and_Small.py, Hemispheres.py, Medium_and_Small.py
#	AUTHORS:  Bob Thomas (Sirian), Soren Johnson, Andy Szybalski, Ben Sarsgard
#
#-----------------------------------------------------------------------------
#	Copyright (c) 2004, 2005, 2007 Firaxis Games, Inc. All rights reserved.
#-----------------------------------------------------------------------------
#
#       Customized by : Sto , EMAIL : <<<stoofisme<delete_me>@hotmail.com>>>
#                           , Forum : http://forums.civfanatics.com/showthread.php?t=151629
#
# Contributions and Thanks :
#
#		To AlanH :
#		Modified version for Mac OS X by AlanH : <<alanh<delete_me>@civfanatics.net>>
#		Mac OS X changes: _winreg calls replaced by Mac OS path definitions.
#		Mac OS X changes: Mac OS path uncompress definitions.
#		Mac OS X changes: python 2.4 sort calls replaced by Mac OS python 2.3 definitions.
#
#               To Bringa :
#               Many advise for FFH2 customization and feed backs
#
#               To FastWorker :
#               Many help for warlord compatibility ,tests and feed backs
#
#               To Balerion :
#               tests and feed backs
#
#               And also to all other peoples from civfanatics that helps me or give me some feed backs
#

def getVersion():
        return "3.00"

from CvPythonExtensions import *
import CvUtil
import CvMapGeneratorUtil
from CvMapGeneratorUtil import FractalWorld
from CvMapGeneratorUtil import MultilayeredFractal
from CvMapGeneratorUtil import HintedWorld
from CvMapGeneratorUtil import TerrainGenerator
from CvMapGeneratorUtil import FeatureGenerator
import os
import sys
import string
import cPickle as pickle
import CvEventInterface
import CvScreensInterface
import CvOptionsScreen
import CvOptionsScreenCallbackInterface
import types
from math import sqrt
import Popup as PyPopup
import traceback
import copy
import webbrowser
import urllib

if (sys.platform == 'darwin'):
        import sets
        def set(arg):
                return sets.Set(arg)
else:
        import _winreg
        import operator

selection = {}
launchScreenNumOptions = False
firstInitDebugFiles = True
XMLEntriesList = {}
XMLDescriptions = {}
bInitDescription = True
bGeneratingMap = False
hinted_world = None

##!_!## map generation
def beforeInit():
        global selGen
        global idMap
        global bScreen
        global bCanWriteLog
        global bGeneratingMap
        bGeneratingMap = True
        bScreen = True
        bCanWriteLog = bool(not CyGame().isPbem())

        initVersions()
        createStoDir()
        initStoFolder()
        initGenerationDebug()

        writeLog(" = beforeInit = ", False, [""])
        
        initGenerationGlobals()

        if isNetMP :
                selTemp = loadSelection("_Multiplayer_Config.cfg", False)
                if selTemp == -1 :
                        selGen = copy.deepcopy(defSel)
                        writeLog("", False, [" selGen : net MP can't read the config", ""])
                else :
                        selGen = dict(selTemp)
                        writeLog("", False, [" selGen : net MP config read (hope this is the good one)", ""])
        elif selection == {} :
                selTemp = loadSelection("_LastConfig.cfg", False)
                if selTemp == -1 :
                        selGen = copy.deepcopy(defSel)
                        writeLog("", False, [" selGen : selection reseted , can't read the config", ""])
                else :
                        selGen = dict(selTemp)
                        writeLog("", False, [" selGen : selection reseted , reading the last config saved", ""])
        else :
                selGen = checkSettings(copy.deepcopy(selection))
                writeLog("", False, [" selGen : use last defined selection", ""])

        bScreen = False
        logList = ["selGen :", ""]
        for sKey1 in sortKeys(selGen) :
                logList += ["%s :" %sKey1, ""]
                for sKey2 in sortKeys(selGen, sKey1) :
                        logList.append("%s :" %sKey2)
                        for sKey3 in sortKeys(selGen, sKey1 , sKey2) :
                                logList.append(" %s : %r" %(sKey3, selGen[sKey1][sKey2][sKey3]))
                        logList.append("")
                logList.append("")
        writeLog("", False, logList)

        logList = ["Game options :"]
        for iGameOption in range(gc.getNumGameOptionInfos()) :
                logList.append("%s : %r" %(gc.getGameOptionInfo(iGameOption).getType(), game.isOption(iGameOption)))
        logList.append("")
        writeLog("", False, logList)

        listMaps = [sKey for sKey in selGen["maps"].keys() if selGen["maps"][sKey]["selected"]]
        if listMaps == [] :
                writeLog("", False, [" no map selected ... choose at random"])
                listMaps = [sKey for sKey in selGen["maps"].keys()]

        writeLog("", False, [" list of maps : %r" %listMaps, ""])

        idMap = str(getRandSel(listMaps))
        writeLog("", True, [" map chosen : %s" %idMap, ""])

        initCustomMapOption()
        initWrap()

def getGridSize(argsList):
	if (argsList[0] == -1): # (-1,) is passed to function on loads
		return []

	listSize = [(6,4), (8,5), (10,6), (13,8), (16,10), (21,13), (26,16), (32,20), (38,24)]
	if idMap == "chess" : listSize = [(6,6), (9,6), (15,9), (21,12), (24,15), (27,18), (30,18), (33,21), (36,21), (39,24), (42,24), (45,27), (48,30)]
	elif idMap == "maze" : listSize = [(6,4), (9,4), (10,6), (14,8), (18,10), (24,14)]

	[eWorldSize] = argsList
	iWorldSize = int(eWorldSize)
	if not iWorldSize in range(6) :
                xSize = gc.getWorldInfo(iWorldSize).getGridWidth()
                ySize = gc.getWorldInfo(iWorldSize).getGridHeight()
                if idMap == "chess" :
                        diffAreas = [abs(xSize*ySize - item[0]*item[1]) for item in listSize]
                        tWorldSize = listSize[diffAreas.index(min(diffAreas))]
                else :
                        tWorldSize = (xSize, ySize)
        else :
                # chess, maze have a custom list . inlandsea, lakes are the smallest maps
                if idMap in ["hub", "pangaea", "ring", "wheel"] : iWorldSize += 1
                elif idMap in ["archipelago", "continents", "customcontinents", "fractals", "islands", "shuffle", "bigandsmall", "hemispheres", "mediumandsmall"] : iWorldSize += 2
                elif idMap in ["terra"] : iWorldSize += 3

                tWorldSize = listSize[iWorldSize]

        writeLog("getGridSize", True, [" world entry : %r , world int : %d , grid size : %r" %(eWorldSize, iWorldSize, tWorldSize)])

	return tWorldSize

def getWrapX():
        return wrapX
	
def getWrapY():
        return wrapY

def getTopLatitude():
        if bGeneratingMap :
                if idMap == "inlandsea" : return 60
                else : return 90
        return 90

def getBottomLatitude():
        if bGeneratingMap :
                if idMap == "inlandsea" : return -60
                else : return -90
        return -90

def isBonusIgnoreLatitude(): # warning called by StoAddBonuses
        if bGeneratingMap :
                if idMap in ["hub", "ring", "wheel"] : return True
                else : return not selGen["resources"]["resourcesgen"]["resspreadclimate"]
        return False

def beforeGeneration():
        initBeforeGenerationGlobals()

        global iNumConts
        global cont_data
        global xShiftRoll
        global yShiftRoll
        global bSuccessFlag
        global region_data
        global buffer_data
        global center_data
        global hub_data
        global templates
        global shuffledPlayers
        global iTemplateRoll
        global iNumRegions
        global iExtras
        global regions_in_use
        global remaining_regions
        global region_coords
        global isTeamGame
        global wheel_data
        global ySplitRoll
        global yPortionRoll
        global yShiftRoll1
        global yShiftRoll2

        #i prefer keep all different generations in one function ... Alleluia Alt-c
        #all comments are removed from the original scripts and can be read in the default map .
        if idMap == "customcontinents" :
                iPlayers = game.countCivPlayersEverAlive()
                iTeams = game.countCivTeamsEverAlive()
                bThisMapBalanced = False
                xShiftRoll = getRandNum(2, "FoR : Region Shift, Horizontal - Custom Continents PYTHON")
                yShiftRoll = getRandNum(2, "FoR : Region Shift, Vertical - Custom Continents PYTHON")
                userInputContinents = cmo[0]
                if userInputContinents > 1:
                        iNumConts = userInputContinents
                elif userInputContinents == 1:
                        bThisMapBalanced = True
                        if iTeams > 1 and iTeams < 7:
                                iNumConts = iTeams
                        elif iTeams < 2:
                                iNumConts = 2
                        elif iTeams <= 12:
                                iNumConts = int(iTeams / 2)
                        elif iTeams <= 18:
                                iNumConts = int(iTeams / 3)
                        else:
                                iNumConts = 6
                else:
                        numContsRoll = getRandNum(100, "FoR : Number of Continents - Custom Continents PYTHON")
                        byPlayerIndex = {2: [60, 90, 100, 111],
                                         3: [55, 85, 96, 100],
                                         4: [50, 80, 94, 99],
                                         5: [48, 78, 92, 98],
                                         6: [45, 75, 90, 96],
                                         7: [40, 70, 85, 95],
                                         8: [38, 68, 83, 94],
                                         9: [35, 65, 80, 92],
                                         10: [33, 60, 75, 90],
                                         11: [30, 55, 70, 88],
                                         12: [28, 53, 68, 86],
                                         13: [25, 50, 65, 85],
                                         14: [25, 45, 63, 85],
                                         15: [20, 40, 60, 80],
                                         16: [17, 35, 55, 75],
                                         17: [13, 30, 50, 70],
                                         18: [10, 25, 45, 65]
                        }
                        if numContsRoll < byPlayerIndex[iPlayers][0]:
                                iNumConts = 2
                        elif numContsRoll < byPlayerIndex[iPlayers][1]:
                                iNumConts = 3
                        elif numContsRoll < byPlayerIndex[iPlayers][2]:
                                iNumConts = 4
                        elif numContsRoll < byPlayerIndex[iPlayers][3]:
                                iNumConts = 5
                        else:
                                iNumConts = 6
                configs = [0, 0, 10, 9, 7, 6, 6]
                if bThisMapBalanced:
                        templateID = 0
                else:
                        templateID = getRandNum(configs[iNumConts], "FoR : Template - Custom Continents PYTHON")
                templates = {(2,0): {0: [2,
                                         [0.03, 0.47, 0.05, 0.65, 0, 0.3, False, True, 55, 23, 3, -1, -1, 11],
                                         [0.14, 0.36, 0.2, 0.5, 0, 0.3, False, True, 60, 1, 1, -1, -1, 7]],
                                     1: [2,
                                         [0.53, 0.97, 0.05, 0.65, 0, 0.3, False, True, 55, 23, 3, -1, -1, 11],
                                         [0.64, 0.86, 0.2, 0.5, 0, 0.3, False, True, 60, 1, 1, -1, -1, 7]]},
                             (2,1): {0: [7,
                                         [0.04, 0.6, 0.74, 0.9, 0.36, -0.64, False, False, 55, 2, 2, -1, -1, 7],
                                         [0.23, 0.41, 0.78, 0.86, 0.36, -0.64, False, False, 60, 1, 1, -1, -1, 5],
                                         [0.1, 0.3, 0.5, 0.9, 0.6, -0.4, False, False, 55, 1, 2, 6, 7, 7],
                                         [0.05, 0.35, 0.45, 0.95, 0.6, -0.4, False, False, 70, 3, 3, 6, 7, 7],
                                         [0.15, 0.5, 0.4, 0.6, 0.35, 0, False, False, 55, 1, 1, -1, -1, 7],
                                         [0.35, 0.5, 0.2, 0.55, 0.15, 0.25, False, False, 60, 2, 3, 6, 6, 5],
                                         [0.2, 0.4, 0.25, 0.4, 0.4, 0.35, False, False, 80, 4, 3, 6, 6, 5]],
                                     1: [5,
                                         [0.6, 0.9, 0.35, 0.45, -0.5, 0.2, False, False, 60, 1, 1, -1, -1, 7],
                                         [0.55, 0.95, 0.3, 0.5, -0.5, 0.2, False, False, 65, 3, 1, -1, -1, 7],
                                         [0.72, 0.85, 0.25, 0.85, -0.57, -0.1, False, False, 50, 1, 2, 6, 7, 7],
                                         [0.7, 0.9, 0.65, 0.85, -0.6, -0.5, False, False, 70, 3, 3, 6, 6, 7],
                                         [0.7, 0.95, 0.1, 0.3, -0.65, 0.6, False, False, 80, 4, 3, 6, 5, 5]]},
                             (2,2): {0: [7,
                                         [0.1, 0.9, 0.2, 0.3, 0, 0.5, False, False, 45, 1, 1, -1, -1, 3],
                                         [0.1, 0.9, 0.1, 0.4, 0, 0.5, False, False, 60, 2, 1, -1, -1, 5],
                                         [0.05, 0.3, 0.15, 0.6, 0, 0.25, False, False, 70, 2, 3, 6, 6, 5],
                                         [0.7, 0.95, 0.15, 0.6, 0, 0.25, False, False, 70, 2, 3, 6, 6, 5],
                                         [0.05, 0.3, 0.15, 0.6, 0, 0.25, False, False, 60, 4, 3, 6, 5, 5],
                                         [0.7, 0.95, 0.15, 0.6, 0, 0.25, False, False, 60, 4, 3, 6, 5, 5],
                                         [0.15, 0.5, 0.05, 0.2, 0.35, 0.75, True, False, 75, 3, 1, 6, 5, 3]],
                                     1: [4,
                                         [0.1, 0.9, 0.65, 0.95, 0, -0.6, False, False, 55, 2, 1, -1, -1, 5],
                                         [0.15, 0.85, 0.75, 0.85, 0, -0.6, False, False, 55, 1, 1, -1, -1, 3],
                                         [0.4, 0.6, 0.45, 0.85, 0, -0.3, False, False, 55, 2, 2, 6, 6, 5],
                                         [0.4, 0.6, 0.45, 0.95, 0, -0.4, False, False, 70, 4, 3, 6, 6, 5]]},
                             (2,3): {0: [3,
                                         [0.03, 0.57, 0.05, 0.75, 0.4, 0.2, False, True, 65, 2, 2, -1, -1, 11],
                                         [0.13, 0.47, 0.2, 0.7, 0.4, 0.1, False, True, 75, 4, 3, -1, -1, 7],
                                         [0.22, 0.38, 0.2, 0.6, 0.4, 0.2, False, True, 60, 1, 1, -1, -1, 7]],
                                     1: [3,
                                         [0.63, 0.97, 0.05, 0.75, -0.6, 0.2, False, True, 60, 2, 2, -1, -1, 9],
                                         [0.68, 0.92, 0.15, 0.65, -0.6, 0.2, False, True, 70, 4, 3, -1, -1, 7],
                                         [0.74, 0.86, 0.2, 0.6, -0.6, 0.2, False, True, 55, 1, 1, -1, -1, 5]]},
                             (2,4): {0: [7,
                                         [0.03, 0.47, 0.6, 0.95, 0.5, -0.55, False, False, 60, 2, 1, -1, -1, 9],
                                         [0.03, 0.37, 0.5, 0.95, 0.6, -0.45, False, False, 60, 2, 1, -1, -1, 7],
                                         [0.03, 0.27, 0.4, 0.85, 0.7, -0.25, False, False, 60, 2, 2, -1, -1, 7],
                                         [0.03, 0.17, 0.3, 0.75, 0.8, -0.05, False, False, 60, 2, 3, -1, -1, 5],
                                         [0.13, 0.57, 0.7, 0.95, 0.5, -0.65, False, False, 60, 1, 1, -1, -1, 7],
                                         [0.23, 0.67, 0.8, 0.95, 0.5, -0.75, False, False, 60, 1, 1, -1, -1, 5],
                                         [0.4, 0.6, 0.5, 0.65, 0, -0.15, False, False, 82, 4, 1, 6, 5, 5]],
                                     1: [8,
                                         [0.53, 0.97, 0.2, 0.55, -0.5, 0.25, False, False, 55, 2, 1, -1, -1, 9],
                                         [0.63, 0.97, 0.3, 0.65, -0.6, 0.05, False, False, 55, 2, 1, -1, -1, 7],
                                         [0.73, 0.97, 0.4, 0.75, -0.7, -0.15, False, False, 55, 2, 1, -1, -1, 7],
                                         [0.83, 0.97, 0.5, 0.85, -0.8, -0.35, False, False, 55, 2, 1, -1, -1, 5],
                                         [0.43, 0.87, 0.1, 0.45, -0.3, 0.45, False, False, 60, 2, 1, -1, -1, 7],
                                         [0.33, 0.77, 0.05, 0.35, -0.1, 0.6, False, False, 60, 2, 1, -1, -1, 7],
                                         [0.23, 0.67, 0.05, 0.25, 0.1, 0.7, False, False, 60, 2, 1, -1, -1, 5],
                                         [0.13, 0.57, 0.05, 0.15, 0.3, 0.8, False, False, 60, 1, 1, -1, -1, 3]]},
                             (2,5): {0: [4,
                                         [0.6, 0.95, 0.2, 0.65, -0.55, 0.15, False, False, 70, 2, 1, -1, -1, 9],
                                         [0.6, 0.95, 0.2, 0.65, -0.55, 0.15, False, False, 65, 2, 2, -1, -1, 9],
                                         [0.4, 0.9, 0.05, 0.45, -0.3, 0.5, False, False, 70, 3, 1, -1, -1, 7],
                                         [0.45, 0.85, 0.15, 0.35, -0.3, 0.5, False, False, 50, 1, 1, -1, -1, 3]],
                                     1: [5,
                                         [0.1, 0.5, 0.5, 0.9, 0.4, -0.4, False, False, 60, 3, 1, -1, -1, 9],
                                         [0.15, 0.45, 0.55, 0.85, 0.4, -0.4, False, False, 65, 1, 1, -1, -1, 7],
                                         [0.3, 0.8, 0.75, 0.95, -0.1, -0.7, False, False, 55, 1, 1, -1, -1, 3],
                                         [0.15, 0.25, 0.2, 0.7, 0.6, 0.1, False, False, 45, 1, 2, 6, 7, 3],
                                         [0.05, 0.35, 0.25, 0.65, 0.6, 0.1, False, False, 75, 4, 3, 6, 6, 5]]},
                             (2,6): {0: [3,
                                         [0.03, 0.77, 0.05, 0.45, 0.2, 0, True, False, 55, 2, 2, -1, -1, 7],
                                         [0.21, 0.59, 0.15, 0.35, 0.2, 0, True, False, 60, 1, 1, -1, -1, 5],
                                         [0.33, 0.47, 0.28, 0.52, 0, 0.2, False, False, 70, 3, 3, 6, 6, 3]],
                                     1: [3,
                                         [0.03, 0.77, 0.55, 0.95, 0.2, 0, True, False, 55, 2, 2, -1, -1, 7],
                                         [0.21, 0.59, 0.65, 0.85, 0.2, 0, True, False, 60, 1, 1, -1, -1, 5],
                                         [0.53, 0.67, 0.48, 0.72, 0, -0.2, False, False, 70, 3, 3, 6, 6, 3]]},
                             (2,7): {0: [8,
                                         [0.3, 0.4, 0.1, 0.9, 0.3, 0, False, True, 40, 1, 2, 6, 7, 5],
                                         [0.15, 0.45, 0.1, 0.3, 0.4, 0.6, False, True, 70, 3, 1, 6, 5, 3],
                                         [0.05, 0.4, 0.15, 0.3, 0.55, 0.2, False, True, 60, 1, 1, 6, 5, 3],
                                         [0.3, 0.65, 0.15, 0.3, 0.05, 0.2, False, True, 60, 1, 1, 6, 5, 3],
                                         [0.05, 0.4, 0.5, 0.65, 0.55, 0.2, False, True, 60, 1, 1, 6, 5, 3],
                                         [0.1, 0.25, 0.18, 0.42, 0.65, 0, False, True, 70, 14, 2, 5, 5, 3],
                                         [0.3, 0.65, 0.5, 0.65, 0.05, 0.2, False, True, 60, 1, 1, 6, 5, 3],
                                         [0.35, 0.6, 0.05, 0.35, 0.05, 0.6, False, True, 80, 34, 0, 6, 6, 5]],
                                     1: [3,
                                         [0.7, 0.95, 0.1, 0.7, -0.6, 0.2, False, True, 60, 24, 2, 6, 6, 5],
                                         [0.75, 0.9, 0.2, 0.6, -0.6, 0.2, False, True, 60, 1, 3, 6, 7, 5],
                                         [0.7, 0.95, 0.1, 0.4, -0.6, 0.5, False, True, 80, 34, 2, 6, 6, 3]]},
                             (2,8): {0: [5,
                                         [0.05, 0.6, 0.1, 0.25, 0.35, 0, False, False, 50, 1, 1, -1, -1, 3],
                                         [0.05, 0.6, 0.4, 0.6, 0.35, 0, False, False, 50, 1, 1, -1, -1, 3],
                                         [0.05, 0.6, 0.75, 0.9, 0.35, 0, False, False, 50, 1, 1, -1, -1, 3],
                                         [0.1, 0.25, 0.45, 0.9, 0.65, -0.35, False, False, 45, 1, 2, 5, 6, 3],
                                         [0.4, 0.55, 0.1, 0.55, 0.05, 0.35, False, False, 45, 1, 2, 5, 6, 3]],
                                     1: [4,
                                         [0.7, 0.95, 0.15, 0.45, -0.65, 0, False, False, 65, 24, 3, 6, 6, 3],
                                         [0.67, 0.98, 0.4, 0.6, -0.65, 0, False, False, 50, 1, 1, -1, -1, 3],
                                         [0.67, 0.8, 0.45, 0.9, -0.47, -0.35, False, False, 45, 1, 2, 5, 6, 3],
                                         [0.85, 0.98, 0.1, 0.55, -0.83, 0.35, False, False, 45, 1, 2, 5, 6, 3]]},
                             (2,9): {0: [3,
                                         [0.03, 0.77, 0.05, 0.7, 0.2, 0.25, True, False, 65, 3, 1, -1, -1, 11],
                                         [0.23, 0.57, 0.2, 0.55, 0.2, 0.25, True, False, 55, 12, 1, -1, -1, 7],
                                         [0.13, 0.67, 0.1, 0.65, 0.2, 0.25, True, False, 80, 34, 1, -1, -1, 9]],
                                     1: [3,
                                         [0.05, 0.65, 0.75, 0.95, 0.3, -0.7, False, False, 55, 2, 1, -1, -1, 5],
                                         [0.15, 0.55, 0.8, 0.9, 0.3, -0.7, True, False, 55, 12, 1, -1, -1, 3],
                                         [0.55, 0.85, 0.75, 0.95, -0.3, -0.7, False, False, 75, 34, 1, 6, 5, 3]]},
                             (3,0): {0: [2,
                                         [0.03, 0.48, 0.05, 0.56, 0, 0.39, False, False, 55, 23, 3, -1, -1, 9],
                                         [0.14, 0.36, 0.18, 0.43, 0, 0.39, False, False, 60, 1, 1, -1, -1, 5]],
                                     1: [2,
                                         [0.52, 0.97, 0.05, 0.56, 0, 0.39, False, False, 55, 23, 3, -1, -1, 9],
                                         [0.64, 0.86, 0.18, 0.43, 0, 0.39, False, False, 60, 1, 1, -1, -1, 5]],
                                     2: [2,
                                         [0.03, 0.83, 0.64, 0.93, 0.14, -0.57, True, False, 55, 23, 1, -1, -1, 9],
                                         [0.23, 0.63, 0.71, 0.86, 0.14, -0.57, True, False, 60, 1, 1, -1, -1, 5]]},
                             (3,1): {0: [2,
                                         [0.03, 0.57, 0.05, 0.46, 0.4, 0, False, False, 55, 13, 3, -1, -1, 9],
                                         [0.21, 0.39, 0.15, 0.36, 0.4, 0, False, False, 60, 1, 1, -1, -1, 5]],
                                     1: [2,
                                         [0.03, 0.57, 0.54, 0.95, 0.4, 0, False, False, 55, 13, 3, -1, -1, 9],
                                         [0.21, 0.39, 0.15, 0.36, 0.4, 0, False, False, 60, 1, 1, -1, -1, 5]],
                                     2: [3,
                                         [0.63, 0.97, 0.05, 0.7, -0.6, 0.25, False, False, 55, 13, 3, 6, 6, 9],
                                         [0.72, 0.88, 0.21, 0.54, -0.6, 0.25, False, False, 60, 1, 1, -1, -1, 5],
                                         [0.65, 0.95, 0.75, 0.9, -0.6, -0.65, False, False, 60, 34, 1, 5, 5, 3]]},
                             (3,2): {0: [3,
                                         [0.03, 0.57, 0.05, 0.75, 0.4, 0.2, False, True, 65, 2, 2, -1, -1, 11],
                                         [0.13, 0.47, 0.2, 0.7, 0.4, 0.1, False, True, 75, 4, 3, -1, -1, 7],
                                         [0.22, 0.38, 0.2, 0.6, 0.4, 0.2, False, True, 60, 1, 1, -1, -1, 7]],
                                     1: [3,
                                         [0.63, 0.97, 0.05, 0.5, -0.6, 0.45, False, False, 60, 2, 2, -1, -1, 5],
                                         [0.68, 0.92, 0.15, 0.4, -0.6, 0.45, False, False, 70, 4, 3, -1, -1, 5],
                                         [0.74, 0.86, 0.2, 0.35, -0.6, 0.45, False, False, 55, 1, 1, 6, 5, 3]],
                                     2: [2,
                                         [0.63, 0.97, 0.55, 0.9, -0.6, -0.45, False, False, 60, 23, 3, -1, -1, 5],
                                         [0.74, 0.86, 0.66, 0.88, -0.6, -0.45, False, False, 55, 1, 1, 6, 5, 3]]},
                             (3,3): {0: [5,
                                         [0.05, 0.45, 0.2, 0.3, 0, 0.5, False, False, 45, 1, 1, -1, -1, 3],
                                         [0.05, 0.45, 0.1, 0.4, 0, 0.5, False, False, 60, 23, 1, -1, -1, 5],
                                         [0.05, 0.3, 0.15, 0.6, 0, 0.25, False, False, 70, 2, 3, 6, 6, 5],
                                         [0.05, 0.3, 0.15, 0.6, 0, 0.25, False, False, 60, 4, 3, 6, 5, 5],
                                         [0.05, 0.25, 0.05, 0.2, 0.2, 0.75, True, False, 75, 3, 1, 6, 5, 3]],
                                     1: [5,
                                         [0.55, 0.95, 0.2, 0.3, 0, 0.5, False, False, 45, 1, 1, -1, -1, 3],
                                         [0.55, 0.95, 0.1, 0.4, 0, 0.5, False, False, 60, 23, 1, -1, -1, 5],
                                         [0.7, 0.95, 0.15, 0.6, 0, 0.25, False, False, 70, 2, 3, 6, 6, 5],
                                         [0.7, 0.95, 0.15, 0.6, 0, 0.25, False, False, 60, 4, 3, 6, 5, 5],
                                         [0.55, 0.75, 0.05, 0.2, 0.2, 0.75, True, False, 75, 3, 1, 6, 5, 3]],
                                     2: [4,
                                         [0.1, 0.9, 0.65, 0.95, 0, -0.6, False, False, 55, 2, 1, -1, -1, 5],
                                         [0.15, 0.85, 0.75, 0.85, 0, -0.6, False, False, 55, 1, 1, -1, -1, 3],
                                         [0.4, 0.6, 0.45, 0.85, 0, -0.3, False, False, 55, 2, 2, 6, 6, 5],
                                         [0.4, 0.6, 0.45, 0.95, 0, -0.4, False, False, 70, 4, 3, 6, 6, 5]]},
                             (3,4): {0: [7,
                                         [0.03, 0.47, 0.6, 0.95, 0.5, -0.55, False, False, 60, 2, 1, -1, -1, 9],
                                         [0.03, 0.37, 0.5, 0.95, 0.6, -0.45, False, False, 60, 2, 1, -1, -1, 7],
                                         [0.03, 0.27, 0.4, 0.85, 0.7, -0.25, False, False, 60, 2, 2, -1, -1, 7],
                                         [0.03, 0.17, 0.3, 0.75, 0.8, -0.05, False, False, 60, 2, 3, -1, -1, 5],
                                         [0.13, 0.57, 0.7, 0.95, 0.3, -0.65, False, False, 60, 1, 1, -1, -1, 7],
                                         [0.23, 0.67, 0.8, 0.95, 0.1, -0.75, False, False, 60, 1, 1, -1, -1, 5],
                                         [0.4, 0.6, 0.5, 0.65, 0, -0.15, False, False, 82, 4, 1, 6, 5, 5]],
                                     1: [5,
                                         [0.53, 0.97, 0.45, 0.55, -0.5, 0, False, False, 45, 1, 1, -1, -1, 3],
                                         [0.63, 0.97, 0.35, 0.65, -0.6, 0, False, False, 55, 23, 3, -1, -1, 5],
                                         [0.73, 0.97, 0.25, 0.75, -0.7, 0, False, False, 55, 2, 3, -1, -1, 7],
                                         [0.83, 0.97, 0.15, 0.85, -0.8, 0, False, False, 55, 2, 3, -1, -1, 5],
                                         [0.9, 0.97, 0.05, 0.95, -0.87, 0, False, False, 50, 1, 2, 5, 6, 3]],
                                     2: [5,
                                         [0.43, 0.47, 0.05, 0.5, 0.1, 0.45, False, False, 45, 1, 2, 5, 6, 1],
                                         [0.33, 0.57, 0.05, 0.4, 0.1, 0.55, False, False, 55, 2, 1, -1, -1, 3],
                                         [0.23, 0.67, 0.05, 0.3, 0.1, 0.65, False, False, 55, 2, 1, -1, -1, 5],
                                         [0.13, 0.77, 0.05, 0.2, 0.1, 0.75, False, False, 55, 2, 1, -1, -1, 3],
                                         [0.03, 0.87, 0.05, 0.1, 0.1, 0.85, False, False, 50, 1, 1, 7, 6, 1]]},
                             (3,5): {0: [4,
                                         [0.6, 0.95, 0.2, 0.65, -0.55, 0.15, False, False, 70, 2, 1, -1, -1, 9],
                                         [0.6, 0.95, 0.2, 0.65, -0.55, 0.15, False, False, 65, 23, 3, -1, -1, 9],
                                         [0.4, 0.9, 0.05, 0.45, -0.3, 0.5, False, False, 70, 3, 1, -1, -1, 7],
                                         [0.45, 0.85, 0.15, 0.35, -0.3, 0.5, False, False, 50, 1, 1, -1, -1, 3]],
                                     1: [2,
                                         [0.55, 0.95, 0.7, 0.9, -0.5, -0.6, False, False, 65, 34, 1, -1, -1, 3],
                                         [0.3, 0.9, 0.75, 0.95, -0.2, -0.7, False, False, 50, 1, 1, -1, -1, 3]],
                                     2: [4,
                                         [0.05, 0.25, 0.4, 0.9, 0.7, -0.3, False, False, 60, 13, 3, -1, -1, 5],
                                         [0.15, 0.45, 0.5, 0.65, 0.4, -0.15, False, False, 65, 1, 1, -1, -1, 3],
                                         [0.15, 0.25, 0.2, 0.6, 0.6, 0.2, False, False, 45, 1, 2, 5, 6, 3],
                                         [0.05, 0.35, 0.25, 0.65, 0.6, 0.1, False, False, 75, 4, 3, 6, 6, 5]]},
                             (3,6): {0: [6,
                                         [0.1, 0.2, 0.1, 0.9, 0, 0, False, False, 40, 1, 2, 5, 6, 3],
                                         [0.05, 0.47, 0.05, 0.35, 0, 0, False, False, 65, 23, 1, -1, -1, 5],
                                         [0.05, 0.47, 0.1, 0.25, 0, 0, False, False, 60, 1, 1, -1, -1, 3],
                                         [0.05, 0.47, 0.65, 0.95, 0, 0, False, False, 65, 23, 1, -1, -1, 5],
                                         [0.05, 0.47, 0.7, 0.95, 0, 0, False, False, 60, 1, 1, -1, -1, 3],
                                         [0.05, 0.25, 0.15, 0.85, 0, 0, False, False, 70, 4, 3, 5, 6, 3]],
                                     1: [2,
                                         [0.3, 0.7, 0.4, 0.6, 0, 0, False, False, 55, 14, 3, -1, -1, 5],
                                         [0.35, 0.65, 0.45, 0.55, 0, 0, False, False, 45, 1, 1, -1, -1, 3]],
                                     2: [6,
                                         [0.8, 0.9, 0.1, 0.9, 0, 0, False, False, 40, 1, 2, 5, 6, 3],
                                         [0.53, 0.95, 0.05, 0.35, 0, 0, False, False, 65, 23, 1, -1, -1, 5],
                                         [0.53, 0.95, 0.1, 0.25, 0, 0, False, False, 60, 1, 1, -1, -1, 3],
                                         [0.53, 0.95, 0.65, 0.95, 0, 0, False, False, 65, 23, 1, -1, -1, 5],
                                         [0.53, 0.95, 0.7, 0.95, 0, 0, False, False, 60, 1, 1, -1, -1, 3],
                                         [0.75, 0.95, 0.15, 0.85, 0, 0, False, False, 70, 4, 3, 5, 6, 3]]},
                             (3,7): {0: [3,
                                         [0.03, 0.77, 0.05, 0.7, 0.2, 0.25, True, False, 65, 3, 1, -1, -1, 11],
                                         [0.23, 0.57, 0.2, 0.55, 0.2, 0.25, True, False, 55, 12, 1, -1, -1, 7],
                                         [0.13, 0.67, 0.1, 0.65, 0.2, 0.25, True, False, 80, 34, 1, -1, -1, 9]],
                                     1: [3,
                                         [0.03, 0.47, 0.75, 0.95, 0, -0.7, False, False, 55, 2, 1, -1, -1, 5],
                                         [0.1, 0.4, 0.8, 0.9, 0, -0.7, False, False, 55, 12, 1, -1, -1, 3],
                                         [0.15, 0.35, 0.75, 0.95, 0, -0.7, False, False, 75, 34, 1, 6, 5, 3]],
                                     2: [3,
                                         [0.53, 0.97, 0.75, 0.95, 0, -0.7, False, False, 55, 2, 1, -1, -1, 5],
                                         [0.6, 0.9, 0.8, 0.9, 0, -0.7, False, False, 55, 12, 1, -1, -1, 3],
                                         [0.65, 0.85, 0.75, 0.95, 0, -0.7, False, False, 75, 34, 1, 6, 5, 3]]},
                             (3,8): {0: [6,
                                         [0.03, 0.57, 0.7, 0.95, 0, -0.65, False, False, 55, 23, 1, -1, -1, 3],
                                         [0.15, 0.55, 0.8, 0.85, 0, -0.65, False, False, 35, 1, 1, -1, -1, 2],
                                         [0.43, 0.97, 0.05, 0.3, 0, 0.65, False, False, 55, 23, 1, -1, -1, 3],
                                         [0.45, 0.85, 0.15, 0.2, 0, 0.65, False, False, 35, 1, 1, -1, -1, 2],
                                         [0.43, 0.57, 0.05, 0.95, 0, 0, False, False, 50, 24, 2, 6, 6, 3],
                                         [0.47, 0.53, 0.1, 0.9, 0, 0, False, False, 20, 1, 2, 5, 6, 1]],
                                     1: [4,
                                         [0.03, 0.37, 0.2, 0.6, 0, 0.3, False, False, 70, 34, 1, -1, -1, 5],
                                         [0.03, 0.17, 0.15, 0.55, 0.2, 0.3, True, False, 45, 12, 2, 5, 6, 3],
                                         [0.03, 0.37, 0.05, 0.2, 0, 0.75, False, False, 55, 1, 1, 6, 5, 3],
                                         [0.03, 0.37, 0.5, 0.65, 0, -0.15, False, False, 55, 1, 1, 6, 5, 3]],
                                         2: [4,
                                         [0.63, 0.97, 0.4, 0.8, 0, -0.3, False, False, 70, 34, 1, -1, -1, 5],
                                         [0.63, 0.77, 0.45, 0.85, 0.2, -0.3, True, False, 45, 12, 2, 5, 6, 3],
                                         [0.63, 0.97, 0.8, 0.95, 0, -0.75, False, False, 55, 1, 1, 6, 5, 3],
                                         [0.63, 0.97, 0.35, 0.5, 0, 0.15, False, False, 55, 1, 1, 6, 5, 3]]},
                             (4,0): {0: [2,
                                         [0.03, 0.47, 0.05, 0.45, 0, 0, False, False, 55, 23, 3, -1, -1, 9],
                                         [0.14, 0.36, 0.15, 0.35, 0, 0, False, False, 60, 1, 1, -1, -1, 5]],
                                     1: [2,
                                         [0.53, 0.97, 0.05, 0.45, 0, 0, False, False, 55, 23, 3, -1, -1, 9],
                                         [0.64, 0.86, 0.15, 0.35, 0, 0, False, False, 60, 1, 1, -1, -1, 5]],
                                     2: [2,
                                         [0.03, 0.47, 0.55, 0.95, 0, 0, False, False, 55, 23, 3, -1, -1, 9],
                                         [0.14, 0.36, 0.65, 0.85, 0, 0, False, False, 60, 1, 1, -1, -1, 5]],
                                     3: [2,
                                         [0.53, 0.97, 0.55, 0.95, 0, 0, False, False, 55, 23, 3, -1, -1, 9],
                                         [0.64, 0.86, 0.65, 0.85, 0, 0, False, False, 60, 1, 1, -1, -1, 5]]},
                             (4,1): {0: [3,
                                         [0.03, 0.47, 0.05, 0.65, 0, 0.3, False, False, 70, 34, 3, -1, -1, 9],
                                         [0.07, 0.43, 0.15, 0.55, 0, 0.3, False, False, 65, 23, 3, -1, -1, 7],
                                         [0.14, 0.36, 0.2, 0.5, 0, 0.3, False, False, 60, 1, 1, -1, -1, 5]],
                                     1: [2,
                                         [0.53, 0.97, 0.05, 0.3, 0, 0.65, False, False, 55, 24, 3, -1, -1, 5],
                                         [0.64, 0.86, 0.1, 0.25, 0, 0.65, False, False, 60, 1, 1, -1, -1, 3]],
                                     2: [2,
                                         [0.03, 0.47, 0.70, 0.95, 0, -0.65, False, False, 55, 24, 3, -1, -1, 5],
                                         [0.14, 0.36, 0.75, 0.9, 0, -0.65, False, False, 60, 1, 1, -1, -1, 3]],
                                     3: [3,
                                         [0.53, 0.97, 0.35, 0.95, 0, -0.3, False, False, 70, 34, 3, -1, -1, 9],
                                         [0.57, 0.93, 0.45, 0.85, 0, -0.3, False, False, 65, 23, 3, -1, -1, 7],
                                         [0.64, 0.86, 0.5, 0.8, 0, -0.3, False, False, 60, 1, 1, -1, -1, 5]]},
                             (4,2): {0: [4,
                                         [0.6, 0.95, 0.2, 0.65, -0.55, 0.15, False, False, 70, 2, 1, -1, -1, 9],
                                         [0.6, 0.95, 0.2, 0.65, -0.55, 0.15, False, False, 65, 23, 3, -1, -1, 9],
                                         [0.4, 0.9, 0.05, 0.45, -0.3, 0.5, False, False, 70, 3, 1, -1, -1, 7],
                                         [0.45, 0.85, 0.15, 0.35, -0.3, 0.5, False, False, 50, 1, 1, -1, -1, 3]],
                                     1: [2,
                                         [0.6, 0.95, 0.75, 0.9, -0.55, -0.65, False, False, 55, 1, 1, -1, -1, 3],
                                         [0.6, 0.95, 0.7, 0.95, -0.55, -0.65, False, False, 50, 23, 3, -1, -1, 3]],
                                     2: [2,
                                         [0.1, 0.55, 0.5, 0.9, 0.35, -0.4, False, False, 60, 14, 3, -1, -1, 7],
                                         [0.2, 0.45, 0.6, 0.8, 0.35, -0.4, False, False, 55, 1, 1, -1, -1, 3]],
                                     3: [3,
                                         [0.05, 0.35, 0.1, 0.4, 0.6, 0.5, False, False, 60, 13, 3, 6, 6, 5],
                                         [0.11, 0.28, 0.15, 0.35, 0.61, 0.5, False, False, 50, 1, 3, 6, 6, 3],
                                         [0.03, 0.36, 0.05, 0.45, 0.61, 0.5, False, False, 75, 35, 3, 6, 6, 5]]},
                             (4,3): {0: [5,
                                         [0.05, 0.45, 0.2, 0.3, 0, 0.5, False, False, 45, 1, 1, -1, -1, 3],
                                         [0.05, 0.45, 0.1, 0.4, 0, 0.5, False, False, 60, 23, 1, -1, -1, 5],
                                         [0.05, 0.3, 0.15, 0.6, 0, 0.25, False, False, 70, 2, 3, 6, 6, 5],
                                         [0.05, 0.3, 0.15, 0.6, 0, 0.25, False, False, 60, 4, 3, 6, 5, 5],
                                         [0.15, 0.35, 0.05, 0.2, 0, 0.75, False, False, 75, 3, 1, 6, 5, 3]],
                                     1: [5,
                                         [0.55, 0.95, 0.2, 0.3, 0, 0.5, False, False, 45, 1, 1, -1, -1, 3],
                                         [0.55, 0.95, 0.1, 0.4, 0, 0.5, False, False, 60, 23, 1, -1, -1, 5],
                                         [0.7, 0.95, 0.15, 0.6, 0, 0.25, False, False, 70, 2, 3, 6, 6, 5],
                                         [0.7, 0.95, 0.15, 0.6, 0, 0.25, False, False, 60, 4, 3, 6, 5, 5],
                                         [0.65, 0.85, 0.05, 0.2, 0, 0.75, False, False, 75, 3, 1, 6, 5, 3]],
                                     2: [3,
                                         [0.55, 0.95, 0.8, 0.95, -0.5, -0.75, False, False, 45, 34, 1, -1, -1, 3],
                                         [0.7, 0.95, 0.65, 0.9, -0.65, -0.55, False, False, 55, 2, 3, -1, -1, 3],
                                         [0.75, 0.9, 0.75, 0.85, -0.65, -0.6, False, False, 60, 1, 1, -1, -1, 3]],
                                     3: [5,
                                         [0.05, 0.45, 0.65, 0.95, 0.5, -0.6, False, False, 55, 3, 1, -1, -1, 5],
                                         [0.15, 0.5, 0.7, 0.9, 0.35, -0.6, False, False, 55, 2, 1, -1, -1, 3],
                                         [0.35, 0.5, 0.68, 0.75, 0.15, -0.43, False, False, 35, 1, 1, -1, -1, 3],
                                         [0.4, 0.6, 0.45, 0.75, 0, -0.2, False, False, 55, 2, 3, 6, 6, 5],
                                         [0.35, 0.65, 0.45, 0.75, 0, -0.2, False, False, 70, 4, 3, 6, 6, 5]]},
                             (4,4): {0: [4,
                                         [0.33, 0.47, 0.55, 0.95, 0.2, -0.5, False, False, 50, 23, 1, -1, -1, 3],
                                         [0.23, 0.57, 0.65, 0.95, 0.2, -0.6, False, False, 55, 12, 1, -1, -1, 5],
                                         [0.13, 0.67, 0.75, 0.95, 0.2, -0.7, False, False, 55, 23, 1, -1, -1, 3],
                                         [0.03, 0.77, 0.85, 0.95, 0.2, -0.8, False, False, 50, 1, 1, -1, -1, 3]],
                                     1: [4,
                                         [0.03, 0.37, 0.45, 0.5, 0.6, 0.05, False, False, 40, 1, 1, 6, 5, 1],
                                         [0.03, 0.27, 0.35, 0.6, 0.7, 0.05, False, False, 45, 13, 3, 6, 6, 3],
                                         [0.03, 0.17, 0.25, 0.7, 0.8, 0.05, False, False, 45, 13, 3, 6, 6, 3],
                                         [0.03, 0.12, 0.2, 0.75, 0.85, 0.05, False, False, 40, 1, 2, 5, 6, 1]],
                                     2: [5,
                                         [0.53, 0.97, 0.45, 0.55, -0.5, 0, False, False, 45, 1, 1, -1, -1, 3],
                                         [0.63, 0.97, 0.35, 0.65, -0.6, 0, False, False, 55, 23, 3, -1, -1, 5],
                                         [0.73, 0.97, 0.25, 0.75, -0.7, 0, False, False, 55, 2, 3, -1, -1, 7],
                                         [0.83, 0.97, 0.15, 0.85, -0.8, 0, False, False, 55, 2, 3, -1, -1, 5],
                                         [0.9, 0.97, 0.1, 0.9, -0.87, 0, False, False, 50, 1, 2, 5, 6, 3]],
                                     3: [5,
                                         [0.38, 0.52, 0.05, 0.45, 0.1, 0.5, False, False, 45, 1, 2, 5, 6, 1],
                                         [0.33, 0.57, 0.05, 0.4, 0.1, 0.55, False, False, 55, 2, 1, -1, -1, 3],
                                         [0.23, 0.67, 0.05, 0.3, 0.1, 0.65, False, False, 55, 2, 1, -1, -1, 5],
                                         [0.13, 0.77, 0.05, 0.2, 0.1, 0.75, False, False, 55, 2, 1, -1, -1, 3],
                                         [0.03, 0.87, 0.05, 0.1, 0.1, 0.85, False, False, 50, 1, 1, 7, 6, 1]]},
                             (4,5): {0: [3,
                                         [0.03, 0.77, 0.05, 0.7, 0.2, 0.25, False, False, 65, 3, 1, -1, -1, 11],
                                         [0.23, 0.57, 0.2, 0.55, 0.2, 0.25, False, False, 55, 12, 1, -1, -1, 7],
                                         [0.13, 0.67, 0.1, 0.65, 0.2, 0.25, False, False, 80, 34, 1, -1, -1, 9]],
                                     1: [3,
                                         [0.83, 0.97, 0.1, 0.7, -0.8, 0.2, False, False, 70, 34, 2, 6, 6, 3],
                                         [0.83, 0.97, 0.1, 0.7, -0.8, 0.2, False, False, 55, 23, 3, 6, 6, 3],
                                         [0.88, 0.93, 0.2, 0.6, -0.8, 0.2, False, False, 45, 1, 2, 5, 6, 1]],
                                     2: [3,
                                         [0.03, 0.47, 0.75, 0.95, 0, -0.7, False, False, 55, 2, 1, -1, -1, 5],
                                         [0.1, 0.4, 0.8, 0.9, 0, -0.7, False, False, 55, 12, 1, -1, -1, 3],
                                         [0.15, 0.35, 0.75, 0.95, 0, -0.7, False, False, 75, 34, 1, 6, 5, 3]],
                                     3: [3,
                                         [0.53, 0.97, 0.75, 0.95, 0, -0.7, False, False, 55, 2, 1, -1, -1, 5],
                                         [0.6, 0.9, 0.8, 0.9, 0, -0.7, False, False, 55, 12, 1, -1, -1, 3],
                                         [0.65, 0.85, 0.75, 0.95, 0, -0.7, False, False, 75, 34, 1, 6, 5, 3]]},
                             (4,6): {0: [2,
                                         [0.03, 0.37, 0.05, 0.55, 0.6, 0, False, False, 55, 23, 3, -1, -1, 9],
                                         [0.12, 0.28, 0.15, 0.45, 0.6, 0, False, False, 60, 1, 1, -1, -1, 5]],
                                     1: [2,
                                         [0.03, 0.37, 0.6, 0.95, 0.6, 0, False, False, 55, 23, 3, -1, -1, 7],
                                         [0.12, 0.28, 0.7, 0.85, 0.6, 0, False, False, 50, 1, 1, -1, -1, 3]],
                                     2: [4,
                                         [0.43, 0.67, 0.25, 0.65, -0.1, 0.1, False, False, 70, 24, 3, -1, -1, 5],
                                         [0.45, 0.65, 0.2, 0.6, -0.1, 0.2, False, False, 55, 2, 3, -1, -1, 5],
                                         [0.43, 0.97, 0.05, 0.35, -0.4, 0.6, False, False, 55, 23, 3, -1, -1, 5],
                                         [0.55, 0.85, 0.1, 0.3, -0.4, 0.6, False, False, 60, 1, 1, -1, -1, 3]],
                                     3: [4,
                                         [0.73, 0.97, 0.35, 0.75, -0.7, -0.1, False, False, 70, 24, 3, -1, -1, 5],
                                         [0.73, 0.97, 0.4, 0.8, -0.7, -0.2, False, False, 55, 2, 3, -1, -1, 5],
                                         [0.43, 0.97, 0.65, 0.95, -0.4, -0.6, False, False, 55, 23, 3, -1, -1, 5],
                                         [0.55, 0.85, 0.7, 0.9, -0.4, -0.6, False, False, 60, 1, 1, -1, -1, 3]]},
                             (5,0): {0: [2,
                                         [0.02, 0.32, 0.05, 0.55, 0, 0.4, False, False, 55, 23, 3, -1, -1, 7],
                                         [0.09, 0.25, 0.18, 0.43, 0, 0.4, False, False, 60, 1, 1, -1, -1, 3]],
                                     1: [2,
                                         [0.35, 0.65, 0.05, 0.55, 0, 0.4, False, False, 55, 23, 3, -1, -1, 7],
                                         [0.42, 0.58, 0.18, 0.43, 0, 0.4, False, False, 60, 1, 1, -1, -1, 3]],
                                     2: [2,
                                         [0.68, 0.98, 0.05, 0.55, 0, 0.4, False, False, 55, 23, 3, -1, -1, 7],
                                         [0.75, 0.86, 0.18, 0.43, 0, 0.4, False, False, 60, 1, 1, -1, -1, 3]],
                                     3: [2,
                                         [0.02, 0.48, 0.62, 0.95, 0, -0.57, False, False, 55, 23, 3, -1, -1, 7],
                                         [0.13, 0.37, 0.7, 0.87, 0, -0.57, False, False, 60, 1, 1, -1, -1, 3]],
                                     4: [2,
                                         [0.52, 0.98, 0.62, 0.95, 0, -0.57, False, False, 55, 23, 3, -1, -1, 7],
                                         [0.63, 0.87, 0.7, 0.87, 0, -0.57, False, False, 60, 1, 1, -1, -1, 3]]},
                             (5,1): {0: [2,
                                         [0.03, 0.47, 0.05, 0.4, 0, 0, False, False, 55, 23, 3, -1, -1, 9],
                                         [0.14, 0.36, 0.15, 0.3, 0, 0, False, False, 60, 1, 1, -1, -1, 5]],
                                     1: [2,
                                         [0.53, 0.97, 0.05, 0.4, 0, 0, False, False, 55, 23, 3, -1, -1, 9],
                                         [0.64, 0.86, 0.15, 0.3, 0, 0, False, False, 60, 1, 1, -1, -1, 5]],
                                     2: [2,
                                         [0.03, 0.47, 0.6, 0.95, 0, 0, False, False, 55, 23, 3, -1, -1, 9],
                                         [0.14, 0.36, 0.7, 0.85, 0, 0, False, False, 60, 1, 1, -1, -1, 5]],
                                     3: [2,
                                         [0.53, 0.97, 0.6, 0.95, 0, 0, False, False, 55, 23, 3, -1, -1, 9],
                                         [0.64, 0.86, 0.7, 0.85, 0, 0, False, False, 60, 1, 1, -1, -1, 5]],
                                     4: [3,
                                         [0.05, 0.95, 0.45, 0.55, 0, 0, False, False, 70, 24, 1, -1, -1, 3],
                                         [0.1, 0.9, 0.45, 0.55, 0, 0, False, False, 70, 3, 1, -1, -1, 3],
                                         [0.15, 0.85, 0.48, 0.52, 0, 0, False, False, 0, 1, 1, 5, 5, 1]]},
                             (5,2): {0: [2,
                                         [0.03, 0.57, 0.7, 0.95, 0, -0.65, False, False, 55, 23, 1, -1, -1, 3],
                                         [0.15, 0.55, 0.8, 0.85, 0, -0.65, False, False, 35, 1, 1, -1, -1, 2]],
                                     1: [2,
                                         [0.43, 0.97, 0.05, 0.3, 0, 0.65, False, False, 55, 23, 1, -1, -1, 3],
                                         [0.45, 0.85, 0.15, 0.2, 0, 0.65, False, False, 35, 1, 1, -1, -1, 2]],
                                     2: [2,
                                         [0.43, 0.57, 0.35, 0.65, 0, 0, False, False, 50, 24, 2, 6, 6, 3],
                                         [0.47, 0.53, 0.35, 0.65, 0, 0, False, False, 20, 1, 2, 5, 6, 1]],
                                     3: [4,
                                         [0.03, 0.37, 0.2, 0.6, 0, 0.3, False, False, 70, 34, 1, -1, -1, 5],
                                         [0.03, 0.17, 0.15, 0.55, 0.2, 0.3, True, False, 45, 12, 2, 5, 6, 3],
                                         [0.03, 0.37, 0.05, 0.2, 0, 0.75, False, False, 55, 1, 1, 6, 5, 3],
                                         [0.03, 0.37, 0.5, 0.65, 0, -0.15, False, False, 55, 1, 1, 6, 5, 3]],
                                         4: [4,
                                         [0.63, 0.97, 0.4, 0.8, 0, -0.3, False, False, 70, 34, 1, -1, -1, 5],
                                         [0.63, 0.77, 0.45, 0.85, 0.2, -0.3, True, False, 45, 12, 2, 5, 6, 3],
                                         [0.63, 0.97, 0.8, 0.95, 0, -0.75, False, False, 55, 1, 1, 6, 5, 3],
                                         [0.63, 0.97, 0.35, 0.5, 0, 0.15, False, False, 55, 1, 1, 6, 5, 3]]},
                             (5,3): {0: [5,
                                         [0.03, 0.47, 0.2, 0.3, 0, 0.5, False, False, 45, 1, 1, -1, -1, 3],
                                         [0.03, 0.47, 0.1, 0.4, 0, 0.5, False, False, 60, 23, 1, -1, -1, 5],
                                         [0.03, 0.32, 0.15, 0.6, 0.65, 0.25, False, False, 70, 2, 3, 6, 6, 5],
                                         [0.03, 0.32, 0.15, 0.6, 0.65, 0.25, False, False, 60, 4, 3, 6, 5, 5],
                                         [0.13, 0.37, 0.05, 0.2, 0, 0.75, False, False, 75, 3, 1, 6, 5, 3]],
                                     1: [5,
                                         [0.53, 0.97, 0.2, 0.3, 0, 0.5, False, False, 45, 1, 1, -1, -1, 3],
                                         [0.53, 0.97, 0.1, 0.4, 0, 0.5, False, False, 60, 23, 1, -1, -1, 5],
                                         [0.53, 0.82, 0.15, 0.6, -0.35, 0.25, False, False, 70, 2, 3, 6, 6, 5],
                                         [0.53, 0.82, 0.15, 0.6, -0.35, 0.25, False, False, 60, 3, 3, 6, 5, 5],
                                         [0.63, 0.85, 0.05, 0.2, 0, 0.75, False, False, 75, 3, 1, 6, 5, 3]],
                                     2: [5,
                                         [0.38, 0.47, 0.45, 0.75, 0.15, -0.2, False, False, 50, 2, 3, 6, 5, 3],
                                         [0.4, 0.45, 0.5, 0.75, 0.15, -0.25, False, False, 50, 1, 2, 5, 6, 1],
                                         [0.03, 0.32, 0.65, 0.95, 0.65, -0.6, False, False, 60, 24, 3, 6, 5, 3],
                                         [0.08, 0.27, 0.7, 0.9, 0.65, -0.6, False, False, 50, 2, 3, 6, 5, 1],
                                         [0.03, 0.47, 0.65, 0.75, 0.5, -0.4, False, False, 50, 1, 1, 6, 5, 2]],
                                     3: [4,
                                         [0.53, 0.82, 0.65, 0.95, -0.35, -0.6, False, False, 60, 24, 3, 6, 5, 3],
                                         [0.53, 0.82, 0.7, 0.9, -0.35, -0.6, False, False, 50, 2, 3, 6, 5, 1],
                                         [0.37, 0.82, 0.8, 0.95, -0.19, -0.75, False, False, 55, 24, 3, -1, -1, 3],
                                         [0.42, 0.77, 0.85, 0.9, -0.19, -0.75, False, False, 40, 1, 1, -1, -1, 1]],
                                     4: [2,
                                         [0.87, 0.98, 0.45, 0.95, -0.85, -0.4, False, False, 55, 23, 3, -1, -1, 3],
                                         [0.87, 0.98, 0.5, 0.9, -0.85, -0.4, False, False, 60, 1, 1, -1, -1, 3]]},
                             (5,4): {0: [4,
                                         [0.03, 0.37, 0.05, 0.25, 0, 0, False, False, 55, 23, 1, 6, 5, 3],
                                         [0.1, 0.3, 0.1, 0.2, 0, 0, False, False, 50, 1, 1, 6, 5, 2],
                                         [0.03, 0.17, 0.1, 0.47, 0, 0, False, False, 60, 24, 1, 5, 5, 3],
                                         [0.05, 0.15, 0.05, 0.45, 0, 0, False, False, 50, 2, 1, 5, 5, 3]],
                                     1: [4,
                                         [0.03, 0.37, 0.75, 0.95, 0, 0, False, False, 55, 23, 1, 6, 5, 3],
                                         [0.1, 0.3, 0.8, 0.9, 0, 0, False, False, 50, 1, 1, 6, 5, 2],
                                         [0.03, 0.17, 0.53, 0.9, 0, 0, False, False, 60, 24, 1, 5, 5, 3],
                                         [0.05, 0.15, 0.55, 0.95, 0, 0, False, False, 50, 2, 1, 5, 5, 3]],
                                     2: [4,
                                         [0.63, 0.97, 0.05, 0.25, 0, 0, False, False, 55, 23, 1, 6, 5, 3],
                                         [0.7, 0.9, 0.1, 0.2, 0, 0, False, False, 50, 1, 1, 6, 5, 2],
                                         [0.83, 0.97, 0.1, 0.47, 0, 0, False, False, 60, 24, 1, 5, 5, 3],
                                         [0.85, 0.95, 0.05, 0.45, 0, 0, False, False, 50, 2, 1, 5, 5, 3]],
                                     3: [4,
                                         [0.63, 0.97, 0.75, 0.95, 0, 0, False, False, 55, 23, 1, 6, 5, 3],
                                         [0.7, 0.9, 0.8, 0.9, 0, 0, False, False, 50, 1, 1, 6, 5, 2],
                                         [0.83, 0.97, 0.53, 0.9, 0, 0, False, False, 60, 24, 1, 5, 5, 3],
                                         [0.85, 0.95, 0.55, 0.95, 0, 0, False, False, 50, 2, 1, 5, 5, 3]],
                                     4: [7,
                                         [0.43, 0.57, 0.1, 0.4, 0, 0, False, False, 70, 34, 1, 6, 5, 3],
                                         [0.43, 0.57, 0.6, 0.85, 0, 0, False, False, 70, 34, 1, 6, 5, 3],
                                         [0.43, 0.57, 0.1, 0.4, 0, 0, False, False, 55, 2, 3, 6, 5, 3],
                                         [0.43, 0.57, 0.6, 0.85, 0, 0, False, False, 55, 2, 3, 6, 5, 3],
                                         [0.23, 0.77, 0.3, 0.7, 0, 0, False, False, 60, 3, 3, -1, -1, 7],
                                         [0.33, 0.67, 0.4, 0.6, 0, 0, False, False, 50, 5, 3, 6, 5, 5],
                                         [0.28, 0.72, 0.35, 0.65, 0, 0, False, False, 50, 2, 1, -1, -1, 5]]},
                             (5,5): {0: [3,
                                         [0.43, 0.97, 0.05, 0.45, -0.4, 0.5, False, False, 55, 2, 2, -1, -1, 7],
                                         [0.55, 0.85, 0.15, 0.35, -0.4, 0.5, False, False, 60, 1, 1, -1, -1, 5],
                                         [0.5, 0.9, 0.1, 0.4, -0.4, 0.5, False, False, 70, 3, 3, 6, 6, 5]],
                                     1: [3,
                                         [0.23, 0.77, 0.55, 0.95, 0, -0.5, False, False, 55, 2, 2, -1, -1, 7],
                                         [0.35, 0.65, 0.65, 0.85, 0, -0.5, False, False, 60, 1, 1, -1, -1, 5],
                                         [0.3, 0.7, 0.6, 0.9, 0, -0.5, False, False, 70, 3, 3, 6, 6, 5]],
                                     2: [2,
                                         [0.03, 0.37, 0.05, 0.45, 0.6, 0.5, False, False, 55, 23, 3, 6, 5, 5],
                                         [0.1, 0.3, 0.15, 0.35, 0.6, 0.5, False, False, 50, 1, 1, 6, 5, 3]],
                                     3: [2,
                                         [0.03, 0.17, 0.5, 0.95, 0, -0.45, False, False, 55, 23, 3, 6, 5, 5],
                                         [0.05, 0.15, 0.55, 0.9, 0, -0.45, False, False, 50, 1, 3, 6, 5, 3]],
                                     4: [2,
                                         [0.83, 0.97, 0.5, 0.95, 0, -0.45, False, False, 55, 23, 3, 6, 5, 5],
                                         [0.85, 0.95, 0.55, 0.9, 0, -0.45, False, False, 50, 1, 3, 6, 5, 3]]},
                             (6,0): {0: [2,
                                         [0.02, 0.32, 0.05, 0.47, 0, 0, False, False, 55, 23, 3, 6, 6, 7],
                                         [0.09, 0.25, 0.15, 0.35, 0, 0, False, False, 60, 1, 1, 5, 5, 3]],
                                     1: [2,
                                         [0.36, 0.64, 0.05, 0.47, 0, 0, False, False, 55, 23, 3, 6, 6, 7],
                                         [0.42, 0.58, 0.15, 0.35, 0, 0, False, False, 60, 1, 1, 5, 5, 3]],
                                     2: [2,
                                         [0.68, 0.98, 0.05, 0.47, 0, 0, False, False, 55, 23, 3, 6, 6, 7],
                                         [0.75, 0.91, 0.15, 0.35, 0, 0, False, False, 60, 1, 1, 5, 5, 3]],
                                     3: [2,
                                         [0.02, 0.32, 0.53, 0.95, 0, 0, False, False, 55, 23, 3, 6, 6, 7],
                                         [0.09, 0.25, 0.65, 0.85, 0, 0, False, False, 60, 1, 1, 5, 5, 3]],
                                     4: [2,
                                         [0.36, 0.64, 0.53, 0.95, 0, 0, False, False, 55, 23, 3, 6, 6, 7],
                                         [0.42, 0.58, 0.65, 0.85, 0, 0, False, False, 60, 1, 1, 5, 5, 3]],
                                     5: [2,
                                         [0.68, 0.98, 0.53, 0.95, 0, 0, False, False, 55, 23, 3, 6, 6, 7],
                                         [0.75, 0.91, 0.65, 0.85, 0, 0, False, False, 60, 1, 1, 5, 5, 3]]},
                             (6,1): {0: [2,
                                         [0.02, 0.32, 0.05, 0.37, 0, 0.58, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.09, 0.25, 0.15, 0.25, 0, 0.58, False, False, 60, 1, 1, 5, 5, 3]],
                                     1: [2,
                                         [0.36, 0.64, 0.05, 0.57, 0, 0.38, False, False, 55, 23, 3, 6, 6, 7],
                                         [0.42, 0.58, 0.15, 0.45, 0, 0.38, False, False, 60, 1, 1, 5, 5, 3]],
                                     2: [2,
                                         [0.68, 0.98, 0.05, 0.37, 0, 0.58, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.75, 0.91, 0.15, 0.25, 0, 0.58, False, False, 60, 1, 1, 5, 5, 3]],
                                     3: [2,
                                         [0.02, 0.32, 0.43, 0.95, 0, -0.38, False, False, 55, 23, 3, 6, 6, 7],
                                         [0.09, 0.25, 0.55, 0.85, 0, -0.38, False, False, 60, 1, 1, 5, 5, 3]],
                                     4: [2,
                                         [0.36, 0.64, 0.63, 0.95, 0, -0.58, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.42, 0.58, 0.75, 0.85, 0, -0.58, False, False, 60, 1, 1, 5, 5, 3]],
                                     5: [2,
                                         [0.68, 0.98, 0.43, 0.95, 0, -0.38, False, False, 55, 23, 3, 6, 6, 7],
                                         [0.75, 0.91, 0.55, 0.85, 0, -0.38, False, False, 60, 1, 1, 5, 5, 3]]},
                             (6,2): {0: [2,
                                         [0.03, 0.47, 0.05, 0.53, 0, 0.42, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.1, 0.4, 0.17, 0.41, 0, 0.42, False, False, 60, 1, 1, 5, 5, 3]],
                                     1: [2,
                                         [0.53, 0.72, 0.05, 0.53, 0, 0.42, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.57, 0.67, 0.17, 0.41, 0, 0.42, False, False, 60, 1, 1, 5, 5, 3]],
                                     2: [2,
                                         [0.77, 0.97, 0.05, 0.53, 0, 0.42, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.82, 0.92, 0.17, 0.41, 0, 0.42, False, False, 60, 1, 1, 5, 5, 3]],
                                     3: [2,
                                         [0.02, 0.32, 0.58, 0.95, 0, -0.53, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.1, 0.25, 0.67, 0.84, 0, -0.53, False, False, 60, 1, 1, 5, 5, 3]],
                                     4: [2,
                                         [0.35, 0.65, 0.58, 0.95, 0, -0.53, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.42, 0.58, 0.67, 0.84, 0, -0.53, False, False, 60, 1, 1, 5, 5, 3]],
                                     5: [2,
                                         [0.68, 0.98, 0.58, 0.95, 0, -0.53, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.75, 0.9, 0.67, 0.84, 0, -0.53, False, False, 60, 1, 1, 5, 5, 3]]},
                             (6,3): {0: [2,
                                         [0.02, 0.35, 0.06, 0.62, 0.63, 0.32, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.1, 0.27, 0.2, 0.5, 0.63, 0.32, False, False, 60, 1, 1, 5, 5, 3]],
                                     1: [2,
                                         [0.02, 0.35, 0.66, 0.94, 0.63, -0.6, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.1, 0.27, 0.73, 0.87, 0.63, -0.6, False, False, 60, 1, 1, 5, 5, 3]],
                                     2: [2,
                                         [0.39, 0.61, 0.05, 0.48, 0, 0, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.45, 0.55, 0.16, 0.37, 0, 0, False, False, 60, 1, 1, 5, 5, 3]],
                                     3: [2,
                                         [0.39, 0.61, 0.52, 0.95, 0, 0, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.45, 0.55, 0.63, 0.84, 0, 0, False, False, 60, 1, 1, 5, 5, 3]],
                                     4: [2,
                                         [0.65, 0.98, 0.06, 0.62, -0.63, 0, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.73, 0.9, 0.2, 0.5, 0, -0.63, False, False, 60, 1, 1, 5, 5, 3]],
                                     5: [2,
                                         [0.65, 0.98, 0.66, 0.94, -0.63, 0, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.73, 0.9, 0.73, 0.87, -0.63, 0, False, False, 60, 1, 1, 5, 5, 3]]},
                             (6,4): {0: [2,
                                         [0.03, 0.27, 0.05, 0.53, 0, 0.42, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.08, 0.22, 0.17, 0.41, 0, 0.42, False, False, 60, 1, 1, 5, 5, 3]],
                                     1: [2,
                                         [0.33, 0.67, 0.05, 0.53, 0, 0.42, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.4, 0.6, 0.17, 0.41, 0, 0.42, False, False, 60, 1, 1, 5, 5, 3]],
                                     2: [2,
                                         [0.73, 0.97, 0.05, 0.53, 0, 0.42, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.78, 0.92, 0.17, 0.41, 0, 0.42, False, False, 60, 1, 1, 5, 5, 3]],
                                     3: [2,
                                         [0.02, 0.32, 0.58, 0.95, 0, -0.53, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.1, 0.25, 0.67, 0.84, 0, -0.53, False, False, 60, 1, 1, 5, 5, 3]],
                                     4: [2,
                                         [0.35, 0.65, 0.58, 0.95, 0, -0.53, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.42, 0.58, 0.67, 0.84, 0, -0.53, False, False, 60, 1, 1, 5, 5, 3]],
                                     5: [2,
                                         [0.68, 0.98, 0.58, 0.95, 0, -0.53, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.75, 0.9, 0.67, 0.84, 0, -0.53, False, False, 60, 1, 1, 5, 5, 3]]},
                             (6,5): {0: [2,
                                         [0.02, 0.6, 0.06, 0.34, 0.38, 0.6, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.1, 0.53, 0.13, 0.27, 0.38, 0.6, False, False, 60, 1, 1, 5, 5, 3]],
                                     1: [2,
                                         [0.02, 0.35, 0.38, 0.62, 0, 0, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.1, 0.27, 0.44, 0.56, 0, 0, False, False, 60, 1, 1, 5, 5, 3]],
                                     2: [4,
                                         [0.02, 0.35, 0.66, 0.94, 0.62, -0.6, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.1, 0.27, 0.73, 0.87, 0.62, -0.6, False, False, 60, 1, 1, 5, 5, 3],
                                         [0.39, 0.61, 0.05, 0.48, 0, 0, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.45, 0.55, 0.16, 0.37, 0, 0, False, False, 60, 1, 1, 5, 5, 3]],
                                     3: [4,
                                         [0.39, 0.61, 0.52, 0.95, 0, 0, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.45, 0.55, 0.63, 0.84, 0, 0, False, False, 60, 1, 1, 5, 5, 3],
                                         [0.4, 0.98, 0.06, 0.34, -0.38, 0, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.47, 0.9, 0.13, 0.27, -0.38, 0, False, False, 60, 1, 1, 5, 5, 3]],
                                     4: [2,
                                         [0.65, 0.98, 0.38, 0.62, 0, 0, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.73, 0.9, 0.44, 0.56, 0, 0, False, False, 60, 1, 1, 5, 5, 3]],
                                     5: [2,
                                         [0.65, 0.98, 0.66, 0.94, -0.62, 0, False, False, 55, 23, 3, 6, 6, 5],
                                         [0.73, 0.9, 0.73, 0.87, -0.62, 0, False, False, 60, 1, 1, 5, 5, 3]]}
                }
                cont_data = templates[(iNumConts, templateID)]
        elif idMap == "hub" :
                iPlayers = game.countCivPlayersEverAlive()
                if iPlayers < 2 or iPlayers > 18:
                        bSuccessFlag = False
                        return 0
                else:
                        bSuccessFlag = True
                userInputLandmass = cmo[0]
                if userInputLandmass == 1 and iPlayers >= 2 and iPlayers <= 10:
                        templates = {2: {0: [0.0, 0.333, 0.0, 1.0],
                                         1: [0.667, 1.0, 0.0, 1.0]},
                                     3: {0: [0.0, 0.4, 0.667, 1.0],
                                         1: [0.8, 1.0, 0.333, 1.0],
                                         2: [0.2, 0.6, 0.0, 0.333]},
                                     4: {0: [0.0, 0.333, 0.333, 0.667],
                                         1: [0.333, 0.667, 0.667, 1.0],
                                         2: [0.667, 1.0, 0.333, 0.667],
                                         3: [0.333, 0.667, 0.0, 0.333]},
                                     5: {0: [0.0, 0.167, 0.4, 0.8],
                                         1: [0.333, 0.667, 0.8, 1.0],
                                         2: [0.833, 1.0, 0.4, 0.8],
                                         3: [0.583, 0.917, 0.0, 0.2],
                                         4: [0.083, 0.417, 0.0, 0.2]},
                                     6: {0: [0.0, 0.333, 0.8, 1.0],
                                         1: [0.5, 0.833, 0.8, 1.0],
                                         2: [0.833, 1.0, 0.4, 0.8],
                                         3: [0.667, 1.0, 0.0, 0.2],
                                         4: [0.167, 0.5, 0.0, 0.2],
                                         5: [0.0, 0.167, 0.2, 0.6]},
                                     7: {0: [0.0, 0.2, 0.75, 1.0],
                                         1: [0.4, 0.6, 0.75, 1.0],
                                         2: [0.8, 1.0, 0.75, 1.0],
                                         3: [0.8, 1.0, 0.25, 0.5],
                                         4: [0.6, 0.8, 0.0, 0.25],
                                         5: [0.2, 0.4, 0.0, 0.25],
                                         6: [0.0, 0.2, 0.25, 0.5]},
                                     8: {0: [0.0, 0.2, 0.6, 0.8],
                                         1: [0.2, 0.4, 0.8, 1.0],
                                         2: [0.6, 0.8, 0.8, 1.0],
                                         3: [0.8, 1.0, 0.6, 0.8],
                                         4: [0.8, 1.0, 0.2, 0.4],
                                         5: [0.6, 0.8, 0.0, 0.2],
                                         6: [0.2, 0.4, 0.0, 0.2],
                                         7: [0.0, 0.2, 0.2, 0.4]},
                                     9: {0: [0.0, 0.167, 0.6, 0.8],
                                         1: [0.167, 0.333, 0.8, 1.0],
                                         2: [0.5, 0.677, 0.8, 1.0],
                                         3: [0.833, 1.0, 0.8, 1.0],
                                         4: [0.833, 1.0, 0.4, 0.6],
                                         5: [0.833, 1.0, 0.0, 0.2],
                                         6: [0.5, 0.667, 0.0, 0.2],
                                         7: [0.167, 0.333, 0.0, 0.2],
                                         8: [0.0, 0.167, 0.2, 0.4]},
                                     10: {0: [0.0, 0.167, 0.667, 0.833],
                                          1: [0.167, 0.333, 0.833, 1.0],
                                          2: [0.5, 0.667, 0.833, 1.0],
                                          3: [0.833, 1.0, 0.833, 1.0],
                                          4: [0.833, 1.0, 0.5, 0.667],
                                          5: [0.833, 1.0, 0.167, 0.333],
                                          6: [0.667, 0.833, 0.0, 0.167],
                                          7: [0.333, 0.5, 0.0, 0.167],
                                          8: [0.0, 0.167, 0.0, 0.167],
                                          9: [0.0, 0.167, 0.333, 0.5]}
                        }
                        buffers = {2: {0: [0.4, 0.6, 0.1, 0.3],
                                       1: [0.4, 0.6, 0.7, 0.9]},
                                   3: {0: [0.4, 0.8, 0.667, 1.0],
                                       1: [0.6, 1.0, 0.0, 0.333],
                                       2: [0.0, 0.2, 0.0, 0.667]},
                                   4: {0: [0.0, 0.333, 0.667, 1.0],
                                       1: [0.667, 1.0, 0.667, 1.0],
                                       2: [0.667, 1.0, 0.0, 0.333],
                                       3: [0.0, 0.333, 0.0, 0.333]},
                                   5: {0: [0.0, 0.167, 0.2, 0.4],
                                       1: [0.167, 0.333, 0.8, 1.0],
                                       2: [0.667, 0.833, 0.8, 1.0],
                                       3: [0.833, 1.0, 0.2, 0.4],
                                       4: [0.417, 0.583, 0.0, 0.2]},
                                   6: {0: [0.0, 0.167, 0.6, 0.8],
                                       1: [0.333, 0.5, 0.8, 1.0],
                                       2: [0.833, 1.0, 0.8, 1.0],
                                       3: [0.833, 1.0, 0.2, 0.4],
                                       4: [0.5, 0.667, 0.0, 0.2],
                                       5: [0.0, 0.167, 0.0, 0.2]},
                                   7: {0: [0.2, 0.4, 0.77, 1.0],
                                       1: [0.6, 0.8, 0.77, 1.0],
                                       2: [0.82, 1.0, 0.5, 0.7],
                                       3: [0.8, 1.0, 0.0, 0.25],
                                       4: [0.4, 0.6, 0.0, 0.25],
                                       5: [0.0, 0.2, 0.0, 0.25],
                                       6: [0.0, 0.18, 0.5, 0.7]},
                                   8: {0: [0.0, 0.2, 0.8, 1.0],
                                       1: [0.4, 0.6, 0.8, 1.0],
                                       2: [0.8, 1.0, 0.8, 1.0],
                                       3: [0.8, 1.0, 0.4, 0.6],
                                       4: [0.8, 1.0, 0.0, 0.2],
                                       5: [0.4, 0.6, 0.0, 0.2],
                                       6: [0.0, 0.2, 0.0, 0.2],
                                       7: [0.0, 0.2, 0.4, 0.6]},
                                   9: {0: [0.0, 0.167, 0.8, 1.0],
                                       1: [0.333, 0.5, 0.8, 1.0],
                                       2: [0.667, 0.81, 0.82, 1.0],
                                       3: [0.85, 1.0, 0.6, 0.77],
                                       4: [0.85, 1.0, 0.22, 0.4],
                                       5: [0.667, 0.81, 0.0, 0.18],
                                       6: [0.333, 0.5, 0.0, 0.2],
                                       7: [0.0, 0.167, 0.0, 0.2],
                                       8: [0.0, 0.167, 0.4, 0.6]},
                                   10: {0: [0.0, 0.15, 0.5, 0.65],
                                        1: [0.0, 0.167, 0.833, 1.0],
                                        2: [0.333, 0.5, 0.833, 1.0],
                                        3: [0.667, 0.81, 0.85, 1.0],
                                        4: [0.85, 1.0, 0.667, 0.81],
                                        5: [0.833, 1.0, 0.333, 0.5],
                                        6: [0.833, 1.0, 0.0, 0.167],
                                        7: [0.5, 0.667, 0.0, 0.167],
                                        8: [0.18, 0.333, 0.0, 0.15],
                                        9: [0.0, 0.15, 0.18, 0.333]}
                        }
                        center_isle = {2: [0.35, 0.65, 0.4, 0.6],
                                       3: [0.28, 0.72, 0.4, 0.6],
                                       4: [0.38, 0.62, 0.38, 0.62],
                                       5: [0.27, 0.73, 0.3, 0.7],
                                       6: [0.25, 0.75, 0.3, 0.7],
                                       7: [0.3, 0.7, 0.35, 0.65],
                                       8: [0.32, 0.68, 0.32, 0.68],
                                       9: [0.25, 0.75, 0.3, 0.7],
                                       10: [0.25, 0.75, 0.25, 0.75]
                        }
                        the_spokes = {2: [[0.167, 0.2, 0.167, 0.8], [0.833, 0.2, 0.833, 0.8], 
                                          [0.167, 0.5, 0.833, 0.5], [0.5, 0.2, 0.5, 0.8]],
                                      3: [[0.2, 0.833, 0.5, 0.5], [0.9, 0.667, 0.5, 0.5], [0.4, 0.167, 0.5, 0.5]],
                                      4: [[0.167, 0.5, 0.833, 0.5], [0.5, 0.833, 0.5, 0.167]],
                                      5: [[0.083, 0.6, 0.5, 0.5], [0.5, 0.917, 0.5, 0.5], [0.917, 0.6, 0.5, 0.5],
                                          [0.25, 0.083, 0.5, 0.5], [0.75, 0.083, 0.5, 0.5]],
                                      6: [[0.083, 0.4, 0.917, 0.6], [0.167, 0.9, 0.833, 0.1], [0.667, 0.9, 0.333, 0.1]],
                                      7: [[0.1, 0.875, 0.4, 0.5], [0.3, 0.125, 0.5, 0.5], [0.1, 0.4, 0.4, 0.5],
                                          [0.7, 0.125, 0.5, 0.5], [0.5, 0.875, 0.5, 0.5], [0.9, 0.875, 0.6, 0.5],
                                          [0.9, 0.375, 0.6, 0.5], [0.4, 0.5, 0.6, 0.5]],
                                      8: [[0.1, 0.7, 0.9, 0.3], [0.3, 0.9, 0.7, 0.1], 
                                          [0.1, 0.3, 0.9, 0.7], [0.7, 0.9, 0.3, 0.1]],
                                      9: [[0.083, 0.7, 0.333, 0.5], [0.083, 0.3, 0.333, 0.5], [0.25, 0.1, 0.417, 0.5], 
                                          [0.25, 0.9, 0.417, 0.5], [0.583, 0.9, 0.583, 0.1], [0.333, 0.5, 0.917, 0.5],
                                          [0.917, 0.9, 0.667, 0.5], [0.917, 0.1, 0.667, 0.5]],
                                      10: [[0.25, 0.917, 0.75, 0.083], [0.417, 0.083, 0.583, 0.917], [0.083, 0.083, 0.917, 0.917], 
                                           [0.083, 0.417, 0.917, 0.583], [0.083, 0.75, 0.917, 0.25]]
                        }
                else:
                        templates = {2: {0: [0.0, 0.333, 0.0, 1.0],
                                         1: [0.667, 1.0, 0.0, 1.0]},
                                     3: {0: [0.0, 0.25, 0.25, 0.75],
                                         1: [0.5, 1.0, 0.75, 1.0],
                                         2: [0.5, 1.0, 0.0, 0.25]},
                                     4: {0: [0.0, 0.333, 0.333, 0.667],
                                         1: [0.333, 0.667, 0.667, 1.0],
                                         2: [0.667, 1.0, 0.333, 0.667],
                                         3: [0.333, 0.667, 0.0, 0.333]},
                                     5: {0: [0.0, 0.25, 0.333, 1.0],
                                         1: [0.25, 0.75, 0.667, 1.0],
                                         2: [0.75, 1.0, 0.333, 1.0],
                                         3: [0.5, 1.0, 0.0, 0.333],
                                         4: [0.0, 0.5, 0.0, 0.333]},
                                     6: {0: [0.0, 0.4, 0.667, 1.0],
                                         1: [0.4, 0.8, 0.667, 1.0],
                                         2: [0.8, 1.0, 0.333, 1.0],
                                         3: [0.6, 1.0, 0.0, 0.333],
                                         4: [0.2, 0.6, 0.0, 0.333],
                                         5: [0.0, 0.2, 0.0, 0.667]},
                                     7: {0: [0.0, 0.4, 0.75, 1.0],
                                         1: [0.4, 0.8, 0.75, 1.0],
                                         2: [0.8, 1.0, 0.5, 1.0],
                                         3: [0.8, 1.0, 0.0, 0.5],
                                         4: [0.4, 0.8, 0.0, 0.25],
                                         5: [0.0, 0.4, 0.0, 0.25],
                                         6: [0.0, 0.2, 0.25, 0.75]},
                                     8: {0: [0.0, 0.3, 0.35, 0.65],
                                         1: [0.0, 0.3, 0.7, 1.0],
                                         2: [0.35, 0.65, 0.7, 1.0],
                                         3: [0.7, 1.0, 0.7, 1.0],
                                         4: [0.7, 1.0, 0.35, 0.65],
                                         5: [0.7, 1.0, 0.0, 0.3],
                                         6: [0.35, 0.65, 0.0, 0.3],
                                         7: [0.0, 0.3, 0.0, 0.3]},
                                     9: {0: [0.0, 0.167, 0.6, 1.0],
                                         1: [0.167, 0.5, 0.8, 1.0],
                                         2: [0.5, 0.833, 0.8, 1.0],
                                         3: [0.833, 1.0, 0.6, 1.0],
                                         4: [0.833, 1.0, 0.2, 0.6],
                                         5: [0.667, 1.0, 0.0, 0.2],
                                         6: [0.333, 0.667, 0.0, 0.2],
                                         7: [0.0, 0.333, 0.0, 0.2],
                                         8: [0.0, 0.167, 0.2, 0.6]},
                                     10: {0: [0.0, 0.167, 0.5, 0.833],
                                          1: [0.0, 0.333, 0.833, 1.0],
                                          2: [0.333, 0.667, 0.833, 1.0],
                                          3: [0.667, 1.0, 0.833, 1.0],
                                          4: [0.833, 1.0, 0.5, 0.833],
                                          5: [0.833, 1.0, 0.167, 0.5],
                                          6: [0.667, 1.0, 0.0, 0.167],
                                          7: [0.333, 0.667, 0.0, 0.167],
                                          8: [0.0, 0.333, 0.0, 0.167],
                                          9: [0.0, 0.167, 0.167, 0.5]},
                                     11: {0: [0.0, 0.2, 0.167, 0.5],
                                          1: [0.0, 0.2, 0.5, 0.833],
                                          2: [0.2, 0.4, 0.667, 1.0],
                                          3: [0.4, 0.6, 0.667, 1.0],
                                          4: [0.6, 0.8, 0.667, 1.0],
                                          5: [0.8, 1.0, 0.667, 1.0],
                                          6: [0.8, 1.0, 0.333, 0.667],
                                          7: [0.8, 1.0, 0.0, 0.333],
                                          8: [0.6, 0.8, 0.0, 0.333],
                                          9: [0.4, 0.6, 0.0, 0.333],
                                          10: [0.2, 0.4, 0.0, 0.333]},
                                     12: {0: [0.0, 0.2, 0.333, 0.667],
                                          1: [0.0, 0.2, 0.667, 1.0],
                                          2: [0.2, 0.4, 0.667, 1.0],
                                          3: [0.4, 0.6, 0.667, 1.0],
                                          4: [0.6, 0.8, 0.667, 1.0],
                                          5: [0.8, 1.0, 0.667, 1.0],
                                          6: [0.8, 1.0, 0.333, 0.667],
                                          7: [0.8, 1.0, 0.0, 0.333],
                                          8: [0.6, 0.8, 0.0, 0.333],
                                          9: [0.4, 0.6, 0.0, 0.333],
                                          10: [0.2, 0.4, 0.0, 0.333],
                                          11: [0.0, 0.2, 0.0, 0.333]},
                                     13: {0: [0.0, 0.2, 0.375, 0.625],
                                          1: [0.0, 0.2, 0.7, 0.95],
                                          2: [0.2, 0.4, 0.75, 1.0],
                                          3: [0.4, 0.6, 0.75, 1.0],
                                          4: [0.6, 0.8, 0.75, 1.0],
                                          5: [0.8, 1.0, 0.75, 1.0],
                                          6: [0.8, 1.0, 0.5, 0.75],
                                          7: [0.8, 1.0, 0.25, 0.5],
                                          8: [0.8, 1.0, 0.0, 0.25],
                                          9: [0.6, 0.8, 0.0, 0.25],
                                          10: [0.4, 0.6, 0.0, 0.25],
                                          11: [0.2, 0.4, 0.0, 0.25],
                                          12: [0.0, 0.2, 0.05, 0.3]},
                                     14: {0: [0.0, 0.2, 0.5, 0.75],
                                          1: [0.0, 0.2, 0.75, 1.0],
                                          2: [0.2, 0.4, 0.75, 1.0],
                                          3: [0.4, 0.6, 0.75, 1.0],
                                          4: [0.6, 0.8, 0.75, 1.0],
                                          5: [0.8, 1.0, 0.75, 1.0],
                                          6: [0.8, 1.0, 0.5, 0.75],
                                          7: [0.8, 1.0, 0.25, 0.5],
                                          8: [0.8, 1.0, 0.0, 0.25],
                                          9: [0.6, 0.8, 0.0, 0.25],
                                          10: [0.4, 0.6, 0.0, 0.25],
                                          11: [0.2, 0.4, 0.0, 0.25],
                                          12: [0.0, 0.2, 0.0, 0.25],
                                          13: [0.0, 0.2, 0.25, 0.5]},
                                     15: {0: [0.0, 0.167, 0.375, 0.625],
                                          1: [0.0, 0.167, 0.7, 0.95],
                                          2: [0.167, 0.333, 0.75, 1.0],
                                          3: [0.333, 0.5, 0.75, 1.0],
                                          4: [0.5, 0.667, 0.75, 1.0],
                                          5: [0.667, 0.833, 0.75, 1.0],
                                          6: [0.833, 1.0, 0.75, 1.0],
                                          7: [0.833, 1.0, 0.5, 0.75],
                                          8: [0.833, 1.0, 0.25, 0.5],
                                          9: [0.833, 1.0, 0.0, 0.25],
                                          10: [0.667, 0.833, 0.0, 0.25],
                                          11: [0.5, 0.667, 0.0, 0.25],
                                          12: [0.333, 0.5, 0.0, 0.25],
                                          13: [0.167, 0.333, 0.0, 0.25],
                                          14: [0.0, 0.167, 0.05, 0.3]},
                                     16: {0: [0.0, 0.167, 0.5, 0.75],
                                          1: [0.0, 0.167, 0.75, 1.0],
                                          2: [0.167, 0.333, 0.75, 1.0],
                                          3: [0.333, 0.5, 0.75, 1.0],
                                          4: [0.5, 0.667, 0.75, 1.0],
                                          5: [0.667, 0.833, 0.75, 1.0],
                                          6: [0.833, 1.0, 0.75, 1.0],
                                          7: [0.833, 1.0, 0.5, 0.75],
                                          8: [0.833, 1.0, 0.25, 0.5],
                                          9: [0.833, 1.0, 0.0, 0.25],
                                          10: [0.667, 0.833, 0.0, 0.25],
                                          11: [0.5, 0.667, 0.0, 0.25],
                                          12: [0.333, 0.5, 0.0, 0.25],
                                          13: [0.167, 0.333, 0.0, 0.25],
                                          14: [0.0, 0.167, 0.25, 0.5],
                                          15: [0.0, 0.167, 0.0, 0.25]},
                                     17: {0: [0.0, 0.167, 0.5, 0.7],
                                          1: [0.0, 0.167, 0.7, 0.9],
                                          2: [0.167, 0.333, 0.8, 1.0],
                                          3: [0.333, 0.5, 0.8, 1.0],
                                          4: [0.5, 0.667, 0.8, 1.0],
                                          5: [0.667, 0.833, 0.8, 1.0],
                                          6: [0.833, 1.0, 0.8, 1.0],
                                          7: [0.833, 1.0, 0.6, 0.8],
                                          8: [0.833, 1.0, 0.4, 0.6],
                                          9: [0.833, 1.0, 0.2, 0.4],
                                          10: [0.833, 1.0, 0.0, 0.2],
                                          11: [0.667, 0.833, 0.0, 0.2],
                                          12: [0.5, 0.667, 0.0, 0.2],
                                          13: [0.333, 0.5, 0.0, 0.2],
                                          14: [0.167, 0.333, 0.0, 0.2],
                                          15: [0.0, 0.167, 0.1, 0.3],
                                          16: [0.0, 0.167, 0.3, 0.5]},
                                     18: {0: [0.0, 0.167, 0.6, 0.8],
                                          1: [0.0, 0.167, 0.8, 1.0],
                                          2: [0.167, 0.333, 0.8, 1.0],
                                          3: [0.333, 0.5, 0.8, 1.0],
                                          4: [0.5, 0.667, 0.8, 1.0],
                                          5: [0.667, 0.833, 0.8, 1.0],
                                          6: [0.833, 1.0, 0.8, 1.0],
                                          7: [0.833, 1.0, 0.6, 0.8],
                                          8: [0.833, 1.0, 0.4, 0.6],
                                          9: [0.833, 1.0, 0.2, 0.4],
                                          10: [0.833, 1.0, 0.0, 0.2],
                                          11: [0.667, 0.833, 0.0, 0.2],
                                          12: [0.5, 0.667, 0.0, 0.2],
                                          13: [0.333, 0.5, 0.0, 0.2],
                                          14: [0.167, 0.333, 0.0, 0.2],
                                          15: [0.0, 0.167, 0.0, 0.2],
                                          16: [0.0, 0.167, 0.2, 0.4],
                                          17: [0.0, 0.167, 0.4, 0.6]}
                        }
                        center_isle = {2: [0.35, 0.65, 0.4, 0.6],
                                       3: [0.38, 0.7, 0.35, 0.65],
                                       4: [0.37, 0.63, 0.37, 0.63],
                                       5: [0.32, 0.68, 0.38, 0.62],
                                       6: [0.28, 0.72, 0.38, 0.62],
                                       7: [0.28, 0.72, 0.35, 0.65],
                                       8: [0.37, 0.63, 0.37, 0.63],
                                       9: [0.3, 0.7, 0.35, 0.65],
                                       10: [0.3, 0.7, 0.3, 0.7],
                                       11: [0.28, 0.72, 0.38, 0.62],
                                       12: [0.28, 0.72, 0.38, 0.62],
                                       13: [0.3, 0.7, 0.35, 0.65],
                                       14: [0.3, 0.7, 0.35, 0.65],
                                       15: [0.25, 0.75, 0.35, 0.65],
                                       16: [0.25, 0.75, 0.35, 0.65],
                                       17: [0.25, 0.75, 0.3, 0.7],
                                       18: [0.25, 0.75, 0.3, 0.7]
                        }
                        the_spokes = {2: [[0.167, 0.2, 0.167, 0.8], [0.833, 0.2, 0.833, 0.8], [0.167, 0.5, 0.833, 0.5]],
                                      3: [[0.125, 0.5, 0.5, 0.5], [0.75, 0.125, 0.5, 0.5], [0.75, 0.875, 0.5, 0.5]],
                                      4: [[0.167, 0.5, 0.833, 0.5], [0.5, 0.833, 0.5, 0.167]],
                                      5: [[0.125, 0.667, 0.375, 0.5], [0.25, 0.167, 0.375, 0.5], [0.375, 0.5, 0.625, 0.5],
                                          [0.5, 0.5, 0.5, 0.833], [0.625, 0.5, 0.75, 0.167], [0.625, 0.5, 0.875, 0.667]],
                                      6: [[0.1, 0.333, 0.3, 0.5], [0.7, 0.5, 0.8, 0.167], [0.7, 0.5, 0.9, 0.667], 
                                          [0.4, 0.167, 0.6, 0.833], [0.2, 0.833, 0.3, 0.5], [0.3, 0.5, 0.7, 0.5]],
                                      7: [[0.2, 0.875, 0.3, 0.5], [0.2, 0.125, 0.3, 0.5], [0.1, 0.5, 0.7, 0.5],
                                          [0.6, 0.125, 0.5, 0.5], [0.6, 0.875, 0.5, 0.5], [0.9, 0.75, 0.7, 0.5],
                                          [0.9, 0.25, 0.7, 0.5]],
                                      8: [[0.167, 0.5, 0.833, 0.5], [0.5, 0.833, 0.5, 0.167], 
                                          [0.167, 0.167, 0.833, 0.833], [0.167, 0.833, 0.833, 0.167]],
                                      9: [[0.083, 0.8, 0.375, 0.5], [0.083, 0.4, 0.375, 0.5], [0.167, 0.1, 0.375, 0.5], 
                                          [0.333, 0.9, 0.5, 0.5], [0.667, 0.9, 0.5, 0.5], [0.5, 0.1, 0.5, 0.5],
                                          [0.917, 0.8, 0.625, 0.5], [0.917, 0.4, 0.625, 0.5], [0.833, 0.1, 0.625, 0.5], 
                                          [0.375, 0.5, 0.625, 0.5]],
                                      10: [[0.167, 0.917, 0.833, 0.083], [0.5, 0.083, 0.5, 0.917], [0.167, 0.083, 0.833, 0.917], 
                                           [0.083, 0.333, 0.917, 0.667], [0.083, 0.667, 0.917, 0.333]],
                                      11: [[0.7, 0.5, 0.9, 0.5], [0.7, 0.5, 0.9, 0.167], [0.7, 0.5, 0.9, 0.833], 
                                           [0.6, 0.5, 0.7, 0.833], [0.6, 0.5, 0.7, 0.167], [0.5, 0.5, 0.5, 0.833],
                                           [0.5, 0.5, 0.5, 0.167], [0.4, 0.5, 0.3, 0.167], [0.4, 0.5, 0.3, 0.833], 
                                           [0.3, 0.5, 0.1, 0.667], [0.3, 0.5, 0.1, 0.333], [0.3, 0.5, 0.7, 0.5]],
                                      12: [[0.7, 0.5, 0.9, 0.5], [0.7, 0.5, 0.9, 0.167], [0.7, 0.5, 0.9, 0.833], 
                                           [0.6, 0.5, 0.7, 0.833], [0.6, 0.5, 0.7, 0.167], [0.5, 0.5, 0.5, 0.833],
                                           [0.5, 0.5, 0.5, 0.167], [0.4, 0.5, 0.3, 0.167], [0.4, 0.5, 0.3, 0.833], 
                                           [0.3, 0.5, 0.1, 0.167], [0.3, 0.5, 0.1, 0.833], [0.3, 0.5, 0.1, 0.5], 
                                           [0.3, 0.5, 0.7, 0.5]],
                                      13: [[0.3, 0.875, 0.5, 0.125], [0.3, 0.5, 0.6, 0.5], [0.5, 0.875, 0.3, 0.125], 
                                           [0.7, 0.125, 0.9, 0.375], [0.7, 0.875, 0.9, 0.625], [0.9, 0.125, 0.6, 0.5],
                                           [0.9, 0.875, 0.6, 0.5], [0.1, 0.175, 0.3, 0.5], [0.1, 0.5, 0.3, 0.5], 
                                           [0.1, 0.825, 0.3, 0.5]],
                                      14: [[0.3, 0.875, 0.1, 0.625], [0.4, 0.5, 0.6, 0.5], [0.1, 0.375, 0.3, 0.125], 
                                           [0.7, 0.125, 0.9, 0.375], [0.7, 0.875, 0.9, 0.625], [0.9, 0.125, 0.6, 0.5],
                                           [0.9, 0.875, 0.6, 0.5], [0.1, 0.125, 0.4, 0.5], [0.1, 0.875, 0.4, 0.5], 
                                           [0.5, 0.125, 0.5, 0.875]],
                                      15: [[0.583, 0.125, 0.25, 0.875], [0.25, 0.5, 0.667, 0.5], [0.583, 0.875, 0.25, 0.125], 
                                           [0.75, 0.125, 0.917, 0.375], [0.75, 0.875, 0.917, 0.625], [0.917, 0.125, 0.667, 0.5],
                                           [0.917, 0.875, 0.667, 0.5], [0.083, 0.175, 0.25, 0.5], [0.083, 0.5, 0.25, 0.5], 
                                           [0.083, 0.825, 0.25, 0.5], [0.417, 0.125, 0.417, 0.875]],
                                      16: [[0.083, 0.875, 0.417, 0.125], [0.25, 0.5, 0.75, 0.5], [0.417, 0.875, 0.083, 0.125], 
                                           [0.75, 0.125, 0.75, 0.875], [0.25, 0.125, 0.25, 0.875], [0.917, 0.125, 0.583, 0.875],
                                           [0.917, 0.875, 0.583, 0.125], [0.083, 0.625, 0.25, 0.5], [0.083, 0.375, 0.25, 0.5], 
                                           [0.917, 0.375, 0.75, 0.5], [0.917, 0.625, 0.75, 0.5]],
                                      17: [[0.25, 0.5, 0.917, 0.5], [0.083, 0.6, 0.25, 0.5], [0.083, 0.4, 0.25, 0.5], 
                                           [0.083, 0.8, 0.333, 0.7], [0.25, 0.9, 0.417, 0.5], [0.417, 0.9, 0.333, 0.7], 
                                           [0.583, 0.9, 0.75, 0.7], [0.75, 0.9, 0.75, 0.7], [0.917, 0.9, 0.583, 0.5], 
                                           [0.917, 0.7, 0.75, 0.5], [0.917, 0.3, 0.75, 0.5], [0.917, 0.1, 0.583, 0.5],
                                           [0.75, 0.1, 0.75, 0.3], [0.583, 0.1, 0.75, 0.3], [0.417, 0.1, 0.333, 0.3], 
                                           [0.25, 0.1, 0.417, 0.5], [0.083, 0.2, 0.333, 0.3]],
                                      18: [[0.083, 0.5, 0.917, 0.5], [0.083, 0.7, 0.25, 0.5], [0.083, 0.3, 0.25, 0.5], 
                                           [0.083, 0.9, 0.417, 0.5], [0.25, 0.9, 0.25, 0.7], [0.417, 0.9, 0.25, 0.7], 
                                           [0.583, 0.9, 0.75, 0.7], [0.75, 0.9, 0.75, 0.7], [0.917, 0.9, 0.583, 0.5], 
                                           [0.917, 0.7, 0.75, 0.5], [0.917, 0.3, 0.75, 0.5], [0.917, 0.1, 0.583, 0.5],
                                           [0.75, 0.1, 0.75, 0.3], [0.583, 0.1, 0.75, 0.3], [0.417, 0.1, 0.25, 0.3], 
                                           [0.25, 0.1, 0.25, 0.3], [0.083, 0.1, 0.417, 0.5]]
                        }
                region_data = []
                for regionLoop in range(iPlayers):
                        [fWestLon, fEastLon, fSouthLat, fNorthLat] = templates[iPlayers][regionLoop]
                        iWestX = int((iW - 1) * fWestLon)
                        iEastX = int((iW - 1) * fEastLon) - 1
                        iSouthY = int((iH - 1) * fSouthLat)
                        iNorthY = int((iH - 1) * fNorthLat) -1
                        region_data.append([iWestX, iEastX, iSouthY, iNorthY])
                if userInputLandmass == 1 and iPlayers >= 2 and iPlayers <= 10:
                        buffer_data = []
                        for bufferLoop in range(iPlayers):
                                [fWestLon, fEastLon, fSouthLat, fNorthLat] = buffers[iPlayers][bufferLoop]
                                iWestX = int((iW - 1) * fWestLon)
                                iEastX = int((iW - 1) * fEastLon) - 1
                                iSouthY = int((iH - 1) * fSouthLat)
                                iNorthY = int((iH - 1) * fNorthLat) -1
                                buffer_data.append([iWestX, iEastX, iSouthY, iNorthY])
                else: pass
                [fWestLon, fEastLon, fSouthLat, fNorthLat] = center_isle[iPlayers]
                iWestX = int((iW - 1) * fWestLon)
                iEastX = int((iW - 1) * fEastLon) - 1
                iSouthY = int((iH - 1) * fSouthLat)
                iNorthY = int((iH - 1) * fNorthLat) -1
                center_data = [iWestX, iEastX, iSouthY, iNorthY]
                hub_data = []
                for [fStartLon, fStartLat, fEndLon, fEndLat] in the_spokes[iPlayers]:
                        iStartX = int((iW - 1) * fStartLon)
                        iStartY = int((iH - 1) * fStartLat)
                        iEndX = int((iW - 1) * fEndLon)
                        iEndY = int((iH - 1) * fEndLat)
                        hub_data.append([iStartX, iStartY, iEndX, iEndY])
        elif idMap == "inlandsea" :
                configs = [0, 1, 6, 4, 3, 2, 2, 2, 4, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1]
                iPlayers = game.countCivPlayersEverAlive()
                iNumTemplates = configs[iPlayers]
                iTemplateRoll = getRandNum(iNumTemplates, "FoR : Template Selection - Inland Sea PYTHON")
                map_size = map.getWorldSize()
                sizevalues = {
                        WorldSizeTypes.WORLDSIZE_DUEL:		(2, 3),
                        WorldSizeTypes.WORLDSIZE_TINY:		(2, 3),
                        WorldSizeTypes.WORLDSIZE_SMALL:		(3, 4),
                        WorldSizeTypes.WORLDSIZE_STANDARD:	(4, 7),
                        WorldSizeTypes.WORLDSIZE_LARGE:		(5, 10),
                        WorldSizeTypes.WORLDSIZE_HUGE:		(6, 15)
                        }
                if map_size in sizevalues :
                        (threeVar, twoVar) = sizevalues[map_size]
                else :
                        (threeVar, twoVar) = (7, 21)
                if iPlayers <= threeVar:
                        fVar = 3
                elif iPlayers <= twoVar:
                        fVar = 2
                else:
                        fVar = 1
                templates = {(1,0): {0: [0.5, 0.5, int(0.5 * iW), int(0.5 * iH)]},
                             (2,0): {0: [0.1, 0.5, fVar, int(0.5 * iH)],
                                     1: [0.9, 0.5, fVar, int(0.5 * iH)]},
                             (2,1): {0: [0.5, 0.167, int(0.3 * iW), fVar],
                                     1: [0.5, 0.833, int(0.3 * iW), fVar]},
                             (2,2): {0: [0.3, 0.167, int(0.3 * iW), fVar],
                                     1: [0.7, 0.833, int(0.3 * iW), fVar]},
                             (2,3): {0: [0.7, 0.167, int(0.3 * iW), fVar],
                                     1: [0.3, 0.833, int(0.3 * iW), fVar]},
                             (2,4): {0: [0.2, 0.333, int(0.2 * iW), int(0.333 * iH)],
                                     1: [0.8, 0.667, int(0.2 * iW), int(0.333 * iH)]},
                             (2,5): {0: [0.8, 0.333, int(0.2 * iW), int(0.333 * iH)],
                                     1: [0.2, 0.677, int(0.2 * iW), int(0.333 * iH)]},
                             (3,0): {0: [0.1, 0.5, fVar, fVar],
                                     1: [0.7, 0.167, fVar, fVar],
                                     2: [0.7, 0.833, fVar, fVar]},
                             (3,1): {0: [0.9, 0.5, fVar, fVar],
                                     1: [0.3, 0.167, fVar, fVar],
                                     2: [0.3, 0.833, fVar, fVar]},
                             (3,2): {0: [0.5, 0.167, fVar, fVar],
                                     1: [0.1, 0.833, fVar, fVar],
                                     2: [0.9, 0.833, fVar, fVar]},
                             (3,3): {0: [0.5, 0.833, fVar, fVar],
                                     1: [0.1, 0.167, fVar, fVar],
                                     2: [0.9, 0.167, fVar, fVar]},
                             (4,0): {0: [0.1, 0.5, fVar, fVar],
                                     1: [0.5, 0.167, fVar, fVar],
                                     2: [0.9, 0.5, fVar, fVar],
                                     3: [0.5, 0.833, fVar, fVar]},
                             (4,1): {0: [0.1, 0.167, fVar, fVar],
                                     1: [0.7, 0.167, fVar, fVar],
                                     2: [0.9, 0.833, fVar, fVar],
                                     3: [0.3, 0.833, fVar, fVar]},
                             (4,2): {0: [0.1, 0.833, fVar, fVar],
                                     1: [0.7, 0.833, fVar, fVar],
                                     2: [0.9, 0.167, fVar, fVar],
                                     3: [0.3, 0.167, fVar, fVar]},
                             (5,0): {0: [0.5, 0.167, fVar, fVar],
                                     1: [0.125, 0.333, fVar, fVar],
                                     2: [0.25, 0.833, fVar, fVar],
                                     3: [0.75, 0.833, fVar, fVar],
                                     4: [0.875, 0.333, fVar, fVar]},
                             (5,1): {0: [0.5, 0.833, fVar, fVar],
                                     1: [0.125, 0.667, fVar, fVar],
                                     2: [0.25, 0.167, fVar, fVar],
                                     3: [0.75, 0.167, fVar, fVar],
                                     4: [0.875, 0.667, fVar, fVar]},
                             (6,0): {0: [0.1, 0.5, fVar, fVar],
                                     1: [0.3, 0.167, fVar, fVar],
                                     2: [0.7, 0.167, fVar, fVar],
                                     3: [0.9, 0.5, fVar, fVar],
                                     4: [0.7, 0.833, fVar, fVar],
                                     5: [0.3, 0.833, fVar, fVar]},
                             (6,1): {0: [0.1, 0.167, fVar, fVar],
                                     1: [0.5, 0.167, fVar, fVar],
                                     2: [0.9, 0.167, fVar, fVar],
                                     3: [0.9, 0.833, fVar, fVar],
                                     4: [0.5, 0.833, fVar, fVar],
                                     5: [0.1, 0.833, fVar, fVar]},
                             (7,0): {0: [0.1, 0.5, fVar, fVar],
                                     1: [0.2, 0.125, fVar, fVar],
                                     2: [0.6, 0.125, fVar, fVar],
                                     3: [0.9, 0.25, fVar, fVar],
                                     4: [0.9, 0.75, fVar, fVar],
                                     5: [0.6, 0.875, fVar, fVar],
                                     6: [0.2, 0.875, fVar, fVar]},
                             (7,1): {0: [0.9, 0.5, fVar, fVar],
                                     1: [0.8, 0.125, fVar, fVar],
                                     2: [0.4, 0.125, fVar, fVar],
                                     3: [0.1, 0.25, fVar, fVar],
                                     4: [0.1, 0.75, fVar, fVar],
                                     5: [0.4, 0.875, fVar, fVar],
                                     6: [0.8, 0.875, fVar, fVar]},
                             (8,0): {0: [0.583, 0.125, fVar, fVar],
                                     1: [0.25, 0.125, fVar, fVar],
                                     2: [0.083, 0.375, fVar, fVar],
                                     3: [0.083, 0.875, fVar, fVar],
                                     4: [0.417, 0.875, fVar, fVar],
                                     5: [0.75, 0.875, fVar, fVar],
                                     6: [0.917, 0.625, fVar, fVar],
                                     7: [0.917, 0.125, fVar, fVar]},
                             (8,1): {0: [0.417, 0.125, fVar, fVar],
                                     1: [0.083, 0.125, fVar, fVar],
                                     2: [0.083, 0.625, fVar, fVar],
                                     3: [0.25, 0.875, fVar, fVar],
                                     4: [0.583, 0.875, fVar, fVar],
                                     5: [0.917, 0.875, fVar, fVar],
                                     6: [0.917, 0.375, fVar, fVar],
                                     7: [0.75, 0.125, fVar, fVar]},
                             (8,2): {0: [0.1, 0.5, fVar, fVar],
                                     1: [0.2, 0.125, fVar, fVar],
                                     2: [0.5, 0.125, fVar, fVar],
                                     3: [0.8, 0.125, fVar, fVar],
                                     4: [0.9, 0.5, fVar, fVar],
                                     5: [0.8, 0.875, fVar, fVar],
                                     6: [0.5, 0.875, fVar, fVar],
                                     7: [0.2, 0.875, fVar, fVar]},
                             (8,3): {0: [0.1, 0.75, fVar, fVar],
                                     1: [0.1, 0.25, fVar, fVar],
                                     2: [0.333, 0.125, fVar, fVar],
                                     3: [0.667, 0.125, fVar, fVar],
                                     4: [0.9, 0.25, fVar, fVar],
                                     5: [0.9, 0.75, fVar, fVar],
                                     6: [0.667, 0.875, fVar, fVar],
                                     7: [0.333, 0.875, fVar, fVar]},
                             (9,0): {0: [0.833, 0.15, fVar, fVar],
                                     1: [0.5, 0.15, fVar, fVar],
                                     2: [0.167, 0.15, fVar, fVar],
                                     3: [0.08, 0.412, fVar, fVar],
                                     4: [0.08, 0.775, fVar, fVar],
                                     5: [0.35, 0.85, fVar, fVar],
                                     6: [0.65, 0.85, fVar, fVar],
                                     7: [0.92, 0.775, fVar, fVar],
                                     8: [0.92, 0.412, fVar, fVar]},
                             (9,1): {0: [0.833, 0.85, fVar, fVar],
                                     1: [0.5, 0.85, fVar, fVar],
                                     2: [0.167, 0.85, fVar, fVar],
                                     3: [0.08, 0.588, fVar, fVar],
                                     4: [0.08, 0.225, fVar, fVar],
                                     5: [0.35, 0.15, fVar, fVar],
                                     6: [0.65, 0.15, fVar, fVar],
                                     7: [0.92, 0.225, fVar, fVar],
                                     8: [0.92, 0.588, fVar, fVar]},
                             (10,0): {0: [0.875, 0.15, fVar, fVar],
                                      1: [0.625, 0.15, fVar, fVar],
                                      2: [0.375, 0.15, fVar, fVar],
                                      3: [0.125, 0.15, fVar, fVar],
                                      4: [0.08, 0.5, fVar, fVar],
                                      5: [0.125, 0.85, fVar, fVar],
                                      6: [0.375, 0.85, fVar, fVar],
                                      7: [0.625, 0.85, fVar, fVar],
                                      8: [0.875, 0.85, fVar, fVar],
                                      9: [0.92, 0.5, fVar, fVar]},
                             (10,1): {0: [0.75, 0.15, fVar, fVar],
                                      1: [0.5, 0.15, fVar, fVar],
                                      2: [0.25, 0.15, fVar, fVar],
                                      3: [0.08, 0.33, fVar, fVar],
                                      4: [0.08, 0.67, fVar, fVar],
                                      5: [0.25, 0.85, fVar, fVar],
                                      6: [0.5, 0.85, fVar, fVar],
                                      7: [0.75, 0.85, fVar, fVar],
                                      8: [0.92, 0.67, fVar, fVar],
                                      9: [0.92, 0.33, fVar, fVar]},
                             (11,0): {0: [0.875, 0.15, fVar, fVar],
                                      1: [0.625, 0.15, fVar, fVar],
                                      2: [0.375, 0.15, fVar, fVar],
                                      3: [0.125, 0.15, fVar, fVar],
                                      4: [0.08, 0.45, fVar, fVar],
                                      5: [0.08, 0.75, fVar, fVar],
                                      6: [0.28, 0.85, fVar, fVar],
                                      7: [0.5, 0.85, fVar, fVar],
                                      8: [0.72, 0.85, fVar, fVar],
                                      9: [0.92, 0.75, fVar, fVar],
                                      10: [0.92, 0.45, fVar, fVar]},
                             (11,1): {0: [0.875, 0.85, fVar, fVar],
                                      1: [0.625, 0.85, fVar, fVar],
                                      2: [0.375, 0.85, fVar, fVar],
                                      3: [0.125, 0.85, fVar, fVar],
                                      4: [0.08, 0.55, fVar, fVar],
                                      5: [0.08, 0.25, fVar, fVar],
                                      6: [0.28, 0.15, fVar, fVar],
                                      7: [0.5, 0.15, fVar, fVar],
                                      8: [0.72, 0.15, fVar, fVar],
                                      9: [0.92, 0.25, fVar, fVar],
                                      10: [0.92, 0.55, fVar, fVar]},
                             (12,0): {0: [0.7, 0.15, fVar, fVar],
                                      1: [0.5, 0.15, fVar, fVar],
                                      2: [0.3, 0.15, fVar, fVar],
                                      3: [0.1, 0.15, fVar, fVar],
                                      4: [0.08, 0.5, fVar, fVar],
                                      5: [0.1, 0.85, fVar, fVar],
                                      6: [0.3, 0.85, fVar, fVar],
                                      7: [0.5, 0.85, fVar, fVar],
                                      8: [0.7, 0.85, fVar, fVar],
                                      9: [0.9, 0.85, fVar, fVar],
                                      10: [0.92, 0.5, fVar, fVar],
                                      11: [0.9, 0.15, fVar, fVar]},
                             (13,0): {0: [0.7, 0.125, fVar, fVar],
                                      1: [0.5, 0.125, fVar, fVar],
                                      2: [0.3, 0.125, fVar, fVar],
                                      3: [0.1, 0.125, fVar, fVar],
                                      4: [0.08, 0.425, fVar, fVar],
                                      5: [0.08, 0.725, fVar, fVar],
                                      6: [0.2, 0.875, fVar, fVar],
                                      7: [0.4, 0.875, fVar, fVar],
                                      8: [0.6, 0.875, fVar, fVar],
                                      9: [0.8, 0.875, fVar, fVar],
                                      10: [0.92, 0.725, fVar, fVar],
                                      11: [0.92, 0.425, fVar, fVar],
                                      12: [0.9, 0.125, fVar, fVar]},
                             (13,1): {0: [0.7, 0.875, fVar, fVar],
                                      1: [0.5, 0.875, fVar, fVar],
                                      2: [0.3, 0.875, fVar, fVar],
                                      3: [0.1, 0.875, fVar, fVar],
                                      4: [0.08, 0.575, fVar, fVar],
                                      5: [0.08, 0.275, fVar, fVar],
                                      6: [0.2, 0.125, fVar, fVar],
                                      7: [0.4, 0.125, fVar, fVar],
                                      8: [0.6, 0.125, fVar, fVar],
                                      9: [0.8, 0.125, fVar, fVar],
                                      10: [0.92, 0.275, fVar, fVar],
                                      11: [0.92, 0.575, fVar, fVar],
                                      12: [0.9, 0.875, fVar, fVar]},
                             (14,0): {0: [0.7, 0.125, fVar, fVar],
                                      1: [0.5, 0.125, fVar, fVar],
                                      2: [0.3, 0.125, fVar, fVar],
                                      3: [0.1, 0.125, fVar, fVar],
                                      4: [0.08, 0.375, fVar, fVar],
                                      5: [0.08, 0.625, fVar, fVar],
                                      6: [0.1, 0.875, fVar, fVar],
                                      7: [0.3, 0.875, fVar, fVar],
                                      8: [0.5, 0.875, fVar, fVar],
                                      9: [0.7, 0.875, fVar, fVar],
                                      10: [0.9, 0.875, fVar, fVar],
                                      11: [0.92, 0.625, fVar, fVar],
                                      12: [0.92, 0.375, fVar, fVar],
                                      13: [0.9, 0.125, fVar, fVar]},
                             (15,0): {0: [0.583, 0.125, fVar, fVar],
                                      1: [0.417, 0.125, fVar, fVar],
                                      2: [0.25, 0.125, fVar, fVar],
                                      3: [0.083, 0.125, fVar, fVar],
                                      4: [0.083, 0.4, fVar, fVar],
                                      5: [0.083, 0.65, fVar, fVar],
                                      6: [0.1, 0.9, fVar, fVar],
                                      7: [0.3, 0.875, fVar, fVar],
                                      8: [0.5, 0.875, fVar, fVar],
                                      9: [0.7, 0.875, fVar, fVar],
                                      10: [0.9, 0.9, fVar, fVar],
                                      11: [0.917, 0.65, fVar, fVar],
                                      12: [0.917, 0.4, fVar, fVar],
                                      13: [0.917, 0.125, fVar, fVar],
                                      14: [0.75, 0.125, fVar, fVar]},
                             (15,1): {0: [0.583, 0.875, fVar, fVar],
                                      1: [0.417, 0.875, fVar, fVar],
                                      2: [0.25, 0.875, fVar, fVar],
                                      3: [0.083, 0.875, fVar, fVar],
                                      4: [0.083, 0.6, fVar, fVar],
                                      5: [0.083, 0.35, fVar, fVar],
                                      6: [0.1, 0.1, fVar, fVar],
                                      7: [0.3, 0.125, fVar, fVar],
                                      8: [0.5, 0.125, fVar, fVar],
                                      9: [0.7, 0.125, fVar, fVar],
                                      10: [0.9, 0.1, fVar, fVar],
                                      11: [0.917, 0.35, fVar, fVar],
                                      12: [0.917, 0.6, fVar, fVar],
                                      13: [0.917, 0.875, fVar, fVar],
                                      14: [0.75, 0.875, fVar, fVar]},
                             (16,0): {0: [0.583, 0.125, fVar, fVar],
                                      1: [0.417, 0.125, fVar, fVar],
                                      2: [0.25, 0.125, fVar, fVar],
                                      3: [0.083, 0.125, fVar, fVar],
                                      4: [0.083, 0.375, fVar, fVar],
                                      5: [0.083, 0.625, fVar, fVar],
                                      6: [0.083, 0.875, fVar, fVar],
                                      7: [0.25, 0.875, fVar, fVar],
                                      8: [0.417, 0.875, fVar, fVar],
                                      9: [0.583, 0.875, fVar, fVar],
                                      10: [0.75, 0.875, fVar, fVar],
                                      11: [0.917, 0.875, fVar, fVar],
                                      12: [0.917, 0.625, fVar, fVar],
                                      13: [0.917, 0.375, fVar, fVar],
                                      14: [0.917, 0.125, fVar, fVar],
                                      15: [0.75, 0.125, fVar, fVar]},
                             (17,0): {0: [0.5, 0.125, fVar, fVar],
                                      1: [0.35, 0.125, fVar, fVar],
                                      2: [0.2, 0.125, fVar, fVar],
                                      3: [0.05, 0.175, fVar, fVar],
                                      4: [0.083, 0.45, fVar, fVar],
                                      5: [0.083, 0.7, fVar, fVar],
                                      6: [0.083, 0.95, fVar, fVar],
                                      7: [0.25, 0.875, fVar, fVar],
                                      8: [0.417, 0.875, fVar, fVar],
                                      9: [0.583, 0.875, fVar, fVar],
                                      10: [0.75, 0.875, fVar, fVar],
                                      11: [0.917, 0.95, fVar, fVar],
                                      12: [0.917, 0.7, fVar, fVar],
                                      13: [0.917, 0.45, fVar, fVar],
                                      14: [0.95, 0.175, fVar, fVar],
                                      15: [0.8, 0.125, fVar, fVar],
                                      16: [0.65, 0.125, fVar, fVar]},
                             (17,1): {0: [0.5, 0.875, fVar, fVar],
                                      1: [0.35, 0.875, fVar, fVar],
                                      2: [0.2, 0.875, fVar, fVar],
                                      3: [0.05, 0.825, fVar, fVar],
                                      4: [0.083, 0.65, fVar, fVar],
                                      5: [0.083, 0.3, fVar, fVar],
                                      6: [0.083, 0.05, fVar, fVar],
                                      7: [0.25, 0.125, fVar, fVar],
                                      8: [0.417, 0.125, fVar, fVar],
                                      9: [0.583, 0.125, fVar, fVar],
                                      10: [0.75, 0.125, fVar, fVar],
                                      11: [0.917, 0.05, fVar, fVar],
                                      12: [0.917, 0.3, fVar, fVar],
                                      13: [0.917, 0.65, fVar, fVar],
                                      14: [0.95, 0.825, fVar, fVar],
                                      15: [0.8, 0.875, fVar, fVar],
                                      16: [0.65, 0.875, fVar, fVar]},
                             (18,0): {0: [0.5, 0.125, fVar, fVar],
                                      1: [0.35, 0.125, fVar, fVar],
                                      2: [0.2, 0.125, fVar, fVar],
                                      3: [0.05, 0.125, fVar, fVar],
                                      4: [0.075, 0.375, fVar, fVar],
                                      5: [0.075, 0.625, fVar, fVar],
                                      6: [0.05, 0.875, fVar, fVar],
                                      7: [0.2, 0.875, fVar, fVar],
                                      8: [0.35, 0.875, fVar, fVar],
                                      9: [0.5, 0.875, fVar, fVar],
                                      10: [0.65, 0.875, fVar, fVar],
                                      11: [0.8, 0.875, fVar, fVar],
                                      12: [0.95, 0.875, fVar, fVar],
                                      13: [0.925, 0.625, fVar, fVar],
                                      14: [0.925, 0.375, fVar, fVar],
                                      15: [0.95, 0.125, fVar, fVar],
                                      16: [0.8, 0.125, fVar, fVar],
                                      17: [0.65, 0.125, fVar, fVar]}
                }
                player_list = []
                for playerLoop in range(game.countCivPlayersEverAlive()):
                        player_list.append(playerLoop)
                shuffledPlayers = []
                for playerLoopTwo in range(game.countCivPlayersEverAlive()):
                        iChoosePlayer = getRandNum(len(player_list), "FoR : Shuffling Template IDs - Inland Sea PYTHON")
                        shuffledPlayers.append(player_list[iChoosePlayer])
                        del player_list[iChoosePlayer]
        elif idMap == "islands" :
                userInputLargeIslands = cmo[0]
                iPlayers = game.countCivPlayersEverAlive()
                if iPlayers < 1 or iPlayers > 18:
                        return None
                if userInputLargeIslands == 0:
                        configs = [0, 4, 4, 4, 6, 8, 8, 12, 12, 12, 15, 15, 15, 15, 20, 20, 20, 24, 24]
                        iExtras = 0
                elif userInputLargeIslands == 2:
                        configs = [0, 4, 4, 6, 8, 8, 12, 12, 12, 15, 15, 15, 20, 20, 20, 24, 24, 24, 24]
                        extras_min_list = [0, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 3, 4, 4, 4, 4]
                        extras_max_list = [0, 3, 2, 3, 3, 3, 5, 5, 4, 6, 5, 4, 7, 7, 6, 8, 8, 7, 6]
                        extras_min = extras_min_list[iPlayers]
                        extras_max = extras_max_list[iPlayers]
                        if extras_min == extras_max:
                                iExtras = extras_min
                        else:
                                extras_range = getRandNum((extras_max - extras_min + 1), "FoR : Extra Islands - Islands PYTHON")
                                iExtras = extras_min + extras_range
                else:
                        configs = [0, 4, 4, 6, 6, 8, 8, 12, 12, 12, 15, 15, 15, 15, 20, 20, 20, 24, 24]
                        extras_min_list = [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 2]
                        extras_max_list = [0, 2, 1, 2, 2, 2, 2, 3, 3, 2, 3, 3, 3, 2, 3, 4, 4, 4, 4]
                        extras_min = extras_min_list[iPlayers]
                        extras_max = extras_max_list[iPlayers]
                        if extras_min == extras_max:
                                iExtras = extras_min
                        else:
                                extras_range = getRandNum((extras_max - extras_min + 1), "FoR : Extra Islands - Islands PYTHON")
                                iExtras = extras_min + extras_range
                iNumRegions = configs[iPlayers]
                regions_in_use = []
                remaining_regions = []
                for loopy in range(iNumRegions):
                        remaining_regions.append(loopy)
                templates = {4: {0: [0.0, 0.5, 0.1, 0.45],
                                 1: [0.5, 1.0, 0.1, 0.45],
                                 2: [0.0, 0.5, 0.55, 0.9],
                                 3: [0.5, 1.0, 0.55, 0.9]},
                             6: {0: [0.0, 0.333, 0.1, 0.45],
                                 1: [0.333, 0.667, 0.1, 0.45],
                                 2: [0.667, 1.0, 0.1, 0.45],
                                 3: [0.0, 0.333, 0.55, 0.9],
                                 4: [0.333, 0.667, 0.55, 0.9],
                                 5: [0.667, 1.0, 0.55, 0.9]},
                             8: {0: [0.0, 0.25, 0.1, 0.45],
                                 1: [0.25, 0.5, 0.1, 0.45],
                                 2: [0.5, 0.75, 0.1, 0.45],
                                 3: [0.75, 1.0, 0.1, 0.45],
                                 4: [0.0, 0.25, 0.55, 0.9],
                                 5: [0.25, 0.5, 0.55, 0.9],
                                 6: [0.5, 0.75, 0.55, 0.9],
                                 7: [0.75, 1.0, 0.55, 0.9]},
                             12: {0: [0.0, 0.25, 0.1, 0.35],
                                  1: [0.25, 0.5, 0.1, 0.35],
                                  2: [0.5, 0.75, 0.1, 0.35],
                                  3: [0.75, 1.0, 0.1, 0.35],
                                  4: [0.0, 0.25, 0.4, 0.6],
                                  5: [0.25, 0.5, 0.4, 0.6],
                                  6: [0.5, 0.75, 0.4, 0.6],
                                  7: [0.75, 1.0, 0.4, 0.6],
                                  8: [0.0, 0.25, 0.65, 0.9],
                                  9: [0.25, 0.5, 0.65, 0.9],
                                  10: [0.5, 0.75, 0.65, 0.9],
                                  11: [0.75, 1.0, 0.65, 0.9]},
                             15: {0: [0.0, 0.2, 0.1, 0.35],
                                  1: [0.2, 0.4, 0.1, 0.35],
                                  2: [0.4, 0.6, 0.1, 0.35],
                                  3: [0.6, 0.8, 0.1, 0.35],
                                  4: [0.8, 1.0, 0.1, 0.35],
                                  5: [0.0, 0.2, 0.4, 0.6],
                                  6: [0.2, 0.4, 0.4, 0.6],
                                  7: [0.4, 0.6, 0.4, 0.6],
                                  8: [0.6, 0.8, 0.4, 0.6],
                                  9: [0.8, 1.0, 0.4, 0.6],
                                  10: [0.0, 0.2, 0.65, 0.9],
                                  11: [0.2, 0.4, 0.65, 0.9],
                                  12: [0.4, 0.6, 0.65, 0.9],
                                  13: [0.6, 0.8, 0.65, 0.9],
                                  14: [0.8, 1.0, 0.65, 0.9]},
                             20: {0: [0.0, 0.2, 0.1, 0.29],
                                  1: [0.2, 0.4, 0.1, 0.29],
                                  2: [0.4, 0.6, 0.1, 0.29],
                                  3: [0.6, 0.8, 0.1, 0.29],
                                  4: [0.8, 1.0, 0.1, 0.29],
                                  5: [0.0, 0.2, 0.33, 0.48],
                                  6: [0.2, 0.4, 0.33, 0.48],
                                  7: [0.4, 0.6, 0.33, 0.48],
                                  8: [0.6, 0.8, 0.33, 0.48],
                                  9: [0.8, 1.0, 0.33, 0.48],
                                  10: [0.0, 0.2, 0.52, 0.67],
                                  11: [0.2, 0.4, 0.52, 0.67],
                                  12: [0.4, 0.6, 0.52, 0.67],
                                  13: [0.6, 0.8, 0.52, 0.67],
                                  14: [0.8, 1.0, 0.52, 0.67],
                                  15: [0.0, 0.2, 0.71, 0.9],
                                  16: [0.2, 0.4, 0.71, 0.9],
                                  17: [0.4, 0.6, 0.71, 0.9],
                                  18: [0.6, 0.8, 0.71, 0.9],
                                  19: [0.8, 1.0, 0.71, 0.9]},
                             24: {0: [0.0, 0.167, 0.1, 0.29],
                                  1: [0.167, 0.333, 0.1, 0.29],
                                  2: [0.333, 0.5, 0.1, 0.29],
                                  3: [0.5, 0.667, 0.1, 0.29],
                                  4: [0.667, 0.833, 0.1, 0.29],
                                  5: [0.833, 1.0, 0.1, 0.29],
                                  6: [0.0, 0.167, 0.33, 0.48],
                                  7: [0.167, 0.333, 0.33, 0.48],
                                  8: [0.333, 0.5, 0.33, 0.48],
                                  9: [0.5, 0.667, 0.33, 0.48],
                                  10: [0.667, 0.833, 0.33, 0.48],
                                  11: [0.833, 1.0, 0.33, 0.48],
                                  12: [0.0, 0.167, 0.52, 0.67],
                                  13: [0.167, 0.333, 0.52, 0.67],
                                  14: [0.333, 0.5, 0.52, 0.67],
                                  15: [0.5, 0.667, 0.52, 0.67],
                                  16: [0.667, 0.833, 0.52, 0.67],
                                  17: [0.833, 1.0, 0.52, 0.67],
                                  18: [0.0, 0.167, 0.71, 0.9],
                                  19: [0.167, 0.333, 0.71, 0.9],
                                  20: [0.333, 0.5, 0.71, 0.9],
                                  21: [0.5, 0.667, 0.71, 0.9],
                                  22: [0.667, 0.833, 0.71, 0.9],
                                  23: [0.833, 1.0, 0.71, 0.9]}
                }
                region_coords = templates[iNumRegions]
        elif idMap == "pangaea" :
                iPlayers = game.countCivPlayersEverAlive()
                iTeams = game.countCivTeamsEverAlive()
                if iPlayers >= iTeams * 2 or iPlayers == 2:
                        isTeamGame = True
                else:
                        isTeamGame = False
        elif idMap == "ring" :
                iPlayers = game.countCivPlayersEverAlive()
                if iPlayers < 2 or iPlayers > 18:
                        bSuccessFlag = False
                        return 0
                else:
                        bSuccessFlag = True
                userInputLandmass = cmo[0]
                if userInputLandmass == 1 and iPlayers >= 2 and iPlayers <= 10:
                        templates = {2: {0: [0.0, 0.333, 0.0, 1.0],
                                         1: [0.667, 1.0, 0.0, 1.0]},
                                     3: {0: [0.0, 0.4, 0.667, 1.0],
                                         1: [0.8, 1.0, 0.333, 1.0],
                                         2: [0.2, 0.6, 0.0, 0.333]},
                                     4: {0: [0.0, 0.333, 0.333, 0.667],
                                         1: [0.333, 0.667, 0.667, 1.0],
                                         2: [0.667, 1.0, 0.333, 0.667],
                                         3: [0.333, 0.667, 0.0, 0.333]},
                                     5: {0: [0.0, 0.167, 0.4, 0.8],
                                         1: [0.333, 0.667, 0.8, 1.0],
                                         2: [0.833, 1.0, 0.4, 0.8],
                                         3: [0.583, 0.917, 0.0, 0.2],
                                         4: [0.083, 0.417, 0.0, 0.2]},
                                     6: {0: [0.0, 0.333, 0.8, 1.0],
                                         1: [0.5, 0.833, 0.8, 1.0],
                                         2: [0.833, 1.0, 0.4, 0.8],
                                         3: [0.667, 1.0, 0.0, 0.2],
                                         4: [0.167, 0.5, 0.0, 0.2],
                                         5: [0.0, 0.167, 0.2, 0.6]},
                                     7: {0: [0.0, 0.2, 0.75, 1.0],
                                         1: [0.4, 0.6, 0.75, 1.0],
                                         2: [0.8, 1.0, 0.75, 1.0],
                                         3: [0.8, 1.0, 0.25, 0.5],
                                         4: [0.6, 0.8, 0.0, 0.25],
                                         5: [0.2, 0.4, 0.0, 0.25],
                                         6: [0.0, 0.2, 0.25, 0.5]},
                                     8: {0: [0.0, 0.2, 0.6, 0.8],
                                         1: [0.2, 0.4, 0.8, 1.0],
                                         2: [0.6, 0.8, 0.8, 1.0],
                                         3: [0.8, 1.0, 0.6, 0.8],
                                         4: [0.8, 1.0, 0.2, 0.4],
                                         5: [0.6, 0.8, 0.0, 0.2],
                                         6: [0.2, 0.4, 0.0, 0.2],
                                         7: [0.0, 0.2, 0.2, 0.4]},
                                     9: {0: [0.0, 0.167, 0.6, 0.8],
                                         1: [0.167, 0.333, 0.8, 1.0],
                                         2: [0.5, 0.677, 0.8, 1.0],
                                         3: [0.833, 1.0, 0.8, 1.0],
                                         4: [0.833, 1.0, 0.4, 0.6],
                                         5: [0.833, 1.0, 0.0, 0.2],
                                         6: [0.5, 0.667, 0.0, 0.2],
                                         7: [0.167, 0.333, 0.0, 0.2],
                                         8: [0.0, 0.167, 0.2, 0.4]},
                                     10: {0: [0.0, 0.167, 0.667, 0.833],
                                          1: [0.167, 0.333, 0.833, 1.0],
                                          2: [0.5, 0.667, 0.833, 1.0],
                                          3: [0.833, 1.0, 0.833, 1.0],
                                          4: [0.833, 1.0, 0.5, 0.667],
                                          5: [0.833, 1.0, 0.167, 0.333],
                                          6: [0.667, 0.833, 0.0, 0.167],
                                          7: [0.333, 0.5, 0.0, 0.167],
                                          8: [0.0, 0.167, 0.0, 0.167],
                                          9: [0.0, 0.167, 0.333, 0.5]}
                        }
                        buffers = {2: {0: [0.4, 0.6, 0.1, 0.3],
                                       1: [0.4, 0.6, 0.7, 0.9]},
                                   3: {0: [0.4, 0.8, 0.667, 1.0],
                                       1: [0.6, 1.0, 0.0, 0.333],
                                       2: [0.0, 0.2, 0.0, 0.667]},
                                   4: {0: [0.0, 0.333, 0.667, 1.0],
                                       1: [0.667, 1.0, 0.667, 1.0],
                                       2: [0.667, 1.0, 0.0, 0.333],
                                       3: [0.0, 0.333, 0.0, 0.333]},
                                   5: {0: [0.0, 0.167, 0.2, 0.4],
                                       1: [0.167, 0.333, 0.8, 1.0],
                                       2: [0.667, 0.833, 0.8, 1.0],
                                       3: [0.833, 1.0, 0.2, 0.4],
                                       4: [0.417, 0.583, 0.0, 0.2]},
                                   6: {0: [0.0, 0.167, 0.6, 0.8],
                                       1: [0.333, 0.5, 0.8, 1.0],
                                       2: [0.833, 1.0, 0.8, 1.0],
                                       3: [0.833, 1.0, 0.2, 0.4],
                                       4: [0.5, 0.667, 0.0, 0.2],
                                       5: [0.0, 0.167, 0.0, 0.2]},
                                   7: {0: [0.2, 0.4, 0.75, 1.0],
                                       1: [0.6, 0.8, 0.75, 1.0],
                                       2: [0.8, 1.0, 0.5, 0.75],
                                       3: [0.8, 1.0, 0.0, 0.25],
                                       4: [0.4, 0.6, 0.0, 0.25],
                                       5: [0.0, 0.2, 0.0, 0.25],
                                       6: [0.0, 0.2, 0.5, 0.75]},
                                   8: {0: [0.0, 0.2, 0.8, 1.0],
                                       1: [0.4, 0.6, 0.8, 1.0],
                                       2: [0.8, 1.0, 0.8, 1.0],
                                       3: [0.8, 1.0, 0.4, 0.6],
                                       4: [0.8, 1.0, 0.0, 0.2],
                                       5: [0.4, 0.6, 0.0, 0.2],
                                       6: [0.0, 0.2, 0.0, 0.2],
                                       7: [0.0, 0.2, 0.4, 0.6]},
                                   9: {0: [0.0, 0.167, 0.8, 1.0],
                                       1: [0.333, 0.5, 0.8, 1.0],
                                       2: [0.667, 0.833, 0.8, 1.0],
                                       3: [0.833, 1.0, 0.6, 0.8],
                                       4: [0.833, 1.0, 0.2, 0.4],
                                       5: [0.667, 0.833, 0.0, 0.2],
                                       6: [0.333, 0.5, 0.0, 0.2],
                                       7: [0.0, 0.167, 0.0, 0.2],
                                       8: [0.0, 0.167, 0.4, 0.6]},
                                   10: {0: [0.0, 0.167, 0.5, 0.667],
                                        1: [0.0, 0.167, 0.833, 1.0],
                                        2: [0.333, 0.5, 0.833, 1.0],
                                        3: [0.667, 0.833, 0.833, 1.0],
                                        4: [0.833, 1.0, 0.667, 0.833],
                                        5: [0.833, 1.0, 0.333, 0.5],
                                        6: [0.833, 1.0, 0.0, 0.167],
                                        7: [0.5, 0.667, 0.0, 0.167],
                                        8: [0.167, 0.333, 0.0, 0.167],
                                        9: [0.0, 0.167, 0.167, 0.333]}
                        }
                        center_isle = {2: [0.4, 0.6, 0.4, 0.6],
                                       3: [0.28, 0.72, 0.4, 0.6],
                                       4: [0.4, 0.6, 0.4, 0.6],
                                       5: [0.27, 0.73, 0.3, 0.7],
                                       6: [0.25, 0.75, 0.3, 0.7],
                                       7: [0.3, 0.7, 0.35, 0.65],
                                       8: [0.32, 0.68, 0.32, 0.68],
                                       9: [0.25, 0.75, 0.3, 0.7],
                                       10: [0.25, 0.75, 0.25, 0.75]
                        }
                        the_wheel = {2: [[0.167, 0.2], [0.167, 0.8], [0.833, 0.8], [0.833, 0.2]],
                                     3: [[0.1, 0.167], [0.1, 0.833], [0.9, 0.833], [0.9, 0.167]],
                                     4: [[0.167, 0.167], [0.167, 0.833], [0.833, 0.833], [0.833, 0.167]],
                                     5: [[0.083, 0.7], [0.25, 0.9], [0.75, 0.9], [0.917, 0.7], [0.917, 0.3], [0.833, 0.1], [0.167, 0.1], [0.083, 0.3]],
                                     6: [[0.083, 0.1], [0.083, 0.9], [0.917, 0.9], [0.917, 0.1]],
                                     7: [[0.1, 0.125], [0.1, 0.875], [0.9, 0.875], [0.9, 0.125]],
                                     8: [[0.1, 0.1], [0.1, 0.9], [0.9, 0.9], [0.9, 0.1]],
                                     9: [[0.083, 0.1], [0.083, 0.9], [0.917, 0.9], [0.917, 0.1]],
                                     10: [[0.083, 0.083], [0.083, 0.917], [0.917, 0.917], [0.917, 0.083]]
                        }

                else:
                        templates = {2: {0: [0.0, 0.333, 0.0, 1.0],
                                         1: [0.667, 1.0, 0.0, 1.0]},
                                     3: {0: [0.0, 0.25, 0.25, 0.75],
                                         1: [0.5, 1.0, 0.75, 1.0],
                                         2: [0.5, 1.0, 0.0, 0.25]},
                                     4: {0: [0.0, 0.333, 0.333, 0.667],
                                         1: [0.333, 0.667, 0.667, 1.0],
                                         2: [0.667, 1.0, 0.333, 0.667],
                                         3: [0.333, 0.667, 0.0, 0.333]},
                                     5: {0: [0.0, 0.25, 0.333, 1.0],
                                         1: [0.25, 0.75, 0.667, 1.0],
                                         2: [0.75, 1.0, 0.333, 1.0],
                                         3: [0.5, 1.0, 0.0, 0.333],
                                         4: [0.0, 0.5, 0.0, 0.333]},
                                     6: {0: [0.0, 0.4, 0.667, 1.0],
                                         1: [0.4, 0.8, 0.667, 1.0],
                                         2: [0.8, 1.0, 0.333, 1.0],
                                         3: [0.6, 1.0, 0.0, 0.333],
                                         4: [0.2, 0.6, 0.0, 0.333],
                                         5: [0.0, 0.2, 0.0, 0.667]},
                                     7: {0: [0.0, 0.4, 0.75, 1.0],
                                         1: [0.4, 0.8, 0.75, 1.0],
                                         2: [0.8, 1.0, 0.5, 1.0],
                                         3: [0.8, 1.0, 0.0, 0.5],
                                         4: [0.4, 0.8, 0.0, 0.25],
                                         5: [0.0, 0.4, 0.0, 0.25],
                                         6: [0.0, 0.2, 0.25, 0.75]},
                                     8: {0: [0.0, 0.3, 0.35, 0.65],
                                         1: [0.0, 0.3, 0.7, 1.0],
                                         2: [0.35, 0.65, 0.7, 1.0],
                                         3: [0.7, 1.0, 0.7, 1.0],
                                         4: [0.7, 1.0, 0.35, 0.65],
                                         5: [0.7, 1.0, 0.0, 0.3],
                                         6: [0.35, 0.65, 0.0, 0.3],
                                         7: [0.0, 0.3, 0.0, 0.3]},
                                     9: {0: [0.0, 0.167, 0.6, 1.0],
                                         1: [0.167, 0.5, 0.8, 1.0],
                                         2: [0.5, 0.833, 0.8, 1.0],
                                         3: [0.833, 1.0, 0.6, 1.0],
                                         4: [0.833, 1.0, 0.2, 0.6],
                                         5: [0.667, 1.0, 0.0, 0.2],
                                         6: [0.333, 0.667, 0.0, 0.2],
                                         7: [0.0, 0.333, 0.0, 0.2],
                                         8: [0.0, 0.167, 0.2, 0.6]},
                                     10: {0: [0.0, 0.167, 0.5, 0.833],
                                          1: [0.0, 0.333, 0.833, 1.0],
                                          2: [0.333, 0.667, 0.833, 1.0],
                                          3: [0.667, 1.0, 0.833, 1.0],
                                          4: [0.833, 1.0, 0.5, 0.833],
                                          5: [0.833, 1.0, 0.167, 0.5],
                                          6: [0.667, 1.0, 0.0, 0.167],
                                          7: [0.333, 0.667, 0.0, 0.167],
                                          8: [0.0, 0.333, 0.0, 0.167],
                                          9: [0.0, 0.167, 0.167, 0.5]},
                                     11: {0: [0.0, 0.2, 0.167, 0.5],
                                          1: [0.0, 0.2, 0.5, 0.833],
                                          2: [0.2, 0.4, 0.667, 1.0],
                                          3: [0.4, 0.6, 0.667, 1.0],
                                          4: [0.6, 0.8, 0.667, 1.0],
                                          5: [0.8, 1.0, 0.667, 1.0],
                                          6: [0.8, 1.0, 0.333, 0.667],
                                          7: [0.8, 1.0, 0.0, 0.333],
                                          8: [0.6, 0.8, 0.0, 0.333],
                                          9: [0.4, 0.6, 0.0, 0.333],
                                          10: [0.2, 0.4, 0.0, 0.333]},
                                     12: {0: [0.0, 0.2, 0.333, 0.667],
                                          1: [0.0, 0.2, 0.667, 1.0],
                                          2: [0.2, 0.4, 0.667, 1.0],
                                          3: [0.4, 0.6, 0.667, 1.0],
                                          4: [0.6, 0.8, 0.667, 1.0],
                                          5: [0.8, 1.0, 0.667, 1.0],
                                          6: [0.8, 1.0, 0.333, 0.667],
                                          7: [0.8, 1.0, 0.0, 0.333],
                                          8: [0.6, 0.8, 0.0, 0.333],
                                          9: [0.4, 0.6, 0.0, 0.333],
                                          10: [0.2, 0.4, 0.0, 0.333],
                                          11: [0.0, 0.2, 0.0, 0.333]},
                                     13: {0: [0.0, 0.2, 0.375, 0.625],
                                          1: [0.0, 0.2, 0.7, 0.95],
                                          2: [0.2, 0.4, 0.75, 1.0],
                                          3: [0.4, 0.6, 0.75, 1.0],
                                          4: [0.6, 0.8, 0.75, 1.0],
                                          5: [0.8, 1.0, 0.75, 1.0],
                                          6: [0.8, 1.0, 0.5, 0.75],
                                          7: [0.8, 1.0, 0.25, 0.5],
                                          8: [0.8, 1.0, 0.0, 0.25],
                                          9: [0.6, 0.8, 0.0, 0.25],
                                          10: [0.4, 0.6, 0.0, 0.25],
                                          11: [0.2, 0.4, 0.0, 0.25],
                                          12: [0.0, 0.2, 0.05, 0.3]},
                                     14: {0: [0.0, 0.2, 0.5, 0.75],
                                          1: [0.0, 0.2, 0.75, 1.0],
                                          2: [0.2, 0.4, 0.75, 1.0],
                                          3: [0.4, 0.6, 0.75, 1.0],
                                          4: [0.6, 0.8, 0.75, 1.0],
                                          5: [0.8, 1.0, 0.75, 1.0],
                                          6: [0.8, 1.0, 0.5, 0.75],
                                          7: [0.8, 1.0, 0.25, 0.5],
                                          8: [0.8, 1.0, 0.0, 0.25],
                                          9: [0.6, 0.8, 0.0, 0.25],
                                          10: [0.4, 0.6, 0.0, 0.25],
                                          11: [0.2, 0.4, 0.0, 0.25],
                                          12: [0.0, 0.2, 0.0, 0.25],
                                          13: [0.0, 0.2, 0.25, 0.5]},
                                     15: {0: [0.0, 0.167, 0.375, 0.625],
                                          1: [0.0, 0.167, 0.7, 0.95],
                                          2: [0.167, 0.333, 0.75, 1.0],
                                          3: [0.333, 0.5, 0.75, 1.0],
                                          4: [0.5, 0.667, 0.75, 1.0],
                                          5: [0.667, 0.833, 0.75, 1.0],
                                          6: [0.833, 1.0, 0.75, 1.0],
                                          7: [0.833, 1.0, 0.5, 0.75],
                                          8: [0.833, 1.0, 0.25, 0.5],
                                          9: [0.833, 1.0, 0.0, 0.25],
                                          10: [0.667, 0.833, 0.0, 0.25],
                                          11: [0.5, 0.667, 0.0, 0.25],
                                          12: [0.333, 0.5, 0.0, 0.25],
                                          13: [0.167, 0.333, 0.0, 0.25],
                                          14: [0.0, 0.167, 0.05, 0.3]},
                                     16: {0: [0.0, 0.167, 0.5, 0.75],
                                          1: [0.0, 0.167, 0.75, 1.0],
                                          2: [0.167, 0.333, 0.75, 1.0],
                                          3: [0.333, 0.5, 0.75, 1.0],
                                          4: [0.5, 0.667, 0.75, 1.0],
                                          5: [0.667, 0.833, 0.75, 1.0],
                                          6: [0.833, 1.0, 0.75, 1.0],
                                          7: [0.833, 1.0, 0.5, 0.75],
                                          8: [0.833, 1.0, 0.25, 0.5],
                                          9: [0.833, 1.0, 0.0, 0.25],
                                          10: [0.667, 0.833, 0.0, 0.25],
                                          11: [0.5, 0.667, 0.0, 0.25],
                                          12: [0.333, 0.5, 0.0, 0.25],
                                          13: [0.167, 0.333, 0.0, 0.25],
                                          14: [0.0, 0.167, 0.25, 0.5],
                                          15: [0.0, 0.167, 0.0, 0.25]},
                                     17: {0: [0.0, 0.167, 0.5, 0.7],
                                          1: [0.0, 0.167, 0.7, 0.9],
                                          2: [0.167, 0.333, 0.8, 1.0],
                                          3: [0.333, 0.5, 0.8, 1.0],
                                          4: [0.5, 0.667, 0.8, 1.0],
                                          5: [0.667, 0.833, 0.8, 1.0],
                                          6: [0.833, 1.0, 0.8, 1.0],
                                          7: [0.833, 1.0, 0.6, 0.8],
                                          8: [0.833, 1.0, 0.4, 0.6],
                                          9: [0.833, 1.0, 0.2, 0.4],
                                          10: [0.833, 1.0, 0.0, 0.2],
                                          11: [0.667, 0.833, 0.0, 0.2],
                                          12: [0.5, 0.667, 0.0, 0.2],
                                          13: [0.333, 0.5, 0.0, 0.2],
                                          14: [0.167, 0.333, 0.0, 0.2],
                                          15: [0.0, 0.167, 0.1, 0.3],
                                          16: [0.0, 0.167, 0.3, 0.5]},
                                     18: {0: [0.0, 0.167, 0.6, 0.8],
                                          1: [0.0, 0.167, 0.8, 1.0],
                                          2: [0.167, 0.333, 0.8, 1.0],
                                          3: [0.333, 0.5, 0.8, 1.0],
                                          4: [0.5, 0.667, 0.8, 1.0],
                                          5: [0.667, 0.833, 0.8, 1.0],
                                          6: [0.833, 1.0, 0.8, 1.0],
                                          7: [0.833, 1.0, 0.6, 0.8],
                                          8: [0.833, 1.0, 0.4, 0.6],
                                          9: [0.833, 1.0, 0.2, 0.4],
                                          10: [0.833, 1.0, 0.0, 0.2],
                                          11: [0.667, 0.833, 0.0, 0.2],
                                          12: [0.5, 0.667, 0.0, 0.2],
                                          13: [0.333, 0.5, 0.0, 0.2],
                                          14: [0.167, 0.333, 0.0, 0.2],
                                          15: [0.0, 0.167, 0.0, 0.2],
                                          16: [0.0, 0.167, 0.2, 0.4],
                                          17: [0.0, 0.167, 0.4, 0.6]}
                        }
                        center_isle = {2: [0.4, 0.6, 0.4, 0.6],
                                       3: [0.4, 0.7, 0.35, 0.65],
                                       4: [0.4, 0.6, 0.4, 0.6],
                                       5: [0.32, 0.68, 0.4, 0.6],
                                       6: [0.28, 0.72, 0.4, 0.6],
                                       7: [0.28, 0.72, 0.35, 0.65],
                                       8: [0.4, 0.6, 0.4, 0.6],
                                       9: [0.3, 0.7, 0.35, 0.65],
                                       10: [0.3, 0.7, 0.3, 0.7],
                                       11: [0.28, 0.72, 0.4, 0.6],
                                       12: [0.28, 0.72, 0.4, 0.6],
                                       13: [0.3, 0.7, 0.35, 0.65],
                                       14: [0.3, 0.7, 0.35, 0.65],
                                       15: [0.25, 0.75, 0.35, 0.65],
                                       16: [0.25, 0.75, 0.35, 0.65],
                                       17: [0.25, 0.75, 0.3, 0.7],
                                       18: [0.25, 0.75, 0.3, 0.7]
                        }
                        the_wheel = {2: [[0.167, 0.3], [0.167, 0.7], [0.833, 0.7], [0.833, 0.3]],
                                     3: [[0.125, 0.375], [0.125, 0.625], [0.625, 0.875], [0.875, 0.875], [0.875, 0.125], [0.625, 0.125]],
                                     4: [[0.167, 0.5], [0.5, 0.833], [0.833, 0.5], [0.5, 0.167]],
                                     5: [[0.125, 0.167], [0.125, 0.833], [0.875, 0.833], [0.875, 0.167]],
                                     6: [[0.1, 0.167], [0.1, 0.833], [0.9, 0.833], [0.9, 0.167]],
                                     7: [[0.1, 0.125], [0.1, 0.875], [0.9, 0.875], [0.9, 0.125]],
                                     8: [[0.167, 0.167], [0.167, 0.833], [0.833, 0.833], [0.833, 0.167]],
                                     9: [[0.083, 0.1], [0.083, 0.9], [0.917, 0.9], [0.917, 0.1]],
                                     10: [[0.083, 0.083], [0.083, 0.917], [0.917, 0.917], [0.917, 0.083]],
                                     11: [[0.1, 0.333], [0.1, 0.667], [0.3, 0.833], [0.9, 0.833], [0.9, 0.167], [0.3, 0.167]],
                                     12: [[0.1, 0.167], [0.1, 0.833], [0.9, 0.833], [0.9, 0.167]],
                                     13: [[0.1, 0.175], [0.1, 0.825], [0.3, 0.875], [0.9, 0.875], [0.9, 0.125], [0.3, 0.125]],
                                     14: [[0.1, 0.125], [0.1, 0.875], [0.9, 0.875], [0.9, 0.125]],
                                     15: [[0.083, 0.175], [0.083, 0.825], [0.25, 0.875], [0.917, 0.875], [0.917, 0.125], [0.25, 0.125]],
                                     16: [[0.083, 0.125], [0.083, 0.875], [0.917, 0.875], [0.917, 0.125]],
                                     17: [[0.083, 0.2], [0.083, 0.8], [0.25, 0.9], [0.917, 0.9], [0.917, 0.1], [0.25, 0.1]],
                                     18: [[0.083, 0.1], [0.083, 0.9], [0.917, 0.9], [0.917, 0.1]]
                        }
                region_data = []
                for regionLoop in range(iPlayers):
                        [fWestLon, fEastLon, fSouthLat, fNorthLat] = templates[iPlayers][regionLoop]
                        iWestX = int((iW - 1) * fWestLon)
                        iEastX = int((iW - 1) * fEastLon) - 1
                        iSouthY = int((iH - 1) * fSouthLat)
                        iNorthY = int((iH - 1) * fNorthLat) -1
                        region_data.append([iWestX, iEastX, iSouthY, iNorthY])
                if userInputLandmass == 1 and iPlayers >= 2 and iPlayers <= 10:
                        buffer_data = []
                        for bufferLoop in range(iPlayers):
                                [fWestLon, fEastLon, fSouthLat, fNorthLat] = buffers[iPlayers][bufferLoop]
                                iWestX = int((iW - 1) * fWestLon)
                                iEastX = int((iW - 1) * fEastLon) - 1
                                iSouthY = int((iH - 1) * fSouthLat)
                                iNorthY = int((iH - 1) * fNorthLat) -1
                                buffer_data.append([iWestX, iEastX, iSouthY, iNorthY])
                else: pass
                [fWestLon, fEastLon, fSouthLat, fNorthLat] = center_isle[iPlayers]
                iWestX = int((iW - 1) * fWestLon)
                iEastX = int((iW - 1) * fEastLon) - 1
                iSouthY = int((iH - 1) * fSouthLat)
                iNorthY = int((iH - 1) * fNorthLat) -1
                center_data = [iWestX, iEastX, iSouthY, iNorthY]
                wheel_data = []
                for [fLon, fLat] in the_wheel[iPlayers]:
                        iX = int((iW - 1) * fLon)
                        iY = int((iH - 1) * fLat)
                        wheel_data.append([iX, iY])
                [fLon, fLat] = the_wheel[iPlayers][0]
                iX = int((iW - 1) * fLon)
                iY = int((iH - 1) * fLat)
                wheel_data.append([iX, iY])
        elif idMap == "wheel" :
                iPlayers = game.countCivPlayersEverAlive()
                if iPlayers < 2 or iPlayers > 18:
                        bSuccessFlag = False
                        return 0
                else:
                        bSuccessFlag = True
                userInputLandmass = cmo[0]
                if userInputLandmass == 1 and iPlayers >= 2 and iPlayers <= 10:
                        templates = {2: {0: [0.0, 0.333, 0.0, 1.0],
                                         1: [0.667, 1.0, 0.0, 1.0]},
                                     3: {0: [0.0, 0.4, 0.667, 1.0],
                                         1: [0.8, 1.0, 0.333, 1.0],
                                         2: [0.2, 0.6, 0.0, 0.333]},
                                     4: {0: [0.0, 0.333, 0.333, 0.667],
                                         1: [0.333, 0.667, 0.667, 1.0],
                                         2: [0.667, 1.0, 0.333, 0.667],
                                         3: [0.333, 0.667, 0.0, 0.333]},
                                     5: {0: [0.0, 0.167, 0.4, 0.8],
                                         1: [0.333, 0.667, 0.8, 1.0],
                                         2: [0.833, 1.0, 0.4, 0.8],
                                         3: [0.583, 0.917, 0.0, 0.2],
                                         4: [0.083, 0.417, 0.0, 0.2]},
                                     6: {0: [0.0, 0.333, 0.8, 1.0],
                                         1: [0.5, 0.833, 0.8, 1.0],
                                         2: [0.833, 1.0, 0.4, 0.8],
                                         3: [0.667, 1.0, 0.0, 0.2],
                                         4: [0.167, 0.5, 0.0, 0.2],
                                         5: [0.0, 0.167, 0.2, 0.6]},
                                     7: {0: [0.0, 0.2, 0.75, 1.0],
                                         1: [0.4, 0.6, 0.75, 1.0],
                                         2: [0.8, 1.0, 0.75, 1.0],
                                         3: [0.8, 1.0, 0.25, 0.5],
                                         4: [0.6, 0.8, 0.0, 0.25],
                                         5: [0.2, 0.4, 0.0, 0.25],
                                         6: [0.0, 0.2, 0.25, 0.5]},
                                     8: {0: [0.0, 0.2, 0.6, 0.8],
                                         1: [0.2, 0.4, 0.8, 1.0],
                                         2: [0.6, 0.8, 0.8, 1.0],
                                         3: [0.8, 1.0, 0.6, 0.8],
                                         4: [0.8, 1.0, 0.2, 0.4],
                                         5: [0.6, 0.8, 0.0, 0.2],
                                         6: [0.2, 0.4, 0.0, 0.2],
                                         7: [0.0, 0.2, 0.2, 0.4]},
                                     9: {0: [0.0, 0.167, 0.6, 0.8],
                                         1: [0.167, 0.333, 0.8, 1.0],
                                         2: [0.5, 0.677, 0.8, 1.0],
                                         3: [0.833, 1.0, 0.8, 1.0],
                                         4: [0.833, 1.0, 0.4, 0.6],
                                         5: [0.833, 1.0, 0.0, 0.2],
                                         6: [0.5, 0.667, 0.0, 0.2],
                                         7: [0.167, 0.333, 0.0, 0.2],
                                         8: [0.0, 0.167, 0.2, 0.4]},
                                     10: {0: [0.0, 0.167, 0.667, 0.833],
                                          1: [0.167, 0.333, 0.833, 1.0],
                                          2: [0.5, 0.667, 0.833, 1.0],
                                          3: [0.833, 1.0, 0.833, 1.0],
                                          4: [0.833, 1.0, 0.5, 0.667],
                                          5: [0.833, 1.0, 0.167, 0.333],
                                          6: [0.667, 0.833, 0.0, 0.167],
                                          7: [0.333, 0.5, 0.0, 0.167],
                                          8: [0.0, 0.167, 0.0, 0.167],
                                          9: [0.0, 0.167, 0.333, 0.5]}
                        }
                        buffers = {2: {0: [0.4, 0.6, 0.1, 0.3],
                                       1: [0.4, 0.6, 0.7, 0.9]},
                                   3: {0: [0.4, 0.8, 0.667, 1.0],
                                       1: [0.6, 1.0, 0.0, 0.333],
                                       2: [0.0, 0.2, 0.0, 0.667]},
                                   4: {0: [0.0, 0.333, 0.667, 1.0],
                                       1: [0.667, 1.0, 0.667, 1.0],
                                       2: [0.667, 1.0, 0.0, 0.333],
                                       3: [0.0, 0.333, 0.0, 0.333]},
                                   5: {0: [0.0, 0.167, 0.2, 0.4],
                                       1: [0.167, 0.333, 0.8, 1.0],
                                       2: [0.667, 0.833, 0.8, 1.0],
                                       3: [0.833, 1.0, 0.2, 0.4],
                                       4: [0.417, 0.583, 0.0, 0.2]},
                                   6: {0: [0.0, 0.167, 0.6, 0.8],
                                       1: [0.333, 0.5, 0.8, 1.0],
                                       2: [0.833, 1.0, 0.8, 1.0],
                                       3: [0.833, 1.0, 0.2, 0.4],
                                       4: [0.5, 0.667, 0.0, 0.2],
                                       5: [0.0, 0.167, 0.0, 0.2]},
                                   7: {0: [0.2, 0.4, 0.77, 1.0],
                                       1: [0.6, 0.8, 0.77, 1.0],
                                       2: [0.82, 1.0, 0.5, 0.7],
                                       3: [0.8, 1.0, 0.0, 0.25],
                                       4: [0.4, 0.6, 0.0, 0.25],
                                       5: [0.0, 0.2, 0.0, 0.25],
                                       6: [0.0, 0.18, 0.5, 0.7]},
                                   8: {0: [0.0, 0.2, 0.8, 1.0],
                                       1: [0.4, 0.6, 0.8, 1.0],
                                       2: [0.8, 1.0, 0.8, 1.0],
                                       3: [0.8, 1.0, 0.4, 0.6],
                                       4: [0.8, 1.0, 0.0, 0.2],
                                       5: [0.4, 0.6, 0.0, 0.2],
                                       6: [0.0, 0.2, 0.0, 0.2],
                                       7: [0.0, 0.2, 0.4, 0.6]},
                                   9: {0: [0.0, 0.167, 0.8, 1.0],
                                       1: [0.333, 0.5, 0.8, 1.0],
                                       2: [0.667, 0.81, 0.82, 1.0],
                                       3: [0.85, 1.0, 0.6, 0.77],
                                       4: [0.85, 1.0, 0.22, 0.4],
                                       5: [0.667, 0.81, 0.0, 0.18],
                                       6: [0.333, 0.5, 0.0, 0.2],
                                       7: [0.0, 0.167, 0.0, 0.2],
                                       8: [0.0, 0.167, 0.4, 0.6]},
                                   10: {0: [0.0, 0.15, 0.5, 0.65],
                                        1: [0.0, 0.167, 0.833, 1.0],
                                        2: [0.333, 0.5, 0.833, 1.0],
                                        3: [0.667, 0.81, 0.85, 1.0],
                                        4: [0.85, 1.0, 0.667, 0.81],
                                        5: [0.833, 1.0, 0.333, 0.5],
                                        6: [0.833, 1.0, 0.0, 0.167],
                                        7: [0.5, 0.667, 0.0, 0.167],
                                        8: [0.18, 0.333, 0.0, 0.15],
                                        9: [0.0, 0.15, 0.18, 0.333]}
                        }
                        center_isle = {2: [0.35, 0.65, 0.4, 0.6],
                                       3: [0.28, 0.72, 0.4, 0.6],
                                       4: [0.38, 0.62, 0.38, 0.62],
                                       5: [0.27, 0.73, 0.3, 0.7],
                                       6: [0.25, 0.75, 0.3, 0.7],
                                       7: [0.3, 0.7, 0.35, 0.65],
                                       8: [0.32, 0.68, 0.32, 0.68],
                                       9: [0.25, 0.75, 0.3, 0.7],
                                       10: [0.25, 0.75, 0.25, 0.75]
                        }
                        the_wheel = {2: [[0.167, 0.2], [0.167, 0.8], [0.833, 0.8], [0.833, 0.2]],
                                     3: [[0.1, 0.167], [0.1, 0.833], [0.9, 0.833], [0.9, 0.167]],
                                     4: [[0.167, 0.167], [0.167, 0.833], [0.833, 0.833], [0.833, 0.167]],
                                     5: [[0.083, 0.7], [0.25, 0.9], [0.75, 0.9], [0.917, 0.7], [0.917, 0.3], [0.833, 0.1], [0.167, 0.1], [0.083, 0.3]],
                                     6: [[0.083, 0.1], [0.083, 0.9], [0.917, 0.9], [0.917, 0.1]],
                                     7: [[0.1, 0.125], [0.1, 0.875], [0.9, 0.875], [0.9, 0.125]],
                                     8: [[0.1, 0.1], [0.1, 0.9], [0.9, 0.9], [0.9, 0.1]],
                                     9: [[0.083, 0.1], [0.083, 0.9], [0.917, 0.9], [0.917, 0.1]],
                                     10: [[0.083, 0.083], [0.083, 0.917], [0.917, 0.917], [0.917, 0.083]]
                        }
                        the_spokes = {2: [[0.167, 0.2, 0.167, 0.8], [0.833, 0.2, 0.833, 0.8], 
                                          [0.167, 0.5, 0.833, 0.5], [0.5, 0.2, 0.5, 0.8]],
                                      3: [[0.2, 0.833, 0.5, 0.5], [0.9, 0.667, 0.5, 0.5], [0.4, 0.167, 0.5, 0.5]],
                                      4: [[0.167, 0.5, 0.833, 0.5], [0.5, 0.833, 0.5, 0.167]],
                                      5: [[0.083, 0.6, 0.5, 0.5], [0.5, 0.917, 0.5, 0.5], [0.917, 0.6, 0.5, 0.5],
                                          [0.25, 0.083, 0.5, 0.5], [0.75, 0.083, 0.5, 0.5]],
                                      6: [[0.083, 0.4, 0.917, 0.6], [0.167, 0.9, 0.833, 0.1], [0.667, 0.9, 0.333, 0.1]],
                                      7: [[0.1, 0.875, 0.4, 0.5], [0.3, 0.125, 0.5, 0.5], [0.1, 0.4, 0.4, 0.5],
                                          [0.7, 0.125, 0.5, 0.5], [0.5, 0.875, 0.5, 0.5], [0.9, 0.875, 0.6, 0.5],
                                          [0.9, 0.375, 0.6, 0.5], [0.4, 0.5, 0.6, 0.5]],
                                      8: [[0.1, 0.7, 0.9, 0.3], [0.3, 0.9, 0.7, 0.1], 
                                          [0.1, 0.3, 0.9, 0.7], [0.7, 0.9, 0.3, 0.1]],
                                      9: [[0.083, 0.7, 0.333, 0.5], [0.083, 0.3, 0.333, 0.5], [0.25, 0.1, 0.417, 0.5], 
                                          [0.25, 0.9, 0.417, 0.5], [0.583, 0.9, 0.583, 0.1], [0.333, 0.5, 0.917, 0.5],
                                          [0.917, 0.9, 0.667, 0.5], [0.917, 0.1, 0.667, 0.5]],
                                      10: [[0.25, 0.917, 0.75, 0.083], [0.417, 0.083, 0.583, 0.917], [0.083, 0.083, 0.917, 0.917], 
                                           [0.083, 0.417, 0.917, 0.583], [0.083, 0.75, 0.917, 0.25]]
                        }

                else:
                        templates = {2: {0: [0.0, 0.333, 0.0, 1.0],
                                         1: [0.667, 1.0, 0.0, 1.0]},
                                     3: {0: [0.0, 0.25, 0.25, 0.75],
                                         1: [0.5, 1.0, 0.75, 1.0],
                                         2: [0.5, 1.0, 0.0, 0.25]},
                                     4: {0: [0.0, 0.333, 0.333, 0.667],
                                         1: [0.333, 0.667, 0.667, 1.0],
                                         2: [0.667, 1.0, 0.333, 0.667],
                                         3: [0.333, 0.667, 0.0, 0.333]},
                                     5: {0: [0.0, 0.25, 0.333, 1.0],
                                         1: [0.25, 0.75, 0.667, 1.0],
                                         2: [0.75, 1.0, 0.333, 1.0],
                                         3: [0.5, 1.0, 0.0, 0.333],
                                         4: [0.0, 0.5, 0.0, 0.333]},
                                     6: {0: [0.0, 0.4, 0.667, 1.0],
                                         1: [0.4, 0.8, 0.667, 1.0],
                                         2: [0.8, 1.0, 0.333, 1.0],
                                         3: [0.6, 1.0, 0.0, 0.333],
                                         4: [0.2, 0.6, 0.0, 0.333],
                                         5: [0.0, 0.2, 0.0, 0.667]},
                                     7: {0: [0.0, 0.4, 0.75, 1.0],
                                         1: [0.4, 0.8, 0.75, 1.0],
                                         2: [0.8, 1.0, 0.5, 1.0],
                                         3: [0.8, 1.0, 0.0, 0.5],
                                         4: [0.4, 0.8, 0.0, 0.25],
                                         5: [0.0, 0.4, 0.0, 0.25],
                                         6: [0.0, 0.2, 0.25, 0.75]},
                                     8: {0: [0.0, 0.3, 0.35, 0.65],
                                         1: [0.0, 0.3, 0.7, 1.0],
                                         2: [0.35, 0.65, 0.7, 1.0],
                                         3: [0.7, 1.0, 0.7, 1.0],
                                         4: [0.7, 1.0, 0.35, 0.65],
                                         5: [0.7, 1.0, 0.0, 0.3],
                                         6: [0.35, 0.65, 0.0, 0.3],
                                         7: [0.0, 0.3, 0.0, 0.3]},
                                     9: {0: [0.0, 0.167, 0.6, 1.0],
                                         1: [0.167, 0.5, 0.8, 1.0],
                                         2: [0.5, 0.833, 0.8, 1.0],
                                         3: [0.833, 1.0, 0.6, 1.0],
                                         4: [0.833, 1.0, 0.2, 0.6],
                                         5: [0.667, 1.0, 0.0, 0.2],
                                         6: [0.333, 0.667, 0.0, 0.2],
                                         7: [0.0, 0.333, 0.0, 0.2],
                                         8: [0.0, 0.167, 0.2, 0.6]},
                                     10: {0: [0.0, 0.167, 0.5, 0.833],
                                          1: [0.0, 0.333, 0.833, 1.0],
                                          2: [0.333, 0.667, 0.833, 1.0],
                                          3: [0.667, 1.0, 0.833, 1.0],
                                          4: [0.833, 1.0, 0.5, 0.833],
                                          5: [0.833, 1.0, 0.167, 0.5],
                                          6: [0.667, 1.0, 0.0, 0.167],
                                          7: [0.333, 0.667, 0.0, 0.167],
                                          8: [0.0, 0.333, 0.0, 0.167],
                                          9: [0.0, 0.167, 0.167, 0.5]},
                                     11: {0: [0.0, 0.2, 0.167, 0.5],
                                          1: [0.0, 0.2, 0.5, 0.833],
                                          2: [0.2, 0.4, 0.667, 1.0],
                                          3: [0.4, 0.6, 0.667, 1.0],
                                          4: [0.6, 0.8, 0.667, 1.0],
                                          5: [0.8, 1.0, 0.667, 1.0],
                                          6: [0.8, 1.0, 0.333, 0.667],
                                          7: [0.8, 1.0, 0.0, 0.333],
                                          8: [0.6, 0.8, 0.0, 0.333],
                                          9: [0.4, 0.6, 0.0, 0.333],
                                          10: [0.2, 0.4, 0.0, 0.333]},
                                     12: {0: [0.0, 0.2, 0.333, 0.667],
                                          1: [0.0, 0.2, 0.667, 1.0],
                                          2: [0.2, 0.4, 0.667, 1.0],
                                          3: [0.4, 0.6, 0.667, 1.0],
                                          4: [0.6, 0.8, 0.667, 1.0],
                                          5: [0.8, 1.0, 0.667, 1.0],
                                          6: [0.8, 1.0, 0.333, 0.667],
                                          7: [0.8, 1.0, 0.0, 0.333],
                                          8: [0.6, 0.8, 0.0, 0.333],
                                          9: [0.4, 0.6, 0.0, 0.333],
                                          10: [0.2, 0.4, 0.0, 0.333],
                                          11: [0.0, 0.2, 0.0, 0.333]},
                                     13: {0: [0.0, 0.2, 0.375, 0.625],
                                          1: [0.0, 0.2, 0.7, 0.95],
                                          2: [0.2, 0.4, 0.75, 1.0],
                                          3: [0.4, 0.6, 0.75, 1.0],
                                          4: [0.6, 0.8, 0.75, 1.0],
                                          5: [0.8, 1.0, 0.75, 1.0],
                                          6: [0.8, 1.0, 0.5, 0.75],
                                          7: [0.8, 1.0, 0.25, 0.5],
                                          8: [0.8, 1.0, 0.0, 0.25],
                                          9: [0.6, 0.8, 0.0, 0.25],
                                          10: [0.4, 0.6, 0.0, 0.25],
                                          11: [0.2, 0.4, 0.0, 0.25],
                                          12: [0.0, 0.2, 0.05, 0.3]},
                                     14: {0: [0.0, 0.2, 0.5, 0.75],
                                          1: [0.0, 0.2, 0.75, 1.0],
                                          2: [0.2, 0.4, 0.75, 1.0],
                                          3: [0.4, 0.6, 0.75, 1.0],
                                          4: [0.6, 0.8, 0.75, 1.0],
                                          5: [0.8, 1.0, 0.75, 1.0],
                                          6: [0.8, 1.0, 0.5, 0.75],
                                          7: [0.8, 1.0, 0.25, 0.5],
                                          8: [0.8, 1.0, 0.0, 0.25],
                                          9: [0.6, 0.8, 0.0, 0.25],
                                          10: [0.4, 0.6, 0.0, 0.25],
                                          11: [0.2, 0.4, 0.0, 0.25],
                                          12: [0.0, 0.2, 0.0, 0.25],
                                          13: [0.0, 0.2, 0.25, 0.5]},
                                     15: {0: [0.0, 0.167, 0.375, 0.625],
                                          1: [0.0, 0.167, 0.7, 0.95],
                                          2: [0.167, 0.333, 0.75, 1.0],
                                          3: [0.333, 0.5, 0.75, 1.0],
                                          4: [0.5, 0.667, 0.75, 1.0],
                                          5: [0.667, 0.833, 0.75, 1.0],
                                          6: [0.833, 1.0, 0.75, 1.0],
                                          7: [0.833, 1.0, 0.5, 0.75],
                                          8: [0.833, 1.0, 0.25, 0.5],
                                          9: [0.833, 1.0, 0.0, 0.25],
                                          10: [0.667, 0.833, 0.0, 0.25],
                                          11: [0.5, 0.667, 0.0, 0.25],
                                          12: [0.333, 0.5, 0.0, 0.25],
                                          13: [0.167, 0.333, 0.0, 0.25],
                                          14: [0.0, 0.167, 0.05, 0.3]},
                                     16: {0: [0.0, 0.167, 0.5, 0.75],
                                          1: [0.0, 0.167, 0.75, 1.0],
                                          2: [0.167, 0.333, 0.75, 1.0],
                                          3: [0.333, 0.5, 0.75, 1.0],
                                          4: [0.5, 0.667, 0.75, 1.0],
                                          5: [0.667, 0.833, 0.75, 1.0],
                                          6: [0.833, 1.0, 0.75, 1.0],
                                          7: [0.833, 1.0, 0.5, 0.75],
                                          8: [0.833, 1.0, 0.25, 0.5],
                                          9: [0.833, 1.0, 0.0, 0.25],
                                          10: [0.667, 0.833, 0.0, 0.25],
                                          11: [0.5, 0.667, 0.0, 0.25],
                                          12: [0.333, 0.5, 0.0, 0.25],
                                          13: [0.167, 0.333, 0.0, 0.25],
                                          14: [0.0, 0.167, 0.25, 0.5],
                                          15: [0.0, 0.167, 0.0, 0.25]},
                                     17: {0: [0.0, 0.167, 0.5, 0.7],
                                          1: [0.0, 0.167, 0.7, 0.9],
                                          2: [0.167, 0.333, 0.8, 1.0],
                                          3: [0.333, 0.5, 0.8, 1.0],
                                          4: [0.5, 0.667, 0.8, 1.0],
                                          5: [0.667, 0.833, 0.8, 1.0],
                                          6: [0.833, 1.0, 0.8, 1.0],
                                          7: [0.833, 1.0, 0.6, 0.8],
                                          8: [0.833, 1.0, 0.4, 0.6],
                                          9: [0.833, 1.0, 0.2, 0.4],
                                          10: [0.833, 1.0, 0.0, 0.2],
                                          11: [0.667, 0.833, 0.0, 0.2],
                                          12: [0.5, 0.667, 0.0, 0.2],
                                          13: [0.333, 0.5, 0.0, 0.2],
                                          14: [0.167, 0.333, 0.0, 0.2],
                                          15: [0.0, 0.167, 0.1, 0.3],
                                          16: [0.0, 0.167, 0.3, 0.5]},
                                     18: {0: [0.0, 0.167, 0.6, 0.8],
                                          1: [0.0, 0.167, 0.8, 1.0],
                                          2: [0.167, 0.333, 0.8, 1.0],
                                          3: [0.333, 0.5, 0.8, 1.0],
                                          4: [0.5, 0.667, 0.8, 1.0],
                                          5: [0.667, 0.833, 0.8, 1.0],
                                          6: [0.833, 1.0, 0.8, 1.0],
                                          7: [0.833, 1.0, 0.6, 0.8],
                                          8: [0.833, 1.0, 0.4, 0.6],
                                          9: [0.833, 1.0, 0.2, 0.4],
                                          10: [0.833, 1.0, 0.0, 0.2],
                                          11: [0.667, 0.833, 0.0, 0.2],
                                          12: [0.5, 0.667, 0.0, 0.2],
                                          13: [0.333, 0.5, 0.0, 0.2],
                                          14: [0.167, 0.333, 0.0, 0.2],
                                          15: [0.0, 0.167, 0.0, 0.2],
                                          16: [0.0, 0.167, 0.2, 0.4],
                                          17: [0.0, 0.167, 0.4, 0.6]}
                        }
                        center_isle = {2: [0.35, 0.65, 0.4, 0.6],
                                       3: [0.38, 0.7, 0.35, 0.65],
                                       4: [0.37, 0.63, 0.37, 0.63],
                                       5: [0.32, 0.68, 0.38, 0.62],
                                       6: [0.28, 0.72, 0.38, 0.62],
                                       7: [0.28, 0.72, 0.35, 0.65],
                                       8: [0.37, 0.63, 0.37, 0.63],
                                       9: [0.3, 0.7, 0.35, 0.65],
                                       10: [0.3, 0.7, 0.3, 0.7],
                                       11: [0.28, 0.72, 0.38, 0.62],
                                       12: [0.28, 0.72, 0.38, 0.62],
                                       13: [0.3, 0.7, 0.35, 0.65],
                                       14: [0.3, 0.7, 0.35, 0.65],
                                       15: [0.25, 0.75, 0.35, 0.65],
                                       16: [0.25, 0.75, 0.35, 0.65],
                                       17: [0.25, 0.75, 0.3, 0.7],
                                       18: [0.25, 0.75, 0.3, 0.7]
                        }
                        the_wheel = {2: [[0.167, 0.3], [0.167, 0.7], [0.833, 0.7], [0.833, 0.3]],
                                     3: [[0.125, 0.375], [0.125, 0.625], [0.625, 0.875], [0.875, 0.875], [0.875, 0.125], [0.625, 0.125]],
                                     4: [[0.167, 0.5], [0.5, 0.833], [0.833, 0.5], [0.5, 0.167]],
                                     5: [[0.125, 0.167], [0.125, 0.833], [0.875, 0.833], [0.875, 0.167]],
                                     6: [[0.1, 0.167], [0.1, 0.833], [0.9, 0.833], [0.9, 0.167]],
                                     7: [[0.1, 0.125], [0.1, 0.875], [0.9, 0.875], [0.9, 0.125]],
                                     8: [[0.167, 0.167], [0.167, 0.833], [0.833, 0.833], [0.833, 0.167]],
                                     9: [[0.083, 0.1], [0.083, 0.9], [0.917, 0.9], [0.917, 0.1]],
                                     10: [[0.083, 0.083], [0.083, 0.917], [0.917, 0.917], [0.917, 0.083]],
                                     11: [[0.1, 0.333], [0.1, 0.667], [0.3, 0.833], [0.9, 0.833], [0.9, 0.167], [0.3, 0.167]],
                                     12: [[0.1, 0.167], [0.1, 0.833], [0.9, 0.833], [0.9, 0.167]],
                                     13: [[0.1, 0.175], [0.1, 0.825], [0.3, 0.875], [0.9, 0.875], [0.9, 0.125], [0.3, 0.125]],
                                     14: [[0.1, 0.125], [0.1, 0.875], [0.9, 0.875], [0.9, 0.125]],
                                     15: [[0.083, 0.175], [0.083, 0.825], [0.25, 0.875], [0.917, 0.875], [0.917, 0.125], [0.25, 0.125]],
                                     16: [[0.083, 0.125], [0.083, 0.875], [0.917, 0.875], [0.917, 0.125]],
                                     17: [[0.083, 0.2], [0.083, 0.8], [0.25, 0.9], [0.917, 0.9], [0.917, 0.1], [0.25, 0.1]],
                                     18: [[0.083, 0.1], [0.083, 0.9], [0.917, 0.9], [0.917, 0.1]]
                        }
                        the_spokes = {2: [[0.167, 0.2, 0.167, 0.8], [0.833, 0.2, 0.833, 0.8], [0.167, 0.5, 0.833, 0.5]],
                                      3: [[0.125, 0.5, 0.5, 0.5], [0.75, 0.125, 0.5, 0.5], [0.75, 0.875, 0.5, 0.5]],
                                      4: [[0.167, 0.5, 0.833, 0.5], [0.5, 0.833, 0.5, 0.167]],
                                      5: [[0.125, 0.667, 0.375, 0.5], [0.25, 0.167, 0.375, 0.5], [0.375, 0.5, 0.625, 0.5],
                                          [0.5, 0.5, 0.5, 0.833], [0.625, 0.5, 0.75, 0.167], [0.625, 0.5, 0.875, 0.667]],
                                      6: [[0.1, 0.333, 0.3, 0.5], [0.7, 0.5, 0.8, 0.167], [0.7, 0.5, 0.9, 0.667], 
                                          [0.4, 0.167, 0.6, 0.833], [0.2, 0.833, 0.3, 0.5], [0.3, 0.5, 0.7, 0.5]],
                                      7: [[0.2, 0.875, 0.3, 0.5], [0.2, 0.125, 0.3, 0.5], [0.1, 0.5, 0.7, 0.5],
                                          [0.6, 0.125, 0.5, 0.5], [0.6, 0.875, 0.5, 0.5], [0.9, 0.75, 0.7, 0.5],
                                          [0.9, 0.25, 0.7, 0.5]],
                                      8: [[0.167, 0.5, 0.833, 0.5], [0.5, 0.833, 0.5, 0.167], 
                                          [0.167, 0.167, 0.833, 0.833], [0.167, 0.833, 0.833, 0.167]],
                                      9: [[0.083, 0.8, 0.375, 0.5], [0.083, 0.4, 0.375, 0.5], [0.167, 0.1, 0.375, 0.5], 
                                          [0.333, 0.9, 0.5, 0.5], [0.667, 0.9, 0.5, 0.5], [0.5, 0.1, 0.5, 0.5],
                                          [0.917, 0.8, 0.625, 0.5], [0.917, 0.4, 0.625, 0.5], [0.833, 0.1, 0.625, 0.5], 
                                          [0.375, 0.5, 0.625, 0.5]],
                                      10: [[0.167, 0.917, 0.833, 0.083], [0.5, 0.083, 0.5, 0.917], [0.167, 0.083, 0.833, 0.917], 
                                           [0.083, 0.333, 0.917, 0.667], [0.083, 0.667, 0.917, 0.333]],
                                      11: [[0.7, 0.5, 0.9, 0.5], [0.7, 0.5, 0.9, 0.167], [0.7, 0.5, 0.9, 0.833], 
                                           [0.6, 0.5, 0.7, 0.833], [0.6, 0.5, 0.7, 0.167], [0.5, 0.5, 0.5, 0.833],
                                           [0.5, 0.5, 0.5, 0.167], [0.4, 0.5, 0.3, 0.167], [0.4, 0.5, 0.3, 0.833], 
                                           [0.3, 0.5, 0.1, 0.667], [0.3, 0.5, 0.1, 0.333], [0.3, 0.5, 0.7, 0.5]],
                                      12: [[0.7, 0.5, 0.9, 0.5], [0.7, 0.5, 0.9, 0.167], [0.7, 0.5, 0.9, 0.833], 
                                           [0.6, 0.5, 0.7, 0.833], [0.6, 0.5, 0.7, 0.167], [0.5, 0.5, 0.5, 0.833],
                                           [0.5, 0.5, 0.5, 0.167], [0.4, 0.5, 0.3, 0.167], [0.4, 0.5, 0.3, 0.833], 
                                           [0.3, 0.5, 0.1, 0.167], [0.3, 0.5, 0.1, 0.833], [0.3, 0.5, 0.1, 0.5], 
                                           [0.3, 0.5, 0.7, 0.5]],
                                      13: [[0.3, 0.875, 0.5, 0.125], [0.3, 0.5, 0.6, 0.5], [0.5, 0.875, 0.3, 0.125], 
                                           [0.7, 0.125, 0.9, 0.375], [0.7, 0.875, 0.9, 0.625], [0.9, 0.125, 0.6, 0.5],
                                           [0.9, 0.875, 0.6, 0.5], [0.1, 0.175, 0.3, 0.5], [0.1, 0.5, 0.3, 0.5], 
                                           [0.1, 0.825, 0.3, 0.5]],
                                      14: [[0.3, 0.875, 0.1, 0.625], [0.4, 0.5, 0.6, 0.5], [0.1, 0.375, 0.3, 0.125], 
                                           [0.7, 0.125, 0.9, 0.375], [0.7, 0.875, 0.9, 0.625], [0.9, 0.125, 0.6, 0.5],
                                           [0.9, 0.875, 0.6, 0.5], [0.1, 0.125, 0.4, 0.5], [0.1, 0.875, 0.4, 0.5], 
                                           [0.5, 0.125, 0.5, 0.875]],
                                      15: [[0.583, 0.125, 0.25, 0.875], [0.25, 0.5, 0.667, 0.5], [0.583, 0.875, 0.25, 0.125], 
                                           [0.75, 0.125, 0.917, 0.375], [0.75, 0.875, 0.917, 0.625], [0.917, 0.125, 0.667, 0.5],
                                           [0.917, 0.875, 0.667, 0.5], [0.083, 0.175, 0.25, 0.5], [0.083, 0.5, 0.25, 0.5], 
                                           [0.083, 0.825, 0.25, 0.5], [0.417, 0.125, 0.417, 0.875]],
                                      16: [[0.083, 0.875, 0.417, 0.125], [0.25, 0.5, 0.75, 0.5], [0.417, 0.875, 0.083, 0.125], 
                                           [0.75, 0.125, 0.75, 0.875], [0.25, 0.125, 0.25, 0.875], [0.917, 0.125, 0.583, 0.875],
                                           [0.917, 0.875, 0.583, 0.125], [0.083, 0.625, 0.25, 0.5], [0.083, 0.375, 0.25, 0.5], 
                                           [0.917, 0.375, 0.75, 0.5], [0.917, 0.625, 0.75, 0.5]],
                                      17: [[0.25, 0.5, 0.917, 0.5], [0.083, 0.6, 0.25, 0.5], [0.083, 0.4, 0.25, 0.5], 
                                           [0.083, 0.8, 0.333, 0.7], [0.25, 0.9, 0.417, 0.5], [0.417, 0.9, 0.333, 0.7], 
                                           [0.583, 0.9, 0.75, 0.7], [0.75, 0.9, 0.75, 0.7], [0.917, 0.9, 0.583, 0.5], 
                                           [0.917, 0.7, 0.75, 0.5], [0.917, 0.3, 0.75, 0.5], [0.917, 0.1, 0.583, 0.5],
                                           [0.75, 0.1, 0.75, 0.3], [0.583, 0.1, 0.75, 0.3], [0.417, 0.1, 0.333, 0.3], 
                                           [0.25, 0.1, 0.417, 0.5], [0.083, 0.2, 0.333, 0.3]],
                                      18: [[0.083, 0.5, 0.917, 0.5], [0.083, 0.7, 0.25, 0.5], [0.083, 0.3, 0.25, 0.5], 
                                           [0.083, 0.9, 0.417, 0.5], [0.25, 0.9, 0.25, 0.7], [0.417, 0.9, 0.25, 0.7], 
                                           [0.583, 0.9, 0.75, 0.7], [0.75, 0.9, 0.75, 0.7], [0.917, 0.9, 0.583, 0.5], 
                                           [0.917, 0.7, 0.75, 0.5], [0.917, 0.3, 0.75, 0.5], [0.917, 0.1, 0.583, 0.5],
                                           [0.75, 0.1, 0.75, 0.3], [0.583, 0.1, 0.75, 0.3], [0.417, 0.1, 0.25, 0.3], 
                                           [0.25, 0.1, 0.25, 0.3], [0.083, 0.1, 0.417, 0.5]]
                        }
                region_data = []
                for regionLoop in range(iPlayers):
                        [fWestLon, fEastLon, fSouthLat, fNorthLat] = templates[iPlayers][regionLoop]
                        iWestX = int((iW - 1) * fWestLon)
                        iEastX = int((iW - 1) * fEastLon) - 1
                        iSouthY = int((iH - 1) * fSouthLat)
                        iNorthY = int((iH - 1) * fNorthLat) -1
                        region_data.append([iWestX, iEastX, iSouthY, iNorthY])
                if userInputLandmass == 1 and iPlayers >= 2 and iPlayers <= 10:
                        buffer_data = []
                        for bufferLoop in range(iPlayers):
                                [fWestLon, fEastLon, fSouthLat, fNorthLat] = buffers[iPlayers][bufferLoop]
                                iWestX = int((iW - 1) * fWestLon)
                                iEastX = int((iW - 1) * fEastLon) - 1
                                iSouthY = int((iH - 1) * fSouthLat)
                                iNorthY = int((iH - 1) * fNorthLat) -1
                                buffer_data.append([iWestX, iEastX, iSouthY, iNorthY])
                else: pass
                [fWestLon, fEastLon, fSouthLat, fNorthLat] = center_isle[iPlayers]
                iWestX = int((iW - 1) * fWestLon)
                iEastX = int((iW - 1) * fEastLon) - 1
                iSouthY = int((iH - 1) * fSouthLat)
                iNorthY = int((iH - 1) * fNorthLat) -1
                center_data = [iWestX, iEastX, iSouthY, iNorthY]
                wheel_data = []
                for [fLon, fLat] in the_wheel[iPlayers]:
                        iX = int((iW - 1) * fLon)
                        iY = int((iH - 1) * fLat)
                        wheel_data.append([iX, iY])
                [fLon, fLat] = the_wheel[iPlayers][0]
                iX = int((iW - 1) * fLon)
                iY = int((iH - 1) * fLat)
                wheel_data.append([iX, iY])
                hub_data = []
                for [fStartLon, fStartLat, fEndLon, fEndLat] in the_spokes[iPlayers]:
                        iStartX = int((iW - 1) * fStartLon)
                        iStartY = int((iH - 1) * fStartLat)
                        iEndX = int((iW - 1) * fEndLon)
                        iEndY = int((iH - 1) * fEndLat)
                        hub_data.append([iStartX, iStartY, iEndX, iEndY])
        elif idMap == "bigandsmall" :
                xShiftRoll = getRandNum(2, "FoR : Region Shift, Horizontal - Big and Small PYTHON")
        elif idMap == "hemispheres" :
                xShiftRoll = getRandNum(2, "FoR : Region Shift, Horizontal - Left and Right PYTHON")
                yShiftRoll = getRandNum(2, "FoR : Region Shift, Vertical - Left and Right PYTHON")
                ySplitRoll = getRandNum(2, "FoR : Region Split, Vertical - Left and Right PYTHON")
                yPortionRoll = getRandNum(2, "FoR : Region Portioning, Vertical - Left and Right PYTHON")
        elif idMap == "mediumandsmall" :
                yShiftRoll1 = getRandNum(2, "FoR : West Region Shift, Vertical - Medium and Small PYTHON")
                yShiftRoll2 = getRandNum(2, "FoR : East Region Shift, Vertical - Medium and Small PYTHON")

def generatePlotTypes():
        try :
                writeLog(" = generatePlotTypes = ", False, [""])
                NiTextOut("Setting Plot Types (Full of resources) ...")
                global bSuccessFlag
                if idMap == "archipelago" :
                        waterPer = getRandSel(selGen["maps"]["archipelago"]["waterper"], False)
                        fractal_world = ArchipelagoFractalWorld()
                        userInputLandmass = cmo[0]
                        if userInputLandmass == 2:
                                fractal_world.initFractal(continent_grain = 5, rift_grain = -1, has_center_rift = False, polar = True)
                                plotTypes = fractal_world.generatePlotTypes(water_percent = waterPer, grain_amount = 4)
                        elif userInputLandmass == 0:
                                fractal_world.initFractal(continent_grain = 3, rift_grain = -1, has_center_rift = False, polar = True)
                                plotTypes = fractal_world.generatePlotTypes(water_percent = waterPer, grain_amount = 4)
                        else:
                                fractal_world.initFractal(continent_grain = 4, rift_grain = -1, has_center_rift = False, polar = True)
                                plotTypes = fractal_world.generatePlotTypes(water_percent = waterPer, grain_amount = 4)
                elif idMap == "continents" :
                        waterPer = getRandSel(selGen["maps"]["continents"]["waterper"], False)
                        fractal_world = FractalWorld()
                        fractal_world.initFractal(polar = True)
                        plotTypes = fractal_world.generatePlotTypes(water_percent = waterPer)
                elif idMap == "customcontinents" :
                        fractal_world = CCMultilayeredFractal()
                        plotTypes = fractal_world.generatePlotsByRegion()
                elif idMap == "fractals" :
                        waterPer = getRandSel(selGen["maps"]["fractals"]["waterper"], False)
                        fractal_world = FractalWorld()
                        fractal_world.initFractal(rift_grain = -1, has_center_rift = False, polar = True)
                        plotTypes = fractal_world.generatePlotTypes(water_percent = waterPer)
                elif idMap == "hub" :
                        if not bSuccessFlag:
                                fractal_world = FractalWorld()
                                fractal_world.initFractal(polar = True)
                                plotTypes = fractal_world.generatePlotTypes()
                        else:
                                fractal_world = HubMultilayeredFractal()
                                userInputLandmass = cmo[0]
                                if userInputLandmass == 1:
                                        hub_type = 1
                                else:
                                        hub_type = 0
                                plotTypes = fractal_world.generatePlotsByRegion(hub_type)
                elif idMap == "inlandsea" :
                        global hinted_world
                        hinted_world = ISHintedWorld(4,2)
                        for y in range(hinted_world.h):
                                for x in range(hinted_world.w):
                                        if x in (0, hinted_world.w-1) or y in (0, hinted_world.h-1):
                                                hinted_world.setValue(x, y, 200 + getRandNum(55, "FoR : Plot Types - Inland Sea PYTHON"))
                                        else:
                                                hinted_world.setValue(x, y, 0)

                        hinted_world.buildAllContinents()
                        plotTypes = hinted_world.generatePlotTypes()
                elif idMap == "islands" :
                        iPlayers = game.countCivPlayersEverAlive()
                        if iPlayers > 0 and iPlayers < 19:
                                fractal_world = IslandsMultilayeredFractal()
                                plotTypes = fractal_world.generatePlotsByRegion()
                        else:
                                fractal_world = FractalWorld()
                                fractal_world.initFractal(polar = True)
                                plotTypes = fractal_world.generatePlotTypes()
                elif idMap == "lakes" :
                        waterPer = getRandSel(selGen["maps"]["lakes"]["waterper"], False)
                        userInputLakesSize = getRandSel(selGen["maps"]["lakes"]["lakesize"])
                        grainCont = 3
                        grainCont += userInputLakesSize
                        grainCont += int(waterPer/35)

                        fractal_world = LakesFractalWorld()
                        fractal_world.initFractal(continent_grain = grainCont, rift_grain = -1, has_center_rift = False, invert_heights = True)
                        plotTypes = fractal_world.generatePlotTypes(water_percent = waterPer)
                elif idMap == "maze" :
                        plotTypes = generateMazePlotTypes()
                elif idMap == "pangaea" :
                        plotTypes = generatePangaeaPlotTypes()
                elif idMap == "ring" :
                        if bSuccessFlag:
                                fractal_world = RingMultilayeredFractal()
                                userInputLandmass = cmo[0]
                                if userInputLandmass == 1:
                                        ring_type = 1
                                else:
                                        ring_type = 0
                                plotTypes = fractal_world.generatePlotsByRegion(ring_type)
                        else:
                                fractal_world = FractalWorld()
                                fractal_world.initFractal(polar = True)
                                plotTypes = fractal_world.generatePlotTypes()
                elif idMap == "shuffle" :
                        waterPer = getRandSel(selGen["maps"]["shuffle"]["waterper"], False)
                        fractal_world = FractalWorld()
                        grainRoll = 1 + getRandNum(8, "FoR : Fractal Grain - Shuffle PYTHON")
                        if grainRoll > 5:
                                grainRoll -= 5
                        if grainRoll == 2:
                                fractal_world.initFractal(polar = True)
                                plotTypes = fractal_world.generatePlotTypes(water_percent = waterPer)
                        else:
                                if grainRoll == 5: grainRoll -= 3
                                fractal_world.initFractal(continent_grain = grainRoll, rift_grain = -1, has_center_rift = False, polar = True)
                                plotTypes = fractal_world.generatePlotTypes(water_percent = waterPer)
                elif idMap == "terra" :
                        plotgen = TerraMultilayeredFractal()
                        plotTypes = plotgen.generatePlotsByRegion()
                elif idMap == "wheel" :
                        if bSuccessFlag:
                                fractal_world = WheelMultilayeredFractal()
                                userInputLandmass = cmo[0]
                                if userInputLandmass == 1:
                                        wheel_type = 1
                                else:
                                        wheel_type = 0
                                plotTypes = fractal_world.generatePlotsByRegion(wheel_type)
                        else:
                                fractal_world = FractalWorld()
                                fractal_world.initFractal(polar = True)
                                plotTypes = fractal_world.generatePlotTypes()
                elif idMap == "chess" :
                        bSuccessFlag, plotTypes = generateChessPlotTypes()
                elif idMap == "bigandsmall" :
                        fractal_world = BnSMultilayeredFractal()
                        plotTypes = fractal_world.generatePlotsByRegion()
                elif idMap == "hemispheres" :
                        fractal_world = BnSHemMultilayeredFractal()
                        plotTypes = fractal_world.generatePlotsByRegion()
                elif idMap == "mediumandsmall" :
                        fractal_world = MnSMultilayeredFractal()
                        plotTypes = fractal_world.generatePlotsByRegion()

                if idMap == "chess" :
                        if bSuccessFlag :
                                writeLog("", True, [" Chess generation finished ..."])
                                return plotTypes

                ## apply options chosen
                try :
                        remPeak = bool((selGen["terrain"]["peak"]["peakcoast"]) or (idMap in ["archipelago", "maze"]))
                        minIslandTiles = getRandSel(selGen["terrain"]["island"]["nbtilesminisland"], False)
                        peakPer = getRandSel(selGen["terrain"]["peak"]["peakpercent"], False, "float") / 100.0
                        hillPer = getRandSel(selGen["terrain"]["hill"]["hillpercent"], False) / 100.0

                        # debug
                        logList = []
                        logList.append(" reamove peak : %r" %remPeak)
                        logList.append(" minIslandTiles : %r" %minIslandTiles)
                        logList.append(" peak percent : %r" %peakPer)
                        logList.append(" hill percent : %r" %hillPer)
                        logList.append("")
                        writeLog("", False, logList)

                        pWater = PlotTypes.PLOT_OCEAN
                        pLand = PlotTypes.PLOT_LAND
                        pHill = PlotTypes.PLOT_HILLS
                        pPeak = PlotTypes.PLOT_PEAK
                        rings = generateRings(1)
                        ring1 = rings[1]

                        # store plot types in a grid size
                        tPlots = [[ plotTypes[map.plotNum(iX, iY)] for iY in range(iH)] for iX in range(iW) ]

                        # be sure with some maps that there is no land at the poles (to prevent that ships can't do go everywhere in the map , if ice is removed along the coast)
                        if idMap in ["archipelago", "continents", "customcontinents", "fractals", "islands", "pangaea", "shuffle", "terra", "bigandsmall", "hemispheres", "mediumandsmall"] :
                                for iY in [0, iH-1] :
                                        for iX in range(iW) :
                                                tPlots[iX][iY] = pWater

                        # with prevent a long line of plot just near the border of the map for hub
                        if idMap in ["hub", "wheel", "ring"] :
                                while True :
                                        bChange = False
                                        for iY in [1, iH-2] :
                                                if bChange : break
                                                lXPlots = []
                                                for iX in range(iW) :
                                                        if tPlots[iX][iY] != pWater :
                                                                lXPlots.append(iX)
                                                                continue
                                                        if len(lXPlots) >= 4 :
                                                                iChoice = getRandNum(len(lXPlots) - 2, " FoR : hub , side plot")
                                                                tPlots[lXPlots[iChoice+1]][iY] = pWater
                                                                bChange = True
                                                                break
                                                        else :
                                                                lXPlots = []
                                        if not bChange : break

                                while True :
                                        bChange = False
                                        for iX in [1, iW-2] :
                                                if bChange : break
                                                lYPlots = []
                                                for iY in range(iH) :
                                                        if tPlots[iX][iY] != pWater :
                                                                lYPlots.append(iY)
                                                                continue
                                                        if len(lYPlots) >= 4 :
                                                                iChoice = getRandNum(len(lYPlots) - 2, " FoR : hub , side plot")
                                                                tPlots[iX][lYPlots[iChoice+1]] = pWater
                                                                bChange = True
                                                                break
                                                        else :
                                                                lYPlots = []
                                        if not bChange : break

                        # remove small islands
                        def getAreaTiles((x, y), lPlots):
                                if not (x, y) in lPlots : lPlots.append((x, y))
                                if len(lPlots) <= minIslandTiles + 2 : # prevent an exceed of number of reccursion 
                                        for dx, dy in ring1 :
                                                wTP = toWrap(x + dx, y +dy)
                                                if wTP != -1 :
                                                        if tPlots[wTP[0]][wTP[1]] != pWater :
                                                                if not wTP in lPlots :
                                                                        lPlots = getAreaTiles(wTP, lPlots)
                                return lPlots
                            
                        testedPlots = []
                        plotsToRemove = []
                        for iX in range(iW) :
                                for iY in range(iH) :
                                        if tPlots[iX][iY] == pWater : continue
                                        if (iX, iY) in testedPlots : continue
                                        areaPlots = getAreaTiles((iX, iY), [])
                                        testedPlots += areaPlots
                                        if len(areaPlots) < minIslandTiles : plotsToRemove += areaPlots

                        for x, y in plotsToRemove : tPlots[x][y] = pWater

                        def isCoast(x, y) :
                                for dx, dy in ring1 :
                                        wTP = toWrap(x + dx, y +dy)
                                        if wTP != -1 :
                                                if tPlots[wTP[0]][wTP[1]] == pWater : return True
                                return False

                        # debug
                        nbPeak = 0
                        nbHill = 0
                        nbTile = 0
                        nbUnwantedPeak = 0
                        nbCoastalTiles = 0
                        for iX in range(iW) :
                                for iY in range(iH) :
                                        plotType = tPlots[iX][iY]
                                        if plotType == pWater : continue
                                        if isCoast(iX, iY) :
                                                nbCoastalTiles += 1
                                                if remPeak :
                                                        if plotType == pPeak : nbUnwantedPeak += 1
                                        nbTile += 1
                                        if plotType == pHill : nbHill += 1
                                        elif plotType == pPeak : nbPeak += 1
                        logList = []
                        logList.append(" start peak number : %r" %nbPeak)
                        logList.append(" start peak percent : %r" %(float(nbPeak)/nbTile*100.0, ))
                        if remPeak :
                                if (nbTile - nbCoastalTiles) > 0 :
                                        logList.append(" start peak percent (without coastal tiles) : %r" %(float(nbPeak - nbUnwantedPeak)/(nbTile - nbCoastalTiles)*100.0, ))
                        logList.append(" start hill percent : %r" %(float(nbHill)/nbTile*100.0, ))
                        logList.append(" nb Tiles : %r" %nbTile)
                        logList.append(" nb Coastal Tiles : %r" %nbCoastalTiles)
                        logList.append(" nb unwanted peaks : %r" %nbUnwantedPeak)
                        logList.append("")
                        writeLog("", False, logList)

                        # remove peak along the coast
                        if remPeak :
                                for iX in range(iW) :
                                        for iY in range(iH) :
                                                if tPlots[iX][iY] != pPeak : continue
                                                if isCoast(iX, iY) :
                                                        tPlots[iX][iY] = pHill

                        # adjust peak percent
                        landPlots = []
                        hillPlots = []
                        peakPlots = []
                        waterPlots = []
                        coastalPlots = []
                        for iX in range(iW) :
                                for iY in range(iH) :
                                        plotType = tPlots[iX][iY]
                                        if plotType == pWater :
                                                waterPlots.append((iX, iY))
                                                continue
                                        if isCoast(iX, iY) : coastalPlots.append((iX, iY))
                                        if plotType == pLand : landPlots.append((iX, iY))
                                        elif plotType == pHill : hillPlots.append((iX, iY))
                                        elif plotType == pPeak : peakPlots.append((iX, iY))

                        # check if a path is doable between each land plots around the center plot if i place a peak at the center
                        def canHavePeak(x, y) :
                                lPlots = []
                                allPlots = []
                                nbPeakAround = 0
                                for dx, dy in ring1 :
                                        wTP = toWrap(x + dx, y +dy)
                                        if wTP != -1 :
                                                allPlots.append(wTP)
                                                plotType = tPlots[wTP[0]][wTP[1]]
                                                if plotType in [pLand, pHill] : lPlots.append(wTP)
                                                if plotType == pPeak : nbPeakAround += 1
                                if nbPeakAround > 2 : return False
                                if len(lPlots) <= 1 : return False #prevent the systematic appearance on small islands
                                sPlot = tuple(lPlots[0])
                                foundPlots = [sPlot]
                                testedPlots = []
                                while True :
                                        if len(foundPlots) == len(testedPlots) : break
                                        plotToCheck = [item for item in foundPlots if not item in testedPlots][0]
                                        testedPlots.append(plotToCheck)
                                        for dx, dy in ring1 :
                                                wTP = toWrap(plotToCheck[0] + dx, plotToCheck[1] +dy)
                                                if wTP != -1 :
                                                        if not wTP in allPlots : continue
                                                        if not wTP in lPlots : continue
                                                        if not wTP in foundPlots : foundPlots.append(wTP)
                                if len(lPlots) == len(foundPlots) : return True #all passable plots communicate
                                return False

                        nbTiles = len(peakPlots) + len(hillPlots) + len(landPlots)
                        if remPeak : nbTiles -= len(coastalPlots)

                        if nbTiles > 0 : #all plots are coastal !?
                                effPeakPer = len(peakPlots) / (nbTiles + 0.001)
                                if effPeakPer > peakPer : # remove some peak
                                        while True :
                                                if (len(peakPlots) / (nbTiles + 0.001)) < peakPer : break
                                                if len(peakPlots) == 0 : break
                                                iChoice = getRandNum(len(peakPlots), "FoR : peak remove")
                                                cPlot = peakPlots[iChoice]
                                                tPlots[cPlot[0]][cPlot[1]] = pHill
                                                hillPlots.append(cPlot)
                                                del peakPlots[iChoice]
                                else :
                                        if remPeak :
                                                ncLandPlots = [item for item in landPlots if not item in coastalPlots]
                                                ncHillPlots = [item for item in hillPlots if not item in coastalPlots]
                                        else :
                                                ncLandPlots = copy.copy(landPlots)
                                                ncHillPlots = copy.copy(hillPlots)
                                        while True :
                                                if (len(peakPlots) / (nbTiles + 0.001)) >= peakPer : break
                                                if (len(ncLandPlots) == 0) and (len(ncHillPlots) == 0) : break
                                                listPlots = copy.copy(ncLandPlots) + copy.copy(ncHillPlots)
                                                iChoice = getRandNum(len(listPlots), "FoR : peak add")
                                                cPlot = listPlots[iChoice]
                                                if canHavePeak(cPlot[0], cPlot[1]) :
                                                        tPlots[cPlot[0]][cPlot[1]] = pPeak
                                                        peakPlots.append(cPlot)
                                                        if cPlot in hillPlots : hillPlots.remove(cPlot)
                                                        elif cPlot in landPlots : landPlots.remove(cPlot)
                                                if cPlot in ncHillPlots : ncHillPlots.remove(cPlot)
                                                elif cPlot in ncLandPlots : ncLandPlots.remove(cPlot)

                        # adjust hill percent
                        nbTiles = len(peakPlots) + len(hillPlots) + len(landPlots)

                        effHillPer = len(hillPlots) / (nbTiles + 0.001)
                        if effHillPer > hillPer :
                                while True :
                                        if (len(hillPlots) / (nbTiles + 0.001)) < hillPer : break
                                        if len(hillPlots) == 0 : break
                                        iChoice = getRandNum(len(hillPlots), "FoR : hill remove")
                                        cPlot = hillPlots[iChoice]
                                        tPlots[cPlot[0]][cPlot[1]] = pLand
                                        landPlots.append(cPlot)
                                        del hillPlots[iChoice]
                        else :
                                while True :
                                        if (len(hillPlots) / (nbTiles + 0.001)) >= hillPer : break
                                        if len(landPlots) == 0 : break
                                        iChoice = getRandNum(len(landPlots), "FoR : hill add")
                                        cPlot = landPlots[iChoice]
                                        tPlots[cPlot[0]][cPlot[1]] = pHill
                                        hillPlots.append(cPlot)
                                        del landPlots[iChoice]

                        # debug
                        nbPeak = 0
                        nbHill = 0
                        nbTile = 0
                        nbUnwantedPeak = 0
                        nbCoastalTiles = 0
                        for iX in range(iW) :
                                for iY in range(iH) :
                                        plotType = tPlots[iX][iY]
                                        if plotType == pWater : continue
                                        if isCoast(iX, iY) :
                                                nbCoastalTiles += 1
                                                if remPeak :
                                                        if plotType == pPeak : nbUnwantedPeak += 1
                                        nbTile += 1
                                        if plotType == pHill : nbHill += 1
                                        elif plotType == pPeak : nbPeak += 1
                        logList = []
                        logList.append(" final peak number : %r" %nbPeak)
                        logList.append(" final peak percent : %r" %(float(nbPeak)/nbTile*100.0, ))
                        if remPeak :
                                if (nbTile - nbCoastalTiles) > 0 :
                                        logList.append(" final peak percent (without coastal tiles) : %r" %(float(nbPeak - nbUnwantedPeak)/(nbTile - nbCoastalTiles)*100.0, ))
                        logList.append(" final hill percent : %r" %(float(nbHill)/nbTile*100.0, ))
                        logList.append(" final nb Tiles : %r" %nbTile)
                        logList.append(" final nb Coastal Tiles : %r" %nbCoastalTiles)
                        logList.append(" final nb unwanted peaks : %r" %nbUnwantedPeak)
                        logList.append("")
                        writeLog("", True, logList)

                        # save changes
                        for iX in range(iW) :
                                for iY in range(iH) :
                                        plotTypes[map.plotNum(iX, iY)] = tPlots[iX][iY]
                except :
                        writeLog("", True, ["", " An error occured during option application ..."])
                        writeError()

                return plotTypes
        except :
                writeLog("", True, ["", " An error occured during plot generation ... generate a fractal map"])
                writeError()
                fractal_world = FractalWorld()
                fractal_world.initFractal(polar = True)
                plotTypes = fractal_world.generatePlotTypes()
                return plotTypes

class MnSMultilayeredFractal(CvMapGeneratorUtil.MultilayeredFractal):
	def generatePlotsByRegion(self):
		global yShiftRoll1
		global yShiftRoll2
		if cmo[0] != 4:
			iContinentsGrainWest = 1 + cmo[0]
			iContinentsGrainEast = 1 + cmo[0]
		else:
			iContinentsGrainWest = 1 + getRandNum(4, "FoR : West Continent Grain - Medium and Small PYTHON")
			iContinentsGrainEast = 1 + getRandNum(4, "FoR : East Continent Grain - Medium and Small PYTHON")
		iIslandsGrain = 4 + cmo[1]
		userInputOverlap = cmo[2]
		numTinies = 1 + getRandNum(4, "FoR : Tiny Islands - Medium and Small PYTHON")
		if numTinies:
			for tiny_loop in range(numTinies):
				tinyWestLon = 0.01 * getRandNum(85, "FoR : Tiny Longitude - Medium and Small PYTHON")
				tinyWestX = int(self.iW * tinyWestLon)
				tinySouthLat = 0.01 * getRandNum(85, "FoR : Tiny Latitude - Medium and Small PYTHON")
				tinySouthY = int(self.iH * tinyWestLon)
				tinyWidth = int(self.iW * 0.15)
				tinyHeight = int(self.iH * 0.15)

				self.generatePlotsInRegion(80,
				                           tinyWidth, tinyHeight,
				                           tinyWestX, tinySouthY,
				                           4, 3,
				                           0, self.iTerrainFlags,
				                           6, 5,
				                           True, 3,
				                           -1, False,
				                           False
				                           )
		iSouthY = 0
		iNorthY = self.iH - 1
		iHeight = iNorthY - iSouthY + 1
		iWestX = int(self.iW / 20)
		iEastX = int(self.iW * 0.45) - 1
		iWidth = iEastX - iWestX + 1
		if userInputOverlap:
			yExp = 5
			iWater = 80
		else:
			iWater = 74
			yExp = 6
			if yShiftRoll1:
				southShift = int(0.4 * self.iH)
				northShift = 0
			else:
				southShift = 0
				northShift = int(0.4 * self.iH)

			iSouthY += southShift
			iNorthY -= northShift
			iHeight = iNorthY - iSouthY + 1
		self.generatePlotsInRegion(iWater,
		                           iWidth, iHeight,
		                           iWestX, iSouthY,
		                           iContinentsGrainWest, 4,
		                           self.iRoundFlags, self.iTerrainFlags,
		                           6, yExp,
		                           True, 15,
		                           -1, False,
		                           False
		                           )
		iWestX = int(self.iW * 0.12)
		iEastX = int(self.iW * 0.38) - 1
		iWidth = iEastX - iWestX + 1
		iSouthY = 0
		iNorthY = self.iH - 1
		iHeight = iNorthY - iSouthY + 1
		if userInputOverlap:
			yExp = 5
			iWater = 80
		else:
			iWater = 74
			yExp = 6
			if yShiftRoll1:
				southShift = 0
				northShift = int(0.4 * self.iH)
			else:
				southShift = int(0.4 * self.iH)
				northShift = 0

			iSouthY += southShift
			iNorthY -= northShift
			iHeight = iNorthY - iSouthY + 1
		self.generatePlotsInRegion(iWater,
		                           iWidth, iHeight,
		                           iWestX, iSouthY,
		                           iIslandsGrain, 5,
		                           self.iRoundFlags, self.iTerrainFlags,
		                           6, yExp,
		                           True, 15,
		                           -1, False,
		                           False
		                           )
		iSouthY = 0
		iNorthY = self.iH - 1
		iHeight = iNorthY - iSouthY + 1
		iWestX = int(self.iW * 0.55)
		iEastX = int(self.iW * 0.95) - 1
		iWidth = iEastX - iWestX + 1
		if userInputOverlap:
			yExp = 5
			iWater = 80
		else:
			iWater = 74
			yExp = 6
			if yShiftRoll2:
				southShift = int(0.4 * self.iH)
				northShift = 0
			else:
				southShift = 0
				northShift = int(0.4 * self.iH)
			iSouthY += southShift
			iNorthY -= northShift
			iHeight = iNorthY - iSouthY + 1
		self.generatePlotsInRegion(iWater,
		                           iWidth, iHeight,
		                           iWestX, iSouthY,
		                           iContinentsGrainWest, 4,
		                           self.iRoundFlags, self.iTerrainFlags,
		                           6, yExp,
		                           True, 15,
		                           -1, False,
		                           False
		                           )
		iWestX = int(self.iW * 0.62)
		iEastX = int(self.iW * 0.88) - 1
		iWidth = iEastX - iWestX + 1
		iSouthY = 0
		iNorthY = self.iH - 1
		iHeight = iNorthY - iSouthY + 1
		if userInputOverlap:
			yExp = 5
			iWater = 80
		else:
			iWater = 74
			yExp = 6
			if yShiftRoll2:
				southShift = 0
				northShift = int(0.4 * self.iH)
			else:
				southShift = int(0.4 * self.iH)
				northShift = 0
			iSouthY += southShift
			iNorthY -= northShift
			iHeight = iNorthY - iSouthY + 1
		self.generatePlotsInRegion(iWater,
		                           iWidth, iHeight,
		                           iWestX, iSouthY,
		                           iIslandsGrain, 5,
		                           self.iRoundFlags, self.iTerrainFlags,
		                           6, yExp,
		                           True, 15,
		                           -1, False,
		                           False
		                           )
		return self.wholeworldPlotTypes

class BnSHemMultilayeredFractal(CvMapGeneratorUtil.MultilayeredFractal):
	def generateIslandRegion(self, minTinies, extraTinies, iWestX, iSouthY, iWidth, iHeight, iGrain):
		numTinies = minTinies + getRandNum(extraTinies, "FoR : Tiny Islands - Custom Continents PYTHON")
		if numTinies:
			for tiny_loop in range(numTinies):
				tinyWidth = int(self.iW * 0.15)
				tinyHeight = int(self.iH * 0.15)
				tinyWestX = iWestX + getRandNum(iWidth - tinyWidth, "FoR : Tiny Longitude - Custom Continents PYTHON")
				tinySouthY = iSouthY + getRandNum(iHeight - tinyHeight, "FoR : Tiny Latitude - Custom Continents PYTHON")
				self.generatePlotsInRegion(80,
										   tinyWidth, tinyHeight,
										   tinyWestX, tinySouthY,
										   iGrain, 3,
										   0, self.iTerrainFlags,
										   6, 5,
										   True, 3,
										   -1, False,
										   False
										   )
		return 0

	def generateContinentRegion(self, iWater, iWidth, iHeight, iWestX, iSouthY, iGrain, xExp):
		self.generatePlotsInRegion(iWater,
								   iWidth, iHeight,
								   iWestX, iSouthY,
								   iGrain, 4,
								   self.iRoundFlags, self.iTerrainFlags,
								   xExp, 6,
								   True, 15,
								   -1, False,
								   False
								   )
		return 0

	def generatePlotsByRegion(self):
		global xShiftRoll
		global yShiftRoll
		global ySplitRoll
		global yPortionRoll
		if (cmo[0] == 3):
			iContinentsGrain = 1
			iSecondaryContinentsGrain = 3
			iTertiaryContinentsGrain = 2
			iPrimaryWater = 74
			iSecondaryWater = 79
			iTertiaryWater = 76
		else:
			iContinentsGrain = 1 + cmo[0]
			iSecondaryContinentsGrain = 1 + cmo[0]
			iTertiaryContinentsGrain = 1 + cmo[0]
			iPrimaryWater = 74
			iSecondaryWater = 74
			iTertiaryWater = 74
		iPrimaryWater += self.gc.getSeaLevelInfo(self.map.getSeaLevel()).getSeaLevelChange()
		iSecondaryWater += self.gc.getSeaLevelInfo(self.map.getSeaLevel()).getSeaLevelChange()
		iTertiaryWater += self.gc.getSeaLevelInfo(self.map.getSeaLevel()).getSeaLevelChange()
		splitYBigger = 0.5
		splitYSmaller = 0.5
		splitYBuffer = 0.1
		iIslandsGrain = 3 + cmo[1]
		tinyIslandOverlap = 0
		regions = 2 + cmo[2]
		if (regions == 2):
			vSplitPrimary = 0
			vSplitSecondary = 0
			vSplitTertiary = 0
			tripleSplit = 0
		elif (regions == 3):
			vSplitPrimary = 0
			vSplitSecondary = 0
			vSplitTertiary = 0
			tripleSplit = 1
		elif (regions == 4):
			vSplitPrimary = 1
			vSplitSecondary = 1
			vSplitTertiary = 0
			tripleSplit = 0
		elif (regions == 5):
			vSplitPrimary = 0
			vSplitSecondary = 1
			vSplitTertiary = 1
			tripleSplit = 1
		elif (regions == 6):
			vSplitPrimary = 1
			vSplitSecondary = 1
			vSplitTertiary = 1
			tripleSplit = 1
		else:
			vSplitPrimary = 0
			vSplitSecondary = 0
			vSplitTertiary = 0
			tripleSplit = 0
		iSouthY = 0
		iNorthY = self.iH - 1
		iHeight = iNorthY - iSouthY + 1
		iWestX = 0
		iEastX = self.iW - 1
		iWidth = iEastX - iWestX + 1
		if tinyIslandOverlap:
			self.generateIslandRegion(4, 6, iWestX, iSouthY, iWidth, iHeight, iIslandsGrain)
		xExp = 6
		if tripleSplit:
			if xShiftRoll:
				westShift = int(0.33 * self.iW)
				eastShift = int(0.33 * self.iW)
			else:
				westShift = 0
				eastShift = int(0.66 * self.iW)
		else:
			if xShiftRoll:
				westShift = int(0.5 * self.iW)
				eastShift = 0
			else:
				westShift = 0
				eastShift = int(0.5 * self.iW)
		iWestX = westShift
		iEastX = self.iW - eastShift
		iWidth = iEastX - iWestX
		if vSplitPrimary:
			if yPortionRoll:
				if yShiftRoll:
					northShift = int(splitYBuffer * self.iH)
					southShift = int(splitYBigger * self.iH)
				else:
					northShift = int(splitYSmaller * self.iH)
					southShift = int(splitYBuffer * self.iH)
			else:
				if yShiftRoll:
					northShift = int(splitYBuffer * self.iH)
					southShift = int(splitYSmaller * self.iH)
				else:
					northShift = int(splitYBigger * self.iH)
					southShift = int(splitYBuffer * self.iH)
			iSouthY = southShift
			iNorthY = self.iH - northShift
			iHeight = iNorthY - iSouthY
			self.generateContinentRegion(iPrimaryWater, iWidth, iHeight, iWestX, iSouthY, iContinentsGrain, xExp)
			if (tinyIslandOverlap == 0):
				self.generateIslandRegion(1, 2, iWestX, iSouthY, iWidth, iHeight, iIslandsGrain)
			if yPortionRoll:
				if yShiftRoll:
					northShift = int(splitYSmaller * self.iH)
					southShift = int(splitYBuffer * self.iH)
				else:
					northShift = int(splitYBuffer * self.iH)
					southShift = int(splitYBigger * self.iH)
			else:
				if yShiftRoll:
					northShift = int(splitYBigger * self.iH)
					southShift = int(splitYBuffer * self.iH)
				else:
					northShift = int(splitYBuffer * self.iH)
					southShift = int(splitYSmaller * self.iH)
			iSouthY = southShift
			iNorthY = self.iH - northShift
			iHeight = iNorthY - iSouthY
			self.generateContinentRegion(iPrimaryWater, iWidth, iHeight, iWestX, iSouthY, iContinentsGrain, xExp)
			if (tinyIslandOverlap == 0):
				self.generateIslandRegion(1, 2, iWestX, iSouthY, iWidth, iHeight, iIslandsGrain)
		else:
			iSouthY = 0
			iNorthY = self.iH - 1
			iHeight = iNorthY - iSouthY + 1
			self.generateContinentRegion(iPrimaryWater, iWidth, iHeight, iWestX, iSouthY, iContinentsGrain, xExp)
			if (tinyIslandOverlap == 0):
				self.generateIslandRegion(2, 3, iWestX, iSouthY, iWidth, iHeight, iIslandsGrain)
		xExp = 6
		if tripleSplit:
			if xShiftRoll:
				westShift = 0
				eastShift = int(0.66 * self.iW)
			else:
				westShift = int(0.33 * self.iW)
				eastShift = int(0.33 * self.iW)
		else:
			if xShiftRoll:
				westShift = 0
				eastShift = int(0.5 * self.iW)
			else:
				westShift = int(0.5 * self.iW)
				eastShift = 0
		iWestX = westShift
		iEastX = self.iW - eastShift
		iWidth = iEastX - iWestX
		if vSplitSecondary:
			if yPortionRoll:
				if yShiftRoll:
					northShift = int(splitYBuffer * self.iH)
					southShift = int(splitYBigger * self.iH)
				else:
					northShift = int(splitYSmaller * self.iH)
					southShift = int(splitYBuffer * self.iH)
			else:
				if yShiftRoll:
					northShift = int(splitYBuffer * self.iH)
					southShift = int(splitYSmaller * self.iH)
				else:
					northShift = int(splitYBigger * self.iH)
					southShift = int(splitYBuffer * self.iH)
			iSouthY = southShift
			iNorthY = self.iH - northShift
			iHeight = iNorthY - iSouthY
			self.generateContinentRegion(iSecondaryWater, iWidth, iHeight, iWestX, iSouthY, iSecondaryContinentsGrain, xExp)
			if (tinyIslandOverlap == 0):
				self.generateIslandRegion(2, 3, iWestX, iSouthY, iWidth, iHeight, iIslandsGrain)
			if yPortionRoll:
				if yShiftRoll:
					northShift = int(splitYSmaller * self.iH)
					southShift = int(splitYBuffer * self.iH)
				else:
					northShift = int(splitYBuffer * self.iH)
					southShift = int(splitYBigger * self.iH)
			else:
				if yShiftRoll:
					northShift = int(splitYBigger * self.iH)
					southShift = int(splitYBuffer * self.iH)
				else:
					northShift = int(splitYBuffer * self.iH)
					southShift = int(splitYSmaller * self.iH)
			iSouthY = southShift
			iNorthY = self.iH - northShift
			iHeight = iNorthY - iSouthY
			self.generateContinentRegion(iSecondaryWater, iWidth, iHeight, iWestX, iSouthY, iSecondaryContinentsGrain, xExp)
			if (tinyIslandOverlap == 0):
				self.generateIslandRegion(2, 3, iWestX, iSouthY, iWidth, iHeight, iIslandsGrain)
		else:
			iSouthY = 0
			iNorthY = self.iH - 1
			iHeight = iNorthY - iSouthY + 1
			self.generateContinentRegion(iSecondaryWater, iWidth, iHeight, iWestX, iSouthY, iSecondaryContinentsGrain, xExp)
			if (tinyIslandOverlap == 0):
				self.generateIslandRegion(3, 4, iWestX, iSouthY, iWidth, iHeight, iIslandsGrain)
		if tripleSplit:
			xExp = 6
			westShift = int(0.66 * self.iW)
			eastShift = 0
			iWestX = westShift
			iEastX = self.iW - eastShift
			iWidth = iEastX - iWestX
			if vSplitTertiary:
				if yPortionRoll:
					if yShiftRoll:
						northShift = int(splitYBuffer * self.iH)
						southShift = int(splitYBigger * self.iH)
					else:
						northShift = int(splitYSmaller * self.iH)
						southShift = int(splitYBuffer * self.iH)
				else:
					if yShiftRoll:
						northShift = int(splitYBuffer * self.iH)
						southShift = int(splitYSmaller * self.iH)
					else:
						northShift = int(splitYBigger * self.iH)
						southShift = int(splitYBuffer * self.iH)
				iSouthY = southShift
				iNorthY = self.iH - northShift
				iHeight = iNorthY - iSouthY
				self.generateContinentRegion(iTertiaryWater, iWidth, iHeight, iWestX, iSouthY, iTertiaryContinentsGrain, xExp)
				if (tinyIslandOverlap == 0):
					self.generateIslandRegion(2, 3, iWestX, iSouthY, iWidth, iHeight, iIslandsGrain)
				if yPortionRoll:
					if yShiftRoll:
						northShift = int(splitYSmaller * self.iH)
						southShift = int(splitYBuffer * self.iH)
					else:
						northShift = int(splitYBuffer * self.iH)
						southShift = int(splitYBigger * self.iH)
				else:
					if yShiftRoll:
						northShift = int(splitYBigger * self.iH)
						southShift = int(splitYBuffer * self.iH)
					else:
						northShift = int(splitYBuffer * self.iH)
						southShift = int(splitYSmaller * self.iH)
				iSouthY = southShift
				iNorthY = self.iH - northShift
				iHeight = iNorthY - iSouthY
				self.generateContinentRegion(iTertiaryWater, iWidth, iHeight, iWestX, iSouthY, iTertiaryContinentsGrain, xExp)
				if (tinyIslandOverlap == 0):
					self.generateIslandRegion(2, 3, iWestX, iSouthY, iWidth, iHeight, iIslandsGrain)
			else:
				iSouthY = 0
				iNorthY = self.iH - 1
				iHeight = iNorthY - iSouthY + 1
				self.generateContinentRegion(iTertiaryWater, iWidth, iHeight, iWestX, iSouthY, iTertiaryContinentsGrain, xExp)
				if (tinyIslandOverlap == 0):
					self.generateIslandRegion(3, 4, iWestX, iSouthY, iWidth, iHeight, iIslandsGrain)
		return self.wholeworldPlotTypes

class BnSMultilayeredFractal(CvMapGeneratorUtil.MultilayeredFractal):
	def generatePlotsByRegion(self):
		global xShiftRoll
		iContinentsGrain = 1 + cmo[0]
		iIslandsGrain = 4 + cmo[1]
		userInputOverlap = cmo[2]
		iWater = 74
		numTinies = 1 + getRandNum(4, "FoR : Tiny Islands - Custom Continents PYTHON")
		if numTinies:
			for tiny_loop in range(numTinies):
				tinyWestLon = 0.01 * getRandNum(85, "FoR : Tiny Longitude - Custom Continents PYTHON")
				tinyWestX = int(self.iW * tinyWestLon)
				tinySouthLat = 0.01 * getRandNum(85, "FoR : Tiny Latitude - Custom Continents PYTHON")
				tinySouthY = int(self.iH * tinyWestLon)
				tinyWidth = int(self.iW * 0.15)
				tinyHeight = int(self.iH * 0.15)
				self.generatePlotsInRegion(80,
				                           tinyWidth, tinyHeight,
				                           tinyWestX, tinySouthY,
				                           4, 3,
				                           0, self.iTerrainFlags,
				                           6, 5,
				                           True, 3,
				                           -1, False,
				                           False
				                           )
		iSouthY = 0
		iNorthY = self.iH - 1
		iHeight = iNorthY - iSouthY + 1
		iWestX = 0
		iEastX = self.iW - 1
		iWidth = iEastX - iWestX + 1
		if userInputOverlap:
			xExp = 7
			iWater = 82
		else:
			xExp = 6
			if xShiftRoll:
				westShift = int(0.4 * self.iW)
				eastShift = 0
			else:
				westShift = 0
				eastShift = int(0.4 * self.iW)
			iWestX += westShift
			iEastX -= eastShift
			iWidth = iEastX - iWestX + 1
		self.generatePlotsInRegion(iWater,
		                           iWidth, iHeight,
		                           iWestX, iSouthY,
		                           iContinentsGrain, 4,
		                           self.iRoundFlags, self.iTerrainFlags,
		                           xExp, 6,
		                           True, 15,
		                           -1, False,
		                           False
		                           )
		iWestX = 0
		iEastX = self.iW - 1
		iWidth = iEastX - iWestX + 1
		if userInputOverlap:
			xExp = 7
			iWater = 82
		else:
			xExp = 6
			if xShiftRoll:
				westShift = 0
				eastShift = int(0.4 * self.iW)
			else:
				westShift = int(0.4 * self.iW)
				eastShift = 0
			iWestX += westShift
			iEastX -= eastShift
			iWidth = iEastX - iWestX + 1
		self.generatePlotsInRegion(iWater,
		                           iWidth, iHeight,
		                           iWestX, iSouthY,
		                           iIslandsGrain, 5,
		                           self.iRoundFlags, self.iTerrainFlags,
		                           xExp, 6,
		                           True, 15,
		                           -1, False,
		                           False
		                           )
		return self.wholeworldPlotTypes

def generateChessPlotTypes():
	global chessLakes
	global userInputBorder
	try :
                userInputBorder = getRandSel(selGen["maps"]["chess"]["border"])
                hillPer = getRandSel(selGen["terrain"]["hill"]["hillpercent"], False)/100.0
                waterPer = getRandSel(selGen["maps"]["chess"]["waterper"], False)
                plotTypes = [PlotTypes.PLOT_LAND] * (iW*iH)
                terrainFrac = CyFractal()
                hills = 60
                grain = 7
                area = iW*iH/16
                if area > 500 :
                        area=iW*iH/16
                        if area<750:
                                grain+=1
                        elif area<1050:
                                grain+=2
                        else :
                                grain+=3
                terrainFrac.fracInit(iW, iH, grain, dice, 0, -1, -1)
                iHillsThreshold = terrainFrac.getHeightFromPercent(hills)
                borderPlots = []
                borderSidePlots = []
                for dx in range(iW/6) :
                        for dy in range(iH/6) :
                                for dyy in range(5) : 
                                        borderPlots.append(map.plotNum(dx*6, dy*6+dyy))
                                        cTP = toWrap(dx*6+1, dy*6+dyy)
                                        if (dyy in range(1,4)) and (cTP != -1) :
                                                x, y = cTP
                                                borderSidePlots.append(map.plotNum(x, y))
                                        cTP = toWrap(dx*6-1, dy*6+dyy)
                                        if (dyy in range(1,4)) and (cTP != -1) :
                                                x, y = cTP
                                                borderSidePlots.append(map.plotNum(x, y))
                                for dxx in range(5):
                                        borderPlots.append(map.plotNum(dx*6+dxx+1, dy*6+5))
                                        cTP = toWrap(dx*6+dxx+1, dy*6+4)
                                        if (dxx in range(1,4)) and (cTP != -1) :
                                                x, y = cTP
                                                borderSidePlots.append(map.plotNum(x, y))
                                        cTP = toWrap(dx*6+dxx+1, dy*6+6)
                                        if (dxx in range(1,4)) and (cTP != -1) :
                                                x, y = cTP
                                                borderSidePlots.append(map.plotNum(x, y))

                for iX in range(iW) :
                        for iY in range(iH) :
                                iIndex = map.plotNum(iX, iY)
                                val = terrainFrac.getHeight(iX, iY)
                                if iIndex in borderSidePlots : val *= 1.6
                                if (val >= iHillsThreshold*1.3) and (not iIndex in borderPlots) : plotTypes[iIndex] = PlotTypes.PLOT_HILLS

                plotTP = PlotTypes.PLOT_PEAK
                if userInputBorder == 1 : plotTP = PlotTypes.PLOT_HILLS
                elif userInputBorder == 2 : plotTP = PlotTypes.PLOT_LAND
                elif userInputBorder == 3 : plotTP = PlotTypes.PLOT_OCEAN

                if not wrapY :
                        for dx in range(iW/6) :
                                i = map.plotNum(dx*6, iH-1)
                                plotTypes[i] = plotTP
                if not wrapX :
                        for dy in range(iH/6) :
                                i = map.plotNum(0, dy*6+5)
                                plotTypes[i] = plotTP
                for i in borderPlots : plotTypes[i] = plotTP

                lar = iW/6
                hau = iH/6
                chessLakes = [[0 for i in range(2*hau)] for j in range(lar)]
                waterFrac = CyFractal()
                waterFrac.fracInit(lar, 2*hau, grain-3, dice, 0, -1, -1)
                iWaterThreshold = waterFrac.getHeightFromPercent(int(waterPer))
                for dy in range(2*hau) :
                        for dx in range(lar) :
                                if waterFrac.getHeight(dx,dy) >=  iWaterThreshold : continue
                                for (dxx,dyy) in ((1,0),(2,0),(3,0),(4,0),(5,0),(2,1),(3,1),(4,1),(2,-1),(3,-1),(4,-1),(3,2),(3,-2)) :
                                        i = map.plotNum((dx*6+(dy%2)*3+dxx)%iW, (dy*3+dyy-1)%iH)
                                        plotTypes[i] = PlotTypes.PLOT_OCEAN
                                chessLakes[dx][dy] = 1

                for iX in range(iW) :
                        for iY in range(iH) :
                                iIndex = map.plotNum(iX, iY)
                                if plotTypes[iIndex] != PlotTypes.PLOT_OCEAN :
                                        oceanPlots = 0
                                        for (i,j) in ((-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)) :
                                                k = map.plotNum((iX+i)%iW, (iY+j)%iH)
                                                if plotTypes[k] == PlotTypes.PLOT_OCEAN : oceanPlots += 1
                                        if oceanPlots > 5 : plotTypes[iIndex] = PlotTypes.PLOT_OCEAN

                plotLand = []
                plotHill = []
                for i in range(len(plotTypes)) :
                        if i in borderPlots : continue
                        if plotTypes[i] == PlotTypes.PLOT_HILLS : plotHill.append(i)
                        elif plotTypes[i] == PlotTypes.PLOT_LAND : plotLand.append(i)
                hillPerPlaced = float(len(plotHill))/(len(plotHill)+len(plotLand))

                nbPlaced = 0
                if hillPerPlaced < hillPer :
                        plotToPlace = PlotTypes.PLOT_HILLS
                        refList = plotLand
                        nbToPlace = (hillPer-hillPerPlaced)*(len(plotHill)+len(plotLand))
                else:
                        plotToPlace = PlotTypes.PLOT_LAND
                        refList = plotHill
                        nbToPlace = (hillPerPlaced-hillPer)*(len(plotHill)+len(plotLand))

                while True :
                        if nbPlaced >= nbToPlace : break
                        if len(refList) == 0 : break
                        iChoice = getRandNum(len(refList), 'FoR : chess hill dice')
                        plotTypes[refList[iChoice]] = plotToPlace
                        del refList[iChoice]
                        nbPlaced += 1

                return (True, plotTypes)
        except :
                writeLog("", False, ["", " An error occured during Chess plot generation ... generate a fractal map"])
                writeError()
                fractal_world = FractalWorld()
                fractal_world.initFractal(polar = True)
                plotTypes = fractal_world.generatePlotTypes()
                return (False, plotTypes)

class WheelMultilayeredFractal(CvMapGeneratorUtil.MultilayeredFractal):
	def generatePlotsInRegion(self, iWaterPercent, 
	                          iRegionWidth, iRegionHeight, 
	                          iRegionWestX, iRegionSouthY, 
	                          iRegionGrain, iRegionHillsGrain, 
	                          iRegionPlotFlags, iRegionTerrainFlags, 
	                          iRegionFracXExp = -1, iRegionFracYExp = -1, 
	                          bShift = True, iStrip = 15, 
	                          rift_grain = -1, has_center_rift = False, 
	                          invert_heights = False):
		water = iWaterPercent
		iWestX = iRegionWestX
		iSouthY = iRegionSouthY
		self.plotTypes = []
		self.plotTypes = [PlotTypes.PLOT_OCEAN] * (iRegionWidth*iRegionHeight)
		regionContinentsFrac = CyFractal()
		regionHillsFrac = CyFractal()
		regionPeaksFrac = CyFractal()
		regionContinentsFrac.fracInit(iRegionWidth, iRegionHeight, iRegionGrain, self.dice, iRegionPlotFlags, iRegionFracXExp, iRegionFracYExp)
		regionHillsFrac.fracInit(iRegionWidth, iRegionHeight, iRegionHillsGrain, self.dice, iRegionTerrainFlags, iRegionFracXExp, iRegionFracYExp)
		regionPeaksFrac.fracInit(iRegionWidth, iRegionHeight, iRegionHillsGrain+1, self.dice, iRegionTerrainFlags, iRegionFracXExp, iRegionFracYExp)
		iWaterThreshold = regionContinentsFrac.getHeightFromPercent(water)
		iHillsBottom1 = regionHillsFrac.getHeightFromPercent(max((23 - self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 0))
		iHillsTop1 = regionHillsFrac.getHeightFromPercent(min((30 + self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 100))
		iHillsBottom2 = regionHillsFrac.getHeightFromPercent(max((70 - self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 0))
		iHillsTop2 = regionHillsFrac.getHeightFromPercent(min((77 + self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 100))
		iPeakThreshold = regionPeaksFrac.getHeightFromPercent(self.gc.getClimateInfo(self.map.getClimate()).getPeakPercent())
		for x in range(iRegionWidth):
			for y in range(iRegionHeight):
				i = y*iRegionWidth + x
				val = regionContinentsFrac.getHeight(x,y)
				if val <= iWaterThreshold: pass
				else:
					hillVal = regionHillsFrac.getHeight(x,y)
					if ((hillVal >= iHillsBottom1 and hillVal <= iHillsTop1) or (hillVal >= iHillsBottom2 and hillVal <= iHillsTop2)):
						peakVal = regionPeaksFrac.getHeight(x,y)
						if (peakVal <= iPeakThreshold):
							self.plotTypes[i] = PlotTypes.PLOT_PEAK
						else:
							self.plotTypes[i] = PlotTypes.PLOT_HILLS
					else:
						self.plotTypes[i] = PlotTypes.PLOT_LAND
		if bShift:
			self.shiftRegionPlots(iRegionWidth, iRegionHeight, iStrip)
		for x in range(iRegionWidth):
			wholeworldX = x + iWestX
			for y in range(iRegionHeight):
				i = y*iRegionWidth + x
				if self.plotTypes[i] == PlotTypes.PLOT_OCEAN: continue
				wholeworldY = y + iSouthY
				iWorld = wholeworldY*self.iW + wholeworldX
				self.wholeworldPlotTypes[iWorld] = self.plotTypes[i]
		return

	def generateCenter(self, iWaterPercent, 
	                   iRegionWidth, iRegionHeight, 
	                   iRegionWestX, iRegionSouthY, 
	                   iRegionGrain, iRegionHillsGrain, 
	                   iRegionPlotFlags, iRegionTerrainFlags, 
	                   iRegionFracXExp = -1, iRegionFracYExp = -1, 
	                   bShift = True, iStrip = 15, 
	                   rift_grain = -1, has_center_rift = False, 
	                   invert_heights = False):
		water = iWaterPercent
		iWestX = iRegionWestX
		iSouthY = iRegionSouthY
		self.plotTypes = []
		self.plotTypes = [PlotTypes.PLOT_OCEAN] * (iRegionWidth*iRegionHeight)
		regionContinentsFrac = CyFractal()
		regionHillsFrac = CyFractal()
		regionContinentsFrac.fracInit(iRegionWidth, iRegionHeight, iRegionGrain, self.dice, iRegionPlotFlags, iRegionFracXExp, iRegionFracYExp)
		regionHillsFrac.fracInit(iRegionWidth, iRegionHeight, iRegionHillsGrain, self.dice, iRegionTerrainFlags, iRegionFracXExp, iRegionFracYExp)
		iWaterThreshold = regionContinentsFrac.getHeightFromPercent(water)
		iHillsBottom1 = regionHillsFrac.getHeightFromPercent(max((20 - self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 0))
		iHillsTop1 = regionHillsFrac.getHeightFromPercent(min((30 + self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 100))
		iHillsBottom2 = regionHillsFrac.getHeightFromPercent(max((70 - self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 0))
		iHillsTop2 = regionHillsFrac.getHeightFromPercent(min((80 + self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 100))
		for x in range(iRegionWidth):
			for y in range(iRegionHeight):
				i = y*iRegionWidth + x
				val = regionContinentsFrac.getHeight(x,y)
				if val <= iWaterThreshold: pass
				else:
					hillVal = regionHillsFrac.getHeight(x,y)
					if ((hillVal >= iHillsBottom1 and hillVal <= iHillsTop1) or (hillVal >= iHillsBottom2 and hillVal <= iHillsTop2)):
						self.plotTypes[i] = PlotTypes.PLOT_HILLS
					else:
						self.plotTypes[i] = PlotTypes.PLOT_LAND

		if bShift:
			self.shiftRegionPlots(iRegionWidth, iRegionHeight, iStrip)
		for x in range(iRegionWidth):
			wholeworldX = x + iWestX
			for y in range(iRegionHeight):
				i = y*iRegionWidth + x
				if self.plotTypes[i] == PlotTypes.PLOT_OCEAN: continue
				wholeworldY = y + iSouthY
				iWorld = wholeworldY*self.iW + wholeworldX
				self.wholeworldPlotTypes[iWorld] = self.plotTypes[i]
		return

	def generatePlotsByRegion(self, wheel_type):
		iPlayers = self.gc.getGame().countCivPlayersEverAlive()
		userInputAreaType = cmo[1]
		area_grain = 3 - userInputAreaType
		buffer_one = [0, 58, 64, 70]
		sea = self.gc.getSeaLevelInfo(self.map.getSeaLevel()).getSeaLevelChange()
		sea = min(sea, 5)
		sea = max(sea, -5)
		if wheel_type == 1 and iPlayers < 11 and iPlayers > 1:
			global buffer_data
			for buffer_loop in range(iPlayers):
				[bufWestX, bufEastX, bufSouthY, bufNorthY] = buffer_data[buffer_loop]
				thisBuffer = 1 + getRandNum(3, "FoR : Random Buffer Type - Wheel PYTHON")
				bufWater = sea + buffer_one[thisBuffer]
				bufGrain = thisBuffer + 1
				bufWidth = bufEastX - bufWestX + 1
				bufHeight = bufNorthY - bufSouthY + 1
				self.generatePlotsInRegion(bufWater,
				                           bufWidth, bufHeight,
				                           bufWestX, bufSouthY,
				                           bufGrain, 3,
				                           self.iRoundFlags, self.iTerrainFlags,
				                           6, 6,
				                           True, 3,
				                           -1, False,
				                           False
				                           )
		else: pass
		global region_data
		for region_loop in range(iPlayers):
			[regWestX, regEastX, regSouthY, regNorthY] = region_data[region_loop]
			regWidth = regEastX - regWestX + 1
			regHeight = regNorthY - regSouthY + 1
			self.generatePlotsInRegion(55 + sea,
			                           regWidth, regHeight,
			                           regWestX, regSouthY,
			                           area_grain, 4,
			                           self.iRoundFlags, self.iTerrainFlags,
			                           6, 6,
			                           True, 3,
			                           -1, False,
			                           False
			                           )
			coreWestX = regWestX + int(regWidth * 0.25)
			coreEastX = regEastX - int(regWidth * 0.25)
			coreSouthY = regSouthY + int(regHeight * 0.25)
			coreNorthY = regNorthY - int(regHeight * 0.25)
			coreWidth = coreEastX - coreWestX + 1
			coreHeight = coreNorthY - coreSouthY + 1
			self.generatePlotsInRegion(65,
			                           coreWidth, coreHeight,
			                           coreWestX, coreSouthY,
			                           1, 3,
			                           self.iHorzFlags, self.iTerrainFlags,
			                           5, 5,
			                           True, 3,
			                           -1, False,
			                           False
			                           )
		global wheel_data
		linewidth = 1 + cmo[2]
		iWH = self.iW * self.iH
		offsetstart = 0 - int(linewidth/2)
		offsetrange = range(offsetstart, offsetstart + linewidth)
		for wheel_loop in range(len(wheel_data) - 1):
			[startx, starty] = wheel_data[wheel_loop]
			[endx, endy] = wheel_data[wheel_loop + 1]
			if abs(endy-starty) < abs(endx-startx):
				if startx > endx:
					startx, starty, endx, endy = endx, endy, startx, starty
				dx = endx-startx
				dy = endy-starty
				if dx == 0 or dy == 0:
					slope = 0
				else:
					slope = float(dy)/float(dx)
				y = starty
				for x in range(startx, endx+1):
					for offset in offsetrange:
						if map.isPlot(x, int(round(y+offset))):
							i = map.plotNum(x, int(round(y+offset)))
							self.wholeworldPlotTypes[i] = PlotTypes.PLOT_LAND
					y += slope
			else:
				if starty > endy:
					startx, starty, endx, endy = endx, endy, startx, starty
				dx, dy = endx-startx, endy-starty
				if dx == 0 or dy == 0:
					slope = 0
				else:
					slope = float(dx)/float(dy)
				x = startx
				for y in range(starty, endy+1):
					for offset in offsetrange:
						if map.isPlot(int(round(x+offset)), y):
							i = map.plotNum(int(round(x+offset)), y)
							self.wholeworldPlotTypes[i] = PlotTypes.PLOT_LAND
					x += slope
		global hub_data
		linewidth = 1 + cmo[3]
		iWH = self.iW * self.iH
		offsetstart = 0 - int(linewidth/2)
		offsetrange = range(offsetstart, offsetstart + linewidth)
		for hub_loop in range(len(hub_data)):
			[startx, starty, endx, endy] = hub_data[hub_loop]
			if abs(endy-starty) < abs(endx-startx):
				if startx > endx:
					startx, starty, endx, endy = endx, endy, startx, starty
				dx = endx-startx
				dy = endy-starty
				if dx == 0 or dy == 0:
					slope = 0
				else:
					slope = float(dy)/float(dx)
				y = starty
				for x in range(startx, endx+1):
					for offset in offsetrange:
						if map.isPlot(x, int(round(y+offset))):
							i = map.plotNum(x, int(round(y+offset)))
							self.wholeworldPlotTypes[i] = PlotTypes.PLOT_LAND
					y += slope
			else:
				if starty > endy:
					startx, starty, endx, endy = endx, endy, startx, starty
				dx, dy = endx-startx, endy-starty
				if dx == 0 or dy == 0:
					slope = 0
				else:
					slope = float(dx)/float(dy)
				x = startx
				for y in range(starty, endy+1):
					for offset in offsetrange:
						if map.isPlot(int(round(x+offset)), y):
							i = map.plotNum(int(round(x+offset)), y)
							self.wholeworldPlotTypes[i] = PlotTypes.PLOT_LAND
					x += slope
		global center_data
		[cenWestX, cenEastX, cenSouthY, cenNorthY] = center_data
		cenWidth = cenEastX - cenWestX + 1
		cenHeight = cenNorthY - cenSouthY + 1
		thisBuffer = 1 + getRandNum(3, "FoR : Random Buffer Type - Wheel PYTHON")
		bufWater = sea + buffer_one[thisBuffer]
		bufGrain = thisBuffer + 1
		self.generateCenter(bufWater,
		                    cenWidth, cenHeight,
		                    cenWestX, cenSouthY,
		                    bufGrain, 4,
		                    self.iRoundFlags, self.iTerrainFlags,
		                    -1, -1,
		                    True, 5,
		                    -1, False,
		                    False
		                    )
		return self.wholeworldPlotTypes

class TerraMultilayeredFractal(CvMapGeneratorUtil.MultilayeredFractal):
	def generatePlotsByRegion(self):
		sizekey = self.map.getWorldSize()
		sizevalues = {
			WorldSizeTypes.WORLDSIZE_DUEL:      (3,2,1,2),
			WorldSizeTypes.WORLDSIZE_TINY:      (3,2,1,2),
			WorldSizeTypes.WORLDSIZE_SMALL:     (4,2,1,2),
			WorldSizeTypes.WORLDSIZE_STANDARD:  (4,2,1,2),
			WorldSizeTypes.WORLDSIZE_LARGE:     (4,2,1,2),
			WorldSizeTypes.WORLDSIZE_HUGE:      (5,2,1,2)
			}
		if int(sizekey) in sizevalues.keys() :
                        (archGrain, contGrain, gaeaGrain, eurasiaGrain) = sizevalues[sizekey]
                else :
                        (archGrain, contGrain, gaeaGrain, eurasiaGrain) = (7,4,3,4)
		sea = self.gc.getSeaLevelInfo(self.map.getSeaLevel()).getSeaLevelChange()
		sea = min(sea, 5)
		sea = max(sea, -5)
		newworldWestLon = 0.05
		newworldEastLon = 0.35
		eurasiaWestLon = 0.45
		eurasiaEastLon = 0.95
		eurasiaNorthLat = 0.95
		eurasiaSouthLat = 0.45
		thirdworldDimension = 0.125
		thirdworldNorthLat = 0.35
		thirdworldSouthLat = 0.05
		subcontinentLargeHorz = 0.2
		subcontinentLargeVert = 0.32
		subcontinentLargeNorthLat = 0.6
		subcontinentLargeSouthLat = 0.28
		subcontinentSmallDimension = 0.125
		subcontinentSmallNorthLat = 0.525
		subcontinentSmallSouthLat = 0.4
		roll1 = getRandNum(2, "FoR : Eurasian Hemisphere N/S - Terra PYTHON")
		if roll1 == 1:
			eurasiaNorthLat -= 0.4; eurasiaSouthLat -= 0.4
			thirdworldNorthLat += 0.6; thirdworldSouthLat += 0.6
			subcontinentLargeNorthLat += 0.12; subcontinentLargeSouthLat += 0.12
			subcontinentSmallNorthLat += 0.075; subcontinentSmallSouthLat += 0.075
		roll2 = getRandNum(2, "FoR : Eurasian Hemisphere E/W - Terra PYTHON")
		if roll2 == 1:
			newworldWestLon += 0.6; newworldEastLon += 0.6
			eurasiaWestLon -= 0.4; eurasiaEastLon -= 0.4
		eurasiaWestX = int(self.iW * eurasiaWestLon)
		eurasiaEastX = int(self.iW * eurasiaEastLon)
		eurasiaNorthY = int(self.iH * eurasiaNorthLat)
		eurasiaSouthY = int(self.iH * eurasiaSouthLat)
		eurasiaWidth = eurasiaEastX - eurasiaWestX + 1
		eurasiaHeight = eurasiaNorthY - eurasiaSouthY + 1
		eurasiaWater = 55+sea
		self.generatePlotsInRegion(eurasiaWater,
		                           eurasiaWidth, eurasiaHeight,
		                           eurasiaWestX, eurasiaSouthY,
		                           eurasiaGrain, archGrain,
		                           self.iHorzFlags, self.iTerrainFlags,
		                           -1, -1,
		                           True, 11,
		                           2, False,
		                           False
		                           )
		twHeight = eurasiaHeight/2
		twWestX = eurasiaWestX + eurasiaWidth/10
		twEastX = eurasiaEastX - eurasiaWidth/10
		twWidth = twEastX - twWestX + 1
		twNorthY = eurasiaNorthY - eurasiaHeight/4
		twSouthY = eurasiaSouthY + eurasiaHeight/4
		twWater = 60+sea; twGrain = 1; twRift = 2
		self.generatePlotsInRegion(twWater,
		                           twWidth, twHeight,
		                           twWestX, twSouthY,
		                           twGrain, archGrain,
		                           self.iHorzFlags, self.iTerrainFlags,
		                           -1, -1,
		                           True, 11,
		                           twRift, False,
		                           False
		                           )
		NiTextOut("Generating the New World (Python Terra) ...")
		nwWestX = int(self.iW * newworldWestLon)
		nwEastX = int(self.iW * newworldEastLon)
		nwNorthY = int(self.iH * 0.85)
		nwSouthY = int(self.iH * 0.52)
		nwWidth = nwEastX - nwWestX + 1
		nwHeight = nwNorthY - nwSouthY + 1
		nwWater = 61+sea; nwGrain = 1; nwRift = -1
		self.generatePlotsInRegion(nwWater,
		                           nwWidth, nwHeight,
		                           nwWestX, nwSouthY,
		                           nwGrain, archGrain,
		                           self.iVertFlags, self.iTerrainFlags,
		                           6, 6,
		                           True, 7,
		                           nwRift, False,
		                           False
		                           )
		nwsRoll = getRandNum(2, "FoR : New World South E/W - Terra PYTHON")
		nwsVar = 0.0
		if nwsRoll == 1: nwsVar = 0.05
		nwsWestX = nwWestX + int(self.iW * (0.08 - nwsVar))
		nwsEastX = nwEastX - int(self.iW * (0.03 + nwsVar))
		nwsNorthY = int(self.iH * 0.47)
		nwsSouthY = int(self.iH * 0.25)
		nwsWidth = nwsEastX - nwsWestX + 1
		nwsHeight = nwsNorthY - nwsSouthY + 1
		nwsWater = 55+sea; nwsGrain = 1; nwsRift = -1
		self.generatePlotsInRegion(nwsWater,
		                           nwsWidth, nwsHeight,
		                           nwsWestX, nwsSouthY,
		                           nwsGrain, archGrain,
		                           self.iRoundFlags, self.iTerrainFlags,
		                           6, 6,
		                           True, 5,
		                           nwsRift, False,
		                           False
		                           )
		nwpWestX = nwWestX + int(self.iW * (0.1 - nwsVar))
		nwpEastX = nwEastX - int(self.iW * (0.07 + nwsVar))
		nwpNorthY = int(self.iH * 0.3)
		nwpSouthY = int(self.iH * 0.18)
		nwpWidth = nwpEastX - nwpWestX + 1
		nwpHeight = nwpNorthY - nwpSouthY + 1
		nwpWater = 67+sea; nwpGrain = 1; nwpRift = -1
		self.generatePlotsInRegion(nwpWater,
		                           nwpWidth, nwpHeight,
		                           nwpWestX, nwpSouthY,
		                           nwpGrain, archGrain,
		                           self.iVertFlags, self.iTerrainFlags,
		                           6, 5,
		                           True, 3,
		                           nwpRift, False,
		                           False
		                           )
		twWidth = int(self.iW * 0.15)
		twWestX = nwWestX
		boreal = getRandNum(2, "FoR : New World North E/W - Terra PYTHON")
		if boreal == 1: twWestX += int(self.iW * 0.15)
		twEastX = twWestX + twWidth
		twNorthY = int(self.iH * 0.93)
		twSouthY = int(self.iH * 0.75)
		twHeight = twNorthY - twSouthY + 1
		twWater = 68+sea; twGrain = 2; twRift = -1
		self.generatePlotsInRegion(twWater,
		                           twWidth, twHeight,
		                           twWestX, twSouthY,
		                           twGrain, archGrain,
		                           self.iRoundFlags, self.iTerrainFlags,
		                           6, 5,
		                           True, 5,
		                           twRift, False,
		                           False
		                           )
		twWidth = int(thirdworldDimension * self.iW)
		twHeight = int(thirdworldDimension * self.iH)
		if boreal == 0: 
			twEastX = nwEastX
			twWestX = twEastX - twWidth
		else:
			twWestX = nwWestX
			twEastX = twWestX + twWidth
		twNorthY = int(self.iH * 0.975)
		twSouthY = int(self.iH * 0.85)
		twWater = 76+sea; twGrain = archGrain; twRift = -1
		self.generatePlotsInRegion(twWater,
		                           twWidth, twHeight,
		                           twWestX, twSouthY,
		                           twGrain, archGrain,
		                           self.iHorzFlags, self.iTerrainFlags,
		                           6, 5,
		                           True, 5,
		                           twRift, False,
		                           False
		                           )
 		nwcVar = 0.0
		if nwsRoll == 1: nwcVar = 0.04
		nwcWidth = int(self.iW * 0.06)
		nwcRoll = getRandNum(2, "FoR : Central America and Carribean Placement - Terra PYTHON")
		nwcWestX = nwWestX + int(self.iW * (0.1 + nwcVar))
		nwcEastX = nwcWestX + nwcWidth
		nwcNorthY = int(self.iH * 0.6)
		nwcSouthY = int(self.iH * 0.42)
		nwcHeight = nwcNorthY - nwcSouthY + 1
		nwcWater = 60+sea; nwcGrain = 1; nwcRift = -1
		self.generatePlotsInRegion(nwcWater,
		                           nwcWidth, nwcHeight,
		                           nwcWestX, nwcSouthY,
		                           nwcGrain, archGrain,
		                           self.iVertFlags, self.iTerrainFlags,
		                           6, 5,
		                           True, 5,
		                           nwcRift, False,
		                           False
		                           )
 		carVar = 0.0
		if nwsRoll == 1: carVar = 0.15
		twWidth = int(0.15 * self.iW)
		twEastX = nwEastX - int(carVar * self.iW)
		twWestX = twEastX - twWidth
		twNorthY = int(self.iH * 0.55)
		twSouthY = int(self.iH * 0.47)
		twHeight = twNorthY - twSouthY + 1
		twWater = 75+sea; twGrain = archGrain + 1; twRift = -1
		self.generatePlotsInRegion(twWater,
		                           twWidth, twHeight,
		                           twWestX, twSouthY,
		                           twGrain, archGrain,
		                           0, self.iTerrainFlags,
		                           6, 5,
		                           True, 3,
		                           twRift, False,
		                           False
		                           )
		scLargeWidth = int(subcontinentLargeHorz * self.iW)
		scLargeHeight = int(subcontinentLargeVert * self.iH)
		scRoll = getRandNum((eurasiaWidth - scLargeWidth), "FoR : Large Subcontinent Placement - Terra PYTHON")
		scWestX = eurasiaWestX + scRoll
		scEastX = scWestX + scLargeWidth
		scNorthY = int(self.iH * subcontinentLargeNorthLat)
		scSouthY = int(self.iH * subcontinentLargeSouthLat)
		scShape = getRandNum(4, "FoR : Large Subcontinent Shape - Terra PYTHON")
		if scShape > 1:
			scWater = 55+sea; scGrain = 1; scRift = 2
		elif scShape == 1:
			scWater = 66+sea; scGrain = 2; scRift = 2
		else:
			scWater = 77+sea; scGrain = archGrain; scRift = -1
		self.generatePlotsInRegion(scWater,
		                           scLargeWidth, scLargeHeight,
		                           scWestX, scSouthY,
		                           scGrain, archGrain,
		                           self.iRoundFlags, self.iTerrainFlags,
		                           6, 6,
		                           True, 7,
		                           scRift, False,
		                           False
		                           )
		scSmallWidth = int(subcontinentSmallDimension * self.iW)
		scSmallHeight = int(subcontinentSmallDimension * self.iH)
		endless = 1
		while endless == 1:
			scsRoll = getRandNum((eurasiaWidth - scSmallWidth), "FoR : Small Subcontinent Placement - Terra PYTHON")
			scsWestX = eurasiaWestX + scsRoll
			if abs((scsWestX + self.iW/12) - scWestX) > self.iW/8: break
		scsEastX = scsWestX + scSmallWidth
		scsNorthY = int(self.iH * subcontinentSmallNorthLat)
		scsSouthY = int(self.iH * subcontinentSmallSouthLat)
		scsShape = getRandNum(4, "FoR : Small Subcontinent Shape - Terra PYTHON")
		if scsShape == 2:
			scsWater = 55+sea; scsGrain = 1; scsRift = 2
		elif scsShape == 1:
			scsWater = 66+sea; scsGrain = 2; scsRift = 2
		else:
			scsWater = 77+sea; scsGrain = archGrain; scsRift = -1
		self.generatePlotsInRegion(scsWater,
		                           scSmallWidth, scSmallHeight,
		                           scsWestX, scsSouthY,
		                           scsGrain, archGrain,
		                           self.iHorzFlags, self.iTerrainFlags,
		                           6, 5,
		                           True, 5,
		                           scsRift, False,
		                           False
		                           )
		extras = 2 + getRandNum(3, "FoR : Number of Minor Regions - Terra PYTHON")
		for loop in range(extras):
			twWidth = int(thirdworldDimension * self.iW)
			twHeight = int(thirdworldDimension * self.iH)
			twVertRange = int(0.3 * self.iH) - twHeight
			twRoll = getRandNum((eurasiaWidth - twWidth), "FoR : Minor Region Placement - Terra PYTHON")
			twWestX = eurasiaWestX + twRoll
			twEastX = scWestX + scLargeWidth
			twVertRoll = getRandNum(twVertRange, "FoR : Minor Region Placement - Terra PYTHON")
			twNorthY = int(self.iH * thirdworldNorthLat) + twVertRoll
			twSouthY = int(self.iH * thirdworldSouthLat) + twVertRoll
			twShape = getRandNum(3, "FoR : Minor Region Shape - Terra PYTHON")
			if twShape == 2:
				twWater = 60+sea; twGrain = 1; twRift = 2
			elif twShape == 1:
				twWater = 65+sea; twGrain = 2; twRift = 2
			else:
				twWater = 70+sea; twGrain = archGrain; twRift = -1
			self.generatePlotsInRegion(twWater,
			                           twWidth, twHeight,
			                           twWestX, twSouthY,
			                           twGrain, archGrain,
			                           self.iHorzFlags, self.iTerrainFlags,
			                           6, 5,
			                           True, 5,
			                           twRift, False,
			                           False
			                           )
		return self.wholeworldPlotTypes

class RingMultilayeredFractal(CvMapGeneratorUtil.MultilayeredFractal):
	def generatePlotsInRegion(self, iWaterPercent, 
	                          iRegionWidth, iRegionHeight, 
	                          iRegionWestX, iRegionSouthY, 
	                          iRegionGrain, iRegionHillsGrain, 
	                          iRegionPlotFlags, iRegionTerrainFlags, 
	                          iRegionFracXExp = -1, iRegionFracYExp = -1, 
	                          bShift = True, iStrip = 15, 
	                          rift_grain = -1, has_center_rift = False, 
	                          invert_heights = False):
		water = iWaterPercent
		iWestX = iRegionWestX
		iSouthY = iRegionSouthY
		self.plotTypes = []
		self.plotTypes = [PlotTypes.PLOT_OCEAN] * (iRegionWidth*iRegionHeight)
		regionContinentsFrac = CyFractal()
		regionHillsFrac = CyFractal()
		regionPeaksFrac = CyFractal()
		regionContinentsFrac.fracInit(iRegionWidth, iRegionHeight, iRegionGrain, self.dice, iRegionPlotFlags, iRegionFracXExp, iRegionFracYExp)
		regionHillsFrac.fracInit(iRegionWidth, iRegionHeight, iRegionHillsGrain, self.dice, iRegionTerrainFlags, iRegionFracXExp, iRegionFracYExp)
		regionPeaksFrac.fracInit(iRegionWidth, iRegionHeight, iRegionHillsGrain+1, self.dice, iRegionTerrainFlags, iRegionFracXExp, iRegionFracYExp)
		iWaterThreshold = regionContinentsFrac.getHeightFromPercent(water)
		iHillsBottom1 = regionHillsFrac.getHeightFromPercent(max((23 - self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 0))
		iHillsTop1 = regionHillsFrac.getHeightFromPercent(min((30 + self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 100))
		iHillsBottom2 = regionHillsFrac.getHeightFromPercent(max((70 - self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 0))
		iHillsTop2 = regionHillsFrac.getHeightFromPercent(min((77 + self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 100))
		iPeakThreshold = regionPeaksFrac.getHeightFromPercent(self.gc.getClimateInfo(self.map.getClimate()).getPeakPercent())
		for x in range(iRegionWidth):
			for y in range(iRegionHeight):
				i = y*iRegionWidth + x
				val = regionContinentsFrac.getHeight(x,y)
				if val <= iWaterThreshold: pass
				else:
					hillVal = regionHillsFrac.getHeight(x,y)
					if ((hillVal >= iHillsBottom1 and hillVal <= iHillsTop1) or (hillVal >= iHillsBottom2 and hillVal <= iHillsTop2)):
						peakVal = regionPeaksFrac.getHeight(x,y)
						if (peakVal <= iPeakThreshold):
							self.plotTypes[i] = PlotTypes.PLOT_PEAK
						else:
							self.plotTypes[i] = PlotTypes.PLOT_HILLS
					else:
						self.plotTypes[i] = PlotTypes.PLOT_LAND
		if bShift:
			self.shiftRegionPlots(iRegionWidth, iRegionHeight, iStrip)
		for x in range(iRegionWidth):
			wholeworldX = x + iWestX
			for y in range(iRegionHeight):
				i = y*iRegionWidth + x
				if self.plotTypes[i] == PlotTypes.PLOT_OCEAN: continue
				wholeworldY = y + iSouthY
				iWorld = wholeworldY*self.iW + wholeworldX
				self.wholeworldPlotTypes[iWorld] = self.plotTypes[i]
		return

	def generatePlotsByRegion(self, ring_type):
		iPlayers = self.gc.getGame().countCivPlayersEverAlive()
		userInputAreaType = cmo[1]
		area_grain = 3 - userInputAreaType
		userInputBufferType = cmo[2]
		buffer_one = [0, 58, 64, 70]
		bufWater = buffer_one[userInputBufferType]
		grainType = userInputBufferType
		sea = self.gc.getSeaLevelInfo(self.map.getSeaLevel()).getSeaLevelChange()
		sea = min(sea, 5)
		sea = max(sea, -5)
		bufWater += sea
		if ring_type == 1 and iPlayers < 11 and iPlayers > 1:
			global buffer_data
			for buffer_loop in range(iPlayers):
				[bufWestX, bufEastX, bufSouthY, bufNorthY] = buffer_data[buffer_loop]
				if grainType == 0:
					thisBuffer = 1 + getRandNum(3, "FoR : Random Buffer Type - Ring PYTHON")
					bufWater = sea + buffer_one[thisBuffer]
					bufGrain = thisBuffer + 1
				else:
					bufGrain = grainType + 1
				bufWidth = bufEastX - bufWestX + 1
				bufHeight = bufNorthY - bufSouthY + 1
				self.generatePlotsInRegion(bufWater,
				                           bufWidth, bufHeight,
				                           bufWestX, bufSouthY,
				                           bufGrain, 3,
				                           self.iRoundFlags, self.iTerrainFlags,
				                           6, 6,
				                           True, 3,
				                           -1, False,
				                           False
				                           )
		else: pass
		global region_data
		for region_loop in range(iPlayers):
			[regWestX, regEastX, regSouthY, regNorthY] = region_data[region_loop]
			regWidth = regEastX - regWestX + 1
			regHeight = regNorthY - regSouthY + 1
			self.generatePlotsInRegion(55 + sea,
			                           regWidth, regHeight,
			                           regWestX, regSouthY,
			                           area_grain, 4,
			                           self.iRoundFlags, self.iTerrainFlags,
			                           6, 6,
			                           True, 3,
			                           -1, False,
			                           False
			                           )
			coreWestX = regWestX + int(regWidth * 0.25)
			coreEastX = regEastX - int(regWidth * 0.25)
			coreSouthY = regSouthY + int(regHeight * 0.25)
			coreNorthY = regNorthY - int(regHeight * 0.25)
			coreWidth = coreEastX - coreWestX + 1
			coreHeight = coreNorthY - coreSouthY + 1
			self.generatePlotsInRegion(65,
			                           coreWidth, coreHeight,
			                           coreWestX, coreSouthY,
			                           1, 3,
			                           self.iHorzFlags, self.iTerrainFlags,
			                           5, 5,
			                           True, 3,
			                           -1, False,
			                           False
			                           )
		global center_data
		[cenWestX, cenEastX, cenSouthY, cenNorthY] = center_data
		cenWidth = cenEastX - cenWestX + 1
		cenHeight = cenNorthY - cenSouthY + 1
		if grainType == 0:
			thisBuffer = 1 + getRandNum(3, "FoR : Random Buffer Type - Ring PYTHON")
			bufWater = sea + buffer_one[thisBuffer]
			bufGrain = thisBuffer + 1
		else:
			bufGrain = grainType + 1
		self.generatePlotsInRegion(bufWater,
		                           cenWidth, cenHeight,
		                           cenWestX, cenSouthY,
		                           bufGrain, 4,
		                           self.iRoundFlags, self.iTerrainFlags,
		                           -1, -1,
		                           True, 5,
		                           -1, False,
		                           False
		                           )
		global wheel_data
		linewidth = 1 + cmo[3]
		iWH = self.iW * self.iH
		offsetstart = 0 - int(linewidth/2)
		offsetrange = range(offsetstart, offsetstart + linewidth)
		for wheel_loop in range(len(wheel_data) - 1):
			[startx, starty] = wheel_data[wheel_loop]
			[endx, endy] = wheel_data[wheel_loop + 1]
			if abs(endy-starty) < abs(endx-startx):
				if startx > endx:
					startx, starty, endx, endy = endx, endy, startx, starty
				dx = endx-startx
				dy = endy-starty
				if dx == 0 or dy == 0:
					slope = 0
				else:
					slope = float(dy)/float(dx)
				y = starty
				for x in range(startx, endx+1):
					for offset in offsetrange:
						if map.isPlot(x, int(round(y+offset))):
							i = map.plotNum(x, int(round(y+offset)))
							self.wholeworldPlotTypes[i] = PlotTypes.PLOT_LAND
					y += slope
			else:
				if starty > endy:
					startx, starty, endx, endy = endx, endy, startx, starty
				dx, dy = endx-startx, endy-starty
				if dx == 0 or dy == 0:
					slope = 0
				else:
					slope = float(dx)/float(dy)
				x = startx
				for y in range(starty, endy+1):
					for offset in offsetrange:
						if map.isPlot(int(round(x+offset)), y):
							i = map.plotNum(int(round(x+offset)), y)
							self.wholeworldPlotTypes[i] = PlotTypes.PLOT_LAND
					x += slope
		return self.wholeworldPlotTypes

def generatePangaeaPlotTypes():
	global pangaea_type
	mapgen = CyMapGenerator()
	hinted_world = PangaeaHintedWorld()
	fractal_world = PangaeaMultilayeredFractal()
	userInputLandmass = cmo[0]
	if userInputLandmass == 3:
		typeRoll = getRandNum(3, "FoR : PlotGen Chooser - Pangaea PYTHON")
		cohesive = False
		while not cohesive:
			plotTypes = []
			if typeRoll == 2:
				plotTypes = hinted_world.generateAndysHintedPangaea()
			else:
				plotTypes = hinted_world.generateSorensHintedPangaea()
			mapgen.setPlotTypes(plotTypes)
			biggest_area = map.findBiggestArea(false)
			iTotalLandPlots = map.getLandPlots()
			iBiggestAreaPlots = biggest_area.getNumTiles()
			if iBiggestAreaPlots >= 0.9 * iTotalLandPlots:
				cohesive = True
		return plotTypes
	elif userInputLandmass == 2:
		typeRoll = getRandNum(3, "FoR : PlotGen Chooser - Pangaea PYTHON")
		if typeRoll == 1:
			pangaea_type = 1
		else:
			pangaea_type = 2
		return fractal_world.generatePlotsByRegion(pangaea_type)
	elif userInputLandmass == 1:
		pangaea_type = 0
		return fractal_world.generatePlotsByRegion(pangaea_type)
	else:
		global terrainRoll
		terrainRoll = getRandNum(10, "FoR : PlotGen Chooser - Pangaea PYTHON")
		if terrainRoll > 6:
			cohesive = False
			while not cohesive:
				plotTypes = []
				if terrainRoll == 9:
					plotTypes = hinted_world.generateAndysHintedPangaea()
				else:
					plotTypes = hinted_world.generateSorensHintedPangaea()
				mapgen.setPlotTypes(plotTypes)
				biggest_area = map.findBiggestArea(false)
				iTotalLandPlots = map.getLandPlots()
				iBiggestAreaPlots = biggest_area.getNumTiles()
				if iBiggestAreaPlots >= 0.9 * iTotalLandPlots:
					cohesive = True
			return plotTypes
		elif terrainRoll == 5 or terrainRoll == 6:
			pangaea_type = 2
			return fractal_world.generatePlotsByRegion(pangaea_type)
		elif terrainRoll == 4:
			pangaea_type = 1
			return fractal_world.generatePlotsByRegion(pangaea_type)
		else:
			pangaea_type = 0
			return fractal_world.generatePlotsByRegion(pangaea_type)

class PangaeaHintedWorld:
	def generateSorensHintedPangaea(self):
		global hinted_world
		hinted_world = HintedWorld(8,4)
		for y in range(hinted_world.h):
			for x in range(hinted_world.w):
				if x in (0, hinted_world.w-1) or y in (0, hinted_world.h-1):
					hinted_world.setValue(x,y,0)
				else:
					hinted_world.setValue(x,y,200 + getRandNum(55, "FoR : Plot Types - Pangaea PYTHON"))
		hinted_world.setValue(1, 1 + getRandNum(3, "FoR : Plot Types - Pangaea PYTHON"), getRandNum(64, "FoR : Plot Types - Pangaea PYTHON"))
		hinted_world.setValue(2 + getRandNum(2, "FoR : Plot Types - Pangaea PYTHON"), 1 + getRandNum(3, "FoR : Plot Types - Pangaea PYTHON"), getRandNum(64, "FoR : Plot Types - Pangaea PYTHON"))
		hinted_world.setValue(4 + getRandNum(2, "FoR : Plot Types - Pangaea PYTHON"), 1 + getRandNum(3, "FoR : Plot Types - Pangaea PYTHON"), getRandNum(64, "FoR : Plot Types - Pangaea PYTHON"))
		hinted_world.setValue(6, 1 + getRandNum(3, "FoR : Plot Types - Pangaea PYTHON"), getRandNum(64, "FoR : Plot Types - Pangaea PYTHON"))
		if (getRandNum(2, "FoR : Plot Types - Pangaea PYTHON") == 0):
			hinted_world.setValue(2, 1 + getRandNum(3, "FoR : Plot Types - Pangaea PYTHON"), getRandNum(64, "FoR : Plot Types - Pangaea PYTHON"))
		else:
			hinted_world.setValue(5, 1 + getRandNum(3, "FoR : Plot Types - Pangaea PYTHON"), getRandNum(64, "FoR : Plot Types - Pangaea PYTHON"))
		hinted_world.buildAllContinents()
		return hinted_world.generatePlotTypes(shift_plot_types=True)
	
	def generateAndysHintedPangaea(self):
		global hinted_world
		hinted_world = HintedWorld(16,8)
		numBlocks = hinted_world.w * hinted_world.h
		numBlocksLand = int(numBlocks*0.33)
		cont = hinted_world.addContinent(numBlocksLand,getRandNum(5, "FoR : Generate Plot Types PYTHON")+4,getRandNum(3, "FoR : Generate Plot Types PYTHON")+2)
		if not cont:
			return self.generateSorensHintedPangaea()
		else:		
			for x in range(hinted_world.w):
				for y in (0, hinted_world.h - 1):
					hinted_world.setValue(x,y, 1)
			hinted_world.buildAllContinents()
			return hinted_world.generatePlotTypes(shift_plot_types=True)

class PangaeaMultilayeredFractal(CvMapGeneratorUtil.MultilayeredFractal):
	def generatePlotsByRegion(self, pangaea_type):
		sizekey = self.map.getWorldSize()
		sizevalues = {
			WorldSizeTypes.WORLDSIZE_DUEL:      3,
			WorldSizeTypes.WORLDSIZE_TINY:      3,
			WorldSizeTypes.WORLDSIZE_SMALL:     4,
			WorldSizeTypes.WORLDSIZE_STANDARD:  4,
			WorldSizeTypes.WORLDSIZE_LARGE:     4,
			WorldSizeTypes.WORLDSIZE_HUGE:      5
			}
		if int(sizekey) in sizevalues.keys() :
                        grain = sizevalues[sizekey]
                else :
                        grain = 7
		sea = self.gc.getSeaLevelInfo(self.map.getSeaLevel()).getSeaLevelChange()
		sea = min(sea, 5)
		sea = max(sea, -5)
		mainWestLon = 0.2
		mainEastLon = 0.8
		mainSouthLat = 0.2
		mainNorthLat = 0.8
		subcontinentDimension = 0.4
		bSouthwardShift = False
		if pangaea_type == 2:
			numSubcontinents = 3
			global polarShiftRoll
			polarShiftRoll = getRandNum(2, "FoR : Shift - Pangaea PYTHON")
			if polarShiftRoll == 1:
				mainNorthLat += 0.175
				mainSouthLat += 0.175
				scValues = [[0.05, 0.375, 0.2, 0.0, 0],
				            [0.55, 0.375, 0.2, 0.0, 0],
				            [0.1, 0.225, 0.0, 0.15, 0],
				            [0.3, 0.225, 0.0, 0.15, 0]
				            ]
			else:
				mainNorthLat -= 0.175
				mainSouthLat -= 0.175
				scValues = [[0.05, 0.025, 0.2, 0.0, 0],
				            [0.55, 0.025, 0.2, 0.0, 0],
				            [0.1, 0.375, 0.0, 0.15, 0],
				            [0.3, 0.375, 0.0, 0.15, 0]
				            ]
		elif pangaea_type == 1:
			equRoll = getRandNum(4, "FoR : Subcontinents - Pangaea PYTHON")
			if equRoll == 3: equRoll = 1
			numSubcontinents = 2 + equRoll
			scValues = [[0.05, 0.2, 0.2, 0.0, 0.0],
			            [0.55, 0.2, 0.2, 0.0, 0.0],
			            [0.2, 0.05, 0.0, 0.2, 0.0],
			            [0.2, 0.55, 0.0, 0.2, 0.0]
			            ]
		else:
			subcontinentDimension = 0.3
			global shiftRoll
			shiftRoll = getRandNum(2, "FoR : Shift - Pangaea PYTHON")
			if shiftRoll == 1:
				mainNorthLat += 0.075
				mainSouthLat += 0.075
			else:
				mainNorthLat -= 0.075
				mainSouthLat -= 0.075
				bSouthwardShift = True
			numSubcontinents = 4 + getRandNum(3, "FoR : Subcontinents - Pangaea PYTHON")
			scValues = [[0.05, 0.575, 0.0, 0.0, 0.15],
			            [0.05, 0.275, 0.0, 0.0, 0.15],
			            [0.2, 0.175, 0.0, 0.0, 0.15],
			            [0.5, 0.175, 0.0, 0.0, 0.15],
			            [0.65, 0.575, 0.0, 0.0, 0.15],
			            [0.65, 0.275, 0.0, 0.0, 0.15],
			            [0.2, 0.675, 0.0, 0.0, 0.15],
			            [0.5, 0.675, 0.0, 0.0, 0.15]
			            ]
		mainWestX = int(self.iW * mainWestLon)
		mainEastX = int(self.iW * mainEastLon)
		mainNorthY = int(self.iH * mainNorthLat)
		mainSouthY = int(self.iH * mainSouthLat)
		mainWidth = mainEastX - mainWestX + 1
		mainHeight = mainNorthY - mainSouthY + 1
		mainWater = 55+sea
		self.generatePlotsInRegion(mainWater,
		                           mainWidth, mainHeight,
		                           mainWestX, mainSouthY,
		                           2, grain,
		                           self.iHorzFlags, self.iTerrainFlags,
		                           -1, -1,
		                           True, 15,
		                           2, False,
		                           False
		                           )
		second_layerHeight = mainHeight/2
		second_layerWestX = mainWestX + mainWidth/10
		second_layerEastX = mainEastX - mainWidth/10
		second_layerWidth = second_layerEastX - second_layerWestX + 1
		second_layerNorthY = mainNorthY - mainHeight/4
		second_layerSouthY = mainSouthY + mainHeight/4
		second_layerWater = 60+sea
		self.generatePlotsInRegion(second_layerWater,
		                           second_layerWidth, second_layerHeight,
		                           second_layerWestX, second_layerSouthY,
		                           1, grain,
		                           self.iHorzFlags, self.iTerrainFlags,
		                           -1, -1,
		                           True, 15,
		                           2, False,
		                           False
		                           )
		while numSubcontinents > 0:
			if len(scValues) > 1:
				scIndex = getRandNum(len(scValues), "FoR : Subcontinent Placement - Pangaea PYTHON")
			else:
				scIndex = 0
			[scWestLon, scSouthLat, scVertRange, scHorzRange, scSouthShift] = scValues[scIndex]
			scWidth = int(subcontinentDimension * self.iW)
			scHeight = int(subcontinentDimension * self.iH)
			scHorzShift = 0; scVertShift = 0
			if scHorzRange > 0.0:
				scHorzShift = getRandNum(int(self.iW * scHorzRange), "FoR : Subcontinent Variance - Terra PYTHON")
			if scVertRange > 0.0:
				scVertShift = getRandNum(int(self.iW * scVertRange), "FoR : Subcontinent Variance - Terra PYTHON")
			scWestX = int(self.iW * scWestLon) + scHorzShift
			scEastX = scWestX + scWidth
			if scEastX >= self.iW:
				while scEastX >= self.iW:
					scWidth -= 1
					scEastX = scWestX + scWidth
			scSouthY = int(self.iH * scSouthLat) + scVertShift
			if bSouthwardShift:
				scSouthY -= int(self.iH * scSouthShift)
			scNorthY = scSouthY + scHeight
			if scNorthY >= self.iH:
				while scNorthY >= self.iH:
					scHeight -= 1
					scNorthY = scSouthY + scHeight
			scShape = getRandNum(5, "FoR : Subcontinent Shape - Terra PYTHON")
			if scShape > 1:
				scWater = 55+sea; scGrain = 1; scRift = -1
			elif scShape == 1:
				scWater = 66+sea; scGrain = 2; scRift = 2
			else:
				scWater = 77+sea; scGrain = grain; scRift = -1
			self.generatePlotsInRegion(scWater,
			                           scWidth, scHeight,
			                           scWestX, scSouthY,
			                           scGrain, grain,
			                           self.iRoundFlags, self.iTerrainFlags,
			                           6, 6,
			                           True, 7,
			                           scRift, False,
			                           False
			                           )
			del scValues[scIndex]
			numSubcontinents -= 1
		return self.wholeworldPlotTypes

def generateMazePlotTypes():
	userInputMazeWidth = cmo[0]
	multiplier = 1 + userInputMazeWidth
	if userInputMazeWidth > 1:
		extraPeaks = 5 - userInputMazeWidth
	else:
		extraPeaks = 0 
	sizekey = map.getWorldSize()
	grainvalues = {
		WorldSizeTypes.WORLDSIZE_DUEL:		3,
		WorldSizeTypes.WORLDSIZE_TINY:		3,
		WorldSizeTypes.WORLDSIZE_SMALL:		4,
		WorldSizeTypes.WORLDSIZE_STANDARD:	4,
		WorldSizeTypes.WORLDSIZE_LARGE:		5,
		WorldSizeTypes.WORLDSIZE_HUGE:		6
		}
	if int(sizekey) in grainvalues.keys() :
                grain_amount = grainvalues[sizekey]
        else :
                grain_amount = 8
	hillsFrac = CyFractal()
	peaksFrac = CyFractal()
	hillsFrac.fracInit(iW, iH, grain_amount, dice, 0, -1, -1)
	peaksFrac.fracInit(iW, iH, grain_amount + 1, dice, 0, -1, -1)
	iHillsBottom1 = hillsFrac.getHeightFromPercent(max((25 - gc.getClimateInfo(map.getClimate()).getHillRange()), 0))
	iHillsTop1 = hillsFrac.getHeightFromPercent(min((25 + gc.getClimateInfo(map.getClimate()).getHillRange()), 100))
	iHillsBottom2 = hillsFrac.getHeightFromPercent(max((75 - gc.getClimateInfo(map.getClimate()).getHillRange()), 0))
	iHillsTop2 = hillsFrac.getHeightFromPercent(min((75 + gc.getClimateInfo(map.getClimate()).getHillRange()), 100))
	iPeakThreshold = peaksFrac.getHeightFromPercent((10 * extraPeaks) + gc.getClimateInfo(map.getClimate()).getPeakPercent())
	mazeW = iW/(2 * multiplier)
	mazeH = iH/(2 * multiplier)
	plotTypes = [PlotTypes.PLOT_OCEAN] * (iW*iH)
	matrix = [False] * (mazeW*mazeH)
	path = []
	remainingSegments = mazeW*mazeH - 1
	iX = getRandNum(mazeW, "FoR : Starting X - Maze PYTHON")
	iY = getRandNum(mazeH, "FoR : Starting Y - Maze PYTHON")
	directions = 4
	if iX == 0 or iX == mazeW - 1:
		directions -= 1
	if iY == 0 or iY == mazeH - 1:
		directions -= 1
	x = iX * 2 * multiplier
	y = iY * 2 * multiplier
	i = y*iW + x
	hillVal = hillsFrac.getHeight(x,y)
	if ((hillVal >= iHillsBottom1 and hillVal <= iHillsTop1) or (hillVal >= iHillsBottom2 and hillVal <= iHillsTop2)):
		plotTypes[i] = PlotTypes.PLOT_HILLS
	else:
		plotTypes[i] = PlotTypes.PLOT_LAND
	if multiplier == 1: pass
	else:
		for mazeX in range(x, x+multiplier):
			for mazeY in range(y, y+multiplier):
				i = mazeY*iW + mazeX
				hillVal = hillsFrac.getHeight(mazeX,mazeY)
				if ((hillVal >= iHillsBottom1 and hillVal <= iHillsTop1) or (hillVal >= iHillsBottom2 and hillVal <= iHillsTop2)):
					peakVal = peaksFrac.getHeight(mazeX,mazeY)
					if (peakVal <= iPeakThreshold):
						plotTypes[i] = PlotTypes.PLOT_PEAK
					else:
						plotTypes[i] = PlotTypes.PLOT_HILLS
				else:
					plotTypes[i] = PlotTypes.PLOT_LAND
	while remainingSegments:
		remainingSegments -= 1
		matrixIndex = mazeW*iY + iX
		matrix[matrixIndex] = True
		if iY == mazeH - 1:
			north = 0
		elif matrix[matrixIndex + mazeW] == True:
			north = 0
		else:
			north = 1
		if iY == 0:
			south = 0
		elif matrix[matrixIndex - mazeW] == True:
			south = 0
		else:
			south = 1
		if iX == mazeW - 1:
			east = 0
		elif matrix[matrixIndex + 1] == True:
			east = 0
		else:
			east = 1
		if iX == 0:
			west = 0
		elif matrix[matrixIndex - 1] == True:
			west = 0
		else:
			west = 1
		directions = north + south + east + west
		if directions > 1:
			path.append([iX, iY])
		while directions < 1:
			vertexRoll = getRandNum(len(path), "FoR : Pathfinding - Maze PYTHON")
			[iX, iY] = path[vertexRoll]
			matrixIndex = mazeW*iY + iX
			if iY == mazeH - 1:
				north = 0
			elif matrix[matrixIndex + mazeW] == True:
				north = 0
			else:
				north = 1
			if iY == 0:
				south = 0
			elif matrix[matrixIndex - mazeW] == True:
				south = 0
			else:
				south = 1
			if iX == mazeW - 1:
				east = 0
			elif matrix[matrixIndex + 1] == True:
				east = 0
			else:
				east = 1
			if iX == 0:
				west = 0
			elif matrix[matrixIndex - 1] == True:
				west = 0
			else:
				west = 1
			directions = north + south + east + west
			if directions < 2:
				del path[vertexRoll]
		choose = []
		if north: choose.append([0, 1])
		if south: choose.append([0, -1])
		if east: choose.append([1, 0])
		if west: choose.append([-1, 0])
		dir = getRandNum(len(choose), "FoR : Segment Direction - Maze PYTHON")
		[xPlus, yPlus] = choose[dir]
		for loop in range(1, 3):
			x = (iX * 2 * multiplier) + (multiplier * xPlus * loop)
			y = (iY * 2 * multiplier) + (multiplier * yPlus * loop)
			i = y*iW + x
			hillVal = hillsFrac.getHeight(x,y)
			if ((hillVal >= iHillsBottom1 and hillVal <= iHillsTop1) or (hillVal >= iHillsBottom2 and hillVal <= iHillsTop2)):
				plotTypes[i] = PlotTypes.PLOT_HILLS
			else:
				plotTypes[i] = PlotTypes.PLOT_LAND
			if multiplier == 1: pass
			else:
				for mazeX in range(x, x+multiplier):
					for mazeY in range(y, y+multiplier):
						i = mazeY*iW + mazeX
						hillVal = hillsFrac.getHeight(mazeX,mazeY)
						if ((hillVal >= iHillsBottom1 and hillVal <= iHillsTop1) or (hillVal >= iHillsBottom2 and hillVal <= iHillsTop2)):
							peakVal = peaksFrac.getHeight(mazeX,mazeY)
							if (peakVal <= iPeakThreshold):
								plotTypes[i] = PlotTypes.PLOT_PEAK
							else:
								plotTypes[i] = PlotTypes.PLOT_HILLS
						else:
							plotTypes[i] = PlotTypes.PLOT_LAND
		iX += xPlus
		iY += yPlus
	return plotTypes

class LakesFractalWorld(CvMapGeneratorUtil.FractalWorld):
	def generatePlotTypes(self, water_percent=9, shift_plot_types=True, 
	                      grain_amount=3):
		self.checkForOverrideDefaultUserInputVariances()
		self.hillsFrac.fracInit(self.iNumPlotsX, self.iNumPlotsY, grain_amount, self.mapRand, 0, self.fracXExp, self.fracYExp)
		self.peaksFrac.fracInit(self.iNumPlotsX, self.iNumPlotsY, grain_amount+1, self.mapRand, 0, self.fracXExp, self.fracYExp)
		if water_percent == 9 :
                        water_percent += self.seaLevelChange
                        water_percent = min(water_percent, 14)
                        water_percent = max(water_percent, 7)
		iWaterThreshold = self.continentsFrac.getHeightFromPercent(water_percent)
		iHillsBottom1 = self.hillsFrac.getHeightFromPercent(max((self.hillGroupOneBase - self.hillGroupOneRange), 0))
		iHillsTop1 = self.hillsFrac.getHeightFromPercent(min((self.hillGroupOneBase + self.hillGroupOneRange), 100))
		iHillsBottom2 = self.hillsFrac.getHeightFromPercent(max((self.hillGroupTwoBase - self.hillGroupTwoRange), 0))
		iHillsTop2 = self.hillsFrac.getHeightFromPercent(min((self.hillGroupTwoBase + self.hillGroupTwoRange), 100))
		iPeakThreshold = self.peaksFrac.getHeightFromPercent(self.peakPercent)
		for x in range(self.iNumPlotsX):
			for y in range(self.iNumPlotsY):
				i = y*self.iNumPlotsX + x
				if y == 0 or y == self.iNumPlotsY - 1:
					self.plotTypes[i] = PlotTypes.PLOT_OCEAN
					continue
				val = self.continentsFrac.getHeight(x,y)
				if val <= iWaterThreshold:
					self.plotTypes[i] = PlotTypes.PLOT_OCEAN
				else:
					hillVal = self.hillsFrac.getHeight(x,y)
					if ((hillVal >= iHillsBottom1 and hillVal <= iHillsTop1) or (hillVal >= iHillsBottom2 and hillVal <= iHillsTop2)):
						peakVal = self.peaksFrac.getHeight(x,y)
						if (peakVal <= iPeakThreshold):
							self.plotTypes[i] = PlotTypes.PLOT_PEAK
						else:
							self.plotTypes[i] = PlotTypes.PLOT_HILLS
					else:
						self.plotTypes[i] = PlotTypes.PLOT_LAND
		if shift_plot_types:
			self.shiftPlotTypes()
		return self.plotTypes

class IslandsMultilayeredFractal(CvMapGeneratorUtil.MultilayeredFractal):
	def generatePlotsByRegion(self):
		iPlayers = self.gc.getGame().countCivPlayersEverAlive()
		userInputTinyIslands = cmo[1]
		sea = self.gc.getSeaLevelInfo(self.map.getSeaLevel()).getSeaLevelChange()
		sea = min(sea, 5)
		sea = max(sea, -5)
		if userInputTinyIslands == 0: pass
		else:
			tiny_one = [[-1, -1], [92, 6], [91, 5], [85, 5]]
			[tinyWater, tinyGrain] = tiny_one[userInputTinyIslands]
			self.generatePlotsInRegion(tinyWater,
			                           self.iW, self.iH,
			                           0, 0,
			                           tinyGrain, 4,
			                           self.iHorzFlags, self.iTerrainFlags,
			                           7, 6,
			                           True, 15,
			                           -1, False,
			                           False
			                           )
		global iExtras
		global region_coords
		global regions_in_use
		global remaining_regions
		for region_loop in range(iPlayers + iExtras):
			region_roll = getRandNum(len(remaining_regions), "FoR : Extra Islands - Islands PYTHON")
			thisRegion = remaining_regions[region_roll]
			regions_in_use.append(thisRegion)
			del remaining_regions[region_roll]
			[fWestLon, fEastLon, fSouthLat, fNorthLat] = region_coords[thisRegion]
			iWestX = int(self.iW * fWestLon)
			iEastX = int(self.iW * fEastLon) - 1
			iSouthY = int(self.iH * fSouthLat)
			iNorthY = int(self.iH * fNorthLat) -1
			iWidth = iEastX - iWestX + 1
			iHeight = iNorthY - iSouthY + 1
			thisIslandPattern = getRandNum(4, "FoR : Island Pattern - Islands PYTHON")
			if thisIslandPattern == 1:
				iOffSetX = getRandNum(int(iWidth * 0.2) + 1, "FoR : Island Offset - Islands PYTHON")
				iOffSetY = getRandNum(int(iHeight * 0.2) + 1, "FoR : Island Offset - Islands PYTHON")
				regWestX = iWestX + iOffSetX
				regSouthY = iSouthY + iOffSetY
				regWidth = int(iWidth * 0.8)
				regHeight = int(iHeight * 0.8)
			elif thisIslandPattern == 2:
				iOffSetX = getRandNum(int(iWidth * 0.37) + 1, "FoR : Island Offset - Islands PYTHON")
				iOffSetY = 0
				regWestX = iWestX + iOffSetX
				regSouthY = iSouthY + iOffSetY
				regWidth = int(iWidth * 0.63)
				regHeight = iHeight
			elif thisIslandPattern == 3:
				iOffSetX = 0
				iOffSetY = getRandNum(int(iHeight * 0.37) + 1, "FoR : Island Offset - Islands PYTHON")
				regWestX = iWestX + iOffSetX
				regSouthY = iSouthY + iOffSetY
				regWidth = iWidth
				regHeight = int(iHeight * 0.63)
			else:
				iOffSetX = int(iWidth * 0.1)
				iOffSetY = int(iHeight * 0.1)
				regWestX = iWestX + iOffSetX
				regSouthY = iSouthY + iOffSetY
				regWidth = int(iWidth * 0.8)
				regHeight = int(iHeight * 0.8)
			shore_grain = 1 + getRandNum(3, "FoR : Random Shoreline Type - Islands PYTHON")
			self.generatePlotsInRegion(55 + sea,
			                           regWidth, regHeight,
			                           regWestX, regSouthY,
			                           shore_grain, 4,
			                           self.iRoundFlags, self.iTerrainFlags,
			                           6, 6,
			                           True, 3,
			                           -1, False,
			                           False
			                           )
			coreWestX = regWestX + int(regWidth * 0.25)
			coreEastX = coreWestX + int(regWidth * 0.5)
			coreSouthY = regSouthY + int(regHeight * 0.25)
			coreNorthY = coreSouthY + int(regHeight * 0.5)
			coreWidth = coreEastX - coreWestX + 1
			coreHeight = coreNorthY - coreSouthY + 1
			self.generatePlotsInRegion(65,
			                           coreWidth, coreHeight,
			                           coreWestX, coreSouthY,
			                           1, 3,
			                           self.iHorzFlags, self.iTerrainFlags,
			                           5, 5,
			                           True, 3,
			                           -1, False,
			                           False
			                           )
		return self.wholeworldPlotTypes

class ISFractalWorld(CvMapGeneratorUtil.FractalWorld):
	def generatePlotTypes(self, water_percent=78, shift_plot_types=True, 
	                      grain_amount=3):
		self.checkForOverrideDefaultUserInputVariances()
		self.hillsFrac.fracInit(self.iNumPlotsX, self.iNumPlotsY, grain_amount, self.mapRand, 0, self.fracXExp, self.fracYExp)
		self.peaksFrac.fracInit(self.iNumPlotsX, self.iNumPlotsY, grain_amount+1, self.mapRand, 0, self.fracXExp, self.fracYExp)
		water_percent += self.seaLevelChange
		water_percent = min(water_percent, self.seaLevelMax)
		water_percent = max(water_percent, self.seaLevelMin)
		iWaterThreshold = self.continentsFrac.getHeightFromPercent(water_percent)
		iHillsBottom1 = self.hillsFrac.getHeightFromPercent(max((self.hillGroupOneBase - self.hillGroupOneRange), 0))
		iHillsTop1 = self.hillsFrac.getHeightFromPercent(min((self.hillGroupOneBase + self.hillGroupOneRange), 100))
		iHillsBottom2 = self.hillsFrac.getHeightFromPercent(max((self.hillGroupTwoBase - self.hillGroupTwoRange), 0))
		iHillsTop2 = self.hillsFrac.getHeightFromPercent(min((self.hillGroupTwoBase + self.hillGroupTwoRange), 100))
		iPeakThreshold = self.peaksFrac.getHeightFromPercent(self.peakPercent)
		for x in range(self.iNumPlotsX):
			for y in range(self.iNumPlotsY):
				i = y*self.iNumPlotsX + x
				val = self.continentsFrac.getHeight(x,y)
				if val <= iWaterThreshold:
					self.plotTypes[i] = PlotTypes.PLOT_OCEAN
				else:
					hillVal = self.hillsFrac.getHeight(x,y)
					if ((hillVal >= iHillsBottom1 and hillVal <= iHillsTop1) or (hillVal >= iHillsBottom2 and hillVal <= iHillsTop2)):
						peakVal = self.peaksFrac.getHeight(x,y)
						if (peakVal <= iPeakThreshold):
							self.plotTypes[i] = PlotTypes.PLOT_PEAK
						else:
							self.plotTypes[i] = PlotTypes.PLOT_HILLS
					else:
						self.plotTypes[i] = PlotTypes.PLOT_LAND
		if shift_plot_types:
			self.shiftPlotTypes()
		return self.plotTypes

class ISHintedWorld(CvMapGeneratorUtil.HintedWorld, ISFractalWorld):
	def __doInitFractal(self):
		self.shiftHintsToMap()
		size = len(self.data)
		minExp = min(self.fracXExp, self.fracYExp)
		iGrain = None
		for i in range(minExp):
			width = (1 << (self.fracXExp - minExp + i))
			height = (1 << (self.fracYExp - minExp + i))
			if not self.iFlags & CyFractal.FracVals.FRAC_WRAP_X:
				width += 1
			if not self.iFlags & CyFractal.FracVals.FRAC_WRAP_Y:
				height += 1
			if size == width*height:
				iGrain = i
		assert(iGrain != None)
		iFlags = self.map.getMapFractalFlags()
		self.continentsFrac.fracInitHints(self.iNumPlotsX, self.iNumPlotsY, iGrain, self.mapRand, iFlags, self.data, self.fracXExp, self.fracYExp)

	def generatePlotTypes(self, water_percent=-1, shift_plot_types=False):
		for i in range(len(self.data)):
			if self.data[i] == None:
				self.data[i] = getRandNum(48, "FoR : Generate Plot Types PYTHON")
		self.__doInitFractal()
		if (water_percent == -1):
			numPlots = len(self.data)
			numWaterPlots = 0
			for val in self.data:
				if val < 192:
					numWaterPlots += 1
			water_percent = int(100*numWaterPlots/numPlots)
		return ISFractalWorld.generatePlotTypes(self, water_percent, shift_plot_types)

class HubMultilayeredFractal(CvMapGeneratorUtil.MultilayeredFractal):
	def generateCenter(self, iWaterPercent, 
	                   iRegionWidth, iRegionHeight, 
	                   iRegionWestX, iRegionSouthY, 
	                   iRegionGrain, iRegionHillsGrain, 
	                   iRegionPlotFlags, iRegionTerrainFlags, 
	                   iRegionFracXExp = -1, iRegionFracYExp = -1, 
	                   bShift = True, iStrip = 15, 
	                   rift_grain = -1, has_center_rift = False, 
	                   invert_heights = False):
		water = iWaterPercent
		iWestX = iRegionWestX
		iSouthY = iRegionSouthY
		self.plotTypes = []
		self.plotTypes = [PlotTypes.PLOT_OCEAN] * (iRegionWidth*iRegionHeight)
		regionContinentsFrac = CyFractal()
		regionHillsFrac = CyFractal()
		regionContinentsFrac.fracInit(iRegionWidth, iRegionHeight, iRegionGrain, self.dice, iRegionPlotFlags, iRegionFracXExp, iRegionFracYExp)
		regionHillsFrac.fracInit(iRegionWidth, iRegionHeight, iRegionHillsGrain, self.dice, iRegionTerrainFlags, iRegionFracXExp, iRegionFracYExp)
		iWaterThreshold = regionContinentsFrac.getHeightFromPercent(water)
		iHillsBottom1 = regionHillsFrac.getHeightFromPercent(max((20 - self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 0))
		iHillsTop1 = regionHillsFrac.getHeightFromPercent(min((30 + self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 100))
		iHillsBottom2 = regionHillsFrac.getHeightFromPercent(max((70 - self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 0))
		iHillsTop2 = regionHillsFrac.getHeightFromPercent(min((80 + self.gc.getClimateInfo(self.map.getClimate()).getHillRange()), 100))
		for x in range(iRegionWidth):
			for y in range(iRegionHeight):
				i = y*iRegionWidth + x
				val = regionContinentsFrac.getHeight(x,y)
				if val <= iWaterThreshold: pass
				else:
					hillVal = regionHillsFrac.getHeight(x,y)
					if ((hillVal >= iHillsBottom1 and hillVal <= iHillsTop1) or (hillVal >= iHillsBottom2 and hillVal <= iHillsTop2)):
						self.plotTypes[i] = PlotTypes.PLOT_HILLS
					else:
						self.plotTypes[i] = PlotTypes.PLOT_LAND
		if bShift:
			self.shiftRegionPlots(iRegionWidth, iRegionHeight, iStrip)
		for x in range(iRegionWidth):
			wholeworldX = x + iWestX
			for y in range(iRegionHeight):
				i = y*iRegionWidth + x
				if self.plotTypes[i] == PlotTypes.PLOT_OCEAN: continue
				wholeworldY = y + iSouthY
				iWorld = wholeworldY*self.iW + wholeworldX
				self.wholeworldPlotTypes[iWorld] = self.plotTypes[i]
		return

	def generatePlotsByRegion(self, hub_type):
		iPlayers = self.gc.getGame().countCivPlayersEverAlive()
		userInputAreaType = cmo[1]
		area_grain = 3 - userInputAreaType
		userInputBufferType = cmo[2]
		buffer_one = [0, 58, 64, 70]
		bufWater = buffer_one[userInputBufferType]
		grainType = userInputBufferType
		sea = self.gc.getSeaLevelInfo(self.map.getSeaLevel()).getSeaLevelChange()
		sea = min(sea, 5)
		sea = max(sea, -5)
		bufWater += sea
		if hub_type == 1 and iPlayers < 11 and iPlayers > 1:
			global buffer_data
			for buffer_loop in range(iPlayers):
				[bufWestX, bufEastX, bufSouthY, bufNorthY] = buffer_data[buffer_loop]
				if grainType == 0:
					thisBuffer = 1 + getRandNum(3, "FoR : Random Buffer Type - Hub PYTHON")
					bufWater = sea + buffer_one[thisBuffer]
					bufGrain = thisBuffer + 1
				else:
					bufGrain = grainType + 1
				bufWidth = bufEastX - bufWestX + 1
				bufHeight = bufNorthY - bufSouthY + 1
				self.generatePlotsInRegion(bufWater,
				                           bufWidth, bufHeight,
				                           bufWestX, bufSouthY,
				                           bufGrain, 3,
				                           self.iRoundFlags, self.iTerrainFlags,
				                           6, 6,
				                           True, 3,
				                           -1, False,
				                           False
				                           )
		else: pass
		global region_data
		for region_loop in range(iPlayers):
			[regWestX, regEastX, regSouthY, regNorthY] = region_data[region_loop]
			regWidth = regEastX - regWestX + 1
			regHeight = regNorthY - regSouthY + 1
			self.generatePlotsInRegion(55 + sea,
			                           regWidth, regHeight,
			                           regWestX, regSouthY,
			                           area_grain, 4,
			                           self.iRoundFlags, self.iTerrainFlags,
			                           6, 6,
			                           True, 3,
			                           -1, False,
			                           False
			                           )
			coreWestX = regWestX + int(regWidth * 0.25)
			coreEastX = regEastX - int(regWidth * 0.25)
			coreSouthY = regSouthY + int(regHeight * 0.25)
			coreNorthY = regNorthY - int(regHeight * 0.25)
			coreWidth = coreEastX - coreWestX + 1
			coreHeight = coreNorthY - coreSouthY + 1
			self.generatePlotsInRegion(65,
			                           coreWidth, coreHeight,
			                           coreWestX, coreSouthY,
			                           1, 3,
			                           self.iHorzFlags, self.iTerrainFlags,
			                           5, 5,
			                           True, 3,
			                           -1, False,
			                           False
			                           )
		global hub_data
		linewidth = 1 + cmo[3]
		iWH = self.iW * self.iH
		offsetstart = 0 - int(linewidth/2)
		offsetrange = range(offsetstart, offsetstart + linewidth)
		for hub_loop in range(len(hub_data)):
			[startx, starty, endx, endy] = hub_data[hub_loop]
			if abs(endy-starty) < abs(endx-startx):
				if startx > endx:
					startx, starty, endx, endy = endx, endy, startx, starty
				dx = endx-startx
				dy = endy-starty
				if dx == 0 or dy == 0:
					slope = 0
				else:
					slope = float(dy)/float(dx)
				y = starty
				for x in range(startx, endx+1):
					for offset in offsetrange:
						if map.isPlot(x, int(round(y+offset))):
							i = map.plotNum(x, int(round(y+offset)))
							self.wholeworldPlotTypes[i] = PlotTypes.PLOT_LAND
					y += slope
			else:
				if starty > endy:
					startx, starty, endx, endy = endx, endy, startx, starty
				dx, dy = endx-startx, endy-starty
				if dx == 0 or dy == 0:
					slope = 0
				else:
					slope = float(dx)/float(dy)
				x = startx
				for y in range(starty, endy+1):
					for offset in offsetrange:
						if map.isPlot(int(round(x+offset)), y):
							i = map.plotNum(int(round(x+offset)), y)
							self.wholeworldPlotTypes[i] = PlotTypes.PLOT_LAND
					x += slope
		global center_data
		[cenWestX, cenEastX, cenSouthY, cenNorthY] = center_data
		cenWidth = cenEastX - cenWestX + 1
		cenHeight = cenNorthY - cenSouthY + 1
		if grainType == 0:
			thisBuffer = 1 + getRandNum(3, "FoR : Random Buffer Type - Hub PYTHON")
			bufWater = sea + buffer_one[thisBuffer]
			bufGrain = thisBuffer + 1
		else:
			bufGrain = grainType + 1
		self.generateCenter(bufWater,
		                    cenWidth, cenHeight,
		                    cenWestX, cenSouthY,
		                    bufGrain, 4,
		                    self.iRoundFlags, self.iTerrainFlags,
		                    -1, -1,
		                    True, 5,
		                    -1, False,
		                    False
		                    )
		return self.wholeworldPlotTypes

class ArchipelagoFractalWorld(CvMapGeneratorUtil.FractalWorld):
	def checkForOverrideDefaultUserInputVariances(self):
		extraPeaks = 1 + cmo[0]
		self.peakPercent = min(100, self.peakPercent + (15 * extraPeaks))
		self.peakPercent = max(0, self.peakPercent)
		return

class CCMultilayeredFractal(CvMapGeneratorUtil.MultilayeredFractal):
	def generatePlotsByRegion(self):
		global xShiftRoll, yShiftRoll
		userInputContinents = cmo[0]
		defaultWater = [55, 60, 65, 70, 75, 80, 85]
		numTinies = 1 + getRandNum(4, "FoR : Tiny Islands - Custom Continents PYTHON")
		if numTinies:
			for tiny_loop in range(numTinies):
				tinyWestLon = 0.01 * getRandNum(85, "FoR : Tiny Longitude - Custom Continents PYTHON")
				tinyWestX = int(self.iW * tinyWestLon)
				tinySouthLat = 0.01 * getRandNum(85, "FoR : Tiny Latitude - Custom Continents PYTHON")
				tinySouthY = int(self.iH * tinyWestLon)
				tinyWidth = int(self.iW * 0.15)
				tinyHeight = int(self.iH * 0.15)
				self.generatePlotsInRegion(80,
				                           tinyWidth, tinyHeight,
				                           tinyWestX, tinySouthY,
				                           4, 3,
				                           0, self.iTerrainFlags,
				                           6, 5,
				                           True, 3,
				                           -1, False,
				                           False
				                           )
		global iNumConts
		global cont_data
		for continent_loop in range(iNumConts):
			iNumLayers = cont_data[continent_loop][0]
			for region_loop in range(1, (iNumLayers + 1)):
				[fWestLon, fEastLon, fSouthLat, fNorthLat, horzVar, vertVar, bFlagX, bFlagY, iWater, iGrain, flagID, xExp, yExp, iShift] = cont_data[continent_loop][region_loop]
				iWestX = int(self.iW * fWestLon)
				iEastX = int(self.iW * fEastLon) - 1
				iSouthY = int(self.iH * fSouthLat)
				iNorthY = int(self.iH * fNorthLat) -1
				iWidth = iEastX - iWestX + 1
				iHeight = iNorthY - iSouthY + 1
				if horzVar != 0:
					xVar = int(self.iW * horzVar)
					if bFlagX:
						xShift = getRandNum(xVar, "FoR : Region Shift, Horizontal - Custom Continents PYTHON")
					else:
						if xShiftRoll:
							xShift = xVar
						else:
							xShift = 0
					iWestX += xShift
				if vertVar != 0:
					yVar = int(self.iH * vertVar)
					if bFlagY:
						yShift = getRandNum(yVar, "FoR : Region Shift, Vertical - Custom Continents PYTHON")
					else:
						if yShiftRoll:
							yShift = yVar
						else:
							yShift = 0
					iSouthY += yShift
				if iGrain > 0 and iGrain < 7: pass
				elif iGrain == 12:
					grainRoll = getRandNum(2, "FoR : Random Grain - Custom Continents PYTHON")
					iGrain = grainRoll + 1
				elif iGrain == 13:
					grainRoll = getRandNum(3, "FoR : Random Grain - Custom Continents PYTHON")
					iGrain = grainRoll + 1
				elif iGrain == 14:
					grainRoll = getRandNum(4, "FoR : Random Grain - Custom Continents PYTHON")
					iGrain = grainRoll + 1
				elif iGrain == 23:
					grainRoll = getRandNum(2, "FoR : Random Grain - Custom Continents PYTHON")
					iGrain = grainRoll + 2
				elif iGrain == 24:
					grainRoll = getRandNum(3, "FoR : Random Grain - Custom Continents PYTHON")
					iGrain = grainRoll + 2
				elif iGrain == 34:
					grainRoll = getRandNum(2, "FoR : Random Grain - Custom Continents PYTHON")
					iGrain = grainRoll + 3
				elif iGrain == 35:
					grainRoll = getRandNum(3, "FoR : Random Grain - Custom Continents PYTHON")
					iGrain = grainRoll + 3
				else:
					iGrain = 2
				if iWater == -1:
					iWater = defaultWater[iGrain]
				if flagID == 0:
					iFlags = 0
				elif flagID == 1:
					iFlags = self.iHorzFlags
				elif flagID == 2:
					iFlags = self.iVertFlags
				elif flagID == 3:
					iFlags = self.iRoundFlags
				else:
					iFlags = 0

				self.generatePlotsInRegion(iWater,
				                           iWidth, iHeight,
				                           iWestX, iSouthY,
				                           iGrain, 4,
				                           iFlags, self.iTerrainFlags,
				                           xExp, yExp,
				                           True, iShift,
				                           -1, False,
				                           False
				                           )
		return self.wholeworldPlotTypes

def generateTerrainTypes():
        # don't do any river in the first pass
        global canAddRivers
        canAddRivers = False
        
	NiTextOut("Generating Terrain (Full of resources) ...")
        try :
                writeLog(" = generateTerrainTypes = ", False, [""])

                # pangaea final plot generation
                if idMap == "pangaea" :
                        generatePangaeaTerrainTypes()

                # terrrain generation
                terrainDesert = gc.getInfoTypeForString('TERRAIN_DESERT')
                terrainPlains = gc.getInfoTypeForString('TERRAIN_PLAINS')
                terrainSnow = gc.getInfoTypeForString('TERRAIN_SNOW')
                terrainTundra = gc.getInfoTypeForString('TERRAIN_TUNDRA')
                terrainGrass = gc.getInfoTypeForString('TERRAIN_GRASS')
                userInputGrass = getRandSel(selGen["terrain"]["terrains"]["grass"])
                userInputPlain = getRandSel(selGen["terrain"]["terrains"]["plains"])
                userInputDesert = getRandSel(selGen["terrain"]["terrains"]["desert"])
                userInputTundra = getRandSel(selGen["terrain"]["terrains"]["tundra"])
                userInputSnow = getRandSel(selGen["terrain"]["terrains"]["snow"])

                #debug
                logList = []
                logList.append(" userInputGrass : %r" %userInputGrass)
                logList.append(" userInputPlain : %r" %userInputPlain)
                logList.append(" userInputDesert : %r" %userInputDesert)
                logList.append(" userInputTundra : %r" %userInputTundra)
                logList.append(" userInputSnow : %r" %userInputSnow)
                logList.append("")
                writeLog("", False, logList)

                if idMap in ["archipelago", "continents", "customcontinents", "fractals", "islands", "lakes", "maze", "pangaea", "shuffle", "terra", "chess", "bigandsmall", "hemispheres", "mediumandsmall"] :
                        snowLatitude = min(1.0, 0.9 - userInputSnow*0.093 + 0.016*(userInputDesert + userInputGrass + userInputPlain) )
                        tundraLatitude = max(0.5, min(snowLatitude - 0.1, snowLatitude - userInputTundra*0.05 + 0.01*(userInputDesert + userInputGrass + userInputPlain)))
                        grassLatitude = min(0.25, 0.1 + userInputGrass*0.6 - userInputDesert*0.2)
                        amp = (tundraLatitude - grassLatitude)
                        botDesertLatitude = grassLatitude + min(amp/2, amp*0.13*(4 - userInputDesert))
                        topDesertLatitude = tundraLatitude - min(amp/2,amp*0.13*(4 - userInputDesert))
                        desertPer = max(0, min(60, int(userInputDesert*12.5 - (userInputPlain + userInputGrass)*1.25)))
                        plainsPer = 8 + userInputPlain*12
                        grain = 4

                        #debug
                        logList = []
                        logList.append(" snowLatitude : %r" %snowLatitude)
                        logList.append(" tundraLatitude : %r" %tundraLatitude)
                        logList.append(" grassLatitude : %r" %grassLatitude)
                        logList.append(" botDesertLatitude : %r" %botDesertLatitude)
                        logList.append(" topDesertLatitude : %r" %topDesertLatitude)
                        logList.append(" desertPer : %r" %desertPer)
                        logList.append(" plainsPer : %r" %plainsPer)
                        logList.append(" grain : %r" %grain)
                        logList.append("")
                        writeLog("", False, logList)

                        terraingen = TerrainGenerator(desertPer, plainsPer, snowLatitude, tundraLatitude, grassLatitude, botDesertLatitude, topDesertLatitude, -1, -1, grain)
                elif idMap == "inlandsea" : #the same as normal gen , should change with tests ...
                        snowLatitude = min(1.0, 0.9 - userInputSnow*0.093 + 0.016*(userInputDesert + userInputGrass + userInputPlain) )
                        tundraLatitude = max(0.5, min(snowLatitude - 0.1, snowLatitude - userInputTundra*0.05 + 0.01*(userInputDesert + userInputGrass + userInputPlain)))
                        grassLatitude = min(0.25, 0.1 + userInputGrass*0.6 - userInputDesert*0.2)
                        amp = (tundraLatitude - grassLatitude)
                        botDesertLatitude = grassLatitude + min(amp/2, amp*0.13*(4 - userInputDesert))
                        topDesertLatitude = tundraLatitude - min(amp/2,amp*0.13*(4 - userInputDesert))
                        desertPer = max(0, min(60, int(userInputDesert*12.5 - (userInputPlain + userInputGrass)*1.25)))
                        plainsPer = 8 + userInputPlain*12
                        grain = 4

                        #debug
                        logList = []
                        logList.append(" snowLatitude : %r" %snowLatitude)
                        logList.append(" tundraLatitude : %r" %tundraLatitude)
                        logList.append(" grassLatitude : %r" %grassLatitude)
                        logList.append(" botDesertLatitude : %r" %botDesertLatitude)
                        logList.append(" topDesertLatitude : %r" %topDesertLatitude)
                        logList.append(" desertPer : %r" %desertPer)
                        logList.append(" plainsPer : %r" %plainsPer)
                        logList.append(" grain : %r" %grain)
                        logList.append("")
                        writeLog("", False, logList)

                        terraingen = ISTerrainGenerator(desertPer, plainsPer, snowLatitude, tundraLatitude, grassLatitude, botDesertLatitude, topDesertLatitude, -1, -1, grain)
                elif idMap in ["hub", "ring", "wheel"] :
                        desertPer = 7*userInputDesert + 3 - (userInputGrass*4)
                        plainsPer = 10*userInputPlain + 18 - (userInputGrass*3)
                        icePer = 8 + 14*userInputSnow
                        tundraPer = 2 + 11*userInputTundra
                        grain = 5

                        #debug
                        logList = []
                        logList.append(" desertPer : %r" %desertPer)
                        logList.append(" plainsPer : %r" %plainsPer)
                        logList.append(" icePer : %r" %icePer)
                        logList.append(" tundraPer : %r" %tundraPer)
                        logList.append(" grain : %r" %grain)
                        logList.append("")
                        writeLog("", False, logList)

                        terraingen = HubTerrainGenerator(desertPer, plainsPer, icePer, tundraPer, -1, -1, grain)

                terrainTypes = terraingen.generateTerrain()

                # terrain replacement if none of the designed terrain should appear
                terrainRepSnow = terrainSnow
                terrainRepTundra = terrainTundra
                terrainRepDesert = terrainDesert
                if userInputDesert == 0 :
                        terrainRepDesert = terrainPlains
                if userInputSnow == 0 :
                        if userInputTundra == 0 :
                                terrainRepSnow = terrainPlains
                                terrainRepTundra = terrainGrass
                        else :
                                terrainRepSnow = terrainTundra
                elif userInputTundra == 0 :
                        terrainRepTundra = terrainPlains

                if (userInputSnow == 0) or (userInputTundra == 0) or (userInputDesert == 0) :
                        for iIndex in range(iW*iH) :
                                if terrainTypes[iIndex] == terrainSnow :
                                        terrainTypes[iIndex] = terrainRepSnow
                                elif terrainTypes[iIndex] == terrainTundra :
                                        terrainTypes[iIndex] = terrainRepTundra
                                elif terrainTypes[iIndex] == terrainDesert :
                                        terrainTypes[iIndex] = terrainRepDesert

                writeLog("", True, ["", " terrain generation completed ..."])

                return terrainTypes
        except :
                writeLog("", True, ["", " An error occured during terrain generation ... default generation"])
                writeError()
                terraingen = TerrainGenerator()
                terrainTypes = terraingen.generateTerrain()
                return terrainTypes

class ISTerrainGenerator(CvMapGeneratorUtil.TerrainGenerator):
	def getLatitudeAtPlot(self, iX, iY):
		lat = CvMapGeneratorUtil.TerrainGenerator.getLatitudeAtPlot(self, iX, iY)
		lat = 0.07 + 0.56*lat
		return lat

class HubTerrainGenerator(CvMapGeneratorUtil.TerrainGenerator):
	def __init__(self, iDesertPercent=20, iPlainsPercent=25,
	             iIcePercent=50, iTundraPercent=35,
	             fracXExp=-1, fracYExp=-1, grain_amount=5):
		self.gc = CyGlobalContext()
		self.map = CyMap()
		global center_data
		[self.cenWestX, self.cenEastX, self.cenSouthY, self.cenNorthY] = center_data
		grain_amount += self.gc.getWorldInfo(self.map.getWorldSize()).getTerrainGrainChange()
		self.grain_amount = grain_amount
		self.iWidth = self.map.getGridWidth()
		self.iHeight = self.map.getGridHeight()
		self.mapRand = self.gc.getGame().getMapRand()
		self.iFlags = 0
		if self.map.isWrapX(): self.iFlags += CyFractal.FracVals.FRAC_WRAP_X
		if self.map.isWrapY(): self.iFlags += CyFractal.FracVals.FRAC_WRAP_Y
		self.main=CyFractal()
		self.center=CyFractal()
		iDesertPercent += self.gc.getClimateInfo(self.map.getClimate()).getDesertPercentChange()
		if self.gc.getClimateInfo(self.map.getClimate()).getRandIceLatitude() > 0.25:
			iIcePercent += 10
			iTundraPercent += 5
			iPlainsPercent += 25
		if self.gc.getClimateInfo(self.map.getClimate()).getJungleLatitude() < 5:
			iIcePercent = 15
			iTundraPercent = 20
		self.iDesertBottomPercent = 100 - iDesertPercent
		self.iPlainsBottomPercent = self.iDesertBottomPercent - iPlainsPercent
		self.iIceBottomPercent = 100 - iIcePercent
		self.iTundraBottomPercent = self.iIceBottomPercent - iTundraPercent
		self.fracXExp = fracXExp
		self.fracYExp = fracYExp
		self.initFractals()
		
	def initFractals(self):
		self.main.fracInit(self.iWidth, self.iHeight, self.grain_amount, self.mapRand, self.iFlags, self.fracXExp, self.fracYExp)
		self.iDesertBottom = self.main.getHeightFromPercent(self.iDesertBottomPercent)
		self.iPlainsBottom = self.main.getHeightFromPercent(self.iPlainsBottomPercent)
		self.center.fracInit(self.iWidth, self.iHeight, self.grain_amount, self.mapRand, self.iFlags, self.fracXExp, self.fracYExp)
		self.iIceBottom = self.center.getHeightFromPercent(self.iIceBottomPercent)
		self.iTundraBottom = self.center.getHeightFromPercent(self.iTundraBottomPercent)
		self.terrainDesert = self.gc.getInfoTypeForString("TERRAIN_DESERT")
		self.terrainPlains = self.gc.getInfoTypeForString("TERRAIN_PLAINS")
		self.terrainIce = self.gc.getInfoTypeForString("TERRAIN_SNOW")
		self.terrainTundra = self.gc.getInfoTypeForString("TERRAIN_TUNDRA")
		self.terrainGrass = self.gc.getInfoTypeForString("TERRAIN_GRASS")

	def generateTerrainAtPlot(self,iX,iY):
		if (self.map.plot(iX, iY).isWater()):
			return self.map.plot(iX, iY).getTerrainType()
		if ((iX >= self.cenWestX and iX <= self.cenEastX) and (iY >= self.cenSouthY and iY <= self.cenNorthY)):
			val = self.center.getHeight(iX, iY)
			if val >= self.iIceBottom:
				terrainVal = self.terrainIce
			elif val >= self.iTundraBottom:
				terrainVal = self.terrainTundra
			else:
				terrainVal = self.terrainPlains
		else:
			val = self.main.getHeight(iX, iY)
			if val >= self.iDesertBottom:
				terrainVal = self.terrainDesert
			elif val >= self.iPlainsBottom:
				terrainVal = self.terrainPlains
			else:
				terrainVal = self.terrainGrass
		if (terrainVal == TerrainTypes.NO_TERRAIN):
			return self.map.plot(iX, iY).getTerrainType()
		return terrainVal

def generatePangaeaTerrainTypes():
	iHorzFlags = CyFractal.FracVals.FRAC_WRAP_X + CyFractal.FracVals.FRAC_POLAR
	biggest_area = map.findBiggestArea(false)
	global terrainRoll
	userInputShoreline = cmo[0]
	iTotalLandPlots = map.getLandPlots()
	iBiggestAreaPlots = biggest_area.getNumTiles()
	if (userInputShoreline == 1 or userInputShoreline == 2 or (userInputShoreline == 0 and terrainRoll < 7)) and iBiggestAreaPlots < 0.8 * iTotalLandPlots:
		global pangaea_type
		iWestX = int(0.3 * iW)
		eastX = int(0.7 * iW)
		southLat = 0.4
		northLat = 0.6
		if pangaea_type == 0:
			global shiftRoll
			if shiftRoll == 1:
				southLat += 0.075
				northLat += 0.075
			else:
				southLat -= 0.075
				northLat -= 0.075
		elif pangaea_type == 2:
			global polarShiftRoll
			if polarShiftRoll == 1:
				southLat += 0.175
				northLat += 0.175
			else:
				southLat -= 0.175
				northLat -= 0.175
		else:
			pass
		iSouthY = int(southLat * iH)
		northY = int(northLat * iH)
		iRegionWidth = eastX - iWestX + 1
		iRegionHeight = northY - iSouthY + 1
		plotTypes = []
		plotTypes = [PlotTypes.PLOT_OCEAN] * (iRegionWidth*iRegionHeight)
		regionContinentsFrac = CyFractal()
		regionHillsFrac = CyFractal()
		regionPeaksFrac = CyFractal()
		regionContinentsFrac.fracInit(iRegionWidth, iRegionHeight, 1, dice, iHorzFlags, 7, 5)
		regionHillsFrac.fracInit(iRegionWidth, iRegionHeight, 3, dice, iHorzFlags, 7, 5)
		regionPeaksFrac.fracInit(iRegionWidth, iRegionHeight, 4, dice, iHorzFlags, 7, 5)
		iWaterThreshold = regionContinentsFrac.getHeightFromPercent(40)
		iHillsBottom1 = regionHillsFrac.getHeightFromPercent(20)
		iHillsTop1 = regionHillsFrac.getHeightFromPercent(30)
		iHillsBottom2 = regionHillsFrac.getHeightFromPercent(70)
		iHillsTop2 = regionHillsFrac.getHeightFromPercent(80)
		iPeakThreshold = regionPeaksFrac.getHeightFromPercent(25)
		for x in range(iRegionWidth):
			for y in range(iRegionHeight):
				i = y*iRegionWidth + x
				val = regionContinentsFrac.getHeight(x,y)
				if val <= iWaterThreshold: pass
				else:
					hillVal = regionHillsFrac.getHeight(x,y)
					if ((hillVal >= iHillsBottom1 and hillVal <= iHillsTop1) or (hillVal >= iHillsBottom2 and hillVal <= iHillsTop2)):
						peakVal = regionPeaksFrac.getHeight(x,y)
						if (peakVal <= iPeakThreshold):
							plotTypes[i] = PlotTypes.PLOT_PEAK
						else:
							plotTypes[i] = PlotTypes.PLOT_HILLS
					else:
						plotTypes[i] = PlotTypes.PLOT_LAND
		for x in range(iRegionWidth):
			wholeworldX = x + iWestX
			for y in range(iRegionHeight):
				i = y*iRegionWidth + x
				if plotTypes[i] == PlotTypes.PLOT_OCEAN: continue
				wholeworldY = y + iSouthY
				iWorld = wholeworldY*iW + wholeworldX
				pPlot = map.plotByIndex(iWorld)
				if pPlot.isWater():
					pPlot.setPlotType(plotTypes[i], True, True)

                # remove peak along the coast for pangaea
                if (selGen["terrain"]["peak"]["peakcoast"]) :
                        for plotIndex in range(iW * iH):
                                pPlot = map.plotByIndex(plotIndex)
                                if pPlot.isPeak() :
                                        if pPlot.isCoastalLand() :
                                                pPlot.setPlotType(PlotTypes.PLOT_HILLS, True, True)

		map.recalculateAreas()

def getRiverStartCardinalDirection(argsList):
	if idMap != "inlandsea" :
                CyPythonMgr().allowDefaultImpl()
                return
	pPlot = argsList[0]
	if (pPlot.getY() > ((iH * 2) / 3)):
		return CardinalDirectionTypes.CARDINALDIRECTION_SOUTH

	if (pPlot.getY() < (iH / 3)):
		return CardinalDirectionTypes.CARDINALDIRECTION_NORTH

	if (pPlot.getX() > (iW / 2)):
		return CardinalDirectionTypes.CARDINALDIRECTION_WEST

	return CardinalDirectionTypes.CARDINALDIRECTION_EAST

def getRiverAltitude(argsList):
	if idMap != "inlandsea" :
                CyPythonMgr().allowDefaultImpl()
                return
	pPlot = argsList[0]
	CyPythonMgr().allowDefaultImpl()
	return ((abs(pPlot.getX() - (iW / 2)) + abs(pPlot.getY() - (iH / 2))) * 20)

def addRivers():
	if idMap != "chess" :
                if canAddRivers :
                        CyPythonMgr().allowDefaultImpl()
                        return
                else :
                        return None

        if not bSuccessFlag :
                if canAddRivers :
                        CyPythonMgr().allowDefaultImpl()
                        return
                else :
                        return None

        addChessRivers()
        return None

def addChessRivers():
        try :
                lar=iW/6
                hau=iH/6
                C_EAST = CardinalDirectionTypes.CARDINALDIRECTION_EAST
                C_SOUTH = CardinalDirectionTypes.CARDINALDIRECTION_SOUTH
                C_NORTH = CardinalDirectionTypes.CARDINALDIRECTION_NORTH
                C_WEST = CardinalDirectionTypes.CARDINALDIRECTION_WEST
                if userInputBorder == 3 :
                        C_EAST = CardinalDirectionTypes.CARDINALDIRECTION_WEST
                        C_SOUTH = CardinalDirectionTypes.CARDINALDIRECTION_NORTH
                        C_NORTH = CardinalDirectionTypes.CARDINALDIRECTION_SOUTH
                        C_WEST = CardinalDirectionTypes.CARDINALDIRECTION_EAST

                def setRiver(loc, x, y, card, rid) :
                        pPlot = map.plot(iX*6+x, iY*6+y)
                        if loc == "N" : pPlot.setNOfRiver(True, card)
                        elif loc == "W" : pPlot.setWOfRiver(True, card)
                        pPlot.setRiverID(rid)

                def setRID(x, y, rid) :
                        pPlot = map.plot(iX*6+x, iY*6+y)
                        pPlot.setRiverID(rid)

                for iX in range(lar) :
                        for iY in range(hau) :
                                idRiver = map.getNextRiverID()
                                map.incrementNextRiverID()
                                if (chessLakes[(iX-1)%lar][2*iY+1] == 0) and (chessLakes[iX][(2*iY+2)%(2*hau)] == 0) :
                                        lPlot = [("N", 2, 4, C_EAST), ("W", 1, 4, C_SOUTH), ("W", 2, 3, C_SOUTH), ("W", 2, 2, C_SOUTH)]
                                        for sLoc, dX, dY, iCard in lPlot : setRiver(sLoc, dX, dY, iCard, idRiver)
                                if (chessLakes[(iX-1)%lar][2*iY+1] == 0) and (chessLakes[iX][2*iY] == 0) :
                                        lPlot = [("N", 1, 1, C_EAST), ("N", 2, 2, C_EAST), ("N", 3, 2, C_EAST), ("W", 1, 1, C_NORTH)]
                                        for sLoc, dX, dY, iCard in lPlot : setRiver(sLoc, dX, dY, iCard, idRiver)
                                        setRID(2, 1, idRiver)
                                if (chessLakes[iX][2*iY] == 0) and (chessLakes[iX][2*iY+1] == 0) :
                                        lPlot = [("N", 4, 1, C_WEST), ("W", 4, 0, C_NORTH), ("W", 3, 1, C_NORTH), ("W", 3, 2, C_NORTH)]
                                        for sLoc, dX, dY, iCard in lPlot : setRiver(sLoc, dX, dY, iCard, idRiver)
                                if (chessLakes[iX][2*iY+1] == 0) and (chessLakes[iX][(2*iY+2)%(2*hau)] == 0) :
                                        lPlot = [("N", 5, 4, C_WEST), ("N", 4, 3, C_WEST), ("N", 3, 3, C_WEST), ("W", 4, 3, C_SOUTH)]
                                        for sLoc, dX, dY, iCard in lPlot : setRiver(sLoc, dX, dY, iCard, idRiver)
                                        setRID(5, 3, idRiver)
                                if userInputBorder != 3 :
                                        if (chessLakes[iX][(2*iY+2)%(2*hau)] == 0) and (chessLakes[(iX-1)%lar][2*iY+1] == 1) :
                                                lPlot = [("W", 2, 4, C_SOUTH), ("N", 3, 4, C_EAST), ("W", 3, 3, C_SOUTH)]
                                                for sLoc, dX, dY, iCard in lPlot : setRiver(sLoc, dX, dY, iCard, idRiver)
                                        if (chessLakes[(iX-1)%lar][2*iY+1] == 0) and (chessLakes[iX][2*iY] == 1) :
                                                lPlot = [("N", 1, 2, C_EAST), ("W", 1, 2, C_NORTH), ("N", 2, 3, C_EAST)]
                                                for sLoc, dX, dY, iCard in lPlot : setRiver(sLoc, dX, dY, iCard, idRiver)
                                                setRID(2, 2, idRiver)
                                        if (chessLakes[iX][2*iY] == 0) and (chessLakes[iX][2*iY+1] == 1) :
                                                lPlot = [("W", 3, 0, C_NORTH), ("N", 3, 1, C_WEST), ("W", 2, 1, C_NORTH)]
                                                for sLoc, dX, dY, iCard in lPlot : setRiver(sLoc, dX, dY, iCard, idRiver)
                                        if (chessLakes[iX][2*iY+1] == 0) and (chessLakes[iX][(2*iY+2)%(2*hau)] == 1) :
                                                lPlot = [("N", 5, 3, C_WEST), ("W", 4, 2, C_SOUTH), ("N", 4, 2, C_WEST)]
                                                for sLoc, dX, dY, iCard in lPlot : setRiver(sLoc, dX, dY, iCard, idRiver)
                                                setRID(5, 2, idRiver)
        except :
                writeLog("", False, ["", " An error occured during chess river generation ..."])
                writeError()

def addLakes():
        try :
                if idMap == "chess" :
                        if bSuccessFlag :
                                writeLog(" = addLakes : adding rivers = ", True, [" chess rivers already done . No lakes"])
                                return None

                global canAddRivers
                canAddRivers = True

                writeLog(" = addLakes : adding rivers = ", False, [""])

                # adding river . play with (fresh)water source range to make the longest rivers possible
                userInputPlotEdge = getRandSel(selGen["terrain"]["river"]["riveredge"], False)
                iOriginalMSOGDH = gc.getDefineINT("MODS_SHOULD_OVERRIDE_GLOBAL_DEFINES_HERE")
                iOriginalMinRiverRange = gc.getDefineINT("RIVER_SOURCE_MIN_RIVER_RANGE") #4 in default civ (/2 for the 2 last pass over 4 pass)
                iOriginalMinSeaWaterRange = gc.getDefineINT("RIVER_SOURCE_MIN_SEAWATER_RANGE") #2 in default civ (/2 for the 2 last pass over 4 pass)
                iOriginalPlotPerRiverEdge = gc.getDefineINT("PLOTS_PER_RIVER_EDGE")
                
                #debug
                logList = []
                logList.append(" userInputPlotEdge : %r" %userInputPlotEdge)
                logList.append(" iOriginalMSOGDH : %r" %iOriginalMSOGDH)
                logList.append(" iOriginalMinRiverRange : %r" %iOriginalMinRiverRange)
                logList.append(" iOriginalMinSeaWaterRange : %r" %iOriginalMinSeaWaterRange)
                logList.append(" iOriginalPlotPerRiverEdge : %r" %iOriginalPlotPerRiverEdge)
                logList.append("")
                writeLog("", False, logList)

                # don't seem to have a use . keep it just in case
                gc.setDefineINT("MODS_SHOULD_OVERRIDE_GLOBAL_DEFINES_HERE", 1)
                gc.setDefineINT("PLOTS_PER_RIVER_EDGE", userInputPlotEdge)

                iMRRange = iOriginalMinRiverRange + 15
                iMSRange = iOriginalMinSeaWaterRange + 15
                iLimitMinRiverRange = iOriginalMinRiverRange
                # in case the player want lots of rivers :
                if userInputPlotEdge <= 6 :
                        iLimitMinRiverRange = min(2, iOriginalMinRiverRange)
                
                idRiverStart = map.getNextRiverID() # should be 0

                bBreak = False
                while True :

                        idRiver = map.getNextRiverID()
                        if idRiver > 960 :
                                writeLog("", False, [" number of rivers exceed 960 : break ",""]) # think i remember that with XXXXl map ,1000 was the limit number of rivers
                                break

                        gc.setDefineINT("RIVER_SOURCE_MIN_RIVER_RANGE", iMRRange)
                        gc.setDefineINT("RIVER_SOURCE_MIN_SEAWATER_RANGE", iMSRange)

                        CyMapGenerator().addRivers()

                        if map.getNextRiverID() > idRiver :
                                continue
                        elif bBreak :
                                break

                        iMRRange -= 1
                        iMSRange -= 1
                        iMSRange = max(2, iMSRange)

                        if iMRRange == iLimitMinRiverRange : bBreak = True

                idRiverFinal = map.getNextRiverID()
                nbRivers = idRiverFinal - idRiverStart

                gc.setDefineINT("RIVER_SOURCE_MIN_RIVER_RANGE", iOriginalMinRiverRange)
                gc.setDefineINT("RIVER_SOURCE_MIN_SEAWATER_RANGE", iOriginalMinSeaWaterRange)
                gc.setDefineINT("PLOTS_PER_RIVER_EDGE", iOriginalPlotPerRiverEdge)
                gc.setDefineINT("MODS_SHOULD_OVERRIDE_GLOBAL_DEFINES_HERE", iOriginalMSOGDH)

                logList = []
                logList.append(" idRiverStart : %r" %idRiverStart)
                logList.append(" idRiverFinal : %r" %idRiverFinal)
                logList.append(" nbRivers : %r" %nbRivers)
                logList.append("")
                writeLog("", True, logList)
        except :
                writeLog("", True, ["", " An error occured during river generation ..."])
                writeError()

        # adding lakes
	CyPythonMgr().allowDefaultImpl()
	
def addFeatures():
        try :
                NiTextOut("Adding Features (Full of resources) ...")
                writeLog(" = addFeatures = ", False, [""])

                featureFlood = gc.getInfoTypeForString('FEATURE_FLOOD_PLAINS')
                terrainDesert = gc.getInfoTypeForString('TERRAIN_DESERT')
                featureIce = gc.getInfoTypeForString('FEATURE_ICE')
                featureOasis = gc.getInfoTypeForString('FEATURE_OASIS')
                featureNone = FeatureTypes.NO_FEATURE

                bIce = bool(featureIce != -1)
                bOasis = bool(featureOasis != -1)

                if bIce : userInputIced = selGen["terrain"]["ice"]["iceremove"]
                if bOasis : oasisPer = getRandSel(selGen["terrain"]["oasis"]["oasispercent"], False)

                forestPer = getRandSel(selGen["terrain"]["forest"]["forestpercent"], False)
                junglePer = getRandSel(selGen["terrain"]["jungle"]["junglepercent"], False)

                #debug
                logList = []
                if bIce : logList.append(" userInputIced : %r" %userInputIced)
                if bOasis : logList.append(" oasisPer : %r" %oasisPer)
                logList.append(" forestPer : %r" %forestPer)
                logList.append(" junglePer : %r" %junglePer)
                logList.append("")
                writeLog("", False, logList)

                fGrain=6
                jGrain=5

                if idMap in ["archipelago", "continents", "customcontinents", "fractals", "islands", "lakes", "maze", "pangaea", "shuffle", "terra", "chess", "bigandsmall", "hemispheres", "mediumandsmall"] :
                        featuregen = FeatureGenerator(junglePer, 100 - forestPer, jGrain, fGrain)
                elif idMap == "inlandsea" :
                        featuregen = ISFeatureGenerator(junglePer, 100 - forestPer, jGrain, fGrain)
                elif idMap in ["hub", "ring", "wheel"] :
                        forestPer = int(7.0 / 12 * (100 - forestPer) + 16) + 1
                        junglePer = int(5.0 / 16 * junglePer)
                        featuregen = HubFeatureGenerator(junglePer, 100 - forestPer, fGrain)

                featuregen.addFeatures()

                oasisPlots = []
                for iX in range(iW) :
                        for iY in range(iH) :
                                pPlot = map.plot(iX, iY)
                                iFeature = pPlot.getFeatureType()
                                if iFeature != -1 :
                                        if bOasis :
                                                if iFeature == featureOasis :
                                                        pPlot.setFeatureType(featureNone, -1)
                                        if bIce :
                                                if iFeature == featureIce :
                                                        if userInputIced == 2 :
                                                                pPlot.setFeatureType(featureNone, -1)
                                                        elif userInputIced == 1 :
                                                                for dX, dY in [(-1, 0), (1, 0), (0, -1), (0, 1)] :
                                                                        pLoopPlot = map.plot(iX + dX, iY + dY)
                                                                        if pLoopPlot.isNone() : continue
                                                                        if not pLoopPlot.isWater() :
                                                                                pPlot.setFeatureType(featureNone, -1)
                                                                                break
                                                        continue

                                if bOasis :
                                        if pPlot.canHaveFeature(featureOasis) :
                                                oasisPlots.append((iX, iY))

                # place Oasis
                if bOasis :
                        rings = generateRings(3)
                        nbOasisPlaced = 0
                        nbOasisTiles = len(oasisPlots)
                        oasisPer /= 100.0
                        plotValue = [[0 for iY in range(iH)] for iX in range(iW)]
                        while True :
                                if (nbOasisPlaced / (nbOasisTiles + 0.001)) >= oasisPer : break
                                if len(oasisPlots) == 0 : break
                                bestValue = min([plotValue[iX][iY] for iX, iY in oasisPlots])
                                lPlots = [(iX, iY) for iX, iY in oasisPlots if plotValue[iX][iY] == bestValue]
                                iChoice = getRandNum(len(lPlots), "FoR : hill add")
                                iX, iY = lPlots[iChoice]
                                for iRing in range(1, 4) :
                                        for dX, dY in rings[iRing] :
                                                wTP = toWrap(iX + dX, iY + dY)
                                                if wTP != -1 :
                                                        if wTP in oasisPlots :
                                                                plotValue[wTP[0]][wTP[1]] += (4 - iRing)
                                map.plot(iX, iY).setFeatureType(featureOasis, -1)
                                nbOasisPlaced += 1
                                oasisPlots.remove((iX, iY))

                        #debug
                        logList = []
                        logList.append(" nbOasisPlaced : %r" %nbOasisPlaced)
                        logList.append(" nbOasisTiles : %r" %nbOasisTiles)
                        if nbOasisTiles > 0 : logList.append(" eff oasis percent : %r" %(float(nbOasisPlaced)/nbOasisTiles*100, ))
                        logList.append("")
                        writeLog("", False, logList)

                writeLog("", True, [])
        except :
                writeLog("", True, ["", " An error occured during feature generation ..."])
                writeError()

	return 0

class ISFeatureGenerator(CvMapGeneratorUtil.FeatureGenerator):
	def getLatitudeAtPlot(self, iX, iY):
		lat = CvMapGeneratorUtil.FeatureGenerator.getLatitudeAtPlot(self, iX, iY)
		lat = 0.07 + 0.56*lat
		return lat

class HubFeatureGenerator(CvMapGeneratorUtil.FeatureGenerator):
	def __init__(self, iJunglePercent=25, iForestPercent=40,
	             forest_grain=6, fracXExp=-1, fracYExp=-1):
		self.gc = CyGlobalContext()
		self.map = CyMap()
		self.mapRand = self.gc.getGame().getMapRand()
		self.forests = CyFractal()
		global center_data
		[self.cenWestX, self.cenEastX, self.cenSouthY, self.cenNorthY] = center_data
		self.iFlags = 0
		if self.map.isWrapX(): self.iFlags += CyFractal.FracVals.FRAC_WRAP_X
		if self.map.isWrapY(): self.iFlags += CyFractal.FracVals.FRAC_WRAP_Y
		self.iGridW = self.map.getGridWidth()
		self.iGridH = self.map.getGridHeight()
		self.pineWestX = int(self.cenWestX * 0.7)
		self.pineEastX = self.iGridW - int((self.cenEastX + self.iGridW - 1) * 0.35) - 1
		self.pineSouthY = int(self.cenSouthY * 0.7)
		self.pineNorthY = self.iGridH - int((self.cenNorthY + self.iGridH - 1) * 0.35) - 1
		self.iJunglePercent = iJunglePercent
		self.iForestPercent = iForestPercent
		self.iIceChance = 15
		if self.gc.getClimateInfo(self.map.getClimate()).getJungleLatitude() < 5:
			self.iJunglePercent += 25
			self.iForestPercent -= 10
			self.iIceChance = 30
		if self.gc.getClimateInfo(self.map.getClimate()).getRandIceLatitude() > 0.25:
			self.iIceChance = 6
			self.iJunglePercent -= 10
			self.iForestPercent += 20
		if self.gc.getClimateInfo(self.map.getClimate()).getDesertPercentChange() >= 10:
			self.iJunglePercent = 15
			self.iForestPercent = 20
		forest_grain += self.gc.getWorldInfo(self.map.getWorldSize()).getFeatureGrainChange()
		self.forest_grain = forest_grain
		self.fracXExp = fracXExp
		self.fracYExp = fracYExp
		self.__initFractals()
		self.__initFeatureTypes()
	
	def __initFractals(self):
		self.forests.fracInit(self.iGridW, self.iGridH, self.forest_grain, self.mapRand, self.iFlags, self.fracXExp, self.fracYExp)
		self.iJungleBottom = self.forests.getHeightFromPercent(100 - self.iJunglePercent)
		self.iForestLevel = self.forests.getHeightFromPercent(self.iForestPercent)

	def __initFeatureTypes(self):
		self.featureIce = self.gc.getInfoTypeForString("FEATURE_ICE")
		self.featureJungle = self.gc.getInfoTypeForString("FEATURE_JUNGLE")
		self.featureForest = self.gc.getInfoTypeForString("FEATURE_FOREST")
		self.featureOasis = self.gc.getInfoTypeForString("FEATURE_OASIS")
	
	def addFeaturesAtPlot(self, iX, iY):
		pPlot = self.map.sPlot(iX, iY)
		for iI in range(self.gc.getNumFeatureInfos()):
			if pPlot.canHaveFeature(iI):
				if getRandNum(10000, "FoR : Add Feature PYTHON") < self.gc.getFeatureInfo(iI).getAppearanceProbability():
					pPlot.setFeatureType(iI, -1)
		if (pPlot.getFeatureType() == FeatureTypes.NO_FEATURE):
			self.addIceAtPlot(pPlot, iX, iY)
		if (pPlot.getFeatureType() == FeatureTypes.NO_FEATURE):
			self.addJunglesAtPlot(pPlot, iX, iY)
		if (pPlot.getFeatureType() == FeatureTypes.NO_FEATURE):
			self.addForestsAtPlot(pPlot, iX, iY)
		
	def addIceAtPlot(self, pPlot, iX, iY):
		if pPlot.isWater() and ((iX >= self.cenWestX and iX <= self.cenEastX) and (iY >= self.cenSouthY and iY <= self.cenNorthY)):
			rand = getRandNum(self.iIceChance, "FoR : Add Ice PYTHON")
			if rand == 4:
				pPlot.setFeatureType(self.featureIce, -1)
	
	def addJunglesAtPlot(self, pPlot, iX, iY):
		if pPlot.canHaveFeature(self.featureJungle) and not ((iX >= self.cenWestX and iX <= self.cenEastX) and (iY >= self.cenSouthY and iY <= self.cenNorthY)):
			iJungleHeight = self.forests.getHeight(iX, iY)
			if iJungleHeight >= self.iJungleBottom:
				pPlot.setFeatureType(self.featureJungle, -1)
	
	def addForestsAtPlot(self, pPlot, iX, iY):
		if pPlot.canHaveFeature(self.featureForest):
			if self.forests.getHeight(iX, iY) <= self.iForestLevel:
				if ((iX >= self.cenWestX and iX <= self.cenEastX) and (iY >= self.cenSouthY and iY <= self.cenNorthY)):
					forestVar = 2
				elif (iX <= self.pineWestX or iX >= self.pineEastX or iY <= self.pineSouthY or iY >= self.pineNorthY):
					forestVar = 0
				else:
					forestVar = 1
				pPlot.setFeatureType(self.featureForest, forestVar)

def afterGeneration():
        #default bonus generation done , now add extra bonuses
        try :
                StoAddBonuses()
        except :
                writeLog("", True, ["", " An error occured during resources generation ..."])
                writeError()

def StoAddBonuses():
        global lBonusExtend
        writeLog(" = StoAddBonuses = ", False, [""])

        # initialization

        # remove all goodies , store plots with other improvements .
        # let default goody generation in case some other improvements or goodies are added by the mod .
        iGoody = gc.getInfoTypeForString("IMPROVEMENT_GOODY_HUT")
        bGoody = bool(iGoody != -1)
        lImprovementPlots = []
        for iX in range(iW) :
                for iY in range(iH) :
                        pPlot = map.plot(iX, iY)
                        iImprovement = pPlot.getImprovementType()
                        if iImprovement == -1 : continue
                        if bGoody :
                                if iImprovement == iGoody :
                                        pPlot.setImprovementType(-1)
                                        continue
                        lImprovementPlots.append((iX, iY))

        # entries
        natRes = genNatureRes()
        nbRes = gc.getNumBonusInfos()
        nbTerrain = gc.getNumTerrainInfos()
        nbFeature = gc.getNumFeatureInfos()

        noTeam = TeamTypes.NO_TEAM

        lResPro = [iBonus for iBonus in range(nbRes) if ((gc.getBonusInfo(iBonus).getType() in XMLEntriesList["strategic"]) and (natRes[iBonus][0] == 0))]
        lResFoo = [iBonus for iBonus in range(nbRes) if ((gc.getBonusInfo(iBonus).getType() in XMLEntriesList["health"]) and (natRes[iBonus][0] == 1))]
        lResLux = [iBonus for iBonus in range(nbRes) if ((gc.getBonusInfo(iBonus).getType() in XMLEntriesList["happiness"]) and (natRes[iBonus][0] == 2))]
        lRes = copy.copy(lResPro) + copy.copy(lResFoo) + copy.copy(lResLux)
        lResLand = [iBonus for iBonus in range(nbRes) if ((gc.getBonusInfo(iBonus).getType() in XMLEntriesList["land"]) and (natRes[iBonus][1]))]
        lResWater = [iBonus for iBonus in range(nbRes) if ((gc.getBonusInfo(iBonus).getType() in XMLEntriesList["water"]) and (natRes[iBonus][2]))]
        
	lResNatLoc = [[[iBonus for iBonus in lResPro if iBonus in lResLand], [iBonus for iBonus in lResPro if iBonus in lResWater]],
                      [[iBonus for iBonus in lResFoo if iBonus in lResLand], [iBonus for iBonus in lResFoo if iBonus in lResWater]],
                      [[iBonus for iBonus in lResLux if iBonus in lResLand], [iBonus for iBonus in lResLux if iBonus in lResWater]]]

	bEraseAll = copy.copy(selGen["resources"]["resourcesgen"]["erasedefres"])
        lStandardRes = []

        landPer = copy.copy(selGen["resources"]["resourcesgen"]["landpercent"])
        if landPer == "standard" :
                lStandardRes += copy.copy(lResLand)
                landPer = 0
        else :
                landPer = getRandSel(selGen["resources"]["resourcesgen"]["landpercent"], False)

        waterPer = copy.copy(selGen["resources"]["resourcesgen"]["waterpercent"])
        if waterPer == "standard" :
                lStandardRes += copy.copy(lResWater)
                waterPer = 0
        else :
                waterPer = getRandSel(selGen["resources"]["resourcesgen"]["waterpercent"], False)

        lStandardResSel = [gc.getInfoTypeForString(sType) for sType in selGen["resources"]["resourcesgen"]["standardgen"]]

        lStandardRes = list(set(lStandardResSel + lStandardRes))

        if bEraseAll : lStandardRes = []
        
        lGenRes = [iBonus for iBonus in lRes if not iBonus in lStandardRes]

        lGroupRes = [gc.getInfoTypeForString(sType) for sType in selGen["resources"]["resourcesgen"]["groupres"]]

        landProps = copy.copy(selGen["resources"]["resourcesgen"]["landprop"])
        waterProps = copy.copy(selGen["resources"]["resourcesgen"]["waterprop"])

        bLakes = copy.copy(selGen["resources"]["resourcesgen"]["resspreadlake"])
        bClimate = not isBonusIgnoreLatitude()

        lResMultiply = []
        for sKey in selGen["resources"]["resourcesgen"].keys() :
                if not "resmultiply-" in sKey : continue
                eBonuses = selGen["resources"]["resourcesgen"][sKey][0]
                rFactor = copy.copy(selGen["resources"]["resourcesgen"][sKey][1])
                if eBonuses == [] :
                        continue
                elif eBonuses == "allstrat" :
                        if rFactor > 1.001 :
                                for iBonus in lResPro : lResMultiply.append([iBonus, rFactor])
                elif eBonuses == "allhealth" :
                        if rFactor > 1.001 :
                                for iBonus in lResFoo : lResMultiply.append([iBonus, rFactor])
                elif eBonuses == "allhapp" :
                        if rFactor > 1.001 :
                                for iBonus in lResLux : lResMultiply.append([iBonus, rFactor])
                else :
                        if rFactor > 1.001 :
                                iBonus = gc.getInfoTypeForString(eBonuses[0])
                                if iBonus == -1 :
                                        writeLog("", False, ["ERROR , res multiply type : %r , %r" %(eBonuses, rFactor)])
                                        continue
                                lResMultiply.append([iBonus, rFactor])

        # debug                
        logList = [" resources generation entries :"]
        logList.append("")
        logList.append(" lResPro : %r" %([gc.getBonusInfo(iBonus).getType() for iBonus in lResPro], ))
        logList.append(" lResFoo : %r" %([gc.getBonusInfo(iBonus).getType() for iBonus in lResFoo], ))
        logList.append(" lResLux : %r" %([gc.getBonusInfo(iBonus).getType() for iBonus in lResLux], ))
        logList.append("")
        logList.append(" bEraseAll    : %r" %bEraseAll)
        logList.append(" reslist      : %r" %XMLEntriesList["reslist"])
        logList.append(" lRes         : %r" %([gc.getBonusInfo(iBonus).getType() for iBonus in lRes], ))
        logList.append(" lGenRes      : %r" %([gc.getBonusInfo(iBonus).getType() for iBonus in lGenRes], ))
        logList.append(" lStandardRes : %r" %([gc.getBonusInfo(iBonus).getType() for iBonus in lStandardRes], ))
        logList.append("")
        logList.append(" landlist : %r" %XMLEntriesList["land"])
        logList.append(" lResLand : %r" %([gc.getBonusInfo(iBonus).getType() for iBonus in lResLand], ))
        logList.append("")
        logList.append(" waterlist : %r" %XMLEntriesList["water"])
        logList.append(" lResWater : %r" %([gc.getBonusInfo(iBonus).getType() for iBonus in lResWater], ))
        logList.append("")
        lTag = ["pro", "foo", "lux"]
        for i in range(3) :
                logList.append(" lResNatLoc, %s, land  : %r" %(lTag[i], [gc.getBonusInfo(iBonus).getType() for iBonus in lResNatLoc[i][0]]))
                logList.append(" lResNatLoc, %s, water : %r" %(lTag[i], [gc.getBonusInfo(iBonus).getType() for iBonus in lResNatLoc[i][1]]))
        logList.append("")
        logList.append(" landPer  : %r" %landPer)
        logList.append(" waterPer : %r" %waterPer)
        logList.append("")
        logList.append(" lGroupRes : %r" %([gc.getBonusInfo(iBonus).getType() for iBonus in lGroupRes], ))
        logList.append("")
        logList.append(" landProps : %r" %landProps)
        logList.append(" waterProps : %r" %waterProps)
        logList.append(" bLakes : %r" %bLakes)
        logList.append(" bClimate : %r" %bClimate)
        logList.append("")
        logList.append(" res multiply :")
        for item in lResMultiply :
                logList.append(" res : %r , factor : %r" %(gc.getBonusInfo(item[0]).getType(), item[1]))
        logList.append("")
        writeLog("", False, logList)

        landTerrain = []
        waterTerrain = []
        for iTerrain in range(nbTerrain) :
                terrainXML = gc.getTerrainInfo(iTerrain)
                if terrainXML.isGraphicalOnly() : continue
                for iBonus in lRes :
                        bonusXML = gc.getBonusInfo(iBonus)
                        if bonusXML.isTerrain(iTerrain) or bonusXML.isFeatureTerrain(iTerrain) :
                                if terrainXML.isWater() : waterTerrain.append(iTerrain)
                                else : landTerrain.append(iTerrain)
                                break

        listTerrain = landTerrain + waterTerrain

        terrainWeak = []
        terrainGood = []
        yieldTerrain = {}
        for iTerrain in landTerrain :
                yieldTerrain[iTerrain] = [gc.getTerrainInfo(iTerrain).getYield(iYield) for iYield in (YieldTypes.YIELD_FOOD, YieldTypes.YIELD_PRODUCTION)]
                if sum(yieldTerrain[iTerrain]) < 2 : terrainWeak.append(iTerrain)
                else : terrainGood.append(iTerrain)

        listFeature = []
        for iFeature in range(nbFeature) :
                for iBonus in lRes :
                        if gc.getBonusInfo(iBonus).isFeature(iFeature) :
                                listFeature.append(iFeature)
                                break

        bonusTerrainWeak = []
        bonusTerrainGood = []
        for iBonus in lResLand :
                bonusXML = gc.getBonusInfo(iBonus)
                for iTerrain in terrainWeak :
                        if bonusXML.isTerrain(iTerrain) or bonusXML.isFeatureTerrain(iTerrain) :
                                bonusTerrainWeak.append(iBonus)
                                break
                for iTerrain in terrainGood :
                        if bonusXML.isTerrain(iTerrain) or bonusXML.isFeatureTerrain(iTerrain) :
                                bonusTerrainGood.append(iBonus)
                                break
                                
        logList = [" terrains , features sort :"]
        logList.append("")
        logList.append(" landTerrain : %r" %([gc.getTerrainInfo(iTerrain).getType() for iTerrain in landTerrain], ))
        logList.append(" waterTerrain : %r" %([gc.getTerrainInfo(iTerrain).getType() for iTerrain in waterTerrain], ))
        logList.append(" terrainWeak : %r" %([gc.getTerrainInfo(iTerrain).getType() for iTerrain in terrainWeak], ))
        logList.append(" terrainGood : %r" %([gc.getTerrainInfo(iTerrain).getType() for iTerrain in terrainGood], ))
        for iTerrain in landTerrain :
                logList.append(" yieldTerrain , %r : %r" %(gc.getTerrainInfo(iTerrain).getType(), yieldTerrain[iTerrain]))
        logList.append("")
        logList.append(" Feature bonus : %r" %([gc.getFeatureInfo(iFeature).getType() for iFeature in listFeature], ))
        logList.append("")
        logList.append(" bonusTerrainWeak : %r" %([gc.getBonusInfo(iBonus).getType() for iBonus in bonusTerrainWeak], ))
        logList.append(" bonusTerrainGood : %r" %([gc.getBonusInfo(iBonus).getType() for iBonus in bonusTerrainGood], ))
        logList.append("")
        writeLog("", False, logList)

        rings = generateRings(7)
        cityRings = rings[1] + rings[2]
        dictPlotsPerArea = getAreaPlots()

        # sort list of available land , water plots , placements
        buffTempPlacements = []
        mapSort = [[[[] for iHill in range(2)] for iFeature in range(nbFeature + 1)] for iTerrain in range(nbTerrain)]
        mapBonus = [[-1 for iY in range(iH)] for iX in range(iW)]
        listPlotBonus = [[] for iBonus in range(nbRes)]
        lPlotCanHaveBonus = [[[] for bWater in range(2)] for iBonus in range(nbRes)]
        nbPlaced = [[0 for bWater in range(2)] for iBonus in range(nbRes)]
        lBonusExtend = [[] for iBonus in range(nbRes)]
        landPlots = []
        landPlotsExtra = []
        waterPlots = []
        waterPlotsExtra = []
        lHillPlots = []

        logList = [" Bonus placement extention :"]
        for iX in range(iW):
                for iY in range(iH):
                        pPlot = map.plot(iX, iY)
                        if pPlot.isPeak() :
                                landPlotsExtra.append((iX, iY))
                                continue
                        terrainPlot = pPlot.getTerrainType()
                        featurePlot = pPlot.getFeatureType()
                        bonusPlot = pPlot.getBonusType(-1)

                        if bEraseAll :
                                if not (iX, iY) in lImprovementPlots :
                                        bonusPlot = -1
                                        pPlot.setBonusType(-1)

                        mapBonus[iX][iY] = int(bonusPlot)

                        iWater = 0
                        if pPlot.isWater() : iWater = 1

                        if bonusPlot != -1 :
                                listPlotBonus[bonusPlot].append((iX, iY))
                                pPlot.setBonusType(-1)

                        for iBonus in lGenRes :
                                if pPlot.canHaveBonus(iBonus, not bClimate) : lPlotCanHaveBonus[iBonus][iWater].append((iX, iY))

                        if bonusPlot != -1 : pPlot.setBonusType(bonusPlot)

                        idHill = 0
                        if pPlot.isHills() :
                                idHill = 1
                                lHillPlots.append((iX, iY))

                        if iWater == 1 :
                                if bonusPlot != -1 :
                                        nbPlaced[bonusPlot][1] += 1
                                        waterPlotsExtra.append((iX, iY))
                                elif (iX, iY) in lImprovementPlots :
                                        waterPlotsExtra.append((iX, iY))
                                        continue
                                elif pPlot.isLake() and (not bLakes) :
                                        continue
                                elif len(getListPlotsPerArea((iX, iY), dictPlotsPerArea)) == 1 :
                                        waterPlotsExtra.append((iX, iY))
                                        continue
                                else :
                                        bFound = False
                                        for dX, dY in cityRings :
                                                wTP = toWrap(iX + dX, iY + dY)
                                                if wTP != -1 :
                                                        if not map.plot(wTP[0], wTP[1]).isWater():
                                                                bFound = True
                                                                break
                                        if bFound :
                                                if (terrainPlot in listTerrain) and ((featurePlot in listFeature) or (featurePlot == -1)) :
                                                        waterPlots.append((iX,iY))
                                                        mapSort[terrainPlot][featurePlot + 1][idHill].append((iX, iY))
                                                else :
                                                        waterPlotsExtra.append((iX, iY))
                                                        continue
                                        else :
                                                continue
                        else :
                                if bonusPlot != -1 :
                                        nbPlaced[bonusPlot][0] += 1
                                        landPlotsExtra.append((iX, iY))
                                        continue
                                elif (iX, iY) in lImprovementPlots :
                                        landPlotsExtra.append((iX, iY))
                                        continue
                                elif len(getListPlotsPerArea((iX, iY), dictPlotsPerArea)) == 1 :
                                        landPlotsExtra.append((iX, iY))
                                        continue
                                elif (terrainPlot in listTerrain) and ((featurePlot in listFeature) or (featurePlot == -1)) :
                                        landPlots.append((iX,iY))
                                        mapSort[terrainPlot][featurePlot + 1][idHill].append((iX, iY))
                                else :
                                        landPlotsExtra.append((iX, iY))
                                        continue

                        placement = (terrainPlot, featurePlot + 1, idHill)
                        if placement in buffTempPlacements : continue
                        buffTempPlacements.append(placement)

                        yieldPlot = [pPlot.calculateBestNatureYield(iYield, noTeam) for iYield in (YieldTypes.YIELD_FOOD, YieldTypes.YIELD_PRODUCTION, YieldTypes.YIELD_COMMERCE)]

                        if featurePlot == -1 : logList.append(" %r , No Feature , hill : %r" %(gc.getTerrainInfo(terrainPlot).getType(), bool(idHill)))
                        else : logList.append(" %r , %r , hill : %r" %(gc.getTerrainInfo(terrainPlot).getType(), gc.getFeatureInfo(featurePlot).getType(), bool(idHill)))

                        for iBonus in lRes :
                                bonusXML = gc.getBonusInfo(iBonus)
                                for iImprovement in range(gc.getNumImprovementInfos()) :
                                        improvementXML = gc.getImprovementInfo(iImprovement)

                                        if not improvementXML.isImprovementBonusMakesValid(iBonus) : continue

                                        if terrainPlot in terrainWeak :
                                                if not (bonusXML.isTerrain(terrainPlot) or bonusXML.isFeatureTerrain(terrainPlot)) :
                                                        continue

                                        if improvementXML.isWater():
                                                if terrainPlot in landTerrain : continue
                                        elif terrainPlot in waterTerrain : continue

                                        if improvementXML.isRequiresFeature() :
                                                if featurePlot == -1 : continue
                                                if not improvementXML.getFeatureMakesValid(featurePlot) : continue

                                        if improvementXML.isRequiresFlatlands() and idHill == 1 : continue

                                        bContinue = False
                                        for iYield in range(3) :
                                                if improvementXML.getPrereqNatureYield(iYield) > yieldPlot[iYield] : bContinue = True
                                        if bContinue : continue

                                        if not placement in lBonusExtend[iBonus] : lBonusExtend[iBonus].append(placement)
                                        logList.append(" %r , %r" %(bonusXML.getType(), improvementXML.getType()))
                        logList.append("")
        writeLog("", False, logList)

        # calculate nb Bonus to place .
        logList = [" bonus to place impl :"]

        nbLandPlots = len(landPlots) + len(landPlotsExtra)
        if nbLandPlots > 0 :
                effLandBonusPer = sum([nbPlaced[iBonus][0] for iBonus in range(nbRes)])*100.0/nbLandPlots
        else :
                effLandBonusPer = 110

        nbWaterPlots = len(waterPlots) + len(waterPlotsExtra)
        if nbWaterPlots > 0 :
                effWaterBonusPer = sum([nbPlaced[iBonus][1] for iBonus in range(nbRes)])*100.0/nbWaterPlots
        else :
                effWaterBonusPer = 110

        nbTotLandBonusToPlace = 0
        if effLandBonusPer < landPer :
                nbTotLandBonusToPlace = int(landPer / 100.0 * nbLandPlots) + 1

        nbTotWaterBonusToPlace = 0
        if effWaterBonusPer < waterPer :
                nbTotWaterBonusToPlace = int(waterPer / 100.0 * nbWaterPlots) + 1

        nbBonusToPlaceNatLoc = [[0 for bWater in range(2)] for iNat in range(3)]

        lResNatLocGen = [[[iBonus for iBonus in lResNatLoc[iNat][bWater] if (not iBonus in lStandardRes) and ( (len(lPlotCanHaveBonus[iBonus][0]) +len(lPlotCanHaveBonus[iBonus][1])) != 0 )] for bWater in range(2) ] for iNat in range(3)]
        nbPlacedNatLoc = [[sum([nbPlaced[iBonus][bWater] for iBonus in lResNatLoc[iNat][bWater]]) for bWater in range(2) ] for iNat in range(3)]
        bCanPlaceNatLoc = [[bool(len(lResNatLocGen[iNat][bWater]) != 0) for bWater in range(2) ] for iNat in range(3)]

        logList.append(" effLandBonusPer : %r" %effLandBonusPer)
        logList.append(" nbTotLandBonusToPlace : %r" %nbTotLandBonusToPlace)
        logList.append(" nbLandBonusPlaced : %r" %(sum([nbPlacedNatLoc[iNat][0] for iNat in range(3)]), ))
        logList.append("")
        logList.append(" effWaterBonusPer : %r" %effWaterBonusPer)
        logList.append(" nbTotWaterBonusToPlace : %r" %nbTotWaterBonusToPlace)
        logList.append(" nbWaterBonusPlaced : %r" %(sum([nbPlacedNatLoc[iNat][1] for iNat in range(3)]), ))
        logList.append("")

        for i in range(3) :
                logList.append(" lResNatLocGen, %s, land  : %r" %(lTag[i], [gc.getBonusInfo(iBonus).getType() for iBonus in lResNatLocGen[i][0]]))
                logList.append(" nbPlacedNatLoc, %s, land  : %r" %(lTag[i], nbPlacedNatLoc[i][0]))
                logList.append(" bCanPlaceNatLoc, %s, land  : %r" %(lTag[i], bCanPlaceNatLoc[i][0]))
                logList.append(" lResNatLocGen, %s, water : %r" %(lTag[i], [gc.getBonusInfo(iBonus).getType() for iBonus in lResNatLocGen[i][1]]))
                logList.append(" nbPlacedNatLoc, %s, water  : %r" %(lTag[i], nbPlacedNatLoc[i][1]))
                logList.append(" bCanPlaceNatLoc, %s, water  : %r" %(lTag[i], bCanPlaceNatLoc[i][1]))
        logList.append("")

        props = [landProps, waterProps]
        nbTotBonusToPlace = [nbTotLandBonusToPlace, nbTotWaterBonusToPlace]

        lSumProp = [sum([props[bWater][iNat] for iNat in range(3) if bCanPlaceNatLoc[iNat][bWater]]) for bWater in range(2)]
        for bWater in range(2) :
                if nbTotBonusToPlace[bWater] == 0 : continue
                if lSumProp[bWater] == 0 : continue

                nbAlreadyPlaced = sum([nbPlacedNatLoc[iNat][bWater] for iNat in range(3)])
                if  nbAlreadyPlaced >= nbTotBonusToPlace[bWater] : continue
                
                for iPass in range(nbTotBonusToPlace[bWater] - nbAlreadyPlaced) :
                        iNatPlace = -1
                        bestValue = -100000
                        for iNat in range(3) :
                                if props[bWater][iNat] == 0 : continue
                                if not bCanPlaceNatLoc[iNat][bWater] : continue
                                valueTemp = (props[bWater][iNat] / float(lSumProp[bWater])) * nbTotBonusToPlace[bWater] - nbPlacedNatLoc[iNat][bWater] - nbBonusToPlaceNatLoc[iNat][bWater]
                                if valueTemp > bestValue :
                                        bestValue = valueTemp
                                        iNatPlace = iNat
                        if iNatPlace == -1 :
                                break
                        else :
                                nbBonusToPlaceNatLoc[iNatPlace][bWater] += 1

        for bWater in range(2) :
                for iNat in range(3) :
                        logList.append(" nbBonusToPlaceNatLoc %r , %r : %r" %(iNat, bWater, nbBonusToPlaceNatLoc[iNat][bWater]))
        logList.append("")

        nbCountRes = [0  for iBonus in range(nbRes)]
        for iBonus in lGenRes :
                bonusXML = gc.getBonusInfo(iBonus)

                iBaseCount = bonusXML.getConstAppearance()
                iBaseCount += bonusXML.getRandAppearance1()
                iBaseCount += bonusXML.getRandAppearance2()
                iBaseCount += bonusXML.getRandAppearance3()
                iBaseCount += bonusXML.getRandAppearance4()

                iTiles = 0
                if bonusXML.getTilesPer() > 0 :
                        iTiles += float(len(lPlotCanHaveBonus[iBonus][0]) + len(lPlotCanHaveBonus[iBonus][1])) / bonusXML.getTilesPer()

                nPlay = (len(playerList) * bonusXML.getPercentPerPlayer()) / 100.0
                iBonusCount = (iBaseCount * (iTiles + nPlay)) / 100.0

                nbCountRes[iBonus] = max(1, iBonusCount)
                logList.append(" %r : %r" %(bonusXML.getType(), nbCountRes[iBonus]))

        logList.append("")

        nbBonusToPlace = [[ 0  for bWater in range(2) ] for iBonus in range(nbRes)]
        nbPlacedNatLocGen = [[sum([nbPlaced[iBonus][bWater] for iBonus in lResNatLocGen[iNat][bWater]]) for bWater in range(2) ] for iNat in range(3)]
        for bWater in range(2) :
                for iNat in range(3) :
                        if nbBonusToPlaceNatLoc[iNat][bWater] == 0 : continue

                        countTp = [0  for iBonus in range(nbRes)]
                        for iBonus in lResNatLocGen[iNatPlace][bWater] : countTp[iBonus] = nbCountRes[iBonus]*(float(len(lPlotCanHaveBonus[iBonus][bWater]))/(len(lPlotCanHaveBonus[iBonus][0]) + len(lPlotCanHaveBonus[iBonus][1])))
                        propMax = max([countTp[iBonus] for iBonus in lResNatLocGen[iNatPlace][bWater]])

                        sumProp = 0.0
                        for iBonus in lResNatLocGen[iNat][bWater] :
                                countTp[iBonus] = max(0.33*propMax, countTp[iBonus])
                                sumProp += countTp[iBonus]

                        nbTotTp = nbPlacedNatLocGen[iNat][bWater] + nbBonusToPlaceNatLoc[iNat][bWater]

                        for iPass in range(nbBonusToPlaceNatLoc[iNat][bWater]) :
                                if sumProp == 0 : break
                                iBonusPlace = -1
                                bestValue = -100000
                                for iBonus in lResNatLocGen[iNat][bWater] :
                                        if countTp[iBonus] == 0 : continue
                                        valueTemp = (countTp[iBonus] / sumProp) * nbTotTp - nbPlaced[iBonus][bWater] - nbBonusToPlace[iBonus][bWater]
                                        if (nbPlaced[iBonus][bWater] == 0) and (nbBonusToPlace[iBonus][bWater] == 0) :
                                                valueTemp += 10000
                                        if valueTemp > bestValue :
                                                bestValue = valueTemp
                                                iBonusPlace = iBonus
                                if iBonusPlace == -1 :
                                        break
                                else :
                                        nbBonusToPlace[iBonusPlace][bWater] += 1

                        if (bEraseAll) and (iNat == 0) :
                                for iBonus in lResNatLocGen[iNat][bWater] :
                                        nbBonusToPlace[iBonus][bWater] = max(1, nbBonusToPlace[iBonus][bWater])

        logList.append(" nb bonus to place before multiply :")
        for iBonus in range(nbRes) : logList.append(" %r : %r" %(gc.getBonusInfo(iBonus).getType(), nbBonusToPlace[iBonus]))
        logList.append("")

        for item in lResMultiply :
                iBonus = item[0]
                rFactor = item[1]

                if iBonus in lResWater :
                        nbAllPlace = nbPlaced[iBonus][1] + nbBonusToPlace[iBonus][1]
                        nbAllPlace = max(1, nbAllPlace)
                        nbBonusToPlace[iBonus][1] = max(1, int(nbAllPlace * rFactor) - nbPlaced[iBonus][1])

                if iBonus in lResLand :
                        nbAllPlace = nbPlaced[iBonus][0] + nbBonusToPlace[iBonus][0]
                        nbAllPlace = max(1, nbAllPlace)
                        nbBonusToPlace[iBonus][0] = max(1, int(nbAllPlace * rFactor) - nbPlaced[iBonus][0])

        logList.append(" nb bonus to place after multiply :")
        for iBonus in range(nbRes) : logList.append(" %r : %r" %(gc.getBonusInfo(iBonus).getType(), nbBonusToPlace[iBonus]))
        logList.append("")

        writeLog("", False, logList)

        lBonusWP = [iBonus for iBonus in range(nbRes) if ((nbBonusToPlace[iBonus][0] > 0) or (nbBonusToPlace[iBonus][1] > 0))]

        if lBonusWP == [] :
                writeLog("", True, [" No Bonus to Place ... continue"])
                return

        # map of bonus percentage per plot :
        bonusPercentPlot = {}
        bonusPlots = [landPlots, waterPlots]
        bonusPlotsExtra = [landPlotsExtra, waterPlotsExtra]

        for bWater in range(2) :
                for coord in bonusPlots[bWater] :
                        iX, iY = coord
                        bonusPercentPlot[coord] = [0, 0, 0, 0, 0, 0, 0, 0, 0] #nbTiles, nb bonuses, nbPro, nbFoo, nbLux, per, pro per, foo per, lux per
                        for iRing in range(4) :
                                for dX, dY in rings[iRing] :
                                        wTP = toWrap(iX + dX, iY + dY)
                                        if wTP != -1 :
                                                if (wTP in bonusPlots[bWater]) or (wTP in bonusPlotsExtra[bWater]) :
                                                        boPlTP = mapBonus[wTP[0]][wTP[1]]
                                                        if boPlTP != -1 :
                                                                bonusPercentPlot[coord][1] += 1
                                                                if boPlTP in lResPro : bonusPercentPlot[coord][2] += 1
                                                                elif boPlTP in lResFoo : bonusPercentPlot[coord][3] += 1
                                                                elif boPlTP in lResLux : bonusPercentPlot[coord][4] += 1
                                                        bonusPercentPlot[coord][0] += 1

        def updatePercents(iBD, x, y, bW) :
                if iBD in lResPro : iIN = 2
                elif iBD in lResFoo : iIN = 3
                else : iIN = 4
                for iRing in range(1, 4) :
                        for dX, dY in rings[iRing] :
                                wTP = toWrap(x + dX, y + dY)
                                if wTP != -1 :
                                        if wTP in bonusPlots[bW] :
                                                bonusPercentPlot[wTP][1] += 1
                                                bonusPercentPlot[wTP][5] = int(bonusPercentPlot[wTP][1]/float(bonusPercentPlot[wTP][0])*100)
                                                bonusPercentPlot[wTP][iIN] += 1
                                                bonusPercentPlot[wTP][4 + iIN] = int(bonusPercentPlot[wTP][iIN]/float(bonusPercentPlot[wTP][0])*100)

        # map of distance between bonuses and between bonus class :
        bonusDist = [[[ 8 for iY in range(iH) ] for iX in range(iW) ] for iBonus in range(nbRes) ]
        bonusClass = [ gc.getBonusInfo(iBonus).getBonusClassType() for iBonus in range(nbRes) ]
        nbClass = max(bonusClass) + 1
        bonusClassDist = [[[ 8 for iY in range(iH) ] for iX in range(iW) ] for iClass in range(nbClass) ]
        for i in range(4) :
                for coord in bonusPercentPlot.keys() :
                        bonusPercentPlot[coord][i + 5] = int(bonusPercentPlot[coord][i + 1]/float(bonusPercentPlot[coord][0])*100)

        def updateDistance(iBD, x, y) :
                iBCD = bonusClass[iBD]
                for iRing in range(8) :
                        for dX, dY in rings[iRing] :
                                wTP = toWrap(x + dX, y + dY)
                                if wTP != -1 :
                                        nX, nY = wTP
                                        bonusDist[iBD][nX][nY] = min(iRing, bonusDist[iBD][nX][nY])
                                        bonusClassDist[iBCD][nX][nY] = min(iRing, bonusClassDist[iBCD][nX][nY])

        for iX in range(iW) :
                for iY in range(iH) :
                        boPlTP = mapBonus[iX][iY]
                        if boPlTP == -1 : continue
                        updateDistance(boPlTP, iX, iY)

        # prevent group of bonus on bad terrain by scale :
        # if a bonus can only be place on snow for example ,and because there is not a lot of bonus for snow . Make it placed 1/2 only on good terrain
        bOnlyGood = [True for i in range(nbRes)]
        logList = [" Start Bonus Placement :"]
        originalNB = copy.deepcopy(nbPlaced)
        originalBTP = copy.deepcopy(nbBonusToPlace)
        lHillPlots = [coord for coord in lHillPlots if coord in bonusPlots[0]]
        for bWater in range(2) :
                for iBonus in range(nbRes) :
                        lPlotCanHaveBonus[iBonus][bWater] = [ coord for coord in lPlotCanHaveBonus[iBonus][bWater] if coord in bonusPlots[bWater] ]

        if bClimate :
                lLatPlot = [ [map.plot(iX, iY).getLatitude() for iY in range(iH) ] for iX in range(iW) ]

        def placeBonusAndUpdate(iBU, co, bWU) :
                pTempPlot = map.plot(co[0], co[1])
                terrainPlot = pTempPlot.getTerrainType()
                featurePlot = pTempPlot.getFeatureType()
                idHill = 0
                if pTempPlot.isHills() : idHill = 1
                if idHill == 1 : lHillPlots.remove(co)
                pTempPlot.setBonusType(iBU)
                bonusPlots[bWU].remove(co)
                del bonusPercentPlot[co]
                mapSort[terrainPlot][featurePlot + 1][idHill].remove(co)
                nbPlaced[iBU][bWU] += 1
                nbBonusToPlace[iBU][bWU] -= 1
                updatePercents(iBU, co[0], co[1], bWU)
                updateDistance(iBU, co[0], co[1])
                for iBI in lBonusWP :
                        if co in lPlotCanHaveBonus[iBI][bWU] :
                                lPlotCanHaveBonus[iBI][bWU].remove(co)

        def addBonusAway(iB, bWat) :
                if not bWat : bOnlyGood[iB] = not bOnlyGood[iB]
                iBC = bonusClass[iB]
                if iB in lResPro : iN = 2
                elif iB in lResFoo : iN = 3
                else : iN = 4

                lNaturalPlots = lPlotCanHaveBonus[iB][bWat]

                lOtherPlots = []
                if bWat :
                        for pl in lBonusExtend[iB] :
                                if pl[0] in waterTerrain :
                                        lOtherPlots += copy.copy(mapSort[pl[0]][pl[1]][pl[2]])

                if not bWat :
                        bOnlyWeak = (iB in bonusTerrainWeak) and (not iB in bonusTerrainGood)
                        for pl in lBonusExtend[iB] :
                                if pl[0] in landTerrain :
                                        if (bOnlyWeak) and (bOnlyGood[iB]) :
                                                if pl[0] in terrainWeak : continue
                                        lOtherPlots += copy.copy(mapSort[pl[0]][pl[1]][pl[2]])

                        if (lOtherPlots == []) and (bOnlyWeak) and (bOnlyGood[iB]) :
                                for pl in lBonusExtend[iB] :
                                        if pl[0] in landTerrain :
                                                if pl[0] in terrainWeak :
                                                        lOtherPlots += copy.copy(mapSort[pl[0]][pl[1]][pl[2]])
                lOtherPlots = [coord for coord in lOtherPlots if not coord in lNaturalPlots]

                if bClimate :
                        minLat = gc.getBonusInfo(iB).getMinLatitude()
                        maxLat = gc.getBonusInfo(iB).getMaxLatitude()
                        lOtherPlots = [ coord for coord in lOtherPlots if (lLatPlot[coord[0]][coord[1]] <= maxLat) and (lLatPlot[coord[0]][coord[1]] >= minLat) ]
                        
                allPlots = copy.copy(lNaturalPlots) + copy.copy(lOtherPlots)

                if allPlots == [] :
                        logList.append(" ... No more place for bonus %r (bWater %r)" %(gc.getBonusInfo(iB).getType(), bWat))
                        nbBonusToPlace[iB][bWat] = 0
                        return

                #Choose plots at max distance from same bonus , class (let range 1 for quality placement)
                maxDistClass = max([bonusClassDist[iBC][nX][nY] for nX, nY in allPlots])
                maxDistClass -= 1
                allPlots = [ coord for coord in allPlots if bonusClassDist[iBC][coord[0]][coord[1]] >= maxDistClass ]
                
                maxDistSBonus = max([bonusDist[iB][nX][nY] for nX, nY in allPlots])
                maxDistSBonus -= 1
                allPlots = [ coord for coord in allPlots if bonusDist[iB][coord[0]][coord[1]] >= maxDistSBonus ]

                if allPlots == [] :
                        logList.append(" ... allPlots == [] after bonus(class) sort (Strange) for bonus %r (bWater %r)" %(gc.getBonusInfo(iB).getType(), bWat))
                        nbBonusToPlace[iB][bWat] = 0
                        return

                #Choose plots with less percentage of bonus (& nat bonus) around
                lPlotBonPer = [bonusPercentPlot[coord][5] for coord in allPlots]
                minPer = min(lPlotBonPer)
                maxPer = max(lPlotBonPer)
                if maxPer > minPer :
                        minPer += int((maxPer-minPer)/3.0)
                minPer += 1
                allPlots = [ coord for coord in allPlots if bonusPercentPlot[coord][5] <= minPer ]

                iNPer = iN + 4        
                lPlotNatPer = [bonusPercentPlot[coord][iNPer] for coord in allPlots]
                minPer = min(lPlotNatPer)
                maxPer = max(lPlotNatPer)
                if maxPer > minPer :
                        minPer += int((maxPer-minPer)/3.0)
                minPer += 1
                allPlots = [ coord for coord in allPlots if bonusPercentPlot[coord][iNPer] <= minPer ]

                if allPlots == [] :
                        logList.append(" ... allPlots == [] percentage of bonus (& nat bonus) around (Strange) for bonus %r (bWater %r)" %(gc.getBonusInfo(iB).getType(), bWat))
                        nbBonusToPlace[iB][bWat] = 0
                        return

                #Try to choose the better matching tiles for bonuses , features non taken in count .
                lTemp = []
                if not bWat :
                        bOHill = gc.getBonusInfo(iB).isHills()
                        bOFlat = gc.getBonusInfo(iB).isFlatlands()

                        if (bOHill) and (not bOFlat) :
                                lTemp = [ coord for coord in allPlots if coord in lHillPlots ]

                        elif (not bOHill) and (bOFlat) :
                                lTemp = [ coord for coord in allPlots if not coord in lHillPlots ]

                if lTemp != [] : allPlots = copy.copy(lTemp)

                lTemp = [ coord for coord in allPlots if coord in lNaturalPlots ]

                if lTemp != [] : allPlots = copy.copy(lTemp)

                if allPlots == [] :
                        logList.append(" ... allPlots == [] (Strange) for bonus %r (bWater %r)" %(gc.getBonusInfo(iB).getType(), bWat))
                        nbBonusToPlace[iB][bWat] = 0
                        return

                #choose tile
                choice = getRandNum(len(allPlots), " FoR : addBonusAway plot rand")
                placeBonusAndUpdate(iB, allPlots[choice], bWat)

        #count the number of resources groups for resources that should be added close .
        nbGroup = [0 for i in range(nbRes)]
        for iBonus in lGroupRes :
                tpList = []
                for coord in listPlotBonus[iBonus] :
                        if coord in tpList : continue
                        tpList.append(coord)
                        nbGroup[iBonus] += 1
                        lPlotToTest = [coord]
                        while True :
                                if len(lPlotToTest) == 0 : break
                                iX, iY = lPlotToTest[0]
                                lPlotToTest.remove((iX, iY))
                                for iRing in range(1, 4) :
                                        for dX, dY in rings[iRing] :
                                                wTP = toWrap(iX + dX, iY + dY)
                                                if wTP != -1 :
                                                        if wTP in listPlotBonus[iBonus] :
                                                                if not wTP in tpList :
                                                                        tpList.append(wTP)
                                                                        lPlotToTest.append(wTP)
                
        def addBonusClose(iB, bWat) :
                if nbGroup[iB] < int(map.getWorldSize()) + 1 :
                        nbGroup[iB] += 1
                        addBonusAway(iB, bWat)
                        return

                if not bWat : bOnlyGood[iB] = not bOnlyGood[iB]
                iBC = bonusClass[iB]
                if iB in lResPro : iN = 2
                elif iB in lResFoo : iN = 3
                else : iN = 4

                lNaturalPlots = lPlotCanHaveBonus[iB][bWat]

                lOtherPlots = []
                if bWat :
                        for pl in lBonusExtend[iB] :
                                if pl[0] in waterTerrain :
                                        lOtherPlots += copy.copy(mapSort[pl[0]][pl[1]][pl[2]])

                if not bWat :
                        bOnlyWeak = (iB in bonusTerrainWeak) and (not iB in bonusTerrainGood)
                        for pl in lBonusExtend[iB] :
                                if pl[0] in landTerrain :
                                        if (bOnlyWeak) and (bOnlyGood[iB]) :
                                                if pl[0] in terrainWeak : continue
                                        lOtherPlots += copy.copy(mapSort[pl[0]][pl[1]][pl[2]])

                        if (lOtherPlots == []) and (bOnlyWeak) and (bOnlyGood[iB]) :
                                for pl in lBonusExtend[iB] :
                                        if pl[0] in landTerrain :
                                                if pl[0] in terrainWeak :
                                                        lOtherPlots += copy.copy(mapSort[pl[0]][pl[1]][pl[2]])
                lOtherPlots = [coord for coord in lOtherPlots if not coord in lNaturalPlots]

                if bClimate :
                        minLat = gc.getBonusInfo(iB).getMinLatitude()
                        maxLat = gc.getBonusInfo(iB).getMaxLatitude()
                        lOtherPlots = [ coord for coord in lOtherPlots if (lLatPlot[coord[0]][coord[1]] <= maxLat) and (lLatPlot[coord[0]][coord[1]] >= minLat) ]
                        
                allPlots = copy.copy(lNaturalPlots) + copy.copy(lOtherPlots)

                if allPlots == [] :
                        logList.append(" ... No more place for bonus %r (bWater %r)" %(gc.getBonusInfo(iB).getType(), bWat))
                        nbBonusToPlace[iB][bWat] = 0
                        return

                #Choose plots at max distance 3
                allPlots = [ coord for coord in allPlots if bonusDist[iB][coord[0]][coord[1]] <= 3]

                if allPlots == [] :
                        logList.append(" ... allPlots == [] after bonus dist for bonus %r (bWater %r) ... will try bonus away" %(gc.getBonusInfo(iB).getType(), bWat))
                        addBonusAway(iB, bWat)
                        return

                #Choose plots with less percentage of bonus (& nat bonus) around
                lPlotBonPer = [bonusPercentPlot[coord][5] for coord in allPlots]
                minPer = min(lPlotBonPer)
                maxPer = max(lPlotBonPer)
                if maxPer > minPer :
                        minPer += int((maxPer-minPer)/3.0)
                minPer += 1
                allPlots = [ coord for coord in allPlots if bonusPercentPlot[coord][5] <= minPer ]

                iNPer = iN + 4        
                lPlotNatPer = [bonusPercentPlot[coord][iNPer] for coord in allPlots]
                minPer = min(lPlotNatPer)
                maxPer = max(lPlotNatPer)
                if maxPer > minPer :
                        minPer += int((maxPer-minPer)/3.0)
                minPer += 1
                allPlots = [ coord for coord in allPlots if bonusPercentPlot[coord][iNPer] <= minPer ]

                if allPlots == [] :
                        logList.append(" bonus close ... allPlots == [] percentage of bonus (& nat bonus) around (Strange) for bonus %r (bWater %r)" %(gc.getBonusInfo(iB).getType(), bWat))
                        nbBonusToPlace[iB][bWat] = 0
                        return

                #Try to choose the better matching tiles for bonuses , features non taken in count .
                lTemp = []
                if not bWat :
                        bOHill = gc.getBonusInfo(iB).isHills()
                        bOFlat = gc.getBonusInfo(iB).isFlatlands()

                        if (bOHill) and (not bOFlat) :
                                lTemp = [ coord for coord in allPlots if coord in lHillPlots ]

                        elif (not bOHill) and (bOFlat) :
                                lTemp = [ coord for coord in allPlots if not coord in lHillPlots ]

                if lTemp != [] : allPlots = copy.copy(lTemp)

                lTemp = [ coord for coord in allPlots if coord in lNaturalPlots ]

                if lTemp != [] : allPlots = copy.copy(lTemp)

                if allPlots == [] :
                        logList.append(" bonus close ... allPlots == [] (Strange) for bonus %r (bWater %r)" %(gc.getBonusInfo(iB).getType(), bWat))
                        nbBonusToPlace[iB][bWat] = 0
                        return

                #choose tile
                choice = getRandNum(len(allPlots), " FoR : addBonusClose plot rand")
                placeBonusAndUpdate(iB, allPlots[choice], bWat)

        #arg ... place bonus now :)
        while True :
                bPlaceOne = False
                for bWater in range(2) :
                        for iBonus in range(nbRes) :
                                if nbBonusToPlace[iBonus][bWater] > 0 :
                                        bPlaceOne = True 
                                        if iBonus in lGroupRes :
                                                addBonusClose(iBonus, bWater)
                                        else :
                                                addBonusAway(iBonus, bWater)
                if not bPlaceOne : break

        for iBonus in range(nbRes):
                logList.append("%s :: Land : nbOri %d , nbToPlace %d , nbPlacedAfter %d ... diff %d" %(gc.getBonusInfo(iBonus).getType(), originalNB[iBonus][0], originalBTP[iBonus][0], nbPlaced[iBonus][0], nbPlaced[iBonus][0]-originalNB[iBonus][0]-originalBTP[iBonus][0]))
        logList.append("")

        for iBonus in range(nbRes):
                logList.append("%s :: Water : nbOri %d , nbToPlace %d , nbPlacedAfter %d ... diff %d" %(gc.getBonusInfo(iBonus).getType(), originalNB[iBonus][1], originalBTP[iBonus][1], nbPlaced[iBonus][1], nbPlaced[iBonus][1]-originalNB[iBonus][1]-originalBTP[iBonus][1]))
        logList.append("")

        writeLog("", True, logList)

def StoAddGoodies():
        writeLog(" = StoAddGoodies = ", False, [""])

        iGoody = gc.getInfoTypeForString("IMPROVEMENT_GOODY_HUT")
        if iGoody == -1 :
                writeLog("", True, [" There is no goody hut with this mod ..."])
                return
                
        goodyPer = getRandSel(selGen["terrain"]["goodyhut"]["goodypercent"], False, "float")
        iOptionGoody = gc.getInfoTypeForString("GAMEOPTION_NO_GOODY_HUTS")
        if iOptionGoody != -1 :
                if game.isOption(iOptionGoody) :
                        writeLog("", True, [" the option no goody is selected ..."])
                        return

        writeLog("", False, [" goody percent : %r" %goodyPer, ""])
        if goodyPer < 0.01 :
                writeLog("", True, ["", " goody percent < 0.01 don't launch the function ..."])
                return

        # store starting locations :
        listStartPlots = []
        for iPlayer in startPlots.keys() :
                listStartPlots.append(startPlots[iPlayer])

        # store all plots that can have a goody or would have a goody
        lGoodyPlots = []
        lNGPlots = []
        for iX in range(iW) :
                for iY in range(iH) :
                        pPlot = map.plot(iX, iY)

                        iBonus = pPlot.getBonusType(-1)
                        if iBonus != -1 : pPlot.setBonusType(-1)
                        iImprovement = pPlot.getImprovementType()
                        if iImprovement != -1 : pPlot.setImprovementType(-1)

                        bCanHaveGoody = bool(pPlot.canHaveImprovement(iGoody, -1, True))

                        if (iBonus != -1) or (iImprovement != -1) or ((iX, iY) in listStartPlots) :
                                if bCanHaveGoody : lNGPlots.append((iX, iY))
                                pPlot.setBonusType(iBonus)
                                pPlot.setImprovementType(iImprovement)
                                continue
                        
                        if bCanHaveGoody : lGoodyPlots.append((iX, iY))

        nbGoodyToAdd = int((len(lGoodyPlots) + len(lNGPlots))*goodyPer/100.0) + 1

        #debug
        logList = []
        logList.append(" nb tiles that can receive a goody : %r" %(len(lGoodyPlots), ))
        logList.append(" nb tiles that would receive a goody : %r" %(len(lNGPlots), ))
        logList.append(" nb Goody To Add : %r" %nbGoodyToAdd)
        logList.append("")
        writeLog("", False, logList)

        # assign a value to prevent small islands to ever have a goody
        dictPlotsPerArea = getAreaPlots()
        plotValues = [[7 for iY in range(iH)] for iX in range(iW)]
        for lList in dictPlotsPerArea["land"] :
                nbGP = 0
                lTPPlots = []
                for iX, iY in lList :
                        if (iX, iY) in lNGPlots :
                                nbGP += 1
                        elif (iX, iY) in lGoodyPlots :
                                nbGP += 1
                                lTPPlots.append((iX, iY))
                if nbGP < 3 : #no goody on small islands
                        for cPlot in lTPPlots :
                                lGoodyPlots.remove(cPlot)
                elif nbGP < 11 : #placement penality for medium islands
                        for iX, iY in lTPPlots :
                                val = (11 - nbGP) % 2
                                plotValues[iX][iY] = 7 - val

        rings = generateRings(7)
        nbGoodyPlaced = 0
        while True :
                if nbGoodyPlaced >= nbGoodyToAdd : break
                if len(lGoodyPlots) == 0 : break
                val = max([plotValues[iX][iY] for iX, iY in lGoodyPlots])
                tpList = [(iX, iY) for iX, iY in lGoodyPlots if plotValues[iX][iY] == val]
                iChoice = getRandNum(len(tpList), " FoR : goody plot rand")
                iX, iY = tpList[iChoice]
                areaPlotList = getListPlotsPerArea((iX, iY), dictPlotsPerArea)
                for iRing in range(1, 8) :
                        for dX, dY in rings[iRing] :
                                wTP = toWrap(iX + dX, iY + dY)
                                if wTP != -1 :
                                        if wTP in areaPlotList :
                                                plotValues[wTP[0]][wTP[1]] = min(iRing, plotValues[wTP[0]][wTP[1]])
                map.plot(iX, iY).setImprovementType(iGoody)
                lGoodyPlots.remove((iX, iY))
                nbGoodyPlaced += 1

        writeLog("", True, [" nb goody placed : %r" %nbGoodyPlaced])

def minStartingDistanceModifier():
        # keep original values in case default generation must be run
        if bGeneratingMap :
                if idMap in ["customcontinents", "bigandsmall", "hemispheres"] :
                        return -12
                elif idMap in ["hub", "ring", "wheel"] :
                        global bSuccessFlag
                        if bSuccessFlag == True:
                                return -95
                        else:
                                return -50
                elif idMap == "inlandsea" :
                        numPlrs = game.countCivPlayersEverAlive()
                        if numPlrs  <= 18:
                                return -95
                        else:
                                return -50
                elif idMap == "lakes" :
                        return -15
                elif idMap == "terra" :
                        return -20
	return 0

def assignStartingPlots() :
        global bStandardAssignment
        bStandardAssignment = False
        try :
                if StoAssignStartingPlots() :
                        return None
        except :
                writeLog("", True, ["", " An error occured during assign starting plots ... launch default impl"])
                writeError()
        writeLog("", False, [" assignStartingPlots : running default impl ....", ""])
        bStandardAssignment = True
        CyPythonMgr().allowDefaultImpl()

def StoAssignStartingPlots():
        writeLog(" = StoAssignStartingPlots = ", False, [""])

        bCoast = False
        bInland = False
        bSameArea = False

        if "start" in selGen["maps"][idMap].keys() :
                if 0 in selGen["maps"][idMap]["start"] : bCoast = True
                if 1 in selGen["maps"][idMap]["start"] : bInland = True
        elif "startterra" in selGen["maps"][idMap].keys() :
                if 0 in selGen["maps"][idMap]["startterra"] : bCoast = True
                if 1 in selGen["maps"][idMap]["startterra"] : bInland = True
                if 2 in selGen["maps"][idMap]["startterra"] : bSameArea = True
        if (not bCoast) and (not bInland) or (idMap == "lakes") :
                bCoast = True
                bInland = True

        logList = []
        logList.append(" bCoast : %r" %(bCoast, ))
        logList.append(" bInland : %r" %(bInland, ))
        logList.append(" bSameArea : %r" %(bSameArea, ))

	iRangeStart = max(12, int(sqrt((iH*iW)/nbPlayer)))
        logList.append(" iRangeStart : %r" %(iRangeStart, ))
        rings = generateRings(iRangeStart)
        dictPlotsPerArea = getAreaPlots()
        lPlayers = shuffleList(copy.copy(playerList))

        lakeSize = gc.getDefineINT("LAKE_MAX_AREA_SIZE")
        oceanSize = lakeSize + 1
        for iBuilding in range(gc.getNumBuildingInfos()) :
                buildingXML = gc.getBuildingInfo(iBuilding)
                if buildingXML.isWater() :
                        size = buildingXML.getMinAreaSize()
                        if size > oceanSize : oceanSize = int(size)
        for iUnit in range(gc.getNumUnitInfos()) :
                unitXML = gc.getUnitInfo(iUnit)
                if unitXML.getDomainType() == DomainTypes.DOMAIN_SEA :
                        size = unitXML.getMinAreaSize()
                        if size > oceanSize : oceanSize = int(size)

        logList.append(" lakeSize : %r" %(lakeSize, ))
        logList.append(" oceanSize : %r" %(oceanSize, ))

        # keep these values for later improvements
        bRemovePeaks = bool(getNormalizeRemovePeaks())
        bRemoveBadFeatures = bool(getNormalizeRemoveBadFeatures())
        bRemoveBadTerrains = bool(getNormalizeRemoveBadTerrain())
        bEraseBonus = copy.copy(selGen["resources"]["resourcesstart"]["removestartres"])
        # will guess that the player equalize bonuses if at least one additionnal bonus is added near starting location
        # (normalizations will do the rest, if not)
        if not bEraseBonus :
                for sOptionTag in selGen["resources"]["resourcesstart"].keys() :
                        if "startresselect-" in sOptionTag :
                                locTag = "startreslocation-" + str(splitTag(sOptionTag)[1])
                                if selGen["resources"]["resourcesstart"][locTag] == 0 :
                                        bEraseBonus = True
                                        break

        logList.append(" bRemovePeaks : %r" %(bRemovePeaks, ))
        logList.append(" bRemoveBadFeatures : %r" %(bRemoveBadFeatures, ))
        logList.append(" bRemoveBadTerrains : %r" %(bRemoveBadTerrains, ))
        logList.append(" bEraseBonus : %r" %(bEraseBonus, ))
        logList.append("")
        writeLog("", False, logList)

        nbRes = gc.getNumBonusInfos()
        nbTerrain = gc.getNumTerrainInfos()
        nbFeature = gc.getNumFeatureInfos()

        landTerrain = []
        waterTerrain = []
        for iTerrain in range(nbTerrain) :
                terrainXML = gc.getTerrainInfo(iTerrain)
                if terrainXML.isGraphicalOnly() : continue
                if terrainXML.isWater() : waterTerrain.append(iTerrain)
                else : landTerrain.append(iTerrain)

        terrainWeak = []
        terrainGood = []
        yieldTerrain = {}
        for iTerrain in landTerrain :
                yieldTerrain[iTerrain] = [gc.getTerrainInfo(iTerrain).getYield(iYield) for iYield in (YieldTypes.YIELD_FOOD, YieldTypes.YIELD_PRODUCTION)]
                if sum(yieldTerrain[iTerrain]) < 2 : terrainWeak.append(iTerrain)
                else : terrainGood.append(iTerrain)

        listFeature = []
        featureWeak = []
        featureGood = [-1]
        yieldFeature = {}
        yieldFeature[-1] = 0
        for iFeature in range(nbFeature) :
                featureXML = gc.getFeatureInfo(iFeature)
                yieldFeature[iFeature] = sum([featureXML.getYieldChange(iYield) for iYield in (YieldTypes.YIELD_FOOD, YieldTypes.YIELD_PRODUCTION)])
                if (yieldFeature[iFeature] < 0) or (featureXML.isImpassable()) : featureWeak.append(iFeature)
                else : featureGood.append(iFeature)

        lNoStartTerrain = [gc.getInfoTypeForString('TERRAIN_SNOW'), gc.getInfoTypeForString('TERRAIN_TUNDRA')]

        areaList = []
        for listPlots in dictPlotsPerArea["land"] :
                areaValue = 0
                for iX, iY in listPlots :
                        pPlot = map.plot(iX, iY)
                        if (pPlot.isPeak()) or (pPlot.isImpassable()) :
                                continue
                        if pPlot.getTerrainType() in terrainGood :
                                areaValue += 2
                        elif pPlot.calculateTotalBestNatureYield(TeamTypes.NO_TEAM) > 2 :
                                areaValue += 2
                        else :
                                areaValue += 1
                areaList.append([areaValue, listPlots])

        areaList.sort()
        areaList.reverse()

        def makeMask(co, ir) :
                lL = []
                iX, iY = co
                for iR in range(ir + 1) :
                        for dX, dY in rings[iR] :
                                wTP = toWrap(iX + dX, iY + dY)
                                if wTP != -1 :
                                        lL.append(wTP)
                return lL

        logList = []
        # area assignment
        bOtherAssignment = False
        if (idMap == "customcontinents") and (len(teamList)<7) :
                if cmo[0] == 1 :
                        shuffleT = shuffleList(copy.copy(teamList))
                        lPTeams = [ [iPlayer for iPlayer in playerList if gc.getPlayer(iPlayer).getTeam() == iTeam] for iTeam in shuffleT ]
                        lLenTeams = [len(item) for item in lPTeams]
                        lLenTeams = list(set(lLenTeams))
                        lLenTeams.sort()
                        lLenTeams.reverse()
                        lPlayersPerTeam = []
                        for i in range(len(lLenTeams)) :
                                lPlayersPerTeam += [ item for item in lPTeams if len(item) == lLenTeams[i] ]

                        if len(lPlayersPerTeam) <= len(areaList) :
                                bOtherAssignment = True
                                areaPlayer = [ [lPlayersPerTeam[i], areaList[i][1]] for i in range(len(lPlayersPerTeam)) ]

        if idMap in ["hub", "ring", "wheel"] :
                if bSuccessFlag :
                        shuffleP = shuffleList(copy.copy(playerList))
                        sPlotPerPlayer = []
                        for region_loop in range(len(shuffleP)):
                                [regWestX, regEastX, regSouthY, regNorthY] = region_data[region_loop]
                                regWidth = regEastX - regWestX + 1
                                regHeight = regNorthY - regSouthY + 1
                                iStartX = regWestX + int(regWidth / 2)
                                iStartY = regSouthY + int(regHeight / 2)
                                sPlotPerPlayer.append((iStartX, iStartY))

                        minAirDist = 100000
                        for iPlayer1 in range(len(shuffleP)) :
                                for iPlayer2 in range(iPlayer1 + 1, len(shuffleP)) :
                                        distP = calculateAirDistance(sPlotPerPlayer[iPlayer1], sPlotPerPlayer[iPlayer2])
                                        if distP < minAirDist : minAirDist = distP

                        iShiftRange = max(min(int(minAirDist/3.5), 12), 3)

                        BAllGoods = True
                        areaPlayer = []
                        for region_loop in range(len(shuffleP)):
                                [regWestX, regEastX, regSouthY, regNorthY] = region_data[region_loop]
                                centerPlot = sPlotPerPlayer[region_loop]
                                maskAPlots = makeMask(centerPlot, iShiftRange)

                                lPlayerAroundPlots = []
                                if idMap == "hub" :
                                        # be sure a player is in his own region (got 2 players in the same region once)
                                        clearPlot = -1
                                        iX, iY = centerPlot
                                        for iRing in range(5) :
                                                if clearPlot != -1 : break
                                                for dX, dY in rings[iRing] :
                                                        wTP = toWrap(iX + dX, iY + dY)
                                                        if wTP != -1 :
                                                                pLoopPlot = map.plot(wTP[0], wTP[1])
                                                                if pLoopPlot.isWater() : continue
                                                                if pLoopPlot.isPeak() : continue
                                                                if pLoopPlot.isImpassable() : continue
                                                                clearPlot = wTP
                                                                break

                                        if clearPlot != -1 :
                                                iX, iY = clearPlot
                                                pCenterPlot = map.plot(iX, iY)
                                                for areaValue, lRegionPlots in areaList :
                                                        for coord in maskAPlots :
                                                                dX, dY = coord
                                                                if not coord in lRegionPlots : continue
                                                                if regWestX >= dX : continue
                                                                if regEastX <= dX : continue
                                                                if regSouthY >= dY : continue
                                                                if regNorthY <= dY : continue
                                                                pRegionPlot = map.plot(dX, dY)
                                                                if pRegionPlot.isWater() : continue
                                                                if pRegionPlot.isPeak() : continue
                                                                if pRegionPlot.isImpassable() : continue
                                                                pathDist = map.calculatePathDistance(pCenterPlot, pRegionPlot)
                                                                map.resetPathDistance()
                                                                if pathDist == -1 : continue
                                                                if pathDist > 2 * max(abs(iX - dX), abs(iY - dY)) : continue
                                                                lPlayerAroundPlots.append(coord)
                                                        if lPlayerAroundPlots != [] : break
                                else :
                                        # loop over best list of plots (even if the regions should all be connected, got two separate hub one time ... the default impl should have WOC in this case)
                                        for areaValue, lRegionPlots in areaList :
                                                lPlayerAroundPlots = [ coord for coord in maskAPlots if (coord in lRegionPlots) and (regWestX<coord[0]<regEastX) and (regSouthY<coord[1]<regNorthY)]
                                                if lPlayerAroundPlots != [] : break

                                if lPlayerAroundPlots == [] :
                                        BAllGoods = False
                                        logList.append(" can't define a player zone for hub, ring or wheel ...")
                                        break

                                areaPlayer.append([[shuffleP[region_loop]], lPlayerAroundPlots])

                        if BAllGoods :
                                bOtherAssignment = True

        if not bOtherAssignment :
                if bSameArea :
                        areaPlayer = [ [lPlayers, areaList[0][1]] ]
                else :
                        areaPlayer = [ [[], areaList[i][1]] for i in range(len(areaList)) ]
                        for iPlayer in lPlayers :
                                bestArea = -1
                                bestIndex = -1
                                for i in range(len(areaPlayer)) :
                                        nArea = len(areaPlayer[i][1]) / (len(areaPlayer[i][0]) + 1)
                                        if nArea > bestArea :
                                                bestArea = nArea
                                                bestIndex = i
                                areaPlayer[bestIndex][0].append(iPlayer)
        logList.append(" areaList : %r" %([ [item[0], len(item[1])] for item in areaPlayer if item[0] != [] ], ))

        # coastal value change
        coastalValue = {}
        lCountPlots = []
        for lPl, lPlo in areaPlayer :
                if len(lPl) > 0 :
                        for coord in lPlo : coastalValue[coord] = [4, 0, 0] #dist ocean, coastal ocean value, nb lakes tiles

        lCountPlots = coastalValue.keys()

        for lWPlots in dictPlotsPerArea["water"] :
                bOcean = True
                if len(lWPlots) < oceanSize : bOcean = False
                for coord in lWPlots :
                        iX, iY = coord
                        if bOcean :
                                val = 2
                                if map.plot(iX, iY).isAdjacentToLand() : val = 1
                        for iRing in range(1, 4) :
                                for dX, dY in rings[iRing] :
                                        wTP = toWrap(iX + dX, iY + dY)
                                        if wTP != -1 :
                                                if wTP in lCountPlots :
                                                        if bOcean :
                                                                coastalValue[wTP][0] = min(iRing, coastalValue[wTP][0])
                                                                coastalValue[wTP][1] += val
                                                        elif iRing < 3 :
                                                                coastalValue[wTP][2] += 1

        # found values (based on original found values , no poles start , found value decrease if lots of water)
        #!! make my own plot value with normalizations defined and bonuses
        for iPlayer in playerList :
                gc.getPlayer(iPlayer).AI_updateFoundValues(True)

        lC = [[] for i in range(4)]
        foundValues = {}
        for coord in lCountPlots :
                coastDist = coastalValue[coord][0]
                coastVal = coastalValue[coord][1]
                lakeVal = coastalValue[coord][2]
                lC[coastDist - 1].append(coord)
                foundValues[coord] = {}
                valuePer = 1
                pPlot = map.plot(coord[0], coord[1])

                if pPlot.getTerrainType() in lNoStartTerrain :
                        valuePer = 0
                elif coastVal > 0 : # default found values already take in count water tiles as bad tiles , increase this effect
                        if coastDist == 1 :
                                if coastVal > 4 :
                                        valuePer = 0.92
                                elif coastVal > 7 :
                                        valuePer = 0.87
                                elif coastVal > 10 :
                                        valuePer = 0.82
                                elif coastVal > 13 :
                                        valuePer = 0.70
##                        elif coastDist == 2 :
##                                valuePer -= coastVal*0.05
                if coastDist == 3 : # Inland start better at at lest 3 tiles from the ocean
                        valuePer -= 0.1
                valuePer = max(0, valuePer - lakeVal*0.02)

                for iPlayer in playerList :
                        foundValues[coord][iPlayer] = int(pPlot.getFoundValue(iPlayer)* valuePer)

        #!! make values in function of size and nb players
        nbAttempts = 8
        minDist = 7
        maxDist = 10
        perValue = 0.84
        bAssign = True

        def initG() :
                global maskMinDistPlots
                global maskMaxDistPlots
                global plotsAssigned

                maskMinDistPlots = []
                maskMaxDistPlots = []
                plotsAssigned = {}

        initG()

        def placePlayersInArea(lP, lPlots, iRange) :
                lResult = [ [-1, []] for i in range(nbAttempts) ]

                for iAttempt in range(nbAttempts) :
                        minVal = -1
                        maxVal = 0
                        listPl = copy.deepcopy(lPlots)

                        for iPlayer in lP :
                                lValuePlots = [ (foundValues[coord][iPlayer], coord) for coord in listPl ]
                                limValMin = int(maxVal*(perValue - iAttempt * 0.02))
                                lValuePlots = [ item for item in lValuePlots if item[0] > limValMin ]

                                if lValuePlots == [] : break

                                lValuePlots.sort()
                                lValuePlots.reverse()

                                nbR = min(3, len(lValuePlots))

                                iChoice = getRandNum(nbR, "FoR : Start Plot choice")

                                val, pCoord = lValuePlots[iChoice]

                                if val > maxVal : maxVal = val
                                if (val < minVal) or (minVal == -1) : minVal = val

                                lResult[iAttempt][0] = minVal
                                lResult[iAttempt][1].append([iPlayer, pCoord])

                                tpMask = makeMask(pCoord, iRange)
                                listPl = [coord for coord in listPl if not coord in tpMask]

                bestVal = -1
                bestList = []
                for iAttempt in range(nbAttempts) :
                        val, lPPList = lResult[iAttempt]

                        if len(lPPList) > len(bestList) :
                                bestVal = val
                                bestList = lPPList
                        elif (val > bestVal) and (len(lPPList) == len(bestList)) :
                                bestVal = val
                                bestList = lPPList

                return bestList

        def placePlayersOneArea(lPl, lBPlots):
                global maskMinDistPlots
                global maskMaxDistPlots
                global plotsAssigned

                logList.append(" place player (%r) for one area : %r" %(lPl, len(lBPlots)))

                lValidPlots = []
                if bCoast :
                        lValidPlots += [coord for coord in lBPlots if coord in lC[0]]
                if (lValidPlots == []) or (bInland) :
                        lValidPlots += [coord for coord in lBPlots if coord in lC[2]]
                        lValidPlots += [coord for coord in lBPlots if coord in lC[3]]
                        if (not bCoast) and (lValidPlots == []) : #island inland start !?
                                lValidPlots += [coord for coord in lBPlots if coord in lC[0]]

                if lValidPlots == [] :  return False

                lVPlots = [coord for coord in lValidPlots if not coord in maskMaxDistPlots]

                iRS = copy.copy(iRangeStart)
                bReduceMinimalDist = False

                while True :
                        if iRS < 7 : break
                        if (iRS < 10) and (not bReduceMinimalDist) :
                                bReduceMinimalDist = True
                                lVPlots = [coord for coord in lValidPlots if not coord in maskMinDistPlots]

                        if lVPlots == [] :
                                iRS -= 1
                                continue

                        lResAss = placePlayersInArea(lPl, lVPlots, iRS)

                        diffPlacements = len(lPl) - len(lResAss)
                        
                        logList.append(" nb player placed for range %r : %r" %(iRS, len(lResAss)))

                        if diffPlacements == 0 :
                                for iPlayer, coord in lResAss :
                                        plotsAssigned[iPlayer] = coord
                                        maskMinDistPlots += makeMask(coord, minDist)
                                        maskMaxDistPlots += makeMask(coord, maxDist)
                                logList.append(" all players placed in this area -> continue")
                                logList.append("")
                                return True

                        if iRS > 18 :
                                iRS -= min(3, diffPlacements)
                        elif iRS > 14 :
                                iRS -= min(2, diffPlacements)
                        else :
                                iRS -= 1

                logList.append("")
                return False
                        

        for lPlay, lPlo in areaPlayer :
                if lPlay == [] : continue
                if idMap == "chess" :
                        lPlo = [plotCoords for plotCoords in lPlo if (plotCoords[0]%6 == 3) and (plotCoords[1]%6 == 2)]
                                
                if not placePlayersOneArea(lPlay, lPlo) :
                        bAssign = False
                        logList.append(" can't place all players in one area ...")
                        logList.append("")
                        break

        if not bAssign :
                if (bCoast) and (not bInland) :
                        bInland = True
                        initG()
                        for lPlay, lPlo in areaPlayer :
                                if lPlay == [] : continue
                                if idMap == "chess" :
                                        lPlo = [plotCoords for plotCoords in lPlo if (plotCoords[0]%6 == 3) and (plotCoords[1]%6 == 2)]

                                if not placePlayersOneArea(lPlay, lPlo) :
                                        logList.append(" coast start : can't place all players in one area after adding inland plots")
                                        writeLog("", True, logList)
                                        return False
                else :
                        writeLog("", True, logList)
                        return False

        for iPlayer in plotsAssigned.keys() : 
                startPlot = map.plot(plotsAssigned[iPlayer][0], plotsAssigned[iPlayer][1])
                startPlot.setStartingPlot(True)
                gc.getPlayer(iPlayer).setStartingPlot(startPlot, True)

        writeLog("", True, logList)
        return True

def normalizeStartingPlotLocations():
        initPlayerList(True) # store starting locations

        #Done after player assignments to prevent a good place to be skipped in case of lots of goodies
        try :
                StoAddGoodies()
        except :
                writeLog("", True, ["", " An error occured during goody generation ..."])
                writeError()

        #For MP games , humans are as far away as possible between them
        if isGameMP and selGen["startlocs"]["relocate"]["swaphuman"] :
                try :
                        if swapHumanPlayers() :
                                return None
                except :
                        writeLog("", False, ["", " An error occured during sawp humans ..."])
                        writeError()

        iNorm = selGen["startlocs"]["normalize"]["startplot"]
        if iNorm == 2 :
                return None
        elif iNorm == 1 :
                pass
        elif idMap == "customcontinents" :
                if cmo[0] != 1 or game.countCivTeamsAlive() > 6:
                        pass
                else :
                        return None
        CyPythonMgr().allowDefaultImpl()

def swapHumanPlayers():
        nbAIPlayer = len(playerAIList)
        nbHUPlayer = len(playerHUList)

        if nbAIPlayer == 0 :
                writeLog("", False, ["", " swapHumanPlayers : no AI players , don't launch the function ..."])
                return False

        bAreaAssignment = True
        if nbHUPlayer > nbAIPlayer :
                writeLog("", False, ["", " swapHumanPlayers : more human than AI , use air placement only"])
                bAreaAssignment = False

        nbAIperHUmin = nbAIPlayer / nbHUPlayer
        if ((float(nbAIPlayer) / nbHUPlayer) - nbAIperHUmin) > 0.6 : nbAIperHUmin += 1

        logList = [""]
        logList.append(" swapHumanPlayers, nbAIPlayer : %r" %nbAIPlayer)
        logList.append(" swapHumanPlayers, nbHUPlayer : %r" %nbHUPlayer)
        logList.append(" swapHumanPlayers, nbAIperHUmin : %r" %nbAIperHUmin)
        writeLog("", False, logList)

        playerGroups = []
        playerTested = []

        distances = {}
        for iPlayer in playerList :
                for iPlayer2 in playerList :
                        if iPlayer2 == iPlayer : continue
                        distL = map.calculatePathDistance( map.plot(startX[iPlayer], startY[iPlayer]), map.plot(startX[iPlayer2], startY[iPlayer2]))
                        distA = calculateAirDistance(startPlots[iPlayer], startPlots[iPlayer2])
                        distances[(iPlayer, iPlayer2)] = [distL, distA]
                        map.resetPathDistance() # AAAAAAARRRGGGG !!! never forget this ... 1 day of tests and bug searching because of that ^^

        for iPlayer in playerList :
                if iPlayer in playerTested : continue
                playerTested.append(iPlayer)
                tpGroup = [iPlayer]
                for iPlayer2 in playerList :
                        if iPlayer2 in playerTested : continue
                        dist = distances[(iPlayer, iPlayer2)][0]
                        if dist <= 0 : continue
                        playerTested.append(iPlayer2)
                        tpGroup.append(iPlayer2)
                playerGroups.append(tpGroup)

        assignGroup = [[] for i in range(len(playerGroups))]
        nbPlayersPerGroup = [len(group) for group in playerGroups]

        # all players in one area : force path placement
        if len(playerGroups) == 1 :
                nbAIperHUmin = -1
                bAreaAssignment = True
                writeLog("", False, ["", " swapHumanPlayers : all players in one area , force path placement"])

        for iHumanPlayer in shuffleList(copy.copy(playerHUList)) :
                if not bAreaAssignment : break
                values = [ nbPlayersPerGroup[i] - len(assignGroup[i])*nbAIperHUmin -1 for i in range(len(playerGroups))]
                maxVal = max(values)
                if maxVal <= 0 : break
                lIndexGroups = [ i for i in range(len(playerGroups)) if values[i] == maxVal ]
                iIndex = lIndexGroups[getRandNum(len(lIndexGroups), " FoR : assgin player to group")]
                assignGroup[iIndex].append(iHumanPlayer)

        newPlace = {}
        for iHumanPlayer in playerHUList : newPlace[iHumanPlayer] = -1
        assignedPlace = []

        # First place each player in the groups with at least two human players
        for iGroup in range(len(playerGroups)) :
                lHumanGroup = assignGroup[iGroup]
                lPlayerGroup = playerGroups[iGroup]
                nbHU = len(lHumanGroup)
                if nbHU < 2 : continue

                bestList = -1
                bestCombi = -1
                for combi in Cnp(len(lPlayerGroup), nbHU) :
                        lPlayers = [lPlayerGroup[iIndex] for iIndex in combi]
                        listDist = [distances[(lPlayers[i], lPlayers[j])][0] for i, j in Cnp(nbHU, 2)]
                        listDist.sort()
                        if bestCombi == -1 :
                                bestList = copy.copy(listDist)
                                bestCombi = copy.copy(lPlayers)
                        elif listDist > bestList :
                                bestList = copy.copy(listDist)
                                bestCombi = copy.copy(lPlayers)

                assignedPlace += copy.copy(bestCombi)

                for i in range(len(lHumanGroup)) :
                        newPlace[lHumanGroup[i]] = bestCombi[i]

        writeLog("", False, ["", " swapHumanPlayers : assigned Players after groups (more than 2 HU) : %r" %newPlace])

        # Then place humans on one human group :
        lOneHumanGroup = [iGroup for iGroup in range(len(playerGroups)) if len(assignGroup[iGroup]) == 1]
        if lOneHumanGroup != [] :
                if (len(lOneHumanGroup) == 1) and (assignedPlace == []) :
                        iGroup = lOneHumanGroup[0]
                        iHumanPlayer = assignGroup[iGroup][0]
                        lPlayerGroup = playerGroups[iGroup]
                        iChoice = getRandNum(len(lPlayerGroup), " FoR : one area human placement choice")
                        iPlayer = lPlayerGroup[iChoice]
                        assignedPlace.append(iPlayer)
                        newPlace[iHumanPlayer] = iPlayer

                        writeLog("", False, ["", " swapHumanPlayers : assigned Players after only one human group , no assignment done already : %r" %newPlace])

                else : #place players with max dist by air
                        listPlayers = [[]]
                        for iIndex in range(len(lOneHumanGroup)) :
                                tpList = []
                                for lList in listPlayers :
                                        for iPlayer in playerGroups[lOneHumanGroup[iIndex]] :
                                                nList = lList + [iPlayer]
                                                tpList.append(nList)
                                listPlayers = tpList
                        listPlayers = [item + assignedPlace for item in listPlayers]

                        bestList = -1
                        listDist = []
                        for lList in listPlayers :
                                listDistTp = [distances[(lList[i], lList[j])][1] for i, j in Cnp(len(lList), 2)]
                                listDistTp.sort()

                                if bestList == -1 :
                                        bestList = copy.copy(lList)
                                        listDist = copy.copy(listDistTp)
                                elif listDistTp > listDist :
                                        bestList = copy.copy(lList)
                                        listDist = copy.copy(listDistTp)
                        
                        assignedPlace += bestList[0:len(lOneHumanGroup)]

                        for i in range(len(lOneHumanGroup)) :
                                iGroup = lOneHumanGroup[i]
                                iHumanPlayer = assignGroup[iGroup][0]
                                newPlace[iHumanPlayer] = bestList[i]

                        writeLog("", False, ["", " swapHumanPlayers : assigned Players after one human groups : %r" %newPlace])

        # place the rest of players by air :
        if len(assignedPlace) != nbHUPlayer :
                playersToPlace = shuffleList([iPlayer for iPlayer in playerHUList if newPlace[iPlayer] == -1])
                availablePlace = [iPlayer for iPlayer in playerList if not iPlayer in assignedPlace]

                listPlayers = [ [availablePlace[i] for i in lCombi] + assignedPlace for lCombi in Cnp(len(availablePlace), len(playersToPlace)) ]

                bestList = -1
                listDist = []
                for lList in listPlayers :
                        listDistTp = [distances[(lList[i], lList[j])][1] for i, j in Cnp(len(lList), 2)]
                        listDistTp.sort()

                        if bestList == -1 :
                                bestList = copy.copy(lList)
                                listDist = copy.copy(listDistTp)
                        elif listDistTp > listDist :
                                bestList = copy.copy(lList)
                                listDist = copy.copy(listDistTp)
                
                assignedPlace += bestList[0:len(playersToPlace)]

                for i in range(len(playersToPlace)) :
                        iHumanPlayer = playersToPlace[i]
                        newPlace[iHumanPlayer] = bestList[i]

                writeLog("", False, ["", " swapHumanPlayers : assigned Players rest of available players : %r" %newPlace])

        # swap player places
        availablePlace = [ iPlayer for iPlayer in playerList if not iPlayer in assignedPlace ]

        for iPlayer in playerList :
                if iPlayer in playerHUList :
                        stPlot = map.plot(startX[newPlace[iPlayer]], startY[newPlace[iPlayer]])
                        gc.getPlayer(iPlayer).setStartingPlot(stPlot, False)
                else :
                        iChoice = getRandNum(len(availablePlace), " FoR : AI swap place")
                        iPlayerPlaced = availablePlace[iChoice]
                        del availablePlace[iChoice]
                        stPlot = map.plot(startX[iPlayerPlaced], startY[iPlayerPlaced])
                        gc.getPlayer(iPlayer).setStartingPlot(stPlot, True)

        writeLog("", False, [""])
        return True

def normalizeAddRiver():
        initPlayerList(True) # reinit starting locations , in case of a change in normalizeStartingPlotLocations (team or cultural locations)

        iNorm = selGen["startlocs"]["normalize"]["addriver"]
        if (iNorm == 2) or (idMap == "chess") :
                return None
        elif iNorm == 1 :
                pass
	CyPythonMgr().allowDefaultImpl()

def normalizeRemovePeaks():
        #sometimes when creating a river , you can have some desert tiles without floodplains for an example .
        listRiverFeatures = []
        for iFeature in range(gc.getNumFeatureInfos()):
                featureXML = gc.getFeatureInfo(iFeature)
                if featureXML.getAppearanceProbability() < 10000 : continue
                if featureXML.isRequiresRiver() : listRiverFeatures.append(iFeature)
        writeLog("", False, ["", " normalizeRemovePeaks , list of feature to check after normalizeAddRiver : %r" %[gc.getFeatureInfo(i).getType() for i in listRiverFeatures], ""])
        for plotIndex in range(iW * iH):
                pPlot = map.plotByIndex(plotIndex)
                if pPlot.isNone() :
                        writeLog("", False, [" normalizeRemovePeaks , a plot is none ... need to be checked , index : %d" %plotIndex, ""])
                        continue
                if pPlot.isWater() : continue
                if not pPlot.isRiver() : continue
                if pPlot.getFeatureType() != -1 : continue
                if pPlot.getBonusType(-1) != -1 : continue
                for iFeature in listRiverFeatures :
                        if pPlot.canHaveFeature(iFeature):
                                pPlot.setFeatureType(iFeature, -1)
                                break

        if not getNormalizeRemovePeaks() : return None
	CyPythonMgr().allowDefaultImpl()

def getNormalizeRemovePeaks():
        iNorm = selGen["startlocs"]["normalize"]["removepeak"]
        if (iNorm == 2) or (idMap == "chess") :
                return False
        elif iNorm == 1 :
                return True
        elif idMap in ["archipelago", "hub", "islands", "maze", "ring", "wheel"] :
                return False
        return True

def normalizeAddLakes():
        iNorm = selGen["startlocs"]["normalize"]["addlake"]
        if (iNorm == 2)  or (idMap == "chess"):
                return None
        elif iNorm == 1 :
                pass
	CyPythonMgr().allowDefaultImpl()

def normalizeRemoveBadFeatures():
        if not getNormalizeRemoveBadFeatures() : return None
	CyPythonMgr().allowDefaultImpl()

def getNormalizeRemoveBadFeatures():
        iNorm = selGen["startlocs"]["normalize"]["removebadfeature"]
        if iNorm == 2 :
                return False
        elif iNorm == 1 :
                return True
	return True

def normalizeRemoveBadTerrain():
        if not getNormalizeRemoveBadTerrain() : return None
	CyPythonMgr().allowDefaultImpl()

def getNormalizeRemoveBadTerrain():
        iNorm = selGen["startlocs"]["normalize"]["removebadterrain"]
        if iNorm == 2 :
                return False
        elif iNorm == 1 :
                return True
        elif idMap in ["hub", "ring", "wheel"] :
                return False
	return True

def normalizeAddFoodBonuses():
        iNorm = selGen["startlocs"]["normalize"]["addfoodbonus"]
        if iNorm == 2 :
                return None
        elif iNorm == 1 :
                pass
	CyPythonMgr().allowDefaultImpl()

def normalizeAddGoodTerrain():
        iNorm = selGen["startlocs"]["normalize"]["addgoodterrain"]
        if iNorm == 2 :
                return None
        elif iNorm == 1 :
                pass
        elif idMap in ["hub", "ring", "wheel"] :
                return None
	CyPythonMgr().allowDefaultImpl()

def normalizeAddExtras():
        global bGeneratingMap
        bGeneratingMap = False

        #add extra starting bonuses
        try :
                StoAddStartBonuses()
        except :
                writeLog("", True, ["", " An error occured during start bonus implementation ..."])
                writeError()

        if canUseGameOptions :
                initStoAddEvent()
                CyMessageControl().sendApplyEvent(getattr(CvUtil, "Sto_FullOfResources_AddGameElements_EventID"), EventContextTypes.EVENTCONTEXT_SELF, (game.getActivePlayer(),))

        iNorm = selGen["startlocs"]["normalize"]["addextra"]
        if iNorm == 2 :
                return None
        elif iNorm == 1 :
                pass
	CyPythonMgr().allowDefaultImpl()

def StoAddStartBonuses():
        global lBonusExtend
        writeLog(" = StoAddBonuses = ", False, [""])

        #CyMapGenerator().eraseBonuses()

        natRes = genNatureRes()
        nbRes = gc.getNumBonusInfos()
        nbTerrain = gc.getNumTerrainInfos()
        nbFeature = gc.getNumFeatureInfos()

        lResPro = [iBonus for iBonus in range(nbRes) if ((gc.getBonusInfo(iBonus).getType() in XMLEntriesList["strategic"]) and (natRes[iBonus][0] == 0))]
        lResFoo = [iBonus for iBonus in range(nbRes) if ((gc.getBonusInfo(iBonus).getType() in XMLEntriesList["health"]) and (natRes[iBonus][0] == 1))]
        lResLux = [iBonus for iBonus in range(nbRes) if ((gc.getBonusInfo(iBonus).getType() in XMLEntriesList["happiness"]) and (natRes[iBonus][0] == 2))]
        lRes = copy.copy(lResPro) + copy.copy(lResFoo) + copy.copy(lResLux)
        lResLand = [iBonus for iBonus in range(nbRes) if ((gc.getBonusInfo(iBonus).getType() in XMLEntriesList["land"]) and (natRes[iBonus][1]))]
        lResWater = [iBonus for iBonus in range(nbRes) if ((gc.getBonusInfo(iBonus).getType() in XMLEntriesList["water"]) and (natRes[iBonus][2]))]

	bEraseAll = copy.copy(selGen["resources"]["resourcesstart"]["removestartres"])
        lResProNoRand = [iBonus for iBonus in range(nbRes) if ((gc.getBonusInfo(iBonus).getType() in selGen["resources"]["resourcesstart"]["strategicnorandom"]) and (natRes[iBonus][0] == 0))]
        lResFooNoRand = [iBonus for iBonus in range(nbRes) if ((gc.getBonusInfo(iBonus).getType() in selGen["resources"]["resourcesstart"]["healthnorandom"]) and (natRes[iBonus][0] == 1))]
        lResLuxNoRand = [iBonus for iBonus in range(nbRes) if ((gc.getBonusInfo(iBonus).getType() in selGen["resources"]["resourcesstart"]["happinessnorandom"]) and (natRes[iBonus][0] == 2))]

        lStartRes = []
        for sOption2 in selGen["resources"]["resourcesstart"].keys() :
                if sOption2[0:15] == "startresselect-" :
                        if selGen["resources"]["resourcesstart"][sOption2] == [] : continue
                        sIndex = sOption2[15:]
                        lTemp = []
                        for sOption in ["startresselect-", "startresquantity-", "startreslocation-", "startresforce-", "startresplayer-"] :
                                lTemp.append(copy.deepcopy(selGen["resources"]["resourcesstart"][sOption + sIndex]))
                        lStartRes.append([int(sIndex), lTemp])

        lStartRes.sort()
        lStartRes = [item[1] for item in lStartRes]

        logList = [""]
        logList.append(" bEraseAll : %r" %bEraseAll)
        logList.append(" lResProNoRand : %r" %lResProNoRand)
        logList.append(" lResFooNoRand : %r" %lResFooNoRand)
        logList.append(" lResLuxNoRand : %r" %lResLuxNoRand)
        for item in lStartRes :
                logList.append(repr(item))
        if len(lStartRes) == 0 : logList.append(" No start resources selected : skip")
        writeLog("", False, logList)

        if len(lStartRes) == 0 :
                writeLog("", True, [])
                return

        dictPlotsPerArea = getAreaPlots()
        dictBonus = {}
        for iPlayer in playerList :
                dictBonus[iPlayer] = {}
                dictBonus[iPlayer]["zone1"] = []
                dictBonus[iPlayer]["zone2"] = []
                dictBonus[iPlayer]["zone3_1"] = [] # same area
                dictBonus[iPlayer]["zone3_2"] = [] # diff area
                dictBonus[iPlayer]["areaList"] = getListPlotsPerArea(startPlots[iPlayer], dictPlotsPerArea)
                dictBonus[iPlayer]["nbBonus1"] = {}
                dictBonus[iPlayer]["nbBonus2"] = {}
                dictBonus[iPlayer]["nbBonus3"] = {}
                for iBonus in range(nbRes) :
                        dictBonus[iPlayer]["nbBonus1"][iBonus] = 0
                        dictBonus[iPlayer]["nbBonus2"][iBonus] = 0
                        dictBonus[iPlayer]["nbBonus3"][iBonus] = 0
                dictBonus[iPlayer]["nbGoodies"] = 0

        iGoody = gc.getInfoTypeForString("IMPROVEMENT_GOODY_HUT")
        bGoody = bool(iGoody != -1)
        lImprovementPlots = []
        for iX in range(iW) :
                for iY in range(iH) :
                        pPlot = map.plot(iX, iY)
                        iImprovement = pPlot.getImprovementType()
                        if iImprovement in [-1, iGoody] : continue
                        lImprovementPlots.append((iX, iY))

        bOneCityChallenge = bool(game.isOption(gc.getInfoTypeForString("GAMEOPTION_ONE_CITY_CHALLENGE")))

        iZone1Limit = 2
        iZone2Limit = 6
        if bOneCityChallenge : iZone2Limit = 4

        minDist = iW*iH
        maxDist = 0
        for iPlayer in playerList :
                distTemp = iW*iH
                look = False
                for iPlayer2 in playerList :
                        if iPlayer >= iPlayer2 : continue
                        distA = calculateAirDistance(startPlots[iPlayer], startPlots[iPlayer2])
                        distTemp = min(distTemp, distA)
                        look = True
                if look :
                        minDist = min(minDist, distTemp)
                        maxDist = max(maxDist, distTemp)

        iZone3Limit = max(8, int(minDist * 2.15 / 3.0))
        if bOneCityChallenge : iZone3Limit = 6

        rings = generateRings(max(7, iZone3Limit))
        cityRings = rings[1] + rings[2]
        bLakes = copy.copy(selGen["resources"]["resourcesgen"]["resspreadlake"])

        for iPlayer in playerList :
                iBonus = map.plot(startX[iPlayer], startY[iPlayer]).getBonusType(-1)
                if iBonus != -1 :
                        if bEraseAll :
                                map.plot(startX[iPlayer], startY[iPlayer]).setBonusType(-1)
                        else :
                                dictBonus[iPlayer]["nbBonus1"][iBonus] += 1
                                dictBonus[iPlayer]["nbBonus2"][iBonus] += 1
                                dictBonus[iPlayer]["nbBonus3"][iBonus] += 1

                for iRing in range(1, iZone1Limit + 1) :
                        for dX, dY in rings[iRing] :
                                wTP = toWrap(startX[iPlayer] + dX, startY[iPlayer] + dY)
                                if wTP == -1 : continue
                                if wTP in lImprovementPlots : continue

                                iX, iY = wTP
                                pPlot = map.plot(iX, iY)

                                if pPlot.isPeak() : continue
                                if pPlot.isImpassable() : continue

                                iBonus = pPlot.getBonusType(-1)
                                if iBonus != -1 :
                                        if bEraseAll :
                                                pPlot.setBonusType(-1)
                                        else :
                                                dictBonus[iPlayer]["nbBonus1"][iBonus] += 1
                                                dictBonus[iPlayer]["nbBonus2"][iBonus] += 1
                                                dictBonus[iPlayer]["nbBonus3"][iBonus] += 1
                                                continue

                                iImprovement = pPlot.getImprovementType()
                                if (bGoody) and (iImprovement == iGoody) :
                                        dictBonus[iPlayer]["nbGoodies"] += 1
                                        pPlot.setImprovementType(-1)

                                if pPlot.isWater() :
                                        bConnectedSL = True
                                        if pPlot.isLake() :
                                                if not bLakes : continue
                                                if iRing > 1 :
                                                        lPlots = getListPlotsPerArea(wTP, dictPlotsPerArea)
                                                        if (len(lPlots) < 5) or (bOneCityChallenge) : # small lake, check if water connected to start plot
                                                                bCArea = False
                                                                for dXX, dYY in rings[1] :
                                                                        wTP2 = toWrap(startX[iPlayer] + dXX, startY[iPlayer] + dYY)
                                                                        if wTP2 == -1 : continue
                                                                        if wTP2 in lPlots :
                                                                                bCArea = True
                                                                                break
                                                                if not bCArea : bConnectedSL = False

                                        if bConnectedSL : dictBonus[iPlayer]["zone1"].append(wTP)
                                        continue

                                if bOneCityChallenge :
                                        if not wTP in dictBonus[iPlayer]["areaList"] : continue
                                dictBonus[iPlayer]["zone1"].append(wTP)

        lZonePlots = []
        for iPlayer in playerList : lZonePlots += copy.deepcopy(dictBonus[iPlayer]["zone1"])
                                                        
        for iPlayer in playerList :
                for iRing in range(iZone1Limit, iZone2Limit + 1) :
                        for dX, dY in rings[iRing] :
                                wTP = toWrap(startX[iPlayer] + dX, startY[iPlayer] + dY)
                                if wTP == -1 : continue
                                if wTP in lImprovementPlots : continue
                                if wTP in lZonePlots : continue

                                iX, iY = wTP
                                pPlot = map.plot(iX, iY)

                                if pPlot.isPeak() : continue
                                if pPlot.isImpassable() : continue

                                bValid = True
                                for iPlayer2 in playerList :
                                        if wTP in dictBonus[iPlayer2]["zone2"] :
                                                distA = calculateAirDistance(startPlots[iPlayer], wTP)
                                                distB = calculateAirDistance(wTP, startPlots[iPlayer2])
                                                if distA <= distB :
                                                        dictBonus[iPlayer2]["zone2"].remove(wTP)
                                                        iBonus = pPlot.getBonusType(-1)
                                                        if iBonus != -1 :
                                                                dictBonus[iPlayer2]["nbBonus2"][iBonus] -= 1
                                                                dictBonus[iPlayer2]["nbBonus3"][iBonus] -= 1
                                                if distA >= distB :
                                                        bValid = False
                                if not bValid : continue

                                iBonus = pPlot.getBonusType(-1)
                                if iBonus != -1 :
                                        dictBonus[iPlayer]["nbBonus2"][iBonus] += 1
                                        dictBonus[iPlayer]["nbBonus3"][iBonus] += 1
                                        continue

                                iImprovement = pPlot.getImprovementType()
                                if (bGoody) and (iImprovement == iGoody) :
                                        continue

                                if pPlot.isWater() :
                                        if (pPlot.isLake()) and (not bLakes) : continue
                                        
                                        bFoundLand = False
                                        for dXX, dYY in cityRings :
                                                wTP2 = toWrap(iX + dXX, iY + dYY)
                                                if wTP2 == -1 : continue
                                                if not map.plot(wTP2[0], wTP2[1]).isWater() :
                                                        bFoundLand = True
                                                        break
                                        if not bFoundLand : continue
                                        
                                        dictBonus[iPlayer]["zone2"].append(wTP)
                                        continue

                                if bOneCityChallenge :
                                        if not wTP in dictBonus[iPlayer]["areaList"] : continue
                                dictBonus[iPlayer]["zone2"].append(wTP)

        for iPlayer in playerList : lZonePlots += copy.deepcopy(dictBonus[iPlayer]["zone2"])
                                                        
        for iPlayer in playerList :
                for iRing in range(iZone2Limit, iZone3Limit + 1) :
                        for dX, dY in rings[iRing] :
                                wTP = toWrap(startX[iPlayer] + dX, startY[iPlayer] + dY)
                                if wTP == -1 : continue
                                if wTP in lImprovementPlots : continue
                                if wTP in lZonePlots : continue

                                iX, iY = wTP
                                pPlot = map.plot(iX, iY)

                                if pPlot.isPeak() : continue
                                if pPlot.isImpassable() : continue

                                bValid = True
                                bSameArea = bool(wTP in dictBonus[iPlayer]["areaList"])
                                for iPlayer2 in playerList :
                                        if bSameArea :
                                                if wTP in dictBonus[iPlayer2]["zone3_2"] :
                                                        dictBonus[iPlayer2]["zone3_2"].remove(wTP)
                                                        iBonus = pPlot.getBonusType(-1)
                                                        if iBonus != -1 :
                                                                dictBonus[iPlayer2]["nbBonus3"][iBonus] -= 1
                                                elif wTP in dictBonus[iPlayer2]["zone3_1"] :
                                                        distA = min(map.calculatePathDistance(pPlot, map.plot(startX[iPlayer], startY[iPlayer])), calculateAirDistance(startPlots[iPlayer], wTP) * 1.8)
                                                        map.resetPathDistance()
                                                        distB = min(map.calculatePathDistance(pPlot, map.plot(startX[iPlayer2], startY[iPlayer2])), calculateAirDistance(startPlots[iPlayer2], wTP) * 1.8)
                                                        map.resetPathDistance()

                                                        if distA <= distB :
                                                                dictBonus[iPlayer2]["zone3_1"].remove(wTP)
                                                                iBonus = pPlot.getBonusType(-1)
                                                                if iBonus != -1 :
                                                                        dictBonus[iPlayer2]["nbBonus3"][iBonus] -= 1
                                                        if distA >= distB :
                                                                bValid = False
                                        else :
                                                if wTP in dictBonus[iPlayer2]["zone3_1"] :
                                                        bValid = False
                                                elif wTP in dictBonus[iPlayer2]["zone3_2"] :
                                                        distA = calculateAirDistance(startPlots[iPlayer], wTP)
                                                        distB = calculateAirDistance(startPlots[iPlayer2], wTP)

                                                        if distA <= distB :
                                                                dictBonus[iPlayer2]["zone3_2"].remove(wTP)
                                                                iBonus = pPlot.getBonusType(-1)
                                                                if iBonus != -1 :
                                                                        dictBonus[iPlayer2]["nbBonus3"][iBonus] -= 1
                                                        if distA >= distB :
                                                                bValid = False
                                if not bValid : continue

                                iBonus = pPlot.getBonusType(-1)
                                if iBonus != -1 :
                                        dictBonus[iPlayer]["nbBonus3"][iBonus] += 1
                                        continue

                                iImprovement = pPlot.getImprovementType()
                                if (bGoody) and (iImprovement == iGoody) :
                                        continue

                                if pPlot.isWater() :
                                        if (pPlot.isLake()) and (not bLakes) : continue

                                        bFoundLand = False
                                        for dXX, dYY in cityRings :
                                                wTP2 = toWrap(iX + dXX, iY + dYY)
                                                if wTP2 == -1 : continue
                                                if not map.plot(wTP2[0], wTP2[1]).isWater() :
                                                        bFoundLand = True
                                                        break
                                        if not bFoundLand : continue

                                        dictBonus[iPlayer]["zone3_2"].append(wTP)
                                        continue

                                if bOneCityChallenge :
                                        if not bSameArea : continue
                                if bSameArea :
                                        dictBonus[iPlayer]["zone3_1"].append(wTP)
                                else :
                                        dictBonus[iPlayer]["zone3_2"].append(wTP)
        
        logList = [""]
        for iPlayer in playerList :
                logList.append(" Player %d : zone1 %d, zone2 %d, zone3_1 %d, zone 3_2 %d" %(iPlayer, len(dictBonus[iPlayer]["zone1"]), len(dictBonus[iPlayer]["zone2"]), len(dictBonus[iPlayer]["zone3_1"]), len(dictBonus[iPlayer]["zone3_2"])))
        writeLog("", False, logList)
                                        
        for iPlayer in playerList :
                del dictBonus[iPlayer]["areaList"]
                for sTag in ["zone1", "zone2", "zone3_1", "zone3_2"] :
                        sNewTag = sTag + "bonus"
                        dictBonus[iPlayer][sNewTag] = {}
                        for iBonus in lRes :
                                dictBonus[iPlayer][sNewTag][iBonus] = [[], []]

                        for coord in dictBonus[iPlayer][sTag] :
                                iX, iY = coord
                                pPlot = map.plot(iX, iY)

                                terrainPlot = pPlot.getTerrainType()
                                featurePlot = pPlot.getFeatureType()
                                idHill = 0
                                if pPlot.isHills() : idHill = 1

                                pPlacement = (terrainPlot, featurePlot + 1, idHill)

                                for iBonus in lRes :
                                        if pPlot.canHaveBonus(iBonus, True) : dictBonus[iPlayer][sNewTag][iBonus][0].append(coord)
                                        elif pPlacement in lBonusExtend[iBonus] : dictBonus[iPlayer][sNewTag][iBonus][1].append(coord)

##        # verifie region
##        for iPlayer in playerList :
##                for sTag in ["zone1", "zone2", "zone3_1", "zone3_2"] :
##                        sText = "Z" + sTag[4:] + "_P" + str(iPlayer)
##                        for iX, iY in dictBonus[iPlayer][sTag] :
##                                CyEngine().addSign(map.plot(iX, iY), 0, sText)

        logList = ["", " impl Start Resources :"]

        def getPlotForBonus(iP, iB, sZo) :
                for i in range(2) :
                        lP = [co for co in dictBonus[iP][sZo + "bonus"][iB][i] if co in dictBonus[iP][sZo]]
                        if len(lP) > 0 :
                                coc = lP[getRandNum(len(lP), " FoR : Start res plot choice for bonus")]
                                return coc
                return -1

        def getBonusListInZone(iP, sZo) :
                lB = []
                lZ = ["nbBonus1"]
                if sZo == "zone2" : lZ.append("nbBonus2")
                elif sZo in ["zone3_1", "zone3_2"] : lZ += ["nbBonus2", "nbBonus3"]
                for sT in lZ :
                        for iB in dictBonus[iPlayer][sT].keys() :
                                if dictBonus[iPlayer][sT][iB] > 0 : lB.append(iB)
                return lB

        def placeBonuses(dP, lZ, dB, lL) :

                if "zone3_1" in lZ : lT = ["nbBonus3"]
                elif "zone2" in lZ : lT = ["nbBonus2", "nbBonus3"]
                elif "zone1" in lZ : lT = ["nbBonus1", "nbBonus2", "nbBonus3"]

                for iP in dP.keys() :
                        iB, co = dP[iP]
                        lL.append(" place %s for player %d" %(gc.getBonusInfo(iB).getType(), iP))

                        map.plot(co[0], co[1]).setBonusType(iB)

                        for sZ in lZ :
                                if co in dB[iP][sZ] : dB[iP][sZ].remove(co)

                        for sT in lT : dB[iP][sT][iB] += 1
                lL.append("")
                return [dB, lL]

        def getSameBonusForPlayers(lP, lB, lZo) :
                while True :
                        dR = {}

                        if len(lB) == 0 : return -1

                        iBo = int(lB[getRandNum(len(lB), " FoR : bonus choice (same)")])
                        lB.remove(iBo)

                        bFAll = True
                        for iPl in lP :
                                bF = False
                                for szZo in lZo :
                                        cLo = getPlotForBonus(iPl, iBo, szZo)
                                        if cLo != -1 :
                                                bF = True
                                                dR[iPl] = [iBo, cLo]
                                                break

                                if not bF :
                                        bFAll = False
                                        break

                        if bFAll : return dR

        def getBonusForPlayer(iPl, lB, lZo) :
                while True :
                        if len(lB) == 0 : return -1

                        iBo = int(lB[getRandNum(len(lB), " FoR : bonus choice (for player)")])
                        lB.remove(iBo)

                        for szZo in lZo :
                                cLo = getPlotForBonus(iPl, iBo, szZo)
                                if cLo != -1 :
                                        return [iBo, cLo]

        lResProRand = [item for item in lResPro if not item in lResProNoRand]
        lResFooRand = [item for item in lResFoo if not item in lResFooNoRand]
        lResLuxRand = [item for item in lResLux if not item in lResLuxNoRand]

        for iPass in range(3) :
                for bonusSelection, bonusQuantity, bonusLocation, bonusApply, playerApply in lStartRes :
                        if bonusLocation != iPass : continue

                        lApplyPlayers = []
                        if 0 in playerApply : lApplyPlayers += copy.copy(playerHUList)
                        if 1 in playerApply : lApplyPlayers += copy.copy(playerAIList)

                        if bonusLocation == 0 : lZones = ["zone1"]
                        elif bonusLocation == 1 : lZones = ["zone2"]
                        elif bonusLocation == 2 : lZones = ["zone3_1", "zone3_2"]

                        nbBonus = bonusQuantity[0]

                        bForce = False
                        if bonusApply == 0 : bForce = True

                        logList.append("")
                        logList.append("")
                        logList.append(" Start Add for : players %r, bonus %r, quantity %d, zone %r, bForce %r" %(lApplyPlayers, bonusSelection, nbBonus, lZones, bForce))

                        if bForce :
                                for iQuantity in range(bonusQuantity[0]) :
                                        
                                        if bonusSelection in ["allstratsame", "allhealthsame", "allhappsame"] :
                                                dPlayerBonus = {}
                                                for iPlayer in lApplyPlayers : dPlayerBonus[iPlayer] = getBonusListInZone(iPlayer, lZones[0])

                                                if bonusSelection == "allstratsame" : lBonusRand = copy.copy(lResProRand)
                                                elif bonusSelection == "allhealthsame" : lBonusRand = copy.copy(lResFooRand)
                                                elif bonusSelection == "allhappsame" : lBonusRand = copy.copy(lResLuxRand)

                                                lAllBonus = copy.copy(lBonusRand)
                                                lNoneBonus = copy.copy(lBonusRand)

                                                for iPlayer in lApplyPlayers :
                                                        lAllBonus = [item for item in lAllBonus if item in dPlayerBonus[iPlayer]]
                                                        lNoneBonus = [item for item in lNoneBonus if not item in dPlayerBonus[iPlayer]]

                                                lOtherBonus = [item for item in lBonusRand if (not item in lAllBonus) and (not item in lNoneBonus)]

                                                dResult = getSameBonusForPlayers(lApplyPlayers, lNoneBonus, lZones)
                                                if dResult != -1 :
                                                        logList.append("... A bonus not present in the players zone added :")
                                                        dictBonus, logList = placeBonuses(dResult, lZones, dictBonus, logList)
                                                        continue

                                                dResult = getSameBonusForPlayers(lApplyPlayers, lAllBonus, lZones)
                                                if dResult != -1 :
                                                        logList.append("... A bonus present in all of the players zone added :")
                                                        dictBonus, logList = placeBonuses(dResult, lZones, dictBonus, logList)
                                                        continue

                                                dResult = getSameBonusForPlayers(lApplyPlayers, lOtherBonus, lZones)
                                                if dResult != -1 :
                                                        logList.append("... A random bonus added :")
                                                        dictBonus, logList = placeBonuses(dResult, lZones, dictBonus, logList)
                                                        continue

                                                logList.append("... can't find another bonus to add, go to next selection.")
                                                break

                                        elif bonusSelection in ["allstratdiff", "allhealthdiff", "allhappdiff"] :

                                                if bonusSelection == "allstratdiff" : lBonusRand = copy.copy(lResProRand)
                                                elif bonusSelection == "allhealthdiff" : lBonusRand = copy.copy(lResFooRand)
                                                elif bonusSelection == "allhappdiff" : lBonusRand = copy.copy(lResLuxRand)

                                                dResult = {}
                                                bFoundAll = True
                                                for iPlayer in lApplyPlayers :
                                                        lZoneBonus = getBonusListInZone(iPlayer, lZones[0])

                                                        lNoBonus = [item for item in lBonusRand if not item in lZoneBonus]
                                                        lOtherBonus = [item for item in lBonusRand if item in lZoneBonus]

                                                        rPlayer = getBonusForPlayer(iPlayer, lNoBonus, lZones)
                                                        if rPlayer != -1 :
                                                                dResult[iPlayer] = rPlayer
                                                                continue

                                                        rPlayer = getBonusForPlayer(iPlayer, lOtherBonus, lZones)
                                                        if rPlayer != -1 :
                                                                dResult[iPlayer] = rPlayer
                                                                continue

                                                        bFoundAll = False
                                                        break

                                                if bFoundAll :
                                                        logList.append("... A bonus added for all player :")
                                                        dictBonus, logList = placeBonuses(dResult, lZones, dictBonus, logList)
                                                        continue

                                                logList.append("... can't find another bonus to add, go to next selection.")
                                                break

                                        else :
                                                iBonus = gc.getInfoTypeForString(bonusSelection[0])
                                                if iBonus == -1 :
                                                        logList.append("... iBonus = -1 (%s) ??? , go to next selection." %bonusSelection[0])
                                                        break

                                                if not iBonus in lRes :
                                                        logList.append("... iBonus not in lRes (%s) ??? , go to next selection." %bonusSelection[0])
                                                        break

                                                dResult = {}
                                                bFoundAll = True
                                                for iPlayer in lApplyPlayers :

                                                        rPlayer = getBonusForPlayer(iPlayer, [iBonus], lZones)
                                                        if rPlayer != -1 :
                                                                dResult[iPlayer] = rPlayer
                                                                continue

                                                        bFoundAll = False
                                                        break

                                                if bFoundAll :
                                                        logList.append("... A bonus added for all player :")
                                                        dictBonus, logList = placeBonuses(dResult, lZones, dictBonus, logList)
                                                        continue

                                                logList.append("... can't place another bonus for all players, go to next selection.")
                                                break

                        else :
                                iQuantity = bonusQuantity[0]

                                if bonusSelection in ["allstratsame", "allstratdiff"] :
                                        lBonusRef = lResPro
                                        lBonusRand = lResProRand
                                elif bonusSelection in ["allhealthsame", "allhealthdiff"] :
                                        lBonusRef = lResFoo
                                        lBonusRand = lResFooRand
                                elif bonusSelection in ["allhappsame", "allhappdiff"] :
                                        lBonusRef = lResLux
                                        lBonusRand = lResLuxRand

                                if bonusSelection in ["allstratsame", "allhealthsame", "allhappsame"] :

                                        while True :
                                                dPlayerBonus = {}
                                                for iPlayer in lApplyPlayers :
                                                        dPlayerBonus[iPlayer] = {}
                                                        dPlayerBonus[iPlayer]["bonuslist"] = [item for item in getBonusListInZone(iPlayer, lZones[0]) if item in lBonusRef]
                                                        dPlayerBonus[iPlayer]["nbBonusToPlace"] = iQuantity - len(dPlayerBonus[iPlayer]["bonuslist"])

                                                bPlaceOne = False
                                                maxBonusToPlace = max([dPlayerBonus[iPlayer]["nbBonusToPlace"] for iPlayer in lApplyPlayers])
                                                for i in range(max(0, maxBonusToPlace)) :
                                                        iBonusMin = i + 1
                                                        lPlayerPlace = [iPlayer for iPlayer in lApplyPlayers if dPlayerBonus[iPlayer]["nbBonusToPlace"] >= iBonusMin]
                                                        lPlayerNoPlace = [iPlayer for iPlayer in lApplyPlayers if dPlayerBonus[iPlayer]["nbBonusToPlace"] < iBonusMin]

                                                        lBonusPlayerCommon = copy.copy(lBonusRand)
                                                        for iPlayer in lPlayerNoPlace :
                                                                lBonusPlayerCommon = [item for item in lBonusPlayerCommon if item in dPlayerBonus[iPlayer]["bonuslist"]]
                                                        lOtherBonus = [item for item in lBonusRand if not item in lBonusPlayerCommon]

                                                        for iPlayer in lPlayerPlace :
                                                                lBonusPlayerCommon = [item for item in lBonusPlayerCommon if not item in dPlayerBonus[iPlayer]["bonuslist"]]
                                                                lOtherBonus = [item for item in lOtherBonus if not item in dPlayerBonus[iPlayer]["bonuslist"]]

                                                        dResult = getSameBonusForPlayers(lPlayerPlace, lBonusPlayerCommon, lZones)
                                                        if dResult != -1 :
                                                                logList.append("... A bonus common for players %r has been added for players %r :" %(lPlayerNoPlace, lPlayerPlace))
                                                                dictBonus, logList = placeBonuses(dResult, lZones, dictBonus, logList)
                                                                bPlaceOne = True
                                                                break

                                                        dResult = getSameBonusForPlayers(lPlayerPlace, lOtherBonus, lZones)
                                                        if dResult != -1 :
                                                                logList.append("... A bonus NOT common for players %r has been added for players %r :" %(lPlayerNoPlace, lPlayerPlace))
                                                                dictBonus, logList = placeBonuses(dResult, lZones, dictBonus, logList)
                                                                bPlaceOne = True
                                                                break

                                                if not bPlaceOne :
                                                        if maxBonusToPlace > 0 :
                                                                logList.append("... can t find a common bonus, continue to next selection")
                                                        else :
                                                                logList.append("... all bonuses has been placed, continue to next selection")
                                                        break

                                elif bonusSelection in ["allstratdiff", "allhealthdiff", "allhappdiff"] :

                                        while True :
                                                dPlayerBonus = {}
                                                for iPlayer in lApplyPlayers :
                                                        dPlayerBonus[iPlayer] = {}
                                                        dPlayerBonus[iPlayer]["bonuslist"] = [item for item in getBonusListInZone(iPlayer, lZones[0]) if item in lBonusRef]
                                                        dPlayerBonus[iPlayer]["nbBonusToPlace"] = iQuantity - len(dPlayerBonus[iPlayer]["bonuslist"])

                                                maxBonusToPlace = max([dPlayerBonus[iPlayer]["nbBonusToPlace"] for iPlayer in lApplyPlayers])

                                                if maxBonusToPlace <= 0 :
                                                        logList.append("... No more bonus to add, continue to next selection")
                                                        break

                                                lPlayerPlace = [iPlayer for iPlayer in lApplyPlayers if dPlayerBonus[iPlayer]["nbBonusToPlace"] == maxBonusToPlace]

                                                dResult = {}
                                                bFoundAll = True
                                                for iPlayer in lPlayerPlace :
                                                        lOtherBonus = [item for item in lBonusRand if not item in dPlayerBonus[iPlayer]["bonuslist"]]

                                                        rPlayer = getBonusForPlayer(iPlayer, lOtherBonus, lZones)
                                                        if rPlayer != -1 :
                                                                dResult[iPlayer] = rPlayer
                                                                continue

                                                        bFoundAll = False
                                                        break

                                                if bFoundAll :
                                                        logList.append("... A bonus added for players %r " %(lPlayerPlace, ))
                                                        dictBonus, logList = placeBonuses(dResult, lZones, dictBonus, logList)
                                                        continue

                                                logList.append("... A bonus can t be added for players %r, continue to next selection " %(lPlayerPlace, ))
                                                break

                                else :

                                        iBonus = gc.getInfoTypeForString(bonusSelection[0])
                                        if iBonus == -1 :
                                                logList.append("... iBonus = -1 (%s) ??? , go to next selection." %bonusSelection[0])
                                                continue

                                        if not iBonus in lRes :
                                                logList.append("... iBonus not in lRes (%s) ??? , go to next selection." %bonusSelection[0])
                                                continue

                                        if bonusLocation == 0 : sZoneTag = "nbBonus1"
                                        elif bonusLocation == 1 : sZoneTag = "nbBonus2"
                                        elif bonusLocation == 2 : sZoneTag = "nbBonus3"

                                        while True :

                                                dPlayerBonus = {}
                                                for iPlayer in lApplyPlayers :
                                                        dPlayerBonus[iPlayer] = {}
                                                        dPlayerBonus[iPlayer]["nbBonusToPlace"] = iQuantity - dictBonus[iPlayer][sZoneTag][iBonus]

                                                maxBonusToPlace = max([dPlayerBonus[iPlayer]["nbBonusToPlace"] for iPlayer in lApplyPlayers])

                                                if maxBonusToPlace <= 0 :
                                                        logList.append("... No more bonus to add, continue to next selection")
                                                        break

                                                lPlayerPlace = [iPlayer for iPlayer in lApplyPlayers if dPlayerBonus[iPlayer]["nbBonusToPlace"] == maxBonusToPlace]

                                                dResult = {}
                                                bFoundAll = True
                                                for iPlayer in lPlayerPlace :

                                                        rPlayer = getBonusForPlayer(iPlayer, [iBonus], lZones)
                                                        if rPlayer != -1 :
                                                                dResult[iPlayer] = rPlayer
                                                                continue

                                                        bFoundAll = False
                                                        break

                                                if bFoundAll :
                                                        logList.append("... A bonus added for players %r " %(lPlayerPlace, ))
                                                        dictBonus, logList = placeBonuses(dResult, lZones, dictBonus, logList)
                                                        continue

                                                logList.append("... A bonus can t be added for players %r, continue to next selection " %(lPlayerPlace, ))
                                                break

        writeLog("", True, logList)

def startHumansOnSameTile():
        iNorm = selGen["startlocs"]["normalize"]["startsametile"]
        if iNorm == 2 :
                return True
        elif iNorm == 1 :
                pass
        elif idMap == "maze" :
                return True
	return False

##!_!## additional functions for map generation
def StoAddGameElements():
        global dice
        dice = game.getSorenRand()

        writeLog(" = StoAddGameElements = ", False, [""])

        initPlayerList(True) # reinit starting locations , list of players , teams in case a player has disapeared (no more start loc , onGameStart impl)

        try :
                if bStandardAssignment :
                        CyInterface().addImmediateMessage("Warning !! default player starting locations implementation must have been run !!", "")
        except :
                writeLog("", False, ["", " message standart assignment : Error ..."])
                writeError()

        try :
                addGold()
        except :
                writeLog("", False, ["", " addGold : Error ..."])
                writeError()

        try :
                revealMap()
        except :
                writeLog("", False, ["", " revealMap : Error ..."])
                writeError()

        try :
                addTechs()
        except :
                writeLog("", False, [" addTechs : Error ..."])
                writeError()

        try :
                addUnits()
        except :
                writeLog("", False, [" addUnits : Error ..."])
                writeError()

        try :
                addBarbCities()
        except :
                writeLog("", False, [" addBarbCities : Error ..."])
                writeError()

        try :
                addAnimals()
        except :
                writeLog("", False, [" addAnimals : Error ..."])
                writeError()

        writeLog("", True, [""])

def addAnimals():
        animPer = getRandSel(selGen["game"]["animals"]["animalspercent"], False)

        logList = [""]
        if animPer == 0 :
                writeLog("", False, ["", " addAnimals() : animal percent = 0 ...", ""])
                return

        if not isBarb :
                writeLog("", False, ["", " addAnimals() : no barb option on ...", ""])
                return

        animNoPlace = copy.copy(selGen["game"]["animals"]["animalsnoplace"])
        animUnitRange = copy.copy(selGen["game"]["animals"]["animunitrange"][0])
        animXP = copy.copy(selGen["game"]["animals"]["xpanimals"][0])
        nbTilesMin = copy.copy(selGen["game"]["animals"]["nbtilesminisland"][0])

        logList.append(" addAnimals() : animPer %r" %animPer)
        logList.append(" addAnimals() : animNoPlace %r" %animNoPlace)
        logList.append(" addAnimals() : animUnitRange %r" %animUnitRange)
        logList.append(" addAnimals() : animXP %r" %animXP)
        logList.append(" addAnimals() : nbTilesMin %r" %nbTilesMin)
        logList.append("")

        animPer = animPer/100.0
        animPlace = [gc.getInfoTypeForString(item) for item in XMLEntriesList["units"]["animland"] if not item in animNoPlace]
        
        if animPlace == [] :
                writeLog("", False, ["", " addAnimals() : no animals to place ...", ""])
                return

        iBarbPlayer = gc.getBARBARIAN_PLAYER()

        powerAnim = {}
        maxPower = -1
        for iAnimal in animPlace :
                power = max(2, gc.getUnitInfo(iAnimal).getCombat())
                if power > maxPower : maxPower = power
                powerAnim[iAnimal] = power

        rings = generateRings(maxPower)

        lPlotsNoAnim = []
        lPlotsAnim = []
        dictPlotsPerArea = getAreaPlots()

        for lTp in dictPlotsPerArea["land"] :
                if len(lTp) < nbTilesMin : lPlotsNoAnim += copy.copy(lTp)

        for iX in range(iW) :
                for iY in range(iH) :
                        pPlot = map.plot(iX, iY)

                        if pPlot.isOwned() :
                                pass
                        elif pPlot.isUnit() :
                                pUnit = pPlot.getUnit(0)
                                if pUnit.isNone() :
                                        pass
                                elif pUnit.getOwner() != iBarbPlayer :
                                        for dX in range(-1*animUnitRange, animUnitRange + 1) :
                                                for dY in range(-1*animUnitRange, animUnitRange + 1) :
                                                        wTP = toWrap(iX + dX, iY + dY)
                                                        if wTP != -1 :
                                                                if not wTP in lPlotsNoAnim : lPlotsNoAnim.append(wTP)
                                        continue
                        else :
                                continue

                        if not (iX, iY) in lPlotsNoAnim : lPlotsNoAnim.append((iX, iY))

        for iX in range(iW) :
                for iY in range(iH) :
                        pPlot = map.plot(iX, iY)

                        if pPlot.isWater() : continue
                        if pPlot.isPeak() : continue
                        if pPlot.isImpassable() : continue
                        if pPlot.getImprovementType() != -1 : continue
                        if (iX, iY) in lPlotsNoAnim : continue

                        lPlotsAnim.append((iX, iY))

        if len(lPlotsAnim) == 0 :
                logList.append(" addAnimals() : map full , can't place an animal Oo ? ...")
                logList.append("")
                writeLog("", False, logList)
                return
        else :
                logList.append(" addAnimals() : nb anim plots %r" %(len(lPlotsAnim), ))

        plotValues = [[0 for iY in range(iH)] for iX in range(iW)]
        nbAnimPlaced = 0
        nbAnimToPlace = len(lPlotsAnim)*animPer
        while True :
                if nbAnimPlaced >= nbAnimToPlace : break
                if len(lPlotsAnim) == 0 : break
                val = min([plotValues[iX][iY] for iX, iY in lPlotsAnim])
                tpList = [(iX, iY) for iX, iY in lPlotsAnim if plotValues[iX][iY] == val]
                iChoice = getRandNum(len(tpList), " FoR : anim plot rand")
                iAnimal = animPlace[getRandNum(len(animPlace), " FoR : anim rand")]
                iX, iY = tpList[iChoice]
                for iRing in range(1, powerAnim[iAnimal]+1) :
                        for dX, dY in rings[iRing] :
                                wTP = toWrap(iX + dX, iY + dY)
                                if wTP != -1 :
                                        plotValues[wTP[0]][wTP[1]] = max(powerAnim[iAnimal] - iRing + 1, plotValues[wTP[0]][wTP[1]])

                pUnit = spawnUnit(iBarbPlayer, iAnimal, iX, iY)
                if pUnit != -1 :
                        if (animXP > 0) and (pUnit.canAcquirePromotionAny()) :
                                pUnit.setExperience(animXP, -1)

                lPlotsAnim.remove((iX, iY))
                nbAnimPlaced += 1

        logList.append(" addAnimals() : nb anim placed %r" %nbAnimPlaced)
        logList.append("")
        writeLog("", False, logList)

def addBarbCities():
        cityPer = getRandSel(selGen["game"]["barbcities"]["cityper"], False)

        logList = [""]
        if cityPer == 0 :
                writeLog("", False, ["", " addBarbCities : city percent = 0 ...", ""])
                return

        if not isBarb :
                writeLog("", False, ["", " addBarbCities : no barb option on ...", ""])
                return

        cityBuildings = copy.copy(selGen["game"]["barbcities"]["citybuilding"])
        BBRange = copy.copy(selGen["game"]["barbcities"]["barbbarbrange"][0])
        BHRange = copy.copy(selGen["game"]["barbcities"]["barbhumrange"][0])
        defender = copy.copy(selGen["game"]["barbcities"]["defender"])
        nbDefender = copy.copy(selGen["game"]["barbcities"]["nbdefender"][0])
        xpDefender = copy.copy(selGen["game"]["barbcities"]["xpdefender"][0])
        nbTilesMin = copy.copy(selGen["game"]["barbcities"]["nbtilesminisland"][0])

        logList.append(" addBarbCities : cityPer %r" %cityPer)
        logList.append(" addBarbCities : cityBuildings %r" %cityBuildings)
        logList.append(" addBarbCities : BBRange %r" %BBRange)
        logList.append(" addBarbCities : BHRange %r" %BHRange)
        logList.append(" addBarbCities : defender %r" %defender)
        logList.append(" addBarbCities : nbDefender %r" %nbDefender)
        logList.append(" addBarbCities : xpDefender %r" %xpDefender)
        logList.append(" addBarbCities : nbTilesMin %r" %nbTilesMin)
        logList.append("")

        cityPer = cityPer/100.0
        cityBuildings = [gc.getInfoTypeForString(item) for item in cityBuildings]

        bDefender = bool( (defender != []) and (nbDefender > 0) )
        if bDefender : iDefender = gc.getInfoTypeForString(defender[0])

        iBarbPlayer = gc.getBARBARIAN_PLAYER()
        pPlayer = gc.getPlayer(iBarbPlayer)

        rings = generateRings(max(BBRange, BHRange))

        lPlotsNoCity = []
        for iPlayer in playerList :
                for iRing in range(BHRange) :
                        for dX, dY in rings[iRing] :
                                wTP = toWrap(startX[iPlayer] + dX, startY[iPlayer] + dY)
                                if wTP != -1 :
                                        lPlotsNoCity.append(wTP)

        lFeaturesNoCity = []
        for iFeature in range(gc.getNumFeatureInfos()) :
                if gc.getFeatureInfo(iFeature).isNoCity() : lFeaturesNoCity.append(iFeature)

        lGoodyImprovements = []
        for iImprovement in range(gc.getNumImprovementInfos()) :
                if gc.getImprovementInfo(iImprovement).isGoody() : lGoodyImprovements.append(iImprovement)

        logList.append(" addBarbCities : lFeaturesNoCity %r" %([gc.getFeatureInfo(iFeature).getType() for iFeature in lFeaturesNoCity], ))
        logList.append(" addBarbCities : lGoodyImprovements %r" %([gc.getImprovementInfo(iImprovement).getType() for iImprovement in lGoodyImprovements], ))
        logList.append("")

        lPlotsCity = []
        nbCountAreaPlots = 0

        dictPlotsPerArea = getAreaPlots()
        lNoLandPlots = []
        for lTp in dictPlotsPerArea["land"] :
                if len(lTp) < nbTilesMin : lNoLandPlots += copy.copy(lTp)

        for iX in range(iW) :
                for iY in range(iH) :
                        pPlot = map.plot(iX, iY)
                        if pPlot.isWater():
                                for iRing in range(BBRange) :
                                        for dX, dY in rings[iRing] :
                                                wTP = toWrap(iX + dX, iY + dY)
                                                if wTP != -1 :
                                                        if not map.plot(wTP[0], wTP[1]).isWater() :
                                                                if wTP in lNoLandPlots : continue
                                                                nbCountAreaPlots += 1
                                                                break
                                continue

                        if (iX, iY) in lNoLandPlots : continue

                        nbCountAreaPlots += 1

                        if (iX, iY) in lPlotsNoCity : continue
                        if pPlot.isPeak() : continue
                        if pPlot.getFeatureType() in lFeaturesNoCity : continue
                        iPlotImprovement = pPlot.getImprovementType()
                        if (iPlotImprovement != -1) and (not iPlotImprovement in lGoodyImprovements) : continue
                        if not wrapX :
                                if iX < 2 : continue
                                if iX > iW-3 : continue
                        if not wrapY :
                                if iY < 2 : continue
                                if iY > iH-3 : continue

                        lPlotsCity.append((iX, iY))

        if len(lPlotsCity) == 0 :
                logList.append(" addBarbCities : map full , can't place a city ...")
                logList.append("")
                writeLog("", False, logList)
                return

        cityNames = []
        for iCiv in range(gc.getNumCivilizationInfos()) :
                civXML = gc.getCivilizationInfo(iCiv)
                for iIndex in range(civXML.getNumCityNames()) :
                        sName = ""
                        try :
                                uName = CyTranslator().getText(civXML.getCityNames(iIndex),())
                                sName = getSText(uName)
                        except :
                                writeLog("", False, [" addBarbCities : encodage Error ..."])
                                writeError()
                                
                        if sName != "" : cityNames.append(sName)

        sylBarb = []
        sylBarb.append(['sto','mori','kog','lob','zox','cor','kog','kono','xol','bino','zoll','spor','lob','jok','tob','roq','fobo','no','wog','sod'])
        sylBarb.append(['niu','rul','yu','ru','ung','bug','fun','jul','xinu','tlu','yug','mung','urli','dul','xul','molu','neru','halu','miy'])
        sylBarb.append(['shra','xaw','hay','shi','sri','sag','asa','sic','ino','hal','fral','kami','eni','des','noen','ari','slia','pix','ubu','ex'])
        nbSylBarb = len(sylBarb)
        lenBarb = [len(sylBarb[i]) for i in range(nbSylBarb)]
        def getCityName():
                nameTP = ""
                choSyl = getRandNum(nbSylBarb, " FoR : list syl choice for barb city name")
                for i in range(getRandNum(3, " FoR : len barb city name") + 1) :
                        sylTP = sylBarb[choSyl][getRandNum(lenBarb[choSyl], " FoR : syl barb city name")]
                        nameTP += sylTP
                nameTP = nameTP.capitalize()
                if nameTP in cityNames :
                        while nameTP in cityNames :
                                sylTP = sylBarb[choSyl][getRandNum(lenBarb[choSyl], " FoR : additionnal syl barb city name")]
                                nameTP += sylTP
                cityNames.append(nameTP)
                return nameTP

        def fullBarbCity(city):
                for iBuilding in cityBuildings :
                        try:
                                if BtS : city.setNumRealBuilding(iBuilding, 1)
                                else : city.setHasRealBuilding(iBuilding, True)
                        except:
                                writeLog("", False, [" addBarbCities : add building %r Error ..." %(gc.getBuildingInfo(iBuilding).getType(), )])
                                writeError()

                cityName = getCityName()
                try:
                        city.setName(cityName, False)
                except:
                        writeLog("", False, [" addBarbCities : city name error ..."])
                        writeError()

                if bDefender :
                        for i in range(nbDefender) :
                                pUnit = spawnUnit(iBarbPlayer, iDefender, city.getX(), city.getY())
                                if pUnit != -1 :
                                        try:
                                                pUnit.setUnitAIType(UnitAITypes.UNITAI_CITY_DEFENSE)
                                        except:
                                                writeLog("", False, [" addBarbCities : unitAIType error ..."])
                                                writeError()
                                        if (xpDefender > 0) and (pUnit.canAcquirePromotionAny()) :
                                                pUnit.setExperience(xpDefender, -1)

        nbCityPlaced = 0
        lenPlotsToReach = int(len(lPlotsCity)*(1 - cityPer)) # area that not be filled with cities
        ## 1rst try to equalize city placements
        areaCity = 0
        for iRing in range(BBRange) : areaCity += len(rings[iRing])

        nbCityBarbEstim = max(1.0, (nbCountAreaPlots*cityPer/areaCity) - len(playerList))
        nbCityPerPlot = nbCityBarbEstim/len(lPlotsCity)

        # step calculation, in order to have a good region separation 
        pas = sqrt(iW*iH/nbCityBarbEstim)
        if pas > iW :
                nbX = iW
                nbY = max(1, int(iH/nbCityBarbEstim))
        elif pas > iH :
                nbX = max(1, int(iW/nbCityBarbEstim))
                nbY = iH
        else :
                nbX = max(1, int(iW/pas))
                nbY = max(1, int(iH/pas))
        pasX = int(iW/nbX)
        pasY = int(iH/nbY)
        if iW%nbX != 0 : pasX += 1
        if iH%nbY != 0 : pasY += 1
        pasX = max(8, pasX)
        pasY = max(8, pasY)
        nbX = max(1, int(iW/pasX))
        nbY = max(1, int(iH/pasY))
        if iW%pasX != 0 : nbX += 1
        if iH%pasY != 0 : nbY += 1

        forTo = {}
        regionsPlotsEqui = [[[] for j in range(nbY)] for i in range(nbX)]
        for (iX, iY) in lPlotsCity :
                xRest = iX/pasX
                yRest = iY/pasY
                regionsPlotsEqui[xRest][yRest].append((iX, iY))
                forTo[(iX, iY)] = (xRest, yRest)

        nbToPlaceEqui = [[nbCityPerPlot*len(regionsPlotsEqui[i][j]) for j in range(nbY)] for i in range(nbX)]
        nbPlacedEqui = [[0 for j in range(nbY)] for i in range(nbX)]

        nbAttempts = int(nbCityBarbEstim/(nbX*nbY))

        logList.append(" addBarbCities : nbCityBarbEstim %r" %nbCityBarbEstim)
        logList.append(" addBarbCities : nbX %r" %nbX)
        logList.append(" addBarbCities : nbY %r" %nbY)
        logList.append(" addBarbCities : nbAttempts %r" %nbAttempts)
        logList.append("")

        for attempt in range(nbAttempts) :
                for pX in range(nbX) :
                        for pY in range(nbY) :
                                if len(regionsPlotsEqui[pX][pY]) == 0 : continue
                                if nbToPlaceEqui[pX][pY] <= nbPlacedEqui[pX][pY] : continue

                                iChoice = getRandNum(len(regionsPlotsEqui[pX][pY]), " FoR : equi barb city placement")
                                iX, iY = regionsPlotsEqui[pX][pY][iChoice]
                                lPlotsCity.remove((iX, iY))
                                dpX, dpY = forTo[(iX, iY)]
                                regionsPlotsEqui[dpX][dpY].remove((iX, iY))

                                for iRing in range(2) :
                                        for dX, dY in rings[iRing] :
                                                wTP = toWrap(iX + dX, iY + dY)
                                                if wTP != -1 :
                                                        pTempPlot = map.plot(wTP[0], wTP[1])
                                                        if pTempPlot.getImprovementType() in lGoodyImprovements : pTempPlot.setImprovementType(-1)

                                try :
                                        pCity = pPlayer.initCity(iX, iY)
                                except:
                                        writeLog("", False, [" addBarbCities : init city Error ..."])
                                        writeError()
                                        continue

                                for iRing in range(BBRange) :
                                        for dX, dY in rings[iRing] :
                                                wTP = toWrap(iX + dX, iY + dY)
                                                if wTP != -1 :
                                                        if wTP in lPlotsCity:
                                                                lPlotsCity.remove(wTP)
                                                                dpX, dpY = forTo[wTP]
                                                                regionsPlotsEqui[dpX][dpY].remove(wTP)

                                nbCityPlaced += 1
                                nbPlacedEqui[pX][pY] += 1
                                fullBarbCity(pCity)

        logList.append(" addBarbCities : equi placement , nb cities placed %r" %nbCityPlaced)
        logList.append("")

        # place the rest of the cities
        while True:
                if lenPlotsToReach >= len(lPlotsCity) : break
                if len(lPlotsCity) == 0 : break

                iChoice = getRandNum(len(lPlotsCity), " FoR : barb city placement")
                iX, iY = lPlotsCity[iChoice]
                lPlotsCity.remove((iX, iY))

                for iRing in range(2) :
                        for dX, dY in rings[iRing] :
                                wTP = toWrap(iX + dX, iY + dY)
                                if wTP != -1 :
                                        pTempPlot = map.plot(wTP[0], wTP[1])
                                        if pTempPlot.getImprovementType() in lGoodyImprovements : pTempPlot.setImprovementType(-1)

                try :
                        pCity = pPlayer.initCity(iX, iY)
                except:
                        writeLog("", False, [" addBarbCities : init city Error ..."])
                        writeError()
                        continue

                for iRing in range(BBRange) :
                        for dX, dY in rings[iRing] :
                                wTP = toWrap(iX + dX, iY + dY)
                                if wTP != -1 :
                                        if wTP in lPlotsCity:
                                                lPlotsCity.remove(wTP)

                nbCityPlaced += 1
                fullBarbCity(pCity)

        # give some extra gold for barb player to maintain its units for the start of the game
        goldRate = pPlayer.calculateGoldRate()
        if goldRate < 0 :
                extraGold = -1*goldRate*250
                pPlayer.changeGold(extraGold)
                logList.append(" addBarbCities : change gold %r" %extraGold)

        logList.append(" addBarbCities : end placement , nb cities placed %r" %nbCityPlaced)
        logList.append("")
        writeLog("", False, logList)

def addUnits():
        lAddUnits = []
        for sKey in selGen["game"]["startunit"].keys() :
                if not "startunitselect-" in sKey : continue
                pSel = copy.copy(selGen["game"]["startunit"][sKey])
                if pSel == [] : continue
                buff = [pSel[0]]
                selID = sKey.split("-")[1]
                buff.append(copy.copy(selGen["game"]["startunit"]["startunittype-%s" %selID]))
                buff.append(copy.copy(selGen["game"]["startunit"]["startunitquantity-%s" %selID][0]))
                buff.append(copy.copy(selGen["game"]["startunit"]["startunitxp-%s" %selID][0]))
                buff.append(copy.copy(selGen["game"]["startunit"]["startunitplayers-%s" %selID]))
                lAddUnits.append(buff)

        dictPlotsPerArea = getAreaPlots()
        rings = generateRings(1)
        logList = []
        for sUnitType, iAdaptType, nbUnits, nbXP, applyPlayers in lAddUnits :
                logList.append("")
                logList.append(" addUnits : unit %r , iAdaptType %r , nbUnits %r , nbXP %r , applyPlayers %r" %(sUnitType, iAdaptType, nbUnits, nbXP, applyPlayers))
                lPlayers = []
                if 0 in applyPlayers : lPlayers += copy.copy(playerHUList)
                if 1 in applyPlayers : lPlayers += copy.copy(playerAIList)

                for iPlayer in lPlayers :
                        pPlayer = gc.getPlayer(iPlayer)
                        iUnit = gc.getInfoTypeForString(sUnitType)
                        iUnitClass = gc.getUnitInfo(iUnit).getUnitClassType()
                        civXML =  gc.getCivilizationInfo(pPlayer.getCivilizationType())

                        if iAdaptType == 0 :
                                iSpawnUnit = iUnit
                        elif iAdaptType == 1 :
                                iGoodUnit = civXML.getCivilizationUnits(iUnitClass)
                                if iGoodUnit == -1 :
                                        iSpawnUnit = iUnit
                                else :
                                        iSpawnUnit = iGoodUnit
                        else :
                                iGoodUnit = civXML.getCivilizationUnits(iUnitClass)
                                if iGoodUnit == -1 :
                                        logList.append(" addUnits : player %r don't have an unit for class %r" %(iPlayer, gc.getUnitClassInfo(iUnitClass).getType()))
                                        continue
                                else :
                                        iSpawnUnit = iGoodUnit

                        unitXML = gc.getUnitInfo(iSpawnUnit)
                        unitDomain = unitXML.getDomainType()
                        unitMinArea = unitXML.getMinAreaSize()

                        if unitDomain == DomainTypes.DOMAIN_SEA :
                                sX, sY = (-1, -1)
                                for dX, dY in rings[1] :
                                        wTP = toWrap(startX[iPlayer] + dX, startY[iPlayer] + dY)
                                        if wTP != -1 :
                                                if map.plot(wTP[0], wTP[1]).isWater() :
                                                        lAreaPlots = getListPlotsPerArea((wTP[0], wTP[1]), dictPlotsPerArea)
                                                        if len(lAreaPlots) >= unitMinArea :
                                                                sX, sY = wTP
                                                                break
                        else :
                                sX, sY = startPlots[iPlayer]

                        if sX == -1 :
                                logList.append(" addUnits : player %r can't spawn unit %r" %(iPlayer, unitXML.getType()))
                        else :
                                for i in range(nbUnits) :
                                        pUnit = spawnUnit(iPlayer, iSpawnUnit, sX, sY)

                                        if pUnit == -1 :
                                                break
                                        elif (nbXP > 0) and (pUnit.canAcquirePromotionAny()) :
                                                pUnit.setExperience(nbXP, -1)

                                if pUnit != -1 :
                                        logList.append(" addUnits : player %r spawn unit %r" %(iPlayer, unitXML.getType()))
                                else :
                                        logList.append(" addUnits : player %r spawn unit %r ... an error has been raised" %(iPlayer, unitXML.getType()))

        logList.append("")
        writeLog("", False, logList)

def spawnUnit(iPlayer, iUnit, iX, iY):
        pUnit = -1
        try :
                pPlayer = gc.getPlayer(iPlayer)
                if BtS : pUnit = pPlayer.initUnit(iUnit, iX, iY, UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION)
                else : pUnit = pPlayer.initUnit(iUnit, iX, iY, UnitAITypes.NO_UNITAI)
        except :
                writeLog("", False, [" spawnUnit : init unit Error : player %r , unit %r , coords (%r, %r)" %(iPlayer, gc.getUnitInfo(iUnit).getType(), iX, iY)])
                writeError()

        return pUnit

def addTechs():
        userInputRemove = copy.copy(selGen["game"]["techno"]["starttechs"])
        userInputNotRemove = copy.copy(selGen["game"]["techno"]["technoreplace"])
        userInputNotRandom = copy.copy(selGen["game"]["techno"]["technorandom"])

        lAddTechs  = []
        for sKey in selGen["game"]["techno"].keys() :
                if not "addtech-" in sKey : continue
                pSel = copy.copy(selGen["game"]["techno"][sKey])
                if pSel == [] : continue
                buff = [pSel]
                selID = sKey.split("-")[1]
                buff.append(copy.copy(selGen["game"]["techno"]["techquantity-%s" %selID]))
                buff.append(copy.copy(selGen["game"]["techno"]["techplayers-%s" %selID]))
                lAddTechs.append(buff)

        lTechs = copy.copy(XMLEntriesList["techslist"])
        lTechsReapeat = [ sTech for sTech in lTechs if gc.getTechInfo(gc.getInfoTypeForString(sTech)).isRepeat() ]

        logList = [""]
        logList.append(" addTechs : base list : %r" %lTechs)
        logList.append(" addTechs : techs repeat : %r" %lTechsReapeat)
        logList.append(" addTechs : userInputRemove : %r" %userInputRemove)
        logList.append(" addTechs : userInputNotRemove : %r" %userInputNotRemove)
        logList.append(" addTechs : userInputNotRandom : %r" %userInputNotRandom)
        logList.append(" addTechs : lAddTechs : %r" %lAddTechs)
        writeLog("", False, logList)

        lTechsNotRemove = [ gc.getInfoTypeForString(item) for item in userInputNotRemove ]
        lTechsNotRandom = [ gc.getInfoTypeForString(item) for item in userInputNotRandom ]
        lTechs = [ gc.getInfoTypeForString(item) for item in lTechs ]
        lTechsReapeat = [ gc.getInfoTypeForString(item) for item in lTechsReapeat ]

        logList = ["", " addTechs : Techs list per team :"]
        for iTeam in teamList :
                pTeam = gc.getTeam(iTeam)
                lTechsOwned = []
                for iTech in range(gc.getNumTechInfos()) :
                        if pTeam.isHasTech(iTech) :
                                lTechsOwned.append(gc.getTechInfo(iTech).getType())
                logList.append(" addTechs : team %r , starting techs : %r " %(iTeam, lTechsOwned))
        writeLog("", False, logList)
                
        logList = ["", " addTechs : Techs removed :"]
        if userInputRemove == 1 :
                for iTeam in teamList :
                        pTeam = gc.getTeam(iTeam)
                        for iTech in lTechs :
                                if iTech in lTechsNotRemove : continue
                                if pTeam.isHasTech(iTech) :
                                        pTeam.setHasTech(iTech, False, PlayerTypes.NO_PLAYER, False, False)
                                        logList.append(" addTechs : team : %r , %s removed" %(iTeam, gc.getTechInfo(iTech).getType()))
        else :
                logList.append(" addTechs : None")
        writeLog("", False, logList)
                
        logList = ["", " addTechs : Techs added :", ""]
        for techID, nbTech, appliedTeams in lAddTechs :
                logList.append(" addTechs : entries , %r, %r, %r" %(techID, nbTech, appliedTeams))
                if techID in ["alltechsame", "alltechdiff"] :
                        lTeams = []
                        if 0 in appliedTeams : lTeams += copy.copy(teamHUList)
                        if 1 in appliedTeams : lTeams += copy.copy(teamAIList)
                        logList.append("")
                        logList.append(" addTechs : teams , %r" %lTeams)
                        if lTeams == [] : continue

                        for iPass in range(nbTech[0]):
                                logList.append("")
                                logList.append(" addTechs : pass , %r / %r" %(iPass, nbTech[0]-1))
                                dTechsOwned = {}
                                dTechsCanHave = {}
                                for iTeam in lTeams :
                                        dTechsOwned[iTeam] = [iTech for iTech in lTechs if gc.getTeam(iTeam).isHasTech(iTech)]
                                        logList.append(" addTechs : teams %r has techs %r" %(iTeam, [gc.getTechInfo(iTech).getType() for iTech in dTechsOwned[iTeam]]))
                                        dTechsCanHave[iTeam] = [iTech for iTech in lTechs if (not iTech in lTechsNotRandom) and (teamCanResearch(iTeam, iTech))]
                                        logList.append(" addTechs : teams %r can learn techs %r" %(iTeam, [gc.getTechInfo(iTech).getType() for iTech in dTechsCanHave[iTeam]]))

                                logList.append("")

                                if techID == "alltechsame" :
                                        commonTechs = []
                                        for iTech in lTechs :
                                                bCommon = True
                                                for iTeam in lTeams :
                                                        if not iTech in dTechsCanHave[iTeam] :
                                                                bCommon = False
                                                                break
                                                if bCommon : commonTechs.append(iTech)

                                        if len(commonTechs) > 0 :
                                                logList.append(" addTechs : common techs : %r" %([gc.getTechInfo(iTech).getType() for iTech in commonTechs], ))
                                                lSortTechs = [[gc.getTechInfo(iTech).getResearchCost(), iTech] for iTech in commonTechs]
                                                lSortTechs.sort()
                                                logList.append(" addTechs : common techs : %r" %([[item[0], gc.getTechInfo(item[1]).getType()] for item in lSortTechs], ))
                                                maxVal = lSortTechs[0][0]*1.80
                                                lRandTechs = [item[1] for item in lSortTechs if item[0] <= maxVal]
                                                logList.append(" addTechs : common random techs : %r" %([gc.getTechInfo(iTech).getType() for iTech in lRandTechs], ))
                                                iIndexTech = getRandNum(len(lRandTechs), " FoR : same tech selection")
                                                iChosenTech = lRandTechs[iIndexTech]
                                                logList.append(" addTechs : techs %r chosen" %(gc.getTechInfo(iChosenTech).getType(), ))
                                                for iTeam in lTeams :
                                                        gc.getTeam(iTeam).setHasTech(iChosenTech, True, PlayerTypes.NO_PLAYER, False, False)
                                        else :
                                                logList.append(" addTechs : no common techs to learn ...")

                                else :
                                        for iTeam in lTeams :
                                                if len(dTechsCanHave[iTeam]) == 0 :
                                                        logList.append(" addTechs : team %r , no more techs to learn ..." %iTeam)
                                                        logList.append("")
                                                        lTeams.remove(iTeam)
                                                        
                                        if lTeams == [] :
                                                logList.append(" addTechs : no more teams to learn a tech ... break")
                                                break

                                        lTeamEstimate = [[ gc.getTechInfo(iTech).getResearchCost() for iTech in dTechsCanHave[iTeam] ] for iTeam in lTeams ]
                                        minValTeam = [ min(item) for item in lTeamEstimate ]
                                        maxValTeam = [ max(item) for item in lTeamEstimate ]

                                        logList.append(" addTechs : techs value per team : %r" %lTeamEstimate)
                                        logList.append(" addTechs : min techs value per team : %r" %minValTeam)
                                        logList.append(" addTechs : max techs value per team : %r" %maxValTeam)
                                        logList.append("")

                                        minValue = max(minValTeam)
                                        maxValue = min(maxValTeam)

                                        for iTeam in lTeams :
                                                iIndexTeam = lTeams.index(iTeam)

                                                if maxValTeam[iIndexTeam] <= minValue :
                                                        logList.append(" addTechs : team %r , force maximum value for tech" %iTeam)
                                                        lRandTechs = [iTech for iTech in dTechsCanHave[iTeam] if gc.getTechInfo(iTech).getResearchCost() == maxValTeam[iIndexTeam]]
                                                elif minValTeam[iIndexTeam] >= maxValue :
                                                        logList.append(" addTechs : team %r , force minimum value for tech" %iTeam)
                                                        lRandTechs = [iTech for iTech in dTechsCanHave[iTeam] if gc.getTechInfo(iTech).getResearchCost() == minValTeam[iIndexTeam]]
                                                else :
                                                        lRandTechs = [iTech for iTech in dTechsCanHave[iTeam] if (gc.getTechInfo(iTech).getResearchCost() >= minValue) and (gc.getTechInfo(iTech).getResearchCost() <= maxValue)]
                                                        if lRandTechs == [] :
                                                                logList.append(" addTechs : team %r , can find a value in the range ... assign all possible tech for random" %iTeam)
                                                                lRandTechs = dTechsCanHave[iTeam]
                                                        else :
                                                                logList.append(" addTechs : team %r , techs in the range ." %iTeam)

                                                logList.append(" addTechs : team %r , random techs : %r" %(iTeam, [gc.getTechInfo(iTech).getType() for iTech in lRandTechs]))
                                                iIndexTech = getRandNum(len(lRandTechs), " FoR : different tech selection")
                                                iChosenTech = lRandTechs[iIndexTech]
                                                logList.append(" addTechs : team %r , techs %r chosen" %(iTeam, gc.getTechInfo(iChosenTech).getType()))
                                                gc.getTeam(iTeam).setHasTech(iChosenTech, True, PlayerTypes.NO_PLAYER, False, False)
                                                logList.append("")

                else :
                        iTech = gc.getInfoTypeForString(techID[0])
                        lTeams = []
                        if 0 in appliedTeams : lTeams += copy.copy(teamHUList)
                        if 1 in appliedTeams : lTeams += copy.copy(teamAIList)
                        for iTeam in lTeams :
                                nTechs = 1
                                if iTech in lTechsReapeat : nTechs = nbTech[0]
                                for i in range(nTechs) :
                                        gc.getTeam(iTeam).setHasTech(iTech, True, PlayerTypes.NO_PLAYER, False, False)
                        logList.append("")
                        logList.append(" addTechs : teams %r , %r * %r added" %(lTeams, nTechs, gc.getTechInfo(iTech).getType()))

                logList.append("")
        writeLog("", False, logList)

def playerCanResearch(iPlayer, iTech):
        pPlayer = gc.getPlayer(iPlayer)
        pTeam = gc.getTeam(pPlayer.getTeam())
        techXML = gc.getTechInfo(iTech)

        if not techXML.getType() in XMLEntriesList["techslist"] : return False
        if pTeam.isHasTech(iTech) : return False
        try : #try to use can ever research , can bug because of python callback impl
                if not pPlayer.canEverResearch(iTech) : return False
        except :
                writeLog("", False, [" addTechs : Error with canEverResearch (probably python call back error) ..."])
                writeError()
        try : #try to use can research , can bug because of python callback impl . Return false in case of a non advanced start game (no city founded)
                if pPlayer.canResearch(iTech, False) : return True
        except :
                writeLog("", False, [" addTechs : Error with canResearch (probably python call back error) ..."])
                writeError()

        # looking for prerequires for the tech :
        bFoundPossible = False
        bFoundValid = False

        for iOrPrereq in range(gc.getDefineINT("NUM_OR_TECH_PREREQS")) :
                iTechPrereq = techXML.getPrereqOrTechs(iOrPrereq)
                if iTechPrereq == -1 : continue
                bFoundPossible = True
                if pTeam.isHasTech(iTechPrereq) :
                        bFoundValid = True
                        break

        if bFoundPossible and (not bFoundValid) : return False
        
        for iAndPrereq in range(gc.getDefineINT("NUM_AND_TECH_PREREQS")) :
                iTechPrereq = techXML.getPrereqAndTechs(iAndPrereq)
                if iTechPrereq == -1 : continue
                if not pTeam.isHasTech(iTechPrereq) : return False

        return True

def teamCanResearch(iTeam, iTech):
        for iPlayer in playerList :
                if gc.getPlayer(iPlayer).getTeam() != iTeam : continue
                if playerCanResearch(iPlayer, iTech) : return True
        return False

def revealMap():
        userInputRange = getRandSel(selGen["game"]["reveal"]["startrange"], False)
        userInputSea = copy.copy(selGen["game"]["reveal"]["seareveal"])
        userInputLand = copy.copy(selGen["game"]["reveal"]["landreveal"])
        userInputStart = copy.copy(selGen["game"]["reveal"]["startlocs"])

        logList = [""]
        logList.append(" reaveal : start range : %r" %userInputRange)
        logList.append(" reaveal : sea : %r" %userInputSea)
        logList.append(" reaveal : land : %r" %userInputLand)
        logList.append(" reaveal : start loc : %r" %userInputStart)
        writeLog("", False, logList)

        rings = generateRings(max(2, userInputRange))
        cityRings = rings[0] + rings[1] + rings[2]
        noTeam = TeamTypes.NO_TEAM

        if userInputRange > 0 :
                for iPlayer in playerList :
                        iTeam = gc.getPlayer(iPlayer).getTeam()
                        for iRing in range(userInputRange + 1) :
                                for dX, dY in rings[iRing] :
                                        pPlot = map.plot(startX[iPlayer] + dX, startY[iPlayer] + dY)
                                        if pPlot.isNone() : continue
                                        pPlot.setRevealed(iTeam, True, False, noTeam)

        if userInputStart :
                for iTeam in teamList :
                        for iPlayer in playerList :
                                if gc.getPlayer(iPlayer).getTeam() == iTeam : continue
                                for dX, dY in cityRings :
                                        pPlot = map.plot(startX[iPlayer] + dX, startY[iPlayer] + dY)
                                        if pPlot.isNone() : continue
                                        pPlot.setRevealed(iTeam, True, False, noTeam)

                for iPlayer in playerHUList :
                        iTeam = gc.getPlayer(iPlayer).getTeam()
                        for iLoopPlayer in playerList :
                                if gc.getPlayer(iLoopPlayer).getTeam() == iTeam : continue
                                CyEngine().addSign(map.plot(startX[iLoopPlayer],startY[iLoopPlayer]), iPlayer, "Start Plot")

        if userInputSea or userInputLand :
                for iX in range(iW) :
                        for iY in range(iH) :
                                pPlot = map.plot(iX, iY)
                                bWater = pPlot.isWater()
                                if (bWater and userInputSea) or ((not bWater) and userInputLand) :
                                        for iTeam in teamList :
                                                pPlot.setRevealed(iTeam, True, False, noTeam)

def addGold():
        userInputGold = getRandSel(selGen["game"]["gold"]["gold"], False)
        userInputPlayers = selGen["game"]["gold"]["goldplayers"]

        writeLog("", False, ["", " gold : added : %r" %userInputGold])
        writeLog("", False, [" gold : apply players : %r" %userInputPlayers])

        if userInputGold != 0 :
                if 0 in userInputPlayers :
                        for iPlayer in playerHUList :
                                gc.getPlayer(iPlayer).changeGold(userInputGold)
                if 1 in userInputPlayers :
                        for iPlayer in playerAIList :
                                gc.getPlayer(iPlayer).changeGold(userInputGold)

# the list of plots per area ... got some problems with areas sometimes so ...
def getAreaPlots():
        waterPlots = []
        landPlots = []
        areaPlots = { "water" : [], "land" : [] }
        listPlots = []
        rings = generateRings(1)
        ring = { True : [(-1, 0), (0, 1), (0, -1), (1, 0)], False : rings[1] }
        for iX in range(iW) : listPlots += [(iX, iY) for iY in range(iH)]
        areaTp = []
        toCheck = []
        while True :
                if areaTp == [] :
                        if listPlots == [] : break
                        fPlot = copy.copy(listPlots[0])
                        areaTp = []
                        toCheck = [fPlot]
                        bWater = bool(map.plot(fPlot[0], fPlot[1]).isWater())
                        del listPlots[0]

                toCheckNext = []
                areaTp += copy.copy(toCheck)
                for iX, iY in toCheck :
                        for dX, dY in ring[bWater] :
                                wTP = toWrap(iX + dX, iY + dY)
                                if wTP != -1 :
                                        if wTP in areaTp : continue
                                        if wTP in toCheck : continue
                                        if wTP in toCheckNext : continue
                                        if (map.plot(wTP[0], wTP[1]).isWater() != bWater) : continue
                                        toCheckNext.append(wTP)
                                        listPlots.remove(wTP)

                if toCheckNext == [] :
                        if bWater : areaPlots["water"].append(copy.copy(areaTp))
                        else : areaPlots["land"].append(copy.copy(areaTp))
                        areaTp = []
                        continue

                toCheck = copy.copy(toCheckNext)

        return areaPlots

def getListPlotsPerArea(cPlot, areaDict):
        for sId in ["water", "land"] :
                for lList in areaDict[sId] :
                        if cPlot in lList : return lList
        return []

def shuffleList(lList):
        if len(lList) <= 1 : return lList
        newList = []
        while True :
                if len(lList) == 1 :
                        newList.append(lList[0])
                        break
                iChoice = getRandNum(len(lList), " FoR : shuffle list Rand")
                newList.append(lList[iChoice])
                del lList[iChoice]
        return newList

def calculateAirDistance((x1, y1), (x2, y2)):
        distTP = iW*iH
        for w in range(-1, 2) :
                for h in range(-1, 2) :
                        dx1 = x1 + w*iW
                        dy1 = y1 + h*iH
                        if toWrap(dx1, dy1) == -1 : continue
                        loopDist = sqrt((dx1 - x2)**2 + (dy1 - y2)**2)
                        if loopDist < distTP : distTP = loopDist
        return distTP

def genNatureRes():
	natResGen = []
	for iBonus in range(gc.getNumBonusInfos()) :
                bonusXML = gc.getBonusInfo(iBonus)
                bonusHealth = bonusXML.getHealth()
                bonusHappiness = bonusXML.getHappiness()
                bWater = False
                bLand = False
                if bonusXML.getPlacementOrder() < 0 :
                        natResGen.append([-1, bLand, bWater])
                        continue
                for iTerrain in range(gc.getNumTerrainInfos()) :
                        if bonusXML.isTerrain(iTerrain) or bonusXML.isFeatureTerrain(iTerrain):
                                if gc.getTerrainInfo(iTerrain).isWater() : bWater = True
                                else : bLand = True
                if bonusHealth > 0 : natResGen.append([1, bLand, bWater])
                elif bonusHappiness > 0 : natResGen.append([2, bLand, bWater])
                elif bWater or bLand : natResGen.append([0, bLand, bWater])
                else :
                        natResGen.append([-1, bLand, bWater])
                        writeLog("", False, ["", " genNatureRes : failed to find nature for ressources : %s" %(bonusXML.getType(), ), ""])
        return natResGen

def initCustomMapOption():
        global cmo
        cmo = []
        try :
                for sKey in sortKeys(selGen, "maps", idMap) :
                        if sKey in ["selected", "waterper", "wrap", "start", "lakesize", "startterra", "border"] : continue
                        cmo.append(getRandSel(selGen["maps"][idMap][sKey]))

                writeLog("", False, ["", " initCustomMapOption , selgen : %r, cmo : %r" %([" %s : %r" %(sKey, selGen["maps"][idMap][sKey]) for sKey in sortKeys(selGen, "maps", idMap)], cmo)])
        except :
                writeError()

def initWrap():
        global wrapX
        global wrapY

        iWrap = getRandSel(selGen["maps"][idMap]["wrap"])
	wrapX = False
	if iWrap in [1, 2] : wrapX = True
	wrapY = False
	if iWrap == 2 : wrapY = True

        logList = []
        logList.append(" wrapX : %r" %wrapX)
        logList.append(" wrapY : %r" %wrapY)
        logList.append("")
        writeLog("", False, logList)

def initGenerationGlobals():
        global gc
        global isNetMP
        global isGameMP
        global isPbemOrHseat
        global map
        global game
        global dice
        global isBarb
        global canUseGameOptions

	gc = CyGlobalContext()
	map = CyMap()
	game = CyGame()
        isNetMP = game.isNetworkMultiPlayer()
        isGameMP = game.isGameMultiPlayer()
        isPbemOrHseat = bool(game.isPbem() or game.isHotSeat())
        dice = game.getMapRand()

        initMOD()
        initXMLLists(True)
        initCanUseGameOptions()
        initDefaultSelection()
        initValueLimits()
        initPlayerList()

        noBarbOption = gc.getInfoTypeForString("GAMEOPTION_NO_BARBARIANS")
        lockModifiedAssetsOption = gc.getInfoTypeForString("GAMEOPTION_LOCK_MODS")

        isBarb = True
        if noBarbOption != -1 :
                if game.isOption(noBarbOption) : isBarb = False

        logList = []
        if lockModifiedAssetsOption != -1 :
                if game.isOption(lockModifiedAssetsOption) :
                        if canUseGameOptions :
                                popup = PyPopup.PyPopup()
                                popup.setHeaderString(getUText("Warning !"))
                                popup.setBodyString(getUText("You have selected the option 'Lock Modified Assets'. So none of the game options can be applied."))
                                popup.launch()
                                logList.append(" the game locks modified assets : canUseGameOptions turn to False")
                                canUseGameOptions = False

        logList.append(" running Warlords : %r" %Wrds)
        logList.append(" running BtS : %r" %BtS)
        logList.append(" canUseGameOptions : %r" %canUseGameOptions)
        logList.append(" isNetMP : %r" %isNetMP)
        logList.append(" isGameMP : %r" %isGameMP)
        logList.append(" isPbemOrHseat : %r" %isPbemOrHseat)
        logList.append(" isBarb : %r" %isBarb)
        logList.append(" active player : %d" %int(CyGame().getActivePlayer()))
        logList.append("")
        writeLog("", False, logList)

def initPlayerList(bStartPlot = False):
        global playerList
        global playerHUList
        global playerAIList
        global teamList
        global teamHUList
        global teamAIList
        global startPlots
        global startX
        global startY
        global nbPlayer

        playerList = []
        playerHUList = []
        playerAIList = []
        startPlots = {}
        startX = {}
        startY = {}
        for iPlayer in range(gc.getMAX_PLAYERS()):
                pPlayer = gc.getPlayer(iPlayer)
                if pPlayer.isEverAlive() and (iPlayer != gc.getBARBARIAN_PLAYER()):
                        if bStartPlot :
                                startPlot = pPlayer.getStartingPlot()
                                if startPlot.isNone() : continue
                                staX = startPlot.getX()
                                staY = startPlot.getY()
                                if (staX, staY) == (-1, -1) : continue
                                startPlots[iPlayer] = (staX, staY)
                                startX[iPlayer] = staX
                                startY[iPlayer] = staY
                        playerList.append(iPlayer)
                        if pPlayer.isHuman():
                                playerHUList.append(iPlayer)
                        else :
                                playerAIList.append(iPlayer)

        nbPlayer = len(playerList)

        teamList = list(set([gc.getPlayer(iPlayer).getTeam() for iPlayer in playerList]))
        teamHUList = list(set([gc.getPlayer(iPlayer).getTeam() for iPlayer in playerHUList]))
        teamAIList = [iTeam for iTeam in teamList if not iTeam in teamHUList]

        logList = []
        logList.append(" playerList : %r" %playerList)
        logList.append(" playerHUList : %r" %playerHUList)
        logList.append(" playerAIList : %r" %playerAIList)
        logList.append(" teamList : %r" %teamList)
        logList.append(" teamHUList : %r" %teamHUList)
        logList.append(" teamAIList : %r" %teamAIList)
        if bStartPlot :
                logList.append(" startPlots : %r" %startPlots)
                logList.append(" startX : %r" %startX)
                logList.append(" startY : %r" %startY)
        logList.append(" nbPlayer : %r" %nbPlayer)
        logList.append("")
        writeLog("", False, logList)

def initBeforeGenerationGlobals():
        global iW
        global iH

	iW = map.getGridWidth()
	iH = map.getGridHeight()

        logList = []
        logList.append(" iW : %r" %iW)
        logList.append(" iH : %r" %iH)
        logList.append("")
        writeLog("", False, logList)

def getRandSel(lList, sel = True, valType = "int"):
        try :
                if sel :
                        if len(lList) == 1 : return lList[0]
                        iRand = getRandNum(len(lList), "FoR : getRandomSelection sel")
                        return lList[iRand]
                elif valType == "int" :
                        if len(lList) == 1 : return lList[0]
                        minVal, maxVal = lList
                        val = minVal + getRandNum(maxVal-minVal+1, "FoR : getRandomSelection range int")
                        return val
                else :
                        if len(lList) == 1 : return lList[0]
                        minVal, maxVal = lList
                        iRand = getRandNum(10000, "FoR : getRandomSelection range float")
                        val = minVal + (iRand/9999.0)*(maxVal-minVal)
                        return val
        except :
                writeLog("", False, ["", " getRandomSelection entries : %r, %r, %r" %(lList, sel, valType)])
                writeError()
                return -1

def getRandNum(iLen, sLog):
        return dice.get(iLen, sLog)

def toWrap(x, y):
        if wrapX : x = x%iW
        if wrapY : y = y%iH
        if x < 0 : return -1
        if x >= iW : return -1
        if y < 0 : return -1
        if y >= iH : return -1
        return (x,y)

def generateRings(dist):
        tuppleTemp = [[] for i in range(dist+1)]
        for i in range(-1*dist, dist+1) :
                for j in range(-1*dist, dist+1) :
                        k = int(round(sqrt(i**2 + j**2)))
                        if k <= dist :
                                tuppleTemp[k].append((i,j))
        result = []
        for i in range(dist+1) :
                result.append(tuple(tuppleTemp[i]))
        resultat = tuple(result)
        return resultat

def sortList(lList, iKey):
        if (sys.platform == 'darwin') :
                def cmpi(x,y):
                        return cmp(x[iKey], y[iKey])
                lList.sort(cmpi)
        else :
                lList = sorted(lList, key = operator.itemgetter(iKey))
        return lList

# list of sets of p elements into a list of n element
def Cnp(n, p, l = None, res = None):
        if l is None: l = []
        if res is None: res = []
        if p == 0 :
            res.append(l)
            return 
        if n == 0 : return  
        l1 = list(l)
        l1.append(n - 1)
        Cnp(n - 1, p - 1, l1, res)
        Cnp(n - 1, p, l, res)
        return res

##!_!## globals set up
def getXMLInfosMap():
        XMLInfoTemp = {	"bonus": {"NUM": gc.getNumBonusInfos, "GET": gc.getBonusInfo, "DIR": "Terrain", "FILE": "CIV4BonusInfos.xml"},
                        "improvement": {"NUM": gc.getNumImprovementInfos, "GET": gc.getImprovementInfo, "DIR": "Terrain", "FILE": "CIV4ImprovementInfos.xml"},
                        "feature" : {"NUM": gc.getNumFeatureInfos, "GET": gc.getFeatureInfo, "DIR": "Terrain", "FILE": "CIV4FeatureInfos.xml"},
                        "terrain": {"NUM": gc.getNumTerrainInfos, "GET": gc.getTerrainInfo, "DIR": "Terrain", "FILE": "CIV4TerrainInfos.xml"},
                        "religion": {"NUM": gc.getNumReligionInfos, "GET": gc.getReligionInfo, "DIR": "GameInfo", "FILE": "CIV4ReligionInfo.xml"},
                        "civic": {"NUM": gc.getNumCivicInfos, "GET": gc.getCivicInfo, "DIR": "GameInfo", "FILE": "CIV4CivicInfos.xml"},
                        "tech": {"NUM": gc.getNumTechInfos, "GET": gc.getTechInfo, "DIR": "Technologies", "FILE": "CIV4TechInfos.xml"},
                        "building": {"NUM": gc.getNumBuildingInfos, "GET": gc.getBuildingInfo, "DIR": "Buildings", "FILE": "CIV4BuildingInfos.xml"},
                        "civilization": {"NUM": gc.getNumCivilizationInfos, "GET": gc.getCivilizationInfo, "DIR": "Civilizations", "FILE": "CIV4CivilizationInfos.xml"},
                        "leader": {"NUM": gc.getNumLeaderHeadInfos, "GET": gc.getLeaderHeadInfo, "DIR": "Civilizations", "FILE": "CIV4LeaderHeadInfos.xml"},
                        "trait": {"NUM": gc.getNumTraitInfos, "GET": gc.getTraitInfo, "DIR": "Civilizations", "FILE": "CIV4TraitInfos.xml"},
                        "unit": {"NUM": gc.getNumUnitInfos, "GET": gc.getUnitInfo, "DIR": "Units", "FILE": "CIV4UnitInfos.xml"},
                        "promotion": {"NUM":gc.getNumPromotionInfos, "GET": gc.getPromotionInfo, "DIR": "Units", "FILE": "CIV4PromotionInfos.xml"}
                        }
        return XMLInfoTemp

def initMOD():
        global modName
        global modXMLPath
        global modPath
        global XMLCustomAssetsPath
        modName = "None"
        modXMLPath = ""
        modPath = ""
        XMLCustomAssetsPath = ""

        try :
                #try to parse the different folders of civ to check XML types.
                #i will guess that the MOD has at least one unique type in this list to recognize it if i can't get the mod with replay info.
                #this is just to recognize a mod and enable a default implementation for it or for the load/save name.
                #if this is not enough for one MOD ,will add some others requirements.
                #MODs to recognize : _ BtS_FFH2
                XMLInfosMap = getXMLInfosMap()

                writeLog("initMOD", False, [" init Folder paths :", ""])

                docPath = ""
                civPath = os.getcwd()

                # try to set doc path
                try :
                        basePath = civFilePath()
                        if basePath != "" :
                                if (sys.platform == 'darwin'):
                                        civFolder = "Civilization IV"
                                        if Wrds:
                                                civFolder = "Civilization IV Warlords"
                                        if BtS:
                                                civFolder = "Civilization IV Beyond the Sword" #!! need to be checked
                                        docPath = os.path.join(basePath, civFolder)
                                else:
                                        userFolder = regRead(_winreg.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders","Personal")
                                        civFolder = os.path.basename(regRead(_winreg.HKEY_LOCAL_MACHINE,"Software\\Firaxis Games\\Sid Meier's Civilization 4","INSTALLDIR"))
                                        if Wrds:
                                                civFolder = "Warlords" #!! need to be checked
                                        if BtS:
                                                civFolder = "Beyond the Sword"
                                        docPath = os.path.join(basePath, civFolder)
                                if not os.path.isdir(docPath) :
                                        writeLog("", False, [" %r is not an already existing folder" %docPath])
                                        docPath = ""
                                else :
                                        writeLog("", False, [" %r is recognized" %docPath])
                        else :
                                writeLog("", False, [" civFilePath does not return the document path"])
                except :
                        writeLog("", False, [" cannot set doc path"])
                        writeError()

                #check xml custom assets folder
                XMLCustomAssetsFolder = ""
                if docPath != "" :
                        XMLCustomAssetsFolder = os.path.join(docPath, "CustomAssets", "xml")
                        if not os.path.isdir(XMLCustomAssetsFolder) :
                                writeLog("", False, ["", " cannot set XMLCustomAssetsFolder"])
                                XMLCustomAssetsFolder = ""
                        else :
                                writeLog("", False, ["", " XMLCustomAssetsFolder : %r" %XMLCustomAssetsFolder])

                #make the list of MODS and store path infos
                modsInfo = {}
                modsLocPathList = []
                if docPath != "" :
                        docMODFolder = os.path.join(docPath, "MODS")
                        if os.path.isdir(docMODFolder) :
                                modsLocPathList.append(docMODFolder)
                        else :
                                writeLog("", False, ["", " docMODListPath : cannot set MODS folder"])

                MODFolder = os.path.join(civPath, "Mods")
                if os.path.isdir(MODFolder) :
                        modsLocPathList.append(MODFolder)
                else :
                        writeLog("", False, ["", " MODListPath : cannot set Mods folder"])

                for MODFolderLoop in modsLocPathList :
                        for item in os.listdir(MODFolderLoop) :
                                modPathTP = os.path.join(MODFolderLoop, item)
                                if os.path.isdir(modPathTP) :
                                        modINIFile = os.path.join(modPathTP, "%s.ini" %item)
                                        if os.path.isfile(modINIFile) :
                                                iPublicMaps = parseINIFile(modINIFile, "AllowPublicMaps")
                                                if iPublicMaps != 0 :
                                                        modsInfo[item] = {}
                                                        modsInfo[item]["modPath"] = modPathTP

                                                        modsInfo[item]["modXMLPath"] = ""
                                                        xmlFolder = os.path.join(modPathTP, "Assets", "XML")
                                                        if os.path.isdir(xmlFolder) :
                                                                modsInfo[item]["modXMLPath"] = xmlFolder

                                                        modsInfo[item]["isCustomAssets"] = True
                                                        iCustomAssets = parseINIFile(modINIFile, "NoCustomAssets")
                                                        if iCustomAssets == 1 :
                                                                modsInfo[item]["isCustomAssets"] = False

                logList = [""]
                for item in modsInfo.keys() :
                        logList.append(" mod : %r" %item)
                        logList.append(" modPath      : %r" %modsInfo[item]["modPath"])
                        logList.append(" modXMLPath   : %r" %modsInfo[item]["modXMLPath"])
                        logList.append(" CustomAssets : %r" %modsInfo[item]["isCustomAssets"])
                        logList.append("")
                logList.append("")
                writeLog("", False, logList)

                # create a dummy replay info to get the mod name ... don't work with pbem and hotseat games .
                # looking at the SDK this should do not cause problems with other games .tested in sg game and directIP mp game .
                if not isPbemOrHseat :
                        replayInfo = CyReplayInfo()
                        iActivePlayer = CyGame().getActivePlayer()

                        if iActivePlayer != -1 : CyGame().setActivePlayer(-1, False)
                        replayInfo.createInfo(-1)
                        if iActivePlayer != -1 : CyGame().setActivePlayer(iActivePlayer, False)

                        modNameFull = replayInfo.getModName()

                        if modNameFull != "" :
                                if (sys.platform == 'darwin'):
                                        listPaths = [item for item in modNameFull.split("\\") if item != ""]
                                        modNameTP = listPaths[-1]
                                else :
                                        head, modNameTP = os.path.split(os.path.normpath(modNameFull))
                                if modNameTP in modsInfo.keys() :
                                        modName = modNameTP
                                        modXMLPath = modsInfo[modName]["modXMLPath"]
                                        modPath = modsInfo[modName]["modPath"]
                                        if modsInfo[modName]["isCustomAssets"] : XMLCustomAssetsPath = XMLCustomAssetsFolder
                                        writeLog("", True, ["", " MOD name recognized : %s" %modName])
                                else :
                                        writeLog("", True, ["", " MOD name not recognized ... no MOD name will be taken in count"])
                        else :
                                writeLog("", True, ["", " Running default civilisation : modName None"])
                        recognizeMOD()
                        return

                writeLog("", False, ["", " the game isPbem Or Hotseat . will try to recognize the MOD with the xml values ...", ""])
                # make the list of path for civ versions
                defaultXMLFolders = []
                if BtS :
                        xmlFolder = os.path.join(civPath, "Assets", "XML")
                        if os.path.isdir(xmlFolder) :
                                defaultXMLFolders.append(xmlFolder)
                        else :
                                writeLog("", False, [" BtS : cannot set BtS XML folder ..."])

                        head, tail = os.path.split(civPath)

                        xmlFolder = os.path.join(head, "Warlords", "Assets", "XML")
                        if os.path.isdir(xmlFolder) :
                                defaultXMLFolders.append(xmlFolder)
                        else :
                                writeLog("", False, [" BtS : cannot set Warlords XML folder ..."])
                        
                        xmlFolder = os.path.join(head, "Assets", "XML")
                        if os.path.isdir(xmlFolder) :
                                defaultXMLFolders.append(xmlFolder)
                        else :
                                writeLog("", False, [" BtS : cannot set Vanilla XML folder ..."])

                        if len(defaultXMLFolders) == 3 : writeLog("", False, [" BtS : All default XML folders set"])
                        
                elif Wrds :
                        xmlFolder = os.path.join(civPath, "Assets", "XML")
                        if os.path.isdir(xmlFolder) :
                                defaultXMLFolders.append(xmlFolder)
                        else :
                                writeLog("", False, [" Warlords : cannot set Warlords XML folder ..."])

                        head, tail = os.path.split(civPath)

                        xmlFolder = os.path.join(head, "Assets", "XML")
                        if os.path.isdir(xmlFolder) :
                                defaultXMLFolders.append(xmlFolder)
                        else :
                                writeLog("", False, [" Warlords : cannot set Vanilla XML folder ..."])

                        if len(defaultXMLFolders) == 2 : writeLog("", False, [" Warlords : All default XML folders set"])
                        
                else :
                        xmlFolder = os.path.join(civPath, "Assets", "XML")
                        if os.path.isdir(xmlFolder) :
                                defaultXMLFolders.append(xmlFolder)
                                writeLog("", False, [" Vanilla : default XML folder set"])
                        else :
                                writeLog("", False, [" Vanilla : cannot set XML folder ..."])

                writeLog("", False, ["", " Begin XML Mod recognizance :", ""])

                modList = [item for item in modsInfo.keys()]
                bMod = False
                for info in XMLInfosMap.keys() :
                        writeLog("", False, ["", " Check info : %s" %info, ""])

                        elementList = [getSText(XMLInfosMap[info]["GET"](i).getType()) for i in range(XMLInfosMap[info]["NUM"]())]

                        xmlDir = XMLInfosMap[info]["DIR"]
                        xmlFile = XMLInfosMap[info]["FILE"]

                        parsedElementList = []
                        bDefaultElementList = False

                        #first check if the list of elements is default
                        for pathDef in defaultXMLFolders :
                                pathTP = os.path.join(pathDef, xmlDir, xmlFile)
                                if os.path.isfile(pathTP) :
                                        parsedElementList = parseXMLFile(pathTP)
                                        break

                        if elementList == parsedElementList :
                                bDefaultElementList = True
                                writeLog("", False, [" default settings for %s" %info, ""])
                        else :
                                writeLog("", False, [" not default settings for %s ... continue" %info])

                        #check if the file is defined is the custom folder
                        if XMLCustomAssetsFolder != "" :
                                pathTP = os.path.join(XMLCustomAssetsFolder, xmlDir, xmlFile)
                                if os.path.isfile(pathTP) :
                                        parsedElementList = parseXMLFile(pathTP)

                                        if elementList == parsedElementList :
                                                bDefaultElementList = True
                                                writeLog("", False, [" custom assets settings for %s" %info, ""])
                                        else :
                                                writeLog("", False, [" not custom assets settings for %s ... continue" %info])
                                else :
                                        writeLog("", False, [" no file in custom assets for %s ... continue" %info])

                        writeLog("", False, ["", " checking mods for %s :" %info, ""])

                        if not bDefaultElementList : bMod = True

                        # search the mods xml files to compare
                        for modNameTP in [item for item in modList] :
                                xmlFolder = modsInfo[modNameTP]["modXMLPath"]
                                if xmlFolder == "" : #this mod do not have a xml folder so can't check it
                                        modList.remove(modNameTP)
                                        continue
                                pathTP = os.path.join(xmlFolder, xmlDir, xmlFile)
                                if os.path.isfile(pathTP) :
                                        parsedElementList = parseXMLFile(pathTP)

                                        if elementList == parsedElementList :
                                                writeLog("", False, [" mod %s settings for %s" %(modNameTP, info)])
                                        else :
                                                writeLog("", False, [" not mod %s settings for %s ... continue" %(modNameTP, info)])
                                                modList.remove(modNameTP)
                                else :
                                        writeLog("", False, [" no file in mod %s assets for %s ... continue" %(modNameTP, info)])
                                        if not bDefaultElementList : modList.remove(modNameTP)

                        writeLog("", False, [""])

                if bMod :
                        if len(modList) == 1 :
                                modName = modList[0]
                                modXMLPath = modsInfo[modName]["modXMLPath"]
                                modPath = modsInfo[modName]["modPath"]
                                if modsInfo[modName]["isCustomAssets"] : XMLCustomAssetsPath = XMLCustomAssetsFolder
                                writeLog("", True, ["", " MOD name recognized with xml : %s" %modName])
                        elif len(modList) > 1 :
                                writeLog("", True, ["", " multiple mods match xml files , mod not chosen : %r" %modList])
                        else :
                                writeLog("", True, ["", " mod not found ..."])
                else :
                        writeLog("", True, ["", " default xml type for all checked ... mod not chosen"])

        except :
                writeLog("", False, ["", " error during initMOD() : launch recognize mod to initialize vars", ""])
                writeError()

        recognizeMOD()

def recognizeMOD() :
        global is_BtS_FFH2

        is_BtS_FFH2 = False
        if BtS and "Fall from Heaven 2" in modName : is_BtS_FFH2 = True
        writeLog("", False, ["", " recognizeMOD : running BtS FFH2 : %r" %is_BtS_FFH2, ""])
        
def parseINIFile(filePath, sTag):
        try :
                Sfile = open(filePath, "r")
                lLinesFile = Sfile.readlines()
                for item in lLinesFile :
                        if item[0:len(sTag)] == sTag :
                                if "1" in item[len(sTag):] : return 1
                                elif "0" in item[len(sTag):] : return 0
                                else : return -1
        except :
                writeLog("", False, [" parseINIFile : %r , %s" %(filePath, sTag)])
                writeError()
        return -1

def getXMLValues(XMLinfo, sTagBegin, sTagEnd):
        rDict = {}
        try :
                XMLInfosMap = getXMLInfosMap()
                xmlDir = XMLInfosMap[XMLinfo]["DIR"]
                xmlFile = XMLInfosMap[XMLinfo]["FILE"]
                if XMLCustomAssetsPath != "" :
                        pathTP = os.path.join(XMLCustomAssetsPath, xmlDir, xmlFile)
                        if os.path.isfile(pathTP) :
                                rDict = parseXMLFile(pathTP, sTagBegin, sTagEnd)
                elif modXMLPath != "" :
                        pathTP = os.path.join(modXMLPath, xmlDir, xmlFile)
                        if os.path.isfile(pathTP) :
                                rDict = parseXMLFile(pathTP, sTagBegin, sTagEnd)
        except :
                writeLog("", False, [" getXMLValues ERROR : %s , %s , %s" %(XMLinfo, sTagBegin, sTagEnd)])
                writeError()
        return rDict

def parseXMLFile(filePath, sTagBegin="", sTagEnd=""):
        if sTagBegin == "" : result = []
        else : result = {}
        try :
                Sfile = open(filePath, "r")
                sTextFile = Sfile.read()
                textList = sTextFile.split("<Type>")[1:]
                for item in textList :
                        elementType = item[0:item.index("</Type>")]
                        if sTagBegin == "" :
                                result.append(elementType)
                        else :
                                if sTagBegin in item :
                                        itemTp = item.split(sTagBegin)[1]
                                        elementValue = itemTp[0:itemTp.index(sTagEnd)]
                                        result[elementType] = elementValue
                                else :
                                        result[elementType] = ""
        except :
                writeLog("", False, [" parseXMLFile ERROR : %r , %s , %s" %(filePath, sTagBegin, sTagEnd)])
                writeError()
        return result

def initXMLLists(bForce = False):
        global XMLEntriesList

        # make the list of xml values for resources , units , tech , etc ...
        if (XMLEntriesList != {}) and (not bForce) : return

        # resources lists
        XMLEntriesList["list"] = []
        XMLEntriesList["reslist"] = []
        XMLEntriesList["groupreslist"] = []
        XMLEntriesList["strategic"] = []
        XMLEntriesList["health"] = []
        XMLEntriesList["happiness"] = []
        XMLEntriesList["land"] = []
        XMLEntriesList["water"] = []

        barbarianCivXML = gc.getCivilizationInfo( gc.getInfoTypeForString("CIVILIZATION_BARBARIAN") )

	for iBonus in range(gc.getNumBonusInfos()) :
                bonusXML = gc.getBonusInfo(iBonus)

                if bonusXML.getPlacementOrder()<0 : continue # don't take in count the resources not placed during map generation

                # check if the bonus is placed with a standart method
                if (bonusXML.getConstAppearance()<=0) and (bonusXML.getRandAppearance1()<=0) and (bonusXML.getRandAppearance2()<=0) and (bonusXML.getRandAppearance3()<=0) and (bonusXML.getRandAppearance4()<=0) : continue
                if (bonusXML.getTilesPer()<=0) and (bonusXML.getPercentPerPlayer()<=0) : continue

                bonusType = getSText(bonusXML.getType())

                bLand = False
                bWater = False
                for iTerrain in range(gc.getNumTerrainInfos()):
                        if bonusXML.isTerrain(iTerrain) or bonusXML.isFeatureTerrain(iTerrain):
                                if gc.getTerrainInfo(iTerrain).isWater() : bWater = True
                                else : bLand = True

                if (not bLand) and (not bWater) : continue # don't know where to place this bonus
                if bLand : XMLEntriesList["land"].append(str(bonusType))
                if bWater : XMLEntriesList["water"].append(str(bonusType))

                XMLEntriesList["reslist"].append(str(bonusType))
                XMLEntriesList["list"].append(str(bonusType))

                uniqueBonus = bonusXML.getUniqueRange()
                groupRangeBonus = bonusXML.getGroupRange()

                if (uniqueBonus == 0) and (groupRangeBonus > 0) : XMLEntriesList["groupreslist"].append(str(bonusType))

                healthBonus = bonusXML.getHealth()
                happinessBonus = bonusXML.getHappiness()

                if happinessBonus > 0 : XMLEntriesList["happiness"].append(str(bonusType)) # if a bonus is health and happiness , it count as a happiness bonus
                elif healthBonus > 0 : XMLEntriesList["health"].append(str(bonusType))
                else : XMLEntriesList["strategic"].append(str(bonusType)) # every no health , no happiness bonus is considered as a strategic bonus

        # building lists
        XMLEntriesList["buildingsbarb"] = []

        for iBuildingClass in range(gc.getNumBuildingClassInfos()) :
                buildingClassXML = gc.getBuildingClassInfo(iBuildingClass)

                if buildingClassXML.getMaxGlobalInstances() != -1 : continue
                if buildingClassXML.getMaxPlayerInstances() != -1 : continue

                iBuilding = barbarianCivXML.getCivilizationBuildings(iBuildingClass)

                if iBuilding == -1 : continue

                buildingXML = gc.getBuildingInfo(iBuilding)

                if buildingXML.getDefenseModifier() <= 0 : continue
                if buildingXML.getProductionCost() <= 0 : continue

                buildingType = getSText(buildingXML.getType())
                XMLEntriesList["list"].append(str(buildingType))
                XMLEntriesList["buildingsbarb"].append(str(buildingType))

        # tech lists
        XMLEntriesList["techslist"] = []
        XMLEntriesList["techsstartciv"] = []
        XMLEntriesList["techsrepeat"] = []

        for iTech in range(gc.getNumTechInfos()) :
                techXML = gc.getTechInfo(iTech)

                if techXML.isDisable() : continue
                if techXML.getResearchCost() <= 0 : continue # don't take in count the tech not granted by researsh

                bReligionFounding = False
                for iReligion in range(gc.getNumReligionInfos()) :
                        if gc.getReligionInfo(iReligion).getTechPrereq() == iTech :
                                bReligionFounding = True
                                break
                if bReligionFounding : continue # don't take in count the techs that grants some religions

                techType = getSText(techXML.getType())
                XMLEntriesList["list"].append(str(techType))
                XMLEntriesList["techslist"].append(str(techType))

                if techXML.isRepeat() : XMLEntriesList["techsrepeat"].append(str(techType))

                for iCiv in range(gc.getNumCivilizationInfos()) :
                        civXML = gc.getCivilizationInfo(iCiv)

                        if not civXML.isPlayable() : continue

                        if civXML.isCivilizationFreeTechs(iTech) :
                                XMLEntriesList["techsstartciv"].append(str(techType))
                                break

        # unit combat list
        XMLEntriesList["unitcombatlist"] = []

        for iCombat in range(gc.getNumUnitCombatInfos()) :
                combatXML = gc.getUnitCombatInfo(iCombat)

                combatType = getSText(combatXML.getType())
                XMLEntriesList["list"].append(str(combatType))
                XMLEntriesList["unitcombatlist"].append(str(combatType))

        # unit class list
        # unit lists
        XMLEntriesList["unitclasslist"] = []
        XMLEntriesList["units"] = {
                "list" : [] ,
                "barbdefender" : [] ,
                "barbfight" : [] ,
                "animland" : [] ,
                "peace" : [] , # just to sort national , world unit
                "peacedd" : [] , # peace dropdown
                "land" : [] ,
                "landdd" : [] ,
                "water" : [] ,
                "waterdd" : [] ,
                "air" : [] ,
                "airdd" : [] ,
                "other" : [] ,
                "otherdd" : [] ,
                "national" : [] ,
                "team" : [] ,
                "world" : [] ,
                "combatnone" : []
                }

        for sCombatType in XMLEntriesList["unitcombatlist"] : XMLEntriesList["units"][sCombatType] = []

        # for mods that use some type i don't wan't to appear in the list
        # FFH : SPECIALUNIT_SPELL
        specialUnitTypeToRemove = ["SPECIALUNIT_SPELL"]
        specialUnitTypeToRemove = [ gc.getInfoTypeForString(item) for item in specialUnitTypeToRemove ]
        specialUnitTypeToRemove = [ item for item in specialUnitTypeToRemove if item != -1]

        tempBarbList = []
        
        for iUnit in  range(gc.getNumUnitInfos()) :
                unitXML = gc.getUnitInfo(iUnit)

                if unitXML.getSpecialUnitType() in specialUnitTypeToRemove : continue

                if unitXML.isPrereqReligion() : continue
                if unitXML.getHolyCity() >= 0 : continue
                if unitXML.getPrereqReligion() >= 0 : continue
                if unitXML.getReligionType() >= 0 : continue
                if unitXML.getStateReligion() >= 0 : continue

                bSpreadReligion = False
                for iReligion in range(gc.getNumReligionInfos()) :
                        if unitXML.getReligionSpreads(iReligion) :
                                bSpreadReligion = True
                                break
                if bSpreadReligion : continue

                bRequiresReligionTech = False
                techPrereqList = []

                iBuildingRequ = unitXML.getPrereqBuilding()

                if iBuildingRequ != -1 :
                        buildingXML = gc.getBuildingInfo(iBuildingRequ)

                        if buildingXML.getHolyCity() >= 0 : continue
                        if buildingXML.getPrereqReligion() >= 0 : continue
                        if buildingXML.getReligionType() >= 0 : continue
                        if buildingXML.getStateReligion() >= 0 : continue

                        techPrereqList.append(buildingXML.getPrereqAndTech())
                        for i in range(gc.getDefineINT("NUM_BUILDING_AND_TECH_PREREQS")) : techPrereqList.append(buildingXML.getPrereqAndTechs(i))

                techPrereqList.append(unitXML.getPrereqAndTech())
                for i in range(gc.getDefineINT("NUM_UNIT_AND_TECH_PREREQS")) : techPrereqList.append(unitXML.getPrereqAndTechs(i))
                techPrereqList = [ item for item in techPrereqList if item != -1]

                for iReligion in range(gc.getNumReligionInfos()) :
                        if gc.getReligionInfo(iReligion).getTechPrereq() in techPrereqList :
                                bRequiresReligionTech = True
                                break

                if bRequiresReligionTech : continue

                iUnitClass = unitXML.getUnitClassType()
                unitClassXML = gc.getUnitClassInfo(iUnitClass)
                classType = getSText(unitClassXML.getType())
                if not classType in XMLEntriesList["unitclasslist"] :
                        XMLEntriesList["list"].append(str(classType))
                        XMLEntriesList["unitclasslist"].append(str(classType))

                unitType = getSText(unitXML.getType())
                XMLEntriesList["list"].append(str(unitType))
                XMLEntriesList["units"]["list"].append(str(unitType))

                unitDomain = unitXML.getDomainType()
                unitDefaultAI = unitXML.getDefaultUnitAIType()

                # domain list
                if unitDomain == DomainTypes.DOMAIN_LAND : XMLEntriesList["units"]["land"].append(str(unitType))
                elif unitDomain == DomainTypes.DOMAIN_SEA : XMLEntriesList["units"]["water"].append(str(unitType))
                elif unitDomain == DomainTypes.DOMAIN_AIR : XMLEntriesList["units"]["air"].append(str(unitType))
                else : XMLEntriesList["units"]["other"].append(str(unitType))

                # land animals
                if (unitXML.isAnimal()) and (unitDomain == DomainTypes.DOMAIN_LAND) : XMLEntriesList["units"]["animland"].append(str(unitType))

                # combat type
                iCombatType = unitXML.getUnitCombatType()
                if iCombatType == -1 :
                        XMLEntriesList["units"]["combatnone"].append(str(unitType))
                else :
                        unitCombatType = getSText(gc.getUnitCombatInfo(iCombatType).getType())
                        XMLEntriesList["units"][unitCombatType].append(str(unitType))

                # others
                bPeaceUnit = True
                if unitXML.isMilitaryHappiness() or unitXML.isMilitaryProduction() or unitXML.isMilitarySupport() or unitXML.isAnimal() : bPeaceUnit = False
                if unitDefaultAI in [UnitAITypes.UNITAI_WORKER, UnitAITypes.UNITAI_WORKER_SEA] : bPeaceUnit = True
                if unitXML.isFound() : bPeaceUnit = True

                if bPeaceUnit : XMLEntriesList["units"]["peace"].append(str(unitType))

                bLimited = False
                if unitClassXML.getMaxGlobalInstances() != -1 :
                        bLimited = True
                        XMLEntriesList["units"]["world"].append(str(unitType))
                if unitClassXML.getMaxPlayerInstances() != -1 :
                        bLimited = True
                        XMLEntriesList["units"]["national"].append(str(unitType))
                if unitClassXML.getMaxTeamInstances() != -1 :
                        bLimited = True
                        XMLEntriesList["units"]["team"].append(str(unitType))

                if not bLimited :
                        if bPeaceUnit : XMLEntriesList["units"]["peacedd"].append(str(unitType))
                        elif unitDomain == DomainTypes.DOMAIN_LAND : XMLEntriesList["units"]["landdd"].append(str(unitType))
                        elif unitDomain == DomainTypes.DOMAIN_SEA : XMLEntriesList["units"]["waterdd"].append(str(unitType))
                        elif unitDomain == DomainTypes.DOMAIN_AIR : XMLEntriesList["units"]["airdd"].append(str(unitType))
                        else : XMLEntriesList["units"]["otherdd"].append(str(unitType))

                        if (not bPeaceUnit) and (unitDomain == DomainTypes.DOMAIN_LAND) and (not unitXML.isAnimal()):
                                if barbarianCivXML.getCivilizationUnits(iUnitClass) == iUnit :
                                        if unitDefaultAI == UnitAITypes.UNITAI_CITY_DEFENSE :
                                                XMLEntriesList["units"]["barbdefender"].append(str(unitType))
                                        elif unitXML.getUnitAIType(UnitAITypes.UNITAI_CITY_DEFENSE) :
                                                XMLEntriesList["units"]["barbfight"].append(str(unitType))
                                        else :
                                                tempBarbList.append(str(unitType))

        if XMLEntriesList["units"]["barbdefender"] == [] :
                XMLEntriesList["units"]["barbdefender"] = copy.deepcopy(XMLEntriesList["units"]["barbfight"])
                XMLEntriesList["units"]["barbfight"] = copy.deepcopy(tempBarbList)

        if XMLEntriesList["units"]["barbfight"] == [] :
                XMLEntriesList["units"]["barbfight"] = copy.deepcopy(tempBarbList)

        logList = []
        for iKey in XMLEntriesList.keys() :
                if type(XMLEntriesList[iKey]) is types.DictType :
                        logList.append("")
                        for iKey2 in XMLEntriesList[iKey].keys() :
                                logList.append(" %s , %s : %r" %(iKey, iKey2, XMLEntriesList[iKey][iKey2]))
                        logList.append("")
                else :
                                logList.append(" %s : %r" %(iKey, XMLEntriesList[iKey]))
        writeLog("initXMLLists", True, logList)

def initXMLDescriptions() :
        global XMLDescriptions
        global bInitDescription
        
        if not bInitDescription : return
        bInitDescription = False

        writeLog("initXMLDescriptions", False, [""])

        # description lists
        initialLanguage = int(CyGame().getCurrentLanguage())

        for sType in XMLEntriesList["list"] :
                XMLDescriptions[str(sType)] = "ini"

        # used to check if a unitclass has multiple units to add the unit class description in the unit descrition
        nbUnitPerClass = [ 0 for i in range(gc.getNumUnitClassInfos()) ]
        for unitType in XMLEntriesList["units"]["list"] :
                unitXML = gc.getUnitInfo(gc.getInfoTypeForString(unitType))
                iUnitClass = unitXML.getUnitClassType()
                nbUnitPerClass[iUnitClass] += 1

        TXT_MAX_WORLDUNIT = ["Max %d", "Max %d", "Max %d", "Mas %d", "Máx %d"]
        TXT_MAX_TEAMUNIT = ["Max %d per team", "Max %d par équipe", "Max %d pro Team", "Mas %d per gruppo", "Máx %d por equipo"]
        TXT_MAX_PLAYERUNIT = ["Max %d per player", "Max %d par joueur", "Max %d pro Spieler", "Mas %d per giocatore", "Máx %d por jugador"]

        if initialLanguage != language :
                CyGame().setCurrentLanguage(language)

        # resources descriptions
        for bonusType in XMLEntriesList["reslist"] :

                bonusXML = gc.getBonusInfo(gc.getInfoTypeForString(bonusType))

                try :
                        sDescription = getSText(bonusXML.getDescription())
                except :
                        writeLog("", False, ["an error to convert description , language : %d , type : %s" %(language, bonusType), ""])
                        sDescription = ""

                if (sDescription == "") or (sDescription[0:9] == "TXT_KEY_"):
                        sDescription = str(bonusType)[6:]
                        sDescription = sDescription.replace("_", " ")
                        sDescription = sDescription.capitalize()
                XMLDescriptions[str(bonusType)] = str(sDescription)

        # building descriptions
        for buldingType in XMLEntriesList["buildingsbarb"] :

                buildingXML = gc.getBuildingInfo(gc.getInfoTypeForString(buldingType))

                try :
                        sDescription = getSText(buildingXML.getDescription())
                except :
                        writeLog("", False, ["an error to convert description , language : %d , type : %s" %(language, buldingType), ""])
                        sDescription = ""

                if (sDescription == "") or (sDescription[0:9] == "TXT_KEY_"):
                        sDescription = str(buldingType)[9:]
                        sDescription = sDescription.replace("_", " ")
                        sDescription = sDescription.capitalize()
                XMLDescriptions[str(buldingType)] = str(sDescription)

        # tech descriptions
        for techType in XMLEntriesList["techslist"] :

                techXML = gc.getTechInfo(gc.getInfoTypeForString(techType))

                try :
                        sDescription = getSText(techXML.getDescription())
                except :
                        writeLog("", False, ["an error to convert description , language : %d , type : %s" %(language, techType), ""])
                        sDescription = ""

                if (sDescription == "") or (sDescription[0:9] == "TXT_KEY_"):
                        sDescription = str(techType)[5:]
                        sDescription = sDescription.replace("_", " ")
                        sDescription = sDescription.capitalize()
                XMLDescriptions[str(techType)] = str(sDescription)

        # unit combat descriptions
        for combatType in XMLEntriesList["unitcombatlist"] :

                combatXML = gc.getUnitCombatInfo(gc.getInfoTypeForString(combatType))

                try :
                        sDescription = getSText(combatXML.getDescription())
                except :
                        writeLog("", False, ["an error to convert description , language : %d , type : %s" %(language, combatType), ""])
                        sDescription = ""

                if (sDescription == "") or (sDescription[0:9] == "TXT_KEY_"):
                        sDescription = str(combatType)[11:]
                        sDescription = sDescription.replace("_", " ")
                        sDescription = sDescription.capitalize()
                XMLDescriptions[str(combatType)] = str(sDescription)

        # unit class descriptions
        for unitClassType in XMLEntriesList["unitclasslist"] :

                unitClassXML = gc.getUnitClassInfo(gc.getInfoTypeForString(unitClassType))

                try :
                        sDescription = getSText(unitClassXML.getDescription())
                except :
                        writeLog("", False, ["an error to convert description , language : %d , type : %s" %(language, unitClassType), ""])
                        sDescription = ""

                if (sDescription == "") or (sDescription[0:9] == "TXT_KEY_"):
                        sDescription = str(unitClassType)[10:]
                        sDescription = sDescription.replace("_", " ")
                        sDescription = sDescription.capitalize()
                XMLDescriptions[str(unitClassType)] = str(sDescription)

        # unit descriptions
        for unitType in XMLEntriesList["units"]["list"] :

                unitXML = gc.getUnitInfo(gc.getInfoTypeForString(unitType))

                try :
                        sDescription = getSText(unitXML.getDescription())
                except :
                        writeLog("", False, ["an error to convert description , language : %d , type : %s" %(language, unitType), ""])
                        sDescription = ""

                if (sDescription == "") or (sDescription[0:9] == "TXT_KEY_"):
                        sDescription = str(unitType)[5:]
                        sDescription = sDescription.replace("_", " ")
                        sDescription = sDescription.capitalize()

                bAddClassDescription = False
                bAddWorldNb = False
                bAddTeamNb = False
                bAddPlayerNb = False
                
                iUnitClass = unitXML.getUnitClassType()
                unitClassXML = gc.getUnitClassInfo(iUnitClass)

                if nbUnitPerClass[iUnitClass] > 1 : bAddClassDescription = True
                if unitType in XMLEntriesList["units"]["world"] : bAddWorldNb = True
                if unitType in XMLEntriesList["units"]["team"] : bAddTeamNb = True
                if unitType in XMLEntriesList["units"]["national"] : bAddPlayerNb = True

                if bAddClassDescription or bAddWorldNb or bAddTeamNb or bAddPlayerNb :
                        sDescription += " "

                if bAddClassDescription :
                        classType = getSText(unitClassXML.getType())
                        sDescription += "(%s)" %XMLDescriptions[classType]

                if bAddWorldNb or bAddTeamNb or bAddPlayerNb :
                        sList = []
                        if bAddWorldNb : sList.append(TXT_MAX_WORLDUNIT[language] %unitClassXML.getMaxGlobalInstances())
                        if bAddTeamNb : sList.append(TXT_MAX_TEAMUNIT[language] %unitClassXML.getMaxTeamInstances())
                        if bAddPlayerNb : sList.append(TXT_MAX_PLAYERUNIT[language] %unitClassXML.getMaxPlayerInstances())
                        sDescription += "(%s)" %" , ".join(sList)
                        
                XMLDescriptions[str(unitType)] = str(sDescription)

        if initialLanguage != language :
                CyGame().setCurrentLanguage(initialLanguage)

        logList = []
        listKeys = XMLDescriptions.keys()
        listKeys.sort()
        for iKey in listKeys : logList.append(" %s : %r" %(iKey, XMLDescriptions[iKey]))
        writeLog("", True, logList)

# this function is used to sort element type in function of the language descriptions for the screen .
def sortXMLLists():
        global XMLEntriesList

        # resources sort
        XMLEntriesList["reslist"] = []
        for idRes in ["strategic", "health", "happiness"] :
                tpList = [ [XMLDescriptions[item], item] for item in XMLEntriesList[idRes] ]
                tpList.sort()
                XMLEntriesList[idRes] = [item[1] for item in tpList]
                XMLEntriesList["reslist"] += [item[1] for item in tpList]

        # buildings sort
        buildingListTemp = [[item, XMLDescriptions[item], -1] for item in XMLEntriesList["buildingsbarb"]]
        for item in buildingListTemp :
                iTech = gc.getBuildingInfo(gc.getInfoTypeForString(item[0])).getPrereqAndTech()
                if iTech == -1 :
                        item[2] = 0
                else :
                        item[2] = max(0, gc.getTechInfo(iTech).getResearchCost())

        buildingListTemp = sortList(buildingListTemp, 1)
        buildingListTemp = sortList(buildingListTemp, 2)

        XMLEntriesList["buildingsbarb"] = [item[0] for item in buildingListTemp]

        # tech sort
        techListTemp = [[item, XMLDescriptions[item], gc.getTechInfo(gc.getInfoTypeForString(item)).getResearchCost()] for item in XMLEntriesList["techslist"]]
        techListTemp = sortList(techListTemp, 1)
        techListTemp = sortList(techListTemp, 2)

        XMLEntriesList["techslist"] = [item[0] for item in techListTemp]

        techListTemp = [[item, XMLDescriptions[item]] for item in XMLEntriesList["techsstartciv"]]
        techListTemp = sortList(techListTemp, 1)

        XMLEntriesList["techsstartciv"] = [item[0] for item in techListTemp]

        # unit combat sort
        combatListTemp = [[item, XMLDescriptions[item]] for item in XMLEntriesList["unitcombatlist"]]
        combatListTemp = sortList(combatListTemp, 1)

        XMLEntriesList["unitcombatlist"] = [item[0] for item in combatListTemp]

        # unit sort
        # 1rst group units per unit class ( to make them always grouped in the list )      
        unitsPerClass = [ [] for i in range(gc.getNumUnitClassInfos()) ]
        for unitType in XMLEntriesList["units"]["list"] :
                unitXML = gc.getUnitInfo(gc.getInfoTypeForString(unitType))
                iUnitClass = unitXML.getUnitClassType()
                unitsPerClass[iUnitClass].append(unitType)

        # 2nd sort each class group by default unit , then description
        for iUnitClass in range(gc.getNumUnitClassInfos()) :
                if len(unitsPerClass[iUnitClass]) < 2 : continue
                iDefaultUnitType = gc.getUnitClassInfo(iUnitClass).getDefaultUnitIndex()
                if iDefaultUnitType != -1 :
                        sDefaultUnitType = getSText(gc.getUnitInfo(iDefaultUnitType).getType())
                        if sDefaultUnitType in unitsPerClass[iUnitClass] :
                                tpList0 = [sDefaultUnitType]
                        else :
                                tpList0 = []
                else :
                        tpList0 = []

                tpList1 = [[item, XMLDescriptions[item]] for item in unitsPerClass[iUnitClass] if not item in tpList0]
                if len(tpList1) > 1 : tpList1 = sortList(tpList1, 1)

                unitsPerClass[iUnitClass] = tpList0 + [item[0] for item in tpList1]

        # 3rd sort the units lists by class group, element group (peace, land, ...) , power , description
        listTag = ["barbdefender", "barbfight", "animland", "peacedd", "landdd", "waterdd", "airdd", "otherdd", "national", "team", "world", "combatnone"]
        listTag += [item for item in XMLEntriesList["unitcombatlist"]]
        for sTag in listTag :
                if len(XMLEntriesList["units"][sTag]) < 2 : continue

                classList = []
                elementList = []

                for unitType in XMLEntriesList["units"][sTag] :
                        iUnitClass = gc.getUnitInfo(gc.getInfoTypeForString(unitType)).getUnitClassType()

                        if iUnitClass in classList : continue

                        classList.append(iUnitClass)

                        # choose the default unit , or the first in the list to represent the group
                        for unitTypeR in unitsPerClass[iUnitClass] :
                                if not unitTypeR in XMLEntriesList["units"][sTag] : continue
                                unitR = unitTypeR
                                break

                        if unitR in XMLEntriesList["units"]["peace"] : iGroup = 0
                        else : iGroup = 10

                        if unitR in XMLEntriesList["units"]["land"] : iGroup += 1
                        elif unitR in XMLEntriesList["units"]["water"] : iGroup += 2
                        elif unitR in XMLEntriesList["units"]["air"] : iGroup += 3
                        else : iGroup += 4

                        # after sort by power , sort by description , the first unit is almost every time the class description
                        sDescription = XMLDescriptions[unitR]

                        iPower = gc.getUnitInfo(gc.getInfoTypeForString(unitR)).getPowerValue()

                        elementList.append([iUnitClass, sDescription, iPower, iGroup])

                if len(elementList) > 1 :
                        elementList = sortList(elementList, 1)
                        elementList = sortList(elementList, 2)
                        elementList = sortList(elementList, 3)

                endListClass = [item[0] for item in elementList]
                tpList = []

                for iUnitClass in endListClass :
                        for unitType in unitsPerClass[iUnitClass] :
                                if unitType in XMLEntriesList["units"][sTag] : tpList.append(unitType)

                XMLEntriesList["units"][sTag] = [item for item in tpList]

        logList = []
        for iKey in XMLEntriesList.keys() :
                if type(XMLEntriesList[iKey]) is types.DictType :
                        logList.append("")
                        for iKey2 in XMLEntriesList[iKey].keys() :
                                logList.append(" %s , %s : %r" %(iKey, iKey2, XMLEntriesList[iKey][iKey2]))
                        logList.append("")
                else :
                                logList.append(" %s : %r" %(iKey, XMLEntriesList[iKey]))
        writeLog("sortXMLLists", True, logList)

def initMenuGlobals():
        global bScreen
        bScreen = True

        initVersions()

        createStoDir()

        initStoFolder()
        initDebugFiles()
        initMenuDebug()

        initLanguage()

def initPreGameGlobals():
        global gc

	gc = CyGlobalContext()

        initMOD()

        initXMLLists()

        initXMLDescriptions()

        sortXMLLists()

        initCanUseGameOptions()

def initStoFolder():
        global StoFolder

        StoFolder = StoFilePath()

def initMenuDebug():
        global debugFile
        debugFile = "MenuDbg.txt"

def initGenerationDebug():
        global debugFile
        debugFile = "MapGenerationDbg.txt"

def initLanguage():
        global language

        language = loadConfig("language")

        if language == -1 :
                language = CyGame().getCurrentLanguage()
                if not language in range(5) : language = 0
                saveConfig("language", language)

def initVersions():
        global BtS
        global Wrds
        global BorW

        BtS = False
        if (os.path.basename(os.getcwd()) == "Beyond the Sword") : BtS = True

        Wrds = False
        if (os.path.basename(os.getcwd()) == "Warlords") : Wrds = True
        
        BorW = False
        if BtS or Wrds : BorW = True

def Sto_FullOfResources_AddGameElements_Event_Begin(argsList):
        return

def Sto_FullOfResources_AddGameElements_Event_Apply(playerID, userData, popupReturn):
        StoAddGameElements()
        return initStoRemoveEvent()

def initStoAddEvent():
        # search for all event id
        listEventInteger = []
        for item in dir(CvUtil) :
                objTemp = getattr(CvUtil, item)
                if type(objTemp) is types.IntType : listEventInteger.append(int(objTemp))

        # all checks done , add the event
        popUpID = -1
        for i in range(5000, 10000) :
                if not i in listEventInteger :
                        popUpID = i
                        break

        setattr(CvUtil , "Sto_FullOfResources_AddGameElements_EventID", popUpID)
        CvUtil.SilentEvents.append(getattr(CvUtil, "Sto_FullOfResources_AddGameElements_EventID"))
        setattr(CvEventInterface.getEventManager(), "__Sto_FullOfResources_AddGameElements_Event_Begin", Sto_FullOfResources_AddGameElements_Event_Begin)
        setattr(CvEventInterface.getEventManager(), "__Sto_FullOfResources_AddGameElements_Event_Apply", Sto_FullOfResources_AddGameElements_Event_Apply)
        objEvents = getattr(CvEventInterface.getEventManager(), 'Events')
        objEvents[getattr(CvUtil, "Sto_FullOfResources_AddGameElements_EventID")] = "Sto_FullOfResources_AddGameElements_EventID", getattr(CvEventInterface.getEventManager(), "__Sto_FullOfResources_AddGameElements_Event_Apply"), getattr(CvEventInterface.getEventManager(), "__Sto_FullOfResources_AddGameElements_Event_Begin")

def initStoRemoveEvent():
        objEvents = getattr(CvEventInterface.getEventManager(), 'Events')
        del objEvents[getattr(CvUtil, "Sto_FullOfResources_AddGameElements_EventID")]
        delattr(CvEventInterface.getEventManager(), "__Sto_FullOfResources_AddGameElements_Event_Begin")
        delattr(CvEventInterface.getEventManager(), "__Sto_FullOfResources_AddGameElements_Event_Apply")
        CvUtil.SilentEvents.remove(getattr(CvUtil, "Sto_FullOfResources_AddGameElements_EventID"))
        delattr(CvUtil , "Sto_FullOfResources_AddGameElements_EventID")
        return 0

def initCanUseGameOptions():
        global canUseGameOptions

        ## check if the additionnal game options can be added at the beginning of the game
        canUseGameOptions = False

        # check if CvEventManager have Events .
        if not hasattr(CvEventInterface.getEventManager(), 'Events'):
                writeLog("", False, [" initCanUseGameOptions : CvEventManager don't have Events", ""])
                return

        objEvents = getattr(CvEventInterface.getEventManager(), 'Events')

        # check if Events is a dictionnary.
        if not type(objEvents) is types.DictType :
                writeLog("", False, [" initCanUseGameOptions : Events is not a dictionnary", ""])
                return

        # search for all event id
        listEventInteger = []
        for item in dir(CvUtil) :
                objTemp = getattr(CvUtil, item)
                if type(objTemp) is types.IntType : listEventInteger.append(int(objTemp))

        # search an ID for each event to add :
        popUpID=-1
        for i in range(5000, 10000):
                if not i in listEventInteger :
                        popUpID = i
                        break

        if popUpID == -1 :
                writeLog("", False, [" initCanUseGameOptions : No popup id available", ""])
                return

        # check if CvUtil have SilentEvents.
        if not "SilentEvents" in dir(CvUtil) :
                writeLog("", False, [" initCanUseGameOptions : CvUtil don t have SilentEvents", ""])
                return

        # check if SilentEvents is a list.
        if not type(CvUtil.SilentEvents) is types.ListType :
                writeLog("", False, [" initCanUseGameOptions : SilentEvents is not a list", ""])
                return

        canUseGameOptions = True

##!_!## debug set up
def initDebugFiles():
        global firstInitDebugFiles

        if firstInitDebugFiles :
                firstInitDebugFiles = False
                try :
                        Sfile = open(os.path.join(StoFolder,"MenuDbg.txt"),"w")
                        Sfile.write("__ MenuDbg : Full of resources, version %s __\n\n\n" %getVersion())
                        Sfile.close()
                        Sfile = open(os.path.join(StoFolder,"MapGenerationDbg.txt"),"w")
                        Sfile.write("__ MapGenerationDbg : Full of resources, version %s __\n\n\n" %getVersion())
                        Sfile.close()
                except :
                        print " FoR : initDebugFiles : ERROR"

def writeLog(sBegin, bEnd, listLines):
        if not bScreen :
                if not selGen["game"]["log"]["writelog"] :
                        return
        buffLines = []
        if sBegin != "" :
                sTp = "_ %s _" %sBegin
                buffLines = [sTp + "_"*max(40 - len(sTp), 1), ""]
        buffLines += listLines
        if bEnd :
                buffLines += ["", "_"*40, "", ""]

        try :
                sText = "\n".join(buffLines) + "\n"
                Sfile = open(os.path.join(StoFolder, debugFile), "a")
                Sfile.write(sText)
                Sfile.close()
        except :
                writeError()
                for sText in buffLines : sys.stdout.write(" Error writeLog : %s\n" %sText)

def writeError():
        try :
                Sfile = open(os.path.join(StoFolder, debugFile), "a")
                Sfile.write("\n" +"_ ERROR _".ljust(40,"_") + "\n")
                traceback.print_exc(None, Sfile)
                Sfile.write("_".ljust(40,"_") + "\n\n")
                Sfile.close()
        except :
                print " FoR : LoOl : Error writeError "

##!_!## Screen set up
def launchSetUpScreen():
        global selection
        global isNetMP
        global isGameMP
        global isPbemOrHseat
        global isBtSFFH
        global bCanWriteLog

        isNetMP = CyGame().isNetworkMultiPlayer()
        isGameMP = CyGame().isGameMultiPlayer()
        isPbemOrHseat = bool(CyGame().isPbem() or CyGame().isHotSeat())
        bCanWriteLog = bool(not CyGame().isPbem())

        logList = []
        logList.append(" isNetMP : %r" %isNetMP)
        logList.append(" isGameMP : %r" %isGameMP)
        logList.append(" isPbemOrHseat : %r" %isPbemOrHseat)
        logList.append(" bCanWriteLog : %r" %bCanWriteLog)
        logList.append(" active player : %d" %int(CyGame().getActivePlayer()))
        logList.append(" game turn : %d" %int(CyGame().getGameTurn()))

        # in case one of the map option is called during the game : check if the game is already initialized (not in the menu)
        if CyGame().isFinalInitialized() :
                logList.append(" the game is final initialized : don't launch the screen")
                writeLog("launchSetUpScreen", True, logList)
                return

        # only the hosting player edit the settings , and the custom map options are called when exiting the game in mp .
        if CyGame().getActivePlayer() != 0 :
                logList.append(" Active player != 0 : don't launch the screen")
                writeLog("launchSetUpScreen", True, logList)
                return

        # if the game is MP , prevent the screen to appear when you load a game
        if isGameMP :
                if not CyGame().getGameTurn() in [-1, 0] : #should not be equal to -1, just in case
                        logList.append(" MP game , game turn != 0 : don't launch the screen , loading a game")
                        writeLog("launchSetUpScreen", True, logList)
                        return

        initPreGameGlobals()

        initDefaultSelection()
        initValueLimits()

        logList.append(" running Warlords %r" %Wrds)
        logList.append(" running BtS %r" %BtS)
        logList.append(" canUseGameOptions %r" %canUseGameOptions)
        logList.append(" language %d" %language)

        # if there is no setting defined , initialize selection
        if selection == {} :
                selection = dict(loadSelection())
                sortMultiBox()
        else :
                selection = checkSettings(selection) #use if you change the game type (MP,SP) for the writelog option

        if not "optionsScreen" in dir(CvScreensInterface) :
                logList.append(" optionsScreen is not in CvScreensInterface : don't launch the screen")
                writeLog("launchSetUpScreen", True, logList)
                launchPopUP([["TXT_FAILED_POPUP_INIT", ""]])
                return

        # check if the screen can be launched :
        # 1 : check if the original file is not MODDED to prevent a non reversible change
        # 2 : check if the screen in place is not already a Sto screen ... ( in order to restore the option screen )
        # can happen if the user use the 'Esc' key instead of the exit button to exit the screen. So the user can launch the screen again instead of restart CivIV

        canLaunchScreen = False
        for instance in ["CvOptionsScreen.CvOptionsScreen ", ".CvStoFullOfResourcesScreen ", ".CvStoLoadFileScreen ", ".CvStoSaveFileScreen "] :
                if instance in repr(CvScreensInterface.optionsScreen) :
                        canLaunchScreen = True
                        break

        if not canLaunchScreen :
                logList.append(" optionsScreen not recognized : don't launch the screen")
                writeLog("launchSetUpScreen", True, logList)
                launchPopUP([["TXT_FAILED_POPUP_INIT", ""]])
                return
        
        if not "showOptionsScreen" in dir(CvScreensInterface) :
                logList.append(" showOptionsScreen is not in CvScreensInterface : don't launch the screen")
                writeLog("launchSetUpScreen", True, logList)
                launchPopUP([["TXT_FAILED_POPUP_INIT", ""]])
                return

        writeLog("launchSetUpScreen", False, logList)

        initScreenCallBack()

        writeLog("", False, [" callBacks Initialized ..."])
        
        CvScreensInterface.optionsScreen = CvStoFullOfResourcesScreen()
        CvScreensInterface.showOptionsScreen()

        writeLog("", True, [" screen showned ..."])

def loadSelection(fileName = "", bForce = True):
        selTp = {}
        if fileName != "" :
                if fileName in getListDirSto() :
                        try :
                                Sfile = open(os.path.join(StoFolder, fileName),"r")
                                selTpt = pickle.load(Sfile)
                                Sfile.close()
                                selTp = selTpt
                        except :
                                writeError()

        if selTp != {} : return checkSettings(selTp)

        if not bForce : return -1

        #First time you enter in the menu , try to read the last settings used ,for the version and the MOD you have played
        # (if the script recognize the MOD ) . Try to find the best file if you're running a new MOD or Version
        lastFileName = getLastFileUsedName(True)

        if lastFileName != "" :
                try :
                        Sfile = open(os.path.join(StoFolder, lastFileName),"r")
                        selTpt = pickle.load(Sfile)
                        Sfile.close()
                        selTp = selTpt
                except :
                        writeError()

        if selTp != {} : return checkSettings(selTp)

        # Can't find any setting saved , return the default settings
        return copy.deepcopy(defSel)

def saveSelection(fileName):
        try:
                Sfile = open(os.path.join(StoFolder,fileName),"w")
                pickle.dump(selection, Sfile)
                Sfile.close()
                return False
        except :
                writeError()
                return True
            
def loadConfig(idConfig):
        confTp = -1
        if "_userConfig.cfg" in getListDirSto() :
                try :
                        Sfile = open(os.path.join(StoFolder,"_userConfig.cfg"),"r")
                        loadDict = pickle.load(Sfile)
                        Sfile.close()
                        if idConfig in loadDict.keys() :
                                confTp = loadDict[idConfig]
                                writeLog("", False, [" loadConfig : read %s " %idConfig, ""])
                        else :
                                writeLog("", False, [" loadConfig : %s is not in _userConfig.cfg" %idConfig, ""])
                except :
                        writeError()
        else :
                writeLog("", False, [" loadConfig , %s : _userConfig.cfg is not in getListDirSto()" %idConfig, ""])

        return confTp

def saveConfig(idConfig, value):
        confDict = {}
        try :
                Sfile = open(os.path.join(StoFolder,"_userConfig.cfg"),"r")
                loadDict = pickle.load(Sfile)
                Sfile.close()
                confDict = loadDict
        except :
                writeError()

        confDict[idConfig] = value

        try:
                Sfile = open(os.path.join(StoFolder,"_userConfig.cfg"),"w")
                pickle.dump(confDict, Sfile)
                Sfile.close()
        except :
                writeError()

def getLastFileUsedName(bSearch=False):
        modN = ""
        if modName != "None" : modN = "%s_" %modName
        fileNameBtS = "_BtS_currentConfig.cfg"
        fileNameBtSMOD = "_BtS_%scurrentConfig.cfg" %modN
        fileNameWrds = "_Warlords_currentConfig.cfg"
        fileNameWrdsMOD = "_Warlords_%scurrentConfig.cfg" %modN
        fileNameVan = "_Vanilla_currentConfig.cfg"
        fileNameVanMOD = "_Vanilla_%scurrentConfig.cfg" %modN

        fileNameLast = "_LastConfig.cfg"

        if not bSearch :
                if BtS : return fileNameBtSMOD
                elif Wrds : return fileNameWrdsMOD
                else : return fileNameVanMOD

        listFiles = getListDirSto()

        if BtS :
                if fileNameBtSMOD in listFiles : return fileNameBtSMOD
                elif fileNameBtS in listFiles : return fileNameBtS
                elif fileNameLast in listFiles : return fileNameLast
        elif Wrds :
                if fileNameWrdsMOD in listFiles : return fileNameWrdsMOD
                elif fileNameWrds in listFiles : return fileNameWrds
                elif fileNameLast in listFiles : return fileNameLast
        else :
                if fileNameVanMOD in listFiles : return fileNameVanMOD
                elif fileNameVan in listFiles : return fileNameVan
                elif fileNameLast in listFiles : return fileNameLast
        return ""

def createStoDir():
        docFolder = civFilePath()

        if docFolder == "" :
                print " FoR : createStoDir : can t reach document folder"
                return

        if os.path.isdir(os.path.join(docFolder, "CivilizationIV Full of Resources")) :
                print " FoR : createStoDir : the folder already exist "
                return

        try :
                os.mkdir( os.path.join(docFolder, "CivilizationIV Full of Resources") )
                print " FoR : createStoDir : the folder should have been created "
        except :
                print " FoR : createStoDir : ERROR while creating the folder "
        
def regRead(registry, path, field):
        pathKey = _winreg.OpenKey(registry, path)
        try:
                fieldValue = _winreg.QueryValueEx(pathKey, field)
                return fieldValue[0]
        finally:
                pathKey.Close()

def civFilePath():
        if (sys.platform == 'darwin'):
                try:
                        userFolder = os.path.join(os.environ['HOME'], "Documents")
                        return userFolder
                except:
                        print " FoR : ERROR civFilePath()"
                        return ""
        else:
                try:
                        userFolder = regRead(_winreg.HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders","Personal")
                        finalFolder =  os.path.join(userFolder, "My Games")
                        return finalFolder
                except:
                        print " FoR : ERROR civFilePath()"
                        return ""

def StoFilePath():
        try:
                userFolder = civFilePath()
                if userFolder == "" :
                        print " FoR : StoFilePath : can t reach document folder "
                        return ""

                StoFol = os.path.join(userFolder, "CivilizationIV Full of Resources")
                return StoFol
        except:
                print " FoR : StoFilePath : ERROR trying to create folder string "
                return ""

def getListDirSto():
        try :
                if StoFolder == "" :
                        writeLog("", False, [" getListDirSto :  can't read StoFolder ", ""])
                        return []
                listDirSto = os.listdir(StoFolder)
                listDirSto = [getSText(item) for item in listDirSto]

                writeLog("", False, [" getListDirSto : %r" %listDirSto, ""])

                return listDirSto
        except :
                writeError()
                return []

def launchPopUP(argList):
        try :
                popup = PyPopup.PyPopup()
                popup.setHeaderString("")

                if len(argList)>1 :
                        resolution = [int(item) for item in CyUserProfile().getResolutionString(CyUserProfile().getResolution()).split("x") if item != "" ]
                        popup.setPosition(int(resolution[0]*0.05), int(resolution[1]*0.05))
                        popup.setSize(int(resolution[0]*0.90), int(resolution[1]*0.90))
                        textPopUp = ""
                        for [szTag, lList] in argList : textPopUp += getSMenuText(szTag, lList) +"\n"
                else :
                        szTag, lList = argList[0]
                        textPopUp = getSMenuText(szTag, lList) +"\n"

                popup.setBodyString(getUText(textPopUp))
                popup.launch()
        except :
                writeError()

# define default selection
def initDefaultSelection():
        global defSel
        defSel = {}

        # set the map settings
        defaultSelMaps = {}
        defaultSelMaps["archipelago"] = {
                "selected" : False ,
                "landmass" : [1] ,
                "waterper" : [78] ,
                "wrap" : [1] ,
                "start" : [0]
                }
        defaultSelMaps["continents"] = {
                "selected" : False ,
                "waterper" : [75] ,
                "wrap" : [1] ,
                "start" : [0,1]
                }
        defaultSelMaps["customcontinents"] = {
                "selected" : False ,
                "numbercontinents" : [0] ,
                "wrap" : [1] ,
                "start" : [0,1]
                }
        defaultSelMaps["fractals"] = {
                "selected" : False ,
                "waterper" : [78] ,
                "wrap" : [1] ,
                "start" : [0,1]
                }
        defaultSelMaps["hub"] = {
                "selected" : False ,
                "areaperplayer" : [0] ,
                "landshape" : [0,1,2] ,
                "neutralter" : [0,1,2,3] ,
                "isthmuswidth" : [1] ,
                "wrap" : [0] ,
                "start" : [0,1]
                }
        defaultSelMaps["inlandsea"] = {
                "selected" : False ,
                "wrap" : [0] ,
                "start" : [1]
                }
        defaultSelMaps["islands"] = {
                "selected" : False ,
                "largeislands" : [0] ,
                "tinyislands" : [2] ,
                "wrap" : [1] ,
                "start" : [0]
                }
        defaultSelMaps["lakes"] = {
                "selected" : False ,
                "waterper" : [9] ,
                "lakesize" : [0] ,
                "wrap" : [0]
                }
        defaultSelMaps["maze"] = {
                "selected" : False ,
                "mazewidth" : [2] ,
                "wrap" : [1] ,
                "start" : [0,1]
                }
        defaultSelMaps["pangaea"] = {
                "selected" : False ,
                "shoreline" : [0] ,
                "wrap" : [1] ,
                "start" : [0,1]
                }
        defaultSelMaps["ring"] = {
                "selected" : False ,
                "areaperplayer" : [0] ,
                "landshape" : [0,1,2] ,
                "neutralter" : [0,1,2,3] ,
                "isthmuswidth" : [1] ,
                "wrap" : [0] ,
                "start" : [0,1]
                }
        defaultSelMaps["shuffle"] = {
                "selected" : False ,
                "waterper" : [78] ,
                "wrap" : [1] ,
                "start" : [True,True]
                }
        defaultSelMaps["terra"] = {
                "selected" : False ,
                "wrap" : [1] ,
                "startterra" : [0,1,2]
                }
        defaultSelMaps["wheel"] = {
                "selected" : False ,
                "areaperplayer" : [0] ,
                "landshape" : [0,1,2] ,
                "ringwidth" : [1] ,
                "spokewidth" : [1] ,
                "wrap" : [0] ,
                "start" : [0,1]
                }
        defaultSelMaps["chess"] = {
                "selected" : False ,
                "waterper" : [25] ,
                "wrap" : [1] ,
                "start" : [0,1] ,
                "border" : [0]
                }
        if BtS :
                defaultSelMaps["bigandsmall"] = {
                        "selected" : False ,
                        "continentsize" : [1] ,
                        "islandsize" : [0] ,
                        "islandoverlap" : [0] ,
                        "wrap" : [1] ,
                        "start" : [0,1]
                        }
                defaultSelMaps["hemispheres"] = {
                        "selected" : False ,
                        "hemcontinentsize" : [1] ,
                        "islandsize" : [1] ,
                        "hemnumbercontinents" : [0] ,
                        "wrap" : [1] ,
                        "start" : [0,1]
                        }
                defaultSelMaps["mediumandsmall"] = {
                        "selected" : False ,
                        "mascontinentsize" : [4] ,
                        "islandsize" : [1] ,
                        "islandoverlap" : [0] ,
                        "wrap" : [1] ,
                        "start" : [0,1]
                        }

        defSel["maps"] = dict(defaultSelMaps)

        # set the terrain settings
        defaultSelTerrain = {}
        defaultSelTerrain["terrains"] = {
                "grass" : [1] ,
                "plains" : [1] ,
                "desert" : [3] ,
                "tundra" : [3] ,
                "snow" : [3]
                }
        defaultSelTerrain["forest"] = {
                "forestpercent" : [40]
                }
        defaultSelTerrain["jungle"] = {
                "junglepercent" : [80]
                }
        defaultSelTerrain["peak"] = {
                "peakpercent" : [5] ,
                "peakcoast" : False
                }
        defaultSelTerrain["hill"] = {
                "hillpercent" : [17]
                }
        defaultSelTerrain["river"] = {
                "riveredge" : [int(gc.getDefineINT("PLOTS_PER_RIVER_EDGE"))]
                }
        iOasis = gc.getInfoTypeForString("FEATURE_OASIS")
        if iOasis != -1 :
                defaultSelTerrain["oasis"] = {
                        "oasispercent" : [int( gc.getFeatureInfo(iOasis).getAppearanceProbability()/100.0 )]
                        }
        iIce = gc.getInfoTypeForString("FEATURE_ICE")
        if iIce != -1 :
                defaultSelTerrain["ice"] = {
                        "iceremove" : 0
                        }
        iGoodyHut = gc.getInfoTypeForString("IMPROVEMENT_GOODY_HUT")
        if iGoodyHut != -1 :
                goodyper = gc.getImprovementInfo(iGoodyHut).getTilesPerGoody()
                if goodyper > 0 :
                        defaultSelTerrain["goodyhut"] = {
                                "goodypercent" : [normalizeFloat(100.0/goodyper)]
                                }
        defaultSelTerrain["island"] = {
                "nbtilesminisland" : [1]
                }
        defSel["terrain"] = dict(defaultSelTerrain)
        
        # set the resources settings
        defaultSelResources = {}
        defaultSelResources["resourcesgen"]={
                "erasedefres" : False ,
                "landpercent" : "standard" ,
                "landprop" : [80, 100, 70] ,
                "waterpercent" : "standard" ,
                "waterprop" : [5, 80, 10] ,
                "standardgen" : [] ,
                "groupres" : copy.deepcopy(XMLEntriesList["groupreslist"]) ,
                "resspreadclimate" : True ,
                "resspreadlake" : False ,
                "resmultiply-0" : [ [], 1 ]
                }
        defaultSelResources["resourcesstart"]={
                "removestartres" : False ,
                "strategicnorandom" : [] ,
                "healthnorandom" : [] ,
                "happinessnorandom" : [] ,
                "startresselect-0" : [] ,
                "startresquantity-0" : [1] ,
                "startreslocation-0" : 0 ,
                "startresforce-0" : 0 ,
                "startresplayer-0" : [0, 1]
                }
        defSel["resources"] = dict(defaultSelResources)

        # set the start location settings
        defaultSelStart = {}
        defaultSelStart["normalize"] = {
                "startplot" : 0 ,
                "addriver" : 0 ,
                "removepeak" : 0 ,
                "addlake" : 0 ,
                "removebadfeature" : 0 ,
                "removebadterrain" : 0 ,
                "addfoodbonus" : 0 ,
                "addgoodterrain" : 0 ,
                "addextra" : 0 ,
                "startsametile" : 0
                }
        defaultSelStart["relocate"] = {
                "swaphuman" : True
                }
        defSel["startlocs"] = dict(defaultSelStart)

        # set the game settings
        defaultSelGame = {}
        defaultSelGame["log"] = {
                "writelog" : copy.copy(bCanWriteLog)
                }
        defaultSelGame["barbcities"] = {
                "cityper" : [0] ,
                "citybuilding" : [] ,
                "barbbarbrange" : [5] ,
                "barbhumrange" : [7] ,
                "defender" : [] ,
                "nbdefender" : [1] ,
                "xpdefender" : [10] ,
                "nbtilesminisland" : [5]
                }
        defaultSelGame["animals"] = {
                "animalspercent" : [0] ,
                "animalsnoplace" : [] ,
                "animunitrange" : [3] ,
                "xpanimals" : [0] ,
                "nbtilesminisland" : [5]
                }
        defaultSelGame["gold"] = {
                "gold" : [0] ,
                "goldplayers" : [0, 1]
                }
        defaultSelGame["reveal"] = {
                "startrange" : [0] ,
                "seareveal" : False ,
                "landreveal" : False ,
                "startlocs" : False
                }
        defaultSelGame["techno"] = {
                "starttechs" : 0 ,
                "technoreplace" : [] ,
                "technorandom" : [] ,
                "addtech-0" : [] ,
                "techquantity-0" : [1] ,
                "techplayers-0" : [0, 1]
                }
        defaultSelGame["startunit"] = {
                "startunitselect-0" : [] ,
                "startunittype-0" : 1 ,
                "startunitquantity-0" : [1] ,
                "startunitxp-0" : [0] ,
                "startunitplayers-0" : [0, 1]
                }
        defSel["game"] = dict(defaultSelGame)
        
## return the limit of the values that the user of the script can enter in the screen .
def initValueLimits():
        global valueLimits
        valueLimits ={}

        # set the map settings
        limitMaps = {}
        limitMaps["porder"] = 0
        limitMaps["archipelago"] = {
                "description" : "Archipelago" ,
                "porder" : 0 ,
                "landmass" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_ARCHI_LANDMASS" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "waterper" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : [60, 90] ,
                        "drawfunc"  : "ValueRandom" ,
                        "txttag"    : "TXT_MAPS_WATER_PERCENT" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "wrap" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "start" : {
                        "porder"    : 3 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["continents"] = {
                "description" : "Continents" ,
                "porder" : 1 ,
                "waterper" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [60, 82] ,
                        "drawfunc"  : "ValueRandom" ,
                        "txttag"    : "TXT_MAPS_WATER_PERCENT" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "wrap" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "start" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["customcontinents"] = {
                "description" : "Custom Continents" ,
                "porder" : 2 ,
                "numbercontinents" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : 7 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_CC_NB_CONTINENTS" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "wrap" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "start" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["fractals"] = {
                "description" : "Fractals" ,
                "porder" : 3 ,
                "waterper" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [60, 85] ,
                        "drawfunc"  : "ValueRandom" ,
                        "txttag"    : "TXT_MAPS_WATER_PERCENT" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "wrap" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "start" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["hub"] = {
                "description" : "Hub" ,
                "porder" : 4 ,
                "areaperplayer" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_AREAS_PER_PLAYER" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "landshape" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_LAND_SHAPE" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "neutralter" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 4 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_NEUTRAL_TERRITORY" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "isthmuswidth" : {
                        "porder"    : 3 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_ISTHMUS_WIDTH" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "wrap" : {
                        "porder"    : 4 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "start" : {
                        "porder"    : 5 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["inlandsea"] = {
                "description" : "Inland Sea" ,
                "porder" : 5 ,
                "wrap" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "start" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["islands"] = {
                "description" : "Islands" ,
                "porder" : 6 ,
                "largeislands" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_LARGE_ISLANDS" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "tinyislands" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 4 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_TINY_ISLANDS" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "wrap" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "start" : {
                        "porder"    : 3 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["lakes"] = {
                "description" : "Lakes" ,
                "porder" : 7 ,
                "waterper" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [5, 45] ,
                        "drawfunc"  : "ValueRandom" ,
                        "txttag"    : "TXT_MAPS_WATER_PERCENT" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "lakesize" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 4 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_LAKES_SIZE" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "wrap" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["maze"] = {
                "description" : "Maze" ,
                "porder" : 8 ,
                "mazewidth" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : 5 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_MAZE_WIDTH" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "wrap" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "start" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["pangaea"] = {
                "description" : "Pangaea" ,
                "porder" : 9 ,
                "shoreline" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : 4 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_SHORELINE" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "wrap" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "start" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["ring"] = {
                "description" : "Ring" ,
                "porder" : 10 ,
                "areaperplayer" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_AREAS_PER_PLAYER" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "landshape" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_LAND_SHAPE" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "neutralter" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 4 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_NEUTRAL_TERRITORY" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "isthmuswidth" : {
                        "porder"    : 3 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_ISTHMUS_WIDTH" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "wrap" : {
                        "porder"    : 4 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "start" : {
                        "porder"    : 5 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["shuffle"] = {
                "description" : "Shuffle" ,
                "porder" : 11 ,
                "waterper" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [60, 85] ,
                        "drawfunc"  : "ValueRandom" ,
                        "txttag"    : "TXT_MAPS_WATER_PERCENT" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "wrap" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "start" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["terra"] = {
                "description" : "Terra" ,
                "porder" : 12 ,
                "wrap" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "startterra" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START_TERRA" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["wheel"] = {
                "description" : "Wheel" ,
                "porder" : 13 ,
                "areaperplayer" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_AREAS_PER_PLAYER" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "landshape" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_LAND_SHAPE" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "ringwidth" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_RING_WIDTH" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "spokewidth" : {
                        "porder"    : 3 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_SPOKE_WIDTH" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "wrap" : {
                        "porder"    : 4 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "start" : {
                        "porder"    : 5 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitMaps["chess"] = {
                "description" : "Chess" ,
                "porder" : 14 ,
                "waterper" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [0, 50] ,
                        "drawfunc"  : "ValueRandom" ,
                        "txttag"    : "TXT_MAPS_WATER_PERCENT" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "wrap" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_WRAP" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "start" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_START" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "border" : {
                        "porder"    : 3 ,
                        "parent"    : "" ,
                        "limit"     : 4 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_MAPS_CHESS_BORDER" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        if BtS :
                limitMaps["bigandsmall"] = {
                        "description" : "Big and Small" ,
                        "porder" : 15 ,
                        "continentsize" : {
                                "porder"    : 0 ,
                                "parent"    : "" ,
                                "limit"     : 3 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_CONTINENTS_SIZE" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                } ,
                        "islandsize" : {
                                "porder"    : 1 ,
                                "parent"    : "" ,
                                "limit"     : 2 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_ISLANDS_SIZE" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                } ,
                        "islandoverlap" : {
                                "porder"    : 2 ,
                                "parent"    : "" ,
                                "limit"     : 2 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_ISLAND_OVERLAP" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                } ,
                        "wrap" : {
                                "porder"    : 3 ,
                                "parent"    : "" ,
                                "limit"     : 3 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_WRAP" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                } ,
                        "start" : {
                                "porder"    : 4 ,
                                "parent"    : "" ,
                                "limit"     : 2 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_START" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                }
                        }
                limitMaps["hemispheres"] = {
                        "description" : "Hemispheres" ,
                        "porder" : 16 ,
                        "hemcontinentsize" : {
                                "porder"    : 0 ,
                                "parent"    : "" ,
                                "limit"     : 4 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_HEM_CONTINENTS_SIZE" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                } ,
                        "islandsize" : {
                                "porder"    : 1 ,
                                "parent"    : "" ,
                                "limit"     : 2 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_ISLANDS_SIZE" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                } ,
                        "hemnumbercontinents" : {
                                "porder"    : 2 ,
                                "parent"    : "" ,
                                "limit"     : 5 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_HEM_NB_CONTINENTS" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                } ,
                        "wrap" : {
                                "porder"    : 3 ,
                                "parent"    : "" ,
                                "limit"     : 3 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_WRAP" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                } ,
                        "start" : {
                                "porder"    : 4 ,
                                "parent"    : "" ,
                                "limit"     : 2 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_START" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                }
                        }
                limitMaps["mediumandsmall"] = {
                        "description" : "Medium and Small" ,
                        "porder" : 17 ,
                        "mascontinentsize" : {
                                "porder"    : 0 ,
                                "parent"    : "" ,
                                "limit"     : 5 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_MAS_CONTINENTS_SIZE" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                } ,
                        "islandsize" : {
                                "porder"    : 1 ,
                                "parent"    : "" ,
                                "limit"     : 2 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_ISLANDS_SIZE" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                } ,
                        "islandoverlap" : {
                                "porder"    : 2 ,
                                "parent"    : "" ,
                                "limit"     : 2 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_ISLAND_OVERLAP" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                } ,
                        "wrap" : {
                                "porder"    : 3 ,
                                "parent"    : "" ,
                                "limit"     : 3 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_WRAP" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                } ,
                        "start" : {
                                "porder"    : 4 ,
                                "parent"    : "" ,
                                "limit"     : 2 ,
                                "drawfunc"  : "Selection" ,
                                "txttag"    : "TXT_MAPS_START" ,
                                "cbfunc"    : "Sto_Selection_MultiCB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                }
                        }
        valueLimits["maps"] = dict(limitMaps)

        # set the terrain settings
        limitTerrain = {}
        limitTerrain["porder"] = 1
        limitTerrain["terrains"] = {
                "description" : getSMenuText("TXT_TERRAIN_DES") ,
                "porder" : 0 ,
                "grass" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : 4 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_TERRAIN_GRASS" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "plains" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 4 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_TERRAIN_PLAIN" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "desert" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : 5 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_TERRAIN_DESERT" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "tundra" : {
                        "porder"    : 3 ,
                        "parent"    : "" ,
                        "limit"     : 5 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_TERRAIN_TUNDRA" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "snow" : {
                        "porder"    : 4 ,
                        "parent"    : "" ,
                        "limit"     : 5 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_TERRAIN_SNOW" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitTerrain["forest"] = {
                "description" : getSMenuText("TXT_TERRAIN_FOREST") ,
                "porder" : 1 ,
                "forestpercent" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [0,100] ,
                        "drawfunc"  : "ValueRandom" ,
                        "txttag"    : "TXT_TERRAIN_FOREST_PERCENT" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitTerrain["jungle"] = {
                "description" : getSMenuText("TXT_TERRAIN_JUNGLE") ,
                "porder" : 2 ,
                "junglepercent" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [0,100] ,
                        "drawfunc"  : "ValueRandom" ,
                        "txttag"    : "TXT_TERRAIN_JUNGLE_PERCENT" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : ["TXT_TERRAIN_TIP_JUNGLE", (copy.deepcopy(defSel["terrain"]["jungle"]["junglepercent"][0]),)] ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitTerrain["peak"] = {
                "description" : getSMenuText("TXT_TERRAIN_PEAK") ,
                "porder" : 3 ,
                "peakpercent" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [0,15] ,
                        "drawfunc"  : "ValueRandomFloat" ,
                        "txttag"    : "TXT_TERRAIN_PEAK_PERCENT" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "peakcoast" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectOne" ,
                        "txttag"    : "TXT_TERRAIN_PEAKCOAST" ,
                        "cbfunc"    : "Sto_Selection_OneCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitTerrain["hill"] = {
                "description" : getSMenuText("TXT_TERRAIN_HILL") ,
                "porder" : 4 ,
                "hillpercent" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [5,50] ,
                        "drawfunc"  : "ValueRandom" ,
                        "txttag"    : "TXT_TERRAIN_HILL_PERCENT" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitTerrain["river"] = {
                "description" : getSMenuText("TXT_TERRAIN_RIVER") ,
                "porder" : 5 ,
                "riveredge" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [1, int(gc.getDefineINT("PLOTS_PER_RIVER_EDGE"))+4] ,
                        "drawfunc"  : "ValueRandom" ,
                        "txttag"    : "TXT_TERRAIN_RIVEREDGE" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : ["TXT_TERRAIN_TIP_RIVEREDGE", (copy.deepcopy(defSel["terrain"]["river"]["riveredge"][0]),)] ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        iOasis = gc.getInfoTypeForString("FEATURE_OASIS")
        if iOasis != -1 :
                limitTerrain["oasis"] = {
                        "description" : getSMenuText("TXT_TERRAIN_OASIS") ,
                        "porder" : 6 ,
                        "oasispercent" : {
                                "porder"    : 0 ,
                                "parent"    : "" ,
                                "limit"     : [0,50] ,
                                "drawfunc"  : "ValueRandom" ,
                                "txttag"    : "TXT_TERRAIN_OASIS_PERCENT" ,
                                "cbfunc"    : "Sto_Value_Random" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                }
                        }
        iIce = gc.getInfoTypeForString("FEATURE_ICE")
        if iIce != -1 :
                limitTerrain["ice"] = {
                        "description" : getSMenuText("TXT_TERRAIN_ICE") ,
                        "porder" : 7 ,
                        "iceremove" : {
                                "porder"    : 0 ,
                                "parent"    : "" ,
                                "limit"     : 3 ,
                                "drawfunc"  : "SelectionRB" ,
                                "txttag"    : "TXT_TERRAIN_ICE" ,
                                "cbfunc"    : "Sto_Selection_MultiRB" ,
                                "tooltip"   : "" ,
                                "listitem"  : None ,
                                "listcomp"  : None ,
                                "nbperline" : None
                                }
                        }
        iGoodyHut = gc.getInfoTypeForString("IMPROVEMENT_GOODY_HUT")
        if iGoodyHut != -1 :
                goodyper = gc.getImprovementInfo(iGoodyHut).getTilesPerGoody()
                if goodyper > 0 :
                        limitTerrain["goodyhut"] = {
                                "description" : getSMenuText("TXT_TERRAIN_GOODY_HUT") ,
                                "porder" : 8 ,
                                "goodypercent" : {
                                        "porder"    : 0 ,
                                        "parent"    : "" ,
                                        "limit"     : [0,20] ,
                                        "drawfunc"  : "ValueRandomFloat" ,
                                        "txttag"    : "TXT_TERRAIN_GOODY_PERCENT" ,
                                        "cbfunc"    : "Sto_Value_Random" ,
                                        "tooltip"   : "" ,
                                        "listitem"  : None ,
                                        "listcomp"  : None ,
                                        "nbperline" : None
                                        }
                                }
        limitTerrain["island"] = {
                "description" : getSMenuText("TXT_TERRAIN_ISLAND") ,
                "porder" : 9 ,
                "nbtilesminisland" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [1,7] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_TERRAIN_NBTILESMIN" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : ["TXT_TERRAIN_TIP_NBTILESMIN", ""] ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        valueLimits["terrain"] = dict(limitTerrain)

        # set the resources settings
        limitResources = {}
        limitResources["porder"] = 2
        limitResources["resourcesgen"]={
                "description" : getSMenuText("TXT_RESOURCES_RESGEN") ,
                "porder" : 0 ,
                "erasedefres" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectOne" ,
                        "txttag"    : "TXT_RESOURCES_ERASE_DEF_RES" ,
                        "cbfunc"    : "Sto_Selection_OneCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "landpercent" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : [5,50] ,
                        "drawfunc"  : "StandardValueRandom" ,
                        "txttag"    : "TXT_RESOURCES_LANDPERCENT" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "landprop" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : [[0, 100], [0, 100], [0, 100]] ,
                        "drawfunc"  : "MultiValues" ,
                        "txttag"    : "TXT_RESOURCES_LANDPROP" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "waterpercent" : {
                        "porder"    : 3 ,
                        "parent"    : "" ,
                        "limit"     : [5,50] ,
                        "drawfunc"  : "StandardValueRandom" ,
                        "txttag"    : "TXT_RESOURCES_WATPERCENT" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "waterprop" : {
                        "porder"    : 4 ,
                        "parent"    : "" ,
                        "limit"     : [[0, 100], [0, 100], [0, 100]] ,
                        "drawfunc"  : "MultiValues" ,
                        "txttag"    : "TXT_RESOURCES_WATERPROP" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "standardgen" : {
                        "porder"    : 5 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "standardgen" ,
                        "txttag"    : "TXT_RESOURCES_STANDARDFOR" ,
                        "cbfunc"    : "Sto_Selection_Special" ,
                        "tooltip"   : "" ,
                        "listitem"  : copy.deepcopy(XMLEntriesList["reslist"]) ,
                        "listcomp"  : None ,
                        "nbperline" : 6
                        } ,
                "groupres" : {
                        "porder"    : 6 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "standardgen" ,
                        "txttag"    : "TXT_RESOURCES_GROUPRES" ,
                        "cbfunc"    : "Sto_Selection_Special" ,
                        "tooltip"   : "" ,
                        "listitem"  : copy.deepcopy(XMLEntriesList["reslist"]) ,
                        "listcomp"  : None ,
                        "nbperline" : 6
                        } ,
                "resspreadclimate" : {
                        "porder"    : 7 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectOne" ,
                        "txttag"    : "TXT_RESOURCES_SPREAD_CLIMATE" ,
                        "cbfunc"    : "Sto_Selection_OneCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "resspreadlake" : {
                        "porder"    : 8 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectOne" ,
                        "txttag"    : "TXT_RESOURCES_SPREAD_LAKES" ,
                        "cbfunc"    : "Sto_Selection_OneCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "resmultiply" : {
                        "porder"    : 9 ,
                        "parent"    : "" ,
                        "limit"     : [1,20] ,
                        "drawfunc"  : "resmultiply" ,
                        "txttag"    : "TXT_RESOURCES_RESMULTIPLY" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : copy.deepcopy(XMLEntriesList["reslist"]) + ["allstrat", "allhealth", "allhapp"] ,
                        "nbperline" : None
                        }
                }
        limitResources["resourcesstart"]={
                "description" : getSMenuText("TXT_RESOURCES_RESSTART") ,
                "porder" : 1 ,
                "removestartres" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectOne" ,
                        "txttag"    : "TXT_RESOURCES_START_REMOVE" ,
                        "cbfunc"    : "Sto_Selection_OneCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "strategicnorandom" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectionSpecial" ,
                        "txttag"    : "TXT_RESOURCES_STRAT_NORANDOM" ,
                        "cbfunc"    : "Sto_Selection_Special" ,
                        "tooltip"   : "" ,
                        "listitem"  : copy.deepcopy(XMLEntriesList["strategic"]) ,
                        "listcomp"  : None ,
                        "nbperline" : 6
                        } ,
                "healthnorandom" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectionSpecial" ,
                        "txttag"    : "TXT_RESOURCES_HEALTH_NORANDOM" ,
                        "cbfunc"    : "Sto_Selection_Special" ,
                        "tooltip"   : "" ,
                        "listitem"  : copy.deepcopy(XMLEntriesList["health"]) ,
                        "listcomp"  : None ,
                        "nbperline" : 6
                        } ,
                "happinessnorandom" : {
                        "porder"    : 3 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectionSpecial" ,
                        "txttag"    : "TXT_RESOURCES_HAPPINESS_NORANDOM" ,
                        "cbfunc"    : "Sto_Selection_Special" ,
                        "tooltip"   : "" ,
                        "listitem"  : copy.deepcopy(XMLEntriesList["happiness"]) ,
                        "listcomp"  : None ,
                        "nbperline" : 6
                        } ,
                "startresselect" : {
                        "porder"    : 4 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "startresselect" ,
                        "txttag"    : "TXT_RESOURCES_START_RES" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : copy.deepcopy(XMLEntriesList["reslist"]) + ["allstratsame", "allstratdiff", "allhealthsame", "allhealthdiff", "allhappsame", "allhappdiff"] ,
                        "nbperline" : None
                        } ,
                "startresquantity" : {
                        "porder"    : 1 ,
                        "parent"    : "startresselect" ,
                        "limit"     : [1,25] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_QUANTITY" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "startreslocation" : {
                        "porder"    : 2 ,
                        "parent"    : "startresselect" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_RESOURCES_START_LOCATION" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "startresforce" : {
                        "porder"    : 3 ,
                        "parent"    : "startresselect" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_RESOURCES_START_FORCE" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "startresplayer" : {
                        "porder"    : 4 ,
                        "parent"    : "startresselect" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_PLAYER_APPLY" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        valueLimits["resources"] = dict(limitResources)

        # set the start location settings
        limitStart = {}
        limitStart["porder"] = 3
        limitStart["normalize"] = {
                "description" : getSMenuText("TXT_STARTLOCS_NORMALIZE") ,
                "porder" : 0 ,
                "startplot" : {
                        "porder"    : 0 ,
                        "parent"    : None ,
                        "limit"     : 3 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_STARTLOCS_NORM_START" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "addriver" : {
                        "porder"    : 1 ,
                        "parent"    : None ,
                        "limit"     : 3 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_STARTLOCS_NORM_RIVER" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "removepeak" : {
                        "porder"    : 2 ,
                        "parent"    : None ,
                        "limit"     : 3 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_STARTLOCS_NORM_PEAK" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "addlake" : {
                        "porder"    : 3 ,
                        "parent"    : None ,
                        "limit"     : 3 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_STARTLOCS_NORM_LAKE" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "removebadfeature" : {
                        "porder"    : 4 ,
                        "parent"    : None ,
                        "limit"     : 3 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_STARTLOCS_NORM_BADFEAT" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "removebadterrain" : {
                        "porder"    : 5 ,
                        "parent"    : None ,
                        "limit"     : 3 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_STARTLOCS_NORM_BADTER" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "addfoodbonus" : {
                        "porder"    : 6 ,
                        "parent"    : None ,
                        "limit"     : 3 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_STARTLOCS_NORM_FOODBONUS" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "addgoodterrain" : {
                        "porder"    : 7 ,
                        "parent"    : None ,
                        "limit"     : 3 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_STARTLOCS_NORM_GOODTER" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "addextra" : {
                        "porder"    : 8 ,
                        "parent"    : None ,
                        "limit"     : 3 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_STARTLOCS_NORM_EXTRA" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "startsametile" : {
                        "porder"    : 9 ,
                        "parent"    : None ,
                        "limit"     : 3 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_STARTLOCS_NORM_SAMETILE" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitStart["relocate"] = {
                "description" : getSMenuText("TXT_STARTLOCS_RELOCATE") ,
                "porder" : 1 ,
                "swaphuman" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectOne" ,
                        "txttag"    : "TXT_STARTLOCS_SWAPHUMANS" ,
                        "cbfunc"    : "Sto_Selection_OneCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        valueLimits["startlocs"] = dict(limitStart)

        limitGame = {}
        limitGame["porder"] = 4
        limitGame["log"] = {
                "description" : getSMenuText("TXT_GAME_LOG_FILE") ,
                "porder" : 0 ,
                "writelog" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectOne" ,
                        "txttag"    : "TXT_GAME_LOG_WRITE" ,
                        "cbfunc"    : "Sto_Selection_OneCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitGame["barbcities"] = {
                "description" : getSMenuText("TXT_GAME_BARB_CITIES") ,
                "porder" : 1 ,
                "cityper" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [0, 100] ,
                        "drawfunc"  : "ValueRandom" ,
                        "txttag"    : "TXT_GAME_BARB_CITYPER" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "citybuilding" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectionSpecial" ,
                        "txttag"    : "TXT_GAME_CITYBUILD" ,
                        "cbfunc"    : "Sto_Selection_Special" ,
                        "tooltip"   : "" ,
                        "listitem"  : copy.deepcopy(XMLEntriesList["buildingsbarb"]) ,
                        "listcomp"  : None ,
                        "nbperline" : 6
                        } ,
                "barbbarbrange" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : [5, 30] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_GAME_BARBAR_RANGE" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "barbhumrange" : {
                        "porder"    : 3 ,
                        "parent"    : "" ,
                        "limit"     : [5, 30] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_GAME_BARHUM_RANGE" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "defender" : {
                        "porder"    : 4 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "defender" ,
                        "txttag"    : "TXT_GAME_BAR_DEFENDER" ,
                        "cbfunc"    : "Sto_Defender" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : copy.deepcopy(XMLEntriesList["units"]["barbdefender"]) + copy.deepcopy(XMLEntriesList["units"]["barbfight"]) ,
                        "nbperline" : None
                        } ,
                "nbdefender" : {
                        "porder"    : 5 ,
                        "parent"    : "" ,
                        "limit"     : [0, 20] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_QUANTITY" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "xpdefender" : {
                        "porder"    : 6 ,
                        "parent"    : "" ,
                        "limit"     : [0, 1000] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_GAME_XP" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "nbtilesminisland" : {
                        "porder"    : 7 ,
                        "parent"    : "" ,
                        "limit"     : [1,15] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_TERRAIN_NBTILESMIN" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitGame["animals"] = {
                "description" : getSMenuText("TXT_GAME_ANIMALS") ,
                "porder" : 2 ,
                "animalspercent" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [0, 40] ,
                        "drawfunc"  : "ValueRandom" ,
                        "txttag"    : "TXT_GAME_ANIMPER" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "animalsnoplace" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectionSpecial" ,
                        "txttag"    : "TXT_GAME_ANIMNOTPLACED" ,
                        "cbfunc"    : "Sto_Selection_Special" ,
                        "tooltip"   : "" ,
                        "listitem"  : copy.deepcopy(XMLEntriesList["units"]["animland"]) ,
                        "listcomp"  : None ,
                        "nbperline" : 6
                        } ,
                "animunitrange" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : [2, 15] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_GAME_ANIMUNIT_RANGE" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "xpanimals" : {
                        "porder"    : 3 ,
                        "parent"    : "" ,
                        "limit"     : [0, 1000] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_GAME_XP" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "nbtilesminisland" : {
                        "porder"    : 4 ,
                        "parent"    : "" ,
                        "limit"     : [1,15] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_TERRAIN_NBTILESMIN" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitGame["gold"] = {
                "description" : getSMenuText("TXT_GAME_GOLD") ,
                "porder" : 3 ,
                "gold" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [0, 10000] ,
                        "drawfunc"  : "ValueRandom" ,
                        "txttag"    : "TXT_GAME_GOLD" ,
                        "cbfunc"    : "Sto_Value_Random" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "goldplayers" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_PLAYER_APPLY" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitGame["reveal"] = {
                "description" : getSMenuText("TXT_GAME_REVEAL") ,
                "porder" : 4 ,
                "startrange" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : [0, 50] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_GAME_REVEAL_STARTRANGE" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "seareveal" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectOne" ,
                        "txttag"    : "TXT_GAME_SEAREVEAL" ,
                        "cbfunc"    : "Sto_Selection_OneCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "landreveal" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectOne" ,
                        "txttag"    : "TXT_GAME_LANDREVEAL" ,
                        "cbfunc"    : "Sto_Selection_OneCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "startlocs" : {
                        "porder"    : 3 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectOne" ,
                        "txttag"    : "TXT_GAME_STARTREVEAL" ,
                        "cbfunc"    : "Sto_Selection_OneCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitGame["techno"] = {
                "description" : getSMenuText("TXT_GAME_TECHNOS") ,
                "porder" : 5 ,
                "starttechs" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_GAME_STARTTECH" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "technoreplace" : {
                        "porder"    : 1 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectionSpecial" ,
                        "txttag"    : "TXT_GAME_TECH_NOREPLACE" ,
                        "cbfunc"    : "Sto_Selection_Special" ,
                        "tooltip"   : "" ,
                        "listitem"  : copy.deepcopy(XMLEntriesList["techsstartciv"]) ,
                        "listcomp"  : None ,
                        "nbperline" : 6
                        } ,
                "technorandom" : {
                        "porder"    : 2 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "SelectionSpecial" ,
                        "txttag"    : "TXT_GAME_TECH_NORANDOM" ,
                        "cbfunc"    : "Sto_Selection_Special" ,
                        "tooltip"   : "" ,
                        "listitem"  : copy.deepcopy(XMLEntriesList["techslist"]) ,
                        "listcomp"  : None ,
                        "nbperline" : 6
                        } ,
                "addtech" : {
                        "porder"    : 3 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "addtech" ,
                        "txttag"    : "TXT_GAME_ADDTECH" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : copy.deepcopy(XMLEntriesList["techslist"]) + ["alltechsame", "alltechdiff"] ,
                        "nbperline" : None
                        } ,
                "techquantity" : {
                        "porder"    : 1 ,
                        "parent"    : "addtech" ,
                        "limit"     : [1, 15] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_QUANTITY" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "techplayers" : {
                        "porder"    : 2 ,
                        "parent"    : "addtech" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_PLAYER_APPLY" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        limitGame["startunit"] = {
                "description" : getSMenuText("TXT_GAME_UNITS") ,
                "porder" : 6 ,
                "startunitselect" : {
                        "porder"    : 0 ,
                        "parent"    : "" ,
                        "limit"     : None ,
                        "drawfunc"  : "startunitselect" ,
                        "txttag"    : "TXT_GAME_ADDUNIT" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : copy.deepcopy(XMLEntriesList["units"]["list"]) ,
                        "nbperline" : None
                        } ,
                "startunittype" : {
                        "porder"    : 1 ,
                        "parent"    : "startunitselect" ,
                        "limit"     : 3 ,
                        "drawfunc"  : "SelectionRB" ,
                        "txttag"    : "TXT_GAME_UNIT_TYPE" ,
                        "cbfunc"    : "Sto_Selection_MultiRB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "startunitquantity" : {
                        "porder"    : 2 ,
                        "parent"    : "startunitselect" ,
                        "limit"     : [1, 30] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_QUANTITY" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "startunitxp" : {
                        "porder"    : 3 ,
                        "parent"    : "startunitselect" ,
                        "limit"     : [0, 1000] ,
                        "drawfunc"  : "Value" ,
                        "txttag"    : "TXT_GAME_XP" ,
                        "cbfunc"    : "Sto_DummyCallback" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        } ,
                "startunitplayers" : {
                        "porder"    : 4 ,
                        "parent"    : "startunitselect" ,
                        "limit"     : 2 ,
                        "drawfunc"  : "Selection" ,
                        "txttag"    : "TXT_PLAYER_APPLY" ,
                        "cbfunc"    : "Sto_Selection_MultiCB" ,
                        "tooltip"   : "" ,
                        "listitem"  : None ,
                        "listcomp"  : None ,
                        "nbperline" : None
                        }
                }
        valueLimits["game"] = dict(limitGame)

# check that all entries are used in the current version and add/remove settings if running a version with different options .
def checkSettings(settingsEntry):

        settings = copy.deepcopy(settingsEntry)

        for sBase in settings.keys() :
                if not sBase in defSel.keys() :
                        del(settings[sBase])
                        continue
                for sOption1 in settings[sBase].keys() :
                        if not sOption1 in defSel[sBase].keys() :
                                del(settings[sBase][sOption1])
                                continue
                        for sOption2 in settings[sBase][sOption1].keys() :
                                if sOption2 == "selected" : continue
                                #remove settings that should not be present in the dict
                                if "-" in sOption2 :
                                        baseTag, iIndex = splitTag(sOption2)
                                        if not "%s-0" %baseTag in defSel[sBase][sOption1].keys() :
                                                del(settings[sBase][sOption1][sOption2])
                                                continue
                                else :
                                        if not sOption2 in defSel[sBase][sOption1].keys() :
                                                del(settings[sBase][sOption1][sOption2])
                                                continue
                                        baseTag = str(sOption2)
                                        iIndex = -1
                                #check the log option if it's still valid .
                                if baseTag == "writelog" :
                                        if (settings[sBase][sOption1][baseTag]) and (not bCanWriteLog) :
                                                settings[sBase][sOption1][baseTag] = False
                                        elif (not settings[sBase][sOption1][baseTag]) and (not isGameMP) :
                                                settings[sBase][sOption1][baseTag] = True

                                #check entries type and limits
                                drawFunction = valueLimits[sBase][sOption1][baseTag]["drawfunc"]
                                val = copy.deepcopy(settings[sBase][sOption1][sOption2])
                                valLim = copy.deepcopy(valueLimits[sBase][sOption1][baseTag]["limit"])
                                bValid = True

                                if drawFunction == "Selection" :
                                        if not type(val) is types.ListType :
                                                bValid = False
                                        else :
                                                for item in val :
                                                        if not item in range(valLim):
                                                                settings[sBase][sOption1][sOption2].remove(item)
                                                if settings[sBase][sOption1][sOption2] == [] :
                                                        bValid = False
                                elif drawFunction == "ValueRandom" :
                                        if not type(val) is types.ListType :
                                                bValid = False
                                        elif (len(val) == 0) or (len(val) > 2) :
                                                bValid = False
                                        else :
                                                for item in val :
                                                        if not type(item) is types.IntType :
                                                                bValid = False
                                        if bValid :
                                                if len(val) == 2 :
                                                        if val[0] >= val[1] :
                                                                bValid = False
                                                minVal, maxVal = valLim
                                                for item in val :
                                                        if minVal > item :
                                                                bValid = False
                                                        if maxVal < item :
                                                                bValid = False
                                elif drawFunction == "ValueRandomFloat" :
                                        if not type(val) is types.ListType :
                                                bValid = False
                                        elif (len(val) == 0) or (len(val) > 2) :
                                                bValid = False
                                        else :
                                                for item in val :
                                                        if not ((type(item) is types.IntType) or (type(item) is types.FloatType)):
                                                                bValid = False
                                        if bValid :
                                                if len(val) == 2 :
                                                        if val[0] >= val[1] :
                                                                bValid = False
                                                minVal, maxVal = valLim
                                                for item in val :
                                                        if minVal > item :
                                                                bValid = False
                                                        if maxVal < item :
                                                                bValid = False
                                elif drawFunction == "SelectOne" :
                                        if not type(val) is types.BooleanType :
                                                bValid = False
                                elif drawFunction == "SelectionRB" :
                                        if not type(val) is types.IntType :
                                                bValid = False
                                        elif not ((val >= 0) and (val < valLim)) :
                                                bValid = False
                                elif drawFunction == "Value" :
                                        if not type(val) is types.ListType :
                                                bValid = False
                                        elif len(val) != 1 :
                                                bValid = False
                                        elif not type(val[0]) is types.IntType :
                                                bValid = False
                                        else :
                                                minVal, maxVal = valLim
                                                if minVal > val[0] :
                                                        bValid = False
                                                if maxVal < val[0] :
                                                        bValid = False
                                elif drawFunction == "StandardValueRandom" :
                                        if val != "standard" :
                                                if not type(val) is types.ListType :
                                                        bValid = False
                                                elif (len(val) == 0) or (len(val) > 2) :
                                                        bValid = False
                                                else :
                                                        for item in val :
                                                                if not type(item) is types.IntType :
                                                                        bValid = False
                                                if bValid :
                                                        if len(val) == 2 :
                                                                if val[0] >= val[1] :
                                                                        bValid = False
                                                        minVal, maxVal = valLim
                                                        for item in val :
                                                                if minVal > item :
                                                                        bValid = False
                                                                if maxVal < item :
                                                                        bValid = False
                                elif drawFunction == "MultiValues" :
                                        if not type(val) is types.ListType :
                                                bValid = False
                                        elif len(val) != len(valLim) :
                                                bValid = False
                                        else :
                                                for item in val :
                                                        if not type(item) is types.IntType :
                                                                bValid = False
                                        if bValid :
                                                for i in range(len(valLim)) :
                                                        minVal, maxVal = valLim[i]
                                                        if minVal > val[i] :
                                                                bValid = False
                                                        if maxVal < val[i] :
                                                                bValid = False
                                elif drawFunction in ["standardgen", "SelectionSpecial"] :
                                        if not type(val) is types.ListType :
                                                bValid = False
                                        else :
                                                for item in val :
                                                        if not item in valueLimits[sBase][sOption1][baseTag]["listitem"]:
                                                                settings[sBase][sOption1][sOption2].remove(item)
                                elif drawFunction in ["startresselect", "defender", "addtech", "startunitselect"] :
                                        if type(val) is types.StringType :
                                                if not val in valueLimits[sBase][sOption1][baseTag]["listcomp"] :
                                                        bValid = False
                                        elif type(val) is types.ListType :
                                                if len(val) == 0 :
                                                        pass
                                                elif len(val) != 1 :
                                                        bValid = False
                                                elif not val[0] in valueLimits[sBase][sOption1][baseTag]["listcomp"] :
                                                        settings[sBase][sOption1][sOption2] = []
                                        else :
                                                bValid = False
                                elif drawFunction == "resmultiply" :
                                        if not type(val) is types.ListType :
                                                bValid = False
                                        elif len(val) != 2 :
                                                bValid = False
                                        else :
                                                if type(val[0]) is types.StringType :
                                                        if not val[0] in valueLimits[sBase][sOption1][baseTag]["listcomp"] :
                                                                bValid = False
                                                elif type(val[0]) is types.ListType :
                                                        if len(val[0]) == 0 :
                                                                pass
                                                        elif len(val[0]) != 1 :
                                                                bValid = False
                                                        elif not val[0][0] in valueLimits[sBase][sOption1][baseTag]["listcomp"] :
                                                                settings[sBase][sOption1][sOption2][0] = []
                                                else :
                                                        bValid = False

                                                minVal, maxVal = valLim
                                                if not ((type(val[1]) is types.IntType) or (type(val[1]) is types.FloatType)):
                                                        bValid = False
                                                elif minVal > val[1] :
                                                        bValid = False
                                                elif maxVal < val[1] :
                                                        bValid = False
                                else :
                                        #oups! where's my mind ?
                                        #you can ask yourself if someone that listen the pixies CAN listen the miss (dubitative)
                                        writeLog("", False, [" %s, %s, %s, %s function not recognized in check settings" %(sBase, sOption1, sOption2, drawFunction), ""])

                                if not bValid :
                                        writeLog("", False, [" %s, %s, %s, %s : %r . function not valid in check settings" %(sBase, sOption1, sOption2, drawFunction, val), ""])
                                        if iIndex == -1 :
                                                settings[sBase][sOption1][sOption2] = copy.deepcopy(defSel[sBase][sOption1][sOption2])
                                        else :
                                                settings[sBase][sOption1][sOption2] = copy.deepcopy(defSel[sBase][sOption1]["%s-0" %baseTag])

        # add the settings not present in the selection , assigned to the default value
        for sBase in defSel.keys() :
                if not sBase in settings.keys() :
                        settings[sBase] = copy.deepcopy(defSel[sBase])
                        continue
                for sOption1 in defSel[sBase].keys() :
                        if not sOption1 in settings[sBase].keys() :
                                settings[sBase][sOption1] = copy.deepcopy(defSel[sBase][sOption1])
                                continue
                        for sOption2 in defSel[sBase][sOption1].keys() :
                                if not sOption2 in settings[sBase][sOption1].keys() :
                                        settings[sBase][sOption1][sOption2] = copy.deepcopy(defSel[sBase][sOption1][sOption2])

        # add the settings not present in the selection for the multiboxes in case an option has been added , assigned to the default value
        for sBase in defSel.keys() :
                for sOption1 in defSel[sBase].keys() :
                        for sOption2 in defSel[sBase][sOption1].keys() :
                                if "-" in sOption2 :
                                        baseTag, iIndex = splitTag(sOption2)
                                        parentTag = valueLimits[sBase][sOption1][baseTag]["parent"]
                                        if parentTag == "" : continue

                                        listKeys = settings[sBase][sOption1].keys()
                                        for sOptionLoop in listKeys :
                                                if not "-" in sOptionLoop : continue
                                                baseTagLoop, iIndexLoop = splitTag(sOptionLoop)
                                                if baseTagLoop != parentTag : continue

                                                tagLoop = "%s-%d" %(baseTag, iIndexLoop)
                                                if not tagLoop in listKeys :
                                                        settings[sBase][sOption1][tagLoop] = copy.deepcopy(defSel[sBase][sOption1]["%s-0" %baseTag])

        return settings

# when exiting or redraw the screen sort and select the non empty multi boxes :
def sortMultiBox():
        global selection

        buffValues = dict(getParents())
        for parentTag in buffValues.keys() :
                buffValues[parentTag]["parentdict"] = {}

        for optionTag0 in selection.keys() :
                for optionTag1 in selection[optionTag0].keys() :
                        for optionTag2 in selection[optionTag0][optionTag1].keys() :
                                if "-" in optionTag2 :
                                        baseTag, iIndex = splitTag(optionTag2)
                                        parentTag = valueLimits[optionTag0][optionTag1][baseTag]["parent"]
                                        if parentTag == "" :
                                                buffValues[baseTag]["parentdict"][iIndex] = copy.deepcopy(selection[optionTag0][optionTag1][optionTag2])
                                        else :
                                                buffValues[parentTag][optionTag2] = copy.deepcopy(selection[optionTag0][optionTag1][optionTag2])
                                        del(selection[optionTag0][optionTag1][optionTag2])

        for parentTag in buffValues.keys() :
                optionTag0 = buffValues[parentTag]["tag0"]
                optionTag1 = buffValues[parentTag]["tag1"]
                defVal = copy.deepcopy(defSel[optionTag0][optionTag1]["%s-0" %parentTag])

                index = 0
                listIndex = buffValues[parentTag]["parentdict"].keys()
                listIndex.sort()

                listChildrens = getChildrens(optionTag0, optionTag1, parentTag)

                for iIndex in listIndex :
                        bCopy = True
                        if type(defVal) is types.ListType :
                                if len(defVal) > 1 :
                                        if buffValues[parentTag]["parentdict"][iIndex][0] == [] :
                                                bCopy = False
                                else :
                                        if buffValues[parentTag]["parentdict"][iIndex] == [] :
                                                bCopy = False

                        if bCopy :
                                selection[optionTag0][optionTag1]["%s-%d" %(parentTag, index)] = copy.deepcopy(buffValues[parentTag]["parentdict"][iIndex])
                                for childTag in listChildrens :
                                        selection[optionTag0][optionTag1]["%s-%d" %(childTag, index)] = copy.deepcopy(buffValues[parentTag]["%s-%d" %(childTag, iIndex)])
                                index += 1

                if index < 100 :
                        selection[optionTag0][optionTag1]["%s-%d" %(parentTag, index)] = copy.deepcopy(defVal)
                        for childTag in listChildrens :
                                selection[optionTag0][optionTag1]["%s-%d" %(childTag, index)] = copy.deepcopy(defSel[optionTag0][optionTag1]["%s-0" %childTag])

# function to keep a good order in the directory showing
def sortKeys(baseDict, key1 = "" , key2 = "") :
        if key1 == "" and key2 == "" :
                baseList = baseDict.keys()
                baseSort = [[valueLimits[key]["porder"], key] for key in baseList]
        elif key2 == "" :
                baseList = baseDict[key1].keys()
                baseSort = [[valueLimits[key1][key]["porder"], key] for key in baseList]
        else :
                baseList = baseDict[key1][key2].keys()
                baseSort = []
                for key in baseList :
                        if key == "selected" : continue
                        if "-" in key :
                                baseTag, iIndex = splitTag(key)
                                parentTag = valueLimits[key1][key2][baseTag]["parent"]
                                if parentTag != "" :
                                        iOrder = valueLimits[key1][key2][parentTag]["porder"] + iIndex + 0.01*valueLimits[key1][key2][baseTag]["porder"]
                                else :
                                        iOrder = iIndex + valueLimits[key1][key2][baseTag]["porder"]
                                baseSort.append([iOrder, key])
                        else :
                                baseSort.append([valueLimits[key1][key2][key]["porder"], key])
        baseSort.sort()
        result = [item[1] for item in baseSort]
        return result

def getChildrens(baseTag, optionTag1, parentTag):
        listChildren = []
        for optionTag2 in defSel[baseTag][optionTag1].keys():
                if "-" in optionTag2 :
                        baseTagLoop, iIndexLoop = splitTag(optionTag2)
                        if parentTag == valueLimits[baseTag][optionTag1][baseTagLoop]["parent"] :
                                listChildren.append([valueLimits[baseTag][optionTag1][baseTagLoop]["porder"], baseTagLoop])
        if len(listChildren) >1 :
                listChildren.sort()

        listChildren = [item[1] for item in listChildren]
        return listChildren

def getParents():
        dictParent = {}
        for optionTag0 in defSel.keys() :
                for optionTag1 in defSel[optionTag0].keys() :
                        for optionTag2 in defSel[optionTag0][optionTag1].keys() :
                                if "-" in optionTag2 :
                                        baseTag, iIndex = splitTag(optionTag2)
                                        parentTag = valueLimits[optionTag0][optionTag1][baseTag]["parent"]
                                        if parentTag == "" :
                                                dictParent[baseTag] = {}
                                                dictParent[baseTag]["tag0"] = optionTag0
                                                dictParent[baseTag]["tag1"] = optionTag1
        return dictParent

def splitTag(tag):
        head , tail = tag.split("-")
        return [head , int(tail)]

# when reset a tab , the multiboxes can't be deleted , so add some empty box to selection
def addEmptyMultiBox(tag = ""):
        try :
                dictParents = dict(getParents())
                for parentTag in dictParents.keys() :
                        optionTag0 = dictParents[parentTag]["tag0"]
                        if tag != "" :
                                if optionTag0 != tag :
                                        continue
                        optionTag1 = dictParents[parentTag]["tag1"]
                        listChildrens = getChildrens(optionTag0, optionTag1, parentTag)
                        for i in range(nbMultiBox[parentTag]) :
                                selection[optionTag0][optionTag1]["%s-%d" %(parentTag, i)] = copy.deepcopy(defSel[optionTag0][optionTag1]["%s-0" %parentTag])
                                for childTag in listChildrens :
                                        selection[optionTag0][optionTag1]["%s-%d" %(childTag, i)] = copy.deepcopy(defSel[optionTag0][optionTag1]["%s-0" %childTag])
        except :
                writeError()

# keep the number multibox in a global :
def initNbMultiBox():
        global nbMultiBox

        nbMultiBox = {}
        for parentTag in getParents().keys() : nbMultiBox[parentTag] = 0

# create the callBack functions to add in order to apply the menu entries
def getCallBackList():
        cbList = [
                ["Sto_DummyCallback", Sto_DummyCallback_Script] ,
                ["Sto_Apply_Language", Sto_Apply_Language_Script] ,
                ["Sto_Reset_All_Apply", Sto_Reset_All_Apply_Script] ,
                ["Sto_Reset_Table_Apply", Sto_Reset_Table_Apply_Script] ,
                ["Sto_Map_Selected", Sto_Map_Selected_Script] ,
                ["Sto_Selection_MultiCB", Sto_Selection_MultiCB_Script] ,
                ["Sto_Value_Random", Sto_Value_Random_Script] ,
                ["Sto_Reset_Option", Sto_Reset_Option_Script] ,
                ["Sto_Load_File", Sto_Load_File_Script] ,
                ["Sto_Load_File_Apply", Sto_Load_File_Apply_Script] ,
                ["Sto_Save_File", Sto_Save_File_Script] ,
                ["Sto_Save_File_Apply", Sto_Save_File_Apply_Script] ,
                ["Sto_SaveFile_EditBox", Sto_SaveFile_EditBox_Script] ,
                ["Sto_SaveFile_DropdownBox", Sto_SaveFile_DropdownBox_Script] ,
                ["Sto_Exit_Load_Screen", Sto_Exit_Load_Screen_Script] ,
                ["Sto_Exit_Apply", Sto_Exit_Apply_Script] ,
                ["Sto_Refresh_Apply", Sto_Refresh_Apply_Script] ,
                ["Sto_Selection_OneCB", Sto_Selection_OneCB_Script] ,
                ["Sto_Help_Option", Sto_Help_Option_Script] ,
                ["Sto_Selection_Special", Sto_Selection_Special_Script] ,
                ["Sto_Standard_For_All_Buttons", Sto_Standard_For_All_Buttons_Script] ,
                ["Sto_Select_ResMultiply", Sto_Select_ResMultiply_Script] ,
                ["Sto_Select_StartResource", Sto_Select_StartResource_Script] ,
                ["Sto_Selection_MultiRB", Sto_Selection_MultiRB_Script] ,
                ["Sto_Defender", Sto_Defender_Script] ,
                ["Sto_Select_Tech_Select", Sto_Select_Tech_Select_Script] ,
                ["Sto_Select_Unit_Select", Sto_Select_Unit_Select_Script] ,
                ["Sto_Open_Browser", Sto_Open_Browser_Script] ,
                ["Sto_Check_Update", Sto_Check_Update_Script]
                ]
        return cbList

def initScreenCallBack():
        callbackList = getCallBackList()
        for [ funcName , funcScript ] in callbackList : setattr(CvOptionsScreenCallbackInterface, funcName, funcScript)

def deleteScreenCallBack():
        callbackList = getCallBackList()
        for [ funcName , funcScript ] in callbackList : delattr(CvOptionsScreenCallbackInterface, funcName)

def getScreen():
        return CvScreensInterface.optionsScreen

def getTab():
        return CvScreensInterface.optionsScreen.getTabControl()

def destroyScreen():
        sortMultiBox()
        getTab().destroy()

# list of function to add to CvOptionsScreenCallbackInterface
def Sto_Select_Unit_Select_Script(argsList):
        try :
                global selection
                iValue, szName = argsList

                iValue = int(iValue)
                unitTag , rest = szName.split("*")
                dum, baseTag, gameID, optionID = rest.split("_")
                iIndex = int(optionID.split("-")[1])

                tab = getTab()

                if iValue == 0 : valSel = []
                else : valSel = [ str(XMLEntriesList["units"][unitTag][iValue-1]) ]

                listTag = ["peacedd", "landdd", "waterdd", "airdd", "otherdd", "national", "team", "world", "combatnone"]
                listTag += [item for item in XMLEntriesList["unitcombatlist"]]

                for uTag in listTag :
                        if XMLEntriesList["units"][uTag] == [] : continue

                        szWidgetName = "%s*UnitDropdown_%s_%s_%s" %(uTag, baseTag, gameID, optionID)

                        if len(valSel) == 1 :
                                unitType = valSel[0]
                                if unitType in XMLEntriesList["units"][uTag] : tab.setValue(szWidgetName, XMLEntriesList["units"][uTag].index(unitType)+1)
                                else : tab.setValue(szWidgetName, 0)
                        else :
                                tab.setValue(szWidgetName, 0)

                selection[baseTag][gameID][optionID] = valSel

                if (iValue != 0) and (iIndex == nbMultiBox["startunitselect"]-1) and (nbMultiBox["startunitselect"] <= 99):
                        selection[baseTag][gameID]["startunitselect-%d" %nbMultiBox["startunitselect"]] = copy.deepcopy(defSel[baseTag][gameID]["startunitselect-0"])
                        for childTag in getChildrens(baseTag, gameID, "startunitselect"):
                                selection[baseTag][gameID]["%s-%d" %(childTag, nbMultiBox["startunitselect"])] = copy.deepcopy(defSel[baseTag][gameID]["%s-0" %childTag])
                        getScreen().drawStartUnit()
        except :
                writeError()

        return 1

def Sto_Select_Tech_Select_Script(argsList):
        try :
                global selection
                iValue, szName = argsList

                iValue = int(iValue)
                typeElement , sIndex = szName.split("_")
                iIndex = int(sIndex)

                baseTag = "game"
                gameID = "techno"
                optionID = "addtech-%s" %sIndex
                tab = getTab()

                if iValue == 0 : valSel = []
                elif iValue == 1 : valSel = "alltechsame"
                elif iValue == 2 : valSel = "alltechdiff"
                else : valSel = [ str(XMLEntriesList["techslist"][iValue-3]) ]

                selection[baseTag][gameID][optionID] = valSel

                getScreen().checkEditBox()
                getScreen().refreshScreen()

                if (iValue != 0) and (iIndex == nbMultiBox["addtech"]-1) and (nbMultiBox["addtech"] <= 99):
                        selection[baseTag][gameID]["addtech-%d" %nbMultiBox["addtech"]] = copy.deepcopy(defSel[baseTag][gameID]["addtech-0"])
                        for childTag in getChildrens(baseTag, gameID, "addtech"):
                                selection[baseTag][gameID]["%s-%d" %(childTag, nbMultiBox["addtech"])] = copy.deepcopy(defSel[baseTag][gameID]["%s-0" %childTag])
                        getScreen().drawAddTech()
        except :
                writeError()

        return 1

def Sto_Defender_Script(argsList):
        try :
                global selection
                iValue, szName = argsList

                iValue = int(iValue)

                typeElement, baseTag, optionTag1, optionTag2 = szName.split("_")

                tab = getTab()

                if typeElement == "gameCityDef" :
                        if iValue == 0 : valSel = []
                        else : valSel = [ str(XMLEntriesList["units"]["barbdefender"][iValue-1]) ]

                        if XMLEntriesList["units"]["barbfight"] != [] :
                                szWidgetName = "gameCityFight_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                                tab.setValue(szWidgetName, 0)

                elif typeElement == "gameCityFight" :
                        if iValue == 0 : valSel = []
                        else : valSel = [ str(XMLEntriesList["units"]["barbfight"][iValue-1]) ]

                        if XMLEntriesList["units"]["barbdefender"] != [] :
                                szWidgetName = "gameCityDef_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                                tab.setValue(szWidgetName, 0)

                selection[baseTag][optionTag1][optionTag2] = valSel
        except :
                writeError()

        return 1

def Sto_Select_StartResource_Script(argsList):
        try :
                global selection
                iValue, szName = argsList

                iValue = int(iValue)
                typeElement , sIndex = szName.split("_")
                iIndex = int(sIndex)

                baseTag = "resources"
                resourceID = "resourcesstart"
                optionID = "startresselect-%s" %sIndex
                tab = getTab()

                if iValue == 0 :
                        valSel = []

                elif typeElement == "StratStartDropdown" :
                        if iValue == 1 : valSel = "allstratsame"
                        elif iValue == 2 : valSel = "allstratdiff"
                        else : valSel = [ str(XMLEntriesList["strategic"][iValue-3]) ]

                        tab.setValue("HealthStartDropdown_%s" %sIndex, 0)
                        tab.setValue("HappStartDropdown_%s" %sIndex, 0)

                elif typeElement == "HealthStartDropdown" :
                        if iValue == 1 : valSel = "allhealthsame"
                        elif iValue == 2 : valSel = "allhealthdiff"
                        else : valSel = [ str(XMLEntriesList["health"][iValue-3]) ]

                        tab.setValue("StratStartDropdown_%s" %sIndex, 0)
                        tab.setValue("HappStartDropdown_%s" %sIndex, 0)

                elif typeElement == "HappStartDropdown" :

                        if iValue == 1 : valSel = "allhappsame"
                        elif iValue == 2 : valSel = "allhappdiff"
                        else : valSel = [ str(XMLEntriesList["happiness"][iValue-3]) ]

                        tab.setValue("HealthStartDropdown_%s" %sIndex, 0)
                        tab.setValue("StratStartDropdown_%s" %sIndex, 0)

                selection[baseTag][resourceID][optionID] = valSel

                if (iValue != 0) and (iIndex == nbMultiBox["startresselect"]-1) and (nbMultiBox["startresselect"] <= 99):
                        selection[baseTag][resourceID]["startresselect-%d" %nbMultiBox["startresselect"]] = copy.deepcopy(defSel[baseTag][resourceID]["startresselect-0"])
                        for childTag in getChildrens(baseTag, resourceID, "startresselect"):
                                selection[baseTag][resourceID]["%s-%d" %(childTag, nbMultiBox["startresselect"])] = copy.deepcopy(defSel[baseTag][resourceID]["%s-0" %childTag])
                        getScreen().drawStartResources()
        except :
                writeError()

        return 1

def Sto_Select_ResMultiply_Script(argsList):
        try :
                global selection
                iValue, szName = argsList

                iValue = int(iValue)
                typeElement , sIndex = szName.split("_")
                iIndex = int(sIndex)

                baseTag = "resources"
                resourceID = "resourcesgen"
                optionID = "resmultiply-%s" %sIndex
                tab = getTab()

                if iValue == 0 :
                        valSel = []

                elif typeElement == "StratDropdown" :
                        if iValue == 1 : valSel = "allstrat"
                        else : valSel = [ str(XMLEntriesList["strategic"][iValue-2]) ]

                        tab.setValue("HealthDropdown_%s" %sIndex, 0)
                        tab.setValue("HappDropdown_%s" %sIndex, 0)

                elif typeElement == "HealthDropdown" :
                        if iValue == 1 : valSel = "allhealth"
                        else : valSel = [ str(XMLEntriesList["health"][iValue-2]) ]

                        tab.setValue("StratDropdown_%s" %sIndex, 0)
                        tab.setValue("HappDropdown_%s" %sIndex, 0)

                elif typeElement == "HappDropdown" :

                        if iValue == 1 : valSel = "allhapp"
                        else : valSel = [ str(XMLEntriesList["happiness"][iValue-2]) ]

                        tab.setValue("HealthDropdown_%s" %sIndex, 0)
                        tab.setValue("StratDropdown_%s" %sIndex, 0)

                selection[baseTag][resourceID][optionID][0] = valSel

                if (iValue != 0) and (iIndex == nbMultiBox["resmultiply"]-1) and (nbMultiBox["resmultiply"] <= 99):
                        selection[baseTag][resourceID]["resmultiply-%d" %nbMultiBox["resmultiply"]] = copy.deepcopy(defSel[baseTag][resourceID]["resmultiply-0"])
                        for childTag in getChildrens(baseTag, resourceID, "resmultiply"):
                                selection[baseTag][resourceID]["%s-%d" %(childTag, nbMultiBox["resmultiply"])] = copy.deepcopy(defSel[baseTag][resourceID]["%s-0" %childTag])
                        getScreen().drawMultiplyResources()
        except :
                writeError()

        return 1

def Sto_Standard_For_All_Buttons_Script(argsList):
        try :
                global selection
                szName = argsList[0]

                typeTag, baseTag, option1, option2 = szName.split("_")

                getScreen().checkEditBox() # before a reinit , check and save the edit box entries

                if typeTag == "AllStrat" : baseList = [item for item in XMLEntriesList["strategic"]]
                elif typeTag == "AllHealth" : baseList = [item for item in XMLEntriesList["health"]]
                elif typeTag == "AllHapp" : baseList = [item for item in XMLEntriesList["happiness"]]
                
                elementList = selection[baseTag][option1][option2]

                baseList.sort()
                tpList = [item for item in elementList if item in baseList ]
                tpList.sort()
                
                if tpList == baseList :
                        for elementType in baseList : selection[baseTag][option1][option2].remove(elementType)
                else :
                        for elementType in baseList :
                                if not elementType in elementList : selection[baseTag][option1][option2].append(elementType)

                getScreen().refreshScreen()
        except :
                writeError()

        return 1

def Sto_Check_Update_Script(argsList):
        try :
                urlFile = urllib.urlopen("http://forums.civfanatics.com/showthread.php?t=151629")
                lines = urlFile.readlines()
                urlFile.close()
                bFoundLine = False
                for line in lines :
                        if "##^^FoR_Current_Version : " in line :
                                part = line.split("##^^FoR_Current_Version : ")[1]
                                if "^^##" in part :
                                        bFoundLine = True
                                        sVersion = part[0:part.index("^^##")]
                                        try :
                                                if float(sVersion) > float(getVersion()) :
                                                        launchPopUP([["TXT_CHECK_UPDATE_TO_UPDATE", ""], ])
                                                else :
                                                        launchPopUP([["TXT_CHECK_UPDATE_OK", ""], ])
                                        except :
                                                launchPopUP([["TXT_CHECK_UPDATE_FAILED", ""], ])
                                                writeError()
                                break
                if not bFoundLine : launchPopUP([["TXT_CHECK_UPDATE_FAILED", ""], ])
        except :
                launchPopUP(launchPopUP([["TXT_CHECK_UPDATE_FAILED", ""], ]))
                writeError()

        return 1

def Sto_Open_Browser_Script(argsList):
        try :
                webbrowser.open("http://forums.civfanatics.com/showthread.php?t=151629", 1, 0)
        except :
                writeError()

        return 1

def Sto_Help_Option_Script(argsList):
        try :
                szName = argsList[0]

                baseID = szName.split("_")[1]
                optionID = szName.split("_")[2]

                if optionID == "resourcesgen" :
                        txtList = [["TXT_HELP_RESGEN01", ""], ["", ""], ["TXT_HELP_RESGEN0", ""], ["TXT_HELP_RESGEN1", ""], ["", ""], ["TXT_HELP_RESGEN2", ""], ["TXT_HELP_RESGEN3", ""],
                                   ["TXT_HELP_RESGEN4", ""], ["", ""], ["TXT_HELP_RESGEN5", (getSMenuText("TXT_RESOURCES_GROUPRES"),)], ["TXT_HELP_RESGEN6", ""], ["", ""],
                                   ["TXT_HELP_RESGEN7", ""], ["TXT_HELP_RESGEN8", ""], ["TXT_HELP_RESGEN9", ""]]
                        launchPopUP(txtList)
                elif optionID == "resourcesstart" :
                        txtList = [["TXT_HELP_RESSTART0", ""], ["TXT_HELP_RESSTART1", ""], ["TXT_HELP_RESSTART2", ""], ["", ""], ["TXT_HELP_RESSTART3", ""],
                                   ["TXT_HELP_RESSTART4", ""], ["TXT_HELP_RESSTART5", ""], ["TXT_HELP_RESSTART6", ""], ["", ""], ["TXT_HELP_RESSTART7", ""],
                                   ["TXT_HELP_RESSTART8", ""], ["TXT_HELP_RESSTART9", (getSMenuText("TXT_RESOURCES_START_FORCE_SEL0"),)], ["TXT_HELP_RESSTART10", (getSMenuText("TXT_RESOURCES_START_FORCE_SEL1"),)]]
                        launchPopUP(txtList)
                elif optionID == "barbcities" :
                        txtList = [["TXT_HELP_CITIES0", ""], ["TXT_HELP_CITIES1", ""], ["TXT_HELP_CITIES2", ""], ["TXT_HELP_CITIES3", ""],
                                   ["TXT_HELP_CITIES4", ""], ["TXT_HELP_CITIES5", ""]]
                        launchPopUP(txtList)
                elif optionID == "animals" :
                        txtList = [["TXT_HELP_ANIMAL0", ""], ["TXT_HELP_ANIMAL1", ""], ["TXT_HELP_ANIMAL2", ""]]
                        launchPopUP(txtList)
                elif optionID == "techno" :
                        txtList = [["TXT_HELP_TECH0", ""], ["TXT_HELP_TECH1", ""], ["TXT_HELP_TECH2", ""], ["TXT_HELP_TECH3", ""]]
                        launchPopUP(txtList)
                elif optionID == "startunit" :
                        txtList = [["TXT_HELP_UNIT0", ""], ["TXT_HELP_UNIT1", ""], ["", ""], ["TXT_HELP_UNIT2", (getSMenuText("TXT_GAME_UNIT_TYPE"),)],
                                   ["TXT_HELP_UNIT3", ""], ["TXT_HELP_UNIT4", (getSMenuText("TXT_GAME_UNIT_TYPE_SEL0"),)],
                                   ["TXT_HELP_UNIT5", (getSMenuText("TXT_GAME_UNIT_TYPE_SEL1"),)], ["TXT_HELP_UNIT6", (getSMenuText("TXT_GAME_UNIT_TYPE_SEL2"),)]]
                        launchPopUP(txtList)
                elif optionID == "normalize" :
                        txtList = [["TXT_HELP_NORM0", ""], ["TXT_HELP_NORM1", (getSMenuText("TXT_STARTLOCS_NORM_START_SEL0"),)], ["", ""],
                                   ["TXT_STARTLOCS_NORM_START", ""], ["TXT_HELP_NORM2", ""],
                                   ["TXT_HELP_NORM2_1", (getSMenuText("TXT_STARTLOCS_SWAPHUMANS_SEL0"),)], ["", ""], 
                                   ["TXT_STARTLOCS_NORM_RIVER", ""], ["TXT_HELP_NORM3", ""], ["", ""],
                                   ["TXT_STARTLOCS_NORM_PEAK", ""], ["TXT_HELP_NORM4", ""], ["", ""],
                                   ["TXT_STARTLOCS_NORM_LAKE", ""], ["TXT_HELP_NORM5", ""], ["", ""],
                                   ["TXT_STARTLOCS_NORM_BADFEAT", ""], ["TXT_HELP_NORM6", ""], ["", ""],
                                   ["TXT_STARTLOCS_NORM_BADTER", ""], ["TXT_HELP_NORM7", ""], ["", ""],
                                   ["TXT_STARTLOCS_NORM_FOODBONUS", ""], ["TXT_HELP_NORM8", ""], ["", ""],
                                   ["TXT_STARTLOCS_NORM_GOODTER", ""], ["TXT_HELP_NORM9", ""], ["", ""],
                                   ["TXT_STARTLOCS_NORM_EXTRA", ""], ["TXT_HELP_NORM10", ""], ["", ""]]
                        launchPopUP(txtList)
        except :
                writeError()

        return 1

def Sto_Selection_OneCB_Script(argsList):
        try :
                global selection
                bValue, szName = argsList

                dum, baseTag, option1, option2 = szName.split("_")
                selection[baseTag][option1][option2] = bool(bValue)

                if option2 == "erasedefres" :
                        if bool(bValue) :
                                if selection["resources"]["resourcesgen"]["waterpercent"] == "standard" : selection["resources"]["resourcesgen"]["waterpercent"] = [-1]
                                if selection["resources"]["resourcesgen"]["landpercent"] == "standard" : selection["resources"]["resourcesgen"]["landpercent"] = [-1]
                        
                        getScreen().checkEditBox()
                        getScreen().refreshScreen()
        except :
                writeError()

        return 1

def Sto_SaveFile_EditBox_Script(argsList):
        try :
                uText , szName = argsList

                sText = getSText(uText)
                allowedChar = str(string.ascii_letters + string.digits + "_- ")

                while True :
                        if sText == "" :
                                break
                        if sText[0] == "_" :
                                sText = sText[1:]
                                continue
                        break
                lToReplace = ""
                for s in sText :
                        if (( not s in allowedChar ) and ( not s in lToReplace )) : lToReplace += s

                for s in lToReplace : sText = sText.replace(s, "")

                getTab().setText("SaveFileEditBox", getUText(sText))
                
                listFile = [ item[0:-4] for item in getListDirSto() if ((".cfg" in item) and (item[0] != "_")) ]
                listFile.sort()

                if sText in listFile : iIndex = listFile.index(sText) +1
                else : iIndex = 0

                getTab().setValue("ListFilesDropdown", iIndex)
        except :
                writeError()

        return 1

def Sto_SaveFile_DropdownBox_Script(argsList):
        try :
                iValue, szName = argsList

                iValue = int(iValue)

                listFile = [ item for item in getListDirSto() if ((".cfg" in item) and (item[0] != "_")) ]
                listFile.sort()

                if iValue == 0 :
                        getTab().setText("SaveFileEditBox", getUMenuText("TXT_NEW_FILE"))
                else :
                        getTab().setText("SaveFileEditBox", getUText(listFile[iValue-1][0:-4]))
        except :
                writeError()

        return 1

def Sto_Save_File_Apply_Script(argsList):
        try :
                fileName = getSText(getTab().getText("SaveFileEditBox"))+".cfg"
                writeLog("", False, [" Sto_Save_File_Apply : fileName : %s" %fileName, ""])

                if fileName == ".cfg" :
                        launchPopUP([["TXT_ENTER_FILE_NAME", ""]])
                        return 1
                elif fileName == getSMenuText("TXT_NEW_FILE")+".cfg" :
                        launchPopUP([["TXT_CHANGE_FILE_NAME", ""]])
                        return 1

                dB = saveSelection(fileName)

                if dB :
                        launchPopUP([["TXT_FAILED_POPUP_SAVE", ""]])
                        return 1

                saveConfig("LastFileSaved", fileName)

                getTab().destroy()
                CvScreensInterface.optionsScreen = CvStoFullOfResourcesScreen()
                CvScreensInterface.showOptionsScreen()
        except :
                writeError()

        return 1

def Sto_Save_File_Script(argsList):
        try :
                getScreen().checkEditBox() # before a reinit , check and save the edit box entries

                destroyScreen() # destroy the screen

                CvScreensInterface.optionsScreen = CvStoSaveFileScreen() # redirect to the save screen ( i can't use popup with entries before the game )
                CvScreensInterface.showOptionsScreen() # launch the screen
        except :
                writeError()

        return 1

def Sto_Exit_Load_Screen_Script(argsList):
        try :
                getTab().destroy()
                CvScreensInterface.optionsScreen = CvStoFullOfResourcesScreen()
                CvScreensInterface.showOptionsScreen()
        except :
                writeError()

        return 1

def Sto_Load_File_Apply_Script(argsList):
        try :
                global selection

                listFile = [ item for item in getListDirSto() if ((".cfg" in item) and (item != "_userConfig.cfg")) ]
                listFile.sort()

                fileNameIndex = getTab().getValue("ListFilesDropdown")

                fileName = listFile[int(fileNameIndex)]
                writeLog("", False, [" Sto_Load_File_Apply_Script : fileName : %s" %fileName, ""])

                selTp = loadSelection(fileName, False)

                if selTp == -1 :
                        launchPopUP([["TXT_FAILED_POPUP_LOAD", ""]])
                        return 1

                selection = dict(selTp)
                sortMultiBox()

                getTab().destroy()
                CvScreensInterface.optionsScreen = CvStoFullOfResourcesScreen()
                CvScreensInterface.showOptionsScreen()
        except :
                writeError()

        return 1

def Sto_Load_File_Script(argsList):
        try :
                listFile = [ item for item in getListDirSto() if ((".cfg" in item) and (item != "_userConfig.cfg")) ]
                if listFile == [] :
                        launchPopUP([["TXT_NO_FILE_TO_LOAD", ""]])
                        return 1
                        
                getScreen().checkEditBox() # before a reinit , check and save the edit box entries

                destroyScreen() # destroy the screen

                CvScreensInterface.optionsScreen = CvStoLoadFileScreen() # redirect to the load screen ( i can't use popup with entries before the game )
                CvScreensInterface.showOptionsScreen() # launch the screen
        except :
                writeError()

        return 1

def Sto_Selection_MultiRB_Script(argsList):
        try :
                global selection
                bSelected, szName = argsList

                if bSelected :
                        baseTag, optionTag1, optionTag2, sIndex = szName.split("_")

                        selection[baseTag][optionTag1][optionTag2] = int(sIndex)

                getScreen().checkEditBox()
                getScreen().refreshScreen()
        except :
                writeError()

        return 1

def Sto_Value_Random_Script(argsList):
        try :
                global selection
                bSelected, szName = argsList

                if bSelected :
                        rbName , baseTag, optionTag1, optionTag2 = szName.split("_")

                        if rbName == "RBStandard" : selection[baseTag][optionTag1][optionTag2] = "standard"
                        elif rbName == "RBValue" : selection[baseTag][optionTag1][optionTag2] = [-1]
                        else : selection[baseTag][optionTag1][optionTag2] = [-1,-1]

                getScreen().checkEditBox()
                getScreen().refreshScreen()
        except :
                writeError()

        return 1

def Sto_Selection_Special_Script(argsList):
        try :
                global selection
                bValue, szName = argsList

                item , tagList = szName.split("*")

                baseTag, optionTag1, optionTag2, sLabel = tagList.split("_")

                if bValue : selection[baseTag][optionTag1][optionTag2].append(item)
                else : selection[baseTag][optionTag1][optionTag2].remove(item)
        except :
                writeError()

        return 1

def Sto_Selection_MultiCB_Script(argsList):
        try :
                global selection
                bValue, szName = argsList

                baseTag, optionTag1, optionTag2, sIndex, sNbSelection = szName.split("_")
                nbSelection = int(sNbSelection)

                if bValue : selection[baseTag][optionTag1][optionTag2].append(int(sIndex))
                else : selection[baseTag][optionTag1][optionTag2].remove(int(sIndex))

                if selection[baseTag][optionTag1][optionTag2] == [] :
                        getScreen().checkEditBox()
                        selection[baseTag][optionTag1][optionTag2] = list(range(nbSelection))
                        getScreen().refreshScreen()
        except :
                writeError()

        return 1

def Sto_Reset_Option_Script(argsList):
        try :
                global selection
                szName = argsList[0]

                baseID = szName.split("_")[1]
                optionID = szName.split("_")[2]

                getScreen().checkEditBox() # before a reinit , check and save the edit box entries

                if baseID == "maps" :
                        bSel = bool(copy.deepcopy(selection[baseID][optionID]["selected"]))

                selection[baseID][optionID] = copy.deepcopy(defSel[baseID][optionID])

                if baseID == "maps" :
                        selection[baseID][optionID]["selected"] = bSel

                getScreen().refreshScreen()
        except :
                writeError()

        return 1

def Sto_Map_Selected_Script(argsList):
        try :
                global selection
                bValue, szName = argsList

                mapID = szName.split("_")[1]
                selection["maps"][mapID]["selected"] = bool(bValue)

                getScreen().refreshMapOptionsTab()
        except :
                writeError()

        return 1

def Sto_Exit_Apply_Script(argsList):
        try :
                getScreen().checkEditBox() # check if current EB are good and save in selection

                # save back up
                dB = saveSelection("_LastConfig.cfg")
                dB = saveSelection(getLastFileUsedName())
                if isNetMP : dB = saveSelection("_Multiplayer_Config.cfg")

                destroyScreen()
                CvScreensInterface.optionsScreen = CvOptionsScreen.CvOptionsScreen()
                deleteScreenCallBack()

                if dB : launchPopUP([["TXT_FAILED_POPUP_SAVE", ""]])
        except :
                writeError()

        return 1

def Sto_Refresh_Apply_Script(argsList):
        try :
                getScreen().checkEditBox() # check if current EB are good and save in selection
                getScreen().refreshScreen()
        except :
                writeError()

        return 1

def Sto_Reset_All_Apply_Script(argsList):
        try :
                global selection

                selection = copy.deepcopy(defSel)
                addEmptyMultiBox()

                getScreen().refreshScreen()
        except :
                writeError()

        return 1

def Sto_Reset_Table_Apply_Script(argsList):
        try :
                global selection

                szName = argsList[0]

                tag = szName.split("_")[1]
                getScreen().checkEditBox() # check if current EB are good and save in selection

                selection[tag] = copy.deepcopy(defSel[tag])
                addEmptyMultiBox(tag)

                getScreen().refreshScreen()
                        
        except :
                writeError()
                
        return 1

def Sto_Apply_Language_Script(argsList):
        try :
                global language
                global bInitDescription
                bInitDescription = True

                iValue, szName = argsList

                saveConfig("language", iValue)
                language = iValue

                getScreen().checkEditBox() # check if current EB are good and save in selection

                initXMLDescriptions()

                initValueLimits() # reset the descriptions

                sortXMLLists() # sort the xml lists in function of the descriptions

                #delete screen and redraw it
                destroyScreen()
                CvScreensInterface.showOptionsScreen()

        except :
                writeError()

        return 1

# just in case
def Sto_DummyCallback_Script(argsList):
        return

# Main screen
class CvStoFullOfResourcesScreen:
	
	def __init__(self):
		
		self.callbackIFace = "CvOptionsScreenCallbackInterface"
		
	def getTabControl(self):
		return self.pTabControl
		
	def initText(self):
		
		self.szTabControlName = getUMenuText("TXT_TITTLE")
		
		self.szInfosTabName = getUMenuText("TXT_INFOS")
		self.szMapOptionsTabName = getUMenuText("TXT_MAPS")
		self.szTerrainOptionsTabName = getUMenuText("TXT_TERRAIN")
		self.szResourcesOptionsTabName = getUMenuText("TXT_RESOURCES")
		self.szStartOptionsTabName = getUMenuText("TXT_STARTLOC")
		self.szGameOptionsTabName = getUMenuText("TXT_GAME_OPTIONS")

	def refreshScreen(self):
                try : self.refreshMapOptionsTab()
                except : writeError()
                try : self.refreshTerrainOptionsTab()
                except : writeError()
                try : self.refreshResourcesOptionsTab()
                except : writeError()
                try : self.refreshStartOptionsTab()
                except : writeError()
                try : self.refreshGameOptionsTab()
                except : writeError()

	def checkEditBox(self):
                try : self.checkEditBoxMapOptionsTab()
                except : writeError()
                try : self.checkEditBoxTerrainOptionsTab()
                except : writeError()
                try : self.checkEditBoxResourcesOptionsTab()
                except : writeError()
                try : self.checkEditBoxStartOptionsTab()
                except : writeError()
                try : self.checkEditBoxGameOptionsTab()
                except : writeError()

	def interfaceScreen (self):
		self.initText()
		
                initNbMultiBox()

		self.pTabControl = CyGTabCtrl(self.szTabControlName, false, false)
		self.pTabControl.setModal(1)

		# enlarge the screen at the maximum
		resolution = [int(item) for item in CyUserProfile().getResolutionString(CyUserProfile().getResolution()).split("x") if item != "" ]
		self.pTabControl.setSize(int(resolution[0]*0.95), int(resolution[1]*0.95))
		self.pTabControl.setControlsExpanding(false)
		
		self.pTabControl.attachTabItem("InfoForm", self.szInfosTabName)
		self.pTabControl.attachTabItem("MapForm", self.szMapOptionsTabName)
		self.pTabControl.attachTabItem("TerrainForm", self.szTerrainOptionsTabName)
		self.pTabControl.attachTabItem("ResourcesForm", self.szResourcesOptionsTabName)
		self.pTabControl.attachTabItem("StartForm", self.szStartOptionsTabName)
		self.pTabControl.attachTabItem("GameForm", self.szGameOptionsTabName)

		# no need to check errors , CTD occurs if there is an error		
		self.drawInfosTab()
		self.drawMapOptionsTab()
		self.drawTerrainOptionsTab()
		self.drawResourcesOptionsTab()
		self.drawStartOptionsTab()
		self.drawGameOptionsTab()

	def selectDrawFunction(self, optionFunction, argList = []):
                dictFunctions = {
                        "Selection" : self.drawBoxOptionSelection ,
                        "ValueRandom" : self.drawBoxOptionEDValueRandom ,
                        "ValueRandomFloat" : self.drawBoxOptionEDValueRandom ,
                        "SelectOne" : self.drawBoxOptionSelectOne ,
                        "SelectionRB" : self.drawBoxOptionSelectionMultiRB ,
                        "Value" : self.drawBoxOptionValue ,
                        "StandardValueRandom" : self.drawBoxOptionStandardValueRandom ,
                        "MultiValues" : self.drawBoxOptionMultiValues ,
                        "standardgen" : self.drawBoxOptionSelectionSpecialDefaultResources ,
                        "SelectionSpecial" : self.drawBoxOptionSelectionSpecial ,
                        "startresselect" : self.drawStartResources ,
                        "defender" : self.drawBoxOptionDefender ,
                        "addtech" : self.drawAddTech ,
                        "startunitselect" : self.drawStartUnit ,
                        "resmultiply" : self.drawMultiplyResources
                        }
                if argList != [] :
                        dictFunctions[optionFunction](argList)
                else :
                        dictFunctions[optionFunction]()

	def selectRefreshFunction(self, optionFunction, argList = []):
                dictFunctions = {
                        "Selection" : self.refreshSelection ,
                        "ValueRandom" : self.refreshValueRandom ,
                        "ValueRandomFloat" : self.refreshValueRandom ,
                        "SelectOne" : self.refreshSelectOne ,
                        "SelectionRB" : self.refreshSelectionMultiRB ,
                        "Value" : self.refreshValue ,
                        "StandardValueRandom" : self.refreshStandardValueRandom ,
                        "MultiValues" : self.refreshMultiValues ,
                        "standardgen" : self.refreshSelectionSpecialDefaultResources ,
                        "SelectionSpecial" : self.refreshSelectionSpecial ,
                        "startresselect" : self.refreshStartResources ,
                        "defender" : self.refreshOptionDefender ,
                        "addtech" : self.refreshAddTech ,
                        "startunitselect" : self.refreshStartUnit ,
                        "resmultiply" : self.refreshMultiplyResources
                        }
                if argList != [] :
                        dictFunctions[optionFunction](argList)
                else :
                        dictFunctions[optionFunction]()

	def selectCheckEditBoxFunction(self, optionFunction, argList = []):
                dictFunctions = {
                        "ValueRandom" : self.checkEditBoxValueRandom ,
                        "ValueRandomFloat" : self.checkEditBoxValueRandomFloat ,
                        "Value" : self.checkEditBoxValue ,
                        "StandardValueRandom" : self.checkEditBoxStandardValueRandom ,
                        "MultiValues" : self.checkEditBoxMultiValues ,
                        "resmultiply" : self.checkEditBoxMultiplyResources
                        }
                if not optionFunction in dictFunctions : return
                if argList != [] :
                        dictFunctions[optionFunction](argList)
                else :
                        dictFunctions[optionFunction]()

        def drawInfosTab(self):
		
                # draw the tab ,
		tab = self.pTabControl
		tab.attachVBox("InfoForm", "InfoVBoxParent")
		
		# Add Map Options
		
		tab.attachPanel("InfoVBoxParent", "InfoPanelCenter")
		tab.setStyle("InfoPanelCenter", "Panel_Tan15_Style")
		tab.setLayoutFlag("InfoPanelCenter", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("InfoPanelCenter", "LAYOUT_SIZE_VEXPANDING")
		
		tab.attachScrollPanel("InfoPanelCenter", "InfoPanel")
		tab.setLayoutFlag("InfoPanel", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("InfoPanel", "LAYOUT_SIZE_VEXPANDING")

		tab.attachVBox("InfoPanel", "InfoVBox")
		tab.setLayoutFlag("InfoVBox", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("InfoVBox", "LAYOUT_SIZE_VEXPANDING")

                txtList = [
                    "newBox", ["TXT_INFOS_0", ""],
                    "newBox", ["TXT_INFOS_1", ""], "newBox", "button1", "newBox", "button2",
                    "sep", "newBox", ["TXT_INFOS_2", ""],
                    "newBox", ["TXT_INFOS_3", ""], ["TXT_INFOS_4", ""], "newBox", ["TXT_INFOS_5", (getSMenuText("TXT_REFRESH"),)], "newBox",
                    ["TXT_INFOS_6", ""], ["TXT_INFOS_7", (getSMenuText("TXT_EXIT"), getSMenuText("TXT_EXIT0"))], ["TXT_INFOS_8", ""], "newBox",
                    ["TXT_INFOS_9", ""], ["TXT_INFOS_9_0", ""], "newBox", ["TXT_INFOS_10", ""], "newBox", ["TXT_INFOS_11", ""],
                    "sep", "newBox", ["TXT_INFOS_12", ""],
                    "newBox", ["TXT_INFOS_13", ""], "newBox", ["TXT_INFOS_14", ""], "endChapter",
                    ["TXT_INFOS_15", ""], ["TXT_INFOS_16", ""], "endChapter", ["TXT_INFOS_17", ""], ["TXT_INFOS_18", ""], ["TXT_INFOS_19", ""]
                    ]

                iBoxIndex = 0
                iTextIndex = 0
                iSepIndex = 0
                txtTotTemp = ""
                def writeText(szBox, szText, iIndex) :
                        txtTemp = ""
                        for txtPart in szText.split(" ") :
                                if txtPart == "" : continue
                                if len(txtTemp) + len(txtPart) > 130 :
                                        uLabelText = getUText(txtTemp)
                                        labelHBox = "%dInfoLabelHBox%d" %(iIndex, iBoxIndex)
                                        tab.attachHBox(szBox, labelHBox)
                                        tab.setLayoutFlag(labelHBox, "LAYOUT_SIZE_VEXPANDING")
                                        tab.setLayoutFlag(labelHBox, "LAYOUT_SIZE_HEXPANDING")
                                        tab.attachLabel(labelHBox, "%dInfoLabelVLabel%d" %(iIndex, iBoxIndex), uLabelText)
                                        txtTemp = ""
                                        iIndex += 1
                                txtTemp += txtPart+" "
                        if len(txtTemp) > 0 :
                                uLabelText = getUText(txtTemp)
                                labelHBox = "%dInfoLabelHBox%d" %(iIndex, iBoxIndex)
                                tab.attachHBox(szBox, labelHBox)
                                tab.setLayoutFlag(labelHBox, "LAYOUT_SIZE_VEXPANDING")
                                tab.setLayoutFlag(labelHBox, "LAYOUT_SIZE_HEXPANDING")
                                tab.attachLabel(labelHBox, "%dInfoLabelVLabel%d" %(iIndex, iBoxIndex), uLabelText)
                                iIndex += 1
                        return iIndex

                for item in txtList :
                        if (txtTotTemp != "") and (item in ["newBox", "sep", "endChapter", "button1", "button2"]) :
                                iTextIndex = writeText(newBox, txtTotTemp, iTextIndex)
                                txtTotTemp = ""

                        if item == "newBox" :
                                tab.attachFixedSpacer("InfoVBox", 5)

                                newBox = "InfoLabelVBox%d" %iBoxIndex
                                tab.attachVBox("InfoVBox", newBox)
                                tab.setLayoutFlag(newBox, "LAYOUT_SIZE_HEXPANDING")
                                tab.setLayoutFlag(newBox, "LAYOUT_SIZE_VEXPANDING")

                                iBoxIndex += 1
                                iTextIndex = 0

                        elif item == "sep" :
                                tab.attachFixedSpacer("InfoVBox", 15)
                                tab.attachHSeparator("InfoVBox", "InfoVSeparator%d" %iSepIndex)
                                tab.attachFixedSpacer("InfoVBox", 10)

                                iSepIndex += 1

                        elif item == "button1" :
                                tab.setLayoutFlag(newBox, "LAYOUT_LEFT")

                                szOptionDesc = getUMenuText("TXT_OPEN_BROWSER")
                                szCallbackFunction = "Sto_Open_Browser"
                                szWidgetName = "open_browser_%d_%d" %(iTextIndex, iBoxIndex)
                                tab.attachButton(newBox, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

                        elif item == "button2" :
                                tab.setLayoutFlag(newBox, "LAYOUT_LEFT")

                                szOptionDesc = getUMenuText("TXT_CHECK_UPDATE")
                                szCallbackFunction = "Sto_Check_Update"
                                szWidgetName = "Check_Update_%d_%d" %(iTextIndex, iBoxIndex)
                                tab.attachButton(newBox, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

                        elif not item in ["endChapter"] :
                                szTag, lList = item
                                if txtTotTemp != "" : txtTotTemp += " "
                                txtTotTemp += getSMenuText(szTag, lList)

                if txtTotTemp != "" : iTextIndex = writeText(newBox, txtTotTemp, iTextIndex)

                tab.attachFixedSpacer("InfoVBox", 10)
                self.drawLowerPanel("InfoVBoxParent", "InfoTab")

	def drawMapOptionsTab(self):

                # draw the tab ,
		tab = self.pTabControl

                baseTag = "maps"

		tab.attachVBox("MapForm", "MapVBoxParent")
		
		# Add Map Options
		
		tab.attachPanel("MapVBoxParent", "MapPanelCenter")
		tab.setStyle("MapPanelCenter", "Panel_Tan15_Style")
		tab.setLayoutFlag("MapPanelCenter", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("MapPanelCenter", "LAYOUT_SIZE_VEXPANDING")
		
		tab.attachScrollPanel("MapPanelCenter", "MapPanel")
		tab.setLayoutFlag("MapPanel", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("MapPanel", "LAYOUT_SIZE_VEXPANDING")

		tab.attachVBox("MapPanel", "MapVBox")
		tab.setLayoutFlag("MapVBox", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("MapVBox", "LAYOUT_SIZE_VEXPANDING")

		# add a texture to egalize column ( can't find another way for the moment ... will check that later )
                tittleBar1 = "^_^"
                for mapID in selection[baseTag].keys() :
                        while len(valueLimits[baseTag][mapID]["description"])>len(tittleBar1) : tittleBar1 += "^_^"
                tittleBar1 += "^_^"
                tittleBar1 = getUText(tittleBar1)

                tittleBar2 = "^_^"
                for mapID in sortKeys(selection, baseTag) :
                        for optionID in sortKeys(selection, baseTag, mapID) :
                                labelTag = valueLimits[baseTag][mapID][optionID]["txttag"]
                                while len(getSMenuText(labelTag))>len(tittleBar2) : tittleBar2 += "^_^"
                tittleBar2 = getUText(tittleBar2)

                tittleBar3 = "^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^"
                if language == 2 : tittleBar3 += "^_^^_^^_^^_^^_^^_^^_^^_^"
                elif language == 3 : tittleBar3 += "^_^^_^^_^"
                elif language == 4 : tittleBar3 += "^_^^_^^_^^_^^_^"
                tittleBar3 = getUText(tittleBar3)

                # draw each map box
		listMaps = sortKeys(selection, baseTag)
                nbMaps = len(listMaps)

		for iMap in range(nbMaps):

                        mapID = listMaps[iMap]
                        
                        tab.attachHSeparator("MapVBox", "%sHSeparator0" %mapID)
                        tab.attachHSeparator("MapVBox", "%sHSeparator01" %mapID)

                        #create Hbox with 3 Vbox in
                        szBoxName = "%sHBox" %mapID
                        vBox1 = "%sVBox1" %mapID
                        vBox2 = "%sVBox2" %mapID
                        vBox3 = "%sVBox3" %mapID

                        tab.attachHBox("MapVBox", szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_SIZE_HEXPANDING")

                        tab.attachVSeparator(szBoxName, "%sVSeparator0" %mapID)

                        tab.attachVBox(szBoxName, vBox1)

                        tab.attachFixedSpacer(szBoxName, 5)
                        tab.attachVSeparator(szBoxName, "%sVSeparator1" %mapID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        tab.attachVBox(szBoxName, vBox2)
                        tab.setLayoutFlag(vBox2, "LAYOUT_SIZE_VEXPANDING")

                        tab.attachFixedSpacer(szBoxName, 5)
                        tab.attachVSeparator(szBoxName, "%sVSeparator2" %mapID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        tab.attachVBox(szBoxName, vBox3)
                        tab.setLayoutFlag(vBox3, "LAYOUT_SIZE_HEXPANDING")
                        tab.setLayoutFlag(vBox3, "LAYOUT_SIZE_VEXPANDING")

                        tab.attachVSeparator(szBoxName, "%sVSeparator3" %mapID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        ## create tittle , map CB , resetbutton in box 1
                        # Tittle
                        szBoxName = "%sTittleHBox1" %mapID
                        tab.attachHBox(vBox1, szBoxName)

                        tab.attachLabel(szBoxName, "%sTittleLabel1" %mapID, tittleBar1)

                        tab.attachHSeparator(vBox1, "%sHSeparatorTittle1" %mapID)
                        tab.attachHSeparator(vBox1, "%sHSeparatorTittle11" %mapID)

                        # map CB
                        szBoxName = "mapCB_%s" %mapID
                        tab.attachHBox(vBox1, szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_HCENTER")

                        szOptionDesc = getUText(valueLimits[baseTag][mapID]["description"])
                        szCallbackFunction = "Sto_Map_Selected"
                        szWidgetName = "selected_%s" %mapID
                        bBoxOn = copy.deepcopy(selection[baseTag][mapID]["selected"])
                        tab.attachCheckBox(szBoxName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName, bBoxOn)

                        # Reset Button
                        szBoxName = "%sTitlleHBox" %mapID
                        tab.attachHBox(vBox1, szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_HCENTER")

                        szOptionDesc = getUMenuText("TXT_RESET")
                        szCallbackFunction = "Sto_Reset_Option"
                        szWidgetName = "reset_%s_%s" %(baseTag, mapID)
                        tab.attachButton(szBoxName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

                        ## create tittles , list of options ,selections in box 2 et 3
                        # Tittles
                        szBoxName = "%sTittleHBox2" %mapID
                        tab.attachHBox(vBox2, szBoxName)

                        tab.attachLabel(szBoxName, "%sTittleLabel2" %mapID, tittleBar2)

                        tab.attachHSeparator(vBox2, "%sHSeparatorTittle2" %mapID)
                        tab.attachHSeparator(vBox2, "%sHSeparatorTittle22" %mapID)

                        szBoxName = "%sTittleHBox3" %mapID
                        tab.attachHBox(vBox3, szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_LEFT")

                        tab.attachLabel(szBoxName, "%sTittleLabel3" %mapID, tittleBar3)

                        tab.attachHSeparator(vBox3, "%sHSeparatorTittle3" %mapID)
                        tab.attachHSeparator(vBox3, "%sHSeparatorTittle33" %mapID)

                        # list of options
                        listOptionsLoop = sortKeys(selection, baseTag, mapID)
                        nbOptionsLoop = len(listOptionsLoop)

                        for iOption in range(nbOptionsLoop) :

                                optionID = listOptionsLoop[iOption]

                                #box1 : add option label
                                szNameHSupport = "%s%sDescSupport2" %(mapID,optionID)
                                tab.attachHBox(vBox2, szNameHSupport)
                                tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                                tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")

                                szLabelName = "%s%sOptionLabel" %(mapID,optionID)
                                labelTag = valueLimits[baseTag][mapID][optionID]["txttag"]
                                szLabelText = getUMenuText(labelTag)
                                tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                                if not bBoxOn : tab.setEnabled(szLabelName, False)

                                if iOption != (nbOptionsLoop-1) : tab.attachHSeparator(vBox2, "%s%sHSeparator2" %(mapID,optionID))

                                #box2 : add option selection

                                szNameHSupport = "%s%sDescSupport3" %(mapID,optionID)
                                tab.attachHBox(vBox3, szNameHSupport)
                                tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                                optionFunction = valueLimits[baseTag][mapID][optionID]["drawfunc"]
                                self.selectDrawFunction(optionFunction, (szNameHSupport, baseTag, mapID, optionID, bBoxOn))

                                if iOption != (nbOptionsLoop-1) : tab.attachHSeparator(vBox3, "%s%sHSeparator3" %(mapID,optionID))

                        # end map separator
                        tab.attachHSeparator("MapVBox", "%sHSeparator1" %mapID)
                        tab.attachHSeparator("MapVBox", "%sHSeparator11" %mapID)
                        tab.attachFixedSpacer("MapVBox", 10)
                        if iMap != (nbMaps-1) : tab.attachFixedSpacer("MapVBox", 10)

                # draw the language dropdown ,buttons resets , load save , exit buttons
                self.drawLowerPanel("MapVBoxParent", baseTag)

	def refreshMapOptionsTab(self):
		
		tab = self.pTabControl

                baseTag = "maps"
		for optionTag1 in selection[baseTag].keys() :

                        bBoxOn = copy.deepcopy(selection[baseTag][optionTag1]["selected"])

                        szWidgetName = "selected_%s" %optionTag1
                        tab.setValue(szWidgetName, bBoxOn)

                        for optionTag2 in selection[baseTag][optionTag1].keys() :

                                if optionTag2 == "selected" : continue
                                
                                szLabelName = "%s%sOptionLabel" %(optionTag1,optionTag2)
                                tab.setEnabled(szLabelName, bBoxOn)

                                optionFunction = valueLimits[baseTag][optionTag1][optionTag2]["drawfunc"]
                                self.selectRefreshFunction(optionFunction, (baseTag, optionTag1, optionTag2, bBoxOn))
		
	def checkEditBoxMapOptionsTab(self):
		
                baseTag = "maps"
		for optionTag1 in selection[baseTag].keys() :
                        for optionTag2 in selection[baseTag][optionTag1].keys() :
                        
                                if optionTag2 == "selected" : continue
                                
                                optionFunction = valueLimits[baseTag][optionTag1][optionTag2]["drawfunc"]
                                self.selectCheckEditBoxFunction(optionFunction, (baseTag, optionTag1, optionTag2))

	def drawTerrainOptionsTab(self):

                # draw the tab ,
		tab = self.pTabControl

                baseTag = "terrain"

		tab.attachVBox("TerrainForm", "TerrainVBoxParent")
		
		# Add terrain Options
		
		tab.attachPanel("TerrainVBoxParent", "TerrainPanelCenter")
		tab.setStyle("TerrainPanelCenter", "Panel_Tan15_Style")
		tab.setLayoutFlag("TerrainPanelCenter", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("TerrainPanelCenter", "LAYOUT_SIZE_VEXPANDING")
		
		tab.attachScrollPanel("TerrainPanelCenter", "TerrainPanel")
		tab.setLayoutFlag("TerrainPanel", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("TerrainPanel", "LAYOUT_SIZE_VEXPANDING")

		tab.attachVBox("TerrainPanel", "TerrainVBox")
		tab.setLayoutFlag("TerrainVBox", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("TerrainVBox", "LAYOUT_SIZE_VEXPANDING")

		# add a texture to egalize column ( can't find another way for the moment ... will check that later )
                tittleBar1 = "^_^"
                for terrainID in selection[baseTag].keys() :
                        while len(valueLimits[baseTag][terrainID]["description"])>len(tittleBar1) : tittleBar1 += "^_^"
                tittleBar1 = getUText(tittleBar1)

                tittleBar2 = "^_^"
                for terrainID in sortKeys(selection, baseTag) :
                        for optionID in sortKeys(selection, baseTag, terrainID) :
                                labelTag = valueLimits[baseTag][terrainID][optionID]["txttag"]
                                while len(getSMenuText(labelTag))>len(tittleBar2) : tittleBar2 += "^_^"
                if language == 0 : tittleBar2 = tittleBar2[0:-3]
                elif language == 1 : tittleBar2 = tittleBar2[0:-9]
                elif language == 2 : tittleBar2 = tittleBar2[0:-3]
                elif language == 3 : tittleBar2 = tittleBar2[0:-9]
                elif language == 4 : tittleBar2 = tittleBar2[0:-9]
                tittleBar2 = getUText(tittleBar2)

                tittleBar3 = "^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^"
                if language == 0 : tittleBar3 += "^_^"
                elif language == 1 : tittleBar3 += "^_^"
                elif language == 2 : tittleBar3 += "^_^^_^^_^^_^^_^^_^"
                elif language == 3 : tittleBar3 += "^_^^_^^_^^_^"
                elif language == 4 : tittleBar3 += "^_^^_^^_^^_^"
                tittleBar3 = getUText(tittleBar3)

                # draw each terrain box
		listTerrains = sortKeys(selection, baseTag)
                nbTerrains = len(listTerrains)

                bBoxOn = True

		for iTerrain in range(nbTerrains):

                        terrainID = listTerrains[iTerrain]
                        
                        tab.attachHSeparator("TerrainVBox", "%sHSeparator0" %terrainID)
                        tab.attachHSeparator("TerrainVBox", "%sHSeparator01" %terrainID)

                        #create Hbox with 3 Vbox in
                        szBoxName = "%sHBox" %terrainID
                        vBox1 = "%sVBox1" %terrainID
                        vBox2 = "%sVBox2" %terrainID
                        vBox3 = "%sVBox3" %terrainID

                        tab.attachHBox("TerrainVBox", szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_SIZE_HEXPANDING")

                        tab.attachVSeparator(szBoxName, "%sVSeparator0" %terrainID)

                        tab.attachVBox(szBoxName, vBox1)

                        tab.attachFixedSpacer(szBoxName, 5)
                        tab.attachVSeparator(szBoxName, "%sVSeparator1" %terrainID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        tab.attachVBox(szBoxName, vBox2)
                        tab.setLayoutFlag(vBox2, "LAYOUT_SIZE_VEXPANDING")

                        tab.attachFixedSpacer(szBoxName, 5)
                        tab.attachVSeparator(szBoxName, "%sVSeparator2" %terrainID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        tab.attachVBox(szBoxName, vBox3)
                        tab.setLayoutFlag(vBox3, "LAYOUT_SIZE_HEXPANDING")
                        tab.setLayoutFlag(vBox3, "LAYOUT_SIZE_VEXPANDING")

                        tab.attachVSeparator(szBoxName, "%sVSeparator3" %terrainID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        ## create tittle , resetbutton in box 1
                        # Tittle
                        szBoxName = "%sTittleHBox1" %terrainID
                        tab.attachHBox(vBox1, szBoxName)

                        tab.attachLabel(szBoxName, "%sTittleLabel1" %terrainID, tittleBar1)

                        tab.attachHSeparator(vBox1, "%sHSeparatorTittle1" %terrainID)
                        tab.attachHSeparator(vBox1, "%sHSeparatorTittle11" %terrainID)

                        # terrain tittle
                        szBoxName = "TerrainLabel_%s" %terrainID
                        tab.attachHBox(vBox1, szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_HCENTER")

                        szLabelDesc = getUText(valueLimits[baseTag][terrainID]["description"])
                        szWidgetName = "TerrainLabelTitlle_%s" %terrainID
                        tab.attachLabel(szBoxName, szWidgetName, szLabelDesc)

                        # Reset Button
                        if terrainID in ["terrains"] :
                                szBoxName = "%sTitlleHBox" %terrainID
                                tab.attachHBox(vBox1, szBoxName)
                                tab.setLayoutFlag(szBoxName, "LAYOUT_HCENTER")

                                szOptionDesc = getUMenuText("TXT_RESET")
                                szCallbackFunction = "Sto_Reset_Option"
                                szWidgetName = "reset_%s_%s" %(baseTag, terrainID)
                                tab.attachButton(szBoxName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

                        ## create tittles , list of options ,selections in box 2 et 3
                        # Tittles
                        szBoxName = "%sTittleHBox2" %terrainID
                        tab.attachHBox(vBox2, szBoxName)

                        tab.attachLabel(szBoxName, "%sTittleLabel2" %terrainID, tittleBar2)

                        tab.attachHSeparator(vBox2, "%sHSeparatorTittle2" %terrainID)
                        tab.attachHSeparator(vBox2, "%sHSeparatorTittle22" %terrainID)

                        szBoxName = "%sTittleHBox3" %terrainID
                        tab.attachHBox(vBox3, szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_LEFT")

                        tab.attachLabel(szBoxName, "%sTittleLabel3" %terrainID, tittleBar3)

                        tab.attachHSeparator(vBox3, "%sHSeparatorTittle3" %terrainID)
                        tab.attachHSeparator(vBox3, "%sHSeparatorTittle33" %terrainID)

                        listOptionsLoop = sortKeys(selection, baseTag, terrainID)
                        nbOptionsLoop = len(listOptionsLoop)

                        for iOption in range(nbOptionsLoop) :

                                optionID = listOptionsLoop[iOption]

                                #box1 : add option label
                                szNameHSupport = "%s%sDescSupport2" %(terrainID,optionID)
                                tab.attachHBox(vBox2, szNameHSupport)
                                tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                                tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")

                                szLabelName = "%s%sOptionLabel" %(terrainID,optionID)
                                labelTag = valueLimits[baseTag][terrainID][optionID]["txttag"]
                                szLabelText = getUMenuText(labelTag)
                                tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                                if iOption != (nbOptionsLoop-1) : tab.attachHSeparator(vBox2, "%s%sHSeparator2" %(terrainID,optionID))

                                #box2 : add option selection
                                szNameHSupport = "%s%sDescSupport3" %(terrainID,optionID)
                                tab.attachHBox(vBox3, szNameHSupport)
                                tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                                optionFunction = valueLimits[baseTag][terrainID][optionID]["drawfunc"]
                                self.selectDrawFunction(optionFunction, (szNameHSupport, baseTag, terrainID, optionID, bBoxOn))

                                if iOption != (nbOptionsLoop-1) : tab.attachHSeparator(vBox3, "%s%sHSeparator3" %(terrainID,optionID))

                        # end terrain separator
                        tab.attachHSeparator("TerrainVBox", "%sHSeparator1" %terrainID)
                        tab.attachHSeparator("TerrainVBox", "%sHSeparator11" %terrainID)
                        tab.attachFixedSpacer("TerrainVBox", 10)
                        if iTerrain != (nbTerrains-1) : tab.attachFixedSpacer("TerrainVBox", 10)

                # draw the language dropdown ,buttons resets , load save , exit buttons
                self.drawLowerPanel("TerrainVBoxParent", baseTag)

	def refreshTerrainOptionsTab(self):
		
		tab = self.pTabControl
                baseTag = "terrain"
                bBoxOn = True

		for optionTag1 in selection[baseTag].keys() :
                        for optionTag2 in selection[baseTag][optionTag1].keys() :

                                optionFunction = valueLimits[baseTag][optionTag1][optionTag2]["drawfunc"]
                                self.selectRefreshFunction(optionFunction, (baseTag, optionTag1, optionTag2, bBoxOn))

	def checkEditBoxTerrainOptionsTab(self):
		
                baseTag = "terrain"
		for optionTag1 in selection[baseTag].keys() :
                        for optionTag2 in selection[baseTag][optionTag1].keys() :
                        
                                optionFunction = valueLimits[baseTag][optionTag1][optionTag2]["drawfunc"]
                                self.selectCheckEditBoxFunction(optionFunction, (baseTag, optionTag1, optionTag2))

	def drawResourcesOptionsTab(self):

                baseTag = "resources"

                bEraseAll = copy.copy(selection["resources"]["resourcesgen"]["erasedefres"])

                bWater = True
                if selection[baseTag]["resourcesgen"]["waterpercent"] == "standard" : bWater = False

                bLand = True
                if selection[baseTag]["resourcesgen"]["landpercent"] == "standard" : bLand = False

                # draw the tab ,
		tab = self.pTabControl

		tab.attachVBox("ResourcesForm", "ResourceVBoxParent")
		
		# Add resources Options
		
		tab.attachPanel("ResourceVBoxParent", "ResourcePanelCenter")
		tab.setStyle("ResourcePanelCenter", "Panel_Tan15_Style")
		tab.setLayoutFlag("ResourcePanelCenter", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("ResourcePanelCenter", "LAYOUT_SIZE_VEXPANDING")
		
		tab.attachScrollPanel("ResourcePanelCenter", "ResourcePanel")
		tab.setLayoutFlag("ResourcePanel", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("ResourcePanel", "LAYOUT_SIZE_VEXPANDING")

		tab.attachVBox("ResourcePanel", "ResourceVBox")
		tab.setLayoutFlag("ResourceVBox", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("ResourceVBox", "LAYOUT_SIZE_VEXPANDING")

		# add a texture to egalize column ( can't find another way for the moment ... will check that later )
                tittleBar1 = "^_^"
                for resourceID in selection[baseTag].keys() :
                        while len(valueLimits[baseTag][resourceID]["description"])>len(tittleBar1) : tittleBar1 += "^_^"
                tittleBar1 = getUText(tittleBar1)

                tittleBar2 = "^_^"
                for resourceID in sortKeys(selection, baseTag) :
                        for optionID in sortKeys(selection, baseTag, resourceID) :
                                baseOptionID = str(optionID)
                                if "-" in optionID :
                                        baseOptionID, iIndex = splitTag(optionID)
                                labelTag = valueLimits[baseTag][resourceID][baseOptionID]["txttag"]
                                while len(getSMenuText(labelTag))>len(tittleBar2) : tittleBar2 += "^_^"
                if language == 0 : tittleBar2 = tittleBar2[0:-6]
                elif language == 1 : tittleBar2 = tittleBar2[0:-9]
                elif language == 2 : tittleBar2 = tittleBar2[0:-9]
                elif language == 3 : tittleBar2 = tittleBar2[0:-9]
                elif language == 4 : tittleBar2 = tittleBar2[0:-9]
                tittleBar2 = getUText(tittleBar2)

                tittleBar3 = "^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^"
                if language == 0 : tittleBar3 += "^_^^_^^_^^_^^_^^_^"
                elif language == 1 : tittleBar3 += "^_^^_^^_^^_^^_^^_^^_^"
                elif language == 2 : tittleBar3 += "^_^^_^^_^^_^^_^^_^"
                elif language == 3 : tittleBar3 += "^_^^_^^_^^_^"
                elif language == 4 : tittleBar3 += "^_^^_^^_^^_^"
                tittleBar3 = getUText(tittleBar3)

                # draw each resource box
		listResource = sortKeys(selection, baseTag)
                nbResource = len(listResource)
                listParents = getParents().keys()

		for iResource in range(nbResource):

                        resourceID = listResource[iResource]
                        
                        tab.attachHSeparator("ResourceVBox", "%sHSeparator0" %resourceID)
                        tab.attachHSeparator("ResourceVBox", "%sHSeparator01" %resourceID)

                        #create Hbox with 3 Vbox in
                        szBoxName = "%sHBox" %resourceID
                        vBox1 = "%sVBox1" %resourceID
                        vBox2 = "%sVBox2" %resourceID
                        vBox3 = "%sVBox3" %resourceID

                        tab.attachHBox("ResourceVBox", szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_SIZE_HEXPANDING")

                        tab.attachVSeparator(szBoxName, "%sVSeparator0" %resourceID)

                        tab.attachVBox(szBoxName, vBox1)

                        tab.attachFixedSpacer(szBoxName, 5)
                        tab.attachVSeparator(szBoxName, "%sVSeparator1" %resourceID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        tab.attachVBox(szBoxName, vBox2)
                        tab.setLayoutFlag(vBox2, "LAYOUT_SIZE_VEXPANDING")

                        tab.attachFixedSpacer(szBoxName, 5)
                        tab.attachVSeparator(szBoxName, "%sVSeparator2" %resourceID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        tab.attachVBox(szBoxName, vBox3)
                        tab.setLayoutFlag(vBox3, "LAYOUT_SIZE_HEXPANDING")
                        tab.setLayoutFlag(vBox3, "LAYOUT_SIZE_VEXPANDING")

                        tab.attachVSeparator(szBoxName, "%sVSeparator3" %resourceID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        ## create tittle , help button in box 1
                        # Tittle
                        szBoxName = "%sTittleHBox1" %resourceID
                        tab.attachHBox(vBox1, szBoxName)

                        tab.attachLabel(szBoxName, "%sTittleLabel1" %resourceID, tittleBar1)

                        tab.attachHSeparator(vBox1, "%sHSeparatorTittle1" %resourceID)
                        tab.attachHSeparator(vBox1, "%sHSeparatorTittle11" %resourceID)

                        # resource tittle
                        szBoxName = "ResourceLabel_%s" %resourceID
                        tab.attachHBox(vBox1, szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_HCENTER")

                        szLabelDesc = getUText(valueLimits[baseTag][resourceID]["description"])
                        szWidgetName = "ResourceLabelTitlle_%s" %resourceID
                        tab.attachLabel(szBoxName, szWidgetName, szLabelDesc)

                        # help Button
                        if resourceID in ["resourcesgen", "resourcesstart"] :
                                szBoxName = "%sTitlleHBox" %resourceID
                                tab.attachHBox(vBox1, szBoxName)
                                tab.setLayoutFlag(szBoxName, "LAYOUT_HCENTER")

                                szOptionDesc = getUMenuText("TXT_HELP")
                                szCallbackFunction = "Sto_Help_Option"
                                szWidgetName = "Help_%s_%s" %(baseTag, resourceID)
                                tab.attachButton(szBoxName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

                        ## create tittles , list of options ,selections in box 2 et 3
                        # Tittles
                        szBoxName = "%sTittleHBox2" %resourceID
                        tab.attachHBox(vBox2, szBoxName)

                        tab.attachLabel(szBoxName, "%sTittleLabel2" %resourceID, tittleBar2)

                        tab.attachHSeparator(vBox2, "%sHSeparatorTittle2" %resourceID)
                        tab.attachHSeparator(vBox2, "%sHSeparatorTittle22" %resourceID)

                        szBoxName = "%sTittleHBox3" %resourceID
                        tab.attachHBox(vBox3, szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_LEFT")

                        tab.attachLabel(szBoxName, "%sTittleLabel3" %resourceID, tittleBar3)

                        tab.attachHSeparator(vBox3, "%sHSeparatorTittle3" %resourceID)
                        tab.attachHSeparator(vBox3, "%sHSeparatorTittle33" %resourceID)

                        listOptionsLoop = sortKeys(selection, baseTag, resourceID)
                        nbOptionsLoop = len(listOptionsLoop)

                        # double the separator when adding a multiline option
                        bLastOptionMultiLine = False

                        for iOption in range(nbOptionsLoop) :

                                optionID = listOptionsLoop[iOption]

                                # blank functions drawn with other optionID
                                baseOptionID = str(optionID)
                                if "-" in optionID :
                                        baseOptionID, iIndex = splitTag(optionID)
                                        if not baseOptionID in listParents : continue

                                bBoxOn = True
                                if (optionID == "landprop") and (not bLand) and (not bEraseAll) : bBoxOn = False
                                if (optionID == "waterprop") and (not bWater) and (not bEraseAll) : bBoxOn = False
                                bLandOn = copy.copy(bLand)
                                bWaterOn = copy.copy(bWater)
                                if (optionID == "standardgen") and (bEraseAll) :
                                        bLandOn = False
                                        bWaterOn = False

                                optionFunction = valueLimits[baseTag][resourceID][baseOptionID]["drawfunc"]
                                
                                if (optionFunction == "SelectionSpecial") :
                                        nbElement = len(valueLimits[baseTag][resourceID][baseOptionID]["listitem"])
                                        nbPerLine = valueLimits[baseTag][resourceID][baseOptionID]["nbperline"]
                                        if nbElement > nbPerLine :
                                                bThisOptionMultiLine = True
                                        else :
                                                bThisOptionMultiLine = False
                                elif (optionFunction == "standardgen") :
                                        bThisOptionMultiLine = True
                                else :
                                        bThisOptionMultiLine = False

                                if (bThisOptionMultiLine) and (not bLastOptionMultiLine) and (iOption != 0) :
                                        tab.attachHSeparator(vBox2, "%s%sHSeparator4" %(resourceID,optionID))
                                        tab.attachHSeparator(vBox3, "%s%sHSeparator5" %(resourceID,optionID))

                                if optionFunction in listParents:
                                        self.selectDrawFunction(optionFunction)

                                elif optionFunction == "standardgen" :
                                        self.selectDrawFunction(optionFunction, (vBox2, vBox3, baseTag, resourceID, optionID, bLandOn, bWaterOn))

                                elif optionFunction == "SelectionSpecial" :
                                        self.selectDrawFunction(optionFunction, (vBox2, vBox3, baseTag, resourceID, optionID, bBoxOn))

                                else :
                                        #box1 : add option label
                                        szNameHSupport = "%s%sDescSupport2" %(resourceID,optionID)
                                        tab.attachHBox(vBox2, szNameHSupport)
                                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")

                                        szLabelName = "%s%sOptionLabel" %(resourceID,optionID)
                                        labelTag = valueLimits[baseTag][resourceID][baseOptionID]["txttag"]
                                        szLabelText = getUMenuText(labelTag)
                                        tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                                        tab.setEnabled(szLabelName, bBoxOn)

                                        #box2 : add option selection

                                        szNameHSupport = "%s%sDescSupport3" %(resourceID,optionID)
                                        tab.attachHBox(vBox3, szNameHSupport)
                                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                                        self.selectDrawFunction(optionFunction, (szNameHSupport, baseTag, resourceID, optionID, bBoxOn))

                                if (iOption < (nbOptionsLoop-1)) and (not optionFunction in listParents):
                                        tab.attachHSeparator(vBox2, "%s%sHSeparator2" %(resourceID,optionID))
                                        tab.attachHSeparator(vBox3, "%s%sHSeparator3" %(resourceID,optionID))
                                        if bThisOptionMultiLine :
                                                tab.attachHSeparator(vBox2, "%s%sHSeparator6" %(resourceID,optionID))
                                                tab.attachHSeparator(vBox3, "%s%sHSeparator7" %(resourceID,optionID))

                                bLastOptionMultiLine = bool(bThisOptionMultiLine)

                        # end resource separator
                        tab.attachHSeparator("ResourceVBox", "%sHSeparator1" %resourceID)
                        tab.attachHSeparator("ResourceVBox", "%sHSeparator11" %resourceID)
                        tab.attachFixedSpacer("ResourceVBox", 10)
                        if iResource != (nbResource-1) : tab.attachFixedSpacer("ResourceVBox", 10)

                # draw the language dropdown ,buttons resets , load save , exit buttons
                self.drawLowerPanel("ResourceVBoxParent", baseTag)

	def refreshResourcesOptionsTab(self):
		
		tab = self.pTabControl

                baseTag = "resources"

                bEraseAll = copy.copy(selection["resources"]["resourcesgen"]["erasedefres"])

                bWater = True
                if selection[baseTag]["resourcesgen"]["waterpercent"] == "standard" : bWater = False

                bLand = True
                if selection[baseTag]["resourcesgen"]["landpercent"] == "standard" : bLand = False

		for optionTag1 in selection[baseTag].keys() :

                        for optionTag2 in selection[baseTag][optionTag1].keys() :

                                bBoxOn = True
                                if (optionTag2 == "landprop") and (not bLand) and (not bEraseAll) : bBoxOn = False
                                if (optionTag2 == "waterprop") and (not bWater) and (not bEraseAll) : bBoxOn = False
                                bLandOn = copy.copy(bLand)
                                bWaterOn = copy.copy(bWater)
                                if (optionTag2 == "standardgen") and (bEraseAll) :
                                        bLandOn = False
                                        bWaterOn = False

                                baseOptionTag2 = str(optionTag2)
                                if "-" in optionTag2 :
                                        baseOptionTag2, iIndex = splitTag(optionTag2)

                                optionFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["drawfunc"]
                                
                                if ("-" in optionTag2) or (optionFunction == "SelectionSpecial") :
                                        self.selectRefreshFunction(optionFunction, (baseTag, optionTag1, optionTag2, bBoxOn))

                                elif optionFunction == "standardgen" :
                                        self.selectRefreshFunction(optionFunction, (baseTag, optionTag1, optionTag2, bLandOn, bWaterOn))

                                else :
                                        szLabelName = "%s%sOptionLabel" %(optionTag1, optionTag2)
                                        tab.setEnabled(szLabelName, bBoxOn)

                                        self.selectRefreshFunction(optionFunction, (baseTag, optionTag1, optionTag2, bBoxOn))

	def checkEditBoxResourcesOptionsTab(self):
		
		tab = self.pTabControl
                baseTag = "resources"

		for optionTag1 in selection[baseTag].keys() :
                        for optionTag2 in selection[baseTag][optionTag1].keys() :

                                baseOptionTag2 = str(optionTag2)
                                if "-" in optionTag2 :
                                        baseOptionTag2, iIndex = splitTag(optionTag2)

                                optionFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["drawfunc"]
                                self.selectCheckEditBoxFunction(optionFunction, (baseTag, optionTag1, optionTag2))

	def drawStartOptionsTab(self):

                baseTag = "startlocs"

                # draw the tab ,
		tab = self.pTabControl

		tab.attachVBox("StartForm", "StartVBoxParent")
		
		# Add Starts Options
		
		tab.attachPanel("StartVBoxParent", "StartPanelCenter")
		tab.setStyle("StartPanelCenter", "Panel_Tan15_Style")
		tab.setLayoutFlag("StartPanelCenter", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("StartPanelCenter", "LAYOUT_SIZE_VEXPANDING")
		
		tab.attachScrollPanel("StartPanelCenter", "StartPanel")
		tab.setLayoutFlag("StartPanel", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("StartPanel", "LAYOUT_SIZE_VEXPANDING")

		tab.attachVBox("StartPanel", "StartVBox")
		tab.setLayoutFlag("StartVBox", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("StartVBox", "LAYOUT_SIZE_VEXPANDING")

		# add a texture to egalize column ( can't find another way for the moment ... will check that later )
                tittleBar1 = "^_^"
                for StartID in selection[baseTag].keys() :
                        while len(valueLimits[baseTag][StartID]["description"])>len(tittleBar1) : tittleBar1 += "^_^"
                tittleBar1 = getUText(tittleBar1)

                tittleBar2 = "^_^"
                for StartID in sortKeys(selection, baseTag) :
                        for optionID in sortKeys(selection, baseTag, StartID) :
                                baseOptionID = str(optionID)
                                if "-" in optionID :
                                        baseOptionID, iIndex = splitTag(optionID)
                                labelTag = valueLimits[baseTag][StartID][baseOptionID]["txttag"]
                                while len(getSMenuText(labelTag))>len(tittleBar2) : tittleBar2 += "^_^"
                if language == 0 : tittleBar2 = tittleBar2[0:-6]
                elif language == 1 : tittleBar2 = tittleBar2[0:-9]
                elif language == 2 : tittleBar2 = tittleBar2[0:-9]
                elif language == 3 : tittleBar2 = tittleBar2[0:-9]
                elif language == 4 : tittleBar2 = tittleBar2[0:-9]
                tittleBar2 = getUText(tittleBar2)

                tittleBar3 = "^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^"
                if language == 0 : tittleBar3 += "^_^^_^^_^^_^^_^^_^"
                elif language == 1 : tittleBar3 += "^_^^_^^_^^_^^_^^_^^_^"
                elif language == 2 : tittleBar3 += "^_^^_^^_^^_^^_^^_^"
                elif language == 3 : tittleBar3 += "^_^^_^^_^^_^"
                elif language == 4 : tittleBar3 += "^_^^_^^_^^_^"
                tittleBar3 = getUText(tittleBar3)

                # draw each Start box
		listStart = sortKeys(selection, baseTag)
                nbStart = len(listStart)
                listParents = getParents().keys()

		for iStart in range(nbStart):

                        StartID = listStart[iStart]
                        
                        tab.attachHSeparator("StartVBox", "%sHSeparator0" %StartID)
                        tab.attachHSeparator("StartVBox", "%sHSeparator01" %StartID)

                        #create Hbox with 3 Vbox in
                        szBoxName = "%sHBox" %StartID
                        vBox1 = "%sVBox1" %StartID
                        vBox2 = "%sVBox2" %StartID
                        vBox3 = "%sVBox3" %StartID

                        tab.attachHBox("StartVBox", szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_SIZE_HEXPANDING")

                        tab.attachVSeparator(szBoxName, "%sVSeparator0" %StartID)

                        tab.attachVBox(szBoxName, vBox1)

                        tab.attachFixedSpacer(szBoxName, 5)
                        tab.attachVSeparator(szBoxName, "%sVSeparator1" %StartID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        tab.attachVBox(szBoxName, vBox2)
                        tab.setLayoutFlag(vBox2, "LAYOUT_SIZE_VEXPANDING")

                        tab.attachFixedSpacer(szBoxName, 5)
                        tab.attachVSeparator(szBoxName, "%sVSeparator2" %StartID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        tab.attachVBox(szBoxName, vBox3)
                        tab.setLayoutFlag(vBox3, "LAYOUT_SIZE_HEXPANDING")
                        tab.setLayoutFlag(vBox3, "LAYOUT_SIZE_VEXPANDING")

                        tab.attachVSeparator(szBoxName, "%sVSeparator3" %StartID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        ## create tittle , help button in box 1
                        # Tittle
                        szBoxName = "%sTittleHBox1" %StartID
                        tab.attachHBox(vBox1, szBoxName)

                        tab.attachLabel(szBoxName, "%sTittleLabel1" %StartID, tittleBar1)

                        tab.attachHSeparator(vBox1, "%sHSeparatorTittle1" %StartID)
                        tab.attachHSeparator(vBox1, "%sHSeparatorTittle11" %StartID)

                        # Start tittle
                        szBoxName = "StartLabel_%s" %StartID
                        tab.attachHBox(vBox1, szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_HCENTER")

                        szLabelDesc = getUText(valueLimits[baseTag][StartID]["description"])
                        szWidgetName = "StartLabelTitlle_%s" %StartID
                        tab.attachLabel(szBoxName, szWidgetName, szLabelDesc)

                        # help Button
                        if StartID in ["normalize"] :
                                szBoxName = "%sTitlleHBox" %StartID
                                tab.attachHBox(vBox1, szBoxName)
                                tab.setLayoutFlag(szBoxName, "LAYOUT_HCENTER")

                                szOptionDesc = getUMenuText("TXT_HELP")
                                szCallbackFunction = "Sto_Help_Option"
                                szWidgetName = "Help_%s_%s" %(baseTag, StartID)
                                tab.attachButton(szBoxName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

                        ## create tittles , list of options ,selections in box 2 et 3
                        # Tittles
                        szBoxName = "%sTittleHBox2" %StartID
                        tab.attachHBox(vBox2, szBoxName)

                        tab.attachLabel(szBoxName, "%sTittleLabel2" %StartID, tittleBar2)

                        tab.attachHSeparator(vBox2, "%sHSeparatorTittle2" %StartID)
                        tab.attachHSeparator(vBox2, "%sHSeparatorTittle22" %StartID)

                        szBoxName = "%sTittleHBox3" %StartID
                        tab.attachHBox(vBox3, szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_LEFT")

                        tab.attachLabel(szBoxName, "%sTittleLabel3" %StartID, tittleBar3)

                        tab.attachHSeparator(vBox3, "%sHSeparatorTittle3" %StartID)
                        tab.attachHSeparator(vBox3, "%sHSeparatorTittle33" %StartID)

                        listOptionsLoop = sortKeys(selection, baseTag, StartID)
                        nbOptionsLoop = len(listOptionsLoop)

                        # double the separator when adding a multiline option
                        bLastOptionMultiLine = False

                        for iOption in range(nbOptionsLoop) :

                                optionID = listOptionsLoop[iOption]

                                # blank functions drawn with other optionID
                                baseOptionID = str(optionID)
                                if "-" in optionID :
                                        baseOptionID, iIndex = splitTag(optionID)
                                        if not baseOptionID in listParents : continue

                                bBoxOn = True

                                optionFunction = valueLimits[baseTag][StartID][baseOptionID]["drawfunc"]
                                
                                if (optionFunction == "SelectionSpecial") :
                                        nbElement = len(valueLimits[baseTag][StartID][baseOptionID]["listitem"])
                                        nbPerLine = valueLimits[baseTag][StartID][baseOptionID]["nbperline"]
                                        if nbElement > nbPerLine :
                                                bThisOptionMultiLine = True
                                        else :
                                                bThisOptionMultiLine = False
                                else :
                                        bThisOptionMultiLine = False

                                if (bThisOptionMultiLine) and (not bLastOptionMultiLine) and (iOption != 0) :
                                        tab.attachHSeparator(vBox2, "%s%sHSeparator4" %(StartID,optionID))
                                        tab.attachHSeparator(vBox3, "%s%sHSeparator5" %(StartID,optionID))

                                if optionFunction in listParents:
                                        self.selectDrawFunction(optionFunction)

                                elif optionFunction == "SelectionSpecial" :
                                        self.selectDrawFunction(optionFunction, (vBox2, vBox3, baseTag, StartID, optionID, bBoxOn))

                                else :
                                        #box1 : add option label
                                        szNameHSupport = "%s%sDescSupport2" %(StartID,optionID)
                                        tab.attachHBox(vBox2, szNameHSupport)
                                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")

                                        szLabelName = "%s%sOptionLabel" %(StartID,optionID)
                                        labelTag = valueLimits[baseTag][StartID][baseOptionID]["txttag"]
                                        szLabelText = getUMenuText(labelTag)
                                        tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                                        tab.setEnabled(szLabelName, bBoxOn)

                                        #box2 : add option selection

                                        szNameHSupport = "%s%sDescSupport3" %(StartID,optionID)
                                        tab.attachHBox(vBox3, szNameHSupport)
                                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                                        self.selectDrawFunction(optionFunction, (szNameHSupport, baseTag, StartID, optionID, bBoxOn))

                                if (iOption < (nbOptionsLoop-1)) and (not optionFunction in listParents):
                                        tab.attachHSeparator(vBox2, "%s%sHSeparator2" %(StartID,optionID))
                                        tab.attachHSeparator(vBox3, "%s%sHSeparator3" %(StartID,optionID))
                                        if bThisOptionMultiLine :
                                                tab.attachHSeparator(vBox2, "%s%sHSeparator6" %(StartID,optionID))
                                                tab.attachHSeparator(vBox3, "%s%sHSeparator7" %(StartID,optionID))

                                bLastOptionMultiLine = bool(bThisOptionMultiLine)

                        # end Start separator
                        tab.attachHSeparator("StartVBox", "%sHSeparator1" %StartID)
                        tab.attachHSeparator("StartVBox", "%sHSeparator11" %StartID)
                        tab.attachFixedSpacer("StartVBox", 10)
                        if iStart != (nbStart-1) : tab.attachFixedSpacer("StartVBox", 10)

                # draw the language dropdown ,buttons resets , load save , exit buttons
                self.drawLowerPanel("StartVBoxParent", baseTag)

	def refreshStartOptionsTab(self):
		
		tab = self.pTabControl
                baseTag = "startlocs"

		for optionTag1 in selection[baseTag].keys() :

                        for optionTag2 in selection[baseTag][optionTag1].keys() :

                                bBoxOn = True

                                baseOptionTag2 = str(optionTag2)
                                if "-" in optionTag2 :
                                        baseOptionTag2, iIndex = splitTag(optionTag2)

                                optionFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["drawfunc"]
                                
                                if ("-" in optionTag2) or (optionFunction == "SelectionSpecial") :
                                        self.selectRefreshFunction(optionFunction, (baseTag, optionTag1, optionTag2, bBoxOn))

                                else :
                                        szLabelName = "%s%sOptionLabel" %(optionTag1, optionTag2)
                                        tab.setEnabled(szLabelName, bBoxOn)

                                        self.selectRefreshFunction(optionFunction, (baseTag, optionTag1, optionTag2, bBoxOn))

	def checkEditBoxStartOptionsTab(self):
		
		tab = self.pTabControl
                baseTag = "startlocs"

		for optionTag1 in selection[baseTag].keys() :
                        for optionTag2 in selection[baseTag][optionTag1].keys() :

                                baseOptionTag2 = str(optionTag2)
                                if "-" in optionTag2 :
                                        baseOptionTag2, iIndex = splitTag(optionTag2)

                                optionFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["drawfunc"]
                                self.selectCheckEditBoxFunction(optionFunction, (baseTag, optionTag1, optionTag2))

	def drawGameOptionsTab(self):

                baseTag = "game"

                # draw the tab ,
		tab = self.pTabControl

		tab.attachVBox("GameForm", "GameVBoxParent")
		
		# Add Games Options
		
		tab.attachPanel("GameVBoxParent", "GamePanelCenter")
		tab.setStyle("GamePanelCenter", "Panel_Tan15_Style")
		tab.setLayoutFlag("GamePanelCenter", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("GamePanelCenter", "LAYOUT_SIZE_VEXPANDING")
		
		tab.attachScrollPanel("GamePanelCenter", "GamePanel")
		tab.setLayoutFlag("GamePanel", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("GamePanel", "LAYOUT_SIZE_VEXPANDING")

		tab.attachVBox("GamePanel", "GameVBox")
		tab.setLayoutFlag("GameVBox", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("GameVBox", "LAYOUT_SIZE_VEXPANDING")

		if not canUseGameOptions :
                        tab.attachLabel("GameVBox", "noGameOptions", getUMenuText("TXT_NO_GAME_OPTIONS"))
                        tab.attachHBox("GameVBox", "GameVBoxH")
                        tab.setLayoutFlag("GameVBoxH", "LAYOUT_SIZE_HEXPANDING")
                        tab.setLayoutFlag("GameVBoxH", "LAYOUT_LEFT")
                        tab.attachLabel("GameVBoxH", "noGameOptions0", getUMenuText("TXT_NO_GAME_OPTIONS0"))

                        tab.attachHBox("GameVBox", "GameVBoxH2")
                        tab.setLayoutFlag("GameVBoxH2", "LAYOUT_SIZE_HEXPANDING")
                        tab.setLayoutFlag("GameVBoxH2", "LAYOUT_LEFT")
                        szOptionDesc = getUMenuText("TXT_OPEN_BROWSER")
                        szCallbackFunction = "Sto_Open_Browser"
                        szWidgetName = "noGameOptions1"
                        tab.attachButton("GameVBoxH2", szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)
                        return

		# add a texture to egalize column ( can't find another way for the moment ... will check that later )
                tittleBar1 = "^_^"
                for gameID in selection[baseTag].keys() :
                        while len(valueLimits[baseTag][gameID]["description"])>len(tittleBar1) : tittleBar1 += "^_^"
                tittleBar1 = getUText(tittleBar1)

                tittleBar2 = ""
                for gameID in sortKeys(selection, baseTag) :
                        for optionID in sortKeys(selection, baseTag, gameID) :
                                baseOptionID = str(optionID)
                                if "-" in optionID :
                                        baseOptionID, iIndex = splitTag(optionID)
                                labelTag = valueLimits[baseTag][gameID][baseOptionID]["txttag"]
                                while len(getSMenuText(labelTag))>len(tittleBar2) : tittleBar2 += "^_^"
                if language == 0 : tittleBar2 = tittleBar2[0:-9]
                elif language == 1 : tittleBar2 = tittleBar2[0:-9]
                elif language == 2 : tittleBar2 = tittleBar2[0:-9]
                elif language == 3 : tittleBar2 = tittleBar2[0:-9]
                elif language == 4 : tittleBar2 = tittleBar2[0:-9]
                tittleBar2 = getUText(tittleBar2)

                tittleBar3 = "^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^^_^"
                if language == 0 : tittleBar3 += "^_^^_^^_^"
                elif language == 1 : tittleBar3 += "^_^^_^^_^^_^^_^"
                elif language == 2 : tittleBar3 += "^_^^_^^_^^_^^_^"
                elif language == 3 : tittleBar3 += "^_^^_^^_^^_^"
                elif language == 4 : tittleBar3 += "^_^^_^^_^"
                tittleBar3 = getUText(tittleBar3)

                # draw each Game box
		listGame = sortKeys(selection, baseTag)
                nbGame = len(listGame)
                listParents = getParents().keys()

		for iGame in range(nbGame):

                        gameID = listGame[iGame]

                        if (gameID == "animals") and (XMLEntriesList["units"]["animland"] == []) : continue
                        
                        tab.attachHSeparator("GameVBox", "%sHSeparator0" %gameID)
                        tab.attachHSeparator("GameVBox", "%sHSeparator01" %gameID)

                        #create Hbox with 3 Vbox in
                        szBoxName = "%sHBox" %gameID
                        vBox1 = "%sVBox1" %gameID
                        vBox2 = "%sVBox2" %gameID
                        vBox3 = "%sVBox3" %gameID

                        tab.attachHBox("GameVBox", szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_SIZE_HEXPANDING")

                        tab.attachVSeparator(szBoxName, "%sVSeparator0" %gameID)

                        tab.attachVBox(szBoxName, vBox1)

                        tab.attachFixedSpacer(szBoxName, 5)
                        tab.attachVSeparator(szBoxName, "%sVSeparator1" %gameID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        tab.attachVBox(szBoxName, vBox2)
                        tab.setLayoutFlag(vBox2, "LAYOUT_SIZE_VEXPANDING")

                        tab.attachFixedSpacer(szBoxName, 5)
                        tab.attachVSeparator(szBoxName, "%sVSeparator2" %gameID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        tab.attachVBox(szBoxName, vBox3)
                        tab.setLayoutFlag(vBox3, "LAYOUT_SIZE_HEXPANDING")
                        tab.setLayoutFlag(vBox3, "LAYOUT_SIZE_VEXPANDING")

                        tab.attachVSeparator(szBoxName, "%sVSeparator3" %gameID)
                        tab.attachFixedSpacer(szBoxName, 5)

                        ## create tittle , help button in box 1
                        # Tittle
                        szBoxName = "%sTittleHBox1" %gameID
                        tab.attachHBox(vBox1, szBoxName)

                        tab.attachLabel(szBoxName, "%sTittleLabel1" %gameID, tittleBar1)

                        tab.attachHSeparator(vBox1, "%sHSeparatorTittle1" %gameID)
                        tab.attachHSeparator(vBox1, "%sHSeparatorTittle11" %gameID)

                        # Game tittle
                        szBoxName = "GameLabel_%s" %gameID
                        tab.attachHBox(vBox1, szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_HCENTER")

                        szLabelDesc = getUText(valueLimits[baseTag][gameID]["description"])
                        szWidgetName = "GameLabelTitlle_%s" %gameID
                        tab.attachLabel(szBoxName, szWidgetName, szLabelDesc)

                        # help Button
                        if gameID in ["barbcities", "animals", "techno", "startunit"] :
                                szBoxName = "%sTitlleHBox" %gameID
                                tab.attachHBox(vBox1, szBoxName)
                                tab.setLayoutFlag(szBoxName, "LAYOUT_HCENTER")

                                szOptionDesc = getUMenuText("TXT_HELP")
                                szCallbackFunction = "Sto_Help_Option"
                                szWidgetName = "Help_%s_%s" %(baseTag, gameID)
                                tab.attachButton(szBoxName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

                        ## create tittles , list of options ,selections in box 2 et 3
                        # Tittles
                        szBoxName = "%sTittleHBox2" %gameID
                        tab.attachHBox(vBox2, szBoxName)

                        tab.attachLabel(szBoxName, "%sTittleLabel2" %gameID, tittleBar2)

                        tab.attachHSeparator(vBox2, "%sHSeparatorTittle2" %gameID)
                        tab.attachHSeparator(vBox2, "%sHSeparatorTittle22" %gameID)

                        szBoxName = "%sTittleHBox3" %gameID
                        tab.attachHBox(vBox3, szBoxName)
                        tab.setLayoutFlag(szBoxName, "LAYOUT_LEFT")

                        tab.attachLabel(szBoxName, "%sTittleLabel3" %gameID, tittleBar3)

                        tab.attachHSeparator(vBox3, "%sHSeparatorTittle3" %gameID)
                        tab.attachHSeparator(vBox3, "%sHSeparatorTittle33" %gameID)

                        listOptionsLoop = sortKeys(selection, baseTag, gameID)
                        nbOptionsLoop = len(listOptionsLoop)

                        # double the separator when adding a multiline option
                        bLastOptionMultiLine = False

                        for iOption in range(nbOptionsLoop) :

                                optionID = listOptionsLoop[iOption]

                                # blank functions drawn with other optionID
                                baseOptionID = str(optionID)
                                if "-" in optionID :
                                        baseOptionID, iIndex = splitTag(optionID)
                                        if not baseOptionID in listParents : continue

                                if (optionID == "citybuilding") and (XMLEntriesList["buildingsbarb"] == []) :
                                        continue
                                elif (optionID == "defender") and (XMLEntriesList["units"]["barbdefender"] == []) and (XMLEntriesList["units"]["barbfight"] == []) :
                                        continue
                                elif (optionID == "technoreplace") and (XMLEntriesList["techsstartciv"] == []) :
                                        continue

                                optionFunction = valueLimits[baseTag][gameID][baseOptionID]["drawfunc"]
                                
                                bBoxOn = True

                                if optionID == "writelog" :
                                        if not bCanWriteLog : bBoxOn = False
                                        if not isGameMP : bBoxOn = False

                                if (optionFunction == "SelectionSpecial") :
                                        nbElement = len(valueLimits[baseTag][gameID][baseOptionID]["listitem"])
                                        nbPerLine = valueLimits[baseTag][gameID][baseOptionID]["nbperline"]
                                        if nbElement > nbPerLine :
                                                bThisOptionMultiLine = True
                                        else :
                                                bThisOptionMultiLine = False
                                else :
                                        bThisOptionMultiLine = False

                                if (bThisOptionMultiLine) and (not bLastOptionMultiLine) and (iOption != 0) :
                                        tab.attachHSeparator(vBox2, "%s%sHSeparator4" %(gameID,optionID))
                                        tab.attachHSeparator(vBox3, "%s%sHSeparator5" %(gameID,optionID))

                                if optionFunction in listParents:
                                        self.selectDrawFunction(optionFunction)

                                elif optionFunction == "SelectionSpecial" :
                                        self.selectDrawFunction(optionFunction, (vBox2, vBox3, baseTag, gameID, optionID, bBoxOn))

                                else :
                                        #box1 : add option label
                                        szNameHSupport = "%s%sDescSupport2" %(gameID,optionID)
                                        tab.attachHBox(vBox2, szNameHSupport)
                                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")

                                        szLabelName = "%s%sOptionLabel" %(gameID,optionID)
                                        labelTag = valueLimits[baseTag][gameID][baseOptionID]["txttag"]
                                        szLabelText = getUMenuText(labelTag)
                                        tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                                        tab.setEnabled(szLabelName, bBoxOn)

                                        #box2 : add option selection

                                        szNameHSupport = "%s%sDescSupport3" %(gameID,optionID)
                                        tab.attachHBox(vBox3, szNameHSupport)
                                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                                        self.selectDrawFunction(optionFunction, (szNameHSupport, baseTag, gameID, optionID, bBoxOn))

                                if (iOption < (nbOptionsLoop-1)) and (not optionFunction in listParents):
                                        tab.attachHSeparator(vBox2, "%s%sHSeparator2" %(gameID,optionID))
                                        tab.attachHSeparator(vBox3, "%s%sHSeparator3" %(gameID,optionID))
                                        if bThisOptionMultiLine :
                                                tab.attachHSeparator(vBox2, "%s%sHSeparator6" %(gameID,optionID))
                                                tab.attachHSeparator(vBox3, "%s%sHSeparator7" %(gameID,optionID))

                                bLastOptionMultiLine = bool(bThisOptionMultiLine)

                        # end Game separator
                        tab.attachHSeparator("GameVBox", "%sHSeparator1" %gameID)
                        tab.attachHSeparator("GameVBox", "%sHSeparator11" %gameID)
                        tab.attachFixedSpacer("GameVBox", 10)
                        if iGame != (nbGame-1) : tab.attachFixedSpacer("GameVBox", 10)

                # draw the language dropdown ,buttons resets , load save , exit buttons
                self.drawLowerPanel("GameVBoxParent", baseTag)

	def refreshGameOptionsTab(self):

		if not canUseGameOptions : return

                baseTag = "game"
		tab = self.pTabControl

		for optionTag1 in selection[baseTag].keys() :

                        if (optionTag1 == "animals") and (XMLEntriesList["units"]["animland"] == []) : continue
                        
                        for optionTag2 in selection[baseTag][optionTag1].keys() :

                                if (optionTag2 == "citybuilding") and (XMLEntriesList["buildingsbarb"] == []) :
                                        continue
                                elif (optionTag2 == "defender") and (XMLEntriesList["units"]["barbdefender"] == []) and (XMLEntriesList["units"]["barbfight"] == []) :
                                        continue
                                elif (optionTag2 == "technoreplace") and (XMLEntriesList["techsstartciv"] == []) :
                                        continue

                                bBoxOn = True

                                if optionTag2 == "writelog" :
                                        if not bCanWriteLog : bBoxOn = False
                                        if not isGameMP : bBoxOn = False

                                baseOptionTag2 = str(optionTag2)
                                if "-" in optionTag2 :
                                        baseOptionTag2, iIndex = splitTag(optionTag2)

                                optionFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["drawfunc"]
                                
                                if ("-" in optionTag2) or (optionFunction == "SelectionSpecial") :
                                        if "techquantity" in optionTag2 :
                                                tSel = selection[baseTag][optionTag1]["addtech-%d" %iIndex]
                                                if type(tSel) is types.ListType :
                                                        if len(tSel) == 1 :
                                                                if not tSel[0] in XMLEntriesList["techsrepeat"] :
                                                                        bBoxOn = False
                                                        else :
                                                                bBoxOn = False
                                                szLabelName = "%s%sOptionLabel" %(optionTag1, optionTag2)
                                                tab.setEnabled(szLabelName, bBoxOn)
                                        self.selectRefreshFunction(optionFunction, (baseTag, optionTag1, optionTag2, bBoxOn))

                                else :
                                        szLabelName = "%s%sOptionLabel" %(optionTag1, optionTag2)
                                        tab.setEnabled(szLabelName, bBoxOn)

                                        self.selectRefreshFunction(optionFunction, (baseTag, optionTag1, optionTag2, bBoxOn))

	def checkEditBoxGameOptionsTab(self):

		if not canUseGameOptions : return

                baseTag = "game"
		tab = self.pTabControl

		for optionTag1 in selection[baseTag].keys() :

                        if (optionTag1 == "animals") and (XMLEntriesList["units"]["animland"] == []) : continue
                        
                        for optionTag2 in selection[baseTag][optionTag1].keys() :

                                if (optionTag2 == "citybuilding") and (XMLEntriesList["buildingsbarb"] == []) :
                                        continue
                                elif (optionTag2 == "defender") and (XMLEntriesList["units"]["barbdefender"] == []) and (XMLEntriesList["units"]["barbfight"] == []) :
                                        continue
                                elif (optionTag2 == "technoreplace") and (XMLEntriesList["techsstartciv"] == []) :
                                        continue

                                baseOptionTag2 = str(optionTag2)
                                if "-" in optionTag2 :
                                        baseOptionTag2, iIndex = splitTag(optionTag2)

                                optionFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["drawfunc"]
                                self.selectCheckEditBoxFunction(optionFunction, (baseTag, optionTag1, optionTag2))

        #additionnal draw functions
        def drawStartUnit(self):
                global nbMultiBox

                baseTag = "game"
                gameID = "startunit"
                optionID = "startunitselect-%d" %nbMultiBox["startunitselect"]
                baseOptionID = "startunitselect"
                bBoxOn = True

                vBox2 = "%sVBox2" %gameID
                vBox3 = "%sVBox3" %gameID

                # draw the tab ,
		tab = self.pTabControl

                #units dropdowns
                listTag = ["peacedd", "landdd", "waterdd", "airdd", "otherdd", "national", "team", "world", "combatnone"]
                listTag += [item for item in XMLEntriesList["unitcombatlist"]]

                listLabelSelection = ["TXT_UNIT_PEACE", "TXT_UNIT_LAND", "TXT_UNIT_WATER", "TXT_UNIT_AIR", "TXT_UNIT_OTHER",
                                      "TXT_UNIT_NATIONAL", "TXT_UNIT_TEAM", "TXT_UNIT_WORLD", "TXT_UNIT_COMBATNONE"]
                listLabelSelection = [getUMenuText(item) for item in listLabelSelection]
                listLabelSelection += [getUText(XMLDescriptions[item]) for item in XMLEntriesList["unitcombatlist"]]

                nbDD = 0

                for unitTag in listTag :
                        if XMLEntriesList["units"][unitTag] == [] : continue

                        if nbDD % 2 == 0 :
                
                                #box1 : add option label
                                szNameHSupport = "%s%sDescSupport2%d" %(gameID, optionID, nbDD)
                                tab.attachHBox(vBox2, szNameHSupport)
                                tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                                tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")

                                szLabelName = "%s%sOptionLabel%d" %(gameID, optionID, nbDD)
                                if nbDD == 0 : szLabelText = getUMenuText(valueLimits[baseTag][gameID][baseOptionID]["txttag"])
                                else : szLabelText = getUMenuText("TXT_DUM")
                                tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                                tab.setEnabled(szLabelName, bBoxOn)

                                #box2 : add option selection

                                szNameHSupport = "%s%sDescSupport3%d" %(gameID, optionID, nbDD)
                                tab.attachHBox(vBox3, szNameHSupport)
                                tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                                tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                                tab.attachHSeparator(vBox2, "%s%s%dHSeparator20" %(gameID, optionID, nbDD))
                                tab.attachHSeparator(vBox3, "%s%s%dHSeparator30" %(gameID, optionID, nbDD))

                        #dropdowns
                        szDropdownDesc = "%s*UnitDropdownDesc_%d" %(unitTag, nbMultiBox["startunitselect"])

                        listDropdownElements = [listLabelSelection[listTag.index(unitTag)]]
                        listDropdownElements += [getUText(XMLDescriptions[elementType]) for elementType in XMLEntriesList["units"][unitTag]]
                        aszDropdownElements = tuple(listDropdownElements)

                        szCallbackFunction = "Sto_Select_Unit_Select"
                        szWidgetName = "%s*UnitDropdown_%s_%s_%s" %(unitTag, baseTag, gameID, optionID)

                        idSel = selection[baseTag][gameID][optionID]
                        if len(idSel) == 1 :
                                elementType = idSel[0]
                                if elementType in XMLEntriesList["units"][unitTag] : iInitialSelection = XMLEntriesList["units"][unitTag].index(elementType) + 1
                                else : iInitialSelection = 0
                        else :
                                iInitialSelection = 0

                        tab.attachDropDown(szNameHSupport, szWidgetName, szDropdownDesc, aszDropdownElements, self.callbackIFace, szCallbackFunction, szWidgetName, iInitialSelection)
                        tab.setLayoutFlag(szWidgetName, "LAYOUT_LEFT")
                        tab.setEnabled(szWidgetName, bBoxOn)

                        nbDD += 1

                listChildrens = getChildrens(baseTag, gameID, "startunitselect")

                for i in range(len(listChildrens)) :
                        childTag = listChildrens[i]
                        optionID = "%s-%d" %(childTag, nbMultiBox["startunitselect"])

                        if i != 0 :
                                tab.attachHSeparator(vBox2, "%s%sHSeparator20" %(gameID, optionID))
                                tab.attachHSeparator(vBox3, "%s%sHSeparator30" %(gameID, optionID))

                        optionFunction = valueLimits[baseTag][gameID][childTag]["drawfunc"]

                        #box1 : add option label
                        szNameHSupport = "%s%sDescSupport2" %(gameID, optionID)
                        tab.attachHBox(vBox2, szNameHSupport)
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")

                        labelTag = valueLimits[baseTag][gameID][childTag]["txttag"]
                        szLabelName = "%s%sOptionLabel" %(gameID, optionID)
                        szLabelText = getUMenuText(labelTag)
                        tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                        tab.setEnabled(szLabelName, bBoxOn)

                        #box2 : add option selection

                        szNameHSupport = "%s%sDescSupport3" %(gameID, optionID)
                        tab.attachHBox(vBox3, szNameHSupport)
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                        self.selectDrawFunction(optionFunction, (szNameHSupport, baseTag, gameID, optionID, bBoxOn))

                for i in range(2) :
                        tab.attachHSeparator(vBox2, "%s%sHSeparator20%d" %(gameID, optionID, i))
                        tab.attachHSeparator(vBox3, "%s%sHSeparator30%d" %(gameID, optionID, i))

                nbMultiBox["startunitselect"] += 1

        def drawAddTech(self):
                global nbMultiBox

                baseTag = "game"
                gameID = "techno"
                optionID = "addtech-%d" %nbMultiBox["addtech"]
                baseOptionID = "addtech"
                bBoxOn = True

                vBox2 = "%sVBox2" %gameID
                vBox3 = "%sVBox3" %gameID

                # draw the tab ,
		tab = self.pTabControl

                #box1 : add option label
                szNameHSupport = "%s%sDescSupport2" %(gameID,optionID)
                tab.attachHBox(vBox2, szNameHSupport)
                tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")

                szLabelName = "%s%sOptionLabel" %(gameID,optionID)
                szLabelText = getUMenuText(valueLimits[baseTag][gameID][baseOptionID]["txttag"])
                tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                tab.setEnabled(szLabelName, bBoxOn)

                #box2 : add option selection

                szNameHSupport = "%s%sDescSupport3" %(gameID,optionID)
                tab.attachHBox(vBox3, szNameHSupport)
                tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                #tech dropdown
		szDropdownDesc = "TechDropdownDesc_%d" %nbMultiBox["addtech"]

		listDropdownElements = [getUMenuText("TXT_GAME_TECHNOS"), getUMenuText("TXT_SAME_FOR_PLAYERS"), getUMenuText("TXT_DIFFERENT_FOR_PLAYERS")]
		listDropdownElements += [getUText(XMLDescriptions[elementType]) for elementType in XMLEntriesList["techslist"]]
		aszDropdownElements = tuple(listDropdownElements)

		szCallbackFunction = "Sto_Select_Tech_Select"
		szWidgetName = "TechDropdown_%d" %nbMultiBox["addtech"]

		idSel = selection[baseTag][gameID][optionID]
		bQuantityOn = False
		if idSel == "alltechsame" :
                        iInitialSelection = 1
                        bQuantityOn = True
		elif idSel == "alltechdiff" :
                        iInitialSelection = 2
                        bQuantityOn = True
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        iInitialSelection = XMLEntriesList["techslist"].index(elementType) + 3
                        if elementType in XMLEntriesList["techsrepeat"] : bQuantityOn = True
                else :
                        iInitialSelection = 0

		tab.attachDropDown(szNameHSupport, szWidgetName, szDropdownDesc, aszDropdownElements, self.callbackIFace, szCallbackFunction, szWidgetName, iInitialSelection)
		tab.setLayoutFlag(szWidgetName, "LAYOUT_LEFT")
                tab.setEnabled(szWidgetName, bBoxOn)

                listChildrens = getChildrens(baseTag, gameID, baseOptionID)

                for i in range(len(listChildrens)) :
                        childTag = listChildrens[i]
                        optionID = "%s-%d" %(childTag, nbMultiBox[baseOptionID])

                        tab.attachHSeparator(vBox2, "%s%sHSeparator20" %(gameID, optionID))
                        tab.attachHSeparator(vBox3, "%s%sHSeparator30" %(gameID, optionID))

                        optionFunction = valueLimits[baseTag][gameID][childTag]["drawfunc"]

                        if childTag == "techquantity" :
                                bOptionOn = bBoxOn and bQuantityOn
                        else :
                                bOptionOn = bBoxOn

                        #box1 : add option label
                        szNameHSupport = "%s%sDescSupport2" %(gameID, optionID)
                        tab.attachHBox(vBox2, szNameHSupport)
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")

                        labelTag = valueLimits[baseTag][gameID][childTag]["txttag"]
                        szLabelName = "%s%sOptionLabel" %(gameID, optionID)
                        szLabelText = getUMenuText(labelTag)
                        tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                        tab.setEnabled(szLabelName, bOptionOn)

                        #box2 : add option selection

                        szNameHSupport = "%s%sDescSupport3" %(gameID, optionID)
                        tab.attachHBox(vBox3, szNameHSupport)
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                        self.selectDrawFunction(optionFunction, (szNameHSupport, baseTag, gameID, optionID, bOptionOn))

                for i in range(2) :
                        tab.attachHSeparator(vBox2, "%s%sHSeparator20%d" %(gameID, optionID, i))
                        tab.attachHSeparator(vBox3, "%s%sHSeparator30%d" %(gameID, optionID, i))

                nbMultiBox["addtech"] += 1

        def drawBoxOptionDefender(self, argsList):
                boxOptionName, baseTag, optionTag1, optionTag2, bEnable = argsList

		tab = self.pTabControl
		szCallbackFunction = valueLimits[baseTag][optionTag1][optionTag2]["cbfunc"]

		if XMLEntriesList["units"]["barbdefender"] != [] :

                        szDropdownDesc = "gameCityDefenderDropdownDesc"

                        listDropdownElements = [getUMenuText("TXT_GAME_CITYDEF")]
                        listDropdownElements += [getUText(XMLDescriptions[elementType]) for elementType in XMLEntriesList["units"]["barbdefender"]]
                        aszDropdownElements = tuple(listDropdownElements)

                        szWidgetName = "gameCityDef_%s_%s_%s" %(baseTag, optionTag1, optionTag2)

                        idSel = selection[baseTag][optionTag1][optionTag2]
                        if idSel == [] :
                                iInitialSelection = 0
                        elif (not idSel[0] in XMLEntriesList["units"]["barbdefender"]) :
                                iInitialSelection = 0
                        else :
                                iInitialSelection = XMLEntriesList["units"]["barbdefender"].index(idSel[0]) + 1

                        tab.attachDropDown(boxOptionName, szWidgetName, szDropdownDesc, aszDropdownElements, self.callbackIFace, szCallbackFunction, szWidgetName, iInitialSelection)
                        tab.setLayoutFlag(szWidgetName, "LAYOUT_LEFT")
                        tab.setEnabled(szWidgetName, bEnable)

		if XMLEntriesList["units"]["barbfight"] != [] :

                        szDropdownDesc = "gameCityFightDropdownDesc"

                        listDropdownElements = [getUMenuText("TXT_GAME_CITYFIGHT")]
                        listDropdownElements += [getUText(XMLDescriptions[elementType]) for elementType in XMLEntriesList["units"]["barbfight"]]
                        aszDropdownElements = tuple(listDropdownElements)

                        szWidgetName = "gameCityFight_%s_%s_%s" %(baseTag, optionTag1, optionTag2)

                        idSel = selection[baseTag][optionTag1][optionTag2]
                        if idSel == [] :
                                iInitialSelection = 0
                        elif (not idSel[0] in XMLEntriesList["units"]["barbfight"]) :
                                iInitialSelection = 0
                        else :
                                iInitialSelection = XMLEntriesList["units"]["barbfight"].index(idSel[0]) + 1

                        tab.attachDropDown(boxOptionName, szWidgetName, szDropdownDesc, aszDropdownElements, self.callbackIFace, szCallbackFunction, szWidgetName, iInitialSelection)
                        tab.setLayoutFlag(szWidgetName, "LAYOUT_LEFT")
                        tab.setEnabled(szWidgetName, bEnable)

        def drawStartResources(self):
                global nbMultiBox

                baseTag = "resources"
                resourceID = "resourcesstart"
                baseOptionID = "startresselect"
                optionID = "startresselect-%d" %nbMultiBox[baseOptionID]
                bBoxOn = True

                vBox2 = "%sVBox2" %resourceID
                vBox3 = "%sVBox3" %resourceID

                # draw the tab ,
		tab = self.pTabControl

                #box1 : add option label
                szNameHSupport = "%s%sDescSupport2" %(resourceID,optionID)
                tab.attachHBox(vBox2, szNameHSupport)
                tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")

                szLabelName = "%s%sOptionLabel" %(resourceID,optionID)
                szLabelText = getUMenuText(valueLimits[baseTag][resourceID][baseOptionID]["txttag"])
                tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                tab.setEnabled(szLabelName, bBoxOn)

                #box2 : add option selection

                szNameHSupport = "%s%sDescSupport3" %(resourceID,optionID)
                tab.attachHBox(vBox3, szNameHSupport)
                tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                #create 3 resources dropdown
                #strat dropdown
		szDropdownDesc = "StratStartDropdownDesc_%d" %nbMultiBox[baseOptionID]

		listDropdownElements = [getUMenuText("TXT_ALL_STRAT"), getUMenuText("TXT_SAME_FOR_PLAYERS"), getUMenuText("TXT_DIFFERENT_FOR_PLAYERS")]
		listDropdownElements += [getUText(XMLDescriptions[elementType]) for elementType in XMLEntriesList["strategic"]]
		aszDropdownElements = tuple(listDropdownElements)

		szCallbackFunction = "Sto_Select_StartResource"
		szWidgetName = "StratStartDropdown_%d" %nbMultiBox[baseOptionID]

		idSel = selection[baseTag][resourceID][optionID]
		if idSel == "allstratsame" :
                        iInitialSelection = 1
		elif idSel == "allstratdiff" :
                        iInitialSelection = 2
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        if elementType in XMLEntriesList["strategic"] : iInitialSelection = XMLEntriesList["strategic"].index(elementType) + 3
                        else : iInitialSelection = 0
                else :
                        iInitialSelection = 0

		tab.attachDropDown(szNameHSupport, szWidgetName, szDropdownDesc, aszDropdownElements, self.callbackIFace, szCallbackFunction, szWidgetName, iInitialSelection)
		tab.setLayoutFlag(szWidgetName, "LAYOUT_LEFT")
                tab.setEnabled(szWidgetName, bBoxOn)

                #health dropdown
		szDropdownDesc = "HealthStartDropdownDesc_%d" %nbMultiBox[baseOptionID]

		listDropdownElements = [getUMenuText("TXT_ALL_HEALTH"), getUMenuText("TXT_SAME_FOR_PLAYERS"), getUMenuText("TXT_DIFFERENT_FOR_PLAYERS")]
		listDropdownElements += [getUText(XMLDescriptions[elementType]) for elementType in XMLEntriesList["health"]]
		aszDropdownElements = tuple(listDropdownElements)

		szWidgetName = "HealthStartDropdown_%d" %nbMultiBox[baseOptionID]

		if idSel == "allhealthsame" :
                        iInitialSelection = 1
		elif idSel == "allhealthdiff" :
                        iInitialSelection = 2
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        if elementType in XMLEntriesList["health"] : iInitialSelection = XMLEntriesList["health"].index(elementType) + 3
                        else : iInitialSelection = 0
                else :
                        iInitialSelection = 0

		tab.attachDropDown(szNameHSupport, szWidgetName, szDropdownDesc, aszDropdownElements, self.callbackIFace, szCallbackFunction, szWidgetName, iInitialSelection)
		tab.setLayoutFlag(szWidgetName, "LAYOUT_LEFT")
                tab.setEnabled(szWidgetName, bBoxOn)

                #happiness dropdown
		szDropdownDesc = "HappStartDropdownDesc_%d" %nbMultiBox[baseOptionID]

		listDropdownElements = [getUMenuText("TXT_ALL_HAPP"), getUMenuText("TXT_SAME_FOR_PLAYERS"), getUMenuText("TXT_DIFFERENT_FOR_PLAYERS")]
		listDropdownElements += [getUText(XMLDescriptions[elementType]) for elementType in XMLEntriesList["happiness"]]
		aszDropdownElements = tuple(listDropdownElements)

		szWidgetName = "HappStartDropdown_%d" %nbMultiBox[baseOptionID]

		if idSel == "allhappsame" :
                        iInitialSelection = 1
		elif idSel == "allhappdiff" :
                        iInitialSelection = 2
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        if elementType in XMLEntriesList["happiness"] : iInitialSelection = XMLEntriesList["happiness"].index(elementType) + 3
                        else : iInitialSelection = 0
                else :
                        iInitialSelection = 0

		tab.attachDropDown(szNameHSupport, szWidgetName, szDropdownDesc, aszDropdownElements, self.callbackIFace, szCallbackFunction, szWidgetName, iInitialSelection)
		tab.setLayoutFlag(szWidgetName, "LAYOUT_LEFT")
                tab.setEnabled(szWidgetName, bBoxOn)

                listChildrens = getChildrens(baseTag, resourceID, baseOptionID)

                for i in range(len(listChildrens)) :
                        childTag = listChildrens[i]
                        optionID = "%s-%d" %(childTag, nbMultiBox[baseOptionID])

                        tab.attachHSeparator(vBox2, "%s%sHSeparator20" %(resourceID, optionID))
                        tab.attachHSeparator(vBox3, "%s%sHSeparator30" %(resourceID, optionID))

                        #box1 : add option label
                        szNameHSupport = "%s%sDescSupport2" %(resourceID, optionID)
                        tab.attachHBox(vBox2, szNameHSupport)
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")

                        labelTag = valueLimits[baseTag][resourceID][childTag]["txttag"]
                        szLabelName = "%s%sOptionLabel" %(resourceID, optionID)
                        szLabelText = getUMenuText(labelTag)
                        tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                        tab.setEnabled(szLabelName, bBoxOn)

                        #box2 : add option selection

                        szNameHSupport = "%s%sDescSupport3" %(resourceID, optionID)
                        tab.attachHBox(vBox3, szNameHSupport)
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                        optionFunction = valueLimits[baseTag][resourceID][childTag]["drawfunc"]

                        self.selectDrawFunction(optionFunction, (szNameHSupport, baseTag, resourceID, optionID, bBoxOn))

                for i in range(2) :
                        tab.attachHSeparator(vBox2, "%s%sHSeparator20%d" %(resourceID, optionID, i))
                        tab.attachHSeparator(vBox3, "%s%sHSeparator30%d" %(resourceID, optionID, i))

                nbMultiBox[baseOptionID] += 1

        def drawMultiplyResources(self):
                global nbMultiBox

                baseTag = "resources"
                resourceID = "resourcesgen"
                baseOptionID = "resmultiply"
                optionID = "resmultiply-%d" %nbMultiBox["resmultiply"]
                bBoxOn = True

                vBox2 = "%sVBox2" %resourceID
                vBox3 = "%sVBox3" %resourceID

                # draw the tab ,
		tab = self.pTabControl

                #box1 : add option label
                szNameHSupport = "%s%sDescSupport2" %(resourceID,optionID)
                tab.attachHBox(vBox2, szNameHSupport)
                tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")

                szLabelName = "%s%sOptionLabel" %(resourceID,optionID)
                szLabelText = getUMenuText(valueLimits[baseTag][resourceID][baseOptionID]["txttag"])
                tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                tab.setEnabled(szLabelName, bBoxOn)

                #box2 : add option selection

                szNameHSupport = "%s%sDescSupport3" %(resourceID,optionID)
                tab.attachHBox(vBox3, szNameHSupport)
                tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                #create 3 resources dropdown
                #strat dropdown
		szDropdownDesc = "StratDropdownDesc_%d" %nbMultiBox["resmultiply"]

		listDropdownElements = [getUMenuText("TXT_ALL_STRAT"), getUMenuText("TXT_RES_ALL")]
		listDropdownElements += [getUText(XMLDescriptions[elementType]) for elementType in XMLEntriesList["strategic"]]
		aszDropdownElements = tuple(listDropdownElements)

		szCallbackFunction = "Sto_Select_ResMultiply"
		szWidgetName = "StratDropdown_%d" %nbMultiBox["resmultiply"]

		idSel = selection[baseTag][resourceID][optionID][0]
		nbSel = selection[baseTag][resourceID][optionID][1]
		if idSel == "allstrat" :
                        iInitialSelection = 1
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        if elementType in XMLEntriesList["strategic"] : iInitialSelection = XMLEntriesList["strategic"].index(elementType) + 2
                        else : iInitialSelection = 0
                else :
                        iInitialSelection = 0

		tab.attachDropDown(szNameHSupport, szWidgetName, szDropdownDesc, aszDropdownElements, self.callbackIFace, szCallbackFunction, szWidgetName, iInitialSelection)
		tab.setLayoutFlag(szWidgetName, "LAYOUT_LEFT")
                tab.setEnabled(szWidgetName, bBoxOn)

                #health dropdown
		szDropdownDesc = "HealthDropdownDesc_%d" %nbMultiBox["resmultiply"]

		listDropdownElements = [getUMenuText("TXT_ALL_HEALTH"), getUMenuText("TXT_RES_ALL")]
		listDropdownElements += [getUText(XMLDescriptions[elementType]) for elementType in XMLEntriesList["health"]]
		aszDropdownElements = tuple(listDropdownElements)

		szWidgetName = "HealthDropdown_%d" %nbMultiBox["resmultiply"]

		if idSel == "allhealth" :
                        iInitialSelection = 1
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        if elementType in XMLEntriesList["health"] : iInitialSelection = XMLEntriesList["health"].index(elementType) + 2
                        else : iInitialSelection = 0
                else :
                        iInitialSelection = 0

		tab.attachDropDown(szNameHSupport, szWidgetName, szDropdownDesc, aszDropdownElements, self.callbackIFace, szCallbackFunction, szWidgetName, iInitialSelection)
		tab.setLayoutFlag(szWidgetName, "LAYOUT_LEFT")
                tab.setEnabled(szWidgetName, bBoxOn)

                #happiness dropdown
		szDropdownDesc = "HappDropdownDesc_%d" %nbMultiBox["resmultiply"]

		listDropdownElements = [getUMenuText("TXT_ALL_HAPP"), getUMenuText("TXT_RES_ALL")]
		listDropdownElements += [getUText(XMLDescriptions[elementType]) for elementType in XMLEntriesList["happiness"]]
		aszDropdownElements = tuple(listDropdownElements)

		szWidgetName = "HappDropdown_%d" %nbMultiBox["resmultiply"]

		if idSel == "allhapp" :
                        iInitialSelection = 1
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        if elementType in XMLEntriesList["happiness"] : iInitialSelection = XMLEntriesList["happiness"].index(elementType) + 2
                        else : iInitialSelection = 0
                else :
                        iInitialSelection = 0

		tab.attachDropDown(szNameHSupport, szWidgetName, szDropdownDesc, aszDropdownElements, self.callbackIFace, szCallbackFunction, szWidgetName, iInitialSelection)
		tab.setLayoutFlag(szWidgetName, "LAYOUT_LEFT")
                tab.setEnabled(szWidgetName, bBoxOn)

                #by label
                szLabelName = "%s%sByLabel" %(resourceID,optionID)
                szLabelText = getUMenuText("TXT_BY")
                tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                tab.setEnabled(szLabelName, bBoxOn)

                #edit box
                szEditBoxDesc = getUText(str(nbSel))
                szWidgetName = "EDValue_%s_%s_%s" %(baseTag, resourceID, optionID)
		tab.attachEdit(szNameHSupport, szWidgetName, szEditBoxDesc, self.callbackIFace, "Sto_DummyCallback", szWidgetName)
		tab.setEnabled(szWidgetName, bBoxOn)

                tab.attachHSeparator(vBox2, "%s%sHSeparator20" %(resourceID,optionID))
                tab.attachHSeparator(vBox3, "%s%sHSeparator30" %(resourceID,optionID))

                nbMultiBox["resmultiply"] += 1

        def drawBoxOptionSelectionSpecialDefaultResources(self, argsList):
                vBoxLeft, vBoxRight, baseTag, optionTag1, optionTag2, bLandEnable, bWaterEnable = argsList

		tab = self.pTabControl
                szCallbackFunction = valueLimits[baseTag][optionTag1][optionTag2]["cbfunc"]
                elementsList = valueLimits[baseTag][optionTag1][optionTag2]["listitem"]
                labelTxtTag = valueLimits[baseTag][optionTag1][optionTag2]["txttag"]
                nbPerLine = valueLimits[baseTag][optionTag1][optionTag2]["nbperline"]

                nbElements = len(elementsList)
                nbLine = nbElements/nbPerLine
                if nbElements % nbPerLine != 0 : nbLine += 1

                nbLine = max(nbLine, 4)

                for i in range(nbLine) :
                        #box1 : add option label
                        szNameHSupport = "%s%s%dDescSupport2" %(optionTag1, optionTag2, i)
                        tab.attachHBox(vBoxLeft, szNameHSupport)
                        if not i in [1,2,3] : tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                        if i==0 : tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")
                        else : tab.setLayoutFlag(szNameHSupport, "LAYOUT_HCENTER")

                        if i in [1,2,3] :
                                # buttons
                                if i == 1 :
                                        szOptionDesc = getUMenuText("TXT_ALL_STRAT")
                                        szWidgetName = "AllStrat_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                                elif i == 2 :
                                        szOptionDesc = getUMenuText("TXT_ALL_HEALTH")
                                        szWidgetName = "AllHealth_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                                else :
                                        szOptionDesc = getUMenuText("TXT_ALL_HAPP")
                                        szWidgetName = "AllHapp_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                                szCallbackFunctionbutton = "Sto_Standard_For_All_Buttons"
                                tab.attachButton(szNameHSupport, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunctionbutton, szWidgetName)
                                tab.setEnabled(szWidgetName, bLandEnable or bWaterEnable)
                        else :
                                # labels
                                if i==0 : szLabelText = getUMenuText(labelTxtTag)
                                elif i>3 : szLabelText = getUMenuText("TXT_DUM")
                                szLabelName = "%s%s%dOptionLabel" %(optionTag1, optionTag2, i)
                                tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                                tab.setEnabled(szLabelName, bLandEnable or bWaterEnable)

                        #box2 : add option selection
                        szNameHSupport = "%s%s%dDescSupport3" %(optionTag1, optionTag2, i)
                        tab.attachHBox(vBoxRight, szNameHSupport)
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                        for j in range(nbPerLine) :
                                indexElement = i*nbPerLine + j
                                if indexElement >= nbElements :
                                        if j == 0 :
                                                #dum label
                                                szLabelName = "%s%s%d%dOptionLabel" %(optionTag1, optionTag2, i, j)
                                                tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                                                tab.setEnabled(szLabelName, bLandEnable or bWaterEnable)
                                        else :
                                                break

                                elementType = elementsList[indexElement]
                                
                                szOptionDesc = getUText(XMLDescriptions[elementType])
                                szWidgetName = "%s*%s_%s_%s_CBSelectionSpecial" %(elementType, baseTag, optionTag1, optionTag2)
                                bOptionOn = False
                                if elementType in selection[baseTag][optionTag1][optionTag2] : bOptionOn = True
                                tab.attachCheckBox(szNameHSupport, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName, bOptionOn)
                                tab.setEnabled(szWidgetName, ((bLandEnable) and (elementType in XMLEntriesList["land"])) or ((bWaterEnable) and (elementType in XMLEntriesList["water"])) )

                        if i != (nbLine-1) :
                                tab.attachHSeparator(vBoxLeft, "%s%s%dHSeparator2" %(optionTag1, optionTag2, i))
                                tab.attachHSeparator(vBoxRight, "%s%s%dHSeparator3" %(optionTag1, optionTag2, i))

        def drawBoxOptionSelectionSpecial(self, argsList):
                vBoxLeft, vBoxRight, baseTag, optionTag1, optionTag2, bEnable = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)
                szCallbackFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["cbfunc"]
                elementsList = valueLimits[baseTag][optionTag1][baseOptionTag2]["listitem"]
                labelTxtTag = valueLimits[baseTag][optionTag1][baseOptionTag2]["txttag"]
                nbPerLine = valueLimits[baseTag][optionTag1][baseOptionTag2]["nbperline"]

                nbElements = len(elementsList)
                nbLine = nbElements/nbPerLine
                if nbElements % nbPerLine != 0 : nbLine += 1

                for i in range(nbLine) :
                        #box1 : add option label
                        szNameHSupport = "%s%s%dDescSupport2" %(optionTag1, optionTag2, i)
                        tab.attachHBox(vBoxLeft, szNameHSupport)
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                        if i==0 : tab.setLayoutFlag(szNameHSupport, "LAYOUT_RIGHT")
                        else : tab.setLayoutFlag(szNameHSupport, "LAYOUT_HCENTER")

                        if i==0 : szLabelText = getUMenuText(labelTxtTag)
                        else : szLabelText = getUMenuText("TXT_DUM")
                        szLabelName = "%s%s%dOptionLabel" %(optionTag1, optionTag2, i)
                        tab.attachLabel(szNameHSupport, szLabelName, szLabelText)
                        tab.setEnabled(szLabelName, bEnable)

                        #box2 : add option selection
                        szNameHSupport = "%s%s%dDescSupport3" %(optionTag1, optionTag2, i)
                        tab.attachHBox(vBoxRight, szNameHSupport)
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_SIZE_VEXPANDING")
                        tab.setLayoutFlag(szNameHSupport, "LAYOUT_LEFT")

                        for j in range(nbPerLine) :
                                indexElement = i*nbPerLine + j
                                if indexElement >= nbElements : break

                                elementType = elementsList[indexElement]
                                
                                szOptionDesc = getUText(XMLDescriptions[elementType])
                                szWidgetName = "%s*%s_%s_%s_CBSelectionSpecial" %(elementType, baseTag, optionTag1, optionTag2)
                                bOptionOn = False
                                if elementType in selection[baseTag][optionTag1][optionTag2] : bOptionOn = True
                                tab.attachCheckBox(szNameHSupport, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName, bOptionOn)
                                tab.setEnabled(szWidgetName, bEnable)

                        if i != (nbLine-1) :
                                tab.attachHSeparator(vBoxLeft, "%s%s%dHSeparator2" %(optionTag1, optionTag2, i))
                                tab.attachHSeparator(vBoxRight, "%s%s%dHSeparator3" %(optionTag1, optionTag2, i))

        def drawBoxOptionSelectionMultiRB(self, argsList):
                boxOptionName, baseTag, optionTag1, optionTag2, bEnable = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)
                szCallbackFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["cbfunc"]
                labelTxtTag = valueLimits[baseTag][optionTag1][baseOptionTag2]["txttag"]
                nbSelection = valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"]

		for i in range(nbSelection) :
                        szOptionDesc = getUMenuText("%s_SEL%d" %(labelTxtTag, i))
                        szWidgetName = "%s_%s_%s_%d" %(baseTag, optionTag1, optionTag2, i)
                        bOptionOn = False
                        if selection[baseTag][optionTag1][optionTag2] == i : bOptionOn = True
                        tab.attachRadioButton(boxOptionName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName, bOptionOn)
                        tab.setEnabled(szWidgetName, bEnable)

        def drawBoxOptionSelection(self, argsList):
                boxOptionName, baseTag, optionTag1, optionTag2, bEnable = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)
                szCallbackFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["cbfunc"]
                labelTxtTag = valueLimits[baseTag][optionTag1][baseOptionTag2]["txttag"]
                nbSelection = int(valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"])

		for i in range(nbSelection) :
                        szOptionDesc = getUMenuText("%s_SEL%d" %(labelTxtTag, i))
                        szWidgetName = "%s_%s_%s_%d_%d" %(baseTag, optionTag1, optionTag2, i, nbSelection)
                        bOptionOn = False
                        if i in selection[baseTag][optionTag1][optionTag2] : bOptionOn = True
                        tab.attachCheckBox(boxOptionName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName, bOptionOn)
                        tab.setEnabled(szWidgetName, bEnable)

        def drawBoxOptionSelectOne(self, argsList):
                boxOptionName, baseTag, optionTag1, optionTag2, bEnable = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)
                szCallbackFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["cbfunc"]
                labelTxtTag = valueLimits[baseTag][optionTag1][baseOptionTag2]["txttag"]

                szOptionDesc = getUMenuText("%s_SEL0" %labelTxtTag)
                szWidgetName = "oneCB_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                bOptionOn = selection[baseTag][optionTag1][optionTag2]
                tab.attachCheckBox(boxOptionName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName, bOptionOn)
                tab.setEnabled(szWidgetName, bEnable)

        def drawBoxOptionMultiValues(self, argsList):
                boxOptionName, baseTag, optionTag1, optionTag2, bEnable = argsList
                
		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)
                szCallbackFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["cbfunc"]
                labelTxtTag = valueLimits[baseTag][optionTag1][baseOptionTag2]["txttag"]
                toolTipText = copy.deepcopy(valueLimits[baseTag][optionTag1][baseOptionTag2]["tooltip"])
                if toolTipText != "" : toolTipText = getUMenuText(toolTipText[0], toolTipText[1])

                selTp = selection[baseTag][optionTag1][optionTag2]
                if "-" in optionTag2 :
                        defTp = defSel[baseTag][optionTag1]["%s-0" %baseOptionTag2]
                else :
                        defTp = defSel[baseTag][optionTag1][optionTag2]

                for i in range(len(defTp)):
                        szLabelName = "%s%s%s%dMultiValues" %(baseTag, optionTag1, optionTag2, i)
                        tab.attachLabel(boxOptionName, szLabelName, getUMenuText("%s_SEL%d" %(labelTxtTag, i)))
                        tab.setEnabled(szLabelName, bEnable)

                        if bEnable :
                                szEditBoxDesc = getUText(str(selTp[i]))
                        else :
                                szEditBoxDesc = getUText(str(defTp[i]))
                        szWidgetName = "EDMultiValues_%s_%s_%s_%d" %(baseTag, optionTag1, optionTag2, i)
                        tab.attachEdit(boxOptionName, szWidgetName, szEditBoxDesc, self.callbackIFace, szCallbackFunction, szWidgetName)
                        if toolTipText != "" : tab.setToolTip(szWidgetName, toolTipText)
                        tab.setEnabled(szWidgetName, bEnable)

        def drawBoxOptionValue(self, argsList):
                boxOptionName, baseTag, optionTag1, optionTag2 , bEnable = argsList
                
		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)
                szCallbackFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["cbfunc"]
                toolTipText = copy.deepcopy(valueLimits[baseTag][optionTag1][baseOptionTag2]["tooltip"])
                if toolTipText != "" : toolTipText = getUMenuText(toolTipText[0], toolTipText[1])

                selTp = selection[baseTag][optionTag1][optionTag2]
                if "-" in optionTag2 :
                        defTp = defSel[baseTag][optionTag1]["%s-0" %baseOptionTag2]
                else :
                        defTp = defSel[baseTag][optionTag1][optionTag2]

                if bEnable :
                        szEditBoxDesc = getUText(str(selTp[0]))
                else :
                        szEditBoxDesc = getUText(str(defTp[0]))
                szWidgetName = "EDValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
		tab.attachEdit(boxOptionName, szWidgetName, szEditBoxDesc, self.callbackIFace, szCallbackFunction, szWidgetName)
                if toolTipText != "" : tab.setToolTip(szWidgetName, toolTipText)
                tab.setEnabled(szWidgetName, bEnable)

        def drawBoxOptionStandardValueRandom(self, argsList):
                boxOptionName, baseTag, optionTag1, optionTag2 , bEnable = argsList

                bStandartEnable = bEnable
                if (bEnable) and (optionTag1 == "resourcesgen") and (optionTag2 in ["landpercent", "waterpercent"]) :
                        bStandartEnable = not copy.copy(selection["resources"]["resourcesgen"]["erasedefres"])
                
		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)
                szCallbackFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["cbfunc"]
                toolTipText = copy.deepcopy(valueLimits[baseTag][optionTag1][baseOptionTag2]["tooltip"])
                if toolTipText != "" : toolTipText = getUMenuText(toolTipText[0], toolTipText[1])

                selTp = selection[baseTag][optionTag1][optionTag2]
                valTp = valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"]

                minValue = valTp[0]
                maxValue = valTp[1]
                midValue = minValue + (maxValue - minValue)/2

                if selTp == "standard" : boxEnable = 0
                elif len(selTp) == 1 : boxEnable = 1
                else : boxEnable = 2

                szOptionDesc = getUMenuText("TXT_STANDARD")
                szWidgetName = "RBStandard_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                bOptionOn = False
                if boxEnable == 0 : bOptionOn = True
                tab.attachRadioButton(boxOptionName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName, bOptionOn)
                tab.setEnabled(szWidgetName, bStandartEnable)

                szOptionDesc = getUMenuText("TXT_VALUE")
                szWidgetName = "RBValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                bOptionOn = False
                if boxEnable == 1 : bOptionOn = True
                tab.attachRadioButton(boxOptionName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName, bOptionOn)
                tab.setEnabled(szWidgetName, bEnable)

                if bOptionOn :
                        szEditBoxDesc = getUText(str(selTp[0]))
                else :
                        szEditBoxDesc = getUText(str(midValue))
                szWidgetName = "EDValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
		tab.attachEdit(boxOptionName, szWidgetName, szEditBoxDesc, self.callbackIFace, "Sto_DummyCallback", szWidgetName)
                if toolTipText != "" : tab.setToolTip(szWidgetName, toolTipText)
		tab.setEnabled(szWidgetName, bOptionOn and bEnable)

                szOptionDesc = getUMenuText("TXT_RANDOM")
                szWidgetName = "RBRandom_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                bOptionOn = False
                if boxEnable == 2 : bOptionOn = True
                tab.attachRadioButton(boxOptionName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName, bOptionOn)
                tab.setEnabled(szWidgetName, bEnable)

                szLabelName = "%s%s%sBetweenLabel" %(baseTag, optionTag1, optionTag2)
		tab.attachLabel(boxOptionName, szLabelName, getUMenuText("TXT_BETWEEN"))
		tab.setEnabled(szLabelName, bOptionOn and bEnable)

                if bOptionOn :
                        [ valMin, valMax ] = selTp
                else :
                        [ valMin, valMax ] = valTp

		szEditBoxDesc = getUText(str(valMin))
                szWidgetName = "EDRandom1_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
		tab.attachEdit(boxOptionName, szWidgetName, szEditBoxDesc, self.callbackIFace, "Sto_DummyCallback", szWidgetName)
		tab.setEnabled(szWidgetName, bOptionOn and bEnable)

                szLabelName = "%s%s%sAndLabel" %(baseTag, optionTag1, optionTag2)
		tab.attachLabel(boxOptionName, szLabelName, getUMenuText("TXT_AND"))
		tab.setEnabled(szLabelName, bOptionOn and bEnable)

		szEditBoxDesc = getUText(str(valMax))
                szWidgetName = "EDRandom2_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
		tab.attachEdit(boxOptionName, szWidgetName, szEditBoxDesc, self.callbackIFace, "Sto_DummyCallback", szWidgetName)
		tab.setEnabled(szWidgetName, bOptionOn and bEnable)

        def drawBoxOptionEDValueRandom(self, argsList):
                boxOptionName, baseTag, optionTag1, optionTag2 , bEnable = argsList
                
		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)
                szCallbackFunction = valueLimits[baseTag][optionTag1][baseOptionTag2]["cbfunc"]
                toolTipText = copy.deepcopy(valueLimits[baseTag][optionTag1][baseOptionTag2]["tooltip"])
                if toolTipText != "" : toolTipText = getUMenuText(toolTipText[0], toolTipText[1])

                selTp = selection[baseTag][optionTag1][optionTag2]
                valTp = valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"]
                if "-" in optionTag2 :
                        defTp = defSel[baseTag][optionTag1]["%s-0" %baseOptionTag2]
                else :
                        defTp = defSel[baseTag][optionTag1][optionTag2]

                szOptionDesc = getUMenuText("TXT_VALUE")
                szWidgetName = "RBValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                bOptionOn = False
                if len(selTp) == 1 : bOptionOn = True
                tab.attachRadioButton(boxOptionName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName, bOptionOn)
		tab.setEnabled(szWidgetName, bEnable)

                if bOptionOn :
                        szEditBoxDesc = getUText(str(selTp[0]))
                else :
                        szEditBoxDesc = getUText(str(defTp[0]))
                szWidgetName = "EDValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
		tab.attachEdit(boxOptionName, szWidgetName, szEditBoxDesc, self.callbackIFace, "Sto_DummyCallback", szWidgetName)
                if toolTipText != "" : tab.setToolTip(szWidgetName, toolTipText)
		tab.setEnabled(szWidgetName, bOptionOn and bEnable)

		bOptionOn = not bOptionOn
                szOptionDesc = getUMenuText("TXT_RANDOM")
                szWidgetName = "RBRandom_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                tab.attachRadioButton(boxOptionName, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName, bOptionOn)
		tab.setEnabled(szWidgetName, bEnable)

                szLabelName = "%s%s%sBetweenLabel" %(baseTag, optionTag1, optionTag2)
		tab.attachLabel(boxOptionName, szLabelName, getUMenuText("TXT_BETWEEN"))
		tab.setEnabled(szLabelName, bOptionOn and bEnable)

                if len(selTp) == 2 :
                        [ valMin, valMax ] = selTp
                else :
                        [ valMin, valMax ] = valTp

		szEditBoxDesc = getUText(str(valMin))
                szWidgetName = "EDRandom1_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
		tab.attachEdit(boxOptionName, szWidgetName, szEditBoxDesc, self.callbackIFace, "Sto_DummyCallback", szWidgetName)
		tab.setEnabled(szWidgetName, bOptionOn and bEnable)

                szLabelName = "%s%s%sAndLabel" %(baseTag, optionTag1, optionTag2)
		tab.attachLabel(boxOptionName, szLabelName, getUMenuText("TXT_AND"))
		tab.setEnabled(szLabelName, bOptionOn and bEnable)

		szEditBoxDesc = getUText(str(valMax))
                szWidgetName = "EDRandom2_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
		tab.attachEdit(boxOptionName, szWidgetName, szEditBoxDesc, self.callbackIFace, "Sto_DummyCallback", szWidgetName)
		tab.setEnabled(szWidgetName, bOptionOn and bEnable)

        def drawLowerPanel(self, szParentBox, tagTab):

		tab = self.pTabControl

                szBoxName = "%sButtonBox" %tagTab
		tab.attachHBox(szParentBox, szBoxName)
                tab.setLayoutFlag(szBoxName, "LAYOUT_SIZE_HEXPANDING")

                hBox1 = "%sButtonHBox1" %tagTab
                hBox2 = "%sButtonHBox2" %tagTab
                hBox3 = "%sButtonHBox3" %tagTab
                hBox4 = "%sButtonHBox4" %tagTab

		tab.attachHBox(szBoxName, hBox1)
                tab.setLayoutFlag(hBox1, "LAYOUT_LEFT")

		if tagTab != "InfoTab" :
                        tab.attachHBox(szBoxName, hBox2)
                        tab.setLayoutFlag(hBox2, "LAYOUT_SIZE_HEXPANDING")
                        tab.setLayoutFlag(hBox2, "LAYOUT_HCENTER")
                
		tab.attachHBox(szBoxName, hBox3)
                tab.setLayoutFlag(hBox3, "LAYOUT_SIZE_HEXPANDING")
                tab.setLayoutFlag(hBox3, "LAYOUT_HCENTER")

		tab.attachHBox(szBoxName, hBox4)
                tab.setLayoutFlag(hBox4, "LAYOUT_RIGHT")

                #create language dropdown
		szDropdownDesc = "%sLanguagesDropdownBox" %tagTab
		aszDropdownElements = (getUText("English"), getUText("Français"), getUText("Deutsch"), getUText("Italiano"), getUText("Español"))
		szCallbackFunction = "Sto_Apply_Language"
		szWidgetName = "Languages_%s" %tagTab
		iInitialSelection = language
		tab.attachDropDown(hBox1, szWidgetName, szDropdownDesc, aszDropdownElements, self.callbackIFace, szCallbackFunction, szWidgetName, iInitialSelection)
		tab.setLayoutFlag(szWidgetName, "LAYOUT_LEFT")

		if tagTab != "InfoTab" :
                        #create reset all , reset table ,refresh buttons
                        szOptionDesc = getUMenuText("TXT_RESET_ALL")
                        szCallbackFunction = "Sto_Reset_All_Apply"
                        szWidgetName = "ResetAll_%s" %tagTab
                        tab.attachButton(hBox2, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

                        szOptionDesc = getUMenuText("TXT_RESET_TABLE")
                        szCallbackFunction = "Sto_Reset_Table_Apply"
                        szWidgetName = "ResetTable_%s" %tagTab
                        tab.attachButton(hBox2, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

                        szOptionDesc = getUMenuText("TXT_REFRESH")
                        szOptionDescTip = getUMenuText("TXT_REFRESH_TIP")
                        szCallbackFunction = "Sto_Refresh_Apply"
                        szWidgetName = "Refresh_%s" %tagTab
                        tab.attachButton(hBox2, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)
                        tab.setToolTip(szWidgetName, szOptionDescTip)

		#create load , save buttons
                szOptionDesc = getUMenuText("TXT_LOAD_FILE")
                szCallbackFunction = "Sto_Load_File"
                szWidgetName = "LoadFile_%s" %tagTab
                tab.attachButton(hBox3, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

                szOptionDesc = getUMenuText("TXT_SAVE_FILE")
                szCallbackFunction = "Sto_Save_File"
                szWidgetName = "SaveFile_%s" %tagTab
                tab.attachButton(hBox3, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

		#create exit buttons
                szOptionDesc = getUMenuText("TXT_EXIT")
                szCallbackFunction = "Sto_Exit_Apply"
                szWidgetName = "Exit_%s" %tagTab
                tab.attachButton(hBox4, szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

        # additionnal functions : refresh functions
        def refreshOptionDefender(self, argsList):

                baseTag, gameID, optionID, bBoxOn = argsList

		tab = self.pTabControl
                idSel = selection[baseTag][gameID][optionID]

		if XMLEntriesList["units"]["barbdefender"] != [] :

                        szWidgetName = "gameCityDef_%s_%s_%s" %(baseTag, gameID, optionID)

                        if idSel == [] :
                                iSelection = 0
                        elif (not idSel[0] in XMLEntriesList["units"]["barbdefender"]) :
                                iSelection = 0
                        else :
                                iSelection = XMLEntriesList["units"]["barbdefender"].index(idSel[0]) + 1

                        tab.setValue(szWidgetName, iSelection)
                        tab.setEnabled(szWidgetName, bBoxOn)

		if XMLEntriesList["units"]["barbfight"] != [] :

                        szWidgetName = "gameCityFight_%s_%s_%s" %(baseTag, gameID, optionID)

                        if idSel == [] :
                                iSelection = 0
                        elif (not idSel[0] in XMLEntriesList["units"]["barbfight"]) :
                                iSelection = 0
                        else :
                                iSelection = XMLEntriesList["units"]["barbfight"].index(idSel[0]) + 1

                        tab.setValue(szWidgetName, iSelection)
                        tab.setEnabled(szWidgetName, bBoxOn)

        def refreshStartUnit(self, argsList):

                baseTag, gameID, optionID, bBoxOn = argsList

		tab = self.pTabControl

                #units dropdowns
                listTag = ["peacedd", "landdd", "waterdd", "airdd", "otherdd", "national", "team", "world", "combatnone"]
                listTag += [item for item in XMLEntriesList["unitcombatlist"]]

                nbDD = 0
                idSel = selection[baseTag][gameID][optionID]

                for unitTag in listTag :
                        if XMLEntriesList["units"][unitTag] == [] : continue

                        if nbDD % 2 == 0 :
                                szLabelName = "%s%sOptionLabel%d" %(gameID,optionID,nbDD)
                                tab.setEnabled(szLabelName, bBoxOn)

                        #dropdowns
                        szWidgetName = "%s*UnitDropdown_%s_%s_%s" %(unitTag, baseTag, gameID, optionID)

                        if len(idSel) == 1 :
                                elementType = idSel[0]
                                if elementType in XMLEntriesList["units"][unitTag] : iSelection = XMLEntriesList["units"][unitTag].index(elementType) + 1
                                else : iSelection = 0
                        else :
                                iSelection = 0

                        tab.setValue(szWidgetName, iSelection)
                        tab.setEnabled(szWidgetName, bBoxOn)

                        nbDD += 1

        def refreshAddTech(self, argsList):

                baseTag, gameID, optionID, bBoxOn = argsList
                sIndex = optionID.split("-")[1]

		tab = self.pTabControl

                szLabelName = "%s%sOptionLabel" %(gameID,optionID)
                tab.setEnabled(szLabelName, bBoxOn)

		szWidgetName = "TechDropdown_%s" %sIndex

		idSel = selection[baseTag][gameID][optionID]
		if idSel == "alltechsame" :
                        iSelection = 1
		elif idSel == "alltechdiff" :
                        iSelection = 2
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        iSelection = XMLEntriesList["techslist"].index(elementType) + 3
                else :
                        iSelection = 0

                tab.setValue(szWidgetName, iSelection)
                tab.setEnabled(szWidgetName, bBoxOn)

        def refreshStartResources(self, argsList):

                baseTag, resourceID, optionID, bBoxOn = argsList
                sIndex = optionID.split("-")[1]

		tab = self.pTabControl

                szLabelName = "%s%sOptionLabel" %(resourceID,optionID)
                tab.setEnabled(szLabelName, bBoxOn)

                #strat dropdown
		szWidgetName = "StratStartDropdown_%s" %sIndex

		idSel = selection[baseTag][resourceID][optionID]
		if idSel == "allstratsame" :
                        iSelection = 1
		elif idSel == "allstratdiff" :
                        iSelection = 2
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        if elementType in XMLEntriesList["strategic"] : iSelection = XMLEntriesList["strategic"].index(elementType) + 3
                        else : iSelection = 0
                else :
                        iSelection = 0

		tab.setValue(szWidgetName, iSelection)
                tab.setEnabled(szWidgetName, bBoxOn)

                #health dropdown
		szWidgetName = "HealthStartDropdown_%s" %sIndex

		if idSel == "allhealthsame" :
                        iSelection = 1
		elif idSel == "allhealthdiff" :
                        iSelection = 2
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        if elementType in XMLEntriesList["health"] : iSelection = XMLEntriesList["health"].index(elementType) + 3
                        else : iSelection = 0
                else :
                        iSelection = 0

		tab.setValue(szWidgetName, iSelection)
                tab.setEnabled(szWidgetName, bBoxOn)

                #happiness dropdown
		szWidgetName = "HappStartDropdown_%s" %sIndex

		if idSel == "allhappsame" :
                        iSelection = 1
		elif idSel == "allhappdiff" :
                        iSelection = 2
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        if elementType in XMLEntriesList["happiness"] : iSelection = XMLEntriesList["happiness"].index(elementType) + 3
                        else : iSelection = 0
                else :
                        iSelection = 0

		tab.setValue(szWidgetName, iSelection)
                tab.setEnabled(szWidgetName, bBoxOn)

        def refreshMultiplyResources(self, argsList):

                baseTag, resourceID, optionID, bBoxOn = argsList
                sIndex = optionID.split("-")[1]

		tab = self.pTabControl

                szLabelName = "%s%sOptionLabel" %(resourceID,optionID)
                tab.setEnabled(szLabelName, bBoxOn)

		idSel = selection[baseTag][resourceID][optionID][0]
		nbSel = selection[baseTag][resourceID][optionID][1]

		#strat dropdown
		szWidgetName = "StratDropdown_%s" %sIndex

		if idSel == "allstrat" :
                        iSelection = 1
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        if elementType in XMLEntriesList["strategic"] : iSelection = XMLEntriesList["strategic"].index(elementType) + 2
                        else : iSelection = 0
                else :
                        iSelection = 0

		tab.setValue(szWidgetName, iSelection)
                tab.setEnabled(szWidgetName, bBoxOn)

                #health dropdown
		szWidgetName = "HealthDropdown_%s" %sIndex

		if idSel == "allhealth" :
                        iSelection = 1
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        if elementType in XMLEntriesList["health"] : iSelection = XMLEntriesList["health"].index(elementType) + 2
                        else : iSelection = 0
                else :
                        iSelection = 0

		tab.setValue(szWidgetName, iSelection)
                tab.setEnabled(szWidgetName, bBoxOn)

                #happiness dropdown
		szWidgetName = "HappDropdown_%s" %sIndex

		if idSel == "allhapp" :
                        iSelection = 1
		elif len(idSel) == 1 :
                        elementType = idSel[0]
                        if elementType in XMLEntriesList["happiness"] : iSelection = XMLEntriesList["happiness"].index(elementType) + 2
                        else : iSelection = 0
                else :
                        iSelection = 0

		tab.setValue(szWidgetName, iSelection)
                tab.setEnabled(szWidgetName, bBoxOn)

                #by label
                szLabelName = "%s%sByLabel" %(resourceID,optionID)
                tab.setEnabled(szLabelName, bBoxOn)

                #edit box
                szEditBoxDesc = getUText(str(nbSel))
                szWidgetName = "EDValue_%s_%s_%s" %(baseTag, resourceID, optionID)
		tab.setText(szWidgetName, szEditBoxDesc)
		tab.setEnabled(szWidgetName, bBoxOn)

        def refreshStandardValueRandom(self, argsList):
                baseTag, optionTag1, optionTag2, bBoxOn = argsList
                
                bStandartEnable = bBoxOn
                if (bBoxOn) and (optionTag1 == "resourcesgen") and (optionTag2 in ["landpercent", "waterpercent"]) :
                        bStandartEnable = not copy.copy(selection["resources"]["resourcesgen"]["erasedefres"])

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)

                selTp = selection[baseTag][optionTag1][optionTag2]
                valTp = valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"]

                minValue = valTp[0]
                maxValue = valTp[1]
                midValue = minValue + (maxValue - minValue)/2

                if selTp == "standard" : boxEnable = 0
                elif len(selTp) == 1 : boxEnable = 1
                else : boxEnable = 2

                szWidgetName = "RBStandard_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                bOptionOn = False
                if boxEnable == 0 : bOptionOn = True
                tab.setValue(szWidgetName, boxEnable)
		tab.setEnabled(szWidgetName, bStandartEnable)

                szWidgetName = "RBValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                bOptionOn = False
                if boxEnable == 1 : bOptionOn = True
                tab.setValue(szWidgetName, boxEnable)
		tab.setEnabled(szWidgetName, bBoxOn)

                if bOptionOn :
                        szEditBoxDesc = getUText(str(selTp[0]))
                else :
                        szEditBoxDesc = getUText(str(midValue))
                szWidgetName = "EDValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                tab.setText(szWidgetName, szEditBoxDesc)
                tab.setEnabled(szWidgetName, bBoxOn and bOptionOn)

                szWidgetName = "RBRandom_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                bOptionOn = False
                if boxEnable == 2 : bOptionOn = True
                tab.setValue(szWidgetName, boxEnable)
		tab.setEnabled(szWidgetName, bBoxOn)

                szLabelName = "%s%s%sBetweenLabel" %(baseTag, optionTag1, optionTag2)
                tab.setEnabled(szLabelName, bBoxOn and bOptionOn)

                if bOptionOn :
                        [ valMin, valMax ] = selTp
                else :
                        [ valMin, valMax ] = valTp

                szEditBoxDesc = getUText(str(valMin))
                szWidgetName = "EDRandom1_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                tab.setText(szWidgetName, szEditBoxDesc)
                tab.setEnabled(szWidgetName, bBoxOn and bOptionOn)

                szLabelName = "%s%s%sAndLabel" %(baseTag, optionTag1, optionTag2)
                tab.setEnabled(szLabelName, bBoxOn and bOptionOn)

                szEditBoxDesc = getUText(str(valMax))
                szWidgetName = "EDRandom2_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                tab.setText(szWidgetName, szEditBoxDesc)
                tab.setEnabled(szWidgetName, bBoxOn and bOptionOn)

        def refreshValueRandom(self, argsList):

                baseTag, optionTag1, optionTag2, bBoxOn = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)

                selTp = selection[baseTag][optionTag1][optionTag2]
                valTp = valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"]
                if "-" in optionTag2 :
                        defTp = defSel[baseTag][optionTag1]["%s-0" %baseOptionTag2]
                else :
                        defTp = defSel[baseTag][optionTag1][optionTag2]

                szWidgetName = "RBValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                bOptionOn = False
                if len(selTp) == 1 : bOptionOn = True
                tab.setValue(szWidgetName, bOptionOn)
		tab.setEnabled(szWidgetName, bBoxOn)

                if bOptionOn :
                        szEditBoxDesc = getUText(str(selTp[0]))
                else :
                        szEditBoxDesc = getUText(str(defTp[0]))
                szWidgetName = "EDValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                tab.setText(szWidgetName, szEditBoxDesc)
                tab.setEnabled(szWidgetName, bBoxOn and bOptionOn)

                bOptionOn = not bOptionOn

                szWidgetName = "RBRandom_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                tab.setValue(szWidgetName, bOptionOn)
		tab.setEnabled(szWidgetName, bBoxOn)

                szLabelName = "%s%s%sBetweenLabel" %(baseTag, optionTag1, optionTag2)
                tab.setEnabled(szLabelName, bBoxOn and bOptionOn)

                if len(selTp) == 2 :
                        [ valMin, valMax ] = selTp
                else :
                        [ valMin, valMax ] = valTp

                szEditBoxDesc = getUText(str(valMin))
                szWidgetName = "EDRandom1_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                tab.setText(szWidgetName, szEditBoxDesc)
                tab.setEnabled(szWidgetName, bBoxOn and bOptionOn)

                szLabelName = "%s%s%sAndLabel" %(baseTag, optionTag1, optionTag2)
                tab.setEnabled(szLabelName, bBoxOn and bOptionOn)

                szEditBoxDesc = getUText(str(valMax))
                szWidgetName = "EDRandom2_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                tab.setText(szWidgetName, szEditBoxDesc)
                tab.setEnabled(szWidgetName, bBoxOn and bOptionOn)

        def refreshMultiValues(self, argsList):

                baseTag, optionTag1, optionTag2, bBoxOn = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)

                selTp = selection[baseTag][optionTag1][optionTag2]
                if "-" in optionTag2 :
                        defTp = defSel[baseTag][optionTag1]["%s-0" %baseOptionTag2]
                else :
                        defTp = defSel[baseTag][optionTag1][optionTag2]

                for i in range(len(defTp)):
                        szLabelName = "%s%s%s%dMultiValues" %(baseTag, optionTag1, optionTag2, i)
                        tab.setEnabled(szLabelName, bBoxOn)

                        if bBoxOn :
                                szEditBoxDesc = getUText(str(selTp[i]))
                        else :
                                szEditBoxDesc = getUText(str(defTp[i]))
                        szWidgetName = "EDMultiValues_%s_%s_%s_%d" %(baseTag, optionTag1, optionTag2, i)
                        tab.setText(szWidgetName, szEditBoxDesc)
                        tab.setEnabled(szWidgetName, bBoxOn)

        def refreshValue(self, argsList):

                baseTag, optionTag1, optionTag2, bBoxOn = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)

                selTp = selection[baseTag][optionTag1][optionTag2]
                if "-" in optionTag2 :
                        defTp = defSel[baseTag][optionTag1]["%s-0" %baseOptionTag2]
                else :
                        defTp = defSel[baseTag][optionTag1][optionTag2]

                if bBoxOn :
                        szEditBoxDesc = getUText(str(selTp[0]))
                else :
                        szEditBoxDesc = getUText(str(defTp[0]))
                szWidgetName = "EDValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                tab.setText(szWidgetName, szEditBoxDesc)
                tab.setEnabled(szWidgetName, bBoxOn)

        def refreshSelectionSpecialDefaultResources(self, argsList):

                baseTag, optionTag1, optionTag2, bLandEnable, bWaterEnable = argsList

		tab = self.pTabControl
                elementsList = valueLimits[baseTag][optionTag1][optionTag2]["listitem"]
                nbPerLine = valueLimits[baseTag][optionTag1][optionTag2]["nbperline"]

                nbElements = len(elementsList)
                nbLine = nbElements/nbPerLine
                if nbElements % nbPerLine != 0 : nbLine += 1

                nbLine = max(nbLine, 4)

                for i in range(nbLine) :
                        if i in [1,2,3] :
                                # buttons
                                if i == 1 : szWidgetName = "AllStrat_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                                elif i == 2 : szWidgetName = "AllHealth_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                                else : szWidgetName = "AllHapp_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                                tab.setEnabled(szWidgetName, bLandEnable or bWaterEnable)
                        else :
                                szLabelName = "%s%s%dOptionLabel" %(optionTag1, optionTag2, i)
                                tab.setEnabled(szLabelName, bLandEnable or bWaterEnable)

                        for j in range(nbPerLine) :
                                indexElement = i*nbPerLine + j
                                if indexElement >= nbElements :
                                        if j == 0 :
                                                #dum label
                                                szLabelName = "%s%s%d%dOptionLabel" %(optionTag1, optionTag2, i, j)
                                                tab.setEnabled(szLabelName, bLandEnable or bWaterEnable)
                                        else :
                                                break

                listSelected = selection[baseTag][optionTag1][optionTag2]

                for elementType in elementsList :
                        szWidgetName = "%s*%s_%s_%s_CBSelectionSpecial" %(elementType, baseTag, optionTag1, optionTag2)
                        bOptionOn = False
                        if elementType in listSelected : bOptionOn = True
                        tab.setValue(szWidgetName, bOptionOn)
                        tab.setEnabled(szWidgetName, ((bLandEnable) and (elementType in XMLEntriesList["land"])) or ((bWaterEnable) and (elementType in XMLEntriesList["water"])) )

        def refreshSelectionSpecial(self, argsList):

                baseTag, optionTag1, optionTag2, bBoxOn = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)

                elementsList = valueLimits[baseTag][optionTag1][baseOptionTag2]["listitem"]
                nbPerLine = valueLimits[baseTag][optionTag1][baseOptionTag2]["nbperline"]

                nbElements = len(elementsList)
                nbLine = nbElements/nbPerLine
                if nbElements % nbPerLine != 0 : nbLine += 1

                for i in range(nbLine) :
                        szLabelName = "%s%s%dOptionLabel" %(optionTag1, optionTag2, i)
                        tab.setEnabled(szLabelName, bBoxOn)

                listSelected = selection[baseTag][optionTag1][optionTag2]

                for elementType in elementsList :
                        szWidgetName = "%s*%s_%s_%s_CBSelectionSpecial" %(elementType, baseTag, optionTag1, optionTag2)
                        bOptionOn = False
                        if elementType in listSelected : bOptionOn = True
                        tab.setValue(szWidgetName, bOptionOn)
                        tab.setEnabled(szWidgetName, bBoxOn)

        def refreshSelectionMultiRB(self, argsList):

                baseTag, optionTag1, optionTag2, bBoxOn = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)
                nbSelection = valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"]

                stateRB = selection[baseTag][optionTag1][optionTag2]

                for i in range(nbSelection) :
                        szWidgetName = "%s_%s_%s_%d" %(baseTag, optionTag1, optionTag2, i)
                        tab.setValue(szWidgetName, stateRB)
                        tab.setEnabled(szWidgetName, bBoxOn)

        def refreshSelection(self, argsList):

                baseTag, optionTag1, optionTag2, bBoxOn = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)
                nbSelection = valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"]

                listSelected = selection[baseTag][optionTag1][optionTag2]

                for i in range(nbSelection) :
                        szWidgetName = "%s_%s_%s_%d_%d" %(baseTag, optionTag1, optionTag2, i, nbSelection)
                        bOptionOn = False
                        if i in listSelected : bOptionOn = True
                        tab.setValue(szWidgetName, bOptionOn)
                        tab.setEnabled(szWidgetName, bBoxOn)

        def refreshSelectOne(self, argsList):

                baseTag, optionTag1, optionTag2, bBoxOn = argsList

		tab = self.pTabControl

                szWidgetName = "oneCB_%s_%s_%s" %(baseTag, optionTag1, optionTag2)
                bOptionOn = selection[baseTag][optionTag1][optionTag2]
                tab.setValue(szWidgetName, bOptionOn)
                tab.setEnabled(szWidgetName, bBoxOn)

        # additionnal functions : check edit box functions
        def checkEditBoxMultiplyResources(self, argsList):
                global selection

                baseTag, optionTag1, optionTag2 = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)

                valTp = valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"]
                if "-" in optionTag2 :
                        defTp = copy.deepcopy(defSel[baseTag][optionTag1]["%s-0" %baseOptionTag2][1])
                else :
                        defTp = copy.deepcopy(defSel[baseTag][optionTag1][optionTag2][1])

                valTpMin, valTpMax = valTp

                txtEDValue = getSText( tab.getText( "EDValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2) ) )

                try :
                        iEDValue = float(txtEDValue)
                except :
                        iEDValue = -1

                if ( iEDValue<valTpMin ) or ( iEDValue>valTpMax ):
                        iEDValue = float(defTp)

                selection[baseTag][optionTag1][optionTag2][1] = normalizeFloat(iEDValue)

        def checkEditBoxStandardValueRandom(self, argsList):
                global selection

                baseTag, optionTag1, optionTag2 = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)

                valTp = copy.deepcopy(valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"])
                valTpMin, valTpMax = valTp
                midValue = valTpMin + (valTpMax - valTpMin)/2

                txtEDValue = getSText( tab.getText( "EDValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2) ) )
                txtEDRandom1 = getSText( tab.getText( "EDRandom1_%s_%s_%s" %(baseTag, optionTag1, optionTag2) ) )
                txtEDRandom2 = getSText( tab.getText( "EDRandom2_%s_%s_%s" %(baseTag, optionTag1, optionTag2) ) )

                try :
                        iEDValue = int(txtEDValue)
                except :
                        iEDValue = -1
                try :
                        iEDRandom1 = int(txtEDRandom1)
                except :
                        iEDRandom1 = -1
                try :
                        iEDRandom2 = int(txtEDRandom2)
                except :
                        iEDRandom2 = -1

                if ( iEDValue<valTpMin ) or ( iEDValue>valTpMax ):
                        iEDValue = int(midValue)

                if ( iEDRandom1<valTpMin ) or ( iEDRandom1>=valTpMax ) or ( iEDRandom1>iEDRandom2 ):
                        iEDRandom1 = int(valTpMin)

                if ( iEDRandom2<=valTpMin ) or ( iEDRandom2>valTpMax ) or ( iEDRandom2<=iEDRandom1 ):
                        iEDRandom2 = int(valTpMax)

                if len(selection[baseTag][optionTag1][optionTag2]) == 1 :
                        selection[baseTag][optionTag1][optionTag2] = [int(iEDValue)]
                elif len(selection[baseTag][optionTag1][optionTag2]) == 2 :
                        selection[baseTag][optionTag1][optionTag2] = [int(iEDRandom1), int(iEDRandom2)]

        def checkEditBoxValueRandom(self, argsList):
                global selection

                baseTag, optionTag1, optionTag2 = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)

                valTp = copy.deepcopy(valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"])
                if "-" in optionTag2 :
                        defTp = copy.deepcopy(defSel[baseTag][optionTag1]["%s-0" %baseOptionTag2])
                else :
                        defTp = copy.deepcopy(defSel[baseTag][optionTag1][optionTag2])

                valTpMin, valTpMax = valTp

                txtEDValue = getSText( tab.getText( "EDValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2) ) )
                txtEDRandom1 = getSText( tab.getText( "EDRandom1_%s_%s_%s" %(baseTag, optionTag1, optionTag2) ) )
                txtEDRandom2 = getSText( tab.getText( "EDRandom2_%s_%s_%s" %(baseTag, optionTag1, optionTag2) ) )

                try :
                        iEDValue = int(txtEDValue)
                except :
                        iEDValue = -1
                try :
                        iEDRandom1 = int(txtEDRandom1)
                except :
                        iEDRandom1 = -1
                try :
                        iEDRandom2 = int(txtEDRandom2)
                except :
                        iEDRandom2 = -1

                if ( iEDValue<valTpMin ) or ( iEDValue>valTpMax ):
                        iEDValue = int(defTp[0])

                if ( iEDRandom1<valTpMin ) or ( iEDRandom1>=valTpMax ) or ( iEDRandom1>iEDRandom2 ):
                        iEDRandom1 = int(valTpMin)

                if ( iEDRandom2<=valTpMin ) or ( iEDRandom2>valTpMax ) or ( iEDRandom2<=iEDRandom1 ):
                        iEDRandom2 = int(valTpMax)

                if len(selection[baseTag][optionTag1][optionTag2]) == 1 :
                        selection[baseTag][optionTag1][optionTag2] = [int(iEDValue)]
                else :
                        selection[baseTag][optionTag1][optionTag2] = [int(iEDRandom1), int(iEDRandom2)]

        def checkEditBoxValueRandomFloat(self, argsList):
                global selection

                baseTag, optionTag1, optionTag2 = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)

                valTp = copy.deepcopy(valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"])
                if "-" in optionTag2 :
                        defTp = copy.deepcopy(defSel[baseTag][optionTag1]["%s-0" %baseOptionTag2])
                else :
                        defTp = copy.deepcopy(defSel[baseTag][optionTag1][optionTag2])

                valTpMin, valTpMax = valTp

                txtEDValue = getSText( tab.getText( "EDValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2) ) )
                txtEDRandom1 = getSText( tab.getText( "EDRandom1_%s_%s_%s" %(baseTag, optionTag1, optionTag2) ) )
                txtEDRandom2 = getSText( tab.getText( "EDRandom2_%s_%s_%s" %(baseTag, optionTag1, optionTag2) ) )

                try :
                        iEDValue = float(txtEDValue)
                except :
                        iEDValue = -1
                try :
                        iEDRandom1 = float(txtEDRandom1)
                except :
                        iEDRandom1 = -1
                try :
                        iEDRandom2 = float(txtEDRandom2)
                except :
                        iEDRandom2 = -1

                if ( iEDValue<valTpMin ) or ( iEDValue>valTpMax ):
                        iEDValue = float(defTp[0])

                if ( iEDRandom1<valTpMin ) or ( iEDRandom1>=valTpMax ) or ( iEDRandom1>iEDRandom2 ):
                        iEDRandom1 = float(valTpMin)

                if ( iEDRandom2<=valTpMin ) or ( iEDRandom2>valTpMax ) or ( iEDRandom2<=iEDRandom1 ):
                        iEDRandom2 = float(valTpMax)

                if len(selection[baseTag][optionTag1][optionTag2]) == 1 :
                        selection[baseTag][optionTag1][optionTag2] = [normalizeFloat(iEDValue)]
                else :
                        selection[baseTag][optionTag1][optionTag2] = [normalizeFloat(iEDRandom1), normalizeFloat(iEDRandom2)]

        def checkEditBoxMultiValues(self, argsList):
                global selection

                baseTag, optionTag1, optionTag2 = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)

                valTp = copy.deepcopy(valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"])
                if "-" in optionTag2 :
                        defTp = copy.deepcopy(defSel[baseTag][optionTag1]["%s-0" %baseOptionTag2])
                else :
                        defTp = copy.deepcopy(defSel[baseTag][optionTag1][optionTag2])

                for i in range(len(defTp)):

                        txtEDValue = getSText( tab.getText( "EDMultiValues_%s_%s_%s_%d" %(baseTag, optionTag1, optionTag2, i) ) )

                        try :
                                iEDValue = int(txtEDValue)
                        except :
                                iEDValue = -1

                        if ( iEDValue<valTp[i][0] ) or ( iEDValue>valTp[i][1] ):
                                iEDValue = int(defTp[i])

                        selection[baseTag][optionTag1][optionTag2][i] = int(iEDValue)

        def checkEditBoxValue(self, argsList):
                global selection

                baseTag, optionTag1, optionTag2 = argsList

		tab = self.pTabControl
                baseOptionTag2 = str(optionTag2)
                if "-" in optionTag2 :
                        baseOptionTag2, iIndex = splitTag(optionTag2)

                valTp = copy.deepcopy(valueLimits[baseTag][optionTag1][baseOptionTag2]["limit"])
                if "-" in optionTag2 :
                        defTp = copy.deepcopy(defSel[baseTag][optionTag1]["%s-0" %baseOptionTag2])
                else :
                        defTp = copy.deepcopy(defSel[baseTag][optionTag1][optionTag2])

                valTpMin, valTpMax = valTp

                txtEDValue = getSText( tab.getText( "EDValue_%s_%s_%s" %(baseTag, optionTag1, optionTag2) ) )

                try :
                        iEDValue = int(txtEDValue)
                except :
                        iEDValue = -1

                if ( iEDValue<valTpMin ) or ( iEDValue>valTpMax ):
                        iEDValue = int(defTp[0])

                selection[baseTag][optionTag1][optionTag2] = [int(iEDValue)]

# Load file screen
class CvStoLoadFileScreen:

	def __init__(self):
		
		self.callbackIFace = "CvOptionsScreenCallbackInterface"
		
	def getTabControl(self):
		return self.pTabControl
		
	def interfaceScreen (self):
		self.szLoadScreenName = getUMenuText("TXT_TITTLE")
		self.szLoadOptionsTabName = getUText( getSMenuText("TXT_LOAD_FILE")+" :" )
		
		self.pTabControl = CyGTabCtrl(self.szLoadScreenName, false, false)
		self.pTabControl.setModal(1)

		resolution = [int(item) for item in CyUserProfile().getResolutionString(CyUserProfile().getResolution()).split("x") if item != "" ]
		self.pTabControl.setSize(int(resolution[0]*0.95), 300)
		self.pTabControl.setControlsExpanding(false)
		
		self.pTabControl.attachTabItem("LoadForm", self.szLoadOptionsTabName)

		# draw the screen
		tab = self.pTabControl

                listFile = [ item for item in getListDirSto() if ((".cfg" in item) and (item != "_userConfig.cfg")) ]
                listFile.sort()
		
		tab.attachVBox("LoadForm", "LoadVBoxParent")
		
		tab.attachPanel("LoadVBoxParent", "LoadPanelCenter")
		tab.setStyle("LoadPanelCenter", "Panel_Tan15_Style")
		tab.setLayoutFlag("LoadPanelCenter", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("LoadPanelCenter", "LAYOUT_SIZE_VEXPANDING")
		
		tab.attachVBox("LoadPanelCenter", "LoadVBoxCenter")
		tab.setLayoutFlag("LoadVBoxCenter", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("LoadVBoxCenter", "LAYOUT_VCENTER")

		tab.attachScrollPanel("LoadVBoxCenter", "LoadPanel")
		tab.setLayoutFlag("LoadPanel", "LAYOUT_SIZE_HEXPANDING")

		tab.attachVBox("LoadPanel", "LoadVBox")
		tab.setLayoutFlag("LoadVBox", "LAYOUT_SIZE_HEXPANDING")
		
		tab.attachPanel("LoadVBox", "LoadVBoxPanelCenter")
		tab.setStyle("LoadVBoxPanelCenter", "Panel_Black25_Style")
		tab.setLayoutFlag("LoadVBoxPanelCenter", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("LoadVBoxPanelCenter", "LAYOUT_SIZE_VEXPANDING")

		tab.attachHBox("LoadVBoxPanelCenter", "LoadHBox")
		tab.setLayoutFlag("LoadHBox", "LAYOUT_HCENTER")

		# files dropdown
		szDropdownDesc = "LoadDropdownBox"
		szCallbackFunction = "Sto_DummyCallback"
		szWidgetName = "ListFilesDropdown"

		lastFileUsed = getLastFileUsedName()
		lastFileSaved = loadConfig("LastFileSaved")
		if lastFileSaved in listFile :
                        iInitialSelection = listFile.index(lastFileSaved)
		elif lastFileUsed in listFile :
                        iInitialSelection = listFile.index(lastFileUsed)
                else :
                        iInitialSelection = 0

		aszDropdownElements = tuple([getUText(item) for item in listFile])
		tab.attachDropDown("LoadHBox", szWidgetName, szDropdownDesc, aszDropdownElements, self.callbackIFace, szCallbackFunction, szWidgetName, iInitialSelection)
		tab.setLayoutFlag(szWidgetName, "LAYOUT_LEFT")

                tab.attachFixedSpacer("LoadHBox", 5)

		# Load button
                szOptionDesc = getUMenuText("TXT_LOAD_FILE")
                szCallbackFunction = "Sto_Load_File_Apply"
                szWidgetName = "LoadFileScreen"
                tab.attachButton("LoadHBox", szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

                tab.attachFixedSpacer("LoadHBox", 30)

		#create exit buttons
                szOptionDesc = getUMenuText("TXT_EXIT0")
                szCallbackFunction = "Sto_Exit_Load_Screen"
                szWidgetName = "ExitLoadScreen"
                tab.attachButton("LoadHBox", szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

# save file screen
class CvStoSaveFileScreen:

	def __init__(self):
		
		self.callbackIFace = "CvOptionsScreenCallbackInterface"
		
	def getTabControl(self):
		return self.pTabControl
		
	def interfaceScreen (self):
		self.szSaveScreenName = getUMenuText("TXT_TITTLE")
		self.szSaveOptionsTabName = getUText( getSMenuText("TXT_SAVE_FILE")+" :" )
		
		self.pTabControl = CyGTabCtrl(self.szSaveScreenName, false, false)
		self.pTabControl.setModal(1)

		resolution = [int(item) for item in CyUserProfile().getResolutionString(CyUserProfile().getResolution()).split("x") if item != "" ]
		self.pTabControl.setSize(int(resolution[0]*0.95), 300)
		self.pTabControl.setControlsExpanding(false)
		
		self.pTabControl.attachTabItem("SaveForm", self.szSaveOptionsTabName)

		# draw the screen
		tab = self.pTabControl

		tab.attachVBox("SaveForm", "SaveVBoxParent")
		
		tab.attachPanel("SaveVBoxParent", "SavePanelCenter")
		tab.setStyle("SavePanelCenter", "Panel_Tan15_Style")
		tab.setLayoutFlag("SavePanelCenter", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("SavePanelCenter", "LAYOUT_SIZE_VEXPANDING")
		
		tab.attachVBox("SavePanelCenter", "SaveVBoxCenter")
		tab.setLayoutFlag("SaveVBoxCenter", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("SaveVBoxCenter", "LAYOUT_VCENTER")

		tab.attachScrollPanel("SaveVBoxCenter", "SavePanel")
		tab.setLayoutFlag("SavePanel", "LAYOUT_SIZE_HEXPANDING")

		tab.attachVBox("SavePanel", "SaveVBox")
		tab.setLayoutFlag("SaveVBox", "LAYOUT_SIZE_HEXPANDING")
		
		tab.attachPanel("SaveVBox", "SaveVBoxPanelCenter")
		tab.setStyle("SaveVBoxPanelCenter", "Panel_Black25_Style")
		tab.setLayoutFlag("SaveVBoxPanelCenter", "LAYOUT_SIZE_HEXPANDING")
		tab.setLayoutFlag("SaveVBoxPanelCenter", "LAYOUT_SIZE_VEXPANDING")

		tab.attachHBox("SaveVBoxPanelCenter", "SaveHBox")
		tab.setLayoutFlag("SaveHBox", "LAYOUT_HCENTER")

                listFile = [ item for item in getListDirSto() if ((".cfg" in item) and (item[0] != "_")) ]
                listFile.sort()
		
		lastFileSaved = loadConfig("LastFileSaved")

		if lastFileSaved in listFile :
                        szEditBoxDesc = getUText(lastFileSaved[0:-4])
                        iInitialSelection = listFile.index(lastFileSaved) +1
                else :
                        szEditBoxDesc = getUMenuText("TXT_NEW_FILE")
                        iInitialSelection = 0
                        
		# file name editbox
		szOptionDescTip = getUMenuText("TXT_ED_SAVE_TIP")
                szCallbackFunction = "Sto_SaveFile_EditBox"
                szWidgetName = "SaveFileEditBox"
		tab.attachEdit("SaveHBox", szWidgetName, szEditBoxDesc, self.callbackIFace, szCallbackFunction, szWidgetName)
                tab.setToolTip(szWidgetName, szOptionDescTip)

                szLabelName = "SaveCfgLabel"
		tab.attachLabel("SaveHBox", szLabelName, getUText(".cfg"))

                tab.attachFixedSpacer("SaveHBox", 5)

		# files dropdown
		szDropdownDesc = "SaveDropdownBox"
		szCallbackFunction = "Sto_SaveFile_DropdownBox"
		szWidgetName = "ListFilesDropdown"
		lastFileUsed = getLastFileUsedName()
		lastFileSaved = loadConfig("LastFileSaved")
		aszDropdownElements = tuple([getUMenuText("TXT_NEW_FILE")]+[getUText(item) for item in listFile])
		tab.attachDropDown("SaveHBox", szWidgetName, szDropdownDesc, aszDropdownElements, self.callbackIFace, szCallbackFunction, szWidgetName, iInitialSelection)
		tab.setLayoutFlag(szWidgetName, "LAYOUT_LEFT")

                tab.attachFixedSpacer("SaveHBox", 5)

		# save button
                szOptionDesc = getUMenuText("TXT_SAVE_FILE")
                szCallbackFunction = "Sto_Save_File_Apply"
                szWidgetName = "SaveFileScreen"
                tab.attachButton("SaveHBox", szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

                tab.attachFixedSpacer("SaveHBox", 30)

		#create exit buttons
                szOptionDesc = getUMenuText("TXT_EXIT0")
                szCallbackFunction = "Sto_Exit_Load_Screen" # same call back with load screen
                szWidgetName = "StoExitSaveScreen"
                tab.attachButton("SaveHBox", szWidgetName, szOptionDesc, self.callbackIFace, szCallbackFunction, szWidgetName)

##!_!## menu initilization
def getDescription():
	return unicode("Full_of_Resources")
	
def isAdvancedMap():
	return 1

def getNumCustomMapOptions():
        global launchScreenNumOptions

        if launchScreenNumOptions :
                launchScreenNumOptions = False
                launchSetUpScreen()
                
	return 1

def getCustomMapOptionName(argsList):
        global launchScreenNumOptions

        initMenuGlobals()

        # getNumCustomMapOptions is called several times . ( if the map isn't already initailized , CyGame().getActivePlayer() return several times 0 )
        # getCustomMapOptionName is called only when entering the map selection screen . ( only one time because there is only one button )
        # if the map is already initialized : getNumCustomMapOptions is called another time after getCustomMapOptionName ,
        #  where you can know who is the active player and not in getCustomMapOptionName . (the active player is needed for MP games)
        if CyGame().getActivePlayer() != -1 :
                launchSetUpScreen()
        else :
                launchScreenNumOptions = True

	return getUMenuText("TXT_BUTTON_NAME")

def getNumCustomMapOptionValues(argsList):
	return 2
	
def getCustomMapOptionDescAt(argsList):
	[iOption, iSelection] = argsList

	if BtS :
                if iSelection == 0 : return getUMenuText("TXT_BUTTON_SEL0_BTS")
                else : return getUMenuText("TXT_BUTTON_SEL1_BTS")
        else :
                if iSelection == 0 : return getUMenuText("TXT_BUTTON_SEL0_VANILLA")
                else : return getUMenuText("TXT_BUTTON_SEL1_VANILLA")
	
def getCustomMapOptionDefault(argsList):
	return 0

def isRandomCustomMapOption(argsList):
	return False

##!_!## Text functions
def normalizeFloat(fl): # don't understand why round doesn't return a number with n digits
        sfl = str(fl)
        if "." in sfl :
                ifl , dfl = sfl.split(".")
                if len(dfl)>2 : dfl = dfl[0:2]
                fl = float(ifl+"."+dfl)
        return fl

def getUText(sText):
        return CvUtil.convertToUnicode(sText)

def getSText(sText):
        return CvUtil.convertToStr(sText)

def getUMenuText(sTag, rList=""):
        if sTag == "" : return ""
        if rList != "" : return getUText(textDic[sTag][language]  %rList)
        return getUText(textDic[sTag][language])

def getSMenuText(sTag, rList=""):
        if sTag == "" : return ""
        if rList != "" : return getSText(textDic[sTag][language]  %rList)
        return getSText(textDic[sTag][language])

textDic = {
        "TXT_BUTTON_NAME" : [
                "Options :" ,
                "Options :" ,
                "Optionen :" ,
                "Opzioni :" ,
                "Opciones :" ] ,
        "TXT_BUTTON_SEL0_BTS" : [
                "To edit the options ," ,
                "Pour éditer les options ," ,
                "Um die Wahlen zu redigieren ," ,
                "Per pubblicare le opzioni ," ,
                "Para corregir las opciones ," ] ,
        "TXT_BUTTON_SEL1_BTS" : [
                "change the selection of this button" ,
                "Changez la sélection de ce bouton" ,
                "ändern Sie die Vorwähler dieser Taste" ,
                "cambi la selezione di questo tasto" ,
                "cambie la selección de este botón" ] ,
        "TXT_BUTTON_SEL0_VANILLA" : [
                "To edit the options ," ,
                "Pour éditer les options ," ,
                "Um die Wahlen zu redigieren ," ,
                "Per pubblicare le opzioni ," ,
                "Para corregir las opciones ," ] ,
        "TXT_BUTTON_SEL1_VANILLA" : [
                "Select another map then come back" ,
                "Choisissez une autre carte puis revenez" ,
                "beschließen Sie ein anderes Diagramm zurückgehen dann" ,
                "scelga un altro programma allora rinviano" ,
                "elija otro mapa entonces vuelven" ] ,
        "TXT_FAILED_POPUP_INIT" : [
                "Sorry , it's impossible to launch the screen of the options. Please, report this bug on the forum." ,
                "Désolé , il est impossible de lancer l'écran des options. S'il vous plait , reporter ce bug sur le forum." ,
                "Traurig , ist es unmöglich, den Schirm der Wahlen auszustoßen. Bitte berichten Sie über diese Wanze auf dem Forum." ,
                "Spiacente , è impossible da lanciare lo schermo delle opzioni. Per favore, segnali questo insetto sulla tribuna." ,
                "Apesadumbrado , es imposible lanzar la pantalla de las opciones. Por favor, divulgue este insecto en el foro." ] ,
        "TXT_FAILED_POPUP_LOAD" : [
                "Error : the options could not be read" ,
                "Erreur : les options n'ont pas pues être lues" ,
                "Fehler : die Optionen haben nicht gestunken gelesen zu werden" ,
                "Errore : le opzioni pues essere letto" ,
                "Error : leerse las opciones no apestaron" ] ,
        "TXT_NO_FILE_TO_LOAD" : [
                "There is no file to currently load." ,
                "Il n'y a pas de fichier à charger actuellement." ,
                "Es gibt keine Akte, zum z.Z. zu laden." ,
                "Non ci è lima attualmente da caricare." ,
                "No hay archivo a cargar actualmente." ] ,
        "TXT_FAILED_POPUP_SAVE" : [
                "Error : the options could not be saved" ,
                "Erreur : les options n'ont pas pues être sauvegardées" ,
                "Fehler : die Optionen haben nicht gestunken registriert zu werden" ,
                "Errore : le opzioni pues essere registrato" ,
                "Error : registrarse las opciones no apestaron" ] ,
        "TXT_ED_SAVE_TIP" : [
                "Allowed characters : letters without accent, figures, space, _ ( except at the beginning of the name ), -" ,
                "Caractères permis : lettres sans accent, chiffres, espace, _ ( sauf au début du nom ), -" ,
                "Erlaubte Charaktere : Briefe ohne Akzent, Zahlen, Raum, _ ( außer zu Beginn des Namens ), -" ,
                "Caratteri permessi : lettere senza accento, cifre, spazio, _ ( eccetto all'inizio del nome ), -" ,
                "Caracteres permitidos : cartas sin acento, cifras, espacio, _ ( excepto al principio del nombre ), -" ] ,
        "TXT_NEW_FILE" : [
                "New file" ,
                "Nouveau fichier" ,
                "Neue Kartei" ,
                "Nuovo archivio" ,
                "Nuevo fichero" ] ,
        "TXT_ENTER_FILE_NAME" : [
                "Please, enter the name of the file ." ,
                "Svp, entrez le nom du fichier ." ,
                "Bitte gehen hinein der Name der Kartei ." ,
                "Per favore, entrate il nome dell'archivio ." ,
                "Por favor, entran el nombre del fichero ." ] ,
        "TXT_CHANGE_FILE_NAME" : [
                "Please, change the name of the file ." ,
                "Svp, changez le nom du fichier ." ,
                "Bitte ändern den Namen der Kartei ." ,
                "Per favore, cambiate il nome dell'archivio ." ,
                "Por favor, cambian el nombre del fichero ." ] ,
        "TXT_TITTLE" : [
                "Full of Resources" ,
                "Full of Resources" ,
                "Full of Resources" ,
                "Full of Resources" ,
                "Full of Resources" ] ,
        "TXT_INFOS" : [
                "^F_o_R^ :" ,
                "^F_o_R^ :" ,
                "^F_o_R^ :" ,
                "^F_o_R^ :" ,
                "^F_o_R^ :" ] ,
        "TXT_MAPS" : [
                "Maps :" ,
                "Cartes :" ,
                "Diagramme :" ,
                "Programmi :" ,
                "Mapas :" ] ,
        "TXT_TERRAIN" : [
                "Ground :" ,
                "Terrain :" ,
                "Gelände :" ,
                "Terreno :" ,
                "Terreno :" ] ,
        "TXT_RESOURCES" : [
                "Resources :" ,
                "Ressources :" ,
                "Betriebsmittel :" ,
                "Risorse :" ,
                "Recursos :" ] ,
        "TXT_STARTLOC" : [
                "Starting locations :" ,
                "Points de départ :" ,
                "Ausgangspunkte :" ,
                "Località di partenza :" ,
                "Puntos de partida :" ] ,
        "TXT_GAME_OPTIONS" : [
                "Game options :" ,
                "Options de jeu :" ,
                "Spielwahlen :" ,
                "Opzioni del gioco :" ,
                "Opciones del juego :" ] ,
        "TXT_RESET" : [
                "Reset" ,
                "Réinitialiser" ,
                "Neu initialisieren" ,
                "Reinizializzare" ,
                "Reinicializar" ] ,
        "TXT_RESET_ALL" : [
                "Reset all" ,
                "Réinitialiser tout" ,
                "Alles neu initialisieren" ,
                "Reinizializzare tutto" ,
                "Reinicializar todo" ] ,
        "TXT_REFRESH" : [
                "Verify" ,
                "Vérifier" ,
                "Prüfen" ,
                "Controlla" ,
                "Comprobar" ] ,
        "TXT_REFRESH_TIP" : [
                "This button is used to check if the values which you entered are valid." ,
                "Ce bouton sert à vérifier si les valeurs que vous avez entrées sont valables." ,
                "Dieser Knopf dient dazu zu prüfen, ob die Werte, die Sie hineingegangen sind, gültig sind." ,
                "Questo bottone serve a verificare se i valori in che essete entrato sono validi." ,
                "Este botón sirve para comprobar si los valores que entraron son válidos." ] ,
        "TXT_RESET_TABLE" : [
                "Reset the table" ,
                "Réinitialiser la table" ,
                "Die Tafel neu initialisieren" ,
                "Reinizializzare la tavola" ,
                "Reinicializar la tabla" ] ,
        "TXT_LOAD_FILE" : [
                "Load File" ,
                "Charger fichier" ,
                "Datei laden" ,
                "Carica file" ,
                "Cargar archivo" ] ,
        "TXT_SAVE_FILE" : [
                "Save File" ,
                "Sauvegarder fichier" ,
                "Datei speichern" ,
                "Salva file" ,
                "Guardar archivo" ] ,
        "TXT_EXIT0" : [
                "Exit" ,
                "Sortir" ,
                "Ende" ,
                "Uscire" ,
                "Salir" ] ,
        "TXT_EXIT" : [
                "Confirm and Exit" ,
                "Confirmer et Sortir" ,
                "Ende" ,
                "Confermare ed uscire" ,
                "Confirmar y salir" ] ,
        "TXT_MAPS_WRAP" : [
                "World Wrap :" ,
                "Globe terrestre :" ,
                "Weltkugeldrehung :" ,
                "Estensione del pianeta :" ,
                "Cobertura del mundo :" ] ,
        "TXT_MAPS_WRAP_SEL0" : [
                "Flat" ,
                "Plat" ,
                "Flach" ,
                "Piatto" ,
                "Plana" ] ,
        "TXT_MAPS_WRAP_SEL1" : [
                "Cylindrical" ,
                "Cylindrique" ,
                "Zylindrisch" ,
                "Cilindrico" ,
                "Cilíndrico" ] ,
        "TXT_MAPS_WRAP_SEL2" : [
                "Toroidal" ,
                "Toroïdal" ,
                "Ringförmig" ,
                "Toroidale" ,
                "Toroidal" ] ,
        "TXT_MAPS_START" : [
                "Start :" ,
                "Commencer :" ,
                "Start :" ,
                "Cominciare :" ,
                "Comenzar :" ] ,
        "TXT_MAPS_START_SEL0" : [
                "On the coast" ,
                "Sur la côte" ,
                "An der Küste" ,
                "Sulla costa" ,
                "Sobre la costa" ] ,
        "TXT_MAPS_START_SEL1" : [
                "Inland" ,
                "A l'intérieur des terres" ,
                "Innerhalb der Erde" ,
                "All'interno delle terre" ,
                "Dentro de las tierras" ] ,
        "TXT_MAPS_WATER_PERCENT" : [
                "Water percentage :" ,
                "Pourcentage d'eau :" ,
                "Prozentsatz Wasser :" ,
                "Percentuale d'acqua :" ,
                "Porcentaje de agua :" ] ,
        "TXT_VALUE" : [
                "Value" ,
                "Valeur" ,
                "Wert" ,
                "Valore" ,
                "Valor" ] ,
        "TXT_RANDOM" : [
                "Random" ,
                "Aléatoire" ,
                "Zufällig" ,
                "Casuale" ,
                "Al azar" ] ,
        "TXT_BETWEEN" : [
                " , between" ,
                " , entre" ,
                " , zwischen" ,
                " , tra" ,
                " , entre" ] ,
        "TXT_AND" : [
                "and" ,
                "et" ,
                "und" ,
                "e" ,
                "y" ] ,
        "TXT_MAPS_ARCHI_LANDMASS" : [
                "Landmass Type :" ,
                "Type continents :" ,
                "Landmassentyp :" ,
                "Tipo massa terra :" ,
                "Tipo de masa de tierra :" ] ,
        "TXT_MAPS_ARCHI_LANDMASS_SEL0" : [
                "Snaky Continents" ,
                "Continents sinueux" ,
                "Gewundene Kontinente" ,
                "Continenti tortuosi" ,
                "Continentes tortuosos" ] ,
        "TXT_MAPS_ARCHI_LANDMASS_SEL1" : [
                "Archipelago" ,
                "Archipel" ,
                "Archipel" ,
                "Arcipelago" ,
                "archipiélago" ] ,
        "TXT_MAPS_ARCHI_LANDMASS_SEL2" : [
                "Tiny Islands" ,
                "Ilots" ,
                "Winzige Inseln" ,
                "Isole minuscole" ,
                "Islas diminutas" ] ,
        "TXT_MAPS_CC_NB_CONTINENTS" : [
                "Number of Continents :" ,
                "Nombre de continents :" ,
                "Anzahl der Kontinente :" ,
                "Numero di continenti :" ,
                "Número de continentes :" ] ,
        "TXT_MAPS_CC_NB_CONTINENTS_SEL0" : [
                "Random" ,
                "Aléatoire" ,
                "Zufällig" ,
                "Casuale" ,
                "Al azar" ] ,
        "TXT_MAPS_CC_NB_CONTINENTS_SEL1" : [
                "One Per Team" ,
                "1 par équipe" ,
                "1 pro Team" ,
                "Una per squadra" ,
                "Una por equipo" ] ,
        "TXT_MAPS_CC_NB_CONTINENTS_SEL2" : [
                "2" ,
                "2" ,
                "2" ,
                "2" ,
                "2" ] ,
        "TXT_MAPS_CC_NB_CONTINENTS_SEL3" : [
                "3" ,
                "3" ,
                "3" ,
                "3" ,
                "3" ] ,
        "TXT_MAPS_CC_NB_CONTINENTS_SEL4" : [
                "4" ,
                "4" ,
                "4" ,
                "4" ,
                "4" ] ,
        "TXT_MAPS_CC_NB_CONTINENTS_SEL5" : [
                "5" ,
                "5" ,
                "5" ,
                "5" ,
                "5" ] ,
        "TXT_MAPS_CC_NB_CONTINENTS_SEL6" : [
                "6" ,
                "6" ,
                "6" ,
                "6" ,
                "6" ] ,
        "TXT_MAPS_AREAS_PER_PLAYER" : [
                "Areas Per Player :" ,
                "Zones par joueur :" ,
                "Zonen pro Spieler :" ,
                "Aree per giocatore :" ,
                "Áreas Por Jugador :" ] ,
        "TXT_MAPS_AREAS_PER_PLAYER_SEL0" : [
                "1 Per Player" ,
                "1 par joueur" ,
                "1 pro Spieler" ,
                "1 per giocatore" ,
                "1 por jugador" ] ,
        "TXT_MAPS_AREAS_PER_PLAYER_SEL1" : [
                "2 (10 Players Max)" ,
                "2 (10 joueurs maxi)" ,
                "2 (max. 10 Spieler)" ,
                "2 (massimo 10 giocatori)" ,
                "2 (máx. 10 jugadores)" ] ,
        "TXT_MAPS_LAND_SHAPE" : [
                "Land Shape :" ,
                "Forme :" ,
                "Landform :" ,
                "Forma terra :" ,
                "Forma de la tierra :" ] ,
        "TXT_MAPS_LAND_SHAPE_SEL0" : [
                "Natural" ,
                "Naturel" ,
                "Natürlich" ,
                "Naturale" ,
                "Natural" ] ,
        "TXT_MAPS_LAND_SHAPE_SEL1" : [
                "Pressed" ,
                "Serré" ,
                "Gedrängt" ,
                "Pressato" ,
                "Escaso" ] ,
        "TXT_MAPS_LAND_SHAPE_SEL2" : [
                "Solid" ,
                "Solide" ,
                "Solide" ,
                "Solido" ,
                "Compacto" ] ,
        "TXT_MAPS_NEUTRAL_TERRITORY" : [
                "Neutral Territory :" ,
                "Territoire neutre :" ,
                "Neutrales Territorium :" ,
                "Territorio neutrale :" ,
                "Territorio neutral :" ] ,
        "TXT_MAPS_NEUTRAL_TERRITORY_SEL0" : [
                "Varied" ,
                "Varié" ,
                "Abwechslungsreich" ,
                "Vario" ,
                "Variado" ] ,
        "TXT_MAPS_NEUTRAL_TERRITORY_SEL1" : [
                "Pressed" ,
                "Serré" ,
                "Gedrängt" ,
                "Pressato" ,
                "Escaso" ] ,
        "TXT_MAPS_NEUTRAL_TERRITORY_SEL2" : [
                "Natural" ,
                "Naturel" ,
                "Natürlich" ,
                "Naturale" ,
                "Natural" ] ,
        "TXT_MAPS_NEUTRAL_TERRITORY_SEL3" : [
                "Islands" ,
                "Iles" ,
                "Inseln" ,
                "Isole" ,
                "Islas" ] ,
        "TXT_MAPS_ISTHMUS_WIDTH" : [
                "Isthmus Width :" ,
                "Largeur isthme :" ,
                "Landengenbreite :" ,
                "Larghezza istmo :" ,
                "Ancho del istmo :" ] ,
        "TXT_MAPS_ISTHMUS_WIDTH_SEL0" : [
                "1 Plot Wide" ,
                "1 case" ,
                "1 Geländefeld breit" ,
                "Largo 1 terreno" ,
                "1 casilla de ancho" ] ,
        "TXT_MAPS_ISTHMUS_WIDTH_SEL1" : [
                "2 Plots Wide" ,
                "2 cases" ,
                "2 Geländefelder breit" ,
                "Largo 2 terreni" ,
                "2 casillas de ancho" ] ,
        "TXT_MAPS_ISTHMUS_WIDTH_SEL2" : [
                "3 Plots Wide" ,
                "3 cases" ,
                "3 Geländefelder breit" ,
                "Largo 3 terreni" ,
                "3 casillas de ancho" ] ,
        "TXT_MAPS_LARGE_ISLANDS" : [
                "Number of Large Islands :" ,
                "Nombre de grandes îles" ,
                "Anzahl der großen Inseln :" ,
                "Numero di isole grandi :" ,
                "Número de grandes islas :" ] ,
        "TXT_MAPS_LARGE_ISLANDS_SEL0" : [
                "1 Per Player" ,
                "1 par joueur" ,
                "1 pro Spieler" ,
                "1 per giocatore" ,
                "1 por jugador" ] ,
        "TXT_MAPS_LARGE_ISLANDS_SEL1" : [
                "Extras" ,
                "Extras" ,
                "Extras" ,
                "Extra" ,
                "Extras" ] ,
        "TXT_MAPS_LARGE_ISLANDS_SEL2" : [
                "Several Extras" ,
                "Plusieurs extras" ,
                "Einige Extras" ,
                "Diversi extra" ,
                "Extras varios" ] ,
        "TXT_MAPS_TINY_ISLANDS" : [
                "Number of Tiny Islands :" ,
                "Nombre d'îlots :" ,
                "Anzahl der winzigen Inseln :" ,
                "Numero di isole minuscole :" ,
                "Número de islas diminutas :" ] ,
        "TXT_MAPS_TINY_ISLANDS_SEL0" : [
                "No Tiny Islands" ,
                "Pas d'îlots" ,
                "Keine winzigen Inseln" ,
                "Nessuna isola minuscola" ,
                "Sin islas diminutas" ] ,
        "TXT_MAPS_TINY_ISLANDS_SEL1" : [
                "Few Tiny Islands" ,
                "Quelques îlots" ,
                "Wenige winzige Inseln" ,
                "Poche isole minuscole" ,
                "Pocas islas diminutas" ] ,
        "TXT_MAPS_TINY_ISLANDS_SEL2" : [
                "Various Tiny Islands" ,
                "Plusieurs îlots variés" ,
                "Diverse winzige Inseln" ,
                "Varie isole minuscole" ,
                "Varias islas diminutas" ] ,
        "TXT_MAPS_TINY_ISLANDS_SEL3" : [
                "Many Tiny Islands" ,
                "Beaucoup d'îlots" ,
                "Viele winzige Inseln" ,
                "Molte isole minuscole" ,
                "Muchas islas diminutas" ] ,
        "TXT_MAPS_LAKES_SIZE" : [
                "Sizes of the lakes :" ,
                "Tailles des lacs :" ,
                "Größen der Seen :" ,
                "Dimensioni dei laghi :" ,
                "Tamaños de los lagos :" ] ,
        "TXT_MAPS_LAKES_SIZE_SEL0" : [
                "Standard ( Large )" ,
                "Standard ( Grandes )" ,
                "Standard ( Groß )" ,
                "Standard ( Grandi )" ,
                "Norma ( Grandes )" ] ,
        "TXT_MAPS_LAKES_SIZE_SEL1" : [
                "Average" ,
                "Moyennes" ,
                "Durchschnitte" ,
                "Medie" ,
                "Medias" ] ,
        "TXT_MAPS_LAKES_SIZE_SEL2" : [
                "Small" ,
                "Petites" ,
                "Klein" ,
                "Piccole" ,
                "Pequeñas" ] ,
        "TXT_MAPS_LAKES_SIZE_SEL3" : [
                "Very small" ,
                "Très petites" ,
                "Sehr klein" ,
                "Molto piccole" ,
                "Muy pequeñas" ] ,
        "TXT_MAPS_MAZE_WIDTH" : [
                "Maze Width :" ,
                "Largeur labyrinthe :" ,
                "Labyrinthbreite :" ,
                "Larghezza labirinto :" ,
                "Ancho del laberinto :" ] ,
        "TXT_MAPS_MAZE_WIDTH_SEL0" : [
                "1 Plot Wide" ,
                "1 case" ,
                "1 Geländefeld breit" ,
                "Largo 1 terreno" ,
                "1 casilla de ancho" ] ,
        "TXT_MAPS_MAZE_WIDTH_SEL1" : [
                "2 Plots Wide" ,
                "2 cases" ,
                "2 Geländefelder breit" ,
                "Largo 2 terreni" ,
                "2 casillas de ancho" ] ,
        "TXT_MAPS_MAZE_WIDTH_SEL2" : [
                "3 Plots Wide" ,
                "3 cases" ,
                "3 Geländefelder breit" ,
                "Largo 3 terreni" ,
                "3 casillas de ancho" ] ,
        "TXT_MAPS_MAZE_WIDTH_SEL3" : [
                "4 Plots Wide" ,
                "4 cases" ,
                "4 Geländefelder breit" ,
                "Largo 4 terreni" ,
                "4 casillas de ancho" ] ,
        "TXT_MAPS_MAZE_WIDTH_SEL4" : [
                "5 Plots Wide" ,
                "5 cases" ,
                "5 Geländefelder breit" ,
                "Largo 5 terreni" ,
                "5 casillas de ancho" ] ,
        "TXT_MAPS_SHORELINE" : [
                "Shoreline :" ,
                "Côte :" ,
                "Ufer :" ,
                "Riva :" ,
                "Litoral :" ] ,
        "TXT_MAPS_SHORELINE_SEL0" : [
                "Random" ,
                "Aléatoire" ,
                "Zufällig" ,
                "Casuale" ,
                "Al azar" ] ,
        "TXT_MAPS_SHORELINE_SEL1" : [
                "Natural" ,
                "Naturel" ,
                "Natürlich" ,
                "Naturale" ,
                "Natural" ] ,
        "TXT_MAPS_SHORELINE_SEL2" : [
                "Pressed" ,
                "Serré" ,
                "Gedrängt" ,
                "Pressato" ,
                "Escaso" ] ,
        "TXT_MAPS_SHORELINE_SEL3" : [
                "Solid" ,
                "Solide" ,
                "Solide" ,
                "Solido" ,
                "Compacto" ] ,
        "TXT_MAPS_START_TERRA" : [
                "Start :" ,
                "Commencer :" ,
                "Start :" ,
                "Cominciare :" ,
                "Comenzar :" ] ,
        "TXT_MAPS_START_TERRA_SEL0" : [
                "On the coast" ,
                "Sur la côte" ,
                "An der Küste" ,
                "Sulla costa" ,
                "Sobre la costa" ] ,
        "TXT_MAPS_START_TERRA_SEL1" : [
                "Inland" ,
                "A l'intérieur des terres" ,
                "Innerhalb der Erde" ,
                "All'interno delle terre" ,
                "Dentro de las tierras" ] ,
        "TXT_MAPS_START_TERRA_SEL2" : [
                "All on the same continent" ,
                "Tous sur le même continent" ,
                "Alle auf dem gleichen Kontinent" ,
                "Tutti sullo stesso continente" ,
                "Todos en el mismo continente" ] ,
        "TXT_MAPS_RING_WIDTH" : [
                "Ring Width :" ,
                "Largeur anneau :" ,
                "Ringbreite :" ,
                "Larghezza anello :" ,
                "Ancho del anillo :" ] ,
        "TXT_MAPS_RING_WIDTH_SEL0" : [
                "1 Plot Wide" ,
                "1 case" ,
                "1 Geländefeld breit" ,
                "Largo 1 terreno" ,
                "1 casilla de ancho" ] ,
        "TXT_MAPS_RING_WIDTH_SEL1" : [
                "2 Plots Wide" ,
                "2 cases" ,
                "2 Geländefelder breit" ,
                "Largo 2 terreni" ,
                "2 casillas de ancho" ] ,
        "TXT_MAPS_RING_WIDTH_SEL2" : [
                "3 Plots Wide" ,
                "3 cases" ,
                "3 Geländefelder breit" ,
                "Largo 3 terreni" ,
                "3 casillas de ancho" ] ,
        "TXT_MAPS_SPOKE_WIDTH" : [
                "Spoke Width :" ,
                "Largeur rayon :" ,
                "Speichenbreite :" ,
                "Larghezza raggi :" ,
                "Ancho de los radios :" ] ,
        "TXT_MAPS_SPOKE_WIDTH_SEL0" : [
                "1 Plot Wide" ,
                "1 case" ,
                "1 Geländefeld breit" ,
                "Largo 1 terreno" ,
                "1 casilla de ancho" ] ,
        "TXT_MAPS_SPOKE_WIDTH_SEL1" : [
                "2 Plots Wide" ,
                "2 cases" ,
                "2 Geländefelder breit" ,
                "Largo 2 terreni" ,
                "2 casillas de ancho" ] ,
        "TXT_MAPS_SPOKE_WIDTH_SEL2" : [
                "3 Plots Wide" ,
                "3 cases" ,
                "3 Geländefelder breit" ,
                "Largo 3 terreni" ,
                "3 casillas de ancho" ] ,
        "TXT_MAPS_CONTINENTS_SIZE" : [
                "Continents Size :" ,
                "Taille des continents :" ,
                "Kontinentgröße :" ,
                "Dimensione dei continenti :" ,
                "Tamaño de los continentes :" ] ,
        "TXT_MAPS_CONTINENTS_SIZE_SEL0" : [
                "Massive Continents" ,
                "Continents massifs" ,
                "Massive Kontinente" ,
                "Continenti enormi" ,
                "Continentes enormes" ] ,
        "TXT_MAPS_CONTINENTS_SIZE_SEL1" : [
                "Normal Continents" ,
                "Continents normaux" ,
                "Normale Kontinente" ,
                "Continenti normali" ,
                "Continentes normales" ] ,
        "TXT_MAPS_CONTINENTS_SIZE_SEL2" : [
                "Snaky Continents" ,
                "Continents sinueux" ,
                "Gewundene Kontinente" ,
                "Continenti tortuosi" ,
                "Continentes tortuosos" ] ,
        "TXT_MAPS_ISLANDS_SIZE" : [
                "Islands Size :" ,
                "Taille des îles :" ,
                "Inselgröße :" ,
                "Dimensione delle isole :" ,
                "Tamaño de las islas :" ] ,
        "TXT_MAPS_ISLANDS_SIZE_SEL0" : [
                "Islands" ,
                "Iles" ,
                "Inseln" ,
                "Isole" ,
                "Islas" ] ,
        "TXT_MAPS_ISLANDS_SIZE_SEL1" : [
                "Tiny Islands" ,
                "Ilots" ,
                "Winzige Inseln" ,
                "Isole minuscole" ,
                "Islas diminutas" ] ,
        "TXT_MAPS_ISLAND_OVERLAP" : [
                "Island Overlap :" ,
                "Superposition des îles :" ,
                "Inselüberlagerung :" ,
                "Sovrapposizione isole :" ,
                "Solapamiento de islas :" ] ,
        "TXT_MAPS_ISLAND_OVERLAP_SEL0" : [
                "Island Region Separate" ,
                "Séparation des régions insulaires" ,
                "Separate Inselregionen" ,
                "Separa regioni isolane" ,
                "Región de islas separada" ] ,
        "TXT_MAPS_ISLAND_OVERLAP_SEL1" : [
                "Islands Mixed In" ,
                "Mélange des îles" ,
                "Gemischte Inseln" ,
                "Isole mischiate" ,
                "Isole mischiate" ] ,
        "TXT_MAPS_HEM_CONTINENTS_SIZE" : [
                "Continents Size :" ,
                "Taille des continents :" ,
                "Kontinentgröße :" ,
                "Dimensione dei continenti :" ,
                "Tamaño de los continentes :" ] ,
        "TXT_MAPS_HEM_CONTINENTS_SIZE_SEL0" : [
                "Massive Continents" ,
                "Continents massifs" ,
                "Massive Kontinente" ,
                "Continenti enormi" ,
                "Continentes enormes" ] ,
        "TXT_MAPS_HEM_CONTINENTS_SIZE_SEL1" : [
                "Normal Continents" ,
                "Continents normaux" ,
                "Normale Kontinente" ,
                "Continenti normali" ,
                "Continentes normales" ] ,
        "TXT_MAPS_HEM_CONTINENTS_SIZE_SEL2" : [
                "Snaky Continents" ,
                "Continents sinueux" ,
                "Gewundene Kontinente" ,
                "Continenti tortuosi" ,
                "Continentes tortuosos" ] ,
        "TXT_MAPS_HEM_CONTINENTS_SIZE_SEL3" : [
                "Varied" ,
                "Varié" ,
                "Abwechslungsreich" ,
                "Vario" ,
                "Variado" ] ,
        "TXT_MAPS_HEM_NB_CONTINENTS" : [
                "Number of Continents :" ,
                "Nombre de continents :" ,
                "Anzahl der Kontinente :" ,
                "Numero di continenti :" ,
                "Número de continentes :" ] ,
        "TXT_MAPS_HEM_NB_CONTINENTS_SEL0" : [
                "2" ,
                "2" ,
                "2" ,
                "2" ,
                "2" ] ,
        "TXT_MAPS_HEM_NB_CONTINENTS_SEL1" : [
                "3" ,
                "3" ,
                "3" ,
                "3" ,
                "3" ] ,
        "TXT_MAPS_HEM_NB_CONTINENTS_SEL2" : [
                "4" ,
                "4" ,
                "4" ,
                "4" ,
                "4" ] ,
        "TXT_MAPS_HEM_NB_CONTINENTS_SEL3" : [
                "5" ,
                "5" ,
                "5" ,
                "5" ,
                "5" ] ,
        "TXT_MAPS_HEM_NB_CONTINENTS_SEL4" : [
                "6" ,
                "6" ,
                "6" ,
                "6" ,
                "6" ] ,
        "TXT_MAPS_MAS_CONTINENTS_SIZE" : [
                "Continents Size :" ,
                "Taille des continents :" ,
                "Kontinentgröße :" ,
                "Dimensione dei continenti :" ,
                "Tamaño de los continentes :" ] ,
        "TXT_MAPS_MAS_CONTINENTS_SIZE_SEL0" : [
                "Normal Continents" ,
                "Continents normaux" ,
                "Normale Kontinente" ,
                "Continenti normali" ,
                "Continentes normales" ] ,
        "TXT_MAPS_MAS_CONTINENTS_SIZE_SEL1" : [
                "Unpredictable" ,
                "Imprévisible" ,
                "Unvorhersehbar" ,
                "Imprevedibile" ,
                "Impredecible" ] ,
        "TXT_MAPS_MAS_CONTINENTS_SIZE_SEL2" : [
                "Snaky Continents" ,
                "Continents sinueux" ,
                "Gewundene Kontinente" ,
                "Continenti tortuosi" ,
                "Continentes tortuosos" ] ,
        "TXT_MAPS_MAS_CONTINENTS_SIZE_SEL3" : [
                "Islands" ,
                "Iles" ,
                "Inseln" ,
                "Isole" ,
                "Islas" ] ,
        "TXT_MAPS_MAS_CONTINENTS_SIZE_SEL4" : [
                "Random" ,
                "Aléatoire" ,
                "Zufällig" ,
                "Casuale" ,
                "Al azar" ] ,
        "TXT_TERRAIN_DES" : [
                "Grounds :" ,
                "Terrains :" ,
                "Gelände :" ,
                "Terreni :" ,
                "Terrenos :" ] ,
        "TXT_TERRAIN_RIVER" : [
                "Rivers :" ,
                "Rivières :" ,
                "Flüsse :" ,
                "Fiumi :" ,
                "Rios :" ] ,
        "TXT_TERRAIN_ISLAND" : [
                "Islands :" ,
                "Iles :" ,
                "Inseln :" ,
                "Isole :" ,
                "Islas :" ] ,
        "TXT_TERRAIN_GRASS" : [
                "Grassland :" ,
                "Prairie :" ,
                "Grasland :" ,
                "Prateria :" ,
                "Pradera :" ] ,
        "TXT_TERRAIN_GRASS_SEL0" : [
                "Cursed grounds" ,
                "Terres maudites" ,
                "Verfluchter Boden" ,
                "Terre maledette" ,
                "Tierras maldecidas" ] ,
        "TXT_TERRAIN_GRASS_SEL1" : [
                "Pleasant (Standard)" ,
                "Plaisantes (Standard)" ,
                "Ausgewogen (Standard)" ,
                "Piacevoli (Standard)" ,
                "Agradables (Norma)" ] ,
        "TXT_TERRAIN_GRASS_SEL2" : [
                "Rich" ,
                "Riche" ,
                "Reich" ,
                "Ricco" ,
                "Rico" ] ,
        "TXT_TERRAIN_GRASS_SEL3" : [
                "Luxuriant" ,
                "Luxuriantes" ,
                "Üppig" ,
                "Lussureggianti" ,
                "Exuberantes" ] ,
        "TXT_TERRAIN_PLAIN" : [
                "Plains :" ,
                "Plaines :" ,
                "Ebene :" ,
                "Pianure :" ,
                "Llanuras :" ] ,
        "TXT_TERRAIN_PLAIN_SEL0" : [
                "Traces" ,
                "Des traces" ,
                "Spuren" ,
                "Tracce" ,
                "Rastros" ] ,
        "TXT_TERRAIN_PLAIN_SEL1" : [
                "Dispersed (Standard)" ,
                "Dispersées (Standard)" ,
                "Vereinzelt (Standard)" ,
                "Sparse (Standard)" ,
                "Dispersadas (Norma)" ] ,
        "TXT_TERRAIN_PLAIN_SEL2" : [
                "Large plains" ,
                "Grandes plaines" ,
                "Große Ebenen" ,
                "Grandi pianure" ,
                "Grandes llanos" ] ,
        "TXT_TERRAIN_PLAIN_SEL3" : [
                "Djebels" ,
                "Djebels" ,
                "Mächtig" ,
                "Djebels" ,
                "Djebels" ] ,
        "TXT_TERRAIN_DESERT" : [
                "Desert :" ,
                "Désert :" ,
                "Wüste :" ,
                "Deserto :" ,
                "Desierto :" ] ,
        "TXT_TERRAIN_DESERT_SEL0" : [
                "Without" ,
                "Sans" ,
                "Ohne" ,
                "Senza" ,
                "Sin" ] ,
        "TXT_TERRAIN_DESERT_SEL1" : [
                "Oasis" ,
                "Oasis" ,
                "Oase" ,
                "Oasi" ,
                "Oasis" ] ,
        "TXT_TERRAIN_DESERT_SEL2" : [
                "Dispersed" ,
                "Dispersé" ,
                "Vereinzelt" ,
                "Disperso" ,
                "Dispersado" ] ,
        "TXT_TERRAIN_DESERT_SEL3" : [
                "Arid (Standard)" ,
                "Aride (Standard)" ,
                "Trocken (Standard)" ,
                "Arido (Standard)" ,
                "Árido (Norma)" ] ,
        "TXT_TERRAIN_DESERT_SEL4" : [
                "Sahara" ,
                "Sahara" ,
                "Sahara" ,
                "Sahara" ,
                "Sahara" ] ,
        "TXT_TERRAIN_TUNDRA" : [
                "Tundra :" ,
                "Toundra :" ,
                "Tundra :" ,
                "Tundra :" ,
                "Tundra :" ] ,
        "TXT_TERRAIN_TUNDRA_SEL0" : [
                "Without" ,
                "Sans" ,
                "Ohne" ,
                "Senza" ,
                "Sin" ] ,
        "TXT_TERRAIN_TUNDRA_SEL1" : [
                "Traces" ,
                "Des traces" ,
                "Spuren" ,
                "Tracce" ,
                "Rastros" ] ,
        "TXT_TERRAIN_TUNDRA_SEL2" : [
                "Dispersed" ,
                "Dispersé" ,
                "Vereinzelt" ,
                "Disperso" ,
                "Dispersado" ] ,
        "TXT_TERRAIN_TUNDRA_SEL3" : [
                "Steppes (Standard)" ,
                "Steppes (Standard)" ,
                "Steppen (Standard)" ,
                "Steppe (Standard)" ,
                "stepas (Norma)" ] ,
        "TXT_TERRAIN_TUNDRA_SEL4" : [
                "Devastated grounds" ,
                "Terres dévastées" ,
                "Verödeter Boden" ,
                "Terre devastate" ,
                "Tierras devastadas" ] ,
        "TXT_TERRAIN_SNOW" : [
                "Snow :" ,
                "Neige :" ,
                "Schnee :" ,
                "Neve :" ,
                "Nieve :" ] ,
        "TXT_TERRAIN_SNOW_SEL0" : [
                "Without" ,
                "Sans" ,
                "Ohne" ,
                "Senza" ,
                "Sin" ] ,
        "TXT_TERRAIN_SNOW_SEL1" : [
                "Traces" ,
                "Des traces" ,
                "Spuren" ,
                "Tracce" ,
                "Rastros" ] ,
        "TXT_TERRAIN_SNOW_SEL2" : [
                "Dispersed" ,
                "Dispersée" ,
                "Vereinzelt" ,
                "Dispersa" ,
                "Dispersada" ] ,
        "TXT_TERRAIN_SNOW_SEL3" : [
                "Cold (Standard)" ,
                "Froid (Standard)" ,
                "Kält (Standard)" ,
                "Freddo (Standard)" ,
                "Frío (Norma)" ] ,
        "TXT_TERRAIN_SNOW_SEL4" : [
                "North Pole" ,
                "Pôle nord" ,
                "Nordpol" ,
                "Polo Nord" ,
                "Polo Norte" ] ,
        "TXT_TERRAIN_FOREST_PERCENT" : [
                "Percentage of forest :" ,
                "Pourcentage de forêt :" ,
                "Prozentsatz Wald :" ,
                "Percentuale di foresta :" ,
                "Porcentaje de bosque :" ] ,
        "TXT_TERRAIN_JUNGLE_PERCENT" : [
                "Percentage of jungle :" ,
                "Pourcentage de jungle :" ,
                "Prozentsatz Dschungel :" ,
                "Percentuale di giungla :" ,
                "Porcentaje de selva :" ] ,
        "TXT_TERRAIN_TIP_JUNGLE" : [
                "%d %% is the default value. According to maps', that represents the proportion of jungle placed at the equator or a value relative to a maximum of jungle ( for the maps without climate )." ,
                "%d %% est la valeur par défaut. Selon les cartes , cela représente la proportion de jungle placée à l'équateur ou une valeur relative à un maximum de jungle ( pour les cartes sans climat )." ,
                "%d %% ist der Default-Wert. Entsprechend Karten stellt das den Anteil Dschungel gesetzt am Äquator oder an einem Wert im Verhältnis zu einem Maximum des Dschungels dar ( für die Karten ohne Klima )." ,
                "%d %% sono il valore di difetto. Secondo i programmi, quello rappresenta la proporzione della giungla disposta all'Equatore o ad un valore riguardante un massimo della giungla ( per i programmi senza clima )." ,
                "%d %% es el valor prefijado. Según los mapas, eso representa la proporción de la selva puesta en el ecuador o un valor concerniente a un máximo de la selva ( para los mapas sin clima )." ] ,
        "TXT_TERRAIN_PEAK_PERCENT" : [
                "Percentage of mountains :" ,
                "Pourcentage de montagnes :" ,
                "Prozentsatz Berge :" ,
                "Percentuale di montagne :" ,
                "Porcentaje de montañas :" ] ,
        "TXT_TERRAIN_PEAKCOAST" : [
                "Mountains along the coasts :" ,
                "Montagnes le long des côtes :" ,
                "Berge entlang der Küsten :" ,
                "Montagne lungo le coste :" ,
                "Montañas a lo largo de las costas :" ] ,
        "TXT_TERRAIN_PEAKCOAST_SEL0" : [
                "Remove" ,
                "Enlever" ,
                "Wegnehmen" ,
                "Togliere" ,
                "Retirar" ] ,
        "TXT_TERRAIN_ICE" : [
                "Ice :" ,
                "Glace :" ,
                "Eis :" ,
                "Ghiaccio :" ,
                "Hielo :" ] ,
        "TXT_TERRAIN_ICE_SEL0" : [
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Norma" ] ,
        "TXT_TERRAIN_ICE_SEL1" : [
                "Remove along the coasts" ,
                "Enlever le long des côtes" ,
                "Entlang der Küsten wegnehmen" ,
                "Togliere lungo le coste" ,
                "Retirar a lo largo de las costas" ] ,
        "TXT_TERRAIN_ICE_SEL2" : [
                "Remove" ,
                "Enlever" ,
                "Wegnehmen" ,
                "Togliere" ,
                "Retirar" ] ,
        "TXT_TERRAIN_HILL_PERCENT" : [
                "Percentage of hills :" ,
                "Pourcentage de collines :" ,
                "Prozentsatz Hügel :" ,
                "Percentuale di colline :" ,
                "Porcentaje de colinas :" ] ,
        "TXT_TERRAIN_RIVEREDGE" : [
                "Number of plots per river edge :" ,
                "Nombre de cases de terrain par bord de rivières :" ,
                "Anzahl der Geländekästen durch Flußrand :" ,
                "Numero di scatole di terreno per bordo di fiumi :" ,
                "Muchas casillas de terreno por borde de ríos :" ] ,
        "TXT_TERRAIN_TIP_RIVEREDGE" : [
                "%d is the default value. the program makes rivers until the number of tiles of ground divided by the number of segments of rivers is lower than this value. The smaller this number is, the more there will be rivers." ,
                "%d est la valeur par défaut . Le programme fait des rivières jusqu'à ce que le nombre de cases de terrain divisé par le nombre de segments de rivières soit inférieur à cette valeur. Plus ce nombre est petit , plus il y aura de rivières." ,
                "%d ist die Standardvorgabe. Das Programm macht Flüsse, bis die Anzahl der Kästen des Geländes, das durch die Anzahl der Flußsegmente geteilt wurde, niedriger als dieser Wert ist. Mehr ist diese Zahl klein, mehr wird es Flüsse geben." ,
                "%d è il valore per difetto. Il programma fa fiumi fino a che il numero di scatole di terreno diviso per il numero di segmenti di fiumi sia inferiore a questo valore. Più questo numero è piccolo, più ci saranno fiumi." ,
                "%d son el valor por defecto. El programa hace ríos hasta que el número de casillas de terreno dividido por el número de segmentos de ríos sea inferior a este valor. Cuanto más este número es pequeño, más habrá ríos." ] ,
        "TXT_TERRAIN_NBTILESMIN" : [
                "Minimum number of plots :" ,
                "Nombre minimum des cases de terrain :" ,
                "Mindestzahl der Plots :" ,
                "Numero minimo di diagrammi :" ,
                "Número mínimo de diagramas :" ] ,
        "TXT_TERRAIN_TIP_NBTILESMIN" : [
                "The program erases the islands with number of plots lower than this number." ,
                "Le programme efface les îles avec un nombre de parcelles de terrain inférieur à ce nombre." ,
                "Das Programm löscht die Inseln mit der Anzahl der Plots niedriger als diese Zahl." ,
                "Il programma cancella le isole con il numero dei diagrammi più basso di questo numero." ,
                "El programa borra las islas con el número de diagramas más bajo que este número." ] ,
        "TXT_TERRAIN_OASIS_PERCENT" : [
                "Percentage of oasis :" ,
                "Pourcentage d'oasis :" ,
                "Prozentsatz Oasen :" ,
                "Percentuale d'oasi :" ,
                "Porcentaje de oasis :" ] ,
        "TXT_TERRAIN_GOODY_PERCENT" : [
                "Percentage of tribal villages :" ,
                "Pourcentage de villages tribaux :" ,
                "Prozentsatz von Stammesdörfern :" ,
                "Percentuale di villaggi tribali :" ,
                "Porcentaje de aldeas tribales :" ] ,
        "TXT_TERRAIN_FOREST" : [
                "Forest :" ,
                "Forêt :" ,
                "Wald :" ,
                "Foresta :" ,
                "Bosque :" ] ,
        "TXT_TERRAIN_JUNGLE" : [
                "Jungle :" ,
                "Jungle :" ,
                "Dschungel :" ,
                "Giungla :" ,
                "Selva :" ] ,
        "TXT_TERRAIN_PEAK" : [
                "Mountains :" ,
                "Montagnes :" ,
                "Berge :" ,
                "Montagne :" ,
                "Montañas :" ] ,
        "TXT_TERRAIN_HILL" : [
                "Hills :" ,
                "Collines :" ,
                "Hügel :" ,
                "Colline :" ,
                "Colinas :" ] ,
        "TXT_TERRAIN_OASIS" : [
                "Oasis :" ,
                "Oasis :" ,
                "Oase :" ,
                "Oasi :" ,
                "Oasis :" ] ,
        "TXT_TERRAIN_GOODY_HUT" : [
                "Tribal villages :" ,
                "Villages tribaux :" ,
                "Stammesdörfern :" ,
                "Villaggi tribali :" ,
                "Aldeas tribales :" ] ,
        "TXT_RESOURCES_RESGEN" : [
                "Resources :" ,
                "Ressources :" ,
                "Ressourcen :" ,
                "Risorse :" ,
                "Recursos :" ] ,
        "TXT_RESOURCES_RESSTART" : [
                "Starting resources :" ,
                "Ressources de départ :" ,
                "Start Ressourcen :" ,
                "Risorse di partenza :" ,
                "Recursos iniciales :" ] ,
        "TXT_RESOURCES_LANDPERCENT" : [
                "Percentage of ground resources :" ,
                "Pourcentage de ressources de terres :" ,
                "Prozentsatz von Land Ressourcen :" ,
                "Percentuale di risorse di terre :" ,
                "Porcentaje de recursos de tierras :" ] ,
        "TXT_RESOURCES_LANDPROP" : [
                "Proportions of the ground resources :" ,
                "Proportions des ressources de terres :" ,
                "Anteile der Land Ressourcen :" ,
                "Proporzioni delle risorse di terre :" ,
                "Proporciones de los recursos de tierras :" ],
        "TXT_RESOURCES_LANDPROP_SEL0" : [
                "Strategic :" ,
                "Stratégiques :" ,
                "Strategisch :" ,
                "Strategici :" ,
                "Estratégicos :" ],
        "TXT_RESOURCES_LANDPROP_SEL1" : [
                " , Of Health :" ,
                " , De Santé :" ,
                " , Von Gesundheit :" ,
                " , Di salute :" ,
                " , De Salud :" ],
        "TXT_RESOURCES_LANDPROP_SEL2" : [
                " , Of happiness :" ,
                " , De bonheur :" ,
                " , Von Glück :" ,
                " , Di felicità :" ,
                " , De felicidad :" ],
        "TXT_RESOURCES_WATPERCENT" : [
                "Percentage of water resources :" ,
                "Pourcentage de ressources d'eau :" ,
                "Prozentsatz von Wasser Ressourcen :" ,
                "Percentuale di risorse d'acqua :" ,
                "Porcentaje de recursos de agua :" ],
        "TXT_RESOURCES_WATERPROP" : [
                "Proportions of the water resources :" ,
                "Proportions des ressources d'eau :" ,
                "Anteile der Wasser Ressourcen :" ,
                "Proporzioni delle risorse d'acqua :" ,
                "Proporciones de los recursos de agua :" ],
        "TXT_RESOURCES_WATERPROP_SEL0" : [
                "Strategic :" ,
                "Stratégiques :" ,
                "Strategisch :" ,
                "Strategici :" ,
                "Estratégicos :" ],
        "TXT_RESOURCES_WATERPROP_SEL1" : [
                " , Of Health :" ,
                " , De Santé :" ,
                " , Von Gesundheit :" ,
                " , Di salute :" ,
                " , De Salud :" ],
        "TXT_RESOURCES_WATERPROP_SEL2" : [
                " , Of happiness :" ,
                " , De bonheur :" ,
                " , Von Glück :" ,
                " , Di felicità :" ,
                " , De felicidad :" ],
        "TXT_RESOURCES_STANDARDFOR" : [
                "Standard generation for :" ,
                "Génération standard pour :" ,
                "Standardgeneration für :" ,
                "Generazione standard per :" ,
                "Generación normal para :" ],
        "TXT_RESOURCES_GROUPRES" : [
                "Group the resources :" ,
                "Grouper les ressources :" ,
                "Die Mittel gruppieren :" ,
                "Raggruppare le risorse :" ,
                "Agrupar los recursos :" ],
        "TXT_RESOURCES_ERASE_DEF_RES" : [
                "Default resources :" ,
                "Ressources par défaut :" ,
                "Rückstellung Betriebsmittel :" ,
                "Risorse di difetto :" ,
                "Recursos del defecto :" ],
        "TXT_RESOURCES_ERASE_DEF_RES_SEL0" : [
                "Erase all" ,
                "Les effacer toutes" ,
                "Löschen Sie alle" ,
                "Cancellarli tutte" ,
                "Borrarlos todas" ],
        "TXT_RESOURCES_SPREAD_CLIMATE" : [
                "Resources spread :" ,
                "Diffusion ressources :" ,
                "Ressourcen Verteilung :" ,
                "Diffusione risorse :" ,
                "Extensión recursos :" ],
        "TXT_RESOURCES_SPREAD_CLIMATE_SEL0" : [
                "By climatic areas" ,
                "Par régions climatiques" ,
                "Nach klimatischen Regionen" ,
                "Per regioni climatiche" ,
                "Por regiones climáticas" ],
        "TXT_RESOURCES_SPREAD_LAKES" : [
                "Resources spread :" ,
                "Diffusion ressources :" ,
                "Ressourcen Verteilung :" ,
                "Diffusione risorse :" ,
                "Extensión recursos :" ],
        "TXT_RESOURCES_SPREAD_LAKES_SEL0" : [
                "With resources in the lakes" ,
                "Avec des ressources dans les lacs" ,
                "Mit Ressourcen in Seen" ,
                "Con risorse nei laghi" ,
                "Con recursos en los lagos" ],
        "TXT_RESOURCES_RESMULTIPLY" : [
                "Multiply the number of resources :" ,
                "Multiplier le nombre de ressources :" ,
                "Die Anzahl der Ressourcen multiplizieren :" ,
                "Moltiplicare il numero di risorse :" ,
                "Multiplicar el número de recursos :" ],
        "TXT_RESOURCES_START_REMOVE" : [
                "Resources at the starting point :" ,
                "Ressources au point de départ :" ,
                "Betriebs Ressourcen am Ausgangspunkt :" ,
                "Risorse al punto di partenza :" ,
                "Recursos en el punto de partida :" ],
        "TXT_RESOURCES_START_REMOVE_SEL0" : [
                "Remove" ,
                "Enlever" ,
                "Wegnehmen" ,
                "Togliere" ,
                "Retirar" ] ,
        "TXT_RESOURCES_STRAT_NORANDOM" : [
                "Nonby chance selected strategic resources :" ,
                "Ressources stratégiques non choisies aléatoirement :" ,
                "Nicht zufällig gewählte strategische Ressourcen :" ,
                "Risorse strategiche non scelte a caso :" ,
                "Recursos estratégicos no elegidos aleatoriamente :" ],
        "TXT_RESOURCES_HEALTH_NORANDOM" : [
                "Nonby chance selected resources of health :" ,
                "Ressources de santé non choisies aléatoirement :" ,
                "Nicht zufällig gewählte Gesundheits Ressourcen :" ,
                "Risorse di salute non scelte a caso :" ,
                "Recursos de salud no elegidos aleatoriamente :" ],
        "TXT_RESOURCES_HAPPINESS_NORANDOM" : [
                "Nonby chance selected resources of happiness :" ,
                "Ressources de bonheur non choisies aléatoirement :" ,
                "Nicht zufällig gewählte Glücks Ressourcen :" ,
                "Risorse di felicità non scelte a caso :" ,
                "Recursos de felicidad no elegidos aleatoriamente :" ],
        "TXT_RESOURCES_START_RES" : [
                "Starting resource :" ,
                "Ressource de départ :" ,
                "Start Ressourcen :" ,
                "Risorsa di partenza :" ,
                "Recurso inicial :" ] ,
        "TXT_MAPS_CHESS_BORDER" : [
                "Borders :" ,
                "Frontières :" ,
                "Ränder :" ,
                "Bordi :" ,
                "Fronteras :" ] ,
        "TXT_MAPS_CHESS_BORDER_SEL0" : [
                "Mountains" ,
                "Montagnes" ,
                "Berge" ,
                "Montagne" ,
                "Montañas" ] ,
        "TXT_MAPS_CHESS_BORDER_SEL1" : [
                "Hills" ,
                "Collines" ,
                "Hügel" ,
                "Colline" ,
                "Colinas" ] ,
        "TXT_MAPS_CHESS_BORDER_SEL2" : [
                "Plains" ,
                "Plaines" ,
                "Ebene" ,
                "Pianure" ,
                "Llanuras" ] ,
        "TXT_MAPS_CHESS_BORDER_SEL3" : [
                "Water" ,
                "Eau" ,
                "Wasser" ,
                "Acqua" ,
                "Agua" ] ,
        "TXT_DUM" : [
                "  ^_^  " ,
                "  ^_^  " ,
                "  ^_^  " ,
                "  ^_^  " ,
                "  ^_^  " ] ,
        "TXT_HELP" : [
                "Help" ,
                "Aide" ,
                "Hilfe" ,
                "Aiuto" ,
                "Ayuda" ] ,
        "TXT_HELP_RESGEN01" : [
                "You have the choice to erase all the resources generated by default. This option is useful only if you wish to have less resources than by default (for the small sizes of maps with much of players for example)." ,
                "Vous avez le choix d'effacer toutes les ressources générées par défaut. Cette option n'est utile que si vous souhaitez avoir moins de ressources que par défaut (pour les petites tailles de cartes avec beaucoup de joueurs par exemple)." ,
                "Sie haben die Wahl, zum aller Betriebsmittel zu löschen, die durch Rückstellung erzeugt werden. Diese Wahl ist nützlich, nur wenn Sie weniger Betriebsmittel als durch Rückstellung haben möchten (für die kleinen Größen der Diagramme mit viel von Spielern zum Beispiel)." ,
                "Avete la scelta per cancellare tutte le risorse generate per difetto. Questa opzione è utile soltanto se desiderate disporre di meno mezzi che per difetto (per i piccoli formati dei programmi con molto dei giocatori per esempio)." ,
                "Usted tiene la opción para borrar todos los recursos generados por el defecto. Esta opción es útil solamente si usted desea tener menos recursos que por defecto (para los tamaños pequeños de mapas con mucho de jugadores por ejemplo)." ] ,
        "TXT_HELP_RESGEN0" : [
                "For the proportions of resources :" ,
                "Pour les proportions de ressources :" ,
                "Für die Anteile von Mitteln :" ,
                "Per le proporzioni di risorse :" ,
                "Para las proporciones de recursos :" ] ,
        "TXT_HELP_RESGEN1" : [
                "If you choose the generation of standard resources, this option does not have utility. If you put (70,100,50), then for (70+100+50 = 220) resources you will have 70 resources strategic, 100 resources of health and 50 resources of happiness (in proportion) ." ,
                "Si vous choisissez la génération de ressources standard , cette option n'a pas d'utilité . Si vous mettez (70,100,50) , alors pour (70+100+50 = 220) ressources vous aurez 70 ressources stratégiques , 100 ressources de santé et 50 ressources de bonheur (en proportion) ." ,
                "Wenn Sie die Standardmittelgeneration wählen, hat diese Option keinen Nutzen. Wenn Sie stellen (70,100,50), dann für (70+100+50 = 220) Mittel werden Sie 70 strategische Mittel haben, 100 Gesundheitsmittel und 50 Glücksmittel (in Anteil) ." ,
                "Se scegliete la generazione di risorse standard, quest'opzione non ha un'utilità. Se mettete (70,100,50), allora per (70+100+50 = 220) risorse avrete 70 risorse strategiche, 100 risorse di salute e 50 risorse di felicità (in proporzione) ." ,
                "Si eligen la generación de recursos normal, esta opción no tiene utilidad. Si ponen (70,100,50), entonces para (70+100+50 = 220) recursos tendrán 70 recursos estratégicos, 100 recursos de salud y 50 recursos de felicidad (en proporción) ." ] ,
        "TXT_HELP_RESGEN2" : [
                "For the standardized resources :" ,
                "Pour les ressources standardisées :" ,
                "Für die vereinheitlichten Mittel :" ,
                "Per le risorse standardizzate :" ,
                "Para los recursos estandarizados :" ] ,
        "TXT_HELP_RESGEN3" : [
                "If you choose the generation of standard resources, this option does not have utility ." ,
                "Si vous choisissez la génération de ressources standard , cette option n'a pas d'utilité ." ,
                "Wenn Sie die Standardmittelgeneration wählen, hat diese Option keinen Nutzen ." ,
                "Se scegliete la generazione di risorse standard, quest'opzione non ha un'utilità ." ,
                "Si eligen la generación de recursos normal, esta opción no tiene utilidad ." ] ,
        "TXT_HELP_RESGEN4" : [
                "If you choose to fill the map with 8 percent of resources for example : the program makes initially a standard generation of resources, then adds resources until obtaining 8 percent of resources . None the standardized resources will be added ." ,
                "Si vous choisissez de remplir la map avec 8 pourcent de ressources par exemple : le programme fait d'abord une génération standard de ressources , puis rajoute des ressources jusqu'à obtenir 8 pourcent de ressources . Aucune des ressources standardisées ne sera rajoutée ." ,
                "Wenn Sie wählen, das map mit 8 Prozent von Mitteln zu füllen zum Beispiel : das Programm macht zuerst eine Standardmittelgeneration dann hinzufügt Mittel, bis zu 8 Prozent von Mitteln zu erhalten . Kein von den vereinheitlichten Mitteln hinzugefügt wird ." ,
                "Se scegliete di riempire la map con 8 pourcent di risorse ad esempio : il programma fa inizialmente una generazione standard di risorse, quindi aggiunge risorse fino ad ottenere ad 8 pourcent di risorse . Nessuno delle risorse standardizzate sarà aggiunta ." ,
                "Si eligen llenar el map con 8 por ciento de recursos por ejemplo : el programa hace en primer lugar una generación normal de recursos, luego añade recursos hasta obtener 8 por ciento de recursos . Ninguna de los recursos estandarizados no se añadirá ." ] ,
        "TXT_HELP_RESGEN5" : [
                "For the option %r :" ,
                "Pour l'option %r :" ,
                "Für die Option %r :" ,
                "Per l'opzione %r :" ,
                "Para la opción %r :"] ,
        "TXT_HELP_RESGEN6" : [
                "When resources will be added. If a resource is selected, it will be placed close to the same resource, if possible. If not, it will be placed so that these resources are spaced possible." ,
                "Lorsque des ressources vont être ajoutées. Si une ressource est sélectionnée, elle va être placée près d'une même ressource, si possible. Sinon, elle va être placée de façon à ce que ces ressources soient les plus espacées possible." ,
                "Wenn Mittel hinzugefügt werden. Wenn Mittel ausgewählt werden, wird sie in der Nähe ein und derselben Mittel gesetzt, wenn möglich. Andernfalls wird sie gesetzt, so daß diese Mittel das am meisten Abstand gelassen sind mögliche." ,
                "Quando risorse saranno aggiunte. Se una risorsa è scelta, sarà messa vicino di una stessa risorsa, possibilmente. Altrimenti, sarà messa in modo che queste risorse siano le più intervallate il possibile." ,
                "Cuando recursos van a añadirse. Si se selecciona un recurso, va a colocarse cerca de un mismo recurso, si es posible. Si no, van a colocar le de modo que estos recursos sean el más los más espaciados posible."] ,
        "TXT_HELP_RESGEN7" : [
                "For the multiplication of the resources :" ,
                "Pour la multiplication des ressources :" ,
                "Für die Multiplikation der Mittel :" ,
                "Per la moltiplicazione delle risorse :" ,
                "Para la multiplicación de los recursos :"] ,
        "TXT_HELP_RESGEN8" : [
                "The program generates the resources like previously definite. Then the program multiplies the number of resources obtained by the selected value (this number can be a real number, example: 1.2) ." ,
                "Le programme génère les ressources comme définies précédemment . Puis le programme multiplie le nombre de ressources obtenues par la valeur choisie ( ce nombre peut être un nombre réel ,exemple : 1.2 ) ." ,
                "Das Programm erzeugt die Mittel als vorher definiert. Dann multipliziert das Programm die Anzahl der Mittel, die durch den ausgewählten Wert erhalten wurden (diese Zahl kann eine wirkliche Zahl, Beispiel sein: 1.2) ." ,
                "Il programma genera le risorse così definite precedentemente. Quindi il programma moltiplica il numero di risorse ottenute dal valore scelto (questo numero può essere un numero reale, esempio: 1.2) ." ,
                "El programa genera los recursos como se define anteriormente. Luego el programa multiplica el número de recursos obtenidos por el valor elegido (este número puede ser un número real, ejemplo: 1.2) ." ] ,
        "TXT_HELP_RESGEN9" : [
                "Be careful, if you choose 8 percent of resources and then you multiply all the resources by 10, you will obtain 80 percent of resources ." ,
                "Faites attention , si vous choisissez 8 pourcent de ressources et ensuite vous multipliez toutes les ressources par 10 , vous obtiendrez 80 pourcent de ressources ." ,
                "Gemacht Beachtung, wenn Sie 8 Prozent von Mitteln und danach wählen Sie multiplizieren alle Mittel durch 10, werden Sie 80 Prozent von Mitteln erhalten ." ,
                "Fatte attenzione, se scegliete 8 pourcent di risorse ed in seguito voi moltiplicate tutte le risorse per 10, otterrete 80 pourcent di risorse ." ,
                "Hechas atención, si eligen 8 por ciento de recursos y a continuación ustedes multiplican todos los recursos por 10, obtendrán 80 por ciento de recursos ." ] ,
        "TXT_HELP_RESSTART0" : [
                "For the resources added at the beginning :" ,
                "Pour les ressources ajoutées au départ :" ,
                "Für die Mittel, die zum Anfang hinzugefügt wurden :" ,
                "Per le risorse aggiunte alla partenza :" ,
                "Para los recursos añadidos al principio :"] ,
        "TXT_HELP_RESSTART1" : [
                "You can erase all the resources which are in the perimeter of your first city if you want to define the starting resources of each player ." ,
                "Vous pouvez effacer toutes les ressources qui se trouvent dans le périmètre de votre première ville si vous voulez définir les ressources de départ de chaque joueur ." ,
                "Sie können alle Mittel löschen, die sich im Umkreis Ihrer ersten Stadt befinden, ob Sie die Startmittel jedes Spielers definieren wollen ." ,
                "Potete cancellare tutte le risorse che si trovano nel perimetro della vostra prima città se volete definire le risorse di partenza di ogni giocatore ." ,
                "Pueden borrar todos los recursos que se encuentran en el perímetro de su primera ciudad si quieren definir los recursos iniciales de cada jugador ."] ,
        "TXT_HELP_RESSTART2" : [
                "You can choose the resources which will not be randomly selected, if you select a random number of resources ." ,
                "Vous pouvez choisir les ressources qui ne seront pas choisies au hasard , si vous sélectionnez un nombre aléatoire de ressources ." ,
                "Sie können die Mittel wählen, die nicht aufs Geratewohl gewählt werden, wenn Sie eine Zufallsanzahl von Mitteln auswählen ." ,
                "Potete scegliere le risorse che non saranno scelte a caso, se scegliete un numero aleatorio di risorse ." ,
                "Pueden elegir los recursos que no se elegirán aleatoriamente, si seleccionan un número aleatorio de recursos ."] ,
        "TXT_HELP_RESSTART3" : [
                "For the localization of the starting resources :" ,
                "Pour la localisation des ressources de départ :" ,
                "Für die Lokalisierung der Startmittel :" ,
                "Per la localizzazione delle risorse di partenza :" ,
                "Para la localización de los recursos iniciales :" ] ,
        "TXT_HELP_RESSTART4" : [
                "You can add these resources in the perimeter of your first city ." ,
                "Vous pouvez ajouter ces ressources dans le périmètre de votre première ville ." ,
                "Sie können diese Mittel im Umkreis Ihrer ersten Stadt hinzufügen ." ,
                "Potete aggiungere queste risorse nel perimetro della vostra prima città ." ,
                "Pueden añadir estos recursos en el perímetro de su primera ciudad ." ] ,
        "TXT_HELP_RESSTART5" : [
                "You can add these resources in a perimeter close to your first city (If you play with the option One-City Challenge, the program will try to place the resources in the 2, 4 rings around your first city) ." ,
                "Vous pouvez ajouter ces ressources dans un périmètre proche de votre première ville ( Si vous jouez avec l'option Défier une ville , le programme essaiera de placer les ressources dans les 2, 4 anneaux autour de votre première ville ) ." ,
                "Sie können diese Mittel in einem an Ihrer ersten Stadt nahen Umkreis hinzufügen (wenn Sie mit der Option spielen Einzelstadt-Wettkampf, das Programm wird versuchen, die Mittel in den 2, 4 Ringen um Ihre erste Stadt zu setzen) ." ,
                "Potete aggiungere queste risorse in un perimetro vicino alla vostra prima città (se giocate con l'opzione Sfida a città singola, il programma proverà a mettere le risorse nei 2, 4 anelli attorno alla vostra prima città) ." ,
                "Pueden añadir estos recursos en un perímetro próximo a su primera ciudad (si juegan con la opción Reto de una sola ciudad, el programa intentará colocar los recursos en los 2, 4 anillos en torno a su primera ciudad) ." ] ,
        "TXT_HELP_RESSTART6" : [
                "You can also add these resources in the zone of a player ( What the program will regard as a place closer to you than of another player) ." ,
                "Vous pouvez aussi ajouter ces ressources dans la zone d'un joueur ( Ce que le programme considérera comme un endroit plus proche de vous que d'un autre joueur ) ." ,
                "Sie können auch diese Mittel in der Zone eines Spielers hinzufügen ( Das, was das Programm als eine an Ihnen als von einem anderen Spieler nähere Stelle ansehen wird ) ." ,
                "Potete anche aggiungere queste risorse nella zona di un giocatore ( Ciò che il programma considererà come un posto più vicino a voi che di un altro giocatore ) ." ,
                "Pueden también añadir estos recursos en la zona de un jugador ( Lo que el programa considerará como un lugar más cercano ustedes que de otro jugador ) ." ] ,
        "TXT_HELP_RESSTART7" : [
                "The added resources never replace other resources ." ,
                "Les ressources ajoutées ne remplacent jamais d'autres ressources ." ,
                "Die hinzugefügten Mittel ersetzen nie andere Mittel ." ,
                "Le risorse aggiunte non sostituiscono mai altre risorse ." ,
                "Los recursos añadidos sustituyen nunca a otros recursos ." ] ,
        "TXT_HELP_RESSTART8" : [
                "The resources are added in the order that you defined. And if a player cannot receive a resource, none of the players will receive this resource. This is for that that this is necessary to well define the order in which you add the resources ." ,
                "Les ressources sont ajoutées dans l'ordre que vous avez défini . Et si un joueur ne peut pas recevoir une ressource , aucun des joueurs ne recevra cette ressource . C'est pour cela qu'il faut bien définir l'ordre dans lequel vous ajoutez les ressources ." ,
                "Die Mittel werden im Befehl hinzugefügt, den Sie definiert haben. Und wenn ein Spieler keine Mittel erhalten kann, kein von den Spielern werden diese Mittel erhalten. Es ist für das, daß man gut den Befehl definieren muß, in dem Sie die Mittel hinzufügen ." ,
                "Le risorse sono aggiunte nell'ordine che avete definito. E se un giocatore non può ricevere una risorsa, nessuno dei giocatori riceverà questa risorsa. È per ciò che occorre definire l'ordine nel quale aggiungete le risorse ." ,
                "Los recursos se añaden en el orden que definieron. Y si un jugador no puede recibir un recurso, ningún de los jugadores recibirá este recurso. Es para eso que es necesario definir bien el orden en el cual añaden los recursos ." ] ,
        "TXT_HELP_RESSTART9" : [
                "If you choose the option %s: The program will add the definite number of resources in the selected area (by preferring those which are not already present for random resources)." ,
                "Si vous choisissez l'option %s: Le programme va rajouter le nombre défini de ressources dans la région choisie (en préférant celles qui ne sont pas déjà présentes pour des ressources aléatoires )." ,
                "Wenn Sie die Option wählen %s: Das Programm wird die definierte Anzahl der Mittel in der ausgewählten Region hinzufügen (indem man jene vorzieht, die nicht für Zufallsmittel schon anwesend sind)." ,
                "Se scegliete l'opzione %s: Il programma aggiungerà il numero definito di risorse nella regione scelta (preferendo quelle che non sono già presenti per risorse aleatorie)." ,
                "Si eligen la opción %s: El programa va a añadir el número definido de recursos en la región elegida (prefiriendo aquéllas que no están ya presentes para recursos aleatorios)." ] ,
        "TXT_HELP_RESSTART10" : [
                "If you choose the option %s: The program will count the number of resources in the definite area (the number of different resources if you chose a random number of resources). Then the program adds resources if necessary." ,
                "Si vous choisissez l'option %s: Le programme va compter le nombre de ressources dans la région définie (le nombre de ressources différentes si vous avez choisi un nombre aléatoire de ressources ). Puis le programme rajoute des ressources si nécessaire ." ,
                "Wenn Sie die Option wählen %s: Das Programm wird die Anzahl der Mittel in der definierten Region zählen (die Anzahl der anderen Mittel, wenn Sie eine Zufallsanzahl von Mitteln gewählt haben). Dann fügt das Programm Mittel hinzu wenn nötig." ,
                "Se scegliete l'opzione %s: Il programma conterà il numero di risorse nella regione definita (il numero di risorse diverse se avete scelto un numero aleatorio di risorse). Quindi il programma aggiunge risorse se necessario." ,
                "Si eligen la opción %s: El programa va a contar el número de recursos en la región definida (el número de recursos diferentes si eligieron un número aleatorio de recursos). Luego el programa añade recursos en caso necesario." ] ,
        "TXT_RESOURCES_START_FORCE" : [
                "^_^  " ,
                "^_^  " ,
                "^_^  " ,
                "^_^  " ,
                "^_^  " ] ,
        "TXT_RESOURCES_START_FORCE_SEL0" : [
                "Force the appearance" ,
                "Forcer l'apparition" ,
                "Das Aufkommen forcieren" ,
                "Forzare la comparsa" ,
                "Forzar la aparición" ] ,
        "TXT_RESOURCES_START_FORCE_SEL1" : [
                "Equalize the appearance" ,
                "Egaliser l'apparition" ,
                "Das Aufkommen gleichmachen" ,
                "Uguagliare la comparsa" ,
                "Igualar la aparición" ] ,
        "TXT_RESOURCES_START_LOCATION" : [
                "^_^  " ,
                "^_^  " ,
                "^_^  " ,
                "^_^  " ,
                "^_^  " ] ,
        "TXT_RESOURCES_START_LOCATION_SEL0" : [
                "At the starting point" ,
                "Au point de départ" ,
                "An der Start Position" ,
                "Al punto di partenza" ,
                "En el punto de partida" ] ,
        "TXT_RESOURCES_START_LOCATION_SEL1" : [
                "In the neighbourhoods of the starting point" ,
                "Aux alentours du point de départ" ,
                "In der Nähe der Start Position" ,
                "Intorno al punto di partenza" ,
                "En los alrededores del inicio" ] ,
        "TXT_RESOURCES_START_LOCATION_SEL2" : [
                "In the player zone" ,
                "Dans la zone du joueur" ,
                "In der Zone des Spielers" ,
                "Nella zona del giocatore" ,
                "En la zona del jugador" ] ,
        "TXT_PLAYER_APPLY" : [
                "^_^  " ,
                "^_^  " ,
                "^_^  " ,
                "^_^  " ,
                "^_^  " ] ,
        "TXT_PLAYER_APPLY_SEL0" : [
                "Human Players" ,
                "Joueurs Humains" ,
                "Menschliche Spieler" ,
                "Giocatori umani" ,
                "Jugadores Humanos" ] ,
        "TXT_PLAYER_APPLY_SEL1" : [
                "AI players" ,
                "Joueurs IA" ,
                "Spieler KI" ,
                "Giocatori IA" ,
                "Jugadores IA" ] ,
        "TXT_STANDARD" : [
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Norma" ] ,
        "TXT_ALL_STRAT" : [
                "Strategic resources" ,
                "Ressources stratégiques" ,
                "Strategische Mittel" ,
                "Risorse strategiche" ,
                "Recursos estratégicos" ] ,
        "TXT_ALL_HEALTH" : [
                "Resources of health" ,
                "Ressources de santé" ,
                "Gesundheitsmittel" ,
                "Risorse di salute" ,
                "Recursos de salud" ] ,
        "TXT_ALL_HAPP" : [
                "Resources of happiness" ,
                "Ressources de bonheur" ,
                "Glücksmittel" ,
                "Risorse di felicità" ,
                "Recursos de felicidad" ] ,
        "TXT_QUANTITY" : [
                "Quantity :" ,
                "Quantité :" ,
                "Quantität :" ,
                "Quantità :" ,
                "Cantidad :" ] ,
        "TXT_RES_ALL" : [
                "All" ,
                "Toutes" ,
                "Alle" ,
                "Tutte" ,
                "Todos" ] ,
        "TXT_BY" : [
                ", by :" ,
                ", par :" ,
                ", mit :" ,
                ", con :" ,
                ", por :" ] ,
        "TXT_SAME_FOR_PLAYERS" : [
                "Random : The same ones for each player" ,
                "Aléatoire : Les mêmes pour chaque joueur" ,
                "Zufällig : Dasselben für jeden Spieler" ,
                "Casuale : Gli stessi per ogni giocatore" ,
                "Al azar : El mismos para cada jugador" ] ,
        "TXT_DIFFERENT_FOR_PLAYERS" : [
                "Random : Different for each player" ,
                "Aléatoire : Différentes pour chaque joueur" ,
                "Zufällig : Verschieden für jeden Spieler" ,
                "Casuale : Diversi per ogni giocatore" ,
                "Al azar : Diferentes para cada jugador" ] ,
        "TXT_GAME_BARB_CITIES" : [
                "Barbarian cities :" ,
                "Villes barbares :" ,
                "Barbaren Städte :" ,
                "Città barbarian :" ,
                "Ciudades bárbaras :" ] ,
        "TXT_GAME_ANIMALS" : [
                "Wild animals :" ,
                "Animaux sauvages :" ,
                "Wilde Tiere :" ,
                "Animali selvaggi :" ,
                "Animales salvajes :" ] ,
        "TXT_GAME_GOLD" : [
                "Gold :" ,
                "Or :" ,
                "Gold :" ,
                "Oro :" ,
                "Oro :" ] ,
        "TXT_GAME_REVEAL" : [
                "Reveal :" ,
                "Révéler :" ,
                "Aufdecken :" ,
                "Rivelare :" ,
                "Revelar :" ] ,
        "TXT_GAME_TECHNOS" : [
                "Technologies :" ,
                "Technologies :" ,
                "Technologien :" ,
                "Tecnologie :" ,
                "Tecnologías :" ] ,
        "TXT_GAME_UNITS" : [
                "Starting units :" ,
                "Unités de départ :" ,
                "Einheiten des Starts :" ,
                "Unità di partenza :" ,
                "Unidades de partida :" ] ,
        "TXT_GAME_BARB_CITYPER" : [
                "Percentage of barbarian cities :" ,
                "Pourcentage de villes barbares :" ,
                "Prozentsatz der barbarischen Städte :" ,
                "Percentuale delle città barbarian :" ,
                "Porcentaje de ciudades bárbaras :" ] ,
        "TXT_GAME_CITYBUILD" : [
                "Buildings in the cities :" ,
                "Bâtiments dans les villes :" ,
                "Gebäude in den Städte :" ,
                "Costruzioni nelle città :" ,
                "Edificios en las ciudades :" ] ,
        "TXT_GAME_BARBAR_RANGE" : [
                "Minimal distance between two barbarian cities :" ,
                "Distance minimale entre deux villes barbares :" ,
                "Minimaler Abstand zwischen zwei barbarischen Städte :" ,
                "Distanza minima fra due città barbarian :" ,
                "Distancia mínima entre dos ciudades bárbaras :" ] ,
        "TXT_GAME_BARHUM_RANGE" : [
                "Minimal distance between a barbarian city and a starting position :" ,
                "Distance minimale entre une ville barbare et une position de départ :" ,
                "Minimale Distanz zwischen einer barbarischen Stadt und einer Startposition :" ,
                "Distanza minima tra una città barbara ed una posizione di partenza :" ,
                "Distancia mínima entre una ciudad cruel y una posición inicial :" ] ,
        "TXT_GAME_BAR_DEFENDER" : [
                "Defender of the city :" ,
                "Défenseur de la ville :" ,
                "Verteidiger der Stadt :" ,
                "Difensore della città :" ,
                "Partidario de la ciudad :" ] ,
        "TXT_GAME_XP" : [
                "XP :" ,
                "XP :" ,
                "XP :" ,
                "XP :" ,
                "XP :" ] ,
        "TXT_GAME_ANIMPER" : [
                "Percentage of wild animals :" ,
                "Pourcentage d'animaux sauvages :" ,
                "Prozentsatz der wilden Tiere :" ,
                "Percentuale degli animali selvaggi :" ,
                "Porcentaje de animales salvajes :" ] ,
        "TXT_GAME_ANIMNOTPLACED" : [
                "Not added animals :" ,
                "Animaux non ajoutés :" ,
                "Nicht hinzugefügte Tiere :" ,
                "Animali non aggiunti :" ,
                "Animales no añadidos :" ] ,
        "TXT_GAME_ANIMUNIT_RANGE" : [
                "Minimal distance between an animal and a unit :" ,
                "Distance minimale entre un animal et une unité :" ,
                "Minimale Distanz zwischen einem Tier und einer Einheit :" ,
                "Distanza minima tra un animale ed un'unità :" ,
                "Distancia mínima entre un animal y una unidad :" ] ,
        "TXT_GAME_REVEAL_STARTRANGE" : [
                "Extend the vision of the starting point, range :" ,
                "Etendre la vision du point de départ, rayon :" ,
                "Die Sicht vom Start Punkt erweitern, Strahl :" ,
                "Estendere la visione del punto di partenza, raggio :" ,
                "Extender la visión del inicio, rayo :" ] ,
        "TXT_GAME_SEAREVEAL" : [
                "^_^  " ,
                "^_^  " ,
                "^_^  " ,
                "^_^  " ,
                "^_^  " ] ,
        "TXT_GAME_SEAREVEAL_SEL0" : [
                "Reveal all water" ,
                "Révéler toutes les étendues d'eau" ,
                "Das ganze Wasser enthüllen" ,
                "Rivelare tutta l'acqua" ,
                "Revelar todo el agua" ] ,
        "TXT_GAME_LANDREVEAL" : [
                "^_^  " ,
                "^_^  " ,
                "^_^  " ,
                "^_^  " ,
                "^_^  " ] ,
        "TXT_GAME_LANDREVEAL_SEL0" : [
                "Reveal all the ground" ,
                "Révéler toutes les étendues de terre" ,
                "Die ganze Erde enthüllen" ,
                "Rivelare tutta la terra" ,
                "Revelar toda la tierra" ] ,
        "TXT_GAME_STARTREVEAL" : [
                "^_^  " ,
                "^_^  " ,
                "^_^  " ,
                "^_^  " ,
                "^_^  " ] ,
        "TXT_GAME_STARTREVEAL_SEL0" : [
                "Reveal all the starting points" ,
                "Révéler tous les points de départ" ,
                "Alle Ausgangspunkte enthüllen" ,
                "Rivelare tutte le località di partenza" ,
                "Revelar todos los puntos de partida" ] ,
        "TXT_GAME_STARTTECH" : [
                "Starting technologies :" ,
                "Technologies de départ :" ,
                "Starttechnologien :" ,
                "Tecnologie di partenza :" ,
                "Tecnologías iniciales :" ] ,
        "TXT_GAME_STARTTECH_SEL0" : [
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Norma" ] ,
        "TXT_GAME_STARTTECH_SEL1" : [
                "Remove" ,
                "Enlever" ,
                "Wegnehmen" ,
                "Togliere" ,
                "Retirar" ] ,
        "TXT_GAME_TECH_NOREPLACE" : [
                "Technologies not to be removed :" ,
                "Technologies à ne pas enlever :" ,
                "Wegzunehmende nicht Technologien :" ,
                "Tecnologie da non togliere :" ,
                "Tecnologías que deben retirarse :" ] ,
        "TXT_GAME_TECH_NORANDOM" : [
                "Technologies not to be chosen randomly :" ,
                "Technologies à ne pas choisir au hasard :" ,
                "Zu wählende nicht aufs Geratewohl Technologien :" ,
                "Tecnologie da non scegliere a caso :" ,
                "Tecnologías que deben elegirse aleatoriamente :" ] ,
        "TXT_GAME_ADDTECH" : [
                "Add the technology :" ,
                "Ajouter la technologie :" ,
                "Die Technologie hinzufügen :" ,
                "Aggiungere la tecnologia :" ,
                "Añadir la tecnología :" ] ,
        "TXT_GAME_ADDUNIT" : [
                "Add the unit :" ,
                "Ajouter l'unité :" ,
                "Die Einheit hinzufügen :" ,
                "Aggiungere l'unità :" ,
                "Añadir la unidad :" ] ,
        "TXT_GAME_UNIT_TYPE" : [
                "Type of the unit :" ,
                "Type de l'unité :" ,
                "Typ der Einheit :" ,
                "Tipo dell'unità :" ,
                "Tipo de la unidad :" ] ,
        "TXT_GAME_UNIT_TYPE_SEL0" : [
                "Force the type" ,
                "Forcer le type" ,
                "Den Typ forcieren" ,
                "Forzare il tipo" ,
                "Forzar el tipo" ] ,
        "TXT_GAME_UNIT_TYPE_SEL1" : [
                "Adapt the type of the unit" ,
                "Adapter le type de l'unité" ,
                "Den Typ der Einheit anpassen" ,
                "Adattare il tipo dell'unità" ,
                "Adaptar el tipo de la unidad" ] ,
        "TXT_GAME_UNIT_TYPE_SEL2" : [
                "Adapt the type of the unit (Strict)" ,
                "Adapter le type de l'unité (Strict)" ,
                "Den Typ der Einheit anpassen (Strikt)" ,
                "Adattare il tipo dell'unità (Rigoroso)" ,
                "Adaptar el tipo de la unidad (Estricto)" ] ,
        "TXT_HELP_CITIES0" : [
                "For the barbarian cities :" ,
                "Pour les villes barbares :" ,
                "Für die barbarischen Städte :" ,
                "Per le città barbarian :" ,
                "Para las ciudades bárbaras :" ] ,
        "TXT_HELP_CITIES1" : [
                "The percentage of barbarian cities corresponds to a percentage of the maximum number of cities possible according to the parameters of distances between the cities." ,
                "Le pourcentage de cités barbares correspond à un pourcentage du nombre maximal de villes possible en fonction des paramètres de distances entre les villes." ,
                "Der Prozentsatz der barbarischen Städte entspricht einem Prozentsatz der Höchstzahl der Städte, die entsprechend den Parametern von Abständen zwischen den Städte möglich sind." ,
                "La percentuale delle città barbarian corrisponde ad una percentuale del numero massimo delle città possibili secondo i parametri delle distanze fra le città." ,
                "El porcentaje de ciudades bárbaras corresponde a un porcentaje del número máximo de las ciudades posibles según los parámetros de distancias entre las ciudades." ] ,
        "TXT_HELP_CITIES2" : [
                "None of the parameters of CivIV are modified. The cities are simply added to the beginning of the game." ,
                "Aucun des paramètres de CivIV n'est modifié. Les villes sont simplement ajoutées au début de la partie." ,
                "Keine der Parameter von CivIV werden geändert. Die Städte werden einfach dem Anfang des Spiels hinzugefügt." ,
                "Nessun dei parametri di CivIV sono modificati. Le città sono aggiunte semplicemente all'inizio del gioco." ,
                "No se modifica ningunos de los parámetros de CivIV. Las ciudades se agregan simplemente al principio del juego." ] ,
        "TXT_HELP_CITIES3" : [
                "However, according to the MOD which you play, it is possible that the addition of barbarian cities at the beginning of the game prevents other units from appearing (animals or wandering barbarian units)." ,
                "Toutefois, en fonction du MOD que vous jouez, il est possible que l'ajout de villes barbares au debut du jeu empêche d'autres unités d'apparaître (des animaux ou des unités barbares errantes)." ,
                "Jedoch entsprechend dem Umb., den Sie spielen, ist es möglich, daß die Hinzufügung der barbarischen Städte am Anfang des Spiels andere Maßeinheiten am Erscheinen verhindert (Tiere oder wandering barbarische Maßeinheiten)." ,
                "Tuttavia, secondo il MOD che giocate, è possibile che l'aggiunta delle città barbarian all'inizio del gioco impedisce altre unità comparire (animali o unità barbarian erranti)." ,
                "Sin embargo, según la MOD que usted juega, es posible que la adición de ciudades bárbaras al principio del juego evita que aparezcan otras unidades (los animales o las unidades bárbaras que vagan)." ] ,
        "TXT_HELP_CITIES4" : [
                "Do not forget that to add barbarian cities at the beginning of the game modifies considerably the way of playing. It's up to you to find good adjustments." ,
                "N'oubliez pas que rajouter des villes barbares au début du jeu modifie considérablement la façon de jouer . C'est à vous de trouver de bons réglages ." ,
                "Vergessen Sie nicht, daß dem, barbarische Städte am Anfang des Spiels hinzuzufügen beträchtlich die Weise des Spielens ändert. Es ist bis zu Ihnen, zum der guten Justagen zu finden." ,
                "Non si dimentichi che quello aggiungere le città barbarian all'inizio del gioco modifica considerevolmente il senso del gioco. Spetta voi per trovare le buone registrazioni." ,
                "No se olvide que eso agregar ciudades bárbaras al principio del juego modifica considerablemente la manera de jugar. Está hasta usted para encontrar buenos ajustes." ] ,
        "TXT_HELP_CITIES5" : [
                "It's wise to add defenders in the cities to prevent them from being conquered very quickly. It's wise to add technologies and units to all the players to prevent them from being quickly killed." ,
                "Il est conseillé d'ajouter des défenseurs dans les villes pour éviter qu'elles se fassent conquérir très rapidement. Il est conseillé d'ajouter des technologies et des unités à tous les joueurs pour éviter qu'ils ne se fassent rasés rapidement ." ,
                "Es klug, Verteidiger in den Städte hinzuzufügen, um zu verhindern, daß sie sehr schnell erobert ist. Es ist klug, Technologien und Maßeinheiten allen Spielern hinzuzufügen, um sie an schnell getötet werden zu hindern." ,
                "È saggio aggiungere le protezioni nelle città per impedirle la conquista molto rapidamente. È saggio aggiungere le tecnologie e le unità a tutti i giocatori per impedire loro rapidamente di essere uccisa." ,
                "Es sabio agregar a defensores en las ciudades para evitar que sean conquistadas muy rápidamente. Es sabio agregar tecnologías y unidades a todos los jugadores para evitar que los maten rápidamente." ] ,
        "TXT_HELP_ANIMAL0" : [
                "For the wild animals :" ,
                "Pour les animaux sauvages :" ,
                "Für die wilden Tiere :" ,
                "Per gli animali selvaggi :" ,
                "Para los animales salvajes :" ] ,
        "TXT_HELP_ANIMAL1" : [
                "The percentage of animals added corresponds to the percentage of ground where the animals will be placed." ,
                "Le pourcentage d'animaux ajouté correspond au pourcentage de cases de terrain où les animaux vont être placés." ,
                "Der Prozentsatz der addierten Tiere entspricht dem Prozentsatz des Bodens, in dem die Tiere gesetzt werden." ,
                "La percentuale degli animali aggiunti corrisponde alla percentuale di terra in cui gli animali saranno disposti." ,
                "El porcentaje de los animales agregados corresponde al porcentaje de la tierra donde los animales serán colocados." ] ,
        "TXT_HELP_ANIMAL2" : [
                "The animals are simply added to the beginning of the game. None of the parameters of CivIV are modified." ,
                "Les animaux sont simplement ajoutés au début de la partie. Aucun des paramètres de CivIV n'est modifié." ,
                "Die Tiere werden einfach dem Anfang des Spiels hinzugefügt. Keine der Parameter von CivIV werden geändert." ,
                "Gli animali sono aggiunti semplicemente all'inizio del gioco. Nessun dei parametri di CivIV sono modificati." ,
                "Los animales se agregan simplemente al principio del juego. No se modifica ningunos de los parámetros de CivIV." ] ,
        "TXT_HELP_TECH0" : [
                "For technologies :" ,
                "Pour les technologies :" ,
                "Für die Technologien :" ,
                "Per le tecnologie :" ,
                "Para las tecnologías :" ] ,
        "TXT_HELP_TECH1" : [
                "You can leave original technologies or erase them all. You can select technologies not to be erased. That can be useful for MODS which use special technologies to differentiate civilizations. In the doubt, leave original technologies." ,
                "Vous pouvez laisser les technologies originales ou les effacer toutes. Vous pouvez sélectionner des technologies à ne pas effacer. Cela peut être utile pour des MODS qui utilisent des technologies spéciales pour différencier les civilisations. Dans le doute, laissez les technologies originales." ,
                "Sie können die Originaltechnologien lassen oder sie löschen alle. Sie können zu löschende nicht Technologien auswählen. Das kann für MODS nützlich sein, die spezielle Technologien benutzen, um die Zivilisationen zu unterscheiden. Im Zweifel lassen die Originaltechnologien." ,
                "Potete lasciare le tecnologie originali o cancellarle tutte. Potete scegliere tecnologie da non cancellare. Ciò può essere utile per MODS che utilizzano tecnologie speciali per differenziare le civilizzazioni. Nel dubbio, lasciate le tecnologie originali." ,
                "Pueden dejar las tecnologías originales o borrarlos todas. Pueden seleccionar tecnologías que deben borrarse. Eso puede ser útil para MODS que utilizan tecnologías especiales para diferenciar las civilizaciones. En la duda, dejan las tecnologías originales." ] ,
        "TXT_HELP_TECH2" : [
                "When you add a random number of technologies. The program will check that the player can research this technology. The least expensive technologies will be selected." ,
                "Lorsque vous ajoutez un nombre aléatoire de technologies. Le programme vérifiera que le joueur peut rechercher cette technologie. Les technologies les moins coûteuses seront sélectionnées." ,
                "Wenn Sie eine gelegentliche Anzahl von Technologien hinzufügen. Das Programm prüft, ob der Spieler diese Technologie erforschen kann. Die wenigen kostspieligen Technologien werden vorgewählt." ,
                "Quando aggiungete un numero casuale di tecnologie. Il programma controllerà che il giocatore possa ricercare questa tecnologia. Le meno tecnologie costose saranno selezionate." ,
                "Cuando usted agrega un número al azar de tecnologías. El programa comprobará que el jugador pueda investigar esta tecnología. Las menos tecnologías costosas serán seleccionadas." ] ,
        "TXT_HELP_TECH3" : [
                "If you add a technology selected, the program will add this technology without checking." ,
                "Si vous ajoutez une technologie sélectionnées, le programme ajoutera cette technologie sans vérification." ,
                "Wenn Sie eine Technologie hinzufügen ausgewählt, wird das Programm diese Technologie ohne Prüfung hinzufügen." ,
                "Se aggiungete una tecnologia scelte, il programma aggiungerà questa tecnologia senza verifica." ,
                "Si añaden una tecnología seleccionadas, el programa añadirá esta tecnología sin comprobación." ] ,
        "TXT_HELP_UNIT0" : [
                "For the units :" ,
                "Pour les unités :" ,
                "Für die Einheiten :" ,
                "Per le unità :" ,
                "Para las unidades :" ] ,
        "TXT_HELP_UNIT1" : [
                "For certain units, you will see a maximum number indicated (total, by team or player). This number is simply indicative. It's to inform you about what the game provides in general. The program will not limit the number of added units." ,
                "Pour certaines unités, vous verrez un nombre maximal indiqué (global, par équipe ou par joueur). Ce nombre est simplement indicatif. C'est pour vous renseigner sur ce que le jeu prévoit en général. Le programme ne limitera pas le nombre d'unités ajoutées." ,
                "Für bestimmte Maßeinheiten sehen Sie eine Höchstzahl, die angezeigt wird (total, durch Mannschaft oder Spieler). Diese Zahl ist einfach hinweisend. Sie soll informieren Sie über, was das Spiel im allgemeinen zur Verfügung stellt. Das Programm begrenzt nicht die Zahl addierten Maßeinheiten." ,
                "Per determinate unità, vedrete un numero massimo indicato (totale, tramite la squadra o il giocatore). Questo numero è semplicemente indicativo. Deve informarlo circa che cosa il gioco fornisce in generale. Il programma non limiterà il numero di unità aggiunte." ,
                "Para ciertas unidades, usted verá un número máximo indicado (total, por el equipo o el jugador). Este número es simplemente indicativo. Debe informarle sobre lo que proporciona el juego en general. El programa no limitará el número de unidades agregadas." ] ,
        "TXT_HELP_UNIT2" : [
                "For the option '%s', let us take an example: that is to say four civilizations CivA, CivB, CivC and CivD. CivA and CivB can produce ' warriors ', CivC has a single unit in the place of the ' warriors ' which is the ' wild warrior ', and CivD cannot produce ' warriors '." ,
                "Pour l'option '%s', prenons un exemple: soit quatre civilisations CivA, CivB, CivC et CivD. CivA et CivB peuvent produire des 'guerriers ', CivC possède une unité unique à la place des 'guerriers ' qui est le 'guerrier sauvage ', et CivD ne peut pas produire de 'guerriers '." ,
                "Für die Option '%s' nehmen ein Beispiel: das heißt vier Zivilisationen CivA, CivB, CivC et CivD. CivA und CivB können ' kriegerische ' produzieren, CivC besitzt eine einmalige Einheit an der Stelle ' der kriegerischen ', das das ' kriegerische ist wild ', und CivD kann keine ' kriegerischen ' produzieren." ,
                "Per l'opzione '%s', prendiamo un esempio: cioè quattro civilizzazioni CivA, CivB, CivC et CivD. CivA e CivB possono produrre 'guerrieri ', CivC possiede un'unità unica al posto dei 'guerrieri 'che è il 'guerriero selvaggio ', e CivD non può produrre 'guerrieri '." ,
                "Para la opción '%s', toman un ejemplo: o sea cuatro civilizaciones CivA, CivB, CivC et CivD. CivA y CivB pueden producir ' belicosos ', CivC posee una u'nica unidad al lugar del ' belicosos ' que es el ' belicoso salvaje ', y CivD no puede producir ' belicosos '." ] ,
        "TXT_HELP_UNIT3" : [
                "You select the ' wild warrior ' like unit to be added." ,
                "Vous sélectionnez le 'guerrier sauvage ' comme unité à ajouter ." ,
                "Sie wählen das ' kriegerische wild ' als hinzuzufügende Einheit aus." ,
                "Scegliete il 'guerriero selvaggio 'come unità da aggiungere." ,
                "Seleccionan el ' belicoso salvaje ' como unidad que debe añadirse." ] ,
        "TXT_HELP_UNIT4" : [
                "If you choose '%s': four civilizations will have a ' wild warrior '." ,
                "Si vous choisissez '%s': les quatre civilisations auront un 'guerrier sauvage '." ,
                "Wenn Sie wählen '%s': die vier Zivilisationen werden ein ' kriegerische ist wild '." ,
                "Se scegliete '%s': le quattro civilizzazioni avranno un 'guerriero selvaggio '." ,
                "Si eligen '%s': las cuatro civilizaciones tendrán un ' belicoso salvaje '." ] ,
        "TXT_HELP_UNIT5" : [
                "If you choose '%s': CivC will have a ' wild warrior '. And all other civilizations will have a ' warrior '." ,
                "Si vous choisissez '%s': CivC aura un 'guerrier sauvage '. Et toutes les autres civilisations auront un 'guerrier '." ,
                "Wenn Sie wählen '%s': CivC wird ein ' kriegerische ist wild '. Und alle anderen Zivilisationen werden ein ' kriegerisches ' haben." ,
                "Se scegliete '%s': CivC avrà un 'guerriero selvaggio '. E tutte le altre civilizzazioni avranno un 'guerriero '." ,
                "Si eligen '%s': CivC tendrá un ' belicoso salvaje '. Y todas las demás civilizaciones tendrán un ' belicoso '." ] ,
        "TXT_HELP_UNIT6" : [
                "If you choose '%s': CivC will have a ' wild warrior '. CivA and CivB will have a ' warrior '. CivD will not have anything." ,
                "Si vous choisissez '%s': CivC aura un 'guerrier sauvage '. CivA et CivB auront un 'guerrier '. CivD n'aura rien." ,
                "Wenn Sie wählen '%s': CivC wird ein ' kriegerische ist wild '. CivA und CivB werden ein ' kriegerisches ' haben. CivD wird nichts haben." ,
                "Se scegliete '%s': CivC avrà un 'guerriero selvaggio '. CivA e CivB avranno un 'guerriero '. CivD non avrà nulla." ,
                "Si eligen '%s': CivC tendrá un ' belicoso salvaje '. CivA y CivB tendrán un ' belicoso '. CivD no tendrá nada." ] ,
        "TXT_GAME_CITYDEF" : [
                "Experts in defense of city" ,
                "Experts en défense de cité" ,
                "Stadtverteidigungsexperten" ,
                "Esperti in difesa di città" ,
                "Expertos en defensa de ciudad" ] ,
        "TXT_GAME_CITYFIGHT" : [
                "Defenders of city" ,
                "Défenseurs de cité" ,
                "Stadtverteidiger" ,
                "Difensori di città" ,
                "Partidarios de ciudad" ] ,
        "TXT_UNIT_PEACE" : [
                "Peace units" ,
                "Unités de paix" ,
                "Friedensmaßeinheiten" ,
                "Unità di pace" ,
                "Unidades de la paz" ] ,
        "TXT_UNIT_LAND" : [
                "Land units" ,
                "Unités terrestres" ,
                "Erdeinheiten" ,
                "Unità terrestri" ,
                "Unidades terrestres" ] ,
        "TXT_UNIT_WATER" : [
                "Naval units" ,
                "Unités navales" ,
                "Schiffseinheiten" ,
                "Unità navali" ,
                "Unidades navales" ] ,
        "TXT_UNIT_AIR" : [
                "Air units" ,
                "Unités aériennes" ,
                "Lufteinheiten" ,
                "Unità aeree" ,
                "Unidades aéreas" ] ,
        "TXT_UNIT_OTHER" : [
                "Special units" ,
                "Unités spéciales" ,
                "Spezielle Einheiten" ,
                "Unità speciali" ,
                "Unidades especiales" ] ,
        "TXT_UNIT_NATIONAL" : [
                "National units" ,
                "Unités nationales" ,
                "Nationale Einheiten" ,
                "Unità nazionali" ,
                "Unidades nacionais" ] ,
        "TXT_UNIT_TEAM" : [
                "Team units" ,
                "Unités d'équipe" ,
                "Mannschaftmaßeinheiten" ,
                "Unità della squadra" ,
                "Unidades del equipo" ] ,
        "TXT_UNIT_WORLD" : [
                "World units" ,
                "Unités mondiales" ,
                "Weltweite Einheiten" ,
                "Unità mondiali" ,
                "Unidades mundiales" ] ,
        "TXT_UNIT_COMBATNONE" : [
                "Units without combat type" ,
                "Unités sans type de combat" ,
                "Maßeinheiten ohne Kampfart" ,
                "Unità senza tipo di combattimento" ,
                "Unidades sin tipo del combate" ] ,
        "TXT_NO_GAME_OPTIONS" : [
                "Sorry! It seems that the MOD with which you want to play is not compatible with the game options." ,
                "Désolé ! Il semble que le MOD avec lequel vous voulez jouer n'est pas compatible avec les options de jeu ." ,
                "Traurig! Es scheint, daß der Umb., mit dem Sie spielen möchten, nicht mit den Spielwahlen kompatibel ist." ,
                "Spiacente! Sembra che il MOD con cui desiderate giocare non è compatibile con le opzioni del gioco." ,
                "Apesadumbrado! Se parece que la MOD con la cual usted desea jugar no es compatible con las opciones del juego." ] ,
        "TXT_NO_GAME_OPTIONS0" : [
                "Please, defer this bug on the forum :" ,
                "S'il vous plait, reportez ce bug sur le forum :" ,
                "Bitte vertagen dieses bug auf dem Forum :" ,
                "Per favore, rinviate questo bug sulla tribuna :" ,
                "Por favor, se prorroga este bug sobre el foro :" ] ,
        "TXT_STARTLOCS_NORMALIZE" : [
                "Standardization :" ,
                "Normalisation :" ,
                "Normung :" ,
                "Normalizzazione :" ,
                "Normalización :" ] ,
        "TXT_STARTLOCS_NORM_START" : [
                "Teams :" ,
                "Equipes :" ,
                "Teams :" ,
                "Gruppi :" ,
                "Equipos :" ] ,
        "TXT_STARTLOCS_NORM_START_SEL0" : [
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Norma" ] ,
        "TXT_STARTLOCS_NORM_START_SEL1" : [
                "Apply" ,
                "Appliquer" ,
                "Anwenden" ,
                "Applicare" ,
                "Aplicarse" ] ,
        "TXT_STARTLOCS_NORM_START_SEL2" : [
                "Skip" ,
                "Passer" ,
                "Übergehen" ,
                "Passare" ,
                "Pasar" ] ,
        "TXT_STARTLOCS_NORM_RIVER" : [
                "River :" ,
                "Rivière :" ,
                "Fluß :" ,
                "Fiume :" ,
                "Rivière :" ] ,
        "TXT_STARTLOCS_NORM_RIVER_SEL0" : [
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Norma" ] ,
        "TXT_STARTLOCS_NORM_RIVER_SEL1" : [
                "Apply" ,
                "Appliquer" ,
                "Anwenden" ,
                "Applicare" ,
                "Aplicarse" ] ,
        "TXT_STARTLOCS_NORM_RIVER_SEL2" : [
                "Skip" ,
                "Passer" ,
                "Übergehen" ,
                "Passare" ,
                "Pasar" ] ,
        "TXT_STARTLOCS_NORM_PEAK" : [
                "Mountains :" ,
                "Montagnes :" ,
                "Berge :" ,
                "Montagne :" ,
                "Montagnes :" ] ,
        "TXT_STARTLOCS_NORM_PEAK_SEL0" : [
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Norma" ] ,
        "TXT_STARTLOCS_NORM_PEAK_SEL1" : [
                "Apply" ,
                "Appliquer" ,
                "Anwenden" ,
                "Applicare" ,
                "Aplicarse" ] ,
        "TXT_STARTLOCS_NORM_PEAK_SEL2" : [
                "Skip" ,
                "Passer" ,
                "Übergehen" ,
                "Passare" ,
                "Pasar" ] ,
        "TXT_STARTLOCS_NORM_LAKE" : [
                "Lake :" ,
                "Lac :" ,
                "See :" ,
                "lago :" ,
                "lago :" ] ,
        "TXT_STARTLOCS_NORM_LAKE_SEL0" : [
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Norma" ] ,
        "TXT_STARTLOCS_NORM_LAKE_SEL1" : [
                "Apply" ,
                "Appliquer" ,
                "Anwenden" ,
                "Applicare" ,
                "Aplicarse" ] ,
        "TXT_STARTLOCS_NORM_LAKE_SEL2" : [
                "Skip" ,
                "Passer" ,
                "Übergehen" ,
                "Passare" ,
                "Pasar" ] ,
        "TXT_STARTLOCS_NORM_BADFEAT" : [
                "Bad Features :" ,
                "Mauvaises caractéristiques :" ,
                "Schlechte Eigenschaften :" ,
                "Cattive caratteristiche :" ,
                "Malas características :" ] ,
        "TXT_STARTLOCS_NORM_BADFEAT_SEL0" : [
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Norma" ] ,
        "TXT_STARTLOCS_NORM_BADFEAT_SEL1" : [
                "Apply" ,
                "Appliquer" ,
                "Anwenden" ,
                "Applicare" ,
                "Aplicarse" ] ,
        "TXT_STARTLOCS_NORM_BADFEAT_SEL2" : [
                "Skip" ,
                "Passer" ,
                "Übergehen" ,
                "Passare" ,
                "Pasar" ] ,
        "TXT_STARTLOCS_NORM_BADTER" : [
                "Bad grounds :" ,
                "Mauvais terrains :" ,
                "Schlecht Gelände :" ,
                "Cattive terreni :" ,
                "Malas terrenos :" ] ,
        "TXT_STARTLOCS_NORM_BADTER_SEL0" : [
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Norma" ] ,
        "TXT_STARTLOCS_NORM_BADTER_SEL1" : [
                "Apply" ,
                "Appliquer" ,
                "Anwenden" ,
                "Applicare" ,
                "Aplicarse" ] ,
        "TXT_STARTLOCS_NORM_BADTER_SEL2" : [
                "Skip" ,
                "Passer" ,
                "Übergehen" ,
                "Passare" ,
                "Pasar" ] ,
        "TXT_STARTLOCS_NORM_FOODBONUS" : [
                "Food :" ,
                "Nourriture :" ,
                "Nahrung :" ,
                "Prodotti alimentari :" ,
                "Comida :" ] ,
        "TXT_STARTLOCS_NORM_FOODBONUS_SEL0" : [
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Norma" ] ,
        "TXT_STARTLOCS_NORM_FOODBONUS_SEL1" : [
                "Apply" ,
                "Appliquer" ,
                "Anwenden" ,
                "Applicare" ,
                "Aplicarse" ] ,
        "TXT_STARTLOCS_NORM_FOODBONUS_SEL2" : [
                "Skip" ,
                "Passer" ,
                "Übergehen" ,
                "Passare" ,
                "Pasar" ] ,
        "TXT_STARTLOCS_NORM_GOODTER" : [
                "Good grounds :" ,
                "Bon terrains :" ,
                "Gut Gelände :" ,
                "Buono terreni :" ,
                "Bueno terrenos :" ] ,
        "TXT_STARTLOCS_NORM_GOODTER_SEL0" : [
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Norma" ] ,
        "TXT_STARTLOCS_NORM_GOODTER_SEL1" : [
                "Apply" ,
                "Appliquer" ,
                "Anwenden" ,
                "Applicare" ,
                "Aplicarse" ] ,
        "TXT_STARTLOCS_NORM_GOODTER_SEL2" : [
                "Skip" ,
                "Passer" ,
                "Übergehen" ,
                "Passare" ,
                "Pasar" ] ,
        "TXT_STARTLOCS_NORM_EXTRA" : [
                "Extras :" ,
                "Extras :" ,
                "Extras :" ,
                "Extras :" ,
                "Extras :" ] ,
        "TXT_STARTLOCS_NORM_EXTRA_SEL0" : [
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Norma" ] ,
        "TXT_STARTLOCS_NORM_EXTRA_SEL1" : [
                "Apply" ,
                "Appliquer" ,
                "Anwenden" ,
                "Applicare" ,
                "Aplicarse" ] ,
        "TXT_STARTLOCS_NORM_EXTRA_SEL2" : [
                "Skip" ,
                "Passer" ,
                "Übergehen" ,
                "Passare" ,
                "Pasar" ] ,
        "TXT_STARTLOCS_NORM_SAMETILE" : [
                "Units :" ,
                "Unités :" ,
                "Einheiten :" ,
                "Unità :" ,
                "Unidades :" ] ,
        "TXT_STARTLOCS_NORM_SAMETILE_SEL0" : [
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Standard" ,
                "Norma" ] ,
        "TXT_STARTLOCS_NORM_SAMETILE_SEL1" : [
                "Scattered" ,
                "Eparpillées" ,
                "Um den Siedler" ,
                "Diffuse" ,
                "Dispersados" ] ,
        "TXT_STARTLOCS_NORM_SAMETILE_SEL2" : [
                "On the same tile" ,
                "Sur la même case" ,
                "Auf demselben Kasten" ,
                "Sulla stessa scatola" ,
                "Sobre la misma casilla" ] ,
        "TXT_HELP_NORM0" : [
                "CivIV envisages a series of functions to balance the starting points. Here the description of these functions." ,
                "CivIV prévoit une série de fonctions pour équilibrer les points de départ . Voici la description de ces fonctions." ,
                "CivIV sieht eine Reihe von Funktionen vor, um die Ausgangspunkte auszubalancieren. Hier die Beschreibung dieser Funktionen." ,
                "CivIV prevede una serie di funzioni di equilibrare le località di partenza. Ecco la descrizione di queste funzioni." ,
                "CivIV prevé una serie de funciones para equilibrar los puntos de partida. He aquí la descripción de estas funciones." ] ,
        "TXT_HELP_NORM1" : [
                "You can choose %r to leave the implementation by default for the selected map. Or, you can force or pass one this fontions." ,
                "Vous pouvez choisir %r pour laisser l'implémentation par default de la carte sélectionnée. Ou bien , vous pouvez forcer ou passer une de ce fontions." ,
                "Sie können wählen %r, um die Implementierung durch default der ausgewählten Karte zu lassen. Entweder können Sie eines von diesen fontions forcieren oder übergehen." ,
                "Potete scegliere %r di lasciare l'esecuzione per default della carta scelta. O, potete forzare o passare una di questi fontions." ,
                "Pueden elegir %r para dejar la puesta en práctica por default de la tarjeta seleccionada. O, pueden forzar o pasar una de estos fontions." ] ,
        "TXT_HELP_NORM2" : [
                "This function is used to bring closer the players in the same team. Warning, this function may be automatically skipped if other options to replace players are activated." ,
                "Cette fonction sert à rapprocher les joueurs dans la même équipe. Attention, cette fonction peut être automatiquement passée si d'autres options pour replacer des joueurs sont activées." ,
                "Diese Funktion dient dazu, die Spieler im selben Team näher zu bringen. Warnend, kann diese Funktion automatisch übersprungen werden, wenn andere Wahlen, zum der Spieler zu ersetzen aktiviert werden." ,
                "Questa funzione serve ad avvicinare i giocatori nello stesso gruppo. Avvertendo, questa funzione può essere saltata automaticamente se altre opzioni per sostituire i giocatori sono attivate." ,
                "Esta función sirve para acercar a los jugadores en el mismo equipo. Advirtiendo, esta función puede ser saltada automáticamente si otras opciones para substituir a jugadores se activan." ] ,
        "TXT_HELP_NORM2_1" : [
                "If you choose the option %r, this function is not launched." ,
                "Si vous choisissez l'option %r, cette fonction n'est pas lancée." ,
                "Wenn Sie die Option wählen %r, wird diese Funktion nicht eingeführt." ,
                "Se scegliete l'opzione %r, questa funzione non è lanciata." ,
                "Si eligen la opción %r, no se lanza esta función." ] ,
        "TXT_HELP_NORM3" : [
                "This function tries to create a river if the starting point does not have access to water." ,
                "Cette fonction essaie de créer une rivière si le point de départ n'a pas accès à de l'eau." ,
                "Diese Funktion versucht, einen Fluß zu schaffen, wenn der Ausgangspunkt keinen Zugang zu Wasser hat." ,
                "Questa funzione prova a creare un fiume se il punto di partenza non ha accesso all'acqua." ,
                "Esta función intenta crear un río si el inicio no tiene acceso a agua." ] ,
        "TXT_HELP_NORM4" : [
                "This function removes the mountains around the starting point." ,
                "Cette fonction enlève les montagnes autour du point de départ." ,
                "Diese Funktion nimmt die Berge um den Ausgangspunkt weg." ,
                "Questa funzione toglie le montagne attorno al punto di partenza." ,
                "Esta función retira las montañas en torno al inicio." ] ,
        "TXT_HELP_NORM5" : [
                "This function creates a lake beside the starting point if it still does not have access to water." ,
                "Cette fonction crée un lac à côté du point de départ s'il n'a toujours pas accès à l'eau." ,
                "Diese Funktion schafft einen See neben dem Ausgangspunkt, wenn er noch keinen Zugang zum Wasser hat." ,
                "Questa funzione crea un lago accanto al punto di partenza se non ha sempre accesso all'acqua." ,
                "Esta función crea un lago junto al inicio si no tiene siempre acceso al agua." ] ,
        "TXT_HELP_NORM6" : [
                "This function removes the negative elements like the jungle for example." ,
                "Cette fonction enlève les éléments négatifs comme la jungle par exemple." ,
                "Diese Funktion nimmt die negativen Elemente als der Dschungel weg zum Beispiel." ,
                "Questa funzione toglie gli elementi negativi come la giungla ad esempio." ,
                "Esta función retira los elementos negativos como la selva por ejemplo." ] ,
        "TXT_HELP_NORM7" : [
                "This function removes the nonproductive grounds like snow or the tundra." ,
                "Cette fonction enlève les terrains non productifs comme la neige ou la toundra." ,
                "Diese Funktion nimmt die nicht produktiven Gelände als der Schnee oder die Tundra weg." ,
                "Questa funzione toglie i terreni non produttivi come la neve o toundra." ,
                "Esta función retira los terrenos no productivos como la nieve o la tundra." ] ,
        "TXT_HELP_NORM8" : [
                "This function adds zero, one or two resources of food according to those already present." ,
                "Cette fonction ajoute zéro, une ou deux ressources de nourriture en fonction de celles déjà présentes." ,
                "Diese Funktion fügt Null, ein oder zwei Nahrungsmittel gemäß schon gegenwärtigen jenen hinzu." ,
                "Questa funzione aggiunge zero, una o due risorse di prodotti alimentari in funzione di quelle già presenti." ,
                "Esta función añade cero, una o dos recursos de comida en función de las ya presentes." ] ,
        "TXT_HELP_NORM9" : [
                "This function transforms grounds if there are not at least four tiles with a minimum of two foods and a production." ,
                "Cette fonction transforme des terrains si il n'y a pas au moins quatre cases avec un minimum de deux nourritures et une production." ,
                "Diese Funktion wandelt Gelände um, wenn es nicht wenigstens vier Kästen mit einem Minimum von zwei Nahrungen und einer Produktion gibt." ,
                "Questa funzione trasforma terreni se non ci sono almeno quattro scatole con un minimo di due prodotti alimentari ed una produzione." ,
                "Esta función transforma terrenos si no hay al menos cuatro casillas con un mínimo de dos comidas y una producción." ] ,
        "TXT_HELP_NORM10" : [
                "Lastly, this function tries to add elements like forest or resources to equalize the starting points." ,
                "En dernier lieu, cette fonction essaie d'ajouter des éléments comme de la forêt ou des ressources pour égaliser les points de départ." ,
                "Zuletzt versucht diese Funktion, Elemente als Wald oder Mittel hinzuzufügen, um die Ausgangspunkte gleichzumachen." ,
                "Infine, questa funzione prova ad aggiungere elementi come foresta o risorse per uguagliare le località di partenza." ,
                "En último lugar, esta función intenta añadir elementos como bosque o recursos para igualar los puntos de partida." ] ,
        "TXT_GAME_LOG_FILE" : [
                "Log :" ,
                "Log :" ,
                "Log :" ,
                "Log :" ,
                "Log :" ] ,
        "TXT_GAME_LOG_WRITE" : [
                "File log :" ,
                "Fichier log :" ,
                "Kartei log :" ,
                "Archivio log :" ,
                "Fichero log :" ] ,
        "TXT_GAME_LOG_WRITE_SEL0" : [
                "Write" ,
                "Ecrire" ,
                "Schreiben" ,
                "Scrivere" ,
                "Escribir" ] ,
        "TXT_STARTLOCS_RELOCATE" : [
                "Relocate :" ,
                "Relocaliser :" ,
                "Verlagern Sie :" ,
                "Riassegnare :" ,
                "Volver a poner :" ] ,
        "TXT_STARTLOCS_SWAPHUMANS" : [
                "For multi-players game :" ,
                "Pour une partie multi-joueurs :" ,
                "Für ein mp-Spiel :" ,
                "Per un gioco multi-giocatori :" ,
                "Para un juego jugadores multi :" ] ,
        "TXT_STARTLOCS_SWAPHUMANS_SEL0" : [
                "Move away the human players" ,
                "Eloigner les joueurs humains" ,
                "Die menschlichen Spieler entfernen" ,
                "Allontanare i giocatori umani" ,
                "Alejar los jugadores humanos" ] ,
        "TXT_INFOS_0" : [
                "Welcome :" ,
                "Bienvenue :" ,
                "Willkommen :" ,
                "Benvenuto :" ,
                "Bienvenida :" ] ,
        "TXT_INFOS_1" : [
                "Do not hesitate to deliver your opinion or of new ideas on the forum." ,
                "N'hésitez pas a donner votre avis ou de nouvelles idées sur le forum." ,
                "Zögern Sie nicht, Ihre Stellungnahme oder der neuen Ideen auf dem Forum abzugeben." ,
                "Non esiti ad esprimere il vostro parere o di nuove idee sulla tribuna." ,
                "No vacile adoptar su dictamen o de nuevas ideas en el foro." ] ,
        "TXT_INFOS_2" : [
                "General information :" ,
                "Informations générales :" ,
                "Allgemeine Informationen :" ,
                "Informazioni generali :" ,
                "Información general :" ] ,
        "TXT_INFOS_3" : [
                "For many options, you can select several choices (scripts, options of scripts, grounds, ...)." ,
                "Pour de nombreuses options, vous pouvez selectionner plusieurs choix (scripts, options des scripts, terrains, ...)." ,
                "Für zahlreiche Optionen können Sie mehrere Wahl auswählen (Skripte, Optionen der Skripte, Gelände, ...)." ,
                "Per numerose opzioni, potete scegliere molte scelte (manoscritti, opzioni dei manoscritti, terreni, ...)." ,
                "Para numerosas opciones, puede seleccionar varias elecciones (escrituras, opciones de las escrituras, terrenos, ...)." ] ,
        "TXT_INFOS_4" : [
                "All that required a choice will be decided by chance during the generation." ,
                "Tout ce qui necessite un choix sera decidé aléatoirement durant la génération." ,
                "Alles, was erfordert eine Wahl zufällig während der Generation beschlossen wird." ,
                "Tutto e questo richiesto una scelta sarà decisa aléatoirement durante la generazione." ,
                "Todo lo que requerido se decidirá una elección aleatoriamente durante la generación." ] ,
        "TXT_INFOS_5" : [
                "When you enter values, you can check if they are valid while clicking on the <%s> button." ,
                "Quand vous entrez des valeurs, vous pouvez vérifier si elles sont valables en cliquant sur le bouton <%s>." ,
                "Wenn Sie Werte eintragen, können Sie überprüfen, ob sie beim Klicken auf dem <%s> Knopf gültig sind." ,
                "Quando entrate nei valori, potete controllare se sono validi mentre si scattano sul tasto <%s>." ,
                "Cuando usted incorpora valores, usted puede comprobar si son válidos mientras que chascan en el botón <%s>." ] ,
        "TXT_INFOS_6" : [
                "Never press the <Esc> key to leave a screen." ,
                "Ne pressez jamais la touche <Esc> pour sortir d'un écran." ,
                "Drücken Sie nie die <Esc>-Taste, um einen Schirm zu lassen." ,
                "Non premi mai il tasto di <Esc> per lasciare uno schermo." ,
                "Nunca presione la tecla <Esc> Para dejar una pantalla." ] ,
        "TXT_INFOS_7" : [
                "It is always necessary to click on one of the buttons <%s> or <%s>." ,
                "Il faut toujours cliquer sur un des boutons <%s> ou <%s>." ,
                "Man muss immer auf einem der Knöpfe klicken <%s> oder <%s>." ,
                "Occorre sempre premere su uno dei bottoni <%s> o <%s>." ,
                "Es necesario presionar siempre uno de los botones <%s> u <%s>." ] ,
        "TXT_INFOS_8" : [
                "If inopportunely you press the <Esc> key, you can open again the screen and leave while clicking on the button exit." ,
                "Si malencontreusement vous pressez la touche <Esc>, il suffit de revenir dans l'écran et de sortir en cliquant sur le bouton de sortie." ,
                "Wenn unangebracht Sie die <Esc>-Taste drücken, können Sie den Schirm wieder öffnen und beim Klicken auf den Knopfausgang gehen." ,
                "Se inopportuno premete il tasto di <Esc>, potete aprire ancora lo schermo ed andare mentre vi scatti sull'uscita del tasto." ,
                "Si inoportunamente usted presiona la tecla <Esc>, Usted puede abrir otra vez la pantalla e irse mientras que chasca en la salida del botón." ] ,
        "TXT_INFOS_9" : [
                "The script creates the <(My Games)CivilizationIV Full of Resources> folder in your documents to record your various selections." ,
                "Le script crée le dossier <(My Games)CivilizationIV Full of Resources> dans vos documents pour enregistrer vos différentes sélections." ,
                "Der Index stellt das <(My Games)CivilizationIV Full of Resources>-Faltblatt in Ihren Dokumenten her, um Ihre verschiedenen Vorwähleren zu notieren." ,
                "Lo scritto genera il dispositivo di piegatura di <(My Games)CivilizationIV Full of Resources> nei vostri documenti per registrare le vostre varie selezioni." ,
                "La escritura crea la carpeta de <(My Games)CivilizationIV Full of Resources> en sus documentos para registrar sus varias selecciones." ] ,
        "TXT_INFOS_9_0" : [
                "If you encounter a bug, please zip this folder and post it in the FoR thread." ,
                "Si vous avez un bug, zipper ce dossier et postez le dans le forum svp." ,
                "Wenn Sie einen Programmierfehler, zip haben diese Akte und im Forum postieren bitte." ,
                "Se avete una boga, zip questa cartella ed inviate nella tribuna per favore." ,
                "Si tiene un error, zip este expediente y los fija el en el foro por favor." ] ,
        "TXT_INFOS_10" : [
                "Do not use the <Lock Modified Assets> option for reasons of compatibility." ,
                "N'utilisez pas l'option <Bloquer Biens modifiés> pour des raisons de compatibilité." ,
                "Verwenden Sie die <Modifizierte Daten sperren>-Wahl nicht aus Gründen der Kompatibilität." ,
                "Non usi l'opzione di <Blocca la modifica dei beni> in ragione della compatibilità." ,
                "No utilice la opción de <Bloquear parámetros modificados> por razones de compatibilidad." ] ,
        "TXT_INFOS_11" : [
                "Do not use <Regenerate Map> into the world builder." ,
                "N'utilisez pas <Régénérer carte> dans l'éditeur de mondes." ,
                "Verwenden Sie <Karte neu laden> nicht in den Welterbauer." ,
                "Non usi l'<Rigenera mappa> nel editor." ,
                "No utilice <Regenerar mapa> en el Creador de mundos." ] ,
        "TXT_INFOS_12" : [
                "For network multiplayer games :" ,
                "Pour les parties multijoueurs de réseau :" ,
                "Für Netzmultispielerspiele :" ,
                "Per i giochi con diversi giocatori della rete :" ,
                "Para los juegos multijugadores de la red :" ] ,
        "TXT_INFOS_13" : [
                "All players must have the script before beginning a game." ,
                "Tous les joueurs doivent avoir le script avant de commencer une partie." ,
                "Vor dem Beginn eines Spiels alle Spieler müssen den Index haben." ,
                "Tutti i giocatori devono avere lo scritto prima di cominciare un gioco." ,
                "Todos los jugadores deben tener la escritura antes de comenzar un juego." ] ,
        "TXT_INFOS_14" : [
                "It is impossible to make pass the selection before the generation of the map." ,
                "C'est impossible de faire passer la sélection avant la génération de la carte aux autres joueurs." ,
                "Es ist unmöglich, Durchlauf die Vorwähler zu anderen Spielern vor dem Erzeugung des Diagramms zu bilden." ,
                "È impossible da rendere a passaggio la selezione ad altri giocatori prima della generazione del programma." ,
                "Es imposible hacer paso la selección a otros jugadores ante la generación del mapa." ] ,
        "TXT_INFOS_15" : [
                "First solution : you launch the game and you will have an <Out Of Synch> error." ,
                "Première solution : vous lancer la partie et vous allez avoir une erreur <Out Of Synch>." ,
                "Erste Lösung : Sie starten das Spiel und Sie haben eine <Out Of Synch> Störung." ,
                "Prima soluzione : lanciate il gioco ed avrete un errore <Out Of Synch>." ,
                "Primera solución : usted pone en marcha el juego y usted tendrá un error <Out Of Synch>." ] ,
        "TXT_INFOS_16" : [
                "In this case, all the players must leave and connect again to the game to solve this problem." ,
                "Dans ce cas, tous les joueurs doivent sortir et se reconnecter à la partie pour résoudre ce problème." ,
                "In diesem Fall müssen alle Spieler an das Spiel wieder gehen und anschließen, um dieses Problem zu lösen." ,
                "In questo caso, tutti i giocatori devono andare ancora e collegarsi al gioco per risolvere questo problema." ,
                "En este caso, todos los jugadores deben irse y conectar otra vez con el juego para solucionar este problema." ] ,
        "TXT_INFOS_17" : [
                "Second solution : Once the selection finished, you send the <_Multiplayer_Config.cfg> file to the other players." ,
                "Deuxième solution : Une fois la sélection terminée, vous envoyez le fichier <_Multiplayer_Config.cfg> aux autres joueurs." ,
                "Zweite Lösung : Einmal beendete die Vorwähler, Sie schicken den anderen Spielern die <_Multiplayer_Config.cfg>-Akte." ,
                "Seconda soluzione : Una volta che la selezione rifinita, voi trasmette la lima di <_Multiplayer_Config.cfg> agli altri giocatori." ,
                "Segunda solución : Una vez que la selección acabó, usted envía el archivo <_Multiplayer_Config.cfg> a los otros jugadores." ] ,
        "TXT_INFOS_18" : [
                "This file is located in the <(My Games)CivilizationIV Full of Resources> folder, in your documents." ,
                "Ce fichier est situé dans le dossier <(My Games)CivilizationIV Full of Resources>, dans vos documents." ,
                "Diese Akte ist im <(My Games)CivilizationIV Full of Resources>-Faltblatt, in Ihren Dokumenten." ,
                "Questa lima è situata nel dispositivo di piegatura di <(My Games)CivilizationIV Full of Resources>, nei vostri documenti." ,
                "Este archivo está situado en la carpeta <(My Games)CivilizationIV Full of Resources>, en sus documentos." ] ,
        "TXT_INFOS_19" : [
                "This file is saved each time you leave the FoR screen in a multiplayer menu." ,
                "Ce fichier est enregistré à chaque fois que vous sortez de l'écran de FoR dans un menu multijoueur." ,
                "Diese Akte wird gespeichert, jedes Mal wenn Sie den FoR Schirm in einem Multispielermenü lassen." ,
                "Questa lima è conservata ogni volta lasciate lo schermo FoR in un menu con diversi giocatori." ,
                "Se salva este archivo cada vez que usted deja la pantalla FoR en un menú multijugador." ] ,
        "TXT_OPEN_BROWSER" : [
                "Open your browser in the FoR thread" ,
                "Ouvrez votre navigateur sur la page FoR" ,
                "Öffnen Sie Ihren Browser in der FoR Seite" ,
                "Apra il vostro browser nella pagina FoR" ,
                "Abra su hojeador en la página FoR" ] ,
        "TXT_CHECK_UPDATE" : [
                "Check for Updates" ,
                "Chercher des Mises à jour" ,
                "Auf Updates prüfen" ,
                "Verifica Aggiornamenti" ,
                "Comprobar Actualizaciones" ] ,
        "TXT_CHECK_UPDATE_FAILED" : [
                "Sorry, impossible to check if an update is available." ,
                "Désolé, impossible de vérifier si une mise à jour est disponible." ,
                "Traurig, unmöglich, zu überprüfen, ob ein Update vorhanden ist." ,
                "Spiacente, impossible controllare se un aggiornamento è disponibile." ,
                "Apesadumbrado, imposible comprobar si una actualización está disponible." ] ,
        "TXT_CHECK_UPDATE_OK" : [
                "Your version is up to date. Good game!" ,
                "Votre version est à jour. Bonne partie!" ,
                "Ihre Version ist aktuell. Gutes Spiel!" ,
                "La vostra versione è aggiornata. Buon gioco!" ,
                "Su versión es hasta la fecha. ¡Buen juego!" ] ,
        "TXT_CHECK_UPDATE_TO_UPDATE" : [
                "An update is available. You can go on the forum to download it." ,
                "Une mise à jour est disponible. Vous pouvez aller sur le forum pour la télécharger." ,
                "Ein Update ist vorhanden. Sie können das Forum fortfahren, es herunterzuladen." ,
                "Un aggiornamento è disponibile. Potete andare sulla tribuna caricarla programmi oggetto." ,
                "Una actualización está disponible. Usted puede ir en el foro a transferirlo." ]
        }

##        "" : [
##                " :" ,
##                " :" ,
##                " :" ,
##                " :" ,
##                " :" ] ,

##        "" : [
##                "" ,
##                "" ,
##                "" ,
##                "" ,
##                "" ] ,

