Map Display UI Control
The key items for using a control are:
The Height Map
This is a 32 bit TGA texture. The blue channel is used for the height information, for ease of use it is recommended that the heightmap be greyscale. The default name for this should be HEIGHT.TGA and it should live in the DATA/UI/TEXTURES folder (generally this will be in the local campaign folder).
The Map Image
This image is used to texture the map, and can be any valid image format. The default name is MAP.TGA (or DDS, etc). It should be in the DATA/UI/TEXTURES folder also. Note that these texture names are customisable if needed using the scenario file (see below).
This file works in the same way as MAPVIEW.TXT does for in-battle views. It also lives in DATA (either in the main or local path).
Additionally, basic lighting can be specified in CAMPAIGNVIEW.TXT by adding a WORLDLIGHT chunk, ex:
[WORLDLIGHT] DIRECTION 1, -1, 1 COLOUR 0.95 0.95 0.95 AMBIENT 0.35 0.35 0.35
Using a Map Display
Once you have a heightmap and a map image, you can see the map ingame. Add the control to a UI txt file as normal - the below example could be the base for a custom campaign screen:
[CAMPAIGNDISPLAY] level 4 type mapdisplay file MAP.DAT x 0 y 0 width 1024 height 768 script CAMPAIGN.BSF handler QUESTHANDLER
Note the file MAP.DAT entry. This is placeholder for data we will generate later, The control will load the default files when this is missing.
To add borders you can either enter them by hand (not recommended!), or edit them ingame using the control itself. To do this you must be in debug mode and then hit CTRL+E. You will see the control provide feedback that you are in the editor state. The editor has two modes, Border and Region. In Border mode you can edit, drag, remove, etc points which make up the borders of each territory. Use the LMB to add a point, and the RMB to stop editing the current territory ready to begin a new one (or edit an old one). The backspace key deletes points. To save your progress use CTRL+S (currently this will save to DATA/UI/MAP.DAT in the current campaign. The ability to choose the file to save is TBD).
The I key toggles between Border mode and Region mode, where the territory borders can be viewed as they appear ingame.
Once you have saved a MAP.DAT file (which is a text file) you can tweak it should you desire, allowing you to use alternate textures for height and display, and also to change the height scaling of the map, as well as the scaling of its axes, and tweaking the height of the borders above the terrain.
The simplest way to attach data to your map is using the LoadVariableFromParserFile command, loading data into your own variable which matches with the respective area (territory) you have defined.
The behaviour of the control is all done via a custom script, called MAP.BSF. This should be in the DATA/SCRIPTS folder (either global or local). The key functions in the script are:
This is called at initialisation time for the map.
Called each UI update, includes the UI tick value. Note that this means that the function may be called more than 30 times per second, but that the tick value will change only every 30th of a second.
Called to allow custom rendering after all the map and entity rendering has happened.
The functions allow for control over how areas are coloured, highlighted, etc. It also allows for UI control (e.g. selection of 3D entities on the map, drag and drop, etc). The key functions are:
//returns the region that the mouse is currently over, -2 if not over the control, -1 if not over a valid area. If all is nonzero, then the first work array has elements 0,1 as the xy map coords (1000ths), and 2,3 set to the selected entity type and id (or -1), 4,5 L/R mouse buttons. MapViewGetMouse(objectName, [all]) //set the colour used to render an area MapViewSetAreaColour(objectName, areaIndex, colourString) //return the number of areas defined on the map MapViewGetAreaCount(objectName) //returns the xy position of the center of an area, packed with x in the bottom 16 bits, y in the top. If precise<>0 then 0,1, in the first work array is set to the precise values of the center, in 1000ths MapViewGetAreaCenter(objectName, areaIndex, [precise]) //create an entity on the map, it is subsequently accessed via its type and id as provided MapViewAddEntity(objectName, filename, entityType, entityID) //remove an entity from the map MapViewRemoveEntity(objectName, entityType, entityID) //set the position on the map, in 1000ths, of the entity MapViewSetEntityPosition(objectName, entityType, entityID, x, y) //set the colour of the entity, set to zero to use default lighting colour MapViewSetEntityColour(objectName, entityType, entityID, colourString) //set the scale, in 1000ths, of the entity MapViewSetEntityScale(objectName, entityType, entityID, scale) //set the rotational angle, in 1000ths, of the entity MapViewSetEntityAngle(objectName, entityType, entityID, angle)