# Map script

Map script
Map scripts provide a powerful method to generate diverse, dynamic maps with just a few lines of simple script code. Map scripts can be used to generate new maps, as well as modify existing maps defined as static Map.bmp or dynamic Landscape.txt.
Introduction
A map script is simply a script file called Map.c placed in a scenario. On scenario initialization, the engine calls the local function called InitializeMap in this script. If the function returns true, the map will be used by the engine. If false is returned, the map is discarded and the regular fallback map is created.
Here an example of a simple map script:
/* A simple map */

#include Library_Map

func InitializeMap(proplist map) { // Create a big map Resize(150,150); // Draw earth DrawRegularGround(); // Draw some resources into the ground DrawWaterVeins(3, [0,map.Hgt/3,map.Wdt,map.Hgt*2/3]); DrawCoal(6); DrawSulphur(4); DrawRock(15); DrawOre(4); DrawGold(2*GetStartupPlayerCount()); // amount of gold depends on player count! // Make sure liquids don't border tunnel or sky sideways FixLiquidBorders(); // Done. Use this map. return true; }
This draws a pretty boring standard map with basic resources. It makes use of some high-level helper functions such as DrawRegularGround or DrawCoal. which are included in the definition named Library_Map in Objects.ocd/Libraries.ocd. All map scripts should include this definition.
Layers
All map draw functions work on layers, which are simply 8 bit image surfaces. The map itself is a layer, but additional layers can be created as temporary buffers using the CreateLayer or Duplicate script functions. Additional layers are bound to the map they were created from and destroyed alongside with it when map drawing is complete.
In C4Script, map layers are represented as prop lists. They have the implicit properties Wdt and Hgt, which contain the width and height of the surface respectively. To resize a map or layer, use the Resize() function. Do not modify Wdt or Hgt directly.
For example, the following code:
var layer = CreateLayer("Earth"); layer->DrawCoal(); Blit(layer, [0,0,layer.Wdt/2,layer.Hgt]);
would create a secondary layer filled with earth. It would then draw coal onto the layer and finally copy only the left half of its contents to the main map.
Algorithms
Algorithms are the core concept of dynamic map creation to point drawing operations to specific subregions of the map only. An algorithm is a function that maps a position (int x, int y) to either a pixel color (int) or a mask value (bool).
Algorithms are defined as prop list with the Algo property set to one of the MAPALGO_* constants and additional algorithm parameters set as properties. They can then be passed to one of the drawing functions (Draw or Blit), which will evaluate the algorithm at all positions and draw pixel values accordingly.
For example, the following code would draw rectangles of earth in a checkerboard pattern:
Draw("Earth", {Algo=MAPALGO_RndChecker, Wdt=5, Hgt=5});
In addition to pattern-generating algorithms, there are also modifier algorithms that take other algorithms as parameters. For example, the Turbulence algorithm jumbles all pixels of the underlying algorithm around to create a noisy pattern:
var checkerboard = {Algo=MAPALGO_RndChecker, Wdt=10, Hgt=10}; var jumbled_checkerboard = {Algo=MAPALGO_Turbulence, Amplitude=10, Scale=10}; Draw("Earth", jumbled_checkerboard);
Modifier algorithms can also be applied to layer contents directly. For example, to flip the contents of the current map, one could write:
// Backup contents of current map var copy_layer = Duplicate(); // Redraw flipped horizontally Blit({Algo=MAPALGO_Scale, OffX=Wdt/2, X=-100, Op=copy_layer});
Note: If you are using the target layer in a drawing command, always draw from a copy. Otherwise, the result is undefined.
SCRIPTALGO_Layer
Returns the pixel value at the x,y position of the given layer. Instead of passing a SCRIPTALGO_Layer prop list, layers can also be passed directly as algorithms.

Parameter
Default
Meaning
Layer
The layer from which pixel values are taken.

SCRIPTALGO_RndChecker
Returns values from a checkerboard pattern of rectangles that are filled with ones or zeros.

Parameter
Default
Meaning
Seed
Random(65536)
If nonzero, the checkerboard pattern is generated from a fixed seed.
Ratio
50
Percentage of checkerboard fields that are one.
Wdt
10
Width of rectangles.
Hgt
10
Height of rectangles
FixedOffset
false
If true, the pattern always starts at position (0,0). Otherwise, it is offset by a random phase.

SCRIPTALGO_Rect
Returns one if the position is in a given rectangle and zero otherwise.

Parameter
Default
Meaning
X
0
Left side of rectangle (pixel is included).
Y
0
Top side of rectangle (pixel is included).
Wdt
0
Width of rectangle.
Hgt
0
Height of rectangle.

SCRIPTALGO_Ellipsis
Returns one if the position is in a given ellipsis and zero otherwise.

Parameter
Default
Meaning
X
0
Horizontal center of ellipsis.
Y
0
Vertical center of ellipsis.
Wdt
10
Horizontal radius of ellipsis.
Hgt
10
Vertical radius of ellipsis

SCRIPTALGO_Polygon
Returns one if the position is in a given polygon or on its border and zero otherwise.

Parameter
Default
Meaning
X
Array of x coordinates of polygon points.
Y
Array of y coordinates of polygon points.
Wdt
1
Width of border lines of polygon.
Empty
false
If true, the polygon is not filled and only the border is drawn.
Open
false
If true, the last segment of the polygon is not drawn. Useful to draw lines. Only valid if Empty is true.

SCRIPTALGO_And
Returns zero if any of the operands is zero. Otherwise, returns the value of the last operand. If there are zero operands, always returns zero.

Parameter
Default
Meaning
Op
Array of algorithms that are tested.

SCRIPTALGO_Or
Returns the first operand that is nonzero. If all operands are zero, returns zero. If there are zero operands, always returns zero.

Parameter
Default
Meaning
Op
Array of algorithms that are tested.

SCRIPTALGO_Not
Returns one if the operand is zero. Returns zero otherwise.

Parameter
Default
Meaning
Op
Algorithms that is negated.

SCRIPTALGO_Xor
If exactly one of the two operands is nonzero, returns that operand. Otherwise, returns zero.

Parameter
Default
Meaning
Op
Array of two algorithms that are tested.

SCRIPTALGO_Offset
Moves its operand by an offset.

Parameter
Default
Meaning
Op
Algorithms that is being manipulated.
OffX
0
Horizontal offset to the right.
OffY
Vertical offset downwards.

SCRIPTALGO_Scale
Scales its operand by a point.

Parameter
Default
Meaning
Op
Algorithms that is being manipulated.
X
100
Horizontal scaling in percent. Values smaller than zero flip the operand horizontally.
Y
100
Vertical scaling in percent. Values smaller than zero flip the operand vertically.
OffX
0
X position of fixed point that remains in position.
OffY
0
Y position of fixed point that remains in position.

SCRIPTALGO_Rotate
Rotates its operand around a point.

Parameter
Default
Meaning
Op
Algorithms that is being manipulated.
R
0
Rotation angle in degrees (0 to 360). Positive values rotate counter-clockwise.
OffX
0
X position of fixed point that remains in position.
OffY
0
Y position of fixed point that remains in position.

SCRIPTALGO_Turbulence
Jumbles its operand around by moving points by a randomized offset.

Parameter
Default
Meaning
Seed
Random(65536)
If nonzero, the offset map is generated from a fixed seed.
Amplitude
10
Maximum range by which pixels may be moved in a single step. Movement in any direction is half of the amplitude. Can be an single integer for equal movement in both dimensions or an array of two integers for separate amplitudes for horizontal and vertical movement.
Scale
10
Distance of points for which the amplitude is randomized. A large scale relative to the amplitude creates more broadly scaled, regular turbulence, while a small scale can cause borders to look more jumpey. Can be an single integer for equal scale in both dimensions or an array of two integers for separate scales horizontally and vertically.
Iterations
2
Number of times each point is pushed around. The amplitude of the n'th successive push is reduced by 1/n.

SCRIPTALGO_Border
Returns true for positions that lie on an inner or outer border of an operand. An inner border is defined as a position where the operand is nonzero and a position where it is zero lies within inner border width range. An outer border is defined as a position where the operand is zero and a position where it is nonzero lies within outer border width range. Note that borders are only searched in four directions (left, right, upwards, downwards) and not diagonally. This means that for a square, outer borders to not catch the corners.

Parameter
Default
Meaning
Op
Algorithm of which the border is to be determined.
Wdt
1
Border width in all directions. Positive integer for inner border; negative integer for outer border. Can also be an array of two integers of opposing signs for inner and outer borders.
Left
Border width to the left side. Definition like Wdt. Falls back to Wdt if not specified.
Top
Border width upwards. Definition like Wdt. Falls back to Wdt if not specified.
Right
Border width to the right side. Definition like Wdt. Falls back to Wdt if not specified.
Bottom
Border width downwards. Definition like Wdt. Falls back to Wdt if not specified.

SCRIPTALGO_Filter
Return only pixel values of the operand that match the mask specification. Returns zero for other pixels.

Parameter
Default
Meaning
Op
Operand algorithm that is being filtered.
Filter
Mask specification (see section "Material-texture masks" below)

Script function parameters
Map drawing functions follow a common syntax for passing certain structures: Rectangles (array rect) All rectangles are given in the format `[left, top, width, height]`, where the left and top pixel rows are included and left+width and top+height pixel rows are excluded. Unless otherwise specified, rect can always be nil, in which case the area defaults to the whole map or layer (`[0,0,this.Wdt,this.Hgt]`). Material-texture definitions (string mattex) When a material is specified for the drawing functions, the following definitions are valid:

String
Example
Meaning
Material
Earth
Draws the given material in its default texture as underground (tunnel background) material.
Material-Texture
Earth-earth_topSoil
Draws the given material with the given texture as underground material.
^Material
^Water
Draws the given material with its default texture as overground (sky background) material.
^Material-Texture
^Earth-earth_rough
Draws the given material with the given texture as overground material.
Sky
Sky
Draws a sky material. Within the map generator, explicit sky is drawn as IFT (0x80), which is converted to index zero on map drawing. That way, sky can be blitted to other layers without being transparent.
Transparent
Transparent
Draws with index 0.

Material-texture masks (string mask_spec)
When a material is specified as a masking function, the following definitions are valid:

String
Example
Meaning
Material
Earth
True for given material with any texture and any (sky or tunnel) background.
Material-Texture
Earth-earth_topSoil
True for the given material with the given texture and any (sky or tunnel) background.
Sky
Sky
True for explicit sky material (0x80) only. Not true for transaprent (0) pixels.
Transparent
Transparent
True for transparent pixels (index 0) only.
Background
Background
True for all background materials (e.g. Tunnel, BrickBack and Sky).
Liquid
Liquid
True for all liquids (e.g. Water, Acid, Lava and DuroLava).
Solid
Solid
True for solid materials (e.g. Earth, Rock, Brick, etc.).
*
*
True for all materials.
^Definition
^Rock-rock_cracked
True for the definition if overground (sky background) only.
&Definition
&Liquid
True for the definition if underground (tunnel background) only. The example would match all underground liquids.
~Definition
~^*
Inverts the definition, i.e. true only if the definition would originally be false. The example would match all underground materials.

Script functions
All drawing functions are defined in the MapLayer static prop list. Because the Map.c script file is also evaluated in this context with the current map as this pointer, all drawing functions can be called directly by name in that script (e.g.: Resize(150,150)). In other script contexts or if the function is to be executed on a layer instead of on the main map, the base object must be given explicitely (e.g.: map->Resize(150,150), where map is the parameter passed to InitializeMap).
Because layers derive from the MapLayer prop list, all script functions defined in the Map.c and included script files are also available on any layer.
Internal engine functions
bool Draw(string mattex, proplist mask_algo, array rect);
Draws the material given by mattex on all pixels within rect if the algorithm given by mask_algo returns a value other than zero. Returns true on success.
bool Blit(proplist mask_algo, array rect);
Same as draw, but draws the result of evaluation of mask_algo directly instead of a material given by mattex. Because mask_algo can also be a layer, this function can be used to copy layer contents onto other layers or the map. If mask_algo evaluates to zero, nothing is drawn and the original pixel value is kept.
proplist CreateLayer(string mattex_fill, int width, int height);
Creates a new layer of size width,height. If no size is given, the layer is created in the same size as the calling context layer or map. The new layer is filled with the pixel color given by mattex_fill, or with zeroes if mattex_fill is nil. Returns the newly created layer.
bool Resize(int new_width, int new_height);
Recreates the calling layer or map surface in the given size. All contents are deleted and the layer is filled with zeroes. Use functions Duplicate and Blit to backup and restore any old layer contents if you want to extent the map without losing its contents. Returns true on success.
proplist Duplicate(any mask_spec, array rect);
Creates a new layer with the same size and surface contents as this layer. If a rect is given, the new layer is smaller and contains only the portion included in rect. If mask_spec is given, only pixels passing the mask are set and all other pixels in the new layer are zero.
int GetPixel(int x, int y);
Gets the pixel color at the given position in this layer. If x,y is outside the layer, zero is returned.
bool SetPixel(int x, int y, int new_color);
Sets the pixel at position x,y in this layer to new_color. Returns true on success.
int GetPixelCount(any mask_spec, array rect);
Returns number of pixels on this layer or map within rect that fulfill mask_spec.
bool FindPosition(proplist out_pos, mask_spec, array rect, int max_tries);
Tries to find a position on this layer for which the pixel color matches mask_spec. If a position is found, true is returned and the position is set as X and Y parameters in the out_pos prop list. If no position is found after max_tries, the function will walk through all pixels of the layer starting from a random starting position to find a point. If still no position is found, false is returned and out_pos is not changed. max_tries defaults to 500.
array CreateMatTexMask(any mask_spec);
Returns mask_spec as an array of 256 bools to be used e.g. in conjunction with the return value of GetPixel.
Sven2
2013-03