Prettify long option values in /show output.
[freeciv.git] / common / traderoutes.c
blobbd9d733836759f6205a8bda46801a983613da2fe
1 /****************************************************************************
2 Freeciv - Copyright (C) 2004 - The Freeciv Team
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 /* utility */
19 #include "log.h"
21 /* common */
22 #include "city.h"
23 #include "effects.h"
24 #include "game.h"
25 #include "map.h"
26 #include "tile.h"
28 #include "traderoutes.h"
30 const char *trade_route_type_names[] = {
31 "National", "NationalIC", "IN", "INIC"
34 const char *traderoute_cancelling_type_names[] = {
35 "Active", "Inactive", "Cancel"
38 struct trade_route_settings trtss[TRT_LAST];
40 /*************************************************************************
41 Return current maximum number of trade routes city can have.
42 *************************************************************************/
43 int max_trade_routes(const struct city *pcity)
45 int eft = get_city_bonus(pcity, EFT_MAX_TRADE_ROUTES);
47 return CLIP(0, eft, MAX_TRADE_ROUTES);
50 /*************************************************************************
51 What is type of the traderoute between two cities.
52 *************************************************************************/
53 enum trade_route_type cities_trade_route_type(const struct city *pcity1,
54 const struct city *pcity2)
56 if (city_owner(pcity1) != city_owner(pcity2)) {
57 if (city_tile(pcity1)->continent != city_tile(pcity2)->continent) {
58 return TRT_IN_IC;
59 } else {
60 return TRT_IN;
62 } else {
63 if (city_tile(pcity1)->continent != city_tile(pcity2)->continent) {
64 return TRT_NATIONAL_IC;
65 } else {
66 return TRT_NATIONAL;
70 return TRT_LAST;
73 /*************************************************************************
74 Return percentage bonus for trade route type.
75 *************************************************************************/
76 int trade_route_type_trade_pct(enum trade_route_type type)
78 if (type < 0 || type >= TRT_LAST) {
79 return 0;
82 return trtss[type].trade_pct;
85 /*************************************************************************
86 Initialize trade route types.
87 *************************************************************************/
88 void trade_route_types_init(void)
90 enum trade_route_type type;
92 for (type = TRT_NATIONAL; type < TRT_LAST; type++) {
93 struct trade_route_settings *set = trade_route_settings_by_type(type);
95 set->trade_pct = 100;
99 /*************************************************************************
100 Return human readable name of trade route type
101 *************************************************************************/
102 const char *trade_route_type_name(enum trade_route_type type)
104 fc_assert_ret_val(type >= TRT_NATIONAL && type < TRT_LAST, NULL);
106 return trade_route_type_names[type];
109 /*************************************************************************
110 Get trade route type by name.
111 *************************************************************************/
112 enum trade_route_type trade_route_type_by_name(const char *name)
114 enum trade_route_type type;
116 for (type = TRT_NATIONAL; type < TRT_LAST; type++) {
117 if (!fc_strcasecmp(trade_route_type_names[type], name)) {
118 return type;
122 return TRT_LAST;
125 /*************************************************************************
126 Return human readable name of traderoute cancelling type
127 *************************************************************************/
128 const char *traderoute_cancelling_type_name(enum traderoute_illegal_cancelling type)
130 fc_assert_ret_val(type >= TRI_ACTIVE && type < TRI_LAST, NULL);
132 return traderoute_cancelling_type_names[type];
135 /*************************************************************************
136 Get traderoute cancelling type by name.
137 *************************************************************************/
138 enum traderoute_illegal_cancelling traderoute_cancelling_type_by_name(const char *name)
140 enum traderoute_illegal_cancelling type;
142 for (type = TRI_ACTIVE; type < TRI_LAST; type++) {
143 if (!fc_strcasecmp(traderoute_cancelling_type_names[type], name)) {
144 return type;
148 return TRI_LAST;
151 /*************************************************************************
152 Get trade route settings related to type.
153 *************************************************************************/
154 struct trade_route_settings *
155 trade_route_settings_by_type(enum trade_route_type type)
157 fc_assert_ret_val(type >= TRT_NATIONAL && type < TRT_LAST, NULL);
159 return &trtss[type];
162 /**************************************************************************
163 Return TRUE iff the two cities are capable of trade; i.e., if a caravan
164 from one city can enter the other to sell its goods.
166 See also can_establish_trade_route().
167 **************************************************************************/
168 bool can_cities_trade(const struct city *pc1, const struct city *pc2)
170 /* If you change the logic here, make sure to update the help in
171 * helptext_unit(). */
172 return (pc1 && pc2 && pc1 != pc2
173 && (city_owner(pc1) != city_owner(pc2)
174 || map_distance(pc1->tile, pc2->tile)
175 >= game.info.trademindist)
176 && (trade_route_type_trade_pct(cities_trade_route_type(pc1, pc2))
177 > 0));
180 /**************************************************************************
181 Find the worst (minimum) trade route the city has. The value of the
182 trade route is returned and its position (slot) is put into the slot
183 variable.
184 **************************************************************************/
185 int get_city_min_trade_route(const struct city *pcity, int *slot)
187 int i;
188 int value = 0;
189 bool found = FALSE;
191 if (slot) {
192 *slot = 0;
194 /* find min */
195 for (i = 0; i < MAX_TRADE_ROUTES; i++) {
196 if (pcity->trade[i] && (!found || value > pcity->trade_value[i])) {
197 if (slot) {
198 *slot = i;
200 value = pcity->trade_value[i];
201 found = TRUE;
205 return value;
208 /**************************************************************************
209 Returns TRUE iff the two cities can establish a trade route. We look
210 at the distance and ownership of the cities as well as their existing
211 trade routes. Should only be called if you already know that
212 can_cities_trade().
213 **************************************************************************/
214 bool can_establish_trade_route(const struct city *pc1, const struct city *pc2)
216 int trade = -1;
217 int maxpc1;
218 int maxpc2;
220 if (!pc1 || !pc2 || pc1 == pc2
221 || !can_cities_trade(pc1, pc2)
222 || have_cities_trade_route(pc1, pc2)) {
223 return FALSE;
226 /* First check if cities can have trade routes at all. */
227 maxpc1 = max_trade_routes(pc1);
228 if (maxpc1 <= 0) {
229 return FALSE;
231 maxpc2 = max_trade_routes(pc2);
232 if (maxpc2 <= 0) {
233 return FALSE;
236 if (city_num_trade_routes(pc1) == maxpc1) {
237 trade = trade_between_cities(pc1, pc2);
238 /* can we replace trade route? */
239 if (get_city_min_trade_route(pc1, NULL) >= trade) {
240 return FALSE;
244 if (city_num_trade_routes(pc2) == maxpc2) {
245 if (trade == -1) {
246 trade = trade_between_cities(pc1, pc2);
248 /* can we replace trade route? */
249 if (get_city_min_trade_route(pc2, NULL) >= trade) {
250 return FALSE;
254 return TRUE;
257 /**************************************************************************
258 Return the trade that exists between these cities, assuming they have a
259 trade route.
260 **************************************************************************/
261 int trade_between_cities(const struct city *pc1, const struct city *pc2)
263 int bonus = 0;
265 if (NULL != pc1 && NULL != pc1->tile
266 && NULL != pc2 && NULL != pc2->tile) {
268 bonus = real_map_distance(pc1->tile, pc2->tile)
269 + city_size_get(pc1) + city_size_get(pc2);
271 bonus = bonus * trade_route_type_trade_pct(cities_trade_route_type(pc1, pc2)) / 100;
273 bonus /= 12;
276 return bonus;
279 /**************************************************************************
280 Return number of trade route city has
281 **************************************************************************/
282 int city_num_trade_routes(const struct city *pcity)
284 int i, n = 0;
286 for (i = 0; i < MAX_TRADE_ROUTES; i++) {
287 if (pcity->trade[i] != 0) {
288 n++;
292 return n;
295 /**************************************************************************
296 Returns the revenue trade bonus - you get this when establishing a
297 trade route and also when you simply sell your trade goods at the
298 new city.
300 Note if you trade with a city you already have a trade route with,
301 you'll only get 1/3 of this value.
302 **************************************************************************/
303 int get_caravan_enter_city_trade_bonus(const struct city *pc1,
304 const struct city *pc2)
306 int tb, bonus;
308 /* Should this be real_map_distance? */
309 tb = map_distance(pc1->tile, pc2->tile) + 10;
310 tb = (tb * (pc1->surplus[O_TRADE] + pc2->surplus[O_TRADE])) / 24;
312 /* fudge factor to more closely approximate Civ2 behavior (Civ2 is
313 * really very different -- this just fakes it a little better) */
314 tb *= 3;
316 /* Trade_revenue_bonus increases revenue by power of 2 in milimes */
317 bonus = get_city_bonus(pc1, EFT_TRADE_REVENUE_BONUS);
319 tb = (float)tb * pow(2.0, (double)bonus / 1000.0);
321 return tb;
324 /**************************************************************************
325 Check if cities have an established trade route.
326 **************************************************************************/
327 bool have_cities_trade_route(const struct city *pc1, const struct city *pc2)
329 trade_routes_iterate(pc1, route_to) {
330 if (route_to->id == pc2->id) {
331 return TRUE;
333 } trade_routes_iterate_end;
335 return FALSE;