Freeciv21
Develop your civilization from humble roots to a global empire
temperature_map.cpp
Go to the documentation of this file.
1 /*
2 _ ._ Copyright (c) 1996-2021 Freeciv21 and Freeciv contributors.
3  \ | This file is part of Freeciv21. Freeciv21 is free software: you
4  \_| can redistribute it and/or modify it under the terms of the
5  .' '. GNU General Public License as published by the Free
6  :O O: Software Foundation, either version 3 of the License,
7  '/ \' or (at your option) any later version. You should have
8  :X: received a copy of the GNU General Public License along with
9  :X: Freeciv21. If not, see https://www.gnu.org/licenses/.
10  */
11 
12 // utilities
13 #include "log.h"
14 
15 // common
16 #include "map.h"
17 
18 // generator
19 #include "height_map.h"
20 #include "mapgen_topology.h"
21 #include "mapgen_utils.h"
22 
23 #include "temperature_map.h"
24 
25 static int *temperature_map;
26 
27 #define tmap(_tile) (temperature_map[tile_index(_tile)])
28 
32 #ifdef FREECIV_DEBUG
33 static char *tmap_y2str(int ycoor)
34 {
35  static char buf[MAP_MAX_LINEAR_SIZE + 1];
36  char *p = buf;
37  int i, idx;
38 
39  for (i = 0; i < wld.map.xsize; i++) {
40  idx = ycoor * wld.map.xsize + i;
41 
42  if (idx > wld.map.xsize * wld.map.ysize) {
43  break;
44  }
45 
46  switch (temperature_map[idx]) {
47  case TT_TROPICAL:
48  *p++ = 't'; // tropical
49  break;
50  case TT_TEMPERATE:
51  *p++ = 'm'; // medium
52  break;
53  case TT_COLD:
54  *p++ = 'c'; // cold
55  break;
56  case TT_FROZEN:
57  *p++ = 'f'; // frozen
58  break;
59  }
60  }
61 
62  *p = '\0';
63 
64  return buf;
65 }
66 #endif // FREECIV_DEBUG
67 
71 bool temperature_is_initialized() { return temperature_map != nullptr; }
72 
76 bool tmap_is(const struct tile *ptile, temperature_type tt)
77 {
78  return BOOL_VAL(tmap(ptile) & (tt));
79 }
80 
84 bool is_temperature_type_near(const struct tile *ptile, temperature_type tt)
85 {
86  adjc_iterate(&(wld.map), ptile, tile1)
87  {
88  if (BOOL_VAL(tmap(tile1) & (tt))) {
89  return true;
90  };
91  }
93 
94  return false;
95 }
96 
101 {
102  fc_assert_ret(nullptr != temperature_map);
103  delete[] temperature_map;
104  temperature_map = nullptr;
105 }
106 
112 void create_tmap(bool real)
113 {
114  int i;
115 
116  // if map is defined this is not changed
117  // TODO: load if from scenario game with tmap
118  // to debug, never load a this time
119  fc_assert_ret(nullptr == temperature_map);
120 
121  temperature_map = new int[MAP_INDEX_SIZE];
122  whole_map_iterate(&(wld.map), ptile)
123  {
124  // the base temperature is equal to base map_colatitude
125  int t = map_colatitude(ptile);
126 
127  if (!real) {
128  tmap(ptile) = t;
129  } else {
130  // high land can be 30% cooler
131  float height = -0.3 * MAX(0, hmap(ptile) - hmap_shore_level)
133  // near ocean temperature can be 15% more "temperate"
134  float temperate =
135  (0.15 * (wld.map.server.temperature / 100 - t / MAX_COLATITUDE) * 2
136  * MIN(50,
137  count_terrain_class_near_tile(ptile, false, true, TC_OCEAN))
138  / 100);
139 
140  tmap(ptile) = t * (1.0 + temperate) * (1.0 + height);
141  }
142  }
144  // adjust to get well sizes frequencies
145  /* Notice: if colatitude is loaded from a scenario never call adjust.
146  Scenario may have an odd colatitude distribution and adjust will
147  break it */
148  if (!wld.map.server.alltemperate) {
150  }
151  // now simplify to 4 base values
152  for (i = 0; i < MAP_INDEX_SIZE; i++) {
153  int t = temperature_map[i];
154 
155  if (t >= TROPICAL_LEVEL) {
157  } else if (t >= COLD_LEVEL) {
159  } else if (t >= 2 * ICE_BASE_LEVEL) {
161  } else {
163  }
164  }
165 
166  log_debug("%stemperature map ({f}rozen, {c}old, {m}edium, {t}ropical):",
167  real ? "real " : "");
168  for (i = 0; i < wld.map.ysize; i++) {
169  log_debug("%5d: %s", i, tmap_y2str(i));
170  }
171 }
int hmap_shore_level
Definition: height_map.cpp:24
struct world wld
Definition: game.cpp:48
#define hmap_max_level
Definition: height_map.h:30
#define hmap(_tile)
Definition: height_map.h:14
#define fc_assert_ret(condition)
Definition: log.h:112
#define log_debug(message,...)
Definition: log.h:65
#define MAP_MAX_LINEAR_SIZE
Definition: map.h:530
#define adjc_iterate_end
Definition: map.h:358
#define MAP_INDEX_SIZE
Definition: map.h:91
#define adjc_iterate(nmap, center_tile, itr_tile)
Definition: map.h:351
#define whole_map_iterate(_map, _tile)
Definition: map.h:473
#define whole_map_iterate_end
Definition: map.h:480
int map_colatitude(const struct tile *ptile)
Returns the colatitude of this map position.
#define COLD_LEVEL
#define ICE_BASE_LEVEL
#define TROPICAL_LEVEL
#define MAX_COLATITUDE
#define adjust_int_map(int_map, int_map_max)
Definition: mapgen_utils.h:101
#define MIN(x, y)
Definition: shared.h:49
#define BOOL_VAL(x)
Definition: shared.h:63
#define MAX(x, y)
Definition: shared.h:48
int xsize
Definition: map_types.h:73
int ysize
Definition: map_types.h:73
struct civ_map::@39::@41 server
Definition: tile.h:42
struct civ_map map
Definition: world_object.h:21
bool temperature_is_initialized()
Returns one line (given by the y coordinate) of the temperature map.
#define tmap(_tile)
bool tmap_is(const struct tile *ptile, temperature_type tt)
Return true if the tile has tt temperature type.
static int * temperature_map
void destroy_tmap()
Free the tmap.
bool is_temperature_type_near(const struct tile *ptile, temperature_type tt)
Return true if at least one tile has tt temperature type.
void create_tmap(bool real)
Initialize the temperature_map if arg is FALSE, create a dummy tmap == map_colatitude to be used if h...
int temperature_type
#define TT_COLD
#define TT_FROZEN
#define TT_TROPICAL
#define TT_TEMPERATE
int count_terrain_class_near_tile(const struct tile *ptile, bool cardinal_only, bool percentage, enum terrain_class tclass)
Return the number of adjacent tiles that have given terrain class (not including ptile itself).
Definition: terrain.cpp:517