1 /***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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.
7
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 ***********************************************************************/
13
14 #ifdef HAVE_CONFIG_H
15 #include <fc_config.h>
16 #endif
17
18 /* utility */
19 #include "fcintl.h"
20 #include "ioz.h"
21 #include "log.h"
22 #include "mem.h"
23 #include "shared.h"
24 #include "support.h"
25
26 /* aicore */
27 #include "cm.h"
28
29 /* common */
30 #include "ai.h"
31 #include "achievements.h"
32 #include "actions.h"
33 #include "city.h"
34 #include "connection.h"
35 #include "disaster.h"
36 #include "extras.h"
37 #include "government.h"
38 #include "idex.h"
39 #include "map.h"
40 #include "multipliers.h"
41 #include "nation.h"
42 #include "packets.h"
43 #include "player.h"
44 #include "research.h"
45 #include "spaceship.h"
46 #include "specialist.h"
47 #include "style.h"
48 #include "tech.h"
49 #include "terrain.h"
50 #include "traderoutes.h"
51 #include "unit.h"
52 #include "unitlist.h"
53 #include "victory.h"
54
55 #include "game.h"
56
57 struct civ_game game;
58
59 /*
60 struct player_score {
61 int happy;
62 int content;
63 int unhappy;
64 int angry;
65 int taxmen;
66 int scientists;
67 int elvis;
68 int wonders;
69 int techs;
70 int landarea;
71 int settledarea;
72 int population;
73 int cities;
74 int units;
75 int pollution;
76 int literacy;
77 int bnp;
78 int mfg;
79 int spaceship;
80 };
81 */
82
83 bool am_i_server = FALSE;
84
85 static void game_defaults(void);
86
87 /**************************************************************************
88 Set program type to server.
89 **************************************************************************/
i_am_server(void)90 void i_am_server(void)
91 {
92 am_i_server = TRUE;
93 }
94
95 /**************************************************************************
96 Set program type to client.
97 **************************************************************************/
i_am_client(void)98 void i_am_client(void)
99 {
100 am_i_server = FALSE;
101 }
102
103 /**************************************************************************
104 Count the # of thousand citizen in a civilisation.
105 **************************************************************************/
civ_population(const struct player * pplayer)106 int civ_population(const struct player *pplayer)
107 {
108 int ppl = 0;
109
110 city_list_iterate(pplayer->cities, pcity) {
111 ppl += city_population(pcity);
112 } city_list_iterate_end;
113
114 return ppl;
115 }
116
117 /**************************************************************************
118 Find city with given name from any player.
119 **************************************************************************/
game_city_by_name(const char * name)120 struct city *game_city_by_name(const char *name)
121 {
122 players_iterate(pplayer) {
123 struct city *pcity = city_list_find_name(pplayer->cities, name);
124
125 if (pcity) {
126 return pcity;
127 }
128 } players_iterate_end;
129
130 return NULL;
131 }
132
133
134 /**************************************************************************
135 Often used function to get a city pointer from a city ID.
136 City may be any city in the game. This now always uses fast idex
137 method, instead of looking through all cities of all players.
138 **************************************************************************/
game_city_by_number(int id)139 struct city *game_city_by_number(int id)
140 {
141 return idex_lookup_city(id);
142 }
143
144
145 /**************************************************************************
146 Find unit out of all units in game: now uses fast idex method,
147 instead of looking through all units of all players.
148 **************************************************************************/
game_unit_by_number(int id)149 struct unit *game_unit_by_number(int id)
150 {
151 return idex_lookup_unit(id);
152 }
153
154 /**************************************************************************
155 In the server call wipe_unit(), and never this function directly.
156 **************************************************************************/
game_remove_unit(struct unit * punit)157 void game_remove_unit(struct unit *punit)
158 {
159 struct city *pcity;
160
161 /* It's possible that during city transfer homecity/unit owner
162 * information is inconsistent, and client then tries to remove
163 * now unseen unit so that homecity is not in the list of cities
164 * of the player (seemingly) owning the unit.
165 * Thus cannot use player_city_by_number() here, but have to
166 * consider cities of all players. */
167 pcity = game_city_by_number(punit->homecity);
168 if (pcity) {
169 unit_list_remove(pcity->units_supported, punit);
170
171 log_debug("game_remove_unit()"
172 " at (%d,%d) unit %d, %s %s home (%d,%d) city %d, %s %s",
173 TILE_XY(unit_tile(punit)),
174 punit->id,
175 nation_rule_name(nation_of_unit(punit)),
176 unit_rule_name(punit),
177 TILE_XY(pcity->tile),
178 punit->homecity,
179 nation_rule_name(nation_of_city(pcity)),
180 city_name_get(pcity));
181 } else if (IDENTITY_NUMBER_ZERO == punit->homecity) {
182 log_debug("game_remove_unit() at (%d,%d) unit %d, %s %s home %d",
183 TILE_XY(unit_tile(punit)),
184 punit->id,
185 nation_rule_name(nation_of_unit(punit)),
186 unit_rule_name(punit),
187 punit->homecity);
188 } else {
189 log_error("game_remove_unit() at (%d,%d) unit %d, %s %s home %d invalid",
190 TILE_XY(unit_tile(punit)),
191 punit->id,
192 nation_rule_name(nation_of_unit(punit)),
193 unit_rule_name(punit),
194 punit->homecity);
195 }
196
197 unit_list_remove(unit_tile(punit)->units, punit);
198 unit_list_remove(unit_owner(punit)->units, punit);
199
200 idex_unregister_unit(punit);
201
202 if (game.callbacks.unit_deallocate) {
203 (game.callbacks.unit_deallocate)(punit->id);
204 }
205 unit_virtual_destroy(punit);
206 }
207
208 /**************************************************************************
209 Remove city from game.
210 **************************************************************************/
game_remove_city(struct city * pcity)211 void game_remove_city(struct city *pcity)
212 {
213 struct tile *pcenter = city_tile(pcity);
214 struct player *powner = city_owner(pcity);
215
216 if (NULL != powner) {
217 /* always unlink before clearing data */
218 city_list_remove(powner->cities, pcity);
219 }
220
221 if (NULL == pcenter) {
222 log_debug("game_remove_city() virtual city %d, %s",
223 pcity->id,
224 city_name_get(pcity));
225 } else {
226 log_debug("game_remove_city() at (%d,%d) city %d, %s %s",
227 TILE_XY(pcenter),
228 pcity->id,
229 nation_rule_name(nation_of_player(powner)),
230 city_name_get(pcity));
231
232 city_tile_iterate(city_map_radius_sq_get(pcity), pcenter, ptile) {
233 if (tile_worked(ptile) == pcity) {
234 tile_set_worked(ptile, NULL);
235 }
236 } city_tile_iterate_end;
237 }
238
239 idex_unregister_city(pcity);
240 destroy_city_virtual(pcity);
241 }
242
243 /****************************************************************************
244 Set default game values.
245 ****************************************************************************/
game_defaults(void)246 static void game_defaults(void)
247 {
248 int i;
249
250 /* The control packet. */
251 game.control.government_count = 0;
252 game.control.nation_count = 0;
253 game.control.num_base_types = 0;
254 game.control.num_road_types = 0;
255 game.control.num_impr_types = 0;
256 game.control.num_specialist_types = 0;
257 game.control.num_tech_types = 0;
258 game.control.num_unit_classes = 0;
259 game.control.num_unit_types = 0;
260 game.control.num_disaster_types = 0;
261 game.control.num_achievement_types = 0;
262 game.control.num_styles = 0;
263 game.control.num_music_styles = 0;
264 game.control.preferred_tileset[0] = '\0';
265 game.control.preferred_soundset[0] = '\0';
266 game.control.preferred_musicset[0] = '\0';
267 game.control.resource_count = 0;
268 game.control.styles_count = 0;
269 game.control.terrain_count = 0;
270
271 game.ruleset_summary = NULL;
272 game.ruleset_description = NULL;
273
274 /* The info packet. */
275 game.info.aifill = GAME_DEFAULT_AIFILL;
276 game.info.airlifting_style = GAME_DEFAULT_AIRLIFTINGSTYLE;
277 game.info.angrycitizen = GAME_DEFAULT_ANGRYCITIZEN;
278 game.info.borders = GAME_DEFAULT_BORDERS;
279 game.info.calendar_skip_0 = FALSE;
280 game.info.celebratesize = GAME_DEFAULT_CELEBRATESIZE;
281 game.info.citymindist = GAME_DEFAULT_CITYMINDIST;
282 game.info.cooling = 0;
283 game.info.coolinglevel = 0; /* set later */
284 game.info.diplomacy = GAME_DEFAULT_DIPLOMACY;
285 game.info.fogofwar = GAME_DEFAULT_FOGOFWAR;
286 game.info.foodbox = GAME_DEFAULT_FOODBOX;
287 game.info.fulltradesize = GAME_DEFAULT_FULLTRADESIZE;
288 for (i = 0; i < A_LAST; i++) {
289 /* game.num_tech_types = 0 here */
290 game.info.global_advances[i] = FALSE;
291 }
292 for (i = 0; i < B_LAST; i++) {
293 /* game.num_impr_types = 0 here */
294 game.info.great_wonder_owners[i] = WONDER_NOT_OWNED;
295 }
296 game.info.globalwarming = 0;
297 game.info.global_warming = GAME_DEFAULT_GLOBAL_WARMING;
298 game.info.gold = GAME_DEFAULT_GOLD;
299 game.info.revolentype = GAME_DEFAULT_REVOLENTYPE;
300 game.info.default_government_id = G_LAST;
301 game.info.government_during_revolution_id = G_LAST;
302 game.info.happyborders = GAME_DEFAULT_HAPPYBORDERS;
303 game.info.heating = 0;
304 game.info.is_edit_mode = FALSE;
305 game.info.is_new_game = TRUE;
306 game.info.killstack = GAME_DEFAULT_KILLSTACK;
307 game.info.killcitizen = GAME_DEFAULT_KILLCITIZEN;
308 game.info.negative_year_label[0] = '\0';
309 game.info.notradesize = GAME_DEFAULT_NOTRADESIZE;
310 game.info.nuclearwinter = 0;
311 game.info.nuclear_winter = GAME_DEFAULT_NUCLEAR_WINTER;
312 game.info.positive_year_label[0] = '\0';
313 game.info.rapturedelay = GAME_DEFAULT_RAPTUREDELAY;
314 game.info.disasters = GAME_DEFAULT_DISASTERS;
315 game.info.restrictinfra = GAME_DEFAULT_RESTRICTINFRA;
316 game.info.sciencebox = GAME_DEFAULT_SCIENCEBOX;
317 game.info.shieldbox = GAME_DEFAULT_SHIELDBOX;
318 game.info.skill_level = GAME_DEFAULT_SKILL_LEVEL;
319 game.info.slow_invasions = RS_DEFAULT_SLOW_INVASIONS;
320 game.info.victory_conditions = GAME_DEFAULT_VICTORY_CONDITIONS;
321 game.info.team_pooled_research = GAME_DEFAULT_TEAM_POOLED_RESEARCH;
322 game.info.tech = GAME_DEFAULT_TECHLEVEL;
323 game.info.timeout = GAME_DEFAULT_TIMEOUT;
324 game.info.trademindist = GAME_DEFAULT_TRADEMINDIST;
325 game.info.trading_city = GAME_DEFAULT_TRADING_CITY;
326 game.info.trading_gold = GAME_DEFAULT_TRADING_GOLD;
327 game.info.trading_tech = GAME_DEFAULT_TRADING_TECH;
328 game.info.turn = 0;
329 game.info.warminglevel = 0; /* set later */
330 game.info.year_0_hack = FALSE;
331 game.info.year32 = GAME_DEFAULT_START_YEAR;
332 game.info.year16 = GAME_DEFAULT_START_YEAR;
333
334 /* The scenario packets. */
335 game.scenario.is_scenario = FALSE;
336 game.scenario.name[0] = '\0';
337 game.scenario.authors[0] = '\0';
338 game.scenario.players = TRUE;
339 game.scenario.startpos_nations = FALSE;
340 game.scenario.handmade = FALSE;
341 game.scenario.prevent_new_cities = FALSE;
342 game.scenario.lake_flooding = TRUE;
343 game.scenario.have_resources = TRUE;
344 game.scenario.save_random = FALSE;
345 game.scenario.allow_ai_type_fallback = FALSE;
346
347 game.scenario_desc.description[0] = '\0';
348
349 /* Veteran system. */
350 game.veteran = NULL;
351
352 /* player colors */
353 game.plr_bg_color = NULL;
354
355 if (is_server()) {
356 /* All settings only used by the server (./server/ and ./ai/ */
357 sz_strlcpy(game.server.allow_take, GAME_DEFAULT_ALLOW_TAKE);
358 game.server.allowed_city_names = GAME_DEFAULT_ALLOWED_CITY_NAMES;
359 game.server.aqueductloss = GAME_DEFAULT_AQUEDUCTLOSS;
360 game.server.auto_ai_toggle = GAME_DEFAULT_AUTO_AI_TOGGLE;
361 game.server.autoattack = GAME_DEFAULT_AUTOATTACK;
362 game.server.barbarianrate = GAME_DEFAULT_BARBARIANRATE;
363 game.server.civilwarsize = GAME_DEFAULT_CIVILWARSIZE;
364 game.server.connectmsg[0] = '\0';
365 game.server.conquercost = GAME_DEFAULT_CONQUERCOST;
366 game.server.contactturns = GAME_DEFAULT_CONTACTTURNS;
367 for (i = 0; i < DEBUG_LAST; i++) {
368 game.server.debug[i] = FALSE;
369 }
370 sz_strlcpy(game.server.demography, GAME_DEFAULT_DEMOGRAPHY);
371 game.server.diplchance = GAME_DEFAULT_DIPLCHANCE;
372 game.server.diplbulbcost = GAME_DEFAULT_DIPLBULBCOST;
373 game.server.diplgoldcost = GAME_DEFAULT_DIPLGOLDCOST;
374 game.server.dispersion = GAME_DEFAULT_DISPERSION;
375 game.server.endspaceship = GAME_DEFAULT_END_SPACESHIP;
376 game.server.end_turn = GAME_DEFAULT_END_TURN;
377 game.server.event_cache.chat = GAME_DEFAULT_EVENT_CACHE_CHAT;
378 game.server.event_cache.info = GAME_DEFAULT_EVENT_CACHE_INFO;
379 game.server.event_cache.max_size = GAME_DEFAULT_EVENT_CACHE_MAX_SIZE;
380 game.server.event_cache.turns = GAME_DEFAULT_EVENT_CACHE_TURNS;
381 game.server.foggedborders = GAME_DEFAULT_FOGGEDBORDERS;
382 game.server.fogofwar_old = game.info.fogofwar;
383 game.server.last_updated_year = FALSE;
384 game.server.freecost = GAME_DEFAULT_FREECOST;
385 game.server.homecaughtunits = GAME_DEFAULT_HOMECAUGHTUNITS;
386 game.server.kick_time = GAME_DEFAULT_KICK_TIME;
387 game.server.killunhomed = GAME_DEFAULT_KILLUNHOMED;
388 game.server.maxconnectionsperhost = GAME_DEFAULT_MAXCONNECTIONSPERHOST;
389 game.server.last_ping = 0;
390 game.server.max_players = GAME_DEFAULT_MAX_PLAYERS;
391 game.server.meta_info.user_message[0] = '\0';
392 game.server.meta_info.user_message_set = FALSE;
393 /* Do not clear meta_info.type here as it's already set to correct value */
394 game.server.mgr_distance = GAME_DEFAULT_MGR_DISTANCE;
395 game.server.mgr_foodneeded = GAME_DEFAULT_MGR_FOODNEEDED;
396 game.server.mgr_nationchance = GAME_DEFAULT_MGR_NATIONCHANCE;
397 game.server.mgr_turninterval = GAME_DEFAULT_MGR_TURNINTERVAL;
398 game.server.mgr_worldchance = GAME_DEFAULT_MGR_WORLDCHANCE;
399 game.server.migration = GAME_DEFAULT_MIGRATION;
400 game.server.trait_dist = GAME_DEFAULT_TRAIT_DIST_MODE;
401 game.server.min_players = GAME_DEFAULT_MIN_PLAYERS;
402 game.server.natural_city_names = GAME_DEFAULT_NATURALCITYNAMES;
403 game.server.plrcolormode = GAME_DEFAULT_PLRCOLORMODE;
404 game.server.netwait = GAME_DEFAULT_NETWAIT;
405 game.server.occupychance = GAME_DEFAULT_OCCUPYCHANCE;
406 game.server.onsetbarbarian = GAME_DEFAULT_ONSETBARBARIAN;
407 game.server.phase_mode_stored = GAME_DEFAULT_PHASE_MODE;
408 game.server.pingtime = GAME_DEFAULT_PINGTIME;
409 game.server.pingtimeout = GAME_DEFAULT_PINGTIMEOUT;
410 game.server.razechance = GAME_DEFAULT_RAZECHANCE;
411 game.server.revealmap = GAME_DEFAULT_REVEALMAP;
412 game.server.revolution_length = GAME_DEFAULT_REVOLUTION_LENGTH;
413 sz_strlcpy(game.server.rulesetdir, GAME_DEFAULT_RULESETDIR);
414 game.server.save_compress_level = GAME_DEFAULT_COMPRESS_LEVEL;
415 game.server.save_compress_type = GAME_DEFAULT_COMPRESS_TYPE;
416 sz_strlcpy(game.server.save_name, GAME_DEFAULT_SAVE_NAME);
417 game.server.save_nturns = GAME_DEFAULT_SAVETURNS;
418 game.server.save_options.save_known = TRUE;
419 game.server.save_options.save_private_map = TRUE;
420 game.server.save_options.save_starts = TRUE;
421 game.server.savepalace = GAME_DEFAULT_SAVEPALACE;
422 game.server.scorelog = GAME_DEFAULT_SCORELOG;
423 game.server.scoreloglevel = GAME_DEFAULT_SCORELOGLEVEL;
424 game.server.scoreturn = GAME_DEFAULT_SCORETURN - 1;
425 game.server.seed = GAME_DEFAULT_SEED;
426 sz_strlcpy(game.server.start_units, GAME_DEFAULT_START_UNITS);
427 game.server.start_year = GAME_DEFAULT_START_YEAR;
428 game.server.tcptimeout = GAME_DEFAULT_TCPTIMEOUT;
429 game.server.techlost_donor = GAME_DEFAULT_TECHLOST_DONOR;
430 game.server.techlost_recv = GAME_DEFAULT_TECHLOST_RECV;
431 game.server.techpenalty = GAME_DEFAULT_TECHPENALTY;
432 game.server.timeoutaddenemymove = GAME_DEFAULT_TIMEOUTADDEMOVE;
433 game.server.timeoutcounter = GAME_DEFAULT_TIMEOUTCOUNTER;
434 game.server.timeoutinc = GAME_DEFAULT_TIMEOUTINC;
435 game.server.timeoutincmult = GAME_DEFAULT_TIMEOUTINCMULT;
436 game.server.timeoutint = GAME_DEFAULT_TIMEOUTINT;
437 game.server.timeoutintinc = GAME_DEFAULT_TIMEOUTINTINC;
438 game.server.turnblock = GAME_DEFAULT_TURNBLOCK;
439 game.server.unitwaittime = GAME_DEFAULT_UNITWAITTIME;
440 game.server.plr_colors = NULL;
441 } else {
442 /* Client side takes care of itself in client_main() */
443 }
444 }
445
446 /****************************************************************************
447 Initialise all game settings.
448
449 The variables are listed in alphabetical order.
450 ****************************************************************************/
game_init(void)451 void game_init(void)
452 {
453 game_defaults();
454 player_slots_init();
455 map_init();
456 team_slots_init();
457 game_ruleset_init();
458 idex_init();
459 cm_init();
460 researches_init();
461 universal_found_functions_init();
462 }
463
464 /****************************************************************************
465 Initialize map-specific parts of the game structure. Maybe these should
466 be moved into the map structure?
467 ****************************************************************************/
game_map_init(void)468 void game_map_init(void)
469 {
470 /* FIXME: it's not clear where these values should be initialized. It
471 * can't be done in game_init because the map isn't created yet. Maybe it
472 * should be done in the mapgen code or in the maphand code. It should
473 * surely be called when the map is generated. */
474 game.info.warminglevel = (map_num_tiles() + 499) / 500;
475 game.info.coolinglevel = (map_num_tiles() + 499) / 500;
476 }
477
478 /***************************************************************
479 Frees all memory of the game.
480 ***************************************************************/
game_free(void)481 void game_free(void)
482 {
483 player_slots_free();
484 map_free();
485 idex_free();
486 team_slots_free();
487 game_ruleset_free();
488 researches_free();
489 cm_free();
490 }
491
492 /***************************************************************
493 Do all changes to change view, and not full
494 game_free()/game_init().
495 ***************************************************************/
game_reset(void)496 void game_reset(void)
497 {
498 if (is_server()) {
499 game_free();
500 game_init();
501 } else {
502 /* Reset the players infos. */
503 players_iterate(pplayer) {
504 player_clear(pplayer, FALSE);
505 } players_iterate_end;
506
507 map_free();
508 idex_free();
509
510 map_init();
511 idex_init();
512 researches_init();
513 }
514 }
515
516 /***************************************************************
517 Initialize the objects which will read from a ruleset.
518 ***************************************************************/
game_ruleset_init(void)519 void game_ruleset_init(void)
520 {
521 nation_sets_groups_init();
522 ruleset_cache_init();
523 disaster_types_init();
524 achievements_init();
525 actions_init();
526 trade_route_types_init();
527 terrains_init();
528 extras_init();
529 improvements_init();
530 techs_init();
531 unit_classes_init();
532 unit_types_init();
533 specialists_init();
534 user_unit_type_flags_init();
535 user_terrain_flags_init();
536 user_tech_flags_init();
537 multipliers_init();
538
539 if (is_server()) {
540 game.server.ruledit.nationlist = NULL;
541 game.server.ruledit.embedded_nations = NULL;
542 game.server.ruledit.embedded_nations_count = 0;
543 game.server.ruledit.allowed_govs = NULL;
544 game.server.ruledit.allowed_terrains = NULL;
545 game.server.ruledit.allowed_styles = NULL;
546 game.server.ruledit.nc_agovs = NULL;
547 game.server.ruledit.nc_aterrs = NULL;
548 game.server.ruledit.nc_astyles = NULL;
549 game.server.ruledit.ag_count = 0;
550 game.server.ruledit.at_count = 0;
551 game.server.ruledit.as_count = 0;
552 }
553 }
554
555 /***************************************************************
556 Frees all memory which in objects which are read from a ruleset.
557 ***************************************************************/
game_ruleset_free(void)558 void game_ruleset_free(void)
559 {
560 int i;
561
562 CALL_FUNC_EACH_AI(units_ruleset_close);
563
564 /* Clear main structures which can points to the ruleset dependent
565 * structures. */
566 players_iterate(pplayer) {
567 player_ruleset_close(pplayer);
568 } players_iterate_end;
569 game.government_during_revolution = NULL;
570
571 specialists_free();
572 unit_classes_free();
573 techs_free();
574 governments_free();
575 nations_free();
576 unit_types_free();
577 unit_type_flags_free();
578 role_unit_precalcs_free();
579 improvements_free();
580 extras_free();
581 music_styles_free();
582 city_styles_free();
583 styles_free();
584 actions_free();
585 achievements_free();
586 disaster_types_free();
587 terrains_free();
588 user_tech_flags_free();
589 user_terrain_flags_free();
590 ruleset_cache_free();
591 nation_sets_groups_free();
592 multipliers_free();
593
594 /* Destroy the default veteran system. */
595 veteran_system_destroy(game.veteran);
596 game.veteran = NULL;
597
598 /* Player colors. */
599 if (game.plr_bg_color != NULL) {
600 rgbcolor_destroy(game.plr_bg_color);
601 game.plr_bg_color = NULL;
602 }
603
604 if (is_server()) {
605 if (game.server.ruledit.description_file != NULL) {
606 free(game.server.ruledit.description_file);
607 game.server.ruledit.description_file = NULL;
608 }
609 if (game.server.ruledit.nationlist != NULL) {
610 free(game.server.ruledit.nationlist);
611 game.server.ruledit.nationlist = NULL;
612 }
613 if (game.server.ruledit.embedded_nations != NULL) {
614 for (i = 0; i < game.server.ruledit.embedded_nations_count; i++) {
615 free(game.server.ruledit.embedded_nations[i]);
616 }
617 free(game.server.ruledit.embedded_nations);
618 game.server.ruledit.embedded_nations = NULL;
619 game.server.ruledit.embedded_nations_count = 0;
620 if (game.server.ruledit.allowed_govs != NULL) {
621 for (i = 0; i < game.server.ruledit.ag_count; i++) {
622 free(game.server.ruledit.nc_agovs[i]);
623 }
624 free(game.server.ruledit.allowed_govs);
625 game.server.ruledit.allowed_govs = NULL;
626 game.server.ruledit.nc_agovs = NULL;
627 }
628 if (game.server.ruledit.allowed_terrains != NULL) {
629 for (i = 0; i < game.server.ruledit.at_count; i++) {
630 free(game.server.ruledit.nc_aterrs[i]);
631 }
632 free(game.server.ruledit.allowed_terrains);
633 game.server.ruledit.allowed_terrains = NULL;
634 game.server.ruledit.nc_aterrs = NULL;
635 }
636 if (game.server.ruledit.allowed_styles != NULL) {
637 for (i = 0; i < game.server.ruledit.as_count; i++) {
638 free(game.server.ruledit.nc_astyles[i]);
639 }
640 free(game.server.ruledit.allowed_styles);
641 game.server.ruledit.allowed_styles = NULL;
642 game.server.ruledit.nc_astyles = NULL;
643 }
644 }
645 }
646
647 for (i = 0; i < MAX_CALENDAR_FRAGMENTS; i++) {
648 game.info.calendar_fragment_name[i][0] = '\0';
649 }
650
651 if (game.ruleset_summary != NULL) {
652 free(game.ruleset_summary);
653 game.ruleset_summary = NULL;
654 }
655
656 if (game.ruleset_description != NULL) {
657 free(game.ruleset_description);
658 game.ruleset_description = NULL;
659 }
660 }
661
662 /***************************************************************
663 Initialize wonder information.
664 ***************************************************************/
initialize_globals(void)665 void initialize_globals(void)
666 {
667 players_iterate(pplayer) {
668 city_list_iterate(pplayer->cities, pcity) {
669 city_built_iterate(pcity, pimprove) {
670 if (is_wonder(pimprove)) {
671 if (is_great_wonder(pimprove)) {
672 game.info.great_wonder_owners[improvement_index(pimprove)] =
673 player_number(pplayer);
674 }
675 pplayer->wonders[improvement_index(pimprove)] = pcity->id;
676 }
677 } city_built_iterate_end;
678 } city_list_iterate_end;
679 } players_iterate_end;
680 }
681
682 /**************************************************************************
683 Return TRUE if it is this player's phase.
684 NB: The meaning of the 'phase' argument must match its use in the
685 function begin_turn() in server/srv_main.c.
686 NB: The phase mode PMT_TEAMS_ALTERNATE assumes that every player is
687 on a team, i.e. that pplayer->team is never NULL.
688 **************************************************************************/
is_player_phase(const struct player * pplayer,int phase)689 bool is_player_phase(const struct player *pplayer, int phase)
690 {
691 switch (game.info.phase_mode) {
692 case PMT_CONCURRENT:
693 return TRUE;
694 break;
695 case PMT_PLAYERS_ALTERNATE:
696 return player_number(pplayer) == phase;
697 break;
698 case PMT_TEAMS_ALTERNATE:
699 fc_assert_ret_val(NULL != pplayer->team, FALSE);
700 return team_number(pplayer->team) == phase;
701 break;
702 default:
703 break;
704 }
705
706 fc_assert_msg(FALSE, "Unrecognized phase mode %d in is_player_phase().",
707 phase);
708 return TRUE;
709 }
710
711 /****************************************************************************
712 Return a prettily formatted string containing the population text. The
713 population is passed in as the number of citizens, in unit
714 (tens/hundreds/thousands...) defined in cities.ruleset.
715 ****************************************************************************/
population_to_text(int thousand_citizen)716 const char *population_to_text(int thousand_citizen)
717 {
718 /* big_int_to_text can't handle negative values, and in any case we'd
719 * better not have a negative population. */
720 fc_assert_ret_val(thousand_citizen >= 0, NULL);
721 return big_int_to_text(thousand_citizen, game.info.pop_report_zeroes - 1);
722 }
723
724 /**************************************************************************
725 Return a string containing the save year.
726 **************************************************************************/
year_suffix(void)727 static char *year_suffix(void)
728 {
729 static char buf[MAX_LEN_NAME];
730 const char *suffix;
731 char safe_year_suffix[MAX_LEN_NAME];
732 const char *max = safe_year_suffix + MAX_LEN_NAME - 1;
733 char *c = safe_year_suffix;
734
735 if (game.info.year32 < 0) {
736 suffix = game.info.negative_year_label;
737 } else {
738 suffix = game.info.positive_year_label;
739 }
740
741 /* Remove all non alphanumeric characters from the year suffix. */
742 for (; '\0' != *suffix && c < max; suffix++) {
743 if (fc_isalnum(*suffix)) {
744 *c++ = *suffix;
745 }
746 }
747 *c = '\0';
748
749 fc_snprintf(buf, sizeof(buf), "%s", safe_year_suffix);
750
751 return buf;
752 }
753
754 /**************************************************************************
755 Generate a default save file name and place it in the provided buffer.
756 Within the name the following custom formats are allowed:
757
758 %R = <reason>
759 %S = <suffix>
760 %T = <game.info.turn>
761 %Y = <game.info.year>
762
763 Examples:
764 'freeciv-T%04T-Y%+04Y-%R' => 'freeciv-T0099-Y-0050-manual'
765 => 'freeciv-T0100-Y00001-auto'
766
767 Returns the number of characters written, or the number of characters
768 that would have been written if truncation occurs.
769
770 NB: If you change the format definition, be sure to update the above
771 function comment and the help text for the 'savename' setting.
772 **************************************************************************/
generate_save_name(const char * format,char * buf,int buflen,const char * reason)773 int generate_save_name(const char *format, char *buf, int buflen,
774 const char *reason)
775 {
776 struct cf_sequence sequences[5] = {
777 cf_str_seq('R', (reason == NULL) ? "auto" : reason),
778 cf_str_seq('S', year_suffix()),
779 { 0 }, { 0 }, /* Works for both gcc and tcc */
780 cf_end()
781 };
782
783 cf_int_seq('T', game.info.turn, &sequences[2]);
784 cf_int_seq('Y', game.info.year32, &sequences[3]);
785
786 fc_vsnprintcf(buf, buflen, format, sequences, -1);
787
788 if (0 == strcmp(format, buf)) {
789 /* Use the default savename if 'format' does not contain
790 * printf information. */
791 char savename[512];
792
793 fc_snprintf(savename, sizeof(savename), "%s-T%%04T-Y%%05Y-%%R",
794 format);
795 fc_vsnprintcf(buf, buflen, savename, sequences, -1);
796 }
797
798 log_debug("save name generated from '%s': %s", format, buf);
799
800 return strlen(buf);
801 }
802
803 /**************************************************************************
804 Initialize user flag.
805 **************************************************************************/
user_flag_init(struct user_flag * flag)806 void user_flag_init(struct user_flag *flag)
807 {
808 flag->name = NULL;
809 flag->helptxt = NULL;
810 }
811
812 /**************************************************************************
813 Free user flag.
814 **************************************************************************/
user_flag_free(struct user_flag * flag)815 void user_flag_free(struct user_flag *flag)
816 {
817 if (flag->name != NULL) {
818 FC_FREE(flag->name);
819 flag->name = NULL;
820 }
821 if (flag->helptxt != NULL) {
822 FC_FREE(flag->helptxt);
823 flag->helptxt = NULL;
824 }
825 }
826
827 /****************************************************************************
828 Return timeout value for the current turn.
829 ****************************************************************************/
current_turn_timeout(void)830 int current_turn_timeout(void)
831 {
832 if (game.info.turn == 0 && game.info.first_timeout != -1) {
833 return game.info.first_timeout;
834 } else {
835 return game.info.timeout;
836 }
837 }
838