Tutorial: Map Generator - Special Features

This is the fourth part of the map generator tutorial. The previous part can be found here, but only part one and two are prerequisites for this tutorials. This tutorial discusses some features of the map generator that do not fit into distinct categories.

Template overlays

[TODO: Describe how to use overlays as templates.]

Polygon algorithm

[TODO: Describe the polygon algorithm]

Algorithms In C4Script

A golden ellipse with rock border.

A first look at the landscape on the right might make you wonder, how is this created? A quick look into the list of algorithms will convince you that there is no ellipse neither a circle that can be transformed into an ellipse. The trick here is that you can define your own algorithms in C4Script, by using the script algorithm. Producing decent algorithms might need some mathematical skills as we will see in this example. Leaving the rock border aside for now, we'll focus on the algorithm to create an ellipse first. From the documentation we find that the algorithm must be defined in the scenario script, where the following function is called.

func ScriptAlgo[Overlay-Name](int x, int y, int a, int b)

In this function x and y are the pixel coordinates for which the function is called and a, b are the usual parameters. The function should return true if a pixel is to be drawn and false if not. So for our map of MapWidth = MapHeight = 100, x and y range from 0 to 10000. First we scale x and y to normal coordinates and shift them to the middle of the map.Then let a represent the major axis of an ellipse and b the minor axis, see wikipedia. Using the canonical form to describe an ellipse we can create the needed ellipse algorithm, it is:

// Constructs an ellipse with major axis a and minor axis b in percent of the overlay.
func ScriptAlgoEllipse(int x, int y, int a, int b)
{
	// Transform x and y to represent middle of overlay.
	x = x / 100 - 50;
	y = y / 100 - 50;
	// Reduce a and b to represent semi-axes.
	a /= 2;
	b /= 2;
	// Draw all points inside the ellipse with major axis a and minor axis b.
	// This is just the canonical form x^2/a^2 + y^2/b^2 = 1 modified a little.
	if (b**2 * x**2 + a**2 * y**2 < a**2 * b**2)
		return true;
	return false;
}

To use it we need to name our overlay Ellipse. The following piece of map generator code will create the landscape in the figure.

// A golden ellipse with a rock border.
map ExerciseScriptBorder {
	mat=Water; tex=water;
	// This will call ScriptAlgoEllipse in the scenario script.
	overlay Ellipse {
		algo=script; a=80; b=40;
		mat=Gold; tex=gold;
		// Use the border algorithm to create a rock border.
		overlay {
			algo=border; a=5; b=5;
			mat=Rock; tex=rock;
		};
	};
};

To create the rock border we need another special algorithm, which is the border algorithm. This draws an inner border in the parent layer, a and b respectively specify the horizontal and vertical width of the border. This completes the example, as a little exercise you can try to draw a circle half out of gold and half out of rock.

Multiple Maps

[TODO: explain DrawDefMap and KeepMapCreator and rndall algorithm, for loading multiple and/or random maps]

map Map1 {
	mat=Gold; tex=gold;
};

map Map2 {
	mat=Earth; tex=earth;
};

map Map3 {
	mat=Rock; tex=rock;
};
protected func Initialize()
{
	var random = 1 + Random(3);
	// Draw one of the three random maps defined in the map generator code.
	DrawDefMap(0, 0, LandscapeWidth(), LandscapeHeight(), Format("Map%d", random));
	return; 
}

Exercise

Summary

By completing this tutorial you know all features of the map generator. The only thing left is to create good looking, dynamic and playable maps. Therefore the last part of this tutorial contains some examples about actual playable landscapes.