Terrain tables
GAME.C defines twelve base terrains and twelve corresponding special
resource records. Each record is 19 bytes. The special record supplies a
replacement yield, rather than a bonus to add to the base terrain.
struct terrain_type {
char name[12];
unsigned char move_cost;
signed char defense; /* defense multiplier, in halves */
unsigned char food, shields, trade, f5, f6;
};
struct terrain_rec terrains[24] = {
{ "Desert", 1, 2, 0, 1, 0, 1, 14 },
{ "Plains", 1, 2, 1, 1, 0, 1, 6 },
{ "Grassland", 1, 2, 2, 1, 0, 1, 10 },
{ "Forest", 2, 3, 1, 2, 0, 2, 2 },
{ "Hills", 2, 4, 1, 0, 0, 2, 12 },
{ "Mountains", 3, 6, 0, 1, 0, 3, 13 },
{ "Tundra", 1, 2, 1, 0, 0, 0, 7 },
{ "Arctic", 2, 2, 0, 0, 0, 0, 15 },
{ "Swamp", 2, 3, 1, 0, 0, 0, 3 },
{ "Jungle", 2, 3, 1, 0, 0, 0, 11 },
{ "Ocean", 1, 2, 1, 0, 2, 0, 1 },
{ "River", 1, 3, 2, 1, 1, 2, 9 },
{ "Oasis", 1, 2, 3, 1, 0, 1, 14 },
{ "Horses", 1, 2, 1, 3, 0, 1, 6 },
{ "Grassland", 1, 2, 2, 1, 0, 1, 10 },
{ "Game", 2, 3, 3, 2, 0, 2, 2 },
{ "Coal", 2, 4, 1, 2, 0, 2, 12 },
{ "Gold", 3, 6, 0, 1, 6, 3, 13 },
{ "Game", 1, 2, 3, 0, 0, 0, 7 },
{ "Seals", 2, 2, 2, 0, 0, 0, 15 },
{ "Oil", 2, 3, 1, 4, 0, 0, 3 },
{ "Gems", 2, 3, 1, 0, 4, 0, 11 },
{ "Fish", 1, 2, 3, 0, 2, 0, 1 },
{ "River", 1, 3, 2, 1, 1, 2, 9 },
};
The fields after the name are movement cost, defence in halves, food, shields, trade, and two further bytes. A defence value of 2 means the normal factor; 3 means one and a half, 4 means double and 6 means triple. Ships and aircraft have separate combat rules; see Combat.
Special resources
patterned_cell() in MAP.C derives resource positions from coordinates
and map_rng_state. It selects one position per four-by-four block, except
on the two rows nearest each pole. The terrain at that position determines
which special record is used: Desert gives Oasis, Hills Coal, Mountains
Gold, Ocean Fish, and so on.
Grassland and River shields also depend on (7 * x + 11 * y) & 2 in
tile_yield(). The base table alone therefore does not describe every tile.