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"
60 bool am_i_server
= FALSE
;
62 static void game_defaults(bool keep_ruleset_value
);
64 /**************************************************************************
65 Is program type server?
66 **************************************************************************/
72 /**************************************************************************
73 Set program type to server.
74 **************************************************************************/
75 void i_am_server(void)
80 /**************************************************************************
81 Set program type to client.
82 **************************************************************************/
83 void i_am_client(void)
88 /**************************************************************************
89 Count the # of thousand citizen in a civilisation.
90 **************************************************************************/
91 int civ_population(const struct player
*pplayer
)
94 city_list_iterate(pplayer
->cities
, pcity
)
95 ppl
+=city_population(pcity
);
96 city_list_iterate_end
;
101 /**************************************************************************
102 Find city with given name from any player.
103 **************************************************************************/
104 struct city
*game_city_by_name(const char *name
)
106 players_iterate(pplayer
) {
107 struct city
*pcity
= city_list_find_name(pplayer
->cities
, name
);
112 } players_iterate_end
;
118 /**************************************************************************
119 Often used function to get a city pointer from a city ID.
120 City may be any city in the game. This now always uses fast idex
121 method, instead of looking through all cities of all players.
122 **************************************************************************/
123 struct city
*game_city_by_number(int id
)
125 return idex_lookup_city(&wld
, id
);
129 /**************************************************************************
130 Find unit out of all units in game: now uses fast idex method,
131 instead of looking through all units of all players.
132 **************************************************************************/
133 struct unit
*game_unit_by_number(int id
)
135 return idex_lookup_unit(&wld
, id
);
138 /**************************************************************************
139 In the server call wipe_unit(), and never this function directly.
140 **************************************************************************/
141 void game_remove_unit(struct world
*gworld
, struct unit
*punit
)
145 /* It's possible that during city transfer homecity/unit owner
146 * information is inconsistent, and client then tries to remove
147 * now unseen unit so that homecity is not in the list of cities
148 * of the player (seemingly) owning the unit.
149 * Thus cannot use player_city_by_number() here, but have to
150 * consider cities of all players. */
151 pcity
= game_city_by_number(punit
->homecity
);
153 unit_list_remove(pcity
->units_supported
, punit
);
155 log_debug("game_remove_unit()"
156 " at (%d,%d) unit %d, %s %s home (%d,%d) city %d, %s %s",
157 TILE_XY(unit_tile(punit
)),
159 nation_rule_name(nation_of_unit(punit
)),
160 unit_rule_name(punit
),
161 TILE_XY(pcity
->tile
),
163 nation_rule_name(nation_of_city(pcity
)),
164 city_name_get(pcity
));
165 } else if (IDENTITY_NUMBER_ZERO
== punit
->homecity
) {
166 log_debug("game_remove_unit() at (%d,%d) unit %d, %s %s home %d",
167 TILE_XY(unit_tile(punit
)),
169 nation_rule_name(nation_of_unit(punit
)),
170 unit_rule_name(punit
),
173 log_error("game_remove_unit() at (%d,%d) unit %d, %s %s home %d invalid",
174 TILE_XY(unit_tile(punit
)),
176 nation_rule_name(nation_of_unit(punit
)),
177 unit_rule_name(punit
),
181 unit_list_remove(unit_tile(punit
)->units
, punit
);
182 unit_list_remove(unit_owner(punit
)->units
, punit
);
184 idex_unregister_unit(gworld
, punit
);
186 if (game
.callbacks
.unit_deallocate
) {
187 (game
.callbacks
.unit_deallocate
)(punit
->id
);
189 unit_virtual_destroy(punit
);
192 /**************************************************************************
193 Remove city from game.
194 **************************************************************************/
195 void game_remove_city(struct world
*gworld
, struct city
*pcity
)
197 struct tile
*pcenter
= city_tile(pcity
);
198 struct player
*powner
= city_owner(pcity
);
200 if (NULL
!= powner
) {
201 /* always unlink before clearing data */
202 city_list_remove(powner
->cities
, pcity
);
205 if (NULL
== pcenter
) {
206 log_debug("game_remove_city() virtual city %d, %s",
208 city_name_get(pcity
));
210 log_debug("game_remove_city() at (%d,%d) city %d, %s %s",
213 nation_rule_name(nation_of_player(powner
)),
214 city_name_get(pcity
));
216 city_tile_iterate(city_map_radius_sq_get(pcity
), pcenter
, ptile
) {
217 if (tile_worked(ptile
) == pcity
) {
218 tile_set_worked(ptile
, NULL
);
220 } city_tile_iterate_end
;
223 idex_unregister_city(gworld
, pcity
);
224 destroy_city_virtual(pcity
);
227 /****************************************************************************
228 Set default game values.
229 ****************************************************************************/
230 static void game_defaults(bool keep_ruleset_value
)
234 /* The control packet. */
235 game
.control
.government_count
= 0;
236 game
.control
.nation_count
= 0;
237 game
.control
.num_base_types
= 0;
238 game
.control
.num_road_types
= 0;
239 game
.control
.num_resource_types
= 0;
240 game
.control
.num_impr_types
= 0;
241 game
.control
.num_specialist_types
= 0;
242 game
.control
.num_tech_types
= 0;
243 game
.control
.num_unit_classes
= 0;
244 game
.control
.num_unit_types
= 0;
245 game
.control
.num_disaster_types
= 0;
246 game
.control
.num_achievement_types
= 0;
247 game
.control
.num_styles
= 0;
248 game
.control
.num_music_styles
= 0;
249 game
.control
.preferred_tileset
[0] = '\0';
250 game
.control
.preferred_soundset
[0] = '\0';
251 game
.control
.preferred_musicset
[0] = '\0';
252 game
.control
.styles_count
= 0;
253 game
.control
.terrain_count
= 0;
255 game
.ruleset_summary
= NULL
;
256 game
.ruleset_description
= NULL
;
257 game
.ruleset_capabilities
= NULL
;
259 /* The info packet. */
260 game
.info
.aifill
= GAME_DEFAULT_AIFILL
;
261 game
.info
.airlifting_style
= GAME_DEFAULT_AIRLIFTINGSTYLE
;
262 game
.info
.angrycitizen
= GAME_DEFAULT_ANGRYCITIZEN
;
263 game
.info
.borders
= GAME_DEFAULT_BORDERS
;
264 game
.calendar
.calendar_skip_0
= FALSE
;
265 game
.info
.celebratesize
= GAME_DEFAULT_CELEBRATESIZE
;
266 game
.info
.citymindist
= GAME_DEFAULT_CITYMINDIST
;
267 game
.info
.cooling
= 0;
268 game
.info
.coolinglevel
= 0; /* set later */
269 game
.info
.diplomacy
= GAME_DEFAULT_DIPLOMACY
;
270 game
.info
.fogofwar
= GAME_DEFAULT_FOGOFWAR
;
271 game
.info
.foodbox
= GAME_DEFAULT_FOODBOX
;
272 game
.info
.fulltradesize
= GAME_DEFAULT_FULLTRADESIZE
;
273 game
.info
.global_advance_count
= 0;
274 for (i
= 0; i
< A_LAST
; i
++) {
275 /* game.num_tech_types = 0 here */
276 game
.info
.global_advances
[i
] = FALSE
;
278 for (i
= 0; i
< B_LAST
; i
++) {
279 /* game.num_impr_types = 0 here */
280 game
.info
.great_wonder_owners
[i
] = WONDER_NOT_OWNED
;
282 game
.info
.globalwarming
= 0;
283 game
.info
.global_warming
= GAME_DEFAULT_GLOBAL_WARMING
;
284 game
.info
.gold
= GAME_DEFAULT_GOLD
;
285 game
.info
.revolentype
= GAME_DEFAULT_REVOLENTYPE
;
286 game
.info
.default_government_id
= G_LAST
;
287 game
.info
.government_during_revolution_id
= G_LAST
;
288 game
.info
.happyborders
= GAME_DEFAULT_HAPPYBORDERS
;
289 game
.info
.heating
= 0;
290 game
.info
.is_edit_mode
= FALSE
;
291 game
.info
.is_new_game
= TRUE
;
292 game
.info
.killstack
= GAME_DEFAULT_KILLSTACK
;
293 game
.info
.killcitizen
= GAME_DEFAULT_KILLCITIZEN
;
294 game
.calendar
.negative_year_label
[0] = '\0';
295 game
.info
.notradesize
= GAME_DEFAULT_NOTRADESIZE
;
296 game
.info
.nuclearwinter
= 0;
297 game
.info
.nuclear_winter
= GAME_DEFAULT_NUCLEAR_WINTER
;
298 game
.calendar
.positive_year_label
[0] = '\0';
299 game
.info
.rapturedelay
= GAME_DEFAULT_RAPTUREDELAY
;
300 game
.info
.disasters
= GAME_DEFAULT_DISASTERS
;
301 game
.info
.restrictinfra
= GAME_DEFAULT_RESTRICTINFRA
;
302 game
.info
.sciencebox
= GAME_DEFAULT_SCIENCEBOX
;
303 game
.info
.shieldbox
= GAME_DEFAULT_SHIELDBOX
;
304 game
.info
.skill_level
= GAME_DEFAULT_SKILL_LEVEL
;
305 game
.info
.slow_invasions
= RS_DEFAULT_SLOW_INVASIONS
;
306 game
.info
.victory_conditions
= GAME_DEFAULT_VICTORY_CONDITIONS
;
307 game
.info
.team_pooled_research
= GAME_DEFAULT_TEAM_POOLED_RESEARCH
;
308 game
.info
.tech
= GAME_DEFAULT_TECHLEVEL
;
309 game
.info
.timeout
= GAME_DEFAULT_TIMEOUT
;
310 game
.info
.trademindist
= GAME_DEFAULT_TRADEMINDIST
;
311 game
.info
.trading_city
= GAME_DEFAULT_TRADING_CITY
;
312 game
.info
.trading_gold
= GAME_DEFAULT_TRADING_GOLD
;
313 game
.info
.trading_tech
= GAME_DEFAULT_TRADING_TECH
;
315 game
.info
.warminglevel
= 0; /* set later */
316 game
.info
.year_0_hack
= FALSE
;
317 game
.info
.year
= GAME_START_YEAR
;
319 /* The scenario packets. */
320 game
.scenario
.is_scenario
= FALSE
;
321 game
.scenario
.name
[0] = '\0';
322 game
.scenario
.authors
[0] = '\0';
323 game
.scenario
.players
= TRUE
;
324 game
.scenario
.startpos_nations
= FALSE
;
325 game
.scenario
.handmade
= FALSE
;
326 game
.scenario
.prevent_new_cities
= FALSE
;
327 game
.scenario
.lake_flooding
= TRUE
;
328 game
.scenario
.have_resources
= TRUE
;
329 game
.scenario
.ruleset_locked
= TRUE
;
330 game
.scenario
.save_random
= FALSE
;
331 game
.scenario
.allow_ai_type_fallback
= FALSE
;
333 game
.scenario_desc
.description
[0] = '\0';
335 /* Veteran system. */
339 game
.plr_bg_color
= NULL
;
342 /* All settings only used by the server (./server/ and ./ai/ */
343 sz_strlcpy(game
.server
.allow_take
, GAME_DEFAULT_ALLOW_TAKE
);
344 game
.server
.allowed_city_names
= GAME_DEFAULT_ALLOWED_CITY_NAMES
;
345 game
.server
.aqueductloss
= GAME_DEFAULT_AQUEDUCTLOSS
;
346 game
.server
.auto_ai_toggle
= GAME_DEFAULT_AUTO_AI_TOGGLE
;
347 game
.server
.autoattack
= GAME_DEFAULT_AUTOATTACK
;
348 game
.server
.barbarianrate
= GAME_DEFAULT_BARBARIANRATE
;
349 game
.server
.civilwarsize
= GAME_DEFAULT_CIVILWARSIZE
;
350 game
.server
.connectmsg
[0] = '\0';
351 game
.server
.conquercost
= GAME_DEFAULT_CONQUERCOST
;
352 game
.server
.contactturns
= GAME_DEFAULT_CONTACTTURNS
;
353 for (i
= 0; i
< DEBUG_LAST
; i
++) {
354 game
.server
.debug
[i
] = FALSE
;
356 sz_strlcpy(game
.server
.demography
, GAME_DEFAULT_DEMOGRAPHY
);
357 game
.server
.diplchance
= GAME_DEFAULT_DIPLCHANCE
;
358 game
.server
.diplbulbcost
= GAME_DEFAULT_DIPLBULBCOST
;
359 game
.server
.diplgoldcost
= GAME_DEFAULT_DIPLGOLDCOST
;
360 game
.server
.dispersion
= GAME_DEFAULT_DISPERSION
;
361 game
.server
.endspaceship
= GAME_DEFAULT_END_SPACESHIP
;
362 game
.server
.end_turn
= GAME_DEFAULT_END_TURN
;
363 game
.server
.event_cache
.chat
= GAME_DEFAULT_EVENT_CACHE_CHAT
;
364 game
.server
.event_cache
.info
= GAME_DEFAULT_EVENT_CACHE_INFO
;
365 game
.server
.event_cache
.max_size
= GAME_DEFAULT_EVENT_CACHE_MAX_SIZE
;
366 game
.server
.event_cache
.turns
= GAME_DEFAULT_EVENT_CACHE_TURNS
;
367 game
.server
.foggedborders
= GAME_DEFAULT_FOGGEDBORDERS
;
368 game
.server
.fogofwar_old
= game
.info
.fogofwar
;
369 game
.server
.last_updated_year
= FALSE
;
370 game
.server
.freecost
= GAME_DEFAULT_FREECOST
;
371 game
.server
.homecaughtunits
= GAME_DEFAULT_HOMECAUGHTUNITS
;
372 game
.server
.kick_time
= GAME_DEFAULT_KICK_TIME
;
373 game
.server
.killunhomed
= GAME_DEFAULT_KILLUNHOMED
;
374 game
.server
.maxconnectionsperhost
= GAME_DEFAULT_MAXCONNECTIONSPERHOST
;
375 game
.server
.last_ping
= 0;
376 game
.server
.max_players
= GAME_DEFAULT_MAX_PLAYERS
;
377 game
.server
.meta_info
.user_message
[0] = '\0';
378 /* Do not clear meta_info.type here as it's already set to correct value */
379 game
.server
.mgr_distance
= GAME_DEFAULT_MGR_DISTANCE
;
380 game
.server
.mgr_foodneeded
= GAME_DEFAULT_MGR_FOODNEEDED
;
381 game
.server
.mgr_nationchance
= GAME_DEFAULT_MGR_NATIONCHANCE
;
382 game
.server
.mgr_turninterval
= GAME_DEFAULT_MGR_TURNINTERVAL
;
383 game
.server
.mgr_worldchance
= GAME_DEFAULT_MGR_WORLDCHANCE
;
384 game
.server
.migration
= GAME_DEFAULT_MIGRATION
;
385 game
.server
.trait_dist
= GAME_DEFAULT_TRAIT_DIST_MODE
;
386 game
.server
.min_players
= GAME_DEFAULT_MIN_PLAYERS
;
387 game
.server
.natural_city_names
= GAME_DEFAULT_NATURALCITYNAMES
;
388 game
.server
.plrcolormode
= GAME_DEFAULT_PLRCOLORMODE
;
389 game
.server
.netwait
= GAME_DEFAULT_NETWAIT
;
390 game
.server
.occupychance
= GAME_DEFAULT_OCCUPYCHANCE
;
391 game
.server
.onsetbarbarian
= GAME_DEFAULT_ONSETBARBARIAN
;
392 game
.server
.phase_mode_stored
= GAME_DEFAULT_PHASE_MODE
;
393 game
.server
.pingtime
= GAME_DEFAULT_PINGTIME
;
394 game
.server
.pingtimeout
= GAME_DEFAULT_PINGTIMEOUT
;
395 game
.server
.razechance
= GAME_DEFAULT_RAZECHANCE
;
396 game
.server
.revealmap
= GAME_DEFAULT_REVEALMAP
;
397 game
.server
.revolution_length
= GAME_DEFAULT_REVOLUTION_LENGTH
;
398 if (!keep_ruleset_value
) {
399 sz_strlcpy(game
.server
.rulesetdir
, GAME_DEFAULT_RULESETDIR
);
401 game
.server
.save_compress_level
= GAME_DEFAULT_COMPRESS_LEVEL
;
402 game
.server
.save_compress_type
= GAME_DEFAULT_COMPRESS_TYPE
;
403 sz_strlcpy(game
.server
.save_name
, GAME_DEFAULT_SAVE_NAME
);
404 game
.server
.save_nturns
= GAME_DEFAULT_SAVETURNS
;
405 game
.server
.save_options
.save_known
= TRUE
;
406 game
.server
.save_options
.save_private_map
= TRUE
;
407 game
.server
.save_options
.save_starts
= TRUE
;
408 game
.server
.savepalace
= GAME_DEFAULT_SAVEPALACE
;
409 game
.server
.scorelog
= GAME_DEFAULT_SCORELOG
;
410 game
.server
.scoreloglevel
= GAME_DEFAULT_SCORELOGLEVEL
;
411 game
.server
.scoreturn
= GAME_DEFAULT_SCORETURN
- 1;
412 game
.server
.seed
= GAME_DEFAULT_SEED
;
413 sz_strlcpy(game
.server
.start_units
, GAME_DEFAULT_START_UNITS
);
414 game
.server
.start_year
= GAME_START_YEAR
;
415 game
.server
.tcptimeout
= GAME_DEFAULT_TCPTIMEOUT
;
416 game
.server
.techlost_donor
= GAME_DEFAULT_TECHLOST_DONOR
;
417 game
.server
.techlost_recv
= GAME_DEFAULT_TECHLOST_RECV
;
418 game
.server
.techpenalty
= GAME_DEFAULT_TECHPENALTY
;
419 game
.server
.timeoutaddenemymove
= GAME_DEFAULT_TIMEOUTADDEMOVE
;
420 game
.server
.timeoutcounter
= GAME_DEFAULT_TIMEOUTCOUNTER
;
421 game
.server
.timeoutinc
= GAME_DEFAULT_TIMEOUTINC
;
422 game
.server
.timeoutincmult
= GAME_DEFAULT_TIMEOUTINCMULT
;
423 game
.server
.timeoutint
= GAME_DEFAULT_TIMEOUTINT
;
424 game
.server
.timeoutintinc
= GAME_DEFAULT_TIMEOUTINTINC
;
425 game
.server
.turnblock
= GAME_DEFAULT_TURNBLOCK
;
426 game
.server
.unitwaittime
= GAME_DEFAULT_UNITWAITTIME
;
427 game
.server
.plr_colors
= NULL
;
429 /* Client side takes care of itself in client_main() */
433 /****************************************************************************
434 Initialise all game settings.
436 The variables are listed in alphabetical order.
437 ****************************************************************************/
438 void game_init(bool keep_ruleset_value
)
440 game_defaults(keep_ruleset_value
);
442 map_init(&wld
.map
, is_server());
448 universal_found_functions_init();
451 /****************************************************************************
452 Initialize map-specific parts of the game structure. Maybe these should
453 be moved into the map structure?
454 ****************************************************************************/
455 void game_map_init(void)
457 /* FIXME: it's not clear where these values should be initialized. It
458 * can't be done in game_init because the map isn't created yet. Maybe it
459 * should be done in the mapgen code or in the maphand code. It should
460 * surely be called when the map is generated. */
461 game
.info
.warminglevel
= (map_num_tiles() + 499) / 500;
462 game
.info
.coolinglevel
= (map_num_tiles() + 499) / 500;
465 /***************************************************************
466 Frees all memory of the game.
467 ***************************************************************/
471 map_free(&(wld
.map
));
472 free_city_map_index();
480 /***************************************************************
481 Do all changes to change view, and not full
482 game_free()/game_init().
483 ***************************************************************/
484 void game_reset(void)
490 /* Reset the players infos. */
491 players_iterate(pplayer
) {
492 player_clear(pplayer
, FALSE
);
493 } players_iterate_end
;
495 map_free(&(wld
.map
));
496 free_city_map_index();
499 map_init(&wld
.map
, FALSE
);
505 /***************************************************************
506 Initialize the objects which will read from a ruleset.
507 ***************************************************************/
508 void game_ruleset_init(void)
510 nation_sets_groups_init();
511 ruleset_cache_init();
512 disaster_types_init();
515 trade_route_types_init();
524 user_unit_class_flags_init();
525 user_unit_type_flags_init();
526 user_terrain_flags_init();
527 user_extra_flags_init();
529 user_tech_flags_init();
533 game
.server
.luadata
= NULL
;
534 game
.server
.ruledit
.nationlist
= NULL
;
535 game
.server
.ruledit
.embedded_nations
= NULL
;
536 game
.server
.ruledit
.embedded_nations_count
= 0;
537 game
.server
.ruledit
.allowed_govs
= NULL
;
538 game
.server
.ruledit
.allowed_terrains
= NULL
;
539 game
.server
.ruledit
.allowed_styles
= NULL
;
540 game
.server
.ruledit
.nc_agovs
= NULL
;
541 game
.server
.ruledit
.nc_aterrs
= NULL
;
542 game
.server
.ruledit
.nc_astyles
= NULL
;
543 game
.server
.ruledit
.ag_count
= 0;
544 game
.server
.ruledit
.at_count
= 0;
545 game
.server
.ruledit
.as_count
= 0;
549 /***************************************************************
550 Frees all memory which in objects which are read from a ruleset.
551 ***************************************************************/
552 void game_ruleset_free(void)
556 CALL_FUNC_EACH_AI(units_ruleset_close
);
558 /* Clear main structures which can points to the ruleset dependent
560 players_iterate(pplayer
) {
561 player_ruleset_close(pplayer
);
562 } players_iterate_end
;
563 game
.government_during_revolution
= NULL
;
571 unit_type_flags_free();
572 unit_class_flags_free();
573 role_unit_precalcs_free();
582 disaster_types_free();
584 user_tech_flags_free();
586 user_terrain_flags_free();
587 ruleset_cache_free();
588 nation_sets_groups_free();
591 /* Destroy the default veteran system. */
592 veteran_system_destroy(game
.veteran
);
596 if (game
.plr_bg_color
!= NULL
) {
597 rgbcolor_destroy(game
.plr_bg_color
);
598 game
.plr_bg_color
= NULL
;
602 if (game
.server
.luadata
!= NULL
) {
603 secfile_destroy(game
.server
.luadata
);
605 if (game
.server
.ruledit
.description_file
!= NULL
) {
606 free(game
.server
.ruledit
.description_file
);
607 game
.server
.ruledit
.description_file
= NULL
;
609 if (game
.server
.ruledit
.nationlist
!= NULL
) {
610 free(game
.server
.ruledit
.nationlist
);
611 game
.server
.ruledit
.nationlist
= NULL
;
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
]);
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
]);
624 free(game
.server
.ruledit
.allowed_govs
);
625 game
.server
.ruledit
.allowed_govs
= NULL
;
626 game
.server
.ruledit
.nc_agovs
= NULL
;
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
]);
632 free(game
.server
.ruledit
.allowed_terrains
);
633 game
.server
.ruledit
.allowed_terrains
= NULL
;
634 game
.server
.ruledit
.nc_aterrs
= NULL
;
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
]);
640 free(game
.server
.ruledit
.allowed_styles
);
641 game
.server
.ruledit
.allowed_styles
= NULL
;
642 game
.server
.ruledit
.nc_astyles
= NULL
;
647 for (i
= 0; i
< MAX_CALENDAR_FRAGMENTS
; i
++) {
648 game
.calendar
.calendar_fragment_name
[i
][0] = '\0';
651 if (game
.ruleset_summary
!= NULL
) {
652 free(game
.ruleset_summary
);
653 game
.ruleset_summary
= NULL
;
656 if (game
.ruleset_description
!= NULL
) {
657 free(game
.ruleset_description
);
658 game
.ruleset_description
= NULL
;
661 if (game
.ruleset_capabilities
!= NULL
) {
662 free(game
.ruleset_capabilities
);
663 game
.ruleset_capabilities
= NULL
;
667 /***************************************************************
668 Initialize wonder information.
669 ***************************************************************/
670 void initialize_globals(void)
672 players_iterate(pplayer
) {
673 city_list_iterate(pplayer
->cities
, pcity
) {
674 city_built_iterate(pcity
, pimprove
) {
675 if (is_wonder(pimprove
)) {
676 if (is_great_wonder(pimprove
)) {
677 game
.info
.great_wonder_owners
[improvement_index(pimprove
)] =
678 player_number(pplayer
);
680 pplayer
->wonders
[improvement_index(pimprove
)] = pcity
->id
;
682 } city_built_iterate_end
;
683 } city_list_iterate_end
;
684 } players_iterate_end
;
687 /**************************************************************************
688 Return TRUE if it is this player's phase.
689 NB: The meaning of the 'phase' argument must match its use in the
690 function begin_turn() in server/srv_main.c.
691 NB: The phase mode PMT_TEAMS_ALTERNATE assumes that every player is
692 on a team, i.e. that pplayer->team is never NULL.
693 **************************************************************************/
694 bool is_player_phase(const struct player
*pplayer
, int phase
)
696 switch (game
.info
.phase_mode
) {
700 case PMT_PLAYERS_ALTERNATE
:
701 return player_number(pplayer
) == phase
;
703 case PMT_TEAMS_ALTERNATE
:
704 fc_assert_ret_val(NULL
!= pplayer
->team
, FALSE
);
705 return team_number(pplayer
->team
) == phase
;
711 fc_assert_msg(FALSE
, "Unrecognized phase mode %d in is_player_phase().",
716 /****************************************************************************
717 Return a prettily formatted string containing the population text. The
718 population is passed in as the number of citizens, in unit
719 (tens/hundreds/thousands...) defined in cities.ruleset.
720 ****************************************************************************/
721 const char *population_to_text(int thousand_citizen
)
723 /* big_int_to_text can't handle negative values, and in any case we'd
724 * better not have a negative population. */
725 fc_assert_ret_val(thousand_citizen
>= 0, NULL
);
726 return big_int_to_text(thousand_citizen
, game
.info
.pop_report_zeroes
- 1);
729 /**************************************************************************
730 Return a string containing the save year.
731 **************************************************************************/
732 static char *year_suffix(void)
734 static char buf
[MAX_LEN_NAME
];
736 char safe_year_suffix
[MAX_LEN_NAME
];
737 const char *max
= safe_year_suffix
+ MAX_LEN_NAME
- 1;
738 char *c
= safe_year_suffix
;
740 if (game
.info
.year
< 0) {
741 suffix
= game
.calendar
.negative_year_label
;
743 suffix
= game
.calendar
.positive_year_label
;
746 /* Remove all non alphanumeric characters from the year suffix. */
747 for (; '\0' != *suffix
&& c
< max
; suffix
++) {
748 if (fc_isalnum(*suffix
)) {
754 fc_snprintf(buf
, sizeof(buf
), "%s", safe_year_suffix
);
759 /**************************************************************************
760 Generate a default save file name and place it in the provided buffer.
761 Within the name the following custom formats are allowed:
765 %T = <game.info.turn>
766 %Y = <game.info.year>
769 'freeciv-T%04T-Y%+04Y-%R' => 'freeciv-T0099-Y-0050-manual'
770 => 'freeciv-T0100-Y00001-auto'
772 Returns the number of characters written, or the number of characters
773 that would have been written if truncation occurs.
775 NB: If you change the format definition, be sure to update the above
776 function comment and the help text for the 'savename' setting.
777 **************************************************************************/
778 int generate_save_name(const char *format
, char *buf
, int buflen
,
781 struct cf_sequence sequences
[] = {
782 cf_str_seq('R', (reason
== NULL
) ? "auto" : reason
),
783 cf_str_seq('S', year_suffix()),
784 { 0 }, { 0 }, /* Works for both gcc and tcc */
788 cf_int_seq('T', game
.info
.turn
, &sequences
[2]);
789 cf_int_seq('Y', game
.info
.year
, &sequences
[3]);
791 fc_vsnprintcf(buf
, buflen
, format
, sequences
, -1);
793 if (0 == strcmp(format
, buf
)) {
794 /* Use the default savename if 'format' does not contain
795 * printf information. */
798 fc_snprintf(savename
, sizeof(savename
), "%s-T%%04T-Y%%05Y-%%R",
800 fc_vsnprintcf(buf
, buflen
, savename
, sequences
, -1);
803 log_debug("save name generated from '%s': %s", format
, buf
);
808 /**************************************************************************
809 Initialize user flag.
810 **************************************************************************/
811 void user_flag_init(struct user_flag
*flag
)
814 flag
->helptxt
= NULL
;
817 /**************************************************************************
819 **************************************************************************/
820 void user_flag_free(struct user_flag
*flag
)
822 if (flag
->name
!= NULL
) {
826 if (flag
->helptxt
!= NULL
) {
827 FC_FREE(flag
->helptxt
);
828 flag
->helptxt
= NULL
;
832 /****************************************************************************
833 Return timeout value for the current turn.
834 ****************************************************************************/
835 int current_turn_timeout(void)
837 if (game
.info
.turn
== 1 && game
.info
.first_timeout
!= -1) {
838 return game
.info
.first_timeout
;
840 return game
.info
.timeout
;