Updated: October 11th 2003

This is a description of how the mapping scale and placement works for a battle. At the end is a link to a program that uses these equations and will automatically make an annotated map of any objects you want to see.

First, unpack a map and go to the bf1942\levels\somebattlename directory for the battle. We'll use the bf1942\levels\Anzio files as an example.

First, in Init\Terrain.con is the line:


  GeometryTemplate.WorldSize 2048

The number is the scale of the world, how many meters wide and high it is. However, this number can be overridden by a token in Init.con:


  Game.SetActiveCombatArea 512 768 1280 1280

The last two numbers are the X and Z scales (which are always the same, since all maps are square). So now the scale is 1280. The first two numbers are also important, they are the offsets for X and Z. X and Z are the overhead map's axes, X goes to the right and Z goes up from the lower left corner of the map. (I use X and Z here, since the position of objects is in X/Y/Z)

So let's say you want to know where an object is on the map. In the various .con files such as StaticObjects.con, conquest\ControlPoints.con, conquest\ObjectSpawns.con, and conquest\SoldierSpawns.con there is data like this:


  Object.Create ALLIES_BASE
  Object.AbsolutePosition 1096.07/32.5711/1156.19

(from conquest\ControlPoints.con). The absolute position is in terms of the offsets and scales already given. The first number is the X coordinate, the second is the altitude of the object, and the third the Z coordinate. Here's how to compute the map location of the object:


  map_x = (Object_x - offset_x) / scale
  map_z = (Object_z - offset_z) / scale

So, with the numbers we have so far:


  map_x = (1096.07 - 512) / 1280 = 0.4563
  map_z = (1156.19 - 768) / 1280 = 0.3033

On an edge scale of 0 to 1, go 0.4563 to the right and 0.3033 up from the lower left corner and you are at one of the Allied control points. To convert to map grid coordinates (which are from the upper left corner), you would do this:


  coord_x = letter "A" + integer(map_x * 8)
  coord_z = 8 - integer(map_z * 8)

for example:


  coord_x = letter "A" + integer(0.4563 * 8) = "A" + 3 = "D"
  coord_z = 8 - integer(0.3033 * 8) = 8 - 2 = 6

So this base is at D6, which is indeed the case, and can be confirmed on the map at the end of this page.

Perl Makemap Program

The Perl program makemap.zip uses this conversion process to create annotated maps of any battle in Battlefield 1942 or total mod (currently "Desert Combat" and "Eve of Destruction" are supported, but the program is easy to extend). What this program does is to read in object data and minimap from a level and create an overhead map at a user-specified resolution, annotated with icons as desired. Spawn points, flags, repair pads, ammo boxes, and other data can be displayed. The program also dumps the coordinates of all objects found in the scanned files.

As an example, the Secret Weapons maps at the PlanetBattlefield Intel site were made with this program. The output map is in .PPM format, which can be read by the free Irfanview image viewer, among others. I recommend converting this output PPM file to 24-bit color PNG, as GIF has too few colors and the icons will often change horribly, while JPEG will blur the icons.

You can run the program by doing the following:

You're ready to run the perl script. Type:
    perl c:\perlprogs\makemap.pl > mapdata.txt
The map is put in Anzio.ppm, which you can then view and convert with Irfanview or another image viewer. The mapdata.txt file contains the placement of all objects in the level (even if not visible). By default, the makemap.pl program makes a 512x512 map with important objects shown. For a higher resolution version of the map that also includes soldier spawn points, repair pads, and airfield resupply points, do:
    perl c:\perlprogs\makemap_full.pl
The data will stream by instead of getting stored in a file. At the end, Anzio2.ppm is created. Note that this is a different map name; the "2" comes from what the "$mapscale" variable is set to inside the program, if not equal to "1". Other than the options and comments changed at the tops of the files, makemap.pl and makemap_full.pl are identical code.

By default, the program searches the Conquest directory for the object spawn files, and also includes any Objective Mode objectives. You can map other types of battles, by setting "$battletype" to "objectivemode" or "singleplayer" or other battle type; see the top of the program for more options.

If icons overlap, they will be normally be shifted in a reasonable manner so that their overlap is minimized and they are all readable (actually, soldier spawn icons are ignored in this process, since they are so numerous and relatively unimportant). This option can be turned off, and icons can be made semi-transparent so that it is clearer when two icons overlap. There are a number of other options available, such as the output map size, icon transparency, etc.; again, read the documentation at the top of the program. It is also fairly straightforward to edit the program to scan for other types of objects (say, all the trees) and display their locations, and to add new icons.

That said, this program can be fooled. It keys off of the various *Templates.con files' "create" names for weapon spawn points, control points, etc. If the designer uses non-standard names for these points, the program may ignore or miscategorize these. For example, on the Telemark map's ObjectSpawnTemplates.con file it says:

  ObjectTemplate.create ObjectSpawner heavytankspawner
  ObjectTemplate.setObjectTemplate 2 sherman
  ObjectTemplate.setObjectTemplate 1 panzeriv
However, Shermans and Panzer IV's are not normally called heavy tanks on all other maps, they're called light or medium tanks. Because of this different naming scheme, heavy tank icons would incorrectly be shown on this map. My solution is to simply make a special version of makemap.pl and edit it to treat heavy tanks as being medium tanks. This is trivial, it involves changing the lines:
    } elsif ( $showland && $fld[1] =~ /heavytankspawner/i ) {
        &DRAWICON( $subfld[1], $subfld[2], %hvytankicon);
    } elsif ( $showland && $fld[1] =~ /heavytankspawner/i ) {
        &DRAWICON( $subfld[1], $subfld[2], %medtankicon);
i.e. the icon drawn is changed.

The minimap file reader in this program is fairly elaborate, reading in a fair assortment of DDS format files. If you get incorrect results for the output map, such as strange colors or bands, it is likely that the minimap (textures\ingamemap.dds) is in a DDS format that is not supported.

Here is a sample custom map, of Anzio, with all objects shown and with shifting done so all icons are visible.