Add scripting API control over unit 'stay'
[freeciv.git] / server / generator / temperature_map.c
blob4a307424f91f28c9e87d22abf76087dc7986c0d3
1 /***********************************************************************
2 Freeciv - Copyright (C) 2004 - Marcelo J. Burda
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
18 /* utilities */
19 #include "log.h"
21 /* common */
22 #include "map.h"
24 /* generator */
25 #include "height_map.h"
26 #include "mapgen_topology.h"
27 #include "mapgen_utils.h"
29 #include "temperature_map.h"
31 static int *temperature_map;
33 #define tmap(_tile) (temperature_map[tile_index(_tile)])
35 /**************************************************************************
36 Returns one line (given by the y coordinate) of the temperature map.
37 **************************************************************************/
38 #ifdef FREECIV_DEBUG
39 static char *tmap_y2str(int ycoor)
41 static char buf[MAP_MAX_LINEAR_SIZE + 1];
42 char *p = buf;
43 int i, idx;
45 for (i = 0; i < wld.map.xsize; i++) {
46 idx = ycoor * wld.map.xsize + i;
48 if (idx > wld.map.xsize * wld.map.ysize) {
49 break;
52 switch (temperature_map[idx]) {
53 case TT_TROPICAL:
54 *p++ = 't'; /* tropical */
55 break;
56 case TT_TEMPERATE:
57 *p++ = 'm'; /* medium */
58 break;
59 case TT_COLD:
60 *p++ = 'c'; /* cold */
61 break;
62 case TT_FROZEN:
63 *p++ = 'f'; /* frozen */
64 break;
68 *p = '\0';
70 return buf;
72 #endif /* FREECIV_DEBUG */
74 /**************************************************************
75 Return TRUE if temperateure_map is initialized
76 **************************************************************/
77 bool temperature_is_initialized(void)
79 return temperature_map != NULL;
81 /*********************************************************
82 return true if the tile has tt temperature type
83 **********************************************************/
84 bool tmap_is(const struct tile *ptile, temperature_type tt)
86 return BOOL_VAL(tmap(ptile) & (tt));
89 /*****************************************************************
90 return true if at least one tile has tt temperature type
91 ****************************************************************/
92 bool is_temperature_type_near(const struct tile *ptile, temperature_type tt)
94 adjc_iterate(&(wld.map), ptile, tile1) {
95 if (BOOL_VAL(tmap(tile1) & (tt))) {
96 return TRUE;
98 } adjc_iterate_end;
100 return FALSE;
103 /****************************************************************************
104 Free the tmap
105 ****************************************************************************/
106 void destroy_tmap(void)
108 fc_assert_ret(NULL != temperature_map);
109 free(temperature_map);
110 temperature_map = NULL;
113 /***************************************************************************
114 * Initialize the temperature_map
115 * if arg is FALSE, create a dummy tmap == map_colatitude
116 * to be used if hmap or oceans are not placed gen 2-4
117 ***************************************************************************/
118 void create_tmap(bool real)
120 int i;
122 /* if map is defined this is not changed */
123 /* TODO: load if from scenario game with tmap */
124 /* to debug, never load a this time */
125 fc_assert_ret(NULL == temperature_map);
127 temperature_map = fc_malloc(sizeof(*temperature_map) * MAP_INDEX_SIZE);
128 whole_map_iterate(&(wld.map), ptile) {
129 /* the base temperature is equal to base map_colatitude */
130 int t = map_colatitude(ptile);
132 if (!real) {
133 tmap(ptile) = t;
134 } else {
135 /* high land can be 30% cooler */
136 float height = - 0.3 * MAX(0, hmap(ptile) - hmap_shore_level)
137 / (hmap_max_level - hmap_shore_level);
138 /* near ocean temperature can be 15% more "temperate" */
139 float temperate = (0.15 * (wld.map.server.temperature / 100 - t
140 / MAX_COLATITUDE)
141 * 2 * MIN(50, count_terrain_class_near_tile(ptile,
142 FALSE,
143 TRUE,
144 TC_OCEAN))
145 / 100);
147 tmap(ptile) = t * (1.0 + temperate) * (1.0 + height);
149 } whole_map_iterate_end;
150 /* adjust to get well sizes frequencies */
151 /* Notice: if colatitude is loaded from a scenario never call adjust.
152 Scenario may have an odd colatitude distribution and adjust will
153 break it */
154 if (!wld.map.server.alltemperate) {
155 adjust_int_map(temperature_map, MAX_COLATITUDE);
157 /* now simplify to 4 base values */
158 for (i = 0; i < MAP_INDEX_SIZE; i++) {
159 int t = temperature_map[i];
161 if (t >= TROPICAL_LEVEL) {
162 temperature_map[i] = TT_TROPICAL;
163 } else if (t >= COLD_LEVEL) {
164 temperature_map[i] = TT_TEMPERATE;
165 } else if (t >= 2 * ICE_BASE_LEVEL) {
166 temperature_map[i] = TT_COLD;
167 } else {
168 temperature_map[i] = TT_FROZEN;
172 log_debug("%stemperature map ({f}rozen, {c}old, {m}edium, {t}ropical):",
173 real ? "real " : "");
174 for (i = 0; i < wld.map.ysize; i++) {
175 log_debug("%5d: %s", i, tmap_y2str(i));