5 | | The following source files make up !RmGen (each .cpp file has an associated .h): |
6 | | * '''stdafx.h''': Precompiled header. |
7 | | * '''rmgen.cpp''': Program entry point. Sets up !JavaScript engine then executes a file. The rmgen.h header exposes the JS engine objects and some utility functions. |
8 | | * '''random.cpp''': Random map generator (currently using Boost::Random's Mersenne Twister) |
9 | | * '''point.cpp''': 2D point structure with integer coordinates. |
10 | | * '''api.cpp''': C++ functions available directly to !JavaScripts. |
11 | | * '''objparse.cpp''': Utility functions for converting complex !JavaScript objects to their C++ counterparts (area placers, area painters, constraints, etc are all represented by classes in both JS and C++; this file converts a jsval to various types of C++ objects). |
12 | | * '''rmlibrary.js''': !JavaScript part of the library; implements the complex objects such as area placers, area painters and constraints, as well as utility functions, and will eventually hold the high-level JS API. (Note: This file is located in binaries/mods/official/data/maps). |
13 | | * '''output.cpp''': Functions for outputting the map to PMP/XML |
14 | | * '''map.cpp''': The map class, providing functions to access texture/elevation data, add entities and place areas. |
15 | | * '''entity.cpp''': Entity class |
16 | | * '''terrain.cpp''': Terrain painter interface and some implementations (!SimpleTerrain, !RandomTerrain). By terrain here I mean a "logical terrain", which is not just a texture but also objects associated with each tile (for example, forest is a logical terrain). The Terrain interface only requires one method that paints a single tile, so a terrain object can actually paint different tiles with different textures/objects (as long as it does each one independently of the others) - see !RandomTerrain for example. |
17 | | * '''area.cpp''': Area class, which consists of just a numerical ID and a list of points for now. |
18 | | * '''constraint.cpp''': Constraint interface, which can either allow or disallow placement on a tile. |
19 | | * '''areaplacer.cpp''': !AreaPlacer interface, which selects a set of points to place an area on or returns failure given a constraint. |
20 | | * '''areapainter.cpp''': !AreaPainter interface, which performs an action on a given Area. |
21 | | * '''simplepainters.cpp''': Simple area painters (such as !TerrainPainter). |
22 | | * '''simpleconstraints.cpp''': Simple constraints (such as !NullConstraint, simple avoid constraints and AND/OR constraints). |
23 | | * '''smoothelevationpainter.cpp''': !SmoothElevationPainter class: raises/lowers an area to a specific elevation or by a specific delta, with smoothing around the edges. |
24 | | * '''clumpplacer.cpp''': !ClumpPlacer class: places a clump with given size, coherence, smoothness and center point. |
25 | | * '''layeredpainter.cpp''': !LayeredPainter class: paints an area in "layers" of different terrains depending on each point's distance from the edge (for example, a dirt patch can have grass-dirt-50 on the outside and dirt on the inside to blend smoothly on grass terrain). |
| 5 | When loading a scenario, the CMapReader class simply reads an XML file (with map settings, list of entities, and other textual data) together with a binary file called a PMP (which specifies height map and terrain textures). For a random map, there is obviously no predefined map to read. Instead, the engine uses a new CMapGenerator class. The CMapGenerator needs the name of a random map script and some settings, such as number of players and their civs. These are selected during game setup. |
| 6 | |
| 7 | The CMapGenerator provides a few things for the random map scripts. One is a global variable `g_MapSettings` which specifies all the map settings, these are provided by game setup. CMapGenerator also exposes two JavaScript functions: `RMS.LoadLibrary(name)` and `RMS.ExportMap(data)`. `LoadLibrary` is used for choosing the API to which a random map script will have access. `ExportMap` is used to return generated map data from the scripts to the engine. |
| 8 | |
| 9 | The data from a random map script must be in an exact format, which can be specified in JSON as follows: |
| 10 | {{{ |
| 11 | { |
| 12 | "size": 128, |
| 13 | "height": [ 1000, ... ] |
| 14 | "seaLevel": 20.0, |
| 15 | "textureNames": [ "medit_grass_field_a", ... ] |
| 16 | "tileData": [ { "texIdx1" : 0x0001, "texIdx2" : 0xFFFF, "priority" : 0 }, ... ] |
| 17 | "entities": [ { "id" : 100, "name" : "units/hele_support_female_citizen", "x" : 102.4, "y" : 64.8, "angle" : 0.86, "isActor" : false}, ... ] |
| 18 | } |
| 19 | }}} |
| 20 | |
| 21 | * `size`: Integer. This is the size of the map in tiles (integer). |
| 22 | * `height`: Flat array of 16-bit unsigned integers. This is the height data for each tile of the map. |
| 23 | * `seaLevel`: Float. This is the height of the sea, the value in the heightmap for which all lower terrain will be under water. |
| 24 | * `textureNames`: Flat array of strings. This is the terrain textures used. They must be in the order in which they were defined (as they are referenced by tile data). |
| 25 | * `tileData`: Flat array of tile descriptors. Tile descriptors reference the terrain textures for a given tile and an optional priority for blending. The array must be arranged in patches, there are 16 tiles per patch. |
| 26 | * `entities`: Flat array of entities. |
| 27 | |
| 28 | CMapReader is responsible for parsing this data and creating the map, in a process very similar to that for scenarios. |