
[template RMCSliderOption]
{
	;; specify a range that this slider's values can take on
	;; each slider type defines the meaning of the slider's value (see RMCTerrain for example)
	point2	range

	;; area_factor: multiplier to adjust the selected size by the
	;;  area of the map, based on the "reference_size". A value of
	;;  "1" means a linear relationship.
	;; NOTE: see code for how this is actually used
	fixed	area_factor = 1
	
	;; show_ui: if false it will pick a random number for the group size.
	;;  If true the user will be given a slider
	bool	show_ui = true

	;; locked: true means user will not be able to adjust the value
	bool	locked = false
}
	
[template RMCTerrain inherit=RMCSliderOption]
{
	;; specify the range inherited from RMCSliderOption
	;; ex: range = 1,10
	;;
	;; the range for RMCTerrain allows the user to vary the amounts of each terrain type that gets placed
	;; an example is the best way to explain this:
	;;
	;; terrain	range
	;; -------      -----
	;; grass 	1-10
	;; dirt		5-10
	;; water	1-5
	;;
	;; given this setup, the user can assign grass a value between 1-10, dirt between 5-10 and water between 1-5
	;; now, assume that the user picks the following values from the RMC dialog
	;;
	;; terrain	picked value
	;; -------      ------------
	;; grass	10
	;; dirt		8
	;; water	3
	;;
	;; the RMC uses these values to determine the percentages of the map to give to each terrain. a terrain
	;; gets a percentage equal to its value relative to the sum of all the values. In this case, grass would get
	;; 10 out of (10+8+3 = 21) or about 47 percent.

	;; if true, overrides other sliders with the same terrain_ids; ex: if this slider's range is 0-50 and the user
	;; sets it to 25, then other overidden sliders will have a value 50% of their range
	bool override_same = false
	
	;; specify the terrain to generate
	string terrain_ids

	;; this is set automatically (do not change)
	string brush_type

	;; if true, paints the first variation only
	bool paint_first_variation_only = false

	;; attach to map regions (NONE, SOUTHWEST, WEST, NORTHWEST, NORTH, NORTHEAST, EAST, SOUTHEAST, SOUTH, CENTER or RANDOM)
	;; you can specify a comma delimitted list of directions as well (the engine will pick one of them randomly)
	string attachto = NONE
	
	;; for attached brushes you can specify a range that it will offset from the map center or edge. the
	;; RMC will pick a random position within this range. note: if you specify a negative number, it will
	;; use the brush size as the range.
	fixed attach_range = -1
}

;; Terrain Blobs - most land terrains should use blobs, including water terrains. A blob can have a regular shape
;; like a circle or a very irregular and random shape, depending on the settings below.

[template RMCTerrainBlob inherit=RMCTerrain]
{
	brush_type = BLOB

	;; min/max blob size radius (in meters) - the RMC will pick a size in this range randomly
	point2	blob_size = 1,3
	
	;; when the RMC is painting a blob, it starts by painting one tile in the center of the blob. Then, it
	;; looks at all neighboring tiles and assigns a score to each one. The one with the highest score is
	;; painted next. This process continues until the number of tiles making up the blob size is painted.
	;; Note that when a new tile is picked, all previous tiles assigned scores will still being considered.
	;; The scoring mechanism is influenced by four factors: consistency, proximity, dir bias and fuzzy factor.
	;;
	;; consistency - this is a bonus added to a tile's score. For each neighboring tile that has the same
	;; variation as the current tile, a bonus point of 1/8 is given. The consistency value you specify will
	;; be a multiplier of this. So, if you specify a consistency of 2, then a tile with 3 neighbors with the
	;; same varaition will get a bonus of 3*1/8*2 = 3/4.
	;;
	;; dir_bias, dir_bias_factor - this is a bonus added to a tile's score. Each tile has a direction from the blob
	;; center. The angle that this direction makes with the given dir_bias influences the score. The smaller the
	;; angle, the higher the score. The result is tiles going near the dir_bias will get picked more. You can
	;; also specify a dir_bias_factor that essentially weights this property. Give it zero and the dir_bias
	;; will have no influence. Higher factors will cause it to out-influence other factors.

	;; proximity - this is a penalty subtracted from a tile's score. The penalty depends on the distance
	;; the tile is from the center of the blob (in meters). It is normalized to the blob radius, so if the tile
	;; is a distance of the blob radius away, it will have a penalty of one.
	;;
	;; fuzzy factor - this is a random bonus added to a tile's score. For example, if you set fuzzy factor=0.5,
	;; then a random bonus between 0 to 0.5 will be added to a tile's score.
	;;
	;; score = consistency * (num neighbors with same terrain as blob) 
	;;
	;;         		+
	;;
	;;	   fuzzy_factor * (0~1)
	;;
	;;			+
	;;
	;;	   abs( dot( dir_bias, tile_dir ) ) * dir_bias_factor
	;;
	;;	   		-
	;;
	;;	   m_proximity * (distance of tile to center of blob)
	;;
	;; So, what should the range of these factors be? They really depend on each other. Note these points:
	;;
	;; (1) the higher the tile's score, the more chance it will be picked
	;; (2) if you set any factor to 0, it will not effect a tile's score at all.
	;; (3) even though all factors should be positive, they can be made negative to get the opposite effect.
	;; (4) If you make one factor really large relative to the other two, then the other two may be
	;;     inconsequential. This is especially true for distance, so be sure to scale the factors
	;;     to get the desired effect you want.
	;;
	;; The system has been designed so that all values should be in the ranges of 0 to 1.

	fixed	consistency	= 0		;; bonus
	fixed	proximity = 0		;; penalty
	fixed	fuzzy_factor = 1	;; bonus
	point2	dir_bias = 0,0		;; directional bias: (0,0) means pick random
	fixed	dir_bias_factor	= 0	;; directional bias weight

	;; if MicroBlobs is specified, then this blob will contain micro-blobs
	;; of this blob's terrain variations minus the first variation. the blob
	;; itself will be painted with the first variation. the micro-blobs will be
	;; approximately contained within the bounding-circle of this blob. the
	;; variations will be picked randomly but with a distribution specified
	;; by the variation weights.
	;; i.e. if this blob's terrain is grass, then a normal blob of grass01 will
	;; be put down. if Microblobs is specified with a percent of 30, then
	;; approx 30% of the blob will be covered by micro-blobs of grass02 and
	;; grass03. grass02 gets 60% of this 30% because it's weight is that much
	;; higher than grass03.

	[optional MicroBlobs]
	{
		;; approx how much of blob painted over with micro-blobs
		;; specify a ratio range i.e. ratio_range = 0.25, 0.50
		point2 ratio_range
		
		;; same params as normal blobs (please refer to RMCTerrainBlob)
		point2 	blob_size
		fixed 	consistency
		fixed 	proximity
		fixed 	fuzzy_factor	
		bool	affect_height = true		;; if false, the micro-blobs will not affect the heightmap		
	}
}

;; Terrain Streaks - some terrains, particularily mountain terrains, should use streaks instead of blobs.
;; A streak is one continous stroke of the terrain brush, but it is not limited to a straight line. A
;; streak can change direction and brush width a number of times during its stroke. These can be configured
;; below.

[template RMCTerrainStreak inherit=RMCTerrain]
{
	brush_type = STREAK

	;; specify min/max number streaks you want to paint in one continous stroke. the RMC will pick a
	;; random number in this range. Each streak will have a randomly selected length, brush width
	;; and change in direction. Although the choice is random, you can limit the range of the choice below.
	int streaks_min
	int streaks_max
	
	;; length_range - specify the min/max streak length (in meters)
	point2	length_range = 4, 8
	
	;; width_range - specify the min/max brush width (in meters)
	point2	width_range = 4, 8
	
	;; angle_range - specify the min/max change in direction (-/+ range in degrees).
	point2	angle_range = -30, +30
}

;; RMCObjectGroup
;; DESC: describes a group of objects placed in an RMC
[template RMCObjectGroup inherit=RMCSliderOption]
{
	string ids
	localized name

	;; object threshold: if less than this many objects (modified by 'area_factor') are actually
	;;  placed then it counts as failure
	int	objects_min = 0

	;; GROUP CONTENTS - REQUIRED OBJECTS WITH POSITIONS
	;; NOTE: these are always placed regardless of failure_threshold and RMCSliderOption. I.e. the
	;;  number of objects designated by the RMCSliderOption applies to '[list Object]' and not to
	;;  this.  Failure to place a required object is complete failure for the RMG.
	;; TODO: does it create land at that position if necessary?  Altering terrain affects the generation
	;;  process, so instead the RMG would need to (in advance) become aware of all the "RequiredObjects"
	;;  and then before the terrain finalization step ensure those areas are land (or clear). 
	[list RequiredObject]
	{
		string object_ids
	
		;; position: 0,0 means random, otherwise it tries to get as close to the position as possible
		point2 position = 0,0

		;; distance threshold: if the selected position is beyond this, that is failure for the generation
		fixed distance_max = 0
	}

	;; GROUP CONTENTS - RANDOMLY SELECTED OBJECTS
	;; NOTE: using weight==0 will default to the object's placement weight on this biome (which may be 0)
	;; NOTE: refer to 'markers' for nation appropriate actors. Marker resolving can happen at this time.
	;; NOTE: refer to 'random_objects' for a randomly selected object
	[list Object]
	{
		string object_ids
		fixed weight = 0
	}

	;; BALANCED PLACEMENT - if true, this group will be placed using the balanced logic; balanced groups
	;; will ignore intra proximity distances and must not have any group restrictions
	flag balanced_placement = false
	
	;; POSITION SEARCH HINT
	;; you can help the RMG find better random positions by supplying a circle area for it to search in;
	;; first, specify a search radius (if the radius is zero or less, the RMG ignores this entire section)
	;; the large the radius the more likely you will get positions further out from the center)
	
	;; next, specify either a group or kingdom that the circle will be relative to. if a group is specified
	;; the center will be at the center of a bounding circle that encompasses all objects in the group. if
	;; a kingdom is specified, the center will be at the kingdom's starting location.

	;; note: you cannot specify both a relative kingdom and group; you can also specify the special "this"
	;; ids to mean that the relative group is the current group or the kingdom is the kingdom of the current
	;; group, depending on what field it is for.
	
	fixed search_radius = 0
	string search_relative_group_ids = null
	string search_relative_kingdom_ids = null

	;; PLACEMENT RESTRICTIONS
	;; intraproximity_min - minimum distance (in meters) between objects in this group
	;; intraproximity_desired - desired distance (in meters) between objects in this group
	;; starting_location_weight - influence of the group's kingdom's starting location. the
	;;                            higher the value, the more the objects of this group will cluster
	;;                            near the object group's kingdom's starting location
	fixed intraproximity_min = 0
	fixed intraproximity_desired = 0
	fixed starting_location_weight = 100

	[list GroupRestriction]
	{
		;; specify "*" at the end to match all groups with prefix. internally, it will generate a
		;; restriction with each matching group
		;; i.e. "starting*" will match "starting_kingdom0", "starting_kingdom1" and "starting_kingdom2"
		string group_ids
		
		;; same as intraproximity restrictions except relative to objects belonging to the group specified
		;; ex: if group_ids is 'Foobar', then proximity_min means minimum distance between objects of
		;; this group with objects of group 'Foobar'
		fixed proximity_min = 0
		fixed proximity_desired = 0
	}
}

;; NOTE: use markers as a convenience to place a 'nation appropriate' actor for the owner kingdom. 
[template RMCActorGroup inherit=RMCObjectGroup]
{
	;; kingdom_ids = assign these actors to the given kingdom
	string kingdom_ids

	;; if you specify this flag to be true, then this actor group will apply to
	;; all major kingdoms. the kingdom_ids will be ignored; internally, it will generate
	;; an actor group for each of the major kingdoms
	bool apply_to_all_major_kingdoms = false

	;; map must be at least this difficulty level to use this actor group.
	;; null means all difficulty levels.
	string difficulty_level = null
	
	;; can specify properties to apply to actors in this group; can be a comma-delimitted list
	string properties = null
}

;; RMCKingdom
[template RMCKingdom]
{
	string 		IDS
	localized 	name
	bool 		independent = false
	string 		team = null
	
	;; kingdoms are usually placed using balancing logic. however if this is turned off
	;; you can specify an explicit starting pos here (note: coordinates are relative to
	;; the reference map-size and will be adjusted accordingly to the actual map size)
	point2		starting_pos = 0,0

	;; this represents the "type" of kingdom; it can be either "land" or "water".  
	;; this can potentially affect what additional actors are placed into the kingdom (for dyn campaign)
	string		type = land

	;; - for a playable kingdom, any setting set to 'null' means the user will be presented with
	;;    the option (usually via a dropdown).  If it isn't null, then the kingdom is locked to that setting.
	;; - if the final value for nation is 'null' that should probably be an error (markers depend on it)
	;; - faction can be 'null'
	;; - if final value for color is 'null' then it will be randomly assigned by the GWorld
	
	string nation = null
	string faction = null
	string color = null

	;; [Relation] nodes allow changing it on a per kingdom basis
	[list Relation]
	string kingdom_ids
	string relation
}

[template RMCKingdomMinor inherit=RMCKingdom]
{
	independent = true
}

[template RMCKingdomMajor inherit=RMCKingdom]
{
	independent = false

	;; playable: false means no human GPlayer can be assigned to this kingdom. On the settings interface,
	;;  it will not be listed (it will be hidden).
	bool playable = false
	
	;; required: false means if no player is assigned to this kingdom, it is not created (nor are any
	;;  of its actors).
	bool required = false

	;; SAI_default_ids: if not playable or no GPlayer is assigned, it tries to assign the SAI
	;;  with this IDS as the GPlayer.
	string SAI_default_ids = null

	;; Stockpile: define this node to override the default. Otherwise it uses default. This is
	;;  not customizable by the user.
	[optional Stockpile template=PurchaseResource]

	;; Heroes: ids=='null' means random 
	;; NOTE: it will not allow duplicate heroes in the same kingdom
	[list Hero]
	string ids
	
	;; Technology:  A starting technology for this kingdom.
	[list Technology]
	string ids
}

[template RMCTeam]
{
	string IDS
	localized name
}

[template RMC]
{
	string IDS
	localized name
	localized description

	;; true to list this RMC from staging (default: true)
	bool list_in_staging = true

	;; reference_size = reference area is a 128x128 meter map. All numbers (for object groups)
	;;  entered in this file are the numbers designed for a map of that area. Those numbers 
	;;  will be scaled appropriately based on the actual size selected by the user.
	fixed reference_size = 256		;; reference area is a 256x256 meter map

	;; BIOME
	string biome
	
	;; SUN (can be a comma-delimited ids list - RMG will pick one randomly)
	string sun = NULL

	;; WEATHER (can be a comma-delimited ids list - RMG will pick one randomly)
	string weather = NULL

	;; max-percent water/mountain (default is any negative value which means use the values specified
	;; in svars; otherwise should be between 0-1 meaning (0-100%)
	fixed max_percent_water = -1
	fixed max_percent_mountain = -1

	;; balanced-kingdoms (if true, the RMG will use the balancing logic for kingdom placement
	;; else it will use each kingdom's specified starting_pos)
	bool balanced_kingdoms = true

	;; desired distance between kingdoms that are on the same team
	fixed team_desired_distance = 96
	
	;; MAPSIZES - list of playable mapsizes and their recommended # of kingdoms
	[list MapSize]
	{
		fixed width
		fixed height
		
		;; recommended number of kingdoms
		int	recommended_kingdoms_min
		int	recommended_kingdoms_max
	}

	;; WORLD RULES - map_type is always "PLAYABLE"
	[Rules]
	{
		string	game_type
		
		[list Rule]
		string	ids
		string	default
		bool	show_ui = true
	}

	;; TERRAIN
	;; NOTE: variations of the terrain are distributed per weights actually
	;;  stored in the TerrainVariation. They currently cannot be customized here.
	;; NOTE: biome terrains that are not listed here do not appear on the random
	;;  map, so there should be one RMC template setup per biome.
	[list TerrainBlob template=RMCTerrainBlob]
	[list TerrainStreak template=RMCTerrainStreak]

	;; TERRAIN NOISE - specify terrain heightmap noise (see NoiseData in template Terrain)
	;; each node will be applied ontop of the previous nodes' changes
	[list TerrainNoise template=NoiseData]
	
	;; WORLD PARAMETERS - specify the teams and kingdoms that can be selected from staging
	;; NOTE: the kingdom IDS's you assign here can be used to assign actor groups to a
	;; particular kingdom
	[list Team template=RMCTeam]
	[list Kingdom Template = RMCKingdom]

	;; ACTOR GROUPS - groups of actors to randomly place (see RMCActorGroup)
	[list ActorGroup template=RMCActorGroup]

	;; DOODAD GROUPS - groups of doodads to randomly place (see RMCObjectGroup)
	[list DoodadGroup template=RMCObjectGroup]

	;; HEROES - allows allocating random heroes to all kingdoms
	[Heroes]
	{
		localized	name = "#template_rmc_Heroes_name"
		int		random_heroes_min = 0
		int 		random_heroes_max = 0
		bool		show_ui = true
	}
}