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