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)
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 ***********************************************************************/
15 #include <fc_config.h>
31 #include "achievements.h"
34 #include "connection.h"
37 #include "government.h"
40 #include "multipliers.h"
45 #include "spaceship.h"
46 #include "specialist.h"
50 #include "traderoutes.h"
83 bool am_i_server
= FALSE
;
85 static void game_defaults(void);
87 /**************************************************************************
88 Is program type server?
89 **************************************************************************/
95 /**************************************************************************
96 Set program type to server.
97 **************************************************************************/
98 void i_am_server(void)
103 /**************************************************************************
104 Set program type to client.
105 **************************************************************************/
106 void i_am_client(void)
111 /**************************************************************************
112 Count the # of thousand citizen in a civilisation.
113 **************************************************************************/
114 int civ_population(const struct player
*pplayer
)
117 city_list_iterate(pplayer
->cities
, pcity
)
118 ppl
+=city_population(pcity
);
119 city_list_iterate_end
;
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
);
135 } players_iterate_end
;
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
)
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
);
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
)),
182 nation_rule_name(nation_of_unit(punit
)),
183 unit_rule_name(punit
),
184 TILE_XY(pcity
->tile
),
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
)),
192 nation_rule_name(nation_of_unit(punit
)),
193 unit_rule_name(punit
),
196 log_error("game_remove_unit() at (%d,%d) unit %d, %s %s home %d invalid",
197 TILE_XY(unit_tile(punit
)),
199 nation_rule_name(nation_of_unit(punit
)),
200 unit_rule_name(punit
),
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",
231 city_name_get(pcity
));
233 log_debug("game_remove_city() at (%d,%d) city %d, %s %s",
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)
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
;
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. */
359 game
.plr_bg_color
= NULL
;
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
;
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 ****************************************************************************/
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 ***************************************************************/
498 /***************************************************************
499 Do all changes to change view, and not full
500 game_free()/game_init().
501 ***************************************************************/
502 void game_reset(void)
508 /* Reset the players infos. */
509 players_iterate(pplayer
) {
510 player_clear(pplayer
, FALSE
);
511 } players_iterate_end
;
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();
532 trade_route_types_init();
540 user_unit_type_flags_init();
541 user_terrain_flags_init();
542 user_tech_flags_init();
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)
568 CALL_FUNC_EACH_AI(units_ruleset_close
);
570 /* Clear main structures which can points to the ruleset dependent
572 players_iterate(pplayer
) {
573 player_ruleset_close(pplayer
);
574 } players_iterate_end
;
575 game
.government_during_revolution
= NULL
;
583 unit_type_flags_free();
584 role_unit_precalcs_free();
592 disaster_types_free();
594 user_tech_flags_free();
595 user_terrain_flags_free();
596 ruleset_cache_free();
597 nation_sets_groups_free();
600 /* Destroy the default veteran system. */
601 veteran_system_destroy(game
.veteran
);
605 if (game
.plr_bg_color
!= NULL
) {
606 rgbcolor_destroy(game
.plr_bg_color
);
607 game
.plr_bg_color
= NULL
;
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
) {
701 case PMT_PLAYERS_ALTERNATE
:
702 return player_number(pplayer
) == phase
;
704 case PMT_TEAMS_ALTERNATE
:
705 fc_assert_ret_val(NULL
!= pplayer
->team
, FALSE
);
706 return team_number(pplayer
->team
) == phase
;
712 fc_assert_msg(FALSE
, "Unrecognized phase mode %d in is_player_phase().",
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
];
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
;
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
)) {
755 fc_snprintf(buf
, sizeof(buf
), "%s", safe_year_suffix
);
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:
766 %T = <game.info.turn>
767 %Y = <game.info.year>
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
,
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 */
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. */
799 fc_snprintf(savename
, sizeof(savename
), "%s-T%%04T-Y%%05Y-%%R",
801 fc_vsnprintcf(buf
, buflen
, savename
, sequences
, -1);
804 log_debug("save name generated from '%s': %s", format
, buf
);
809 /**************************************************************************
810 Initialize user flag.
811 **************************************************************************/
812 void user_flag_init(struct user_flag
*flag
)
815 flag
->helptxt
= NULL
;
818 /**************************************************************************
820 **************************************************************************/
821 void user_flag_free(struct user_flag
*flag
)
823 if (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
;
841 return game
.info
.timeout
;