1 /***********************************************************************
2 Freeciv - Copyright (C) 1996-2004 - The Freeciv Project
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>
26 #include "string_vector.h"
41 #include "stdinhand.h"
43 /* The following classes determine what can be changed when.
44 * Actually, some of them have the same "changeability", but
45 * different types are separated here in case they have
47 * Also, SSET_GAME_INIT/SSET_RULES separate the two sections
48 * of server settings sent to the client.
49 * See the settings[] array and setting_is_changeable() for what
50 * these correspond to and explanations.
64 typedef bool (*bool_validate_func_t
) (bool value
, struct connection
*pconn
,
66 size_t reject_msg_len
);
67 typedef bool (*int_validate_func_t
) (int value
, struct connection
*pconn
,
69 size_t reject_msg_len
);
70 typedef bool (*string_validate_func_t
) (const char * value
,
71 struct connection
*pconn
,
73 size_t reject_msg_len
);
74 typedef bool (*enum_validate_func_t
) (int value
, struct connection
*pconn
,
76 size_t reject_msg_len
);
77 typedef bool (*bitwise_validate_func_t
) (unsigned value
,
78 struct connection
*pconn
,
80 size_t reject_msg_len
);
82 typedef void (*action_callback_func_t
) (const struct setting
*pset
);
83 typedef const char *(*help_callback_func_t
) (const struct setting
*pset
);
84 typedef const struct sset_val_name
* (*val_name_func_t
) (int value
);
88 enum sset_class sclass
;
90 /* What access level viewing and setting the setting requires. */
91 enum cmdlevel access_level_read
;
92 enum cmdlevel access_level_write
;
95 * Should be less than 42 chars (?), or shorter if the values may
96 * have more than about 4 digits. Don't put "." on the end.
98 const char *short_help
;
101 * May be empty string, if short_help is sufficient. Need not
102 * include embedded newlines (but may, for formatting); lines will
103 * be wrapped (and indented) automatically. Should have punctuation
104 * etc, and should end with a "."
106 const char *extra_help
;
109 const help_callback_func_t help_func
;
111 enum sset_type stype
;
112 enum sset_category scategory
;
113 enum sset_level slevel
;
116 * About the *_validate functions: If the function is non-NULL, it
117 * is called with the new value, and returns whether the change is
118 * legal. The char * is an error message in the case of reject.
125 const bool default_value
;
126 const bool_validate_func_t validate
;
127 const val_name_func_t name
;
133 const int default_value
;
136 const int_validate_func_t validate
;
139 /*** string part ***/
142 const char *const default_value
;
143 const size_t value_size
;
144 const string_validate_func_t validate
;
147 /*** enumerator part ***/
150 const int store_size
;
151 const int default_value
;
152 const enum_validate_func_t validate
;
153 const val_name_func_t name
;
156 /*** bitwise part ***/
158 unsigned *const pvalue
;
159 const unsigned default_value
;
160 const bitwise_validate_func_t validate
;
161 const val_name_func_t name
;
166 /* action function */
167 const action_callback_func_t action
;
169 /* ruleset lock for game settings */
172 /* It's not "default", even if value is the same as default */
173 enum setting_default_level setdef
;
178 struct setting_list
*level
[OLEVELS_NUM
];
179 } setting_sorted
= { .init
= FALSE
};
181 static bool setting_ruleset_one(struct section_file
*file
,
182 const char *name
, const char *path
);
183 static void setting_game_set(struct setting
*pset
, bool init
);
184 static void setting_game_free(struct setting
*pset
);
185 static void setting_game_restore(struct setting
*pset
);
187 static void settings_list_init(void);
188 static void settings_list_free(void);
189 int settings_list_cmp(const struct setting
*const *pset1
,
190 const struct setting
*const *pset2
);
192 #define settings_snprintf(_buf, _buf_len, format, ...) \
193 if (_buf != NULL) { \
194 fc_snprintf(_buf, _buf_len, format, ## __VA_ARGS__); \
197 static bool set_enum_value(struct setting
*pset
, int val
);
199 /****************************************************************************
200 Enumerator name accessors.
202 Important note about compatibility:
203 1) you cannot modify the support name of an existant value. However, in a
204 developpement, you can modify it if it wasn't included in any stable
206 2) Take care of modifiying the pretty name of an existant value: make sure
207 to modify the help texts which are using it.
208 ****************************************************************************/
210 #define NAME_CASE(_val, _support, _pretty) \
213 static const struct sset_val_name name = { _support, _pretty }; \
217 /****************************************************************************
218 Map size definition setting names accessor. This setting has an
219 hard-coded depedence in "server/meta.c".
220 ****************************************************************************/
221 static const struct sset_val_name
*mapsize_name(int mapsize
)
224 NAME_CASE(MAPSIZE_FULLSIZE
, "FULLSIZE", N_("Number of tiles"));
225 NAME_CASE(MAPSIZE_PLAYER
, "PLAYER", N_("Tiles per player"));
226 NAME_CASE(MAPSIZE_XYSIZE
, "XYSIZE", N_("Width and height"));
231 /****************************************************************************
232 Topology setting names accessor.
233 ****************************************************************************/
234 static const struct sset_val_name
*topology_name(int topology_bit
)
236 switch (1 << topology_bit
) {
237 NAME_CASE(TF_WRAPX
, "WRAPX", N_("Wrap East-West"));
238 NAME_CASE(TF_WRAPY
, "WRAPY", N_("Wrap North-South"));
239 NAME_CASE(TF_ISO
, "ISO", N_("Isometric"));
240 NAME_CASE(TF_HEX
, "HEX", N_("Hexagonal"));
245 /****************************************************************************
246 Generator setting names accessor.
247 ****************************************************************************/
248 static const struct sset_val_name
*generator_name(int generator
)
251 NAME_CASE(MAPGEN_SCENARIO
, "SCENARIO", N_("Scenario map"));
252 NAME_CASE(MAPGEN_RANDOM
, "RANDOM", N_("Fully random height"));
253 NAME_CASE(MAPGEN_FRACTAL
, "FRACTAL", N_("Pseudo-fractal height"));
254 NAME_CASE(MAPGEN_ISLAND
, "ISLAND", N_("Island-based"));
255 NAME_CASE(MAPGEN_FAIR
, "FAIR", N_("Fair islands"));
256 NAME_CASE(MAPGEN_FRACTURE
, "FRACTURE", N_("Fracture map"));
261 /****************************************************************************
262 Start position setting names accessor.
263 ****************************************************************************/
264 static const struct sset_val_name
*startpos_name(int startpos
)
267 NAME_CASE(MAPSTARTPOS_DEFAULT
, "DEFAULT",
268 N_("Generator's choice"));
269 NAME_CASE(MAPSTARTPOS_SINGLE
, "SINGLE",
270 N_("One player per continent"));
271 NAME_CASE(MAPSTARTPOS_2or3
, "2or3",
272 N_("Two or three players per continent"));
273 NAME_CASE(MAPSTARTPOS_ALL
, "ALL",
274 N_("All players on a single continent"));
275 NAME_CASE(MAPSTARTPOS_VARIABLE
, "VARIABLE",
276 N_("Depending on size of continents"));
281 /****************************************************************************
282 Team placement setting names accessor.
283 ****************************************************************************/
284 static const struct sset_val_name
*teamplacement_name(int team_placement
)
286 switch (team_placement
) {
287 NAME_CASE(TEAM_PLACEMENT_DISABLED
, "DISABLED",
289 NAME_CASE(TEAM_PLACEMENT_CLOSEST
, "CLOSEST",
290 N_("As close as possible"));
291 NAME_CASE(TEAM_PLACEMENT_CONTINENT
, "CONTINENT",
292 N_("On the same continent"));
293 NAME_CASE(TEAM_PLACEMENT_HORIZONTAL
, "HORIZONTAL",
294 N_("Horizontal placement"));
295 NAME_CASE(TEAM_PLACEMENT_VERTICAL
, "VERTICAL",
296 N_("Vertical placement"));
301 /****************************************************************************
302 Persistentready setting names accessor.
303 ****************************************************************************/
304 static const struct sset_val_name
*persistentready_name(int persistent_ready
)
306 switch (persistent_ready
) {
307 NAME_CASE(PERSISTENTR_DISABLED
, "DISABLED",
309 NAME_CASE(PERSISTENTR_CONNECTED
, "CONNECTED",
310 N_("As long as connected"));
316 /****************************************************************************
317 Victory conditions setting names accessor.
318 ****************************************************************************/
319 static const struct sset_val_name
*victory_conditions_name(int condition_bit
)
321 switch (condition_bit
) {
322 NAME_CASE(VC_SPACERACE
, "SPACERACE", N_("Spacerace"));
323 NAME_CASE(VC_ALLIED
, "ALLIED", N_("Allied victory"));
324 NAME_CASE(VC_CULTURE
, "CULTURE", N_("Culture victory"));
330 /****************************************************************************
331 Autosaves setting names accessor.
332 ****************************************************************************/
333 static const struct sset_val_name
*autosaves_name(int autosaves_bit
)
335 switch (autosaves_bit
) {
336 NAME_CASE(AS_TURN
, "TURN", N_("New turn"));
337 NAME_CASE(AS_GAME_OVER
, "GAMEOVER", N_("Game over"));
338 NAME_CASE(AS_QUITIDLE
, "QUITIDLE", N_("No player connections"));
339 NAME_CASE(AS_INTERRUPT
, "INTERRUPT", N_("Server interrupted"));
340 NAME_CASE(AS_TIMER
, "TIMER", N_("Timer"));
346 /****************************************************************************
347 Borders setting names accessor.
348 ****************************************************************************/
349 static const struct sset_val_name
*borders_name(int borders
)
352 NAME_CASE(BORDERS_DISABLED
, "DISABLED", N_("Disabled"));
353 NAME_CASE(BORDERS_ENABLED
, "ENABLED", N_("Enabled"));
354 NAME_CASE(BORDERS_SEE_INSIDE
, "SEE_INSIDE",
355 N_("See everything inside borders"));
356 NAME_CASE(BORDERS_EXPAND
, "EXPAND",
357 N_("Borders expand to unknown, revealing tiles"));
362 /****************************************************************************
363 Trait distribution setting names accessor.
364 ****************************************************************************/
365 static const struct sset_val_name
*trait_dist_name(int trait_dist
)
367 switch (trait_dist
) {
368 NAME_CASE(TDM_FIXED
, "FIXED", N_("Fixed"));
369 NAME_CASE(TDM_EVEN
, "EVEN", N_("Even"));
374 /****************************************************************************
375 Player colors configuration setting names accessor.
376 ****************************************************************************/
377 static const struct sset_val_name
*plrcol_name(int plrcol
)
380 NAME_CASE(PLRCOL_PLR_ORDER
, "PLR_ORDER", N_("Per-player, in order"));
381 NAME_CASE(PLRCOL_PLR_RANDOM
, "PLR_RANDOM", N_("Per-player, random"));
382 NAME_CASE(PLRCOL_PLR_SET
, "PLR_SET", N_("Set manually"));
383 NAME_CASE(PLRCOL_TEAM_ORDER
, "TEAM_ORDER", N_("Per-team, in order"));
384 NAME_CASE(PLRCOL_NATION_ORDER
, "NATION_ORDER", N_("Per-nation, in order"));
389 /****************************************************************************
390 Happyborders setting names accessor.
391 ****************************************************************************/
392 static const struct sset_val_name
*happyborders_name(int happyborders
)
394 switch (happyborders
) {
395 NAME_CASE(HB_DISABLED
, "DISABLED", N_("Borders are not helping"));
396 NAME_CASE(HB_NATIONAL
, "NATIONAL", N_("Happy within own borders"));
397 NAME_CASE(HB_ALLIANCE
, "ALLIED", N_("Happy within allied borders"));
402 /****************************************************************************
403 Diplomacy setting names accessor.
404 ****************************************************************************/
405 static const struct sset_val_name
*diplomacy_name(int diplomacy
)
408 NAME_CASE(DIPLO_FOR_ALL
, "ALL", N_("Enabled for everyone"));
409 NAME_CASE(DIPLO_FOR_HUMANS
, "HUMAN",
410 N_("Only allowed between human players"));
411 NAME_CASE(DIPLO_FOR_AIS
, "AI", N_("Only allowed between AI players"));
412 NAME_CASE(DIPLO_NO_AIS
, "NOAI", N_("Only allowed when human involved"));
413 NAME_CASE(DIPLO_NO_MIXED
, "NOMIXED", N_("Only allowed between two humans, or two AI players"));
414 NAME_CASE(DIPLO_FOR_TEAMS
, "TEAM", N_("Restricted to teams"));
415 NAME_CASE(DIPLO_DISABLED
, "DISABLED", N_("Disabled for everyone"));
420 /****************************************************************************
421 City names setting names accessor.
422 ****************************************************************************/
423 static const struct sset_val_name
*citynames_name(int citynames
)
426 NAME_CASE(CNM_NO_RESTRICTIONS
, "NO_RESTRICTIONS", N_("No restrictions"));
427 NAME_CASE(CNM_PLAYER_UNIQUE
, "PLAYER_UNIQUE", N_("Unique to a player"));
428 NAME_CASE(CNM_GLOBAL_UNIQUE
, "GLOBAL_UNIQUE", N_("Globally unique"));
429 NAME_CASE(CNM_NO_STEALING
, "NO_STEALING", N_("No city name stealing"));
434 /****************************************************************************
435 Barbarian setting names accessor.
436 ****************************************************************************/
437 static const struct sset_val_name
*barbarians_name(int barbarians
)
439 switch (barbarians
) {
440 NAME_CASE(BARBS_DISABLED
, "DISABLED", N_("No barbarians"));
441 NAME_CASE(BARBS_HUTS_ONLY
, "HUTS_ONLY", N_("Only in huts"));
442 NAME_CASE(BARBS_NORMAL
, "NORMAL", N_("Normal rate of appearance"));
443 NAME_CASE(BARBS_FREQUENT
, "FREQUENT", N_("Frequent barbarian uprising"));
444 NAME_CASE(BARBS_HORDES
, "HORDES", N_("Raging hordes"));
449 /****************************************************************************
450 Revolution length type setting names accessor.
451 ****************************************************************************/
452 static const struct sset_val_name
*revolentype_name(int revolentype
)
454 switch (revolentype
) {
455 NAME_CASE(REVOLEN_FIXED
, "FIXED", N_("Fixed to 'revolen' turns"));
456 NAME_CASE(REVOLEN_RANDOM
, "RANDOM", N_("Randomly 1-'revolen' turns"));
457 NAME_CASE(REVOLEN_QUICKENING
, "QUICKENING", N_("First time 'revolen', then always quicker"));
458 NAME_CASE(REVOLEN_RANDQUICK
, "RANDQUICK", N_("Random, max always quicker"));
463 /****************************************************************************
464 Revealmap setting names accessor.
465 ****************************************************************************/
466 static const struct sset_val_name
*revealmap_name(int bit
)
469 NAME_CASE(REVEAL_MAP_START
, "START", N_("Reveal map at game start"));
470 NAME_CASE(REVEAL_MAP_DEAD
, "DEAD", N_("Unfog map for dead players"));
475 /****************************************************************************
476 Airlifting style setting names accessor.
477 ****************************************************************************/
478 static const struct sset_val_name
*airliftingstyle_name(int bit
)
481 NAME_CASE(AIRLIFTING_ALLIED_SRC
, "FROM_ALLIES",
482 N_("Allows units to be airlifted from allied cities"));
483 NAME_CASE(AIRLIFTING_ALLIED_DEST
, "TO_ALLIES",
484 N_("Allows units to be airlifted to allied cities"));
485 NAME_CASE(AIRLIFTING_UNLIMITED_SRC
, "SRC_UNLIMITED",
486 N_("Unlimited units from source city"));
487 NAME_CASE(AIRLIFTING_UNLIMITED_DEST
, "DEST_UNLIMITED",
488 N_("Unlimited units to destination city"));
493 /****************************************************************************
494 Phase mode names accessor.
495 ****************************************************************************/
496 static const struct sset_val_name
*phasemode_name(int phasemode
)
499 NAME_CASE(PMT_CONCURRENT
, "ALL", N_("All players move concurrently"));
500 NAME_CASE(PMT_PLAYERS_ALTERNATE
,
501 "PLAYER", N_("All players alternate movement"));
502 NAME_CASE(PMT_TEAMS_ALTERNATE
, "TEAM", N_("Team alternate movement"));
507 /****************************************************************************
508 Scorelog level names accessor.
509 ****************************************************************************/
510 static const struct sset_val_name
*
511 scoreloglevel_name(enum scorelog_level sl_level
)
514 NAME_CASE(SL_ALL
, "ALL", N_("All players"));
515 NAME_CASE(SL_HUMANS
, "HUMANS", N_("Human players only"));
520 /****************************************************************************
521 Savegame compress type names accessor.
522 ****************************************************************************/
523 static const struct sset_val_name
*
524 compresstype_name(enum fz_method compresstype
)
526 switch (compresstype
) {
527 NAME_CASE(FZ_PLAIN
, "PLAIN", N_("No compression"));
528 #ifdef FREECIV_HAVE_LIBZ
529 NAME_CASE(FZ_ZLIB
, "LIBZ", N_("Using zlib (gzip format)"));
531 #ifdef FREECIV_HAVE_LIBBZ2
532 NAME_CASE(FZ_BZIP2
, "BZIP2", N_("Using bzip2 (deprecated)"));
534 #ifdef FREECIV_HAVE_LIBLZMA
535 NAME_CASE(FZ_XZ
, "XZ", N_("Using xz"));
541 /****************************************************************************
542 Names accessor for boolean settings (disable/enable).
543 ****************************************************************************/
544 static const struct sset_val_name
*bool_name(int enable
)
547 NAME_CASE(FALSE
, "DISABLED", N_("disabled"));
548 NAME_CASE(TRUE
, "ENABLED", N_("enabled"));
555 /*************************************************************************
556 Help callback functions.
557 *************************************************************************/
559 /*************************************************************************
560 Help about phasemode setting
561 *************************************************************************/
562 static const char *phasemode_help(const struct setting
*pset
)
564 static char pmhelp
[512];
566 /* Translated here */
567 fc_snprintf(pmhelp
, sizeof(pmhelp
),
568 _("This setting controls whether players may make "
569 "moves at the same time during a turn. Change "
570 "in setting takes effect next turn. Currently, at least "
571 "to the end of this turn, mode is \"%s\"."),
572 phasemode_name(game
.info
.phase_mode
)->pretty
);
577 /*************************************************************************
578 Help about huts setting
579 *************************************************************************/
580 static const char *huts_help(const struct setting
*pset
)
582 if (wld
.map
.server
.huts_absolute
>= 0) {
583 static char hutshelp
[512];
585 /* Translated here */
586 fc_snprintf(hutshelp
, sizeof(hutshelp
),
588 "Currently this is being overridden by absolute "
589 "number of huts set to %d. Explicitly set this "
590 "setting again to make it take effect instead."),
591 _(pset
->extra_help
), wld
.map
.server
.huts_absolute
);
596 return pset
->extra_help
;
599 /*************************************************************************
600 Action callback functions.
601 *************************************************************************/
603 /*************************************************************************
604 (De)initialze the score log.
605 *************************************************************************/
606 static void scorelog_action(const struct setting
*pset
)
608 if (*pset
->boolean
.pvalue
) {
609 log_civ_score_init();
611 log_civ_score_free();
615 /*************************************************************************
616 Create the selected number of AI's.
617 *************************************************************************/
618 static void aifill_action(const struct setting
*pset
)
620 const char *msg
= aifill(*pset
->integer
.pvalue
);
622 log_normal(_("Warning: aifill not met: %s."), msg
);
623 notify_conn(NULL
, NULL
, E_SETTING
, ftc_server
,
624 _("Warning: aifill not met: %s."), msg
);
628 /*************************************************************************
629 Restrict to the selected nation set.
630 *************************************************************************/
631 static void nationset_action(const struct setting
*pset
)
633 /* If any player's existing selection is invalid, abort it */
634 players_iterate(pplayer
) {
635 if (pplayer
->nation
!= NULL
) {
636 if (!nation_is_in_current_set(pplayer
->nation
)) {
637 (void) player_set_nation(pplayer
, NO_NATION_SELECTED
);
638 send_player_info_c(pplayer
, game
.est_connections
);
641 } players_iterate_end
;
642 count_playable_nations();
643 (void) aifill(game
.info
.aifill
);
645 /* There might now be too many players for the available nations.
646 * Rather than getting rid of some players arbitrarily, we let the
647 * situation persist for all already-connected players; the server
648 * will simply refuse to start until someone reduces the number of
649 * players. This policy also avoids annoyance if nationset is
650 * accidentally and transiently set to an unintended value.
651 * (However, new connections will start out detached.) */
652 if (normal_player_count() > server
.playable_nations
) {
653 notify_conn(NULL
, NULL
, E_SETTING
, ftc_server
, "%s",
654 _("Warning: not enough nations in this nation set "
655 "for all current players."));
658 send_nation_availability(game
.est_connections
, TRUE
);
661 /*************************************************************************
662 Clear any user-set player colors in modes other than PLRCOL_PLR_SET.
663 *************************************************************************/
664 static void plrcol_action(const struct setting
*pset
)
666 if (!game_was_started()) {
667 if (read_enum_value(pset
) != PLRCOL_PLR_SET
) {
668 players_iterate(pplayer
) {
669 server_player_set_color(pplayer
, NULL
);
670 } players_iterate_end
;
672 /* Update clients with new color scheme. */
673 send_player_info_c(NULL
, NULL
);
677 /*************************************************************************
678 Toggle player AI status.
679 *************************************************************************/
680 static void autotoggle_action(const struct setting
*pset
)
682 if (*pset
->boolean
.pvalue
) {
683 players_iterate(pplayer
) {
684 if (is_human(pplayer
) && !pplayer
->is_connected
) {
685 toggle_ai_player_direct(NULL
, pplayer
);
686 send_player_info_c(pplayer
, game
.est_connections
);
688 } players_iterate_end
;
692 /*************************************************************************
693 Enact a change in the 'timeout' server setting immediately, if the game
695 *************************************************************************/
696 static void timeout_action(const struct setting
*pset
)
698 if (S_S_RUNNING
== server_state()) {
699 int timeout
= *pset
->integer
.pvalue
;
701 if (game
.info
.turn
!= 1 || game
.info
.first_timeout
== -1) {
702 /* This may cause the current turn to end immediately. */
703 game
.tinfo
.seconds_to_phasedone
= timeout
;
705 send_game_info(NULL
);
709 /*************************************************************************
710 Enact a change in the 'first_timeout' server setting immediately, if the game
712 *************************************************************************/
713 static void first_timeout_action(const struct setting
*pset
)
715 if (S_S_RUNNING
== server_state()) {
716 int timeout
= *pset
->integer
.pvalue
;
718 if (game
.info
.turn
== 1) {
719 /* This may cause the current turn to end immediately. */
721 game
.tinfo
.seconds_to_phasedone
= timeout
;
723 game
.tinfo
.seconds_to_phasedone
= game
.info
.timeout
;
726 send_game_info(NULL
);
730 /*************************************************************************
731 Clean out absolute number of huts when relative setting set.
732 *************************************************************************/
733 static void huts_action(const struct setting
*pset
)
735 wld
.map
.server
.huts_absolute
= -1;
738 /*************************************************************************
739 Topology setting changed.
740 *************************************************************************/
741 static void topology_action(const struct setting
*pset
)
743 struct packet_set_topology packet
;
745 packet
.topology_id
= *pset
->integer
.pvalue
;
747 conn_list_iterate(game
.est_connections
, pconn
) {
748 send_packet_set_topology(pconn
, &packet
);
749 } conn_list_iterate_end
;
752 /*************************************************************************
753 Update metaserver message string from changed user meta server message
755 *************************************************************************/
756 static void metamessage_action(const struct setting
*pset
)
758 /* Set the metaserver message based on the new meta server user message.
759 * An empty user metaserver message results in an automatic meta message.
760 * A non empty user meta message results in the user meta message. */
761 set_user_meta_message_string(pset
->string
.value
);
763 if (is_metaserver_open()) {
764 /* Update the meta server. */
765 send_server_info_to_metaserver(META_INFO
);
769 /*************************************************************************
770 Validation callback functions.
771 *************************************************************************/
773 /****************************************************************************
774 Verify the selected savename definition.
775 ****************************************************************************/
776 static bool savename_validate(const char *value
, struct connection
*caller
,
777 char *reject_msg
, size_t reject_msg_len
)
779 char buf
[MAX_LEN_PATH
];
781 generate_save_name(value
, buf
, sizeof(buf
), NULL
);
783 if (!is_safe_filename(buf
)) {
784 settings_snprintf(reject_msg
, reject_msg_len
,
785 _("Invalid save name definition: '%s' "
786 "(resolves to '%s')."), value
, buf
);
793 /****************************************************************************
794 Verify the value of the generator option (notably the MAPGEN_SCENARIO
796 ****************************************************************************/
797 static bool generator_validate(int value
, struct connection
*caller
,
798 char *reject_msg
, size_t reject_msg_len
)
800 if (map_is_empty()) {
801 if (MAPGEN_SCENARIO
== value
802 && (NULL
!= caller
|| !game
.scenario
.is_scenario
)) {
803 settings_snprintf(reject_msg
, reject_msg_len
,
804 _("You cannot disable the map generator."));
809 if (MAPGEN_SCENARIO
!= value
) {
810 settings_snprintf(reject_msg
, reject_msg_len
,
811 _("You cannot require a map generator "
812 "when a map is loaded."));
819 /****************************************************************************
820 Verify the name for the score log file.
821 ****************************************************************************/
823 static bool scorefile_validate(const char *value
, struct connection
*caller
,
824 char *reject_msg
, size_t reject_msg_len
)
826 if (!is_safe_filename(value
)) {
827 settings_snprintf(reject_msg
, reject_msg_len
,
828 _("Invalid score name definition: '%s'."), value
);
834 #endif /* !FREECIV_WEB */
836 /*************************************************************************
837 Verify that a given demography string is valid. See
839 *************************************************************************/
840 static bool demography_callback(const char *value
,
841 struct connection
*caller
,
843 size_t reject_msg_len
)
847 if (is_valid_demography(value
, &error
)) {
850 settings_snprintf(reject_msg
, reject_msg_len
,
851 _("Demography string validation failed at character: "
852 "'%c'. Try \"/help demography\"."), value
[error
]);
857 /*************************************************************************
858 Autosaves setting callback
859 *************************************************************************/
860 static bool autosaves_callback(unsigned value
, struct connection
*caller
,
861 char *reject_msg
, size_t reject_msg_len
)
863 if (S_S_RUNNING
== server_state()) {
864 if ((value
& (1 << AS_TIMER
))
865 && !(game
.server
.autosaves
& (1 << AS_TIMER
))) {
866 game
.server
.save_timer
= timer_renew(game
.server
.save_timer
,
867 TIMER_USER
, TIMER_ACTIVE
);
868 timer_start(game
.server
.save_timer
);
869 } else if (!(value
& (1 << AS_TIMER
))
870 && (game
.server
.autosaves
& (1 << AS_TIMER
))) {
871 timer_stop(game
.server
.save_timer
);
872 timer_destroy(game
.server
.save_timer
);
873 game
.server
.save_timer
= NULL
;
880 /*************************************************************************
881 Verify that a given allowtake string is valid. See
883 *************************************************************************/
884 static bool allowtake_callback(const char *value
,
885 struct connection
*caller
,
887 size_t reject_msg_len
)
889 int len
= strlen(value
), i
;
890 bool havecharacter_state
= FALSE
;
892 /* We check each character individually to see if it's valid. This
893 * does not check for duplicate entries.
895 * We also track the state of the machine. havecharacter_state is
896 * true if the preceeding character was a primary label, e.g.
897 * NHhAadb. It is false if the preceeding character was a modifier
898 * or if this is the first character. */
900 for (i
= 0; i
< len
; i
++) {
901 /* Check to see if the character is a primary label. */
902 if (strchr("HhAadbOo", value
[i
])) {
903 havecharacter_state
= TRUE
;
907 /* If we've already passed a primary label, check to see if the
908 * character is a modifier. */
909 if (havecharacter_state
&& strchr("1234", value
[i
])) {
910 havecharacter_state
= FALSE
;
914 /* Looks like the character was invalid. */
915 settings_snprintf(reject_msg
, reject_msg_len
,
916 _("Allowed take string validation failed at "
917 "character: '%c'. Try \"/help allowtake\"."),
922 /* All characters were valid. */
926 /*************************************************************************
927 Verify that a given startunits string is valid. See
928 game.server.start_units.
929 *************************************************************************/
930 static bool startunits_callback(const char *value
,
931 struct connection
*caller
,
933 size_t reject_msg_len
)
935 int len
= strlen(value
), i
;
936 Unit_Class_id first_role
;
937 bool firstnative
= FALSE
;
939 /* We check each character individually to see if it's valid. */
940 for (i
= 0; i
< len
; i
++) {
941 if (strchr("cwxksfdDaA", value
[i
])) {
945 /* Looks like the character was invalid. */
946 settings_snprintf(reject_msg
, reject_msg_len
,
947 _("Starting units string validation failed at "
948 "character '%c'. Try \"/help startunits\"."),
953 /* Check the first character to make sure it can use a startpos. */
954 first_role
= uclass_index(utype_class(get_role_unit(
955 crole_to_role_id(value
[0]), 0)));
956 terrain_type_iterate(pterrain
) {
957 if (terrain_has_flag(pterrain
, TER_STARTER
)
958 && BV_ISSET(pterrain
->native_to
, first_role
)) {
962 } terrain_type_iterate_end
;
965 /* Loading would cause an infinite loop hunting for a valid startpos. */
966 settings_snprintf(reject_msg
, reject_msg_len
,
967 _("The first starting unit must be native to at "
968 "least one \"Starter\" terrain. "
969 "Try \"/help startunits\"."));
973 /* Everything seems fine. */
977 /*************************************************************************
978 Verify that a given endturn is valid.
979 *************************************************************************/
980 static bool endturn_callback(int value
, struct connection
*caller
,
981 char *reject_msg
, size_t reject_msg_len
)
983 if (value
< game
.info
.turn
) {
984 /* Tried to set endturn earlier than current turn */
985 settings_snprintf(reject_msg
, reject_msg_len
,
986 _("Cannot set endturn earlier than current turn."));
992 /*************************************************************************
993 Verify that a given maxplayers is valid.
994 *************************************************************************/
995 static bool maxplayers_callback(int value
, struct connection
*caller
,
996 char *reject_msg
, size_t reject_msg_len
)
998 if (value
< player_count()) {
999 settings_snprintf(reject_msg
, reject_msg_len
,
1000 _("Number of players (%d) is higher than requested "
1001 "value (%d). Keeping old value."), player_count(),
1005 /* If any start positions are defined by a scenario, we can only
1006 * accommodate as many players as we have start positions. */
1007 if (0 < map_startpos_count() && value
> map_startpos_count()) {
1008 settings_snprintf(reject_msg
, reject_msg_len
,
1009 _("Requested value (%d) is greater than number of "
1010 "available start positions (%d). Keeping old value."),
1011 value
, map_startpos_count());
1018 /*************************************************************************
1019 Validate the 'nationset' server setting.
1020 *************************************************************************/
1021 static bool nationset_callback(const char *value
,
1022 struct connection
*caller
,
1024 size_t reject_msg_len
)
1026 if (strlen(value
) == 0) {
1028 } else if (nation_set_by_rule_name(value
)) {
1031 settings_snprintf(reject_msg
, reject_msg_len
,
1032 /* TRANS: do not translate 'list nationsets' */
1033 _("Unknown nation set \"%s\". See '%slist nationsets' "
1034 "for possible values."), value
, caller
? "/" : "");
1039 /*************************************************************************
1040 Validate the 'timeout' server setting.
1041 *************************************************************************/
1042 static bool timeout_callback(int value
, struct connection
*caller
,
1043 char *reject_msg
, size_t reject_msg_len
)
1045 /* Disallow low timeout values for non-hack connections. */
1046 if (caller
&& caller
->access_level
< ALLOW_HACK
1047 && value
< 30 && value
!= 0) {
1048 settings_snprintf(reject_msg
, reject_msg_len
,
1049 _("You are not allowed to set timeout values less "
1050 "than 30 seconds."));
1054 if (value
== -1 && game
.server
.unitwaittime
!= 0) {
1055 /* autogame only with 'unitwaittime' = 0 */
1056 settings_snprintf(reject_msg
, reject_msg_len
,
1057 /* TRANS: Do not translate setting names in ''. */
1058 _("For autogames ('timeout' = -1) 'unitwaittime' "
1059 "should be deactivated (= 0)."));
1063 if (value
> 0 && value
< game
.server
.unitwaittime
* 3 / 2) {
1064 /* for normal games 'timeout' should be at least 3/2 times the value
1065 * of 'unitwaittime' */
1066 settings_snprintf(reject_msg
, reject_msg_len
,
1067 /* TRANS: Do not translate setting names in ''. */
1068 _("'timeout' can not be lower than 3/2 of the "
1069 "'unitwaittime' setting (= %d). Please change "
1070 "'unitwaittime' first."), game
.server
.unitwaittime
);
1077 /*************************************************************************
1078 Validate the 'first_timeout' server setting.
1079 *************************************************************************/
1080 static bool first_timeout_callback(int value
, struct connection
*caller
,
1081 char *reject_msg
, size_t reject_msg_len
)
1083 /* Disallow low timeout values for non-hack connections. */
1084 if (caller
&& caller
->access_level
< ALLOW_HACK
1085 && value
< 30 && value
!= 0) {
1086 settings_snprintf(reject_msg
, reject_msg_len
,
1087 _("You are not allowed to set timeout values less "
1088 "than 30 seconds."));
1095 /*************************************************************************
1096 Check 'timeout' setting if 'unitwaittime' is changed.
1097 *************************************************************************/
1098 static bool unitwaittime_callback(int value
, struct connection
*caller
,
1099 char *reject_msg
, size_t reject_msg_len
)
1101 if (game
.info
.timeout
== -1 && value
!= 0) {
1102 settings_snprintf(reject_msg
, reject_msg_len
,
1103 /* TRANS: Do not translate setting names in ''. */
1104 _("For autogames ('timeout' = -1) 'unitwaittime' "
1105 "should be deactivated (= 0)."));
1109 if (game
.info
.timeout
> 0 && value
> game
.info
.timeout
* 2 / 3) {
1110 settings_snprintf(reject_msg
, reject_msg_len
,
1111 /* TRANS: Do not translate setting names in ''. */
1112 _("'unitwaittime' has to be lower than 2/3 of the "
1113 "'timeout' setting (= %d). Please change 'timeout' "
1114 "first."), game
.info
.timeout
);
1121 /*************************************************************************
1122 Mapsize setting validation callback.
1123 *************************************************************************/
1124 static bool mapsize_callback(int value
, struct connection
*caller
,
1125 char *reject_msg
, size_t reject_msg_len
)
1127 if (value
== MAPSIZE_XYSIZE
&& MAP_IS_ISOMETRIC
&&
1128 wld
.map
.ysize
% 2 != 0) {
1129 /* An isometric map needs a even ysize. Is is calculated automatically
1130 * for all settings but mapsize=XYSIZE. */
1131 settings_snprintf(reject_msg
, reject_msg_len
,
1132 _("For an isometric or hexagonal map the ysize must be "
1140 /*************************************************************************
1141 xsize setting validation callback.
1142 *************************************************************************/
1143 static bool xsize_callback(int value
, struct connection
*caller
,
1144 char *reject_msg
, size_t reject_msg_len
)
1146 int size
= value
* wld
.map
.ysize
;
1148 if (size
< MAP_MIN_SIZE
* 1000) {
1149 settings_snprintf(reject_msg
, reject_msg_len
,
1150 _("The map size (%d * %d = %d) must be larger than "
1151 "%d tiles."), value
, wld
.map
.ysize
, size
,
1152 MAP_MIN_SIZE
* 1000);
1154 } else if (size
> MAP_MAX_SIZE
* 1000) {
1155 settings_snprintf(reject_msg
, reject_msg_len
,
1156 _("The map size (%d * %d = %d) must be lower than "
1157 "%d tiles."), value
, wld
.map
.ysize
, size
,
1158 MAP_MAX_SIZE
* 1000);
1165 /*************************************************************************
1166 ysize setting validation callback.
1167 *************************************************************************/
1168 static bool ysize_callback(int value
, struct connection
*caller
,
1169 char *reject_msg
, size_t reject_msg_len
)
1171 int size
= wld
.map
.xsize
* value
;
1173 if (size
< MAP_MIN_SIZE
* 1000) {
1174 settings_snprintf(reject_msg
, reject_msg_len
,
1175 _("The map size (%d * %d = %d) must be larger than "
1176 "%d tiles."), wld
.map
.xsize
, value
, size
,
1177 MAP_MIN_SIZE
* 1000);
1179 } else if (size
> MAP_MAX_SIZE
* 1000) {
1180 settings_snprintf(reject_msg
, reject_msg_len
,
1181 _("The map size (%d * %d = %d) must be lower than "
1182 "%d tiles."), wld
.map
.xsize
, value
, size
,
1183 MAP_MAX_SIZE
* 1000);
1185 } else if (wld
.map
.server
.mapsize
== MAPSIZE_XYSIZE
&& MAP_IS_ISOMETRIC
&&
1187 /* An isometric map needs a even ysize. Is is calculated automatically
1188 * for all settings but mapsize=XYSIZE. */
1189 settings_snprintf(reject_msg
, reject_msg_len
,
1190 _("For an isometric or hexagonal map the ysize must be "
1198 /*************************************************************************
1199 Topology setting validation callback.
1200 *************************************************************************/
1201 static bool topology_callback(unsigned value
, struct connection
*caller
,
1202 char *reject_msg
, size_t reject_msg_len
)
1204 if (wld
.map
.server
.mapsize
== MAPSIZE_XYSIZE
&&
1205 ((value
& (TF_ISO
)) != 0 || (value
& (TF_HEX
)) != 0) &&
1206 wld
.map
.ysize
% 2 != 0) {
1207 /* An isometric map needs a even ysize. Is is calculated automatically
1208 * for all settings but mapsize=XYSIZE. */
1209 settings_snprintf(reject_msg
, reject_msg_len
,
1210 _("For an isometric or hexagonal map the ysize must be "
1216 /* Remember to update the help text too if Freeciv-web gets the ability
1217 * to display other map topologies. */
1218 if ((value
& (TF_WRAPY
)) != 0
1219 /* Are you removing this because Freeciv-web gained the ability to
1220 * display isometric maps? Why don't you remove the Freeciv-web
1221 * specific MAP_DEFAULT_TOPO too? */
1222 || (value
& (TF_ISO
)) != 0
1223 || (value
& (TF_HEX
)) != 0) {
1224 /* The Freeciv-web client can't display these topologies yet. */
1225 settings_snprintf(reject_msg
, reject_msg_len
,
1226 _("Freeciv-web doesn't support this topology."));
1229 #endif /* FREECIV_WEB */
1234 /*************************************************************************
1235 Warn about deprecated compresstype selection.
1236 *************************************************************************/
1237 static bool compresstype_callback(int value
,
1238 struct connection
*caller
,
1240 size_t reject_msg_len
)
1242 #ifdef FREECIV_HAVE_LIBBZ2
1243 if (value
== FZ_BZIP2
) {
1244 log_warn(_("Bzip2 is deprecated as compresstype. Consider "
1247 #endif /* FREECIV_HAVE_LIBBZ2 */
1252 /*************************************************************************
1253 Validate that the player color mode can be used.
1254 *************************************************************************/
1255 static bool plrcol_validate(int value
, struct connection
*caller
,
1256 char *reject_msg
, size_t reject_msg_len
)
1258 enum plrcolor_mode mode
= value
;
1259 if (mode
== PLRCOL_NATION_ORDER
) {
1260 nations_iterate(pnation
) {
1261 if (nation_color(pnation
)) {
1262 /* At least one nation has a color. Allow this mode. */
1265 } nations_iterate_end
;
1266 settings_snprintf(reject_msg
, reject_msg_len
,
1267 _("No nations in the currently loaded ruleset have "
1268 "associated colors."));
1274 #define GEN_BOOL(name, value, sclass, scateg, slevel, al_read, al_write, \
1275 short_help, extra_help, func_validate, func_action, \
1277 {name, sclass, al_read, al_write, short_help, extra_help, NULL, SST_BOOL, \
1280 .boolean = {&value, _default, func_validate, bool_name, \
1281 FALSE} INIT_BRACE_END , func_action, FALSE},
1283 #define GEN_INT(name, value, sclass, scateg, slevel, al_read, al_write, \
1284 short_help, extra_help, func_help, \
1285 func_validate, func_action, \
1286 _min, _max, _default) \
1287 {name, sclass, al_read, al_write, short_help, extra_help, func_help, \
1288 SST_INT, scateg, slevel, \
1290 .integer = {(int *) &value, _default, _min, _max, func_validate, \
1291 0} INIT_BRACE_END, \
1292 func_action, FALSE},
1294 #define GEN_STRING(name, value, sclass, scateg, slevel, al_read, al_write, \
1295 short_help, extra_help, func_validate, func_action, \
1297 {name, sclass, al_read, al_write, short_help, extra_help, NULL, \
1298 SST_STRING, scateg, slevel, \
1300 .string = {value, _default, sizeof(value), func_validate, ""} \
1302 func_action, FALSE},
1304 #define GEN_ENUM(name, value, sclass, scateg, slevel, al_read, al_write, \
1305 short_help, extra_help, func_help, func_validate, \
1306 func_action, func_name, _default) \
1307 { name, sclass, al_read, al_write, short_help, extra_help, func_help, \
1308 SST_ENUM, scateg, slevel, \
1310 .enumerator = { &value, sizeof(value), _default, \
1312 (val_name_func_t) func_name, 0 } INIT_BRACE_END, \
1313 func_action, FALSE},
1315 #define GEN_BITWISE(name, value, sclass, scateg, slevel, al_read, al_write, \
1316 short_help, extra_help, func_validate, func_action, \
1317 func_name, _default) \
1318 { name, sclass, al_read, al_write, short_help, extra_help, NULL, \
1319 SST_BITWISE, scateg, slevel, \
1321 .bitwise = { (unsigned *) (void *) &value, _default, func_validate, \
1322 func_name, 0 } INIT_BRACE_END, \
1323 func_action, FALSE},
1326 static struct setting settings
[] = {
1328 /* These should be grouped by sclass */
1330 /* Map size parameters: adjustable if we don't yet have a map */
1331 GEN_ENUM("mapsize", wld
.map
.server
.mapsize
, SSET_MAP_SIZE
,
1332 SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1333 N_("Map size definition"),
1334 /* TRANS: The strings between double quotes are also translated
1335 * separately (they must match!). The strings between single
1336 * quotes are setting names and shouldn't be translated. The
1337 * strings between parentheses and in uppercase must stay as
1339 N_("Chooses the method used to define the map size. Other options "
1340 "specify the parameters for each method.\n"
1341 "- \"Number of tiles\" (FULLSIZE): Map area (option 'size').\n"
1342 "- \"Tiles per player\" (PLAYER): Number of (land) tiles per "
1343 "player (option 'tilesperplayer').\n"
1344 "- \"Width and height\" (XYSIZE): Map width and height in "
1345 "tiles (options 'xsize' and 'ysize')."), NULL
,
1346 mapsize_callback
, NULL
, mapsize_name
, MAP_DEFAULT_MAPSIZE
)
1348 GEN_INT("size", wld
.map
.server
.size
, SSET_MAP_SIZE
,
1349 SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1350 N_("Map area (in thousands of tiles)"),
1351 /* TRANS: The strings between double quotes are also translated
1352 * separately (they must match!). The strings between single
1353 * quotes are setting names and shouldn't be translated. The
1354 * strings between parentheses and in uppercase must stay as
1356 N_("This value is used to determine the map area.\n"
1357 " size = 4 is a normal map of 4,000 tiles (default)\n"
1358 " size = 20 is a huge map of 20,000 tiles\n"
1359 "For this option to take effect, the \"Map size definition\" "
1360 "option ('mapsize') must be set to \"Number of tiles\" "
1361 "(FULLSIZE)."), NULL
, NULL
, NULL
,
1362 MAP_MIN_SIZE
, MAP_MAX_SIZE
, MAP_DEFAULT_SIZE
)
1364 GEN_INT("tilesperplayer", wld
.map
.server
.tilesperplayer
, SSET_MAP_SIZE
,
1365 SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1366 N_("Number of (land) tiles per player"),
1367 /* TRANS: The strings between double quotes are also translated
1368 * separately (they must match!). The strings between single
1369 * quotes are setting names and shouldn't be translated. The
1370 * strings between parentheses and in uppercase must stay as
1372 N_("This value is used to determine the map dimensions. It "
1373 "calculates the map size at game start based on the number "
1374 "of players and the value of the setting 'landmass'.\n"
1375 "For this option to take effect, the \"Map size definition\" "
1376 "option ('mapsize') must be set to \"Tiles per player\" "
1378 NULL
, NULL
, NULL
, MAP_MIN_TILESPERPLAYER
,
1379 MAP_MAX_TILESPERPLAYER
, MAP_DEFAULT_TILESPERPLAYER
)
1381 GEN_INT("xsize", wld
.map
.xsize
, SSET_MAP_SIZE
,
1382 SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1383 N_("Map width in tiles"),
1384 /* TRANS: The strings between double quotes are also translated
1385 * separately (they must match!). The strings between single
1386 * quotes are setting names and shouldn't be translated. The
1387 * strings between parentheses and in uppercase must stay as
1389 N_("Defines the map width.\n"
1390 "For this option to take effect, the \"Map size definition\" "
1391 "option ('mapsize') must be set to \"Width and height\" "
1393 NULL
, xsize_callback
, NULL
,
1394 MAP_MIN_LINEAR_SIZE
, MAP_MAX_LINEAR_SIZE
, MAP_DEFAULT_LINEAR_SIZE
)
1395 GEN_INT("ysize", wld
.map
.ysize
, SSET_MAP_SIZE
,
1396 SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1397 N_("Map height in tiles"),
1398 /* TRANS: The strings between double quotes are also translated
1399 * separately (they must match!). The strings between single
1400 * quotes are setting names and shouldn't be translated. The
1401 * strings between parentheses and in uppercase must stay as
1403 N_("Defines the map height.\n"
1404 "For this option to take effect, the \"Map size definition\" "
1405 "option ('mapsize') must be set to \"Width and height\" "
1407 NULL
, ysize_callback
, NULL
,
1408 MAP_MIN_LINEAR_SIZE
, MAP_MAX_LINEAR_SIZE
, MAP_DEFAULT_LINEAR_SIZE
)
1410 GEN_BITWISE("topology", wld
.map
.topology_id
, SSET_MAP_SIZE
,
1411 SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1412 N_("Map topology index"),
1414 /* TRANS: Freeciv-web version of the help text. */
1415 N_("Freeciv maps are always two-dimensional. They may wrap "
1416 "at the east-west directions to form a flat map or a "
1418 #else /* FREECIV_WEB */
1419 /* TRANS: do not edit the ugly ASCII art */
1420 N_("Freeciv maps are always two-dimensional. They may wrap at "
1421 "the north-south and east-west directions to form a flat "
1422 "map, a cylinder, or a torus (donut). Individual tiles may "
1423 "be rectangular or hexagonal, with either a classic or "
1424 "isometric alignment - this should be set based on the "
1425 "tileset being used.\n"
1426 "Classic rectangular: Isometric rectangular:\n"
1427 " _________ /\\/\\/\\/\\/\\\n"
1428 " |_|_|_|_|_| /\\/\\/\\/\\/\\/\n"
1429 " |_|_|_|_|_| \\/\\/\\/\\/\\/\\\n"
1430 " |_|_|_|_|_| /\\/\\/\\/\\/\\/\n"
1431 " \\/\\/\\/\\/\\/\n"
1432 "Hex tiles: Iso-hex:\n"
1433 " /\\/\\/\\/\\/\\/\\ _ _ _ _ _\n"
1434 " | | | | | | | / \\_/ \\_/ \\_/ \\_/ \\\n"
1435 " \\/\\/\\/\\/\\/\\/\\"
1436 " \\_/ \\_/ \\_/ \\_/ \\_/\n"
1437 " | | | | | | | / \\_/ \\_/ \\_/ \\_/ \\\n"
1438 " \\/\\/\\/\\/\\/\\/"
1439 " \\_/ \\_/ \\_/ \\_/ \\_/\n"),
1440 #endif /* FREECIV_WEB */
1441 topology_callback
, topology_action
, topology_name
, MAP_DEFAULT_TOPO
)
1443 GEN_ENUM("generator", wld
.map
.server
.generator
,
1444 SSET_MAP_GEN
, SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1445 N_("Method used to generate map"),
1446 /* TRANS: The strings between double quotes are also translated
1447 * separately (they must match!). The strings between single
1448 * quotes (except 'fair') are setting names and shouldn't be
1449 * translated. The strings between parentheses and in uppercase
1450 * must stay as untranslated. */
1451 N_("Specifies the algorithm used to generate the map. If the "
1452 "default value of the 'startpos' option is used, then the "
1453 "chosen generator chooses an appropriate 'startpos' setting; "
1454 "otherwise, the generated map tries to accommodate the "
1455 "chosen 'startpos' setting.\n"
1456 "- \"Scenario map\" (SCENARIO): indicates a pre-generated map. "
1457 "By default, if the scenario does not specify start positions, "
1458 "they will be allocated depending on the size of continents.\n"
1459 "- \"Fully random height\" (RANDOM): generates maps with a "
1460 "number of equally spaced, relatively small islands. By default, "
1461 "start positions are allocated depending on continent size.\n"
1462 "- \"Pseudo-fractal height\" (FRACTAL): generates Earthlike "
1463 "worlds with one or more large continents and a scattering of "
1464 "smaller islands. By default, players are all placed on a "
1465 "single continent.\n"
1466 "- \"Island-based\" (ISLAND): generates 'fair' maps with a "
1467 "number of similarly-sized and -shaped islands, each with "
1468 "approximately the same ratios of terrain types. By default, "
1469 "each player gets their own island.\n"
1470 "- \"Fair islands\" (FAIR): generates the exact copy of the "
1471 "same island for every player or every team.\n"
1472 "- \"Fracture map\" (FRACTURE): generates maps from a fracture "
1473 "pattern. Tends to place hills and mountains along the edges "
1474 "of the continents.\n"
1475 "If the requested generator is incompatible with other server "
1476 "settings, the server may fall back to another generator."),
1477 NULL
, generator_validate
, NULL
, generator_name
, MAP_DEFAULT_GENERATOR
)
1479 GEN_ENUM("startpos", wld
.map
.server
.startpos
,
1480 SSET_MAP_GEN
, SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1481 N_("Method used to choose start positions"),
1482 /* TRANS: The strings between double quotes are also translated
1483 * separately (they must match!). The strings between single
1484 * quotes (except 'best') are setting names and shouldn't be
1485 * translated. The strings between parentheses and in uppercase
1486 * must stay as untranslated. */
1487 N_("The method used to choose where each player's initial units "
1488 "start on the map. (For scenarios which include pre-set "
1489 "start positions, this setting is ignored.)\n"
1490 "- \"Generator's choice\" (DEFAULT): the start position "
1491 "placement will depend on the map generator chosen. See the "
1492 "'generator' setting.\n"
1493 "- \"One player per continent\" (SINGLE): one player is "
1494 "placed on each of a set of continents of approximately "
1495 "equivalent value (if possible).\n"
1496 "- \"Two or three players per continent\" (2or3): similar "
1497 "to SINGLE except that two players will be placed on each "
1498 "continent, with three on the 'best' continent if there is an "
1499 "odd number of players.\n"
1500 "- \"All players on a single continent\" (ALL): all players "
1501 "will start on the 'best' available continent.\n"
1502 "- \"Depending on size of continents\" (VARIABLE): players "
1503 "will be placed on the 'best' available continents such that, "
1504 "as far as possible, the number of players on each continent "
1505 "is proportional to its value.\n"
1506 "If the server cannot satisfy the requested setting due to "
1507 "there being too many players for continents, it may fall "
1508 "back to one of the others. (However, map generators try to "
1509 "create the right number of continents for the choice of this "
1510 "'startpos' setting and the number of players, so this is "
1511 "unlikely to occur.)"),
1512 NULL
, NULL
, NULL
, startpos_name
, MAP_DEFAULT_STARTPOS
)
1514 GEN_ENUM("teamplacement", wld
.map
.server
.team_placement
,
1515 SSET_MAP_GEN
, SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1516 N_("Method used for placement of team mates"),
1517 /* TRANS: The strings between double quotes are also translated
1518 * separately (they must match!). The strings between single
1519 * quotes are setting names and shouldn't be translated. The
1520 * strings between parentheses and in uppercase must stay as
1522 N_("After start positions have been generated thanks to the "
1523 "'startpos' setting, this setting controls how the start "
1524 "positions will be assigned to the different players of the "
1526 "- \"Disabled\" (DISABLED): the start positions will be "
1527 "randomly assigned to players, regardless of teams.\n"
1528 "- \"As close as possible\" (CLOSEST): players will be "
1529 "placed as close as possible, regardless of continents.\n"
1530 "- \"On the same continent\" (CONTINENT): if possible, place "
1531 "all players of the same team onto the same "
1532 "island/continent.\n"
1533 "- \"Horizontal placement\" (HORIZONTAL): players of the same "
1534 "team will be placed horizontally.\n"
1535 "- \"Vertical placement\" (VERTICAL): players of the same "
1536 "team will be placed vertically."),
1537 NULL
, NULL
, NULL
, teamplacement_name
, MAP_DEFAULT_TEAM_PLACEMENT
)
1539 GEN_BOOL("tinyisles", wld
.map
.server
.tinyisles
,
1540 SSET_MAP_GEN
, SSET_GEOLOGY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1541 N_("Presence of 1x1 islands"),
1542 N_("This setting controls whether the map generator is allowed "
1543 "to make islands of one only tile size."), NULL
, NULL
,
1544 MAP_DEFAULT_TINYISLES
)
1546 GEN_BOOL("separatepoles", wld
.map
.server
.separatepoles
,
1547 SSET_MAP_GEN
, SSET_GEOLOGY
, SSET_SITUATIONAL
,
1548 ALLOW_NONE
, ALLOW_BASIC
,
1549 N_("Whether the poles are separate continents"),
1550 N_("If this setting is disabled, the continents may attach to "
1551 "poles."), NULL
, NULL
, MAP_DEFAULT_SEPARATE_POLES
)
1553 GEN_INT("flatpoles", wld
.map
.server
.flatpoles
,
1554 SSET_MAP_GEN
, SSET_GEOLOGY
, SSET_SITUATIONAL
, ALLOW_NONE
, ALLOW_BASIC
,
1555 N_("How much the land at the poles is flattened"),
1556 /* TRANS: The strings in quotes shouldn't be translated. */
1557 N_("Controls how much the height of the poles is flattened "
1558 "during map generation, preventing a diversity of land "
1559 "terrain there. 0 is no flattening, 100 is maximum "
1560 "flattening. Only affects the 'RANDOM' and 'FRACTAL' "
1561 "map generators."), NULL
,
1563 MAP_MIN_FLATPOLES
, MAP_MAX_FLATPOLES
, MAP_DEFAULT_FLATPOLES
)
1565 GEN_BOOL("singlepole", wld
.map
.server
.single_pole
,
1566 SSET_MAP_GEN
, SSET_GEOLOGY
, SSET_SITUATIONAL
,
1567 ALLOW_NONE
, ALLOW_BASIC
,
1568 N_("Whether there's just one pole generated"),
1569 N_("If this setting is enabled, only one side of the map will have "
1570 "a pole. This setting has no effect if the map wraps both "
1571 "directions."), NULL
, NULL
, MAP_DEFAULT_SINGLE_POLE
)
1573 GEN_BOOL("alltemperate", wld
.map
.server
.alltemperate
,
1574 SSET_MAP_GEN
, SSET_GEOLOGY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1575 N_("All the map is temperate"),
1576 N_("If this setting is enabled, the temperature will be "
1577 "equivalent everywhere on the map. As a result, the "
1578 "poles won't be generated."),
1579 NULL
, NULL
, MAP_DEFAULT_ALLTEMPERATE
)
1581 GEN_INT("temperature", wld
.map
.server
.temperature
,
1582 SSET_MAP_GEN
, SSET_GEOLOGY
, SSET_SITUATIONAL
,
1583 ALLOW_NONE
, ALLOW_BASIC
,
1584 N_("Average temperature of the planet"),
1585 N_("Small values will give a cold map, while larger values will "
1586 "give a hotter map.\n"
1588 "100 means a very dry and hot planet with no polar arctic "
1589 "zones, only tropical and dry zones.\n"
1590 " 70 means a hot planet with little polar ice.\n"
1591 " 50 means a temperate planet with normal polar, cold, "
1592 "temperate, and tropical zones; a desert zone overlaps "
1593 "tropical and temperate zones.\n"
1594 " 30 means a cold planet with small tropical zones.\n"
1595 " 0 means a very cold planet with large polar zones and no "
1598 MAP_MIN_TEMPERATURE
, MAP_MAX_TEMPERATURE
, MAP_DEFAULT_TEMPERATURE
)
1600 GEN_INT("landmass", wld
.map
.server
.landpercent
,
1601 SSET_MAP_GEN
, SSET_GEOLOGY
, SSET_SITUATIONAL
,
1602 ALLOW_NONE
, ALLOW_BASIC
,
1603 N_("Percentage of the map that is land"),
1604 N_("This setting gives the approximate percentage of the map "
1605 "that will be made into land."), NULL
, NULL
, NULL
,
1606 MAP_MIN_LANDMASS
, MAP_MAX_LANDMASS
, MAP_DEFAULT_LANDMASS
)
1608 GEN_INT("steepness", wld
.map
.server
.steepness
,
1609 SSET_MAP_GEN
, SSET_GEOLOGY
, SSET_SITUATIONAL
,
1610 ALLOW_NONE
, ALLOW_BASIC
,
1611 N_("Amount of hills/mountains"),
1612 N_("Small values give flat maps, while higher values give a "
1613 "steeper map with more hills and mountains."),
1615 MAP_MIN_STEEPNESS
, MAP_MAX_STEEPNESS
, MAP_DEFAULT_STEEPNESS
)
1617 GEN_INT("wetness", wld
.map
.server
.wetness
,
1618 SSET_MAP_GEN
, SSET_GEOLOGY
, SSET_SITUATIONAL
,
1619 ALLOW_NONE
, ALLOW_BASIC
,
1620 N_("Amount of water on landmasses"),
1621 N_("Small values mean lots of dry, desert-like land; "
1622 "higher values give a wetter map with more swamps, "
1623 "jungles, and rivers."), NULL
, NULL
, NULL
,
1624 MAP_MIN_WETNESS
, MAP_MAX_WETNESS
, MAP_DEFAULT_WETNESS
)
1626 GEN_BOOL("globalwarming", game
.info
.global_warming
,
1627 SSET_RULES
, SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1628 N_("Global warming"),
1629 N_("If turned off, global warming will not occur "
1630 "as a result of pollution. This setting does not "
1631 "affect pollution."), NULL
, NULL
,
1632 GAME_DEFAULT_GLOBAL_WARMING
)
1634 GEN_BOOL("nuclearwinter", game
.info
.nuclear_winter
,
1635 SSET_RULES
, SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1636 N_("Nuclear winter"),
1637 N_("If turned off, nuclear winter will not occur "
1638 "as a result of nuclear war."), NULL
, NULL
,
1639 GAME_DEFAULT_NUCLEAR_WINTER
)
1641 GEN_INT("mapseed", wld
.map
.server
.seed_setting
,
1642 SSET_MAP_GEN
, SSET_INTERNAL
, SSET_RARE
, ALLOW_HACK
, ALLOW_HACK
,
1643 N_("Map generation random seed"),
1644 N_("The same seed will always produce the same map; "
1645 "for zero (the default) a seed will be chosen based on "
1646 "the time to give a random map."),
1648 MAP_MIN_SEED
, MAP_MAX_SEED
, MAP_DEFAULT_SEED
)
1650 /* Map additional stuff: huts and specials. gameseed also goes here
1651 * because huts and specials are the first time the gameseed gets used (?)
1652 * These are done when the game starts, so these are historical and
1653 * fixed after the game has started.
1655 GEN_INT("gameseed", game
.server
.seed_setting
,
1656 SSET_MAP_ADD
, SSET_INTERNAL
, SSET_RARE
, ALLOW_HACK
, ALLOW_HACK
,
1657 N_("Game random seed"),
1658 N_("For zero (the default) a seed will be chosen based "
1659 "on the current time."),
1661 GAME_MIN_SEED
, GAME_MAX_SEED
, GAME_DEFAULT_SEED
)
1663 GEN_INT("specials", wld
.map
.server
.riches
,
1664 SSET_MAP_ADD
, SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1665 N_("Amount of \"special\" resource tiles"),
1666 N_("Special resources improve the basic terrain type they "
1667 "are on. The server variable's scale is parts per "
1668 "thousand."), NULL
, NULL
, NULL
,
1669 MAP_MIN_RICHES
, MAP_MAX_RICHES
, MAP_DEFAULT_RICHES
)
1671 GEN_INT("huts", wld
.map
.server
.huts
,
1672 SSET_MAP_ADD
, SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1673 N_("Amount of huts (bonus extras)"),
1674 N_("This setting gives number of huts that will be "
1675 "placed on every one thousand tiles. Huts are "
1676 "tile extras that may be investigated by units."),
1677 huts_help
, NULL
, huts_action
,
1678 MAP_MIN_HUTS
, MAP_MAX_HUTS
, MAP_DEFAULT_HUTS
)
1680 GEN_INT("animals", wld
.map
.server
.animals
,
1681 SSET_MAP_ADD
, SSET_GEOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1682 N_("Amount of animals"),
1683 N_("Amount of animals initially created to terrains "
1684 "defined for them in the ruleset. "
1685 "The server variable's scale is animals per "
1686 "thousand tiles."), NULL
, NULL
, NULL
,
1687 MAP_MIN_ANIMALS
, MAP_MAX_ANIMALS
, MAP_DEFAULT_ANIMALS
)
1689 /* Options affecting numbers of players and AI players. These only
1690 * affect the start of the game and can not be adjusted after that.
1692 GEN_INT("minplayers", game
.server
.min_players
,
1693 SSET_PLAYERS
, SSET_INTERNAL
, SSET_VITAL
,
1694 ALLOW_NONE
, ALLOW_BASIC
,
1695 N_("Minimum number of players"),
1696 N_("There must be at least this many players (connected "
1697 "human players) before the game can start."),
1699 GAME_MIN_MIN_PLAYERS
, GAME_MAX_MIN_PLAYERS
, GAME_DEFAULT_MIN_PLAYERS
)
1701 GEN_INT("maxplayers", game
.server
.max_players
,
1702 SSET_PLAYERS
, SSET_INTERNAL
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1703 N_("Maximum number of players"),
1704 N_("The maximal number of human and AI players who can be in "
1705 "the game. When this number of players are connected in "
1706 "the pregame state, any new players who try to connect "
1707 "will be rejected.\n"
1708 "When playing a scenario which defines player start positions, "
1709 "this setting cannot be set to greater than the number of "
1710 "defined start positions."),
1711 NULL
, maxplayers_callback
, NULL
,
1712 GAME_MIN_MAX_PLAYERS
, GAME_MAX_MAX_PLAYERS
, GAME_DEFAULT_MAX_PLAYERS
)
1714 GEN_INT("aifill", game
.info
.aifill
,
1715 SSET_PLAYERS
, SSET_INTERNAL
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1716 N_("Limited number of AI players"),
1717 N_("If set to a positive value, then AI players will be "
1718 "automatically created or removed to keep the total "
1719 "number of players at this amount. As more players join, "
1720 "these AI players will be replaced. When set to zero, "
1721 "all AI players will be removed."),
1722 NULL
, NULL
, aifill_action
,
1723 GAME_MIN_AIFILL
, GAME_MAX_AIFILL
, GAME_DEFAULT_AIFILL
)
1725 GEN_ENUM("persistentready", game
.info
.persistent_ready
,
1726 SSET_META
, SSET_NETWORK
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1727 N_("When the Readiness of a player gets autotoggled off"),
1728 N_("In pre-game, usually when new players join or old ones leave, "
1729 "those who have already accepted game to start by toggling \"Ready\" "
1730 "get that autotoggled off in the changed situation. This setting "
1731 "can be used to make readiness more persistent."),
1732 NULL
, NULL
, NULL
, persistentready_name
, GAME_DEFAULT_PERSISTENTREADY
)
1734 GEN_STRING("nationset", game
.server
.nationset
,
1735 SSET_PLAYERS
, SSET_INTERNAL
, SSET_RARE
,
1736 ALLOW_NONE
, ALLOW_BASIC
,
1737 N_("Set of nations to choose from"),
1738 /* TRANS: do not translate '/list nationsets' */
1739 N_("Controls the set of nations allowed in the game. The "
1740 "choices are defined by the ruleset.\n"
1741 "Only nations in the set selected here will be allowed in "
1742 "any circumstances, including new players and civil war; "
1743 "small sets may thus limit the number of players in a game.\n"
1744 "If this is left blank, the ruleset's default nation set is "
1746 "See '/list nationsets' for possible choices for the "
1747 "currently loaded ruleset."),
1748 nationset_callback
, nationset_action
, GAME_DEFAULT_NATIONSET
)
1750 GEN_INT("ec_turns", game
.server
.event_cache
.turns
,
1751 SSET_RULES_FLEXIBLE
, SSET_INTERNAL
, SSET_SITUATIONAL
,
1752 ALLOW_NONE
, ALLOW_BASIC
,
1753 N_("Event cache for this number of turns"),
1754 N_("Event messages are saved for this number of turns. A value of "
1755 "0 deactivates the event cache."),
1756 NULL
, NULL
, NULL
, GAME_MIN_EVENT_CACHE_TURNS
, GAME_MAX_EVENT_CACHE_TURNS
,
1757 GAME_DEFAULT_EVENT_CACHE_TURNS
)
1759 GEN_INT("ec_max_size", game
.server
.event_cache
.max_size
,
1760 SSET_RULES_FLEXIBLE
, SSET_INTERNAL
, SSET_SITUATIONAL
,
1761 ALLOW_NONE
, ALLOW_BASIC
,
1762 N_("Size of the event cache"),
1763 N_("This defines the maximal number of events in the event cache."),
1764 NULL
, NULL
, NULL
, GAME_MIN_EVENT_CACHE_MAX_SIZE
,
1765 GAME_MAX_EVENT_CACHE_MAX_SIZE
, GAME_DEFAULT_EVENT_CACHE_MAX_SIZE
)
1767 GEN_BOOL("ec_chat", game
.server
.event_cache
.chat
,
1768 SSET_RULES_FLEXIBLE
, SSET_INTERNAL
, SSET_SITUATIONAL
,
1769 ALLOW_NONE
, ALLOW_BASIC
,
1770 N_("Save chat messages in the event cache"),
1771 N_("If turned on, chat messages will be saved in the event "
1772 "cache."), NULL
, NULL
, GAME_DEFAULT_EVENT_CACHE_CHAT
)
1774 GEN_BOOL("ec_info", game
.server
.event_cache
.info
,
1775 SSET_RULES_FLEXIBLE
, SSET_INTERNAL
, SSET_SITUATIONAL
,
1776 ALLOW_NONE
, ALLOW_BASIC
,
1777 N_("Print turn and time for each cached event"),
1778 /* TRANS: Don't translate the text between single quotes. */
1779 N_("If turned on, all cached events will be marked by the turn "
1780 "and time of the event like '(T2 - 15:29:52)'."),
1781 NULL
, NULL
, GAME_DEFAULT_EVENT_CACHE_INFO
)
1783 /* Game initialization parameters (only affect the first start of the game,
1784 * and not reloads). Can not be changed after first start of game.
1786 GEN_STRING("startunits", game
.server
.start_units
,
1787 SSET_GAME_INIT
, SSET_SOCIOLOGY
, SSET_VITAL
,
1788 ALLOW_NONE
, ALLOW_BASIC
,
1789 N_("List of players' initial units"),
1790 N_("This should be a string of characters, each of which "
1791 "specifies a unit role. The first character must be native to "
1792 "at least one \"Starter\" terrain. The characters and their "
1794 " c = City founder (eg., Settlers)\n"
1795 " w = Terrain worker (eg., Engineers)\n"
1796 " x = Explorer (eg., Explorer)\n"
1797 " k = Gameloss (eg., King)\n"
1798 " s = Diplomat (eg., Diplomat)\n"
1799 " f = Ferryboat (eg., Trireme)\n"
1800 " d = Ok defense unit (eg., Warriors)\n"
1801 " D = Good defense unit (eg., Phalanx)\n"
1802 " a = Fast attack unit (eg., Horsemen)\n"
1803 " A = Strong attack unit (eg., Catapult)\n"),
1804 startunits_callback
, NULL
, GAME_DEFAULT_START_UNITS
)
1806 GEN_BOOL("startcity", game
.server
.start_city
,
1807 SSET_GAME_INIT
, SSET_SOCIOLOGY
, SSET_VITAL
,
1808 ALLOW_NONE
, ALLOW_BASIC
,
1809 N_("Whether player starts with a city"),
1810 N_("If this is set, game will start with player's first "
1811 "city already founded to starting location."),
1812 NULL
, NULL
, GAME_DEFAULT_START_CITY
)
1814 GEN_INT("dispersion", game
.server
.dispersion
,
1815 SSET_GAME_INIT
, SSET_SOCIOLOGY
, SSET_SITUATIONAL
,
1816 ALLOW_NONE
, ALLOW_BASIC
,
1817 N_("Area where initial units are located"),
1818 N_("This is the radius within "
1819 "which the initial units are dispersed."),
1821 GAME_MIN_DISPERSION
, GAME_MAX_DISPERSION
, GAME_DEFAULT_DISPERSION
)
1823 GEN_INT("gold", game
.info
.gold
,
1824 SSET_GAME_INIT
, SSET_ECONOMICS
, SSET_VITAL
,
1825 ALLOW_NONE
, ALLOW_BASIC
,
1826 N_("Starting gold per player"),
1827 N_("At the beginning of the game, each player is given this "
1828 "much gold."), NULL
, NULL
, NULL
,
1829 GAME_MIN_GOLD
, GAME_MAX_GOLD
, GAME_DEFAULT_GOLD
)
1831 GEN_INT("techlevel", game
.info
.tech
,
1832 SSET_GAME_INIT
, SSET_SCIENCE
, SSET_VITAL
,
1833 ALLOW_NONE
, ALLOW_BASIC
,
1834 N_("Number of initial techs per player"),
1835 /* TRANS: The string between single quotes is a setting name and
1836 * should not be translated. */
1837 N_("At the beginning of the game, each player is given this "
1838 "many technologies. The technologies chosen are random for "
1839 "each player. Depending on the value of tech_cost_style in "
1840 "the ruleset, a big value for 'techlevel' can make the next "
1841 "techs really expensive."), NULL
, NULL
, NULL
,
1842 GAME_MIN_TECHLEVEL
, GAME_MAX_TECHLEVEL
, GAME_DEFAULT_TECHLEVEL
)
1844 GEN_INT("sciencebox", game
.info
.sciencebox
,
1845 SSET_RULES_SCENARIO
, SSET_SCIENCE
, SSET_SITUATIONAL
,
1846 ALLOW_NONE
, ALLOW_BASIC
,
1847 N_("Technology cost multiplier percentage"),
1848 N_("This affects how quickly players can research new "
1849 "technology. All tech costs are multiplied by this amount "
1850 "(as a percentage). The base tech costs are determined by "
1851 "the ruleset or other game settings."),
1852 NULL
, NULL
, NULL
, GAME_MIN_SCIENCEBOX
, GAME_MAX_SCIENCEBOX
,
1853 GAME_DEFAULT_SCIENCEBOX
)
1855 GEN_INT("techpenalty", game
.server
.techpenalty
,
1856 SSET_RULES
, SSET_SCIENCE
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1857 N_("Percentage penalty when changing tech"),
1858 N_("If you change your current research technology, and you have "
1859 "positive research points, you lose this percentage of those "
1860 "research points. This does not apply when you have just gained "
1861 "a technology this turn."), NULL
, NULL
, NULL
,
1862 GAME_MIN_TECHPENALTY
, GAME_MAX_TECHPENALTY
,
1863 GAME_DEFAULT_TECHPENALTY
)
1865 GEN_INT("techlost_recv", game
.server
.techlost_recv
,
1866 SSET_RULES
, SSET_SCIENCE
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1867 N_("Chance to lose a technology while receiving it"),
1868 N_("The chance that learning a technology by treaty or theft "
1870 NULL
, NULL
, NULL
, GAME_MIN_TECHLOST_RECV
, GAME_MAX_TECHLOST_RECV
,
1871 GAME_DEFAULT_TECHLOST_RECV
)
1873 GEN_INT("techlost_donor", game
.server
.techlost_donor
,
1874 SSET_RULES
, SSET_SCIENCE
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1875 N_("Chance to lose a technology while giving it"),
1876 N_("The chance that your civilization will lose a technology if "
1877 "you teach it to someone else by treaty, or if it is stolen "
1879 NULL
, NULL
, NULL
, GAME_MIN_TECHLOST_DONOR
, GAME_MAX_TECHLOST_DONOR
,
1880 GAME_DEFAULT_TECHLOST_DONOR
)
1882 GEN_BOOL("team_pooled_research", game
.info
.team_pooled_research
,
1883 SSET_RULES
, SSET_SCIENCE
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
1884 N_("Team pooled research"),
1885 N_("If this setting is turned on, then the team mates will share "
1886 "the science research. Else, every player of the team will "
1887 "have to make its own."),
1888 NULL
, NULL
, GAME_DEFAULT_TEAM_POOLED_RESEARCH
)
1890 GEN_INT("diplbulbcost", game
.server
.diplbulbcost
,
1891 SSET_RULES
, SSET_SCIENCE
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1892 N_("Penalty when getting tech from treaty"),
1893 N_("For each technology you gain from a diplomatic treaty, you "
1894 "lose research points equal to this percentage of the cost to "
1895 "research a new technology. If this is non-zero, you can end up "
1896 "with negative research points."),
1898 GAME_MIN_DIPLBULBCOST
, GAME_MAX_DIPLBULBCOST
, GAME_DEFAULT_DIPLBULBCOST
)
1900 GEN_INT("diplgoldcost", game
.server
.diplgoldcost
,
1901 SSET_RULES
, SSET_SCIENCE
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1902 N_("Penalty when getting gold from treaty"),
1903 N_("When transferring gold in diplomatic treaties, this percentage "
1904 "of the agreed sum is lost to both parties; it is deducted from "
1905 "the donor but not received by the recipient."),
1907 GAME_MIN_DIPLGOLDCOST
, GAME_MAX_DIPLGOLDCOST
, GAME_DEFAULT_DIPLGOLDCOST
)
1909 GEN_INT("conquercost", game
.server
.conquercost
,
1910 SSET_RULES
, SSET_SCIENCE
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1911 N_("Penalty when getting tech from conquering"),
1912 N_("For each technology you gain by conquering an enemy city, you "
1913 "lose research points equal to this percentage of the cost to "
1914 "research a new technology. If this is non-zero, you can end up "
1915 "with negative research points."),
1917 GAME_MIN_CONQUERCOST
, GAME_MAX_CONQUERCOST
,
1918 GAME_DEFAULT_CONQUERCOST
)
1920 GEN_INT("freecost", game
.server
.freecost
,
1921 SSET_RULES
, SSET_SCIENCE
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1922 N_("Penalty when getting a free tech"),
1923 /* TRANS: The strings between single quotes are setting names and
1924 * shouldn't be translated. */
1925 N_("For each technology you gain \"for free\" (other than "
1926 "covered by 'diplcost' or 'conquercost': for instance, from huts "
1927 "or from Great Library effects), you lose research points "
1928 "equal to this percentage of the cost to research a new "
1929 "technology. If this is non-zero, you can end up "
1930 "with negative research points."),
1932 GAME_MIN_FREECOST
, GAME_MAX_FREECOST
, GAME_DEFAULT_FREECOST
)
1934 GEN_INT("techlossforgiveness", game
.server
.techloss_forgiveness
,
1935 SSET_RULES
, SSET_SCIENCE
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1936 N_("Research point debt threshold for losing tech"),
1937 N_("When you have negative research points, and your shortfall is "
1938 "greater than this percentage of the cost of your current "
1939 "research, you forget a technology you already knew.\n"
1940 "The special value -1 prevents loss of technology regardless of "
1941 "research points."),
1943 GAME_MIN_TECHLOSSFG
, GAME_MAX_TECHLOSSFG
,
1944 GAME_DEFAULT_TECHLOSSFG
)
1946 GEN_INT("techlossrestore", game
.server
.techloss_restore
,
1947 SSET_RULES
, SSET_SCIENCE
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1948 N_("Research points restored after losing a tech"),
1949 N_("When you lose a technology due to a negative research balance "
1950 "(see 'techlossforgiveness'), this percentage of its research "
1951 "cost is credited to your research balance (this may not be "
1952 "sufficient to make it positive).\n"
1953 "The special value -1 means that your research balance is always "
1954 "restored to zero, regardless of your previous shortfall."),
1956 GAME_MIN_TECHLOSSREST
, GAME_MAX_TECHLOSSREST
,
1957 GAME_DEFAULT_TECHLOSSREST
)
1959 GEN_INT("foodbox", game
.info
.foodbox
,
1960 SSET_RULES
, SSET_ECONOMICS
, SSET_SITUATIONAL
,
1961 ALLOW_NONE
, ALLOW_BASIC
,
1962 N_("Food required for a city to grow"),
1963 N_("This is the base amount of food required to grow a city. "
1964 "This value is multiplied by another factor that comes from "
1965 "the ruleset and is dependent on the size of the city."),
1967 GAME_MIN_FOODBOX
, GAME_MAX_FOODBOX
, GAME_DEFAULT_FOODBOX
)
1969 GEN_INT("aqueductloss", game
.server
.aqueductloss
,
1970 SSET_RULES
, SSET_ECONOMICS
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1971 N_("Percentage food lost when city can't grow"),
1972 N_("If a city would expand, but it can't because it lacks some "
1973 "prerequisite (traditionally an Aqueduct or Sewer System), "
1974 "this is the base percentage of its foodbox that is lost "
1975 "each turn; the penalty may be reduced by buildings or other "
1976 "circumstances, depending on the ruleset."),
1978 GAME_MIN_AQUEDUCTLOSS
, GAME_MAX_AQUEDUCTLOSS
,
1979 GAME_DEFAULT_AQUEDUCTLOSS
)
1981 GEN_INT("shieldbox", game
.info
.shieldbox
,
1982 SSET_RULES
, SSET_ECONOMICS
, SSET_SITUATIONAL
,
1983 ALLOW_NONE
, ALLOW_BASIC
,
1984 N_("Multiplier percentage for production costs"),
1985 N_("This affects how quickly units and buildings can be "
1986 "produced. The base costs are multiplied by this value (as "
1989 GAME_MIN_SHIELDBOX
, GAME_MAX_SHIELDBOX
, GAME_DEFAULT_SHIELDBOX
)
1991 /* Notradesize and fulltradesize used to have callbacks to prevent them
1992 * from being set illegally (notradesize > fulltradesize). However this
1993 * provided a problem when setting them both through the client's settings
1994 * dialog, since they cannot both be set atomically. So the callbacks were
1995 * removed and instead the game now knows how to deal with invalid
1997 GEN_INT("fulltradesize", game
.info
.fulltradesize
,
1998 SSET_RULES
, SSET_ECONOMICS
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
1999 N_("Minimum city size to get full trade"),
2000 /* TRANS: The strings between single quotes are setting names and
2001 * shouldn't be translated. */
2002 N_("There is a trade penalty in all cities smaller than this. "
2003 "The penalty is 100% (no trade at all) for sizes up to "
2004 "'notradesize', and decreases gradually to 0% (no penalty "
2005 "except the normal corruption) for size='fulltradesize'. "
2006 "See also 'notradesize'."), NULL
, NULL
, NULL
,
2007 GAME_MIN_FULLTRADESIZE
, GAME_MAX_FULLTRADESIZE
,
2008 GAME_DEFAULT_FULLTRADESIZE
)
2010 GEN_INT("notradesize", game
.info
.notradesize
,
2011 SSET_RULES
, SSET_ECONOMICS
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2012 N_("Maximum size of a city without trade"),
2013 /* TRANS: The strings between single quotes are setting names and
2014 * shouldn't be translated. */
2015 N_("Cities do not produce any trade at all unless their size "
2016 "is larger than this amount. The produced trade increases "
2017 "gradually for cities larger than 'notradesize' and smaller "
2018 "than 'fulltradesize'. See also 'fulltradesize'."),
2020 GAME_MIN_NOTRADESIZE
, GAME_MAX_NOTRADESIZE
,
2021 GAME_DEFAULT_NOTRADESIZE
)
2023 GEN_INT("tradeworldrelpct", game
.info
.trade_world_rel_pct
,
2024 SSET_RULES
, SSET_ECONOMICS
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2025 N_("How largely trade distance is relative to world size"),
2026 /* TRANS: The strings between single quotes are setting names and
2027 * shouldn't be translated. */
2028 N_("When determining trade between cities, the distance factor "
2029 "can be partly or fully relative to world size. This setting "
2030 "determines how big percentage of the bonus calculation is "
2031 "relative to world size, and how much only absolute distance "
2034 GAME_MIN_TRADEWORLDRELPCT
, GAME_MAX_TRADEWORLDRELPCT
,
2035 GAME_DEFAULT_TRADEWORLDRELPCT
)
2037 GEN_INT("citymindist", game
.info
.citymindist
,
2038 SSET_RULES
, SSET_SOCIOLOGY
, SSET_SITUATIONAL
,
2039 ALLOW_NONE
, ALLOW_BASIC
,
2040 N_("Minimum distance between cities"),
2041 N_("When a player attempts to found a new city, it is prevented "
2042 "if the distance from any existing city is less than this "
2043 "setting. For example, when this setting is 3, there must be "
2044 "at least two clear tiles in any direction between all existing "
2045 "cities and the new city site. A value of 1 removes any such "
2046 "restriction on city placement."),
2048 GAME_MIN_CITYMINDIST
, GAME_MAX_CITYMINDIST
,
2049 GAME_DEFAULT_CITYMINDIST
)
2051 GEN_BOOL("trading_tech", game
.info
.trading_tech
,
2052 SSET_RULES
, SSET_SOCIOLOGY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2053 N_("Technology trading"),
2054 N_("If turned off, trading technologies in the diplomacy dialog "
2055 "is not allowed."), NULL
, NULL
,
2056 GAME_DEFAULT_TRADING_TECH
)
2058 GEN_BOOL("trading_gold", game
.info
.trading_gold
,
2059 SSET_RULES
, SSET_SOCIOLOGY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2061 N_("If turned off, trading gold in the diplomacy dialog "
2062 "is not allowed."), NULL
, NULL
,
2063 GAME_DEFAULT_TRADING_GOLD
)
2065 GEN_BOOL("trading_city", game
.info
.trading_city
,
2066 SSET_RULES
, SSET_SOCIOLOGY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2068 N_("If turned off, trading cities in the diplomacy dialog "
2069 "is not allowed."), NULL
, NULL
,
2070 GAME_DEFAULT_TRADING_CITY
)
2072 GEN_INT("trademindist", game
.info
.trademindist
,
2073 SSET_RULES
, SSET_ECONOMICS
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2074 N_("Minimum distance for trade routes"),
2075 N_("In order for two cities in the same civilization to establish "
2076 "a trade route, they must be at least this far apart on the "
2077 "map. For square grids, the distance is calculated as "
2078 "\"Manhattan distance\", that is, the sum of the displacements "
2079 "along the x and y directions."), NULL
, NULL
, NULL
,
2080 GAME_MIN_TRADEMINDIST
, GAME_MAX_TRADEMINDIST
,
2081 GAME_DEFAULT_TRADEMINDIST
)
2083 GEN_INT("rapturedelay", game
.info
.rapturedelay
,
2084 SSET_RULES
, SSET_SOCIOLOGY
, SSET_SITUATIONAL
,
2085 ALLOW_NONE
, ALLOW_BASIC
,
2086 N_("Number of turns between rapture effect"),
2087 N_("Sets the number of turns between rapture growth of a city. "
2088 "If set to n a city will grow after celebrating for n+1 "
2091 GAME_MIN_RAPTUREDELAY
, GAME_MAX_RAPTUREDELAY
,
2092 GAME_DEFAULT_RAPTUREDELAY
)
2094 GEN_INT("disasters", game
.info
.disasters
,
2095 SSET_RULES_FLEXIBLE
, SSET_SOCIOLOGY
, SSET_VITAL
,
2096 ALLOW_NONE
, ALLOW_BASIC
,
2097 N_("Frequency of disasters"),
2098 N_("Affects how often random disasters happen to cities, "
2099 "if any are defined by the ruleset. The relative frequency "
2100 "of disaster types is set by the ruleset. Zero prevents "
2101 "any random disasters from occurring."),
2103 GAME_MIN_DISASTERS
, GAME_MAX_DISASTERS
,
2104 GAME_DEFAULT_DISASTERS
)
2106 GEN_ENUM("traitdistribution", game
.server
.trait_dist
,
2107 SSET_RULES
, SSET_SOCIOLOGY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2108 N_("AI trait distribution method"),
2109 N_("How trait values are given to AI players."),
2110 NULL
, NULL
, NULL
, trait_dist_name
, GAME_DEFAULT_TRAIT_DIST_MODE
)
2112 GEN_INT("razechance", game
.server
.razechance
,
2113 SSET_RULES
, SSET_MILITARY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2114 N_("Chance for conquered building destruction"),
2115 N_("When a player conquers a city, each city improvement has this "
2116 "percentage chance to be destroyed."), NULL
, NULL
, NULL
,
2117 GAME_MIN_RAZECHANCE
, GAME_MAX_RAZECHANCE
, GAME_DEFAULT_RAZECHANCE
)
2119 GEN_INT("occupychance", game
.server
.occupychance
,
2120 SSET_RULES
, SSET_MILITARY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2121 N_("Chance of moving into tile after attack"),
2122 N_("If set to 0, combat is Civ1/2-style (when you attack, "
2123 "you remain in place). If set to 100, attacking units "
2124 "will always move into the tile they attacked when they win "
2125 "the combat (and no enemy units remain in the tile). If "
2126 "set to a value between 0 and 100, this will be used as "
2127 "the percent chance of \"occupying\" territory."),
2129 GAME_MIN_OCCUPYCHANCE
, GAME_MAX_OCCUPYCHANCE
,
2130 GAME_DEFAULT_OCCUPYCHANCE
)
2132 GEN_BOOL("autoattack", game
.server
.autoattack
, SSET_RULES_FLEXIBLE
, SSET_MILITARY
,
2133 SSET_SITUATIONAL
, ALLOW_NONE
, ALLOW_BASIC
,
2134 N_("Turn on/off server-side autoattack"),
2135 N_("If set to on, units with moves left will automatically "
2136 "consider attacking enemy units that move adjacent to them."),
2137 NULL
, NULL
, GAME_DEFAULT_AUTOATTACK
)
2139 GEN_BOOL("killstack", game
.info
.killstack
,
2140 SSET_RULES_SCENARIO
, SSET_MILITARY
, SSET_RARE
,
2141 ALLOW_NONE
, ALLOW_BASIC
,
2142 N_("Do all units in tile die with defender"),
2143 N_("If this is enabled, each time a defender unit loses in combat, "
2144 "and is not inside a city or suitable base, all units in the same "
2145 "tile are destroyed along with the defender. If this is disabled, "
2146 "only the defender unit is destroyed."),
2147 NULL
, NULL
, GAME_DEFAULT_KILLSTACK
)
2149 GEN_BOOL("killcitizen", game
.info
.killcitizen
,
2150 SSET_RULES
, SSET_MILITARY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2151 N_("Reduce city population after attack"),
2152 N_("This flag indicates whether a city's population is reduced "
2153 "after a successful attack by an enemy unit. If this is "
2154 "disabled, population is never reduced. Even when this is "
2155 "enabled, only some units may kill citizens."),
2156 NULL
, NULL
, GAME_DEFAULT_KILLCITIZEN
)
2158 GEN_INT("killunhomed", game
.server
.killunhomed
,
2159 SSET_RULES
, SSET_MILITARY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2160 N_("Slowly kill units without home cities (e.g., starting units)"),
2161 N_("If greater than 0, then every unit without a homecity will "
2162 "lose hitpoints each turn. The number of hitpoints lost is "
2163 "given by 'killunhomed' percent of the hitpoints of the unit "
2164 "type. At least one hitpoint is lost every turn until the "
2165 "death of the unit."),
2166 NULL
, NULL
, NULL
, GAME_MIN_KILLUNHOMED
, GAME_MAX_KILLUNHOMED
,
2167 GAME_DEFAULT_KILLUNHOMED
)
2169 GEN_ENUM("borders", game
.info
.borders
,
2170 SSET_RULES
, SSET_MILITARY
, SSET_SITUATIONAL
,
2171 ALLOW_NONE
, ALLOW_BASIC
,
2172 N_("National borders"),
2173 N_("If this is not disabled, then any land tiles around a "
2174 "city or border-claiming extra (like the classic ruleset's "
2175 "Fortress base) will be owned by that nation. "
2176 "SEE_INSIDE and EXPAND makes everything inside a player's "
2177 "borders visible at once. ENABLED will, in some rulesets, "
2178 "grant the same visibility if certain conditions are met."),
2179 NULL
, NULL
, NULL
, borders_name
, GAME_DEFAULT_BORDERS
)
2181 GEN_ENUM("happyborders", game
.info
.happyborders
,
2182 SSET_RULES
, SSET_MILITARY
, SSET_SITUATIONAL
,
2183 ALLOW_NONE
, ALLOW_BASIC
,
2184 N_("Units inside borders cause no unhappiness"),
2185 N_("If this is set, units will not cause unhappiness when "
2186 "inside your borders, or even allies borders, depending "
2187 "on value."), NULL
, NULL
, NULL
,
2188 happyborders_name
, GAME_DEFAULT_HAPPYBORDERS
)
2190 GEN_ENUM("diplomacy", game
.info
.diplomacy
,
2191 SSET_RULES
, SSET_MILITARY
, SSET_SITUATIONAL
,
2192 ALLOW_NONE
, ALLOW_BASIC
,
2193 N_("Ability to do diplomacy with other players"),
2194 N_("This setting controls the ability to do diplomacy with "
2196 NULL
, NULL
, NULL
, diplomacy_name
, GAME_DEFAULT_DIPLOMACY
)
2198 GEN_ENUM("citynames", game
.server
.allowed_city_names
,
2199 SSET_RULES
, SSET_SOCIOLOGY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2200 N_("Allowed city names"),
2201 /* TRANS: The strings between double quotes are also translated
2202 * separately (they must match!). The strings between parentheses
2203 * and in uppercase must not be translated. */
2204 N_("- \"No restrictions\" (NO_RESTRICTIONS): players can have "
2205 "multiple cities with the same names.\n"
2206 "- \"Unique to a player\" (PLAYER_UNIQUE): one player can't "
2207 "have multiple cities with the same name.\n"
2208 "- \"Globally unique\" (GLOBAL_UNIQUE): all cities in a game "
2209 "have to have different names.\n"
2210 "- \"No city name stealing\" (NO_STEALING): like "
2211 "\"Globally unique\", but a player isn't allowed to use a "
2212 "default city name of another nation unless it is a default "
2213 "for their nation also."),
2214 NULL
, NULL
, NULL
, citynames_name
, GAME_DEFAULT_ALLOWED_CITY_NAMES
)
2216 GEN_ENUM("plrcolormode", game
.server
.plrcolormode
,
2217 SSET_RULES
, SSET_INTERNAL
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2218 N_("How to pick player colors"),
2219 /* TRANS: The strings between double quotes are also translated
2220 * separately (they must match!). The strings between single quotes
2221 * are setting names and shouldn't be translated. The strings
2222 * between parentheses and in uppercase must not be translated. */
2223 N_("This setting determines how player colors are chosen. Player "
2224 "colors are used in the Nations report, for national borders on "
2225 "the map, and so on.\n"
2226 "- \"Per-player, in order\" (PLR_ORDER): colors are assigned to "
2227 "individual players in order from a list defined by the "
2229 "- \"Per-player, random\" (PLR_RANDOM): colors are assigned "
2230 "to individual players randomly from the set defined by the "
2232 "- \"Set manually\" (PLR_SET): colors can be set with the "
2233 "'playercolor' command before the game starts; these are not "
2234 "restricted to the ruleset colors. Any players for which no "
2235 "color is set when the game starts get a random color from the "
2237 "- \"Per-team, in order\" (TEAM_ORDER): colors are assigned to "
2238 "teams from the list in the ruleset. Every player on the same "
2239 "team gets the same color.\n"
2240 "- \"Per-nation, in order\" (NATION_ORDER): if the ruleset "
2241 "defines a color for a player's nation, the player takes that "
2242 "color. Any players whose nations don't have associated colors "
2243 "get a random color from the list in the ruleset.\n"
2244 "Regardless of this setting, individual player colors can be "
2245 "changed after the game starts with the 'playercolor' command."),
2246 NULL
, plrcol_validate
, plrcol_action
, plrcol_name
,
2247 GAME_DEFAULT_PLRCOLORMODE
)
2249 /* Flexible rules: these can be changed after the game has started.
2251 * The distinction between "rules" and "flexible rules" is not always
2252 * clearcut, and some existing cases may be largely historical or
2253 * accidental. However some generalizations can be made:
2255 * -- Low-level game mechanics should not be flexible (eg, rulesets).
2256 * -- Options which would affect the game "state" (city production etc)
2257 * should not be flexible (eg, foodbox).
2258 * -- Options which are explicitly sent to the client (eg, in
2259 * packet_game_info) should probably not be flexible, or at
2260 * least need extra care to be flexible.
2262 GEN_ENUM("barbarians", game
.server
.barbarianrate
,
2263 SSET_RULES_FLEXIBLE
, SSET_MILITARY
, SSET_VITAL
,
2264 ALLOW_NONE
, ALLOW_BASIC
,
2265 N_("Barbarian appearance frequency"),
2266 /* TRANS: The string between single quotes is a setting name and
2267 * should not be translated. */
2268 N_("This setting controls how frequently the barbarians appear "
2269 "in the game. See also the 'onsetbarbs' setting."),
2270 NULL
, NULL
, NULL
, barbarians_name
, GAME_DEFAULT_BARBARIANRATE
)
2272 GEN_INT("onsetbarbs", game
.server
.onsetbarbarian
,
2273 SSET_RULES_FLEXIBLE
, SSET_MILITARY
, SSET_VITAL
,
2274 ALLOW_NONE
, ALLOW_BASIC
,
2275 N_("Barbarian onset turn"),
2276 N_("Barbarians will not appear before this turn."),
2278 GAME_MIN_ONSETBARBARIAN
, GAME_MAX_ONSETBARBARIAN
,
2279 GAME_DEFAULT_ONSETBARBARIAN
)
2281 GEN_ENUM("revolentype", game
.info
.revolentype
,
2282 SSET_RULES
, SSET_SOCIOLOGY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2283 N_("Way to determine revolution length"),
2284 N_("Which method is used in determining how long period of anarchy "
2285 "lasts when changing government. The actual value is set with "
2286 "'revolen' setting. The 'quickening' methods depend on how "
2287 "many times any player has changed to this type of government "
2288 "before, so it becomes easier to establish a new system of "
2289 "government if it has been done before."),
2290 NULL
, NULL
, NULL
, revolentype_name
, GAME_DEFAULT_REVOLENTYPE
)
2292 GEN_INT("revolen", game
.server
.revolution_length
,
2293 SSET_RULES_FLEXIBLE
, SSET_SOCIOLOGY
, SSET_RARE
,
2294 ALLOW_NONE
, ALLOW_BASIC
,
2295 N_("Length of revolution"),
2296 N_("When changing governments, a period of anarchy will occur. "
2297 "Value of this setting, used the way 'revolentype' setting "
2298 "dictates, defines the length of the anarchy."),
2300 GAME_MIN_REVOLUTION_LENGTH
, GAME_MAX_REVOLUTION_LENGTH
,
2301 GAME_DEFAULT_REVOLUTION_LENGTH
)
2303 GEN_BOOL("fogofwar", game
.info
.fogofwar
,
2304 SSET_RULES
, SSET_MILITARY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2305 N_("Whether to enable fog of war"),
2306 N_("If this is enabled, only those units and cities within "
2307 "the vision range of your own units and cities will be "
2308 "revealed to you. You will not see new cities or terrain "
2309 "changes in tiles not observed."),
2310 NULL
, NULL
, GAME_DEFAULT_FOGOFWAR
)
2312 GEN_BOOL("foggedborders", game
.server
.foggedborders
,
2313 SSET_RULES
, SSET_MILITARY
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2314 N_("Whether fog of war applies to border changes"),
2315 N_("If this setting is enabled, players will not be able "
2316 "to see changes in tile ownership if they do not have "
2317 "direct sight of the affected tiles. Otherwise, players "
2318 "can see any or all changes to borders as long as they "
2319 "have previously seen the tiles."),
2320 NULL
, NULL
, GAME_DEFAULT_FOGGEDBORDERS
)
2322 GEN_BITWISE("airliftingstyle", game
.info
.airlifting_style
,
2323 SSET_RULES_FLEXIBLE
, SSET_MILITARY
, SSET_SITUATIONAL
,
2324 ALLOW_NONE
, ALLOW_BASIC
, N_("Airlifting style"),
2325 /* TRANS: The strings between double quotes are also
2326 * translated separately (they must match!). The strings
2327 * between parenthesis and in uppercase must not be
2329 N_("This setting affects airlifting units between cities. It "
2330 "can be a set of the following values:\n"
2331 "- \"Allows units to be airlifted from allied cities\" "
2333 "- \"Allows units to be airlifted to allied cities\" "
2335 "- \"Unlimited units from source city\" (SRC_UNLIMITED): "
2336 "note that airlifting from a city doesn't reduce the "
2337 "airlifted counter, but still needs at least 1.\n"
2338 "- \"Unlimited units to destination city\" "
2339 "(DEST_UNLIMITED): note that airlifting to a city doesn't "
2340 "reduce the airlifted counter, and doesn't need any."),
2341 NULL
, NULL
, airliftingstyle_name
, GAME_DEFAULT_AIRLIFTINGSTYLE
)
2343 GEN_INT("diplchance", game
.server
.diplchance
,
2344 SSET_RULES_FLEXIBLE
, SSET_MILITARY
, SSET_SITUATIONAL
,
2345 ALLOW_NONE
, ALLOW_BASIC
,
2346 N_("Base chance for diplomats and spies to succeed"),
2347 N_("The base chance of a spy returning from a successful mission and "
2348 "the base chance of success for diplomats and spies."),
2350 GAME_MIN_DIPLCHANCE
, GAME_MAX_DIPLCHANCE
, GAME_DEFAULT_DIPLCHANCE
)
2352 GEN_BITWISE("victories", game
.info
.victory_conditions
,
2353 SSET_RULES_FLEXIBLE
, SSET_INTERNAL
, SSET_VITAL
,
2354 ALLOW_NONE
, ALLOW_BASIC
,
2355 N_("What kinds of victories are possible"),
2356 /* TRANS: The strings between double quotes are also translated
2357 * separately (they must match!). The strings between single
2358 * quotes are setting names and shouldn't be translated. The
2359 * strings between parentheses and in uppercase must stay as
2361 N_("This setting controls how game can be won. One can always "
2362 "win by conquering entire planet, but other victory conditions "
2363 "can be enabled or disabled:\n"
2364 "- \"Spacerace\" (SPACERACE): Spaceship is built and travels to "
2366 "- \"Allied\" (ALLIED): After defeating enemies, all remaining "
2367 "players are allied.\n"
2368 "- \"Culture\" (CULTURE): Player meets ruleset defined cultural "
2369 "domination criteria.\n"),
2370 NULL
, NULL
, victory_conditions_name
, GAME_DEFAULT_VICTORY_CONDITIONS
)
2372 GEN_BOOL("endspaceship", game
.server
.endspaceship
, SSET_RULES_FLEXIBLE
,
2373 SSET_SCIENCE
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
2374 N_("Should the game end if the spaceship arrives?"),
2375 N_("If this option is turned on, the game will end with the "
2376 "arrival of a spaceship at Alpha Centauri."),
2377 NULL
, NULL
, GAME_DEFAULT_END_SPACESHIP
)
2379 GEN_INT("civilwarsize", game
.server
.civilwarsize
,
2380 SSET_RULES_FLEXIBLE
, SSET_SOCIOLOGY
, SSET_RARE
,
2381 ALLOW_NONE
, ALLOW_BASIC
,
2382 N_("Minimum number of cities for civil war"),
2383 N_("A civil war is triggered when a player has at least this "
2384 "many cities and the player's capital is captured. If "
2385 "this option is set to the maximum value, civil wars are "
2386 "turned off altogether."), NULL
, NULL
, NULL
,
2387 GAME_MIN_CIVILWARSIZE
, GAME_MAX_CIVILWARSIZE
,
2388 GAME_DEFAULT_CIVILWARSIZE
)
2390 GEN_BOOL("restrictinfra", game
.info
.restrictinfra
,
2391 SSET_RULES_FLEXIBLE
, SSET_MILITARY
, SSET_RARE
,
2392 ALLOW_NONE
, ALLOW_BASIC
,
2393 N_("Restrict the use of the infrastructure for enemy units"),
2394 N_("If this option is enabled, the use of roads and rails "
2395 "will be restricted for enemy units."), NULL
, NULL
,
2396 GAME_DEFAULT_RESTRICTINFRA
)
2398 GEN_BOOL("unreachableprotects", game
.info
.unreachable_protects
,
2399 SSET_RULES_FLEXIBLE
, SSET_MILITARY
, SSET_RARE
,
2400 ALLOW_NONE
, ALLOW_BASIC
,
2401 N_("Does unreachable unit protect reachable ones"),
2402 N_("This option controls whether tiles with both unreachable "
2403 "and reachable units can be attacked. If disabled, any "
2404 "tile with reachable units can be attacked. If enabled, "
2405 "tiles with an unreachable unit in them cannot be attacked."),
2406 NULL
, NULL
, GAME_DEFAULT_UNRPROTECTS
)
2408 GEN_INT("contactturns", game
.server
.contactturns
,
2409 SSET_RULES_FLEXIBLE
, SSET_MILITARY
, SSET_RARE
,
2410 ALLOW_NONE
, ALLOW_BASIC
,
2411 N_("Turns until player contact is lost"),
2412 N_("Players may meet for diplomacy this number of turns "
2413 "after their units have last met, even when they do not have "
2414 "an embassy. If set to zero, then players cannot meet unless "
2415 "they have an embassy."),
2417 GAME_MIN_CONTACTTURNS
, GAME_MAX_CONTACTTURNS
,
2418 GAME_DEFAULT_CONTACTTURNS
)
2420 GEN_BOOL("savepalace", game
.server
.savepalace
,
2421 SSET_RULES_FLEXIBLE
, SSET_MILITARY
, SSET_RARE
,
2422 ALLOW_NONE
, ALLOW_BASIC
,
2423 N_("Rebuild palace whenever capital is conquered"),
2424 N_("If this is turned on, when the capital is conquered the "
2425 "palace is automatically rebuilt for free in another randomly "
2426 "chosen city. This is significant because the technology "
2427 "requirement for building a palace will be ignored. (In "
2428 "some rulesets, buildings other than the palace are affected "
2429 "by this setting.)"),
2430 NULL
, NULL
, GAME_DEFAULT_SAVEPALACE
)
2432 GEN_BOOL("homecaughtunits", game
.server
.homecaughtunits
,
2433 SSET_RULES_FLEXIBLE
, SSET_MILITARY
, SSET_RARE
,
2434 ALLOW_NONE
, ALLOW_BASIC
,
2435 N_("Give caught units a homecity"),
2436 /* TRANS: The string between single quotes is a setting name and
2437 * should not be translated. */
2438 N_("If unset, caught units will have no homecity and will be "
2439 "subject to the 'killunhomed' option."),
2440 NULL
, NULL
, GAME_DEFAULT_HOMECAUGHTUNITS
)
2442 GEN_BOOL("naturalcitynames", game
.server
.natural_city_names
,
2443 SSET_RULES_FLEXIBLE
, SSET_SOCIOLOGY
, SSET_RARE
,
2444 ALLOW_NONE
, ALLOW_BASIC
,
2445 N_("Whether to use natural city names"),
2446 N_("If enabled, the default city names will be determined based "
2447 "on the surrounding terrain."),
2448 NULL
, NULL
, GAME_DEFAULT_NATURALCITYNAMES
)
2450 GEN_BOOL("migration", game
.server
.migration
,
2451 SSET_RULES_FLEXIBLE
, SSET_SOCIOLOGY
, SSET_RARE
,
2452 ALLOW_NONE
, ALLOW_BASIC
,
2453 N_("Whether to enable citizen migration"),
2454 /* TRANS: The strings between single quotes are setting names
2455 * and should not be translated. */
2456 N_("This is the master setting that controls whether citizen "
2457 "migration is active in the game. If enabled, citizens may "
2458 "automatically move from less desirable cities to more "
2459 "desirable ones. The \"desirability\" of a given city is "
2460 "calculated from a number of factors. In general larger "
2461 "cities with more income and improvements will be preferred. "
2462 "Citizens will never migrate out of the capital, or cause "
2463 "a wonder to be lost by disbanding a city. A number of other "
2464 "settings control how migration behaves:\n"
2465 " 'mgr_turninterval' - How often citizens try to migrate.\n"
2466 " 'mgr_foodneeded' - Whether destination food is checked.\n"
2467 " 'mgr_distance' - How far citizens will migrate.\n"
2468 " 'mgr_worldchance' - Chance for inter-nation migration.\n"
2469 " 'mgr_nationchance' - Chance for intra-nation migration."),
2470 NULL
, NULL
, GAME_DEFAULT_MIGRATION
)
2472 GEN_INT("mgr_turninterval", game
.server
.mgr_turninterval
,
2473 SSET_RULES_FLEXIBLE
, SSET_SOCIOLOGY
, SSET_RARE
,
2474 ALLOW_NONE
, ALLOW_BASIC
,
2475 N_("Number of turns between migrations from a city"),
2476 /* TRANS: Do not translate 'migration' setting name. */
2477 N_("This setting controls the number of turns between migration "
2478 "checks for a given city. The interval is calculated from "
2479 "the founding turn of the city. So for example if this "
2480 "setting is 5, citizens will look for a suitable migration "
2481 "destination every five turns from the founding of their "
2482 "current city. Migration will never occur the same turn "
2483 "that a city is built. This setting has no effect unless "
2484 "migration is enabled by the 'migration' setting."),
2486 GAME_MIN_MGR_TURNINTERVAL
, GAME_MAX_MGR_TURNINTERVAL
,
2487 GAME_DEFAULT_MGR_TURNINTERVAL
)
2489 GEN_BOOL("mgr_foodneeded", game
.server
.mgr_foodneeded
,
2490 SSET_RULES_FLEXIBLE
, SSET_SOCIOLOGY
, SSET_RARE
,
2491 ALLOW_NONE
, ALLOW_BASIC
,
2492 N_("Whether migration is limited by food"),
2493 /* TRANS: Do not translate 'migration' setting name. */
2494 N_("If this setting is enabled, citizens will not migrate to "
2495 "cities which would not have enough food to support them. "
2496 "This setting has no effect unless migration is enabled by "
2497 "the 'migration' setting."), NULL
, NULL
,
2498 GAME_DEFAULT_MGR_FOODNEEDED
)
2500 GEN_INT("mgr_distance", game
.server
.mgr_distance
,
2501 SSET_RULES_FLEXIBLE
, SSET_SOCIOLOGY
, SSET_RARE
,
2502 ALLOW_NONE
, ALLOW_BASIC
,
2503 N_("Maximum distance citizens may migrate"),
2504 /* TRANS: Do not translate 'migration' setting name. */
2505 N_("This setting controls how far citizens may look for a "
2506 "suitable migration destination when deciding which city "
2507 "to migrate to. The value is added to the current city radius "
2508 "and compared to the distance between the two cities. If "
2509 "the distance is lower or equal, migration is possible. This "
2510 "setting has no effect unless migration is activated by the "
2511 "'migration' setting."),
2512 NULL
, NULL
, NULL
, GAME_MIN_MGR_DISTANCE
, GAME_MAX_MGR_DISTANCE
,
2513 GAME_DEFAULT_MGR_DISTANCE
)
2515 GEN_INT("mgr_nationchance", game
.server
.mgr_nationchance
,
2516 SSET_RULES_FLEXIBLE
, SSET_SOCIOLOGY
, SSET_RARE
,
2517 ALLOW_NONE
, ALLOW_BASIC
,
2518 N_("Percent probability for migration within the same nation"),
2519 /* TRANS: Do not translate 'migration' setting name. */
2520 N_("This setting controls how likely it is for citizens to "
2521 "migrate between cities owned by the same player. Zero "
2522 "indicates migration will never occur, 100 means that "
2523 "migration will always occur if the citizens find a suitable "
2524 "destination. This setting has no effect unless migration "
2525 "is activated by the 'migration' setting."),
2527 GAME_MIN_MGR_NATIONCHANCE
, GAME_MAX_MGR_NATIONCHANCE
,
2528 GAME_DEFAULT_MGR_NATIONCHANCE
)
2530 GEN_INT("mgr_worldchance", game
.server
.mgr_worldchance
,
2531 SSET_RULES_FLEXIBLE
, SSET_SOCIOLOGY
, SSET_RARE
,
2532 ALLOW_NONE
, ALLOW_BASIC
,
2533 N_("Percent probability for migration between foreign cities"),
2534 /* TRANS: Do not translate 'migration' setting name. */
2535 N_("This setting controls how likely it is for migration "
2536 "to occur between cities owned by different players. "
2537 "Zero indicates migration will never occur, 100 means "
2538 "that citizens will always migrate if they find a suitable "
2539 "destination. This setting has no effect if migration is "
2540 "not enabled by the 'migration' setting."),
2542 GAME_MIN_MGR_WORLDCHANCE
, GAME_MAX_MGR_WORLDCHANCE
,
2543 GAME_DEFAULT_MGR_WORLDCHANCE
)
2545 /* Meta options: these don't affect the internal rules of the game, but
2546 * do affect players. Also options which only produce extra server
2547 * "output" and don't affect the actual game.
2548 * ("endturn" is here, and not RULES_FLEXIBLE, because it doesn't
2549 * affect what happens in the game, it just determines when the
2550 * players stop playing and look at the score.)
2552 GEN_STRING("allowtake", game
.server
.allow_take
,
2553 SSET_META
, SSET_NETWORK
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2554 N_("Players that users are allowed to take"),
2555 /* TRANS: the strings in double quotes are server command names
2556 * and should not be translated. */
2557 N_("This should be a string of characters, each of which "
2558 "specifies a type or status of a civilization (player).\n"
2559 "Clients will only be permitted to take or observe those "
2560 "players which match one of the specified letters. This "
2561 "only affects future uses of the \"take\" or \"observe\" "
2562 "commands; it is not retroactive. The characters and their "
2564 " o,O = Global observer\n"
2565 " b = Barbarian players\n"
2566 " d = Dead players\n"
2567 " a,A = AI players\n"
2568 " h,H = Human players\n"
2569 "The first description on this list which matches a "
2570 "player is the one which applies. Thus 'd' does not "
2571 "include dead barbarians, 'a' does not include dead AI "
2572 "players, and so on. Upper case letters apply before "
2573 "the game has started, lower case letters afterwards.\n"
2574 "Each character above may be followed by one of the "
2575 "following numbers to allow or restrict the manner "
2577 "(none) = Controller allowed, observers allowed, "
2578 "can displace connections. (Displacing a connection means "
2579 "that you may take over a player, even when another user "
2580 "already controls that player.)\n"
2581 " 1 = Controller allowed, observers allowed, "
2582 "can't displace connections;\n"
2583 " 2 = Controller allowed, no observers allowed, "
2584 "can displace connections;\n"
2585 " 3 = Controller allowed, no observers allowed, "
2586 "can't displace connections;\n"
2587 " 4 = No controller allowed, observers allowed"),
2588 allowtake_callback
, NULL
, GAME_DEFAULT_ALLOW_TAKE
)
2590 GEN_BOOL("autotoggle", game
.server
.auto_ai_toggle
,
2591 SSET_META
, SSET_NETWORK
, SSET_SITUATIONAL
,
2592 ALLOW_NONE
, ALLOW_BASIC
,
2593 N_("Whether AI-status toggles with connection"),
2594 N_("If enabled, AI status is turned off when a player "
2595 "connects, and on when a player disconnects."),
2596 NULL
, autotoggle_action
, GAME_DEFAULT_AUTO_AI_TOGGLE
)
2598 GEN_INT("endturn", game
.server
.end_turn
,
2599 SSET_META
, SSET_SOCIOLOGY
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
2600 N_("Turn the game ends"),
2601 N_("The game will end at the end of the given turn."),
2602 NULL
, endturn_callback
, NULL
,
2603 GAME_MIN_END_TURN
, GAME_MAX_END_TURN
, GAME_DEFAULT_END_TURN
)
2605 GEN_BITWISE("revealmap", game
.server
.revealmap
, SSET_GAME_INIT
,
2606 SSET_MILITARY
, SSET_SITUATIONAL
, ALLOW_NONE
, ALLOW_BASIC
,
2607 N_("Reveal the map"),
2608 /* TRANS: The strings between double quotes are also translated
2609 * separately (they must match!). The strings between single
2610 * quotes are setting names and shouldn't be translated. The
2611 * strings between parentheses and in uppercase must not be
2613 N_("If \"Reveal map at game start\" (START) is set, the "
2614 "initial state of the entire map will be known to all "
2615 "players from the start of the game, although it may "
2616 "still be fogged (depending on the 'fogofwar' setting). "
2617 "If \"Unfog map for dead players\" (DEAD) is set, dead "
2618 "players can see the entire map, if they are alone in "
2620 NULL
, NULL
, revealmap_name
, GAME_DEFAULT_REVEALMAP
)
2622 GEN_INT("timeout", game
.info
.timeout
,
2623 SSET_META
, SSET_INTERNAL
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
2624 N_("Maximum seconds per turn"),
2625 /* TRANS: \"Turn Done\" refers to the client button; it is also
2626 * translated separately, the translation should be the same.
2627 * \"timeoutincrease\" is a command name and must not to be
2629 N_("If all players have not hit \"Turn Done\" before this "
2630 "time is up, then the turn ends automatically. Zero "
2631 "means there is no timeout. In servers compiled with "
2632 "debugging, a timeout of -1 sets the autogame test mode. "
2633 "Only connections with hack level access may set the "
2634 "timeout to fewer than 30 seconds. Use this with the "
2635 "command \"timeoutincrease\" to have a dynamic timer. "
2636 "The first turn is treated as a special case and is controlled "
2637 "by the 'first_timeout' setting."),
2638 NULL
, timeout_callback
, timeout_action
,
2639 GAME_MIN_TIMEOUT
, GAME_MAX_TIMEOUT
, GAME_DEFAULT_TIMEOUT
)
2641 GEN_INT("first_timeout", game
.info
.first_timeout
,
2642 SSET_META
, SSET_INTERNAL
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
2643 N_("First turn timeout"),
2644 /* TRANS: The strings between single quotes are setting names and
2645 * should not be translated. */
2646 N_("If greater than 0, T1 will last for 'first_timeout' seconds.\n"
2647 "If set to 0, T1 will not have a timeout.\n"
2648 "If set to -1, the special treatment of T1 will be disabled.\n"
2649 "See also 'timeout'."),
2650 NULL
, first_timeout_callback
, first_timeout_action
,
2651 GAME_MIN_FIRST_TIMEOUT
, GAME_MAX_FIRST_TIMEOUT
,
2652 GAME_DEFAULT_FIRST_TIMEOUT
)
2654 GEN_INT("timeaddenemymove", game
.server
.timeoutaddenemymove
,
2655 SSET_META
, SSET_INTERNAL
, SSET_VITAL
, ALLOW_NONE
, ALLOW_BASIC
,
2656 N_("Timeout at least n seconds when enemy moved"),
2657 N_("Any time a unit moves while in sight of an enemy player, "
2658 "the remaining timeout is increased to this value."),
2660 0, GAME_MAX_TIMEOUT
, GAME_DEFAULT_TIMEOUTADDEMOVE
)
2662 GEN_INT("unitwaittime", game
.server
.unitwaittime
,
2663 SSET_RULES_FLEXIBLE
, SSET_INTERNAL
, SSET_VITAL
,
2664 ALLOW_NONE
, ALLOW_BASIC
,
2665 N_("Minimum time between unit actions over turn change"),
2666 /* TRANS: The string between single quotes is a setting name and
2667 * should not be translated. */
2668 N_("This setting gives the minimum amount of time in seconds "
2669 "between unit moves and other significant actions (such as "
2670 "building cities) after a turn change occurs. For example, "
2671 "if this setting is set to 20 and a unit moves 5 seconds "
2672 "before the turn change, it will not be able to move or act "
2673 "in the next turn for at least 15 seconds. This value is "
2674 "limited to a maximum value of 2/3 'timeout'."),
2675 NULL
, unitwaittime_callback
, NULL
, GAME_MIN_UNITWAITTIME
,
2676 GAME_MAX_UNITWAITTIME
, GAME_DEFAULT_UNITWAITTIME
)
2678 /* This setting points to the "stored" value; changing it won't have
2679 * an effect until the next synchronization point (i.e., the start of
2680 * the next turn). */
2681 GEN_ENUM("phasemode", game
.server
.phase_mode_stored
,
2682 SSET_META
, SSET_INTERNAL
, SSET_SITUATIONAL
,
2683 ALLOW_NONE
, ALLOW_BASIC
,
2684 N_("Control of simultaneous player/team phases"),
2685 N_("This setting controls whether players may make "
2686 "moves at the same time during a turn. Change "
2687 "in setting takes effect next turn."),
2688 phasemode_help
, NULL
, NULL
, phasemode_name
, GAME_DEFAULT_PHASE_MODE
)
2690 GEN_INT("nettimeout", game
.server
.tcptimeout
,
2691 SSET_META
, SSET_NETWORK
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2692 N_("Seconds to let a client's network connection block"),
2693 N_("If a network connection is blocking for a time greater than "
2694 "this value, then the connection is closed. Zero "
2695 "means there is no timeout (although connections will be "
2696 "automatically disconnected eventually)."),
2698 GAME_MIN_TCPTIMEOUT
, GAME_MAX_TCPTIMEOUT
, GAME_DEFAULT_TCPTIMEOUT
)
2700 GEN_INT("netwait", game
.server
.netwait
,
2701 SSET_META
, SSET_NETWORK
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2702 N_("Max seconds for network buffers to drain"),
2703 N_("The server will wait for up to the value of this "
2704 "parameter in seconds, for all client connection network "
2705 "buffers to unblock. Zero means the server will not "
2706 "wait at all."), NULL
, NULL
, NULL
,
2707 GAME_MIN_NETWAIT
, GAME_MAX_NETWAIT
, GAME_DEFAULT_NETWAIT
)
2709 GEN_INT("pingtime", game
.server
.pingtime
,
2710 SSET_META
, SSET_NETWORK
, SSET_RARE
, ALLOW_NONE
, ALLOW_BASIC
,
2711 N_("Seconds between PINGs"),
2712 N_("The server will poll the clients with a PING request "
2713 "each time this period elapses."), NULL
, NULL
, NULL
,
2714 GAME_MIN_PINGTIME
, GAME_MAX_PINGTIME
, GAME_DEFAULT_PINGTIME
)
2716 GEN_INT("pingtimeout", game
.server
.pingtimeout
,
2717 SSET_META
, SSET_NETWORK
, SSET_RARE
,
2718 ALLOW_NONE
, ALLOW_BASIC
,
2719 N_("Time to cut a client"),
2720 N_("If a client doesn't reply to a PING in this time the "
2721 "client is disconnected."), NULL
, NULL
, NULL
,
2722 GAME_MIN_PINGTIMEOUT
, GAME_MAX_PINGTIMEOUT
, GAME_DEFAULT_PINGTIMEOUT
)
2724 GEN_BOOL("turnblock", game
.server
.turnblock
,
2725 SSET_META
, SSET_INTERNAL
, SSET_SITUATIONAL
,
2726 ALLOW_NONE
, ALLOW_BASIC
,
2727 N_("Turn-blocking game play mode"),
2728 N_("If this is turned on, the game turn is not advanced "
2729 "until all players have finished their turn, including "
2730 "disconnected players."),
2731 NULL
, NULL
, GAME_DEFAULT_TURNBLOCK
)
2733 GEN_BOOL("fixedlength", game
.server
.fixedlength
,
2734 SSET_META
, SSET_INTERNAL
, SSET_SITUATIONAL
,
2735 ALLOW_NONE
, ALLOW_BASIC
,
2736 N_("Fixed-length turns play mode"),
2737 /* TRANS: \"Turn Done\" refers to the client button; it is also
2738 * translated separately, the translation should be the same. */
2739 N_("If this is turned on the game turn will not advance "
2740 "until the timeout has expired, even after all players "
2741 "have clicked on \"Turn Done\"."),
2744 GEN_STRING("demography", game
.server
.demography
,
2745 SSET_META
, SSET_INTERNAL
, SSET_SITUATIONAL
,
2746 ALLOW_NONE
, ALLOW_BASIC
,
2747 N_("What is in the Demographics report"),
2748 /* TRANS: The strings between double quotes should be
2750 N_("This should be a string of characters, each of which "
2751 "specifies the inclusion of a line of information "
2752 "in the Demographics report.\n"
2753 "The characters and their meanings are:\n"
2754 " N = include Population\n"
2755 " P = include Production\n"
2756 " A = include Land Area\n"
2757 " L = include Literacy\n"
2758 " R = include Research Speed\n"
2759 " S = include Settled Area\n"
2760 " E = include Economics\n"
2761 " M = include Military Service\n"
2762 " O = include Pollution\n"
2763 " C = include Culture\n"
2764 "Additionally, the following characters control whether "
2765 "or not certain columns are displayed in the report:\n"
2766 " q = display \"quantity\" column\n"
2767 " r = display \"rank\" column\n"
2768 " b = display \"best nation\" column\n"
2769 "The order of characters is not significant, but "
2770 "their capitalization is."),
2771 demography_callback
, NULL
, GAME_DEFAULT_DEMOGRAPHY
)
2773 GEN_INT("saveturns", game
.server
.save_nturns
,
2774 SSET_META
, SSET_INTERNAL
, SSET_VITAL
, ALLOW_HACK
, ALLOW_HACK
,
2775 N_("Turns per auto-save"),
2776 /* TRANS: The string between double quotes is also translated
2777 * separately (it must match!). The string between single
2778 * quotes is a setting name and shouldn't be translated. */
2779 N_("How many turns elapse between automatic game saves. This "
2780 "setting only has an effect when the 'autosaves' setting "
2781 "includes \"New turn\"."), NULL
, NULL
, NULL
,
2782 GAME_MIN_SAVETURNS
, GAME_MAX_SAVETURNS
, GAME_DEFAULT_SAVETURNS
)
2784 GEN_INT("savefrequency", game
.server
.save_frequency
,
2785 SSET_META
, SSET_INTERNAL
, SSET_VITAL
, ALLOW_HACK
, ALLOW_HACK
,
2786 N_("Minutes per auto-save"),
2787 /* TRANS: The string between double quotes is also translated
2788 * separately (it must match!). The string between single
2789 * quotes is a setting name and shouldn't be translated. */
2790 N_("How many minutes elapse between automatic game saves. "
2791 "Unlike other save types, this save is only meant as backup "
2792 "for computer memory, and it always uses the same name, older "
2793 "saves are not kept. This setting only has an effect when the "
2794 "'autosaves' setting includes \"Timer\"."), NULL
, NULL
, NULL
,
2795 GAME_MIN_SAVEFREQUENCY
, GAME_MAX_SAVEFREQUENCY
, GAME_DEFAULT_SAVEFREQUENCY
)
2797 GEN_BITWISE("autosaves", game
.server
.autosaves
,
2798 SSET_META
, SSET_INTERNAL
, SSET_VITAL
, ALLOW_HACK
, ALLOW_HACK
,
2799 N_("Which savegames are generated automatically"),
2800 /* TRANS: The strings between double quotes are also translated
2801 * separately (they must match!). The strings between single
2802 * quotes are setting names and shouldn't be translated. The
2803 * strings between parentheses and in uppercase must stay as
2805 N_("This setting controls which autosave types get generated:\n"
2806 "- \"New turn\" (TURN): Save when turn begins, once every "
2807 "'saveturns' turns.\n"
2808 "- \"Game over\" (GAMEOVER): Final save when game ends.\n"
2809 "- \"No player connections\" (QUITIDLE): "
2810 "Save before server restarts due to lack of players.\n"
2811 "- \"Server interrupted\" (INTERRUPT): Save when server "
2812 "quits due to interrupt.\n"
2813 "- \"Timer\" (TIMER): Save every 'savefrequency' minutes."),
2814 autosaves_callback
, NULL
, autosaves_name
, GAME_DEFAULT_AUTOSAVES
)
2816 GEN_BOOL("threaded_save", game
.server
.threaded_save
,
2817 SSET_META
, SSET_INTERNAL
, SSET_RARE
, ALLOW_HACK
, ALLOW_HACK
,
2818 N_("Whether to do saving in separate thread"),
2819 /* TRANS: The string between single quotes is a setting name and
2820 * should not be translated. */
2821 N_("If this is turned in, compressing and saving the actual "
2822 "file containing the game situation takes place in "
2823 "the background while game otherwise continues. This way "
2824 "users are not required to wait for the save to finish."),
2825 NULL
, NULL
, GAME_DEFAULT_THREADED_SAVE
)
2827 GEN_INT("compress", game
.server
.save_compress_level
,
2828 SSET_META
, SSET_INTERNAL
, SSET_RARE
, ALLOW_HACK
, ALLOW_HACK
,
2829 N_("Savegame compression level"),
2830 /* TRANS: 'compresstype' setting name should not be translated. */
2831 N_("If non-zero, saved games will be compressed depending on the "
2832 "'compresstype' setting. Larger values will give better "
2833 "compression but take longer."),
2835 GAME_MIN_COMPRESS_LEVEL
, GAME_MAX_COMPRESS_LEVEL
, GAME_DEFAULT_COMPRESS_LEVEL
)
2837 GEN_ENUM("compresstype", game
.server
.save_compress_type
,
2838 SSET_META
, SSET_INTERNAL
, SSET_RARE
, ALLOW_HACK
, ALLOW_HACK
,
2839 N_("Savegame compression algorithm"),
2840 N_("Compression library to use for savegames."),
2841 NULL
, compresstype_callback
, NULL
, compresstype_name
, GAME_DEFAULT_COMPRESS_TYPE
)
2843 GEN_STRING("savename", game
.server
.save_name
,
2844 SSET_META
, SSET_INTERNAL
, SSET_VITAL
, ALLOW_HACK
, ALLOW_HACK
,
2845 N_("Definition of the save file name"),
2846 /* TRANS: %R, %S, %T and %Y must not be translated. The
2847 * strings (examples and setting names) between single quotes
2848 * neither. The strings between <> should be translated.
2849 * xgettext:no-c-format */
2850 N_("Within the string the following custom formats are "
2854 " %T = <turn-number>\n"
2855 " %Y = <game-year>\n"
2857 "Example: 'freeciv-T%04T-Y%+05Y-%R' => "
2858 "'freeciv-T0100-Y00001-manual'\n"
2860 "Be careful to use at least one of %T and %Y, else newer "
2861 "savegames will overwrite old ones. If none of the formats "
2862 "is used '-T%04T-Y%05Y-%R' is appended to the value of "
2864 savename_validate
, NULL
, GAME_DEFAULT_SAVE_NAME
)
2866 GEN_BOOL("scorelog", game
.server
.scorelog
,
2867 SSET_META
, SSET_INTERNAL
, SSET_SITUATIONAL
,
2869 ALLOW_NONE
, ALLOW_CTRL
,
2870 #else /* FREECIV_WEB */
2871 ALLOW_HACK
, ALLOW_HACK
,
2872 #endif /* FREECIV_WEB */
2873 N_("Whether to log player statistics"),
2874 /* TRANS: The string between single quotes is a setting name and
2875 * should not be translated. */
2876 N_("If this is turned on, player statistics are appended to "
2877 "the file defined by the option 'scorefile' every turn. "
2878 "These statistics can be used to create power graphs after "
2879 "the game."), NULL
, scorelog_action
, GAME_DEFAULT_SCORELOG
)
2881 GEN_ENUM("scoreloglevel", game
.server
.scoreloglevel
,
2882 SSET_META
, SSET_INTERNAL
, SSET_SITUATIONAL
,
2883 ALLOW_HACK
, ALLOW_HACK
,
2884 N_("Scorelog level"),
2885 N_("Whether scores are logged for all players including AIs, "
2886 "or only for human players."), NULL
, NULL
, NULL
,
2887 scoreloglevel_name
, GAME_DEFAULT_SCORELOGLEVEL
)
2890 GEN_STRING("scorefile", game
.server
.scorefile
,
2891 SSET_META
, SSET_INTERNAL
, SSET_SITUATIONAL
,
2892 ALLOW_HACK
, ALLOW_HACK
,
2893 N_("Name for the score log file"),
2894 /* TRANS: Don't translate the string in single quotes. */
2895 N_("The default name for the score log file is "
2896 "'freeciv-score.log'."),
2897 scorefile_validate
, NULL
, GAME_DEFAULT_SCOREFILE
)
2898 #endif /* !FREECIV_WEB */
2900 GEN_INT("maxconnectionsperhost", game
.server
.maxconnectionsperhost
,
2901 SSET_RULES_FLEXIBLE
, SSET_NETWORK
, SSET_RARE
,
2902 ALLOW_NONE
, ALLOW_BASIC
,
2903 N_("Maximum number of connections to the server per host"),
2904 N_("New connections from a given host will be rejected if "
2905 "the total number of connections from the very same host "
2906 "equals or exceeds this value. A value of 0 means that "
2907 "there is no limit, at least up to the maximum number of "
2908 "connections supported by the server."), NULL
, NULL
, NULL
,
2909 GAME_MIN_MAXCONNECTIONSPERHOST
, GAME_MAX_MAXCONNECTIONSPERHOST
,
2910 GAME_DEFAULT_MAXCONNECTIONSPERHOST
)
2912 GEN_INT("kicktime", game
.server
.kick_time
,
2913 SSET_RULES_FLEXIBLE
, SSET_NETWORK
, SSET_RARE
,
2914 ALLOW_HACK
, ALLOW_HACK
,
2915 N_("Time before a kicked user can reconnect"),
2916 /* TRANS: the string in double quotes is a server command name and
2917 * should not be translated */
2918 N_("Gives the time in seconds before a user kicked using the "
2919 "\"kick\" command may reconnect. Changing this setting will "
2920 "affect users kicked in the past."), NULL
, NULL
, NULL
,
2921 GAME_MIN_KICK_TIME
, GAME_MAX_KICK_TIME
, GAME_DEFAULT_KICK_TIME
)
2923 GEN_STRING("metamessage", game
.server
.meta_info
.user_message
,
2924 SSET_META
, SSET_INTERNAL
, SSET_RARE
, ALLOW_CTRL
, ALLOW_CTRL
,
2925 N_("Metaserver info line"),
2926 N_("User defined metaserver info line. For most of the time "
2927 "a user defined metamessage will be used instead of an "
2928 "automatically generated message. "
2929 "Set to empty (\"\", not \"empty\") to always use an "
2930 "automatically generated meta server message."),
2931 NULL
, metamessage_action
, GAME_DEFAULT_USER_META_MESSAGE
)
2940 /* The number of settings, not including the END. */
2941 static const int SETTINGS_NUM
= ARRAY_SIZE(settings
);
2943 /****************************************************************************
2944 Returns the setting to the given id.
2945 ****************************************************************************/
2946 struct setting
*setting_by_number(int id
)
2948 return (0 <= id
&& id
< SETTINGS_NUM
? settings
+ id
: NULL
);
2951 /****************************************************************************
2952 Returns the setting to the given name.
2953 ****************************************************************************/
2954 struct setting
*setting_by_name(const char *name
)
2956 fc_assert_ret_val(name
, NULL
);
2958 settings_iterate(SSET_ALL
, pset
) {
2959 if (0 == strcmp(name
, pset
->name
)) {
2962 } settings_iterate_end
;
2966 /****************************************************************************
2967 Returns the id to the given setting.
2968 ****************************************************************************/
2969 int setting_number(const struct setting
*pset
)
2971 fc_assert_ret_val(pset
!= NULL
, -1);
2972 return pset
- settings
;
2975 /****************************************************************************
2976 Access function for the setting name.
2977 ****************************************************************************/
2978 const char *setting_name(const struct setting
*pset
)
2983 /****************************************************************************
2984 Access function for the short help (not translated yet) of the setting.
2985 ****************************************************************************/
2986 const char *setting_short_help(const struct setting
*pset
)
2988 return pset
->short_help
;
2991 /****************************************************************************
2992 Access function for the long (extra) help of the setting.
2993 If 'constant' is TRUE, static, not-yet-translated string is always returned.
2994 ****************************************************************************/
2995 const char *setting_extra_help(const struct setting
*pset
, bool constant
)
2997 if (!constant
&& pset
->help_func
!= NULL
) {
2998 return pset
->help_func(pset
);
3001 return _(pset
->extra_help
);
3004 /****************************************************************************
3005 Access function for the setting type.
3006 ****************************************************************************/
3007 enum sset_type
setting_type(const struct setting
*pset
)
3012 /****************************************************************************
3013 Access function for the setting level (used by the /show command).
3014 ****************************************************************************/
3015 enum sset_level
setting_level(const struct setting
*pset
)
3017 return pset
->slevel
;
3020 /****************************************************************************
3021 Access function for the setting category.
3022 ****************************************************************************/
3023 enum sset_category
setting_category(const struct setting
*pset
)
3025 return pset
->scategory
;
3028 /****************************************************************************
3029 Returns whether the specified server setting (option) can currently
3030 be changed without breaking data consistency (map dimension options
3031 can't change when map has already been created with certain dimensions)
3032 ****************************************************************************/
3033 static bool setting_is_free_to_change(const struct setting
*pset
,
3035 size_t reject_msg_len
)
3037 switch (pset
->sclass
) {
3040 /* Only change map options if we don't yet have a map: */
3041 if (map_is_empty()) {
3045 settings_snprintf(reject_msg
, reject_msg_len
,
3046 _("The setting '%s' can't be modified after the map "
3047 "is fixed."), setting_name(pset
));
3050 case SSET_RULES_SCENARIO
:
3051 /* Like SSET_RULES except that it can be changed before the game starts
3052 * for heavy scenarios. A heavy scenario comes with players. It can
3053 * include cities, units, diplomatic relations and other complex
3054 * state. Make sure that changing a setting can't make the state of a
3055 * heavy scenario illegal if you want to change it from SSET_RULES to
3056 * SSET_RULES_SCENARIO. */
3058 if (game
.scenario
.is_scenario
&& game
.scenario
.players
3059 && server_state() == S_S_INITIAL
) {
3060 /* Special case detected. */
3064 /* The special case didn't make it legal to change the setting. Don't
3065 * give up. It could still be legal. Fall through so the non special
3066 * cases are checked too. */
3070 case SSET_GAME_INIT
:
3072 /* Only change start params and most rules if we don't yet have a map,
3073 * or if we do have a map but its a scenario one (ie, the game has
3074 * never actually been started).
3076 if (map_is_empty() || game
.info
.is_new_game
) {
3080 settings_snprintf(reject_msg
, reject_msg_len
,
3081 _("The setting '%s' can't be modified after the game "
3082 "has started."), setting_name(pset
));
3085 case SSET_RULES_FLEXIBLE
:
3087 /* These can always be changed: */
3091 log_error("Wrong class variant for setting %s (%d): %d.",
3092 setting_name(pset
), setting_number(pset
), pset
->sclass
);
3093 settings_snprintf(reject_msg
, reject_msg_len
, _("Internal error."));
3098 /****************************************************************************
3099 Returns whether the specified server setting (option) can currently
3100 be changed by the caller. If it returns FALSE, the reason of the failure
3101 is available by the function setting_error().
3102 ****************************************************************************/
3103 bool setting_is_changeable(const struct setting
*pset
,
3104 struct connection
*caller
, char *reject_msg
,
3105 size_t reject_msg_len
)
3108 && (caller
->access_level
< pset
->access_level_write
)) {
3109 settings_snprintf(reject_msg
, reject_msg_len
,
3110 _("You are not allowed to change the setting '%s'."),
3111 setting_name(pset
));
3115 if (setting_locked(pset
)) {
3116 /* setting is locked by the ruleset */
3117 settings_snprintf(reject_msg
, reject_msg_len
,
3118 _("The setting '%s' is locked by the ruleset."),
3119 setting_name(pset
));
3123 return setting_is_free_to_change(pset
, reject_msg
, reject_msg_len
);
3126 /****************************************************************************
3127 Returns whether the specified server setting (option) can be seen by a
3128 caller with the specified access level.
3129 ****************************************************************************/
3130 bool setting_is_visible_at_level(const struct setting
*pset
,
3131 enum cmdlevel plevel
)
3133 return (plevel
>= pset
->access_level_read
);
3136 /****************************************************************************
3137 Returns whether the specified server setting (option) can be seen by the
3139 ****************************************************************************/
3140 bool setting_is_visible(const struct setting
*pset
,
3141 struct connection
*caller
)
3144 || setting_is_visible_at_level(pset
, caller
->access_level
));
3147 /****************************************************************************
3148 Convert the string prefix to an integer representation.
3149 NB: This function is used for SST_ENUM *and* SST_BITWISE.
3151 FIXME: this mostly duplicate match_prefix_full().
3152 ****************************************************************************/
3153 static enum m_pre_result
3154 setting_match_prefix_base(const val_name_func_t name_fn
,
3155 const char *prefix
, int *ind_result
,
3156 const char **matches
, size_t max_matches
,
3157 size_t *pnum_matches
)
3159 const struct sset_val_name
*name
;
3160 size_t len
= strlen(prefix
);
3170 for (i
= 0, num_matches
= 0; (name
= name_fn(i
)); i
++) {
3171 if (0 == fc_strncasecmp(name
->support
, prefix
, len
)) {
3172 if (strlen(name
->support
) == len
) {
3176 if (num_matches
< max_matches
) {
3177 matches
[num_matches
] = name
->support
;
3180 if (0 == num_matches
++) {
3186 if (1 == num_matches
) {
3188 } else if (1 < num_matches
) {
3189 return M_PRE_AMBIGUOUS
;
3195 /****************************************************************************
3196 Convert the string prefix to an integer representation.
3197 NB: This function is used for SST_ENUM *and* SST_BITWISE.
3198 ****************************************************************************/
3199 static bool setting_match_prefix(const val_name_func_t name_fn
,
3200 const char *prefix
, int *pvalue
,
3202 size_t reject_msg_len
)
3204 const char *matches
[16];
3207 switch (setting_match_prefix_base(name_fn
, prefix
, pvalue
, matches
,
3208 ARRAY_SIZE(matches
), &num_matches
)) {
3211 return TRUE
; /* Ok. */
3212 case M_PRE_AMBIGUOUS
:
3214 struct astring astr
= ASTRING_INIT
;
3216 fc_assert(2 <= num_matches
);
3217 settings_snprintf(reject_msg
, reject_msg_len
,
3218 _("\"%s\" prefix is ambiguous. Candidates are: %s."),
3220 astr_build_and_list(&astr
, matches
, num_matches
));
3225 settings_snprintf(reject_msg
, reject_msg_len
, _("Missing value."));
3233 settings_snprintf(reject_msg
, reject_msg_len
,
3234 _("No match for \"%s\"."), prefix
);
3238 /****************************************************************************
3239 Compute the string representation of the value for this boolean setting.
3240 ****************************************************************************/
3241 static const char *setting_bool_to_str(const struct setting
*pset
,
3242 bool value
, bool pretty
,
3243 char *buf
, size_t buf_len
)
3245 const struct sset_val_name
*name
= pset
->boolean
.name(value
);
3248 fc_snprintf(buf
, buf_len
, "%s", Q_(name
->pretty
));
3250 fc_strlcpy(buf
, name
->support
, buf_len
);
3255 /****************************************************************************
3256 Returns TRUE if 'val' is a valid value for this setting. If it's not,
3257 the reason of the failure is available in the optionnal parameter
3260 FIXME: also check the access level of pconn.
3261 ****************************************************************************/
3262 static bool setting_bool_validate_base(const struct setting
*pset
,
3263 const char *val
, int *pint_val
,
3264 struct connection
*caller
,
3266 size_t reject_msg_len
)
3270 if (SST_BOOL
!= pset
->stype
) {
3271 settings_snprintf(reject_msg
, reject_msg_len
,
3272 _("This setting is not a boolean."));
3276 sz_strlcpy(buf
, val
);
3277 remove_leading_trailing_spaces(buf
);
3279 return (setting_match_prefix(pset
->boolean
.name
, buf
, pint_val
,
3280 reject_msg
, reject_msg_len
)
3281 && (NULL
== pset
->boolean
.validate
3282 || pset
->boolean
.validate(0 != *pint_val
, caller
, reject_msg
,
3286 /****************************************************************************
3287 Set the setting to 'val'. Returns TRUE on success. If it's not,
3288 the reason of the failure is available in the optionnal parameter
3290 ****************************************************************************/
3291 bool setting_bool_set(struct setting
*pset
, const char *val
,
3292 struct connection
*caller
, char *reject_msg
,
3293 size_t reject_msg_len
)
3297 if (!setting_is_changeable(pset
, caller
, reject_msg
, reject_msg_len
)
3298 || !setting_bool_validate_base(pset
, val
, &int_val
, caller
,
3299 reject_msg
, reject_msg_len
)) {
3303 *pset
->boolean
.pvalue
= (0 != int_val
);
3307 /****************************************************************************
3308 Get value of boolean setting
3309 ****************************************************************************/
3310 bool setting_bool_get(struct setting
*pset
)
3312 fc_assert(setting_type(pset
) == SST_BOOL
);
3314 return *pset
->boolean
.pvalue
;
3317 /****************************************************************************
3318 Returns TRUE if 'val' is a valid value for this setting. If it's not,
3319 the reason of the failure is available in the optionnal parameter
3321 ****************************************************************************/
3322 bool setting_bool_validate(const struct setting
*pset
, const char *val
,
3323 struct connection
*caller
, char *reject_msg
,
3324 size_t reject_msg_len
)
3328 return setting_bool_validate_base(pset
, val
, &int_val
, caller
,
3329 reject_msg
, reject_msg_len
);
3332 /****************************************************************************
3333 Convert the integer to the long support string representation of a boolean
3334 setting. This function must match the secfile_enum_name_data_fn_t type.
3335 ****************************************************************************/
3336 static const char *setting_bool_secfile_str(secfile_data_t data
, int val
)
3338 const struct sset_val_name
*name
=
3339 ((const struct setting
*) data
)->boolean
.name(val
);
3341 return (NULL
!= name
? name
->support
: NULL
);
3344 /****************************************************************************
3345 Compute the string representation of the value for this integer setting.
3346 ****************************************************************************/
3347 static const char *setting_int_to_str(const struct setting
*pset
,
3348 int value
, bool pretty
,
3349 char *buf
, size_t buf_len
)
3351 fc_snprintf(buf
, buf_len
, "%d", value
);
3355 /****************************************************************************
3356 Returns the minimal integer value for this setting.
3357 ****************************************************************************/
3358 int setting_int_min(const struct setting
*pset
)
3360 fc_assert_ret_val(pset
->stype
== SST_INT
, 0);
3361 return pset
->integer
.min_value
;
3364 /****************************************************************************
3365 Returns the maximal integer value for this setting.
3366 ****************************************************************************/
3367 int setting_int_max(const struct setting
*pset
)
3369 fc_assert_ret_val(pset
->stype
== SST_INT
, 0);
3370 return pset
->integer
.max_value
;
3373 /****************************************************************************
3374 Set the setting to 'val'. Returns TRUE on success. If it fails, the
3375 reason of the failure is available by the function setting_error().
3376 ****************************************************************************/
3377 bool setting_int_set(struct setting
*pset
, int val
,
3378 struct connection
*caller
, char *reject_msg
,
3379 size_t reject_msg_len
)
3381 if (!setting_is_changeable(pset
, caller
, reject_msg
, reject_msg_len
)
3382 || !setting_int_validate(pset
, val
, caller
, reject_msg
,
3387 *pset
->integer
.pvalue
= val
;
3391 /****************************************************************************
3392 Returns TRUE if 'val' is a valid value for this setting. If it's not,
3393 the reason of the failure is available by the function setting_error().
3395 FIXME: also check the access level of pconn.
3396 ****************************************************************************/
3397 bool setting_int_validate(const struct setting
*pset
, int val
,
3398 struct connection
*caller
, char *reject_msg
,
3399 size_t reject_msg_len
)
3401 if (SST_INT
!= pset
->stype
) {
3402 settings_snprintf(reject_msg
, reject_msg_len
,
3403 _("This setting is not an integer."));
3407 if (val
< pset
->integer
.min_value
|| val
> pset
->integer
.max_value
) {
3408 settings_snprintf(reject_msg
, reject_msg_len
,
3409 _("Value out of range: %d (min: %d; max: %d)."),
3410 val
, pset
->integer
.min_value
, pset
->integer
.max_value
);
3414 return (!pset
->integer
.validate
3415 || pset
->integer
.validate(val
, caller
, reject_msg
,
3419 /****************************************************************************
3420 Get value of integer setting
3421 ****************************************************************************/
3422 int setting_int_get(struct setting
*pset
)
3424 fc_assert(setting_type(pset
) == SST_INT
);
3426 return *pset
->integer
.pvalue
;
3429 /****************************************************************************
3430 Compute the string representation of the value for this string setting.
3431 ****************************************************************************/
3432 static const char *setting_str_to_str(const struct setting
*pset
,
3433 const char *value
, bool pretty
,
3434 char *buf
, size_t buf_len
)
3437 fc_snprintf(buf
, buf_len
, "\"%s\"", value
);
3439 fc_strlcpy(buf
, value
, buf_len
);
3444 /****************************************************************************
3445 Set the setting to 'val'. Returns TRUE on success. If it fails, the
3446 reason of the failure is available by the function setting_error().
3447 ****************************************************************************/
3448 bool setting_str_set(struct setting
*pset
, const char *val
,
3449 struct connection
*caller
, char *reject_msg
,
3450 size_t reject_msg_len
)
3452 if (!setting_is_changeable(pset
, caller
, reject_msg
, reject_msg_len
)
3453 || !setting_str_validate(pset
, val
, caller
, reject_msg
,
3458 fc_strlcpy(pset
->string
.value
, val
, pset
->string
.value_size
);
3462 /****************************************************************************
3463 Returns TRUE if 'val' is a valid value for this setting. If it's not,
3464 the reason of the failure is available by the function setting_error().
3466 FIXME: also check the access level of pconn.
3467 ****************************************************************************/
3468 bool setting_str_validate(const struct setting
*pset
, const char *val
,
3469 struct connection
*caller
, char *reject_msg
,
3470 size_t reject_msg_len
)
3472 if (SST_STRING
!= pset
->stype
) {
3473 settings_snprintf(reject_msg
, reject_msg_len
,
3474 _("This setting is not a string."));
3478 if (strlen(val
) >= pset
->string
.value_size
) {
3479 settings_snprintf(reject_msg
, reject_msg_len
,
3480 _("String value too long (max length: %lu)."),
3481 (unsigned long) pset
->string
.value_size
);
3485 return (!pset
->string
.validate
3486 || pset
->string
.validate(val
, caller
, reject_msg
,
3490 /****************************************************************************
3491 Get value of string setting
3492 ****************************************************************************/
3493 char *setting_str_get(struct setting
*pset
)
3495 fc_assert(setting_type(pset
) == SST_STRING
);
3497 return pset
->string
.value
;
3500 /****************************************************************************
3501 Convert the integer to the long support string representation of an
3502 enumerator. This function must match the secfile_enum_name_data_fn_t type.
3503 ****************************************************************************/
3504 const char *setting_enum_secfile_str(secfile_data_t data
, int val
)
3506 const struct sset_val_name
*name
=
3507 ((const struct setting
*) data
)->enumerator
.name(val
);
3509 return (NULL
!= name
? name
->support
: NULL
);
3512 /****************************************************************************
3513 Convert the integer to the string representation of an enumerator.
3514 Return NULL if 'val' is not a valid enumerator.
3515 ****************************************************************************/
3516 const char *setting_enum_val(const struct setting
*pset
, int val
,
3519 const struct sset_val_name
*name
;
3521 fc_assert_ret_val(SST_ENUM
== pset
->stype
, NULL
);
3522 name
= pset
->enumerator
.name(val
);
3525 } else if (pretty
) {
3526 return _(name
->pretty
);
3528 return name
->support
;
3532 /****************************************************************************
3533 Compute the string representation of the value for this enumerator
3535 ****************************************************************************/
3536 static const char *setting_enum_to_str(const struct setting
*pset
,
3537 int value
, bool pretty
,
3538 char *buf
, size_t buf_len
)
3540 const struct sset_val_name
*name
= pset
->enumerator
.name(value
);
3543 fc_snprintf(buf
, buf_len
, "\"%s\" (%s)",
3544 Q_(name
->pretty
), name
->support
);
3546 fc_strlcpy(buf
, name
->support
, buf_len
);
3551 /****************************************************************************
3552 Returns TRUE if 'val' is a valid value for this setting. If it's not,
3553 the reason of the failure is available in the optionnal parameter
3556 FIXME: also check the access level of pconn.
3557 ****************************************************************************/
3558 static bool setting_enum_validate_base(const struct setting
*pset
,
3559 const char *val
, int *pint_val
,
3560 struct connection
*caller
,
3562 size_t reject_msg_len
)
3566 if (SST_ENUM
!= pset
->stype
) {
3567 settings_snprintf(reject_msg
, reject_msg_len
,
3568 _("This setting is not an enumerator."));
3572 sz_strlcpy(buf
, val
);
3573 remove_leading_trailing_spaces(buf
);
3575 return (setting_match_prefix(pset
->enumerator
.name
, buf
, pint_val
,
3576 reject_msg
, reject_msg_len
)
3577 && (NULL
== pset
->enumerator
.validate
3578 || pset
->enumerator
.validate(*pint_val
, caller
, reject_msg
,
3582 /****************************************************************************
3583 Helper function to write value to enumerator setting
3584 ****************************************************************************/
3585 static bool set_enum_value(struct setting
*pset
, int val
)
3587 switch(pset
->enumerator
.store_size
) {
3590 int *to_int
= pset
->enumerator
.pvalue
;
3597 char *to_char
= pset
->enumerator
.pvalue
;
3599 *to_char
= (char) val
;
3604 short *to_short
= pset
->enumerator
.pvalue
;
3606 *to_short
= (short) val
;
3616 /****************************************************************************
3617 Helper function to read value from enumerator setting
3618 ****************************************************************************/
3619 int read_enum_value(const struct setting
*pset
)
3623 switch(pset
->enumerator
.store_size
) {
3625 val
= *((int *)pset
->enumerator
.pvalue
);
3628 val
= *((char *)pset
->enumerator
.pvalue
);
3631 val
= *((short *)pset
->enumerator
.pvalue
);
3634 log_error("Illegal enum store size %d, can't read value", pset
->enumerator
.store_size
);
3641 /****************************************************************************
3642 Set the setting to 'val'. Returns TRUE on success. If it fails, the
3643 reason of the failure is available in the optionnal parameter
3645 ****************************************************************************/
3646 bool setting_enum_set(struct setting
*pset
, const char *val
,
3647 struct connection
*caller
, char *reject_msg
,
3648 size_t reject_msg_len
)
3652 if (!setting_is_changeable(pset
, caller
, reject_msg
, reject_msg_len
)) {
3656 if (!setting_enum_validate_base(pset
, val
, &int_val
, caller
,
3657 reject_msg
, reject_msg_len
)) {
3661 if (!set_enum_value(pset
, int_val
)) {
3662 log_error("Illegal enumerator value size %d for %s",
3663 pset
->enumerator
.store_size
, val
);
3670 /****************************************************************************
3671 Returns TRUE if 'val' is a valid value for this setting. If it's not,
3672 the reason of the failure is available in the optionnal parameter
3674 ****************************************************************************/
3675 bool setting_enum_validate(const struct setting
*pset
, const char *val
,
3676 struct connection
*caller
, char *reject_msg
,
3677 size_t reject_msg_len
)
3681 return setting_enum_validate_base(pset
, val
, &int_val
, caller
,
3682 reject_msg
, reject_msg_len
);
3685 /****************************************************************************
3686 Convert the integer to the long support string representation of an
3687 enumerator. This function must match the secfile_enum_name_data_fn_t type.
3688 ****************************************************************************/
3689 const char *setting_bitwise_secfile_str(secfile_data_t data
, int bit
)
3691 const struct sset_val_name
*name
=
3692 ((const struct setting
*) data
)->bitwise
.name(bit
);
3694 return (NULL
!= name
? name
->support
: NULL
);
3697 /****************************************************************************
3698 Convert the bit number to its string representation.
3699 Return NULL if 'bit' is not a valid bit.
3700 ****************************************************************************/
3701 const char *setting_bitwise_bit(const struct setting
*pset
,
3702 int bit
, bool pretty
)
3704 const struct sset_val_name
*name
;
3706 fc_assert_ret_val(SST_BITWISE
== pset
->stype
, NULL
);
3707 name
= pset
->bitwise
.name(bit
);
3710 } else if (pretty
) {
3711 return _(name
->pretty
);
3713 return name
->support
;
3717 /****************************************************************************
3718 Compute the string representation of the value for this bitwise setting.
3719 ****************************************************************************/
3720 static const char *setting_bitwise_to_str(const struct setting
*pset
,
3721 unsigned value
, bool pretty
,
3722 char *buf
, size_t buf_len
)
3724 const struct sset_val_name
*name
;
3725 char *old_buf
= buf
;
3730 struct astring astr
= ASTRING_INIT
;
3731 struct strvec
*vec
= strvec_new();
3734 for (bit
= 0; (name
= pset
->bitwise
.name(bit
)); bit
++) {
3735 if ((1 << bit
) & value
) {
3736 /* TRANS: only emphasizing a string. */
3737 fc_snprintf(buf2
, sizeof(buf2
), _("\"%s\""), Q_(name
->pretty
));
3738 strvec_append(vec
, buf2
);
3742 if (0 == strvec_size(vec
)) {
3744 fc_assert(0 == value
);
3745 /* TRANS: Bitwise setting has no bits set. */
3746 fc_strlcpy(buf
, _("empty value"), buf_len
);
3747 strvec_destroy(vec
);
3751 strvec_to_and_list(vec
, &astr
);
3752 strvec_destroy(vec
);
3753 fc_strlcpy(buf
, astr_str(&astr
), buf_len
);
3755 fc_strlcat(buf
, " (", buf_len
);
3761 /* Long support part. */
3763 for (bit
= 0; (name
= pset
->bitwise
.name(bit
)); bit
++) {
3764 if ((1 << bit
) & value
) {
3765 if ('\0' != buf
[0]) {
3766 fc_strlcat(buf
, "|", buf_len
);
3768 fc_strlcat(buf
, name
->support
, buf_len
);
3773 fc_strlcat(buf
, ")", buf_len
);
3778 /****************************************************************************
3779 Returns TRUE if 'val' is a valid value for this setting. If it's not,
3780 the reason of the failure is available in the optionnal parameter
3783 FIXME: also check the access level of pconn.
3784 ****************************************************************************/
3785 static bool setting_bitwise_validate_base(const struct setting
*pset
,
3788 struct connection
*caller
,
3790 size_t reject_msg_len
)
3796 if (SST_BITWISE
!= pset
->stype
) {
3797 settings_snprintf(reject_msg
, reject_msg_len
,
3798 _("This setting is not a bitwise."));
3804 /* Value names are separated by '|'. */
3806 p
= strchr(val
, '|');
3809 fc_strlcpy(buf
, val
, MIN(p
- val
, sizeof(buf
)));
3811 /* Last segment, full copy. */
3812 sz_strlcpy(buf
, val
);
3814 remove_leading_trailing_spaces(buf
);
3815 if (NULL
== p
&& '\0' == buf
[0] && 0 == *pint_val
) {
3816 /* Empty string = value 0. */
3818 } else if (!setting_match_prefix(pset
->bitwise
.name
, buf
, &bit
,
3819 reject_msg
, reject_msg_len
)) {
3822 *pint_val
|= 1 << bit
;
3824 } while (NULL
!= p
);
3826 return (NULL
== pset
->bitwise
.validate
3827 || pset
->bitwise
.validate(*pint_val
, caller
,
3828 reject_msg
, reject_msg_len
));
3831 /****************************************************************************
3832 Set the setting to 'val'. Returns TRUE on success. If it fails, the
3833 reason of the failure is available in the optionnal parameter
3835 ****************************************************************************/
3836 bool setting_bitwise_set(struct setting
*pset
, const char *val
,
3837 struct connection
*caller
, char *reject_msg
,
3838 size_t reject_msg_len
)
3842 if (!setting_is_changeable(pset
, caller
, reject_msg
, reject_msg_len
)
3843 || !setting_bitwise_validate_base(pset
, val
, &int_val
, caller
,
3844 reject_msg
, reject_msg_len
)) {
3848 *pset
->bitwise
.pvalue
= int_val
;
3852 /****************************************************************************
3853 Returns TRUE if 'val' is a valid value for this setting. If it's not,
3854 the reason of the failure is available in the optionnal parameter
3856 ****************************************************************************/
3857 bool setting_bitwise_validate(const struct setting
*pset
, const char *val
,
3858 struct connection
*caller
, char *reject_msg
,
3859 size_t reject_msg_len
)
3863 return setting_bitwise_validate_base(pset
, val
, &int_val
, caller
,
3864 reject_msg
, reject_msg_len
);
3867 /****************************************************************************
3868 Get value of bitwise setting
3869 ****************************************************************************/
3870 int setting_bitwise_get(struct setting
*pset
)
3872 fc_assert(setting_type(pset
) == SST_BITWISE
);
3874 return *pset
->bitwise
.pvalue
;
3877 /****************************************************************************
3878 Compute the name of the current value of the setting.
3879 ****************************************************************************/
3880 const char *setting_value_name(const struct setting
*pset
, bool pretty
,
3881 char *buf
, size_t buf_len
)
3883 fc_assert_ret_val(NULL
!= pset
, NULL
);
3884 fc_assert_ret_val(NULL
!= buf
, NULL
);
3885 fc_assert_ret_val(0 < buf_len
, NULL
);
3887 switch (pset
->stype
) {
3889 return setting_bool_to_str(pset
, *pset
->boolean
.pvalue
,
3890 pretty
, buf
, buf_len
);
3892 return setting_int_to_str(pset
, *pset
->integer
.pvalue
,
3893 pretty
, buf
, buf_len
);
3895 return setting_str_to_str(pset
, pset
->string
.value
,
3896 pretty
, buf
, buf_len
);
3898 return setting_enum_to_str(pset
, read_enum_value(pset
),
3899 pretty
, buf
, buf_len
);
3901 return setting_bitwise_to_str(pset
, *pset
->bitwise
.pvalue
,
3902 pretty
, buf
, buf_len
);
3904 /* Error logged below. */
3908 log_error("%s(): Setting \"%s\" (nb %d) not handled in switch statement.",
3909 __FUNCTION__
, setting_name(pset
), setting_number(pset
));
3913 /****************************************************************************
3914 Compute the name of the default value of the setting.
3915 ****************************************************************************/
3916 const char *setting_default_name(const struct setting
*pset
, bool pretty
,
3917 char *buf
, size_t buf_len
)
3919 fc_assert_ret_val(NULL
!= pset
, NULL
);
3920 fc_assert_ret_val(NULL
!= buf
, NULL
);
3921 fc_assert_ret_val(0 < buf_len
, NULL
);
3923 switch (pset
->stype
) {
3925 return setting_bool_to_str(pset
, pset
->boolean
.default_value
,
3926 pretty
, buf
, buf_len
);
3928 return setting_int_to_str(pset
, pset
->integer
.default_value
,
3929 pretty
, buf
, buf_len
);
3931 return setting_str_to_str(pset
, pset
->string
.default_value
,
3932 pretty
, buf
, buf_len
);
3934 return setting_enum_to_str(pset
, pset
->enumerator
.default_value
,
3935 pretty
, buf
, buf_len
);
3937 return setting_bitwise_to_str(pset
, pset
->bitwise
.default_value
,
3938 pretty
, buf
, buf_len
);
3940 /* Error logged below. */
3944 log_error("%s(): Setting \"%s\" (nb %d) not handled in switch statement.",
3945 __FUNCTION__
, setting_name(pset
), setting_number(pset
));
3949 /****************************************************************************
3950 Update the setting to the default value
3951 ****************************************************************************/
3952 void setting_set_to_default(struct setting
*pset
)
3954 switch (pset
->stype
) {
3956 (*pset
->boolean
.pvalue
) = pset
->boolean
.default_value
;
3959 (*pset
->integer
.pvalue
) = pset
->integer
.default_value
;
3962 fc_strlcpy(pset
->string
.value
, pset
->string
.default_value
,
3963 pset
->string
.value_size
);
3966 set_enum_value(pset
, pset
->enumerator
.default_value
);
3969 (*pset
->bitwise
.pvalue
) = pset
->bitwise
.default_value
;
3972 fc_assert(pset
->stype
!= SST_COUNT
);
3976 pset
->setdef
= SETDEF_INTERNAL
;
3979 /********************************************************************
3980 Execute the action callback if needed.
3981 *********************************************************************/
3982 void setting_action(const struct setting
*pset
)
3984 if (pset
->action
!= NULL
) {
3989 /**************************************************************************
3990 Load game settings from ruleset file 'game.ruleset'.
3991 **************************************************************************/
3992 bool settings_ruleset(struct section_file
*file
, const char *section
,
3998 /* Unlock all settings. */
3999 settings_iterate(SSET_ALL
, pset
) {
4000 setting_lock_set(pset
, FALSE
);
4001 setting_set_to_default(pset
);
4002 } settings_iterate_end
;
4005 if (NULL
== secfile_section_by_name(file
, section
)) {
4006 /* no settings in ruleset file */
4007 log_verbose("no [%s] section for game settings in %s", section
,
4008 secfile_name(file
));
4010 for (j
= 0; (name
= secfile_lookup_str_default(file
, NULL
, "%s.set%d.name",
4011 section
, j
)); j
++) {
4013 fc_snprintf(path
, sizeof(path
), "%s.set%d", section
, j
);
4015 if (!setting_ruleset_one(file
, name
, path
)) {
4016 log_error("unknown setting in '%s': %s", secfile_name(file
), name
);
4021 /* Execute all setting actions to consider actions due to the
4022 * default values. */
4024 settings_iterate(SSET_ALL
, pset
) {
4025 setting_action(pset
);
4026 } settings_iterate_end
;
4029 autolock_settings();
4031 /* send game settings */
4032 send_server_settings(NULL
);
4037 /**************************************************************************
4038 Set one setting from the game.ruleset file.
4039 **************************************************************************/
4040 static bool setting_ruleset_one(struct section_file
*file
,
4041 const char *name
, const char *path
)
4043 struct setting
*pset
= NULL
;
4044 char reject_msg
[256], buf
[256];
4047 settings_iterate(SSET_ALL
, pset_check
) {
4048 if (0 == fc_strcasecmp(setting_name(pset_check
), name
)) {
4052 } settings_iterate_end
;
4055 /* no setting found */
4059 switch (pset
->stype
) {
4065 /* Allow string with same boolean representation as accepted on
4066 * server command line */
4067 if (secfile_lookup_enum_data(file
, &ival
, FALSE
,
4068 setting_bool_secfile_str
, pset
,
4069 "%s.value", path
)) {
4071 } else if (!secfile_lookup_bool(file
, &val
, "%s.value", path
)) {
4072 log_error("Can't read value for setting '%s': %s", name
,
4076 if (val
!= *pset
->boolean
.pvalue
) {
4077 if (NULL
== pset
->boolean
.validate
4078 || pset
->boolean
.validate(val
, NULL
, reject_msg
,
4079 sizeof(reject_msg
))) {
4080 *pset
->boolean
.pvalue
= val
;
4081 log_normal(_("Ruleset: '%s' has been set to %s."),
4083 setting_value_name(pset
, TRUE
, buf
, sizeof(buf
)));
4085 log_error("%s", reject_msg
);
4095 if (!secfile_lookup_int(file
, &val
, "%s.value", path
)) {
4096 log_error("Can't read value for setting '%s': %s", name
,
4098 } else if (val
!= *pset
->integer
.pvalue
) {
4099 if (setting_int_set(pset
, val
, NULL
, reject_msg
,
4100 sizeof(reject_msg
))) {
4101 log_normal(_("Ruleset: '%s' has been set to %s."),
4103 setting_value_name(pset
, TRUE
, buf
, sizeof(buf
)));
4105 log_error("%s", reject_msg
);
4113 const char *val
= secfile_lookup_str(file
, "%s.value", path
);
4116 log_error("Can't read value for setting '%s': %s", name
,
4118 } else if (0 != strcmp(val
, pset
->string
.value
)) {
4119 if (setting_str_set(pset
, val
, NULL
, reject_msg
,
4120 sizeof(reject_msg
))) {
4121 log_normal(_("Ruleset: '%s' has been set to %s."),
4123 setting_value_name(pset
, TRUE
, buf
, sizeof(buf
)));
4125 log_error("%s", reject_msg
);
4135 if (!secfile_lookup_enum_data(file
, &val
, FALSE
,
4136 setting_enum_secfile_str
, pset
,
4137 "%s.value", path
)) {
4138 log_error("Can't read value for setting '%s': %s",
4139 name
, secfile_error());
4140 } else if (val
!= read_enum_value(pset
)) {
4141 if (NULL
== pset
->enumerator
.validate
4142 || pset
->enumerator
.validate(val
, NULL
, reject_msg
,
4143 sizeof(reject_msg
))) {
4144 set_enum_value(pset
, val
);
4145 log_normal(_("Ruleset: '%s' has been set to %s."),
4147 setting_value_name(pset
, TRUE
, buf
, sizeof(buf
)));
4149 log_error("%s", reject_msg
);
4159 if (!secfile_lookup_enum_data(file
, &val
, TRUE
,
4160 setting_bitwise_secfile_str
, pset
,
4161 "%s.value", path
)) {
4162 log_error("Can't read value for setting '%s': %s",
4163 name
, secfile_error());
4164 } else if (val
!= *pset
->bitwise
.pvalue
) {
4165 if (NULL
== pset
->bitwise
.validate
4166 || pset
->bitwise
.validate((unsigned) val
, NULL
,
4167 reject_msg
, sizeof(reject_msg
))) {
4168 *pset
->bitwise
.pvalue
= val
;
4169 log_normal(_("Ruleset: '%s' has been set to %s."),
4171 setting_value_name(pset
, TRUE
, buf
, sizeof(buf
)));
4173 log_error("%s", reject_msg
);
4180 fc_assert(pset
->stype
!= SST_COUNT
);
4184 pset
->setdef
= SETDEF_RULESET
;
4187 lock
= secfile_lookup_bool_default(file
, FALSE
, "%s.lock", path
);
4191 setting_lock_set(pset
, lock
);
4192 log_normal(_("Ruleset: '%s' has been locked by the ruleset."),
4193 setting_name(pset
));
4199 /**************************************************************************
4200 Returns whether the setting has non-default value.
4201 **************************************************************************/
4202 bool setting_non_default(const struct setting
*pset
)
4204 switch (setting_type(pset
)) {
4206 return (*pset
->boolean
.pvalue
!= pset
->boolean
.default_value
);
4208 return (*pset
->integer
.pvalue
!= pset
->integer
.default_value
);
4210 return (0 != strcmp(pset
->string
.value
, pset
->string
.default_value
));
4212 return (read_enum_value(pset
) != pset
->enumerator
.default_value
);
4214 return (*pset
->bitwise
.pvalue
!= pset
->bitwise
.default_value
);
4216 /* Error logged below. */
4220 log_error("%s(): Setting \"%s\" (nb %d) not handled in switch statement.",
4221 __FUNCTION__
, setting_name(pset
), setting_number(pset
));
4225 /**************************************************************************
4226 Returns if the setting is locked by the ruleset.
4227 **************************************************************************/
4228 bool setting_locked(const struct setting
*pset
)
4230 return pset
->locked
;
4233 /**************************************************************************
4234 Set the value for the lock of a setting.
4235 **************************************************************************/
4236 void setting_lock_set(struct setting
*pset
, bool lock
)
4238 pset
->locked
= lock
;
4241 /**************************************************************************
4242 Save the setting value of the current game.
4243 **************************************************************************/
4244 static void setting_game_set(struct setting
*pset
, bool init
)
4246 switch (setting_type(pset
)) {
4248 pset
->boolean
.game_value
= *pset
->boolean
.pvalue
;
4252 pset
->integer
.game_value
= *pset
->integer
.pvalue
;
4257 pset
->string
.game_value
4258 = fc_calloc(1, pset
->string
.value_size
4259 * sizeof(pset
->string
.game_value
));
4261 fc_strlcpy(pset
->string
.game_value
, pset
->string
.value
,
4262 pset
->string
.value_size
);
4266 pset
->enumerator
.game_value
= read_enum_value(pset
);
4270 pset
->bitwise
.game_value
= *pset
->bitwise
.pvalue
;
4274 fc_assert(setting_type(pset
) != SST_COUNT
);
4279 /**************************************************************************
4280 Free the memory used for the settings at game start.
4281 **************************************************************************/
4282 static void setting_game_free(struct setting
*pset
)
4284 if (setting_type(pset
) == SST_STRING
) {
4285 FC_FREE(pset
->string
.game_value
);
4289 /**************************************************************************
4290 Restore the setting to the value used at the start of the current game.
4291 **************************************************************************/
4292 static void setting_game_restore(struct setting
*pset
)
4294 char reject_msg
[256] = "", buf
[256];
4297 if (!setting_is_changeable(pset
, NULL
, reject_msg
, sizeof(reject_msg
))) {
4298 log_debug("Can't restore '%s': %s", setting_name(pset
),
4303 switch (setting_type(pset
)) {
4305 res
= (NULL
!= setting_bool_to_str(pset
, pset
->boolean
.game_value
,
4306 FALSE
, buf
, sizeof(buf
))
4307 && setting_bool_set(pset
, buf
, NULL
, reject_msg
,
4308 sizeof(reject_msg
)));
4312 res
= setting_int_set(pset
, pset
->integer
.game_value
, NULL
, reject_msg
,
4313 sizeof(reject_msg
));
4317 res
= setting_str_set(pset
, pset
->string
.game_value
, NULL
, reject_msg
,
4318 sizeof(reject_msg
));
4322 res
= (NULL
!= setting_enum_to_str(pset
, pset
->enumerator
.game_value
,
4323 FALSE
, buf
, sizeof(buf
))
4324 && setting_enum_set(pset
, buf
, NULL
, reject_msg
,
4325 sizeof(reject_msg
)));
4329 res
= (NULL
!= setting_bitwise_to_str(pset
, pset
->bitwise
.game_value
,
4330 FALSE
, buf
, sizeof(buf
))
4331 && setting_bitwise_set(pset
, buf
, NULL
, reject_msg
,
4332 sizeof(reject_msg
)));
4341 log_error("Error restoring setting '%s' to the value from game start: "
4342 "%s", setting_name(pset
), reject_msg
);
4346 /**************************************************************************
4347 Save setting values at the start of the game.
4348 **************************************************************************/
4349 void settings_game_start(void)
4351 settings_iterate(SSET_ALL
, pset
) {
4352 setting_game_set(pset
, FALSE
);
4353 } settings_iterate_end
;
4355 /* Settings from the start of the game are saved. */
4356 game
.server
.settings_gamestart_valid
= TRUE
;
4359 /********************************************************************
4361 *********************************************************************/
4362 void settings_game_save(struct section_file
*file
, const char *section
)
4366 settings_iterate(SSET_ALL
, pset
) {
4369 if (/* It's explicitly set to some value to save */
4370 setting_get_setdef(pset
) == SETDEF_CHANGED
4371 /* It must be same at loading time as it was saving time, even if
4372 * freeciv's default has changed. */
4373 || !setting_is_free_to_change(pset
, errbuf
, sizeof(errbuf
))) {
4374 secfile_insert_str(file
, setting_name(pset
),
4375 "%s.set%d.name", section
, set_count
);
4376 switch (setting_type(pset
)) {
4378 secfile_insert_bool(file
, *pset
->boolean
.pvalue
,
4379 "%s.set%d.value", section
, set_count
);
4380 secfile_insert_bool(file
, pset
->boolean
.game_value
,
4381 "%s.set%d.gamestart", section
, set_count
);
4384 secfile_insert_int(file
, *pset
->integer
.pvalue
,
4385 "%s.set%d.value", section
, set_count
);
4386 secfile_insert_int(file
, pset
->integer
.game_value
,
4387 "%s.set%d.gamestart", section
, set_count
);
4390 secfile_insert_str(file
, pset
->string
.value
,
4391 "%s.set%d.value", section
, set_count
);
4392 secfile_insert_str(file
, pset
->string
.game_value
,
4393 "%s.set%d.gamestart", section
, set_count
);
4396 secfile_insert_enum_data(file
, read_enum_value(pset
), FALSE
,
4397 setting_enum_secfile_str
, pset
,
4398 "%s.set%d.value", section
, set_count
);
4399 secfile_insert_enum_data(file
, pset
->enumerator
.game_value
, FALSE
,
4400 setting_enum_secfile_str
, pset
,
4401 "%s.set%d.gamestart", section
, set_count
);
4404 secfile_insert_enum_data(file
, *pset
->bitwise
.pvalue
, TRUE
,
4405 setting_bitwise_secfile_str
, pset
,
4406 "%s.set%d.value", section
, set_count
);
4407 secfile_insert_enum_data(file
, pset
->bitwise
.game_value
, TRUE
,
4408 setting_bitwise_secfile_str
, pset
,
4409 "%s.set%d.gamestart", section
, set_count
);
4412 fc_assert(setting_type(pset
) != SST_COUNT
);
4413 secfile_insert_str(file
, "Unknown setting type",
4414 "%s.set%d.value", section
, set_count
);
4415 secfile_insert_str(file
, "Unknown setting type",
4416 "%s.set%d.gamestart", section
, set_count
);
4421 } settings_iterate_end
;
4423 secfile_insert_int(file
, set_count
, "%s.set_count", section
);
4424 secfile_insert_bool(file
, game
.server
.settings_gamestart_valid
,
4425 "%s.gamestart_valid", section
);
4428 /********************************************************************
4429 Restore all settings from a savegame.
4430 *********************************************************************/
4431 void settings_game_load(struct section_file
*file
, const char *section
)
4434 char reject_msg
[256], buf
[256];
4436 int oldcitymindist
= game
.info
.citymindist
; /* backwards compat, see below */
4438 /* Compatibility with savegames created with older versions is usually
4439 * handled as conversions in savecompat.c compat_load_<version>() */
4441 if (!secfile_lookup_int(file
, &set_count
, "%s.set_count", section
)) {
4442 /* Old savegames and scenarios doesn't contain this, not an error. */
4443 log_verbose("Can't read the number of settings in the save file.");
4447 /* Check if the saved settings are valid settings from game start. */
4448 game
.server
.settings_gamestart_valid
4449 = secfile_lookup_bool_default(file
, FALSE
, "%s.gamestart_valid",
4452 for (i
= 0; i
< set_count
; i
++) {
4453 name
= secfile_lookup_str(file
, "%s.set%d.name", section
, i
);
4455 settings_iterate(SSET_ALL
, pset
) {
4456 if (fc_strcasecmp(setting_name(pset
), name
) != 0) {
4460 /* Load the current value of the setting. */
4461 switch (pset
->stype
) {
4466 if (!secfile_lookup_bool(file
, &val
, "%s.set%d.value", section
,
4468 log_verbose("Option '%s' not defined in the savegame: %s", name
,
4471 pset
->setdef
= SETDEF_CHANGED
;
4473 if (val
!= *pset
->boolean
.pvalue
) {
4474 if (setting_is_changeable(pset
, NULL
, reject_msg
,
4476 && (NULL
== pset
->boolean
.validate
4477 || pset
->boolean
.validate(val
, NULL
, reject_msg
,
4478 sizeof(reject_msg
)))) {
4479 *pset
->boolean
.pvalue
= val
;
4480 log_normal(_("Savegame: '%s' has been set to %s."),
4482 setting_value_name(pset
, TRUE
, buf
, sizeof(buf
)));
4484 log_error("Savegame: error restoring '%s' . (%s)",
4485 setting_name(pset
), reject_msg
);
4488 log_normal(_("Savegame: '%s' explicitly set to value same as default."),
4489 setting_name(pset
));
4499 if (!secfile_lookup_int(file
, &val
, "%s.set%d.value", section
, i
)) {
4500 log_verbose("Option '%s' not defined in the savegame: %s", name
,
4503 pset
->setdef
= SETDEF_CHANGED
;
4505 if (val
!= *pset
->integer
.pvalue
) {
4506 if (setting_is_changeable(pset
, NULL
, reject_msg
,
4508 && (NULL
== pset
->integer
.validate
4509 || pset
->integer
.validate(val
, NULL
, reject_msg
,
4510 sizeof(reject_msg
)))) {
4511 *pset
->integer
.pvalue
= val
;
4512 log_normal(_("Savegame: '%s' has been set to %s."),
4514 setting_value_name(pset
, TRUE
, buf
, sizeof(buf
)));
4516 log_error("Savegame: error restoring '%s' . (%s)",
4517 setting_name(pset
), reject_msg
);
4520 log_normal(_("Savegame: '%s' explicitly set to value same as default."),
4521 setting_name(pset
));
4529 const char *val
= secfile_lookup_str(file
, "%s.set%d.value",
4533 log_verbose("Option '%s' not defined in the savegame: %s", name
,
4536 pset
->setdef
= SETDEF_CHANGED
;
4538 if (0 != strcmp(val
, pset
->string
.value
)) {
4539 if (setting_str_set(pset
, val
, NULL
, reject_msg
,
4540 sizeof(reject_msg
))) {
4541 log_normal(_("Savegame: '%s' has been set to %s."),
4543 setting_value_name(pset
, TRUE
, buf
, sizeof(buf
)));
4545 log_error("Savegame: error restoring '%s' . (%s)",
4546 setting_name(pset
), reject_msg
);
4549 log_normal(_("Savegame: '%s' explicitly set to value same as default."),
4550 setting_name(pset
));
4560 if (!secfile_lookup_enum_data(file
, &val
, FALSE
,
4561 setting_enum_secfile_str
, pset
,
4562 "%s.set%d.value", section
, i
)) {
4563 log_verbose("Option '%s' not defined in the savegame: %s", name
,
4566 pset
->setdef
= SETDEF_CHANGED
;
4568 if (val
!= read_enum_value(pset
)) {
4569 if (setting_is_changeable(pset
, NULL
, reject_msg
,
4571 && (NULL
== pset
->enumerator
.validate
4572 || pset
->enumerator
.validate(val
, NULL
, reject_msg
,
4573 sizeof(reject_msg
)))) {
4574 set_enum_value(pset
, val
);
4575 log_normal(_("Savegame: '%s' has been set to %s."),
4577 setting_value_name(pset
, TRUE
, buf
, sizeof(buf
)));
4579 log_error("Savegame: error restoring '%s' . (%s)",
4580 setting_name(pset
), reject_msg
);
4583 log_normal(_("Savegame: '%s' explicitly set to value same as default."),
4584 setting_name(pset
));
4594 if (!secfile_lookup_enum_data(file
, &val
, TRUE
,
4595 setting_bitwise_secfile_str
, pset
,
4596 "%s.set%d.value", section
, i
)) {
4597 log_verbose("Option '%s' not defined in the savegame: %s", name
,
4600 pset
->setdef
= SETDEF_CHANGED
;
4602 if (val
!= *pset
->bitwise
.pvalue
) {
4603 if (setting_is_changeable(pset
, NULL
, reject_msg
,
4605 && (NULL
== pset
->bitwise
.validate
4606 || pset
->bitwise
.validate(val
, NULL
, reject_msg
,
4607 sizeof(reject_msg
)))) {
4608 *pset
->bitwise
.pvalue
= val
;
4609 log_normal(_("Savegame: '%s' has been set to %s."),
4611 setting_value_name(pset
, TRUE
, buf
, sizeof(buf
)));
4613 log_error("Savegame: error restoring '%s' . (%s)",
4614 setting_name(pset
), reject_msg
);
4617 log_normal(_("Savegame: '%s' explicitly set to value same as default."),
4618 setting_name(pset
));
4625 fc_assert(pset
->stype
!= SST_COUNT
);
4629 if (game
.server
.settings_gamestart_valid
) {
4630 /* Load the value of the setting at the start of the game. */
4631 switch (pset
->stype
) {
4633 pset
->boolean
.game_value
=
4634 secfile_lookup_bool_default(file
, *pset
->boolean
.pvalue
,
4635 "%s.set%d.gamestart", section
, i
);
4639 pset
->integer
.game_value
=
4640 secfile_lookup_int_default(file
, *pset
->integer
.pvalue
,
4641 "%s.set%d.gamestart", section
, i
);
4645 fc_strlcpy(pset
->string
.game_value
,
4646 secfile_lookup_str_default(file
, pset
->string
.value
,
4647 "%s.set%d.gamestart",
4649 pset
->string
.value_size
);
4653 pset
->enumerator
.game_value
=
4654 secfile_lookup_enum_default_data(file
,
4655 read_enum_value(pset
), FALSE
, setting_enum_secfile_str
,
4656 pset
, "%s.set%d.gamestart", section
, i
);
4660 pset
->bitwise
.game_value
=
4661 secfile_lookup_enum_default_data(file
,
4662 *pset
->bitwise
.pvalue
, TRUE
, setting_bitwise_secfile_str
,
4663 pset
, "%s.set%d.gamestart", section
, i
);
4667 fc_assert(pset
->stype
!= SST_COUNT
);
4671 pset
->setdef
= SETDEF_CHANGED
;
4673 } settings_iterate_end
;
4676 /* Backwards compatibility for pre-2.4 savegames: citymindist=0 used to mean
4677 * take from ruleset min_dist_bw_cities, but that no longer exists.
4678 * This is here rather than in savegame2.c compat functions, as we need
4679 * to have loaded the relevant ruleset to know what to set it to (the
4680 * ruleset and any 'citymindist' setting it contains will have been loaded
4681 * before this function was called). */
4682 if (game
.info
.citymindist
== 0) {
4683 game
.info
.citymindist
= oldcitymindist
;
4686 settings_iterate(SSET_ALL
, pset
) {
4687 /* Have to do this at the end due to dependencies ('aifill' and
4689 setting_action(pset
);
4690 } settings_iterate_end
;
4693 /**************************************************************************
4694 Reset all settings to the values at game start.
4695 **************************************************************************/
4696 bool settings_game_reset(void)
4698 if (!game
.server
.settings_gamestart_valid
) {
4699 log_debug("No saved settings from the game start available.");
4703 settings_iterate(SSET_ALL
, pset
) {
4704 setting_game_restore(pset
);
4705 } settings_iterate_end
;
4710 /**************************************************************************
4711 Initialize stuff related to this code module.
4712 **************************************************************************/
4713 void settings_init(bool act
)
4715 settings_list_init();
4717 settings_iterate(SSET_ALL
, pset
) {
4718 setting_lock_set(pset
, FALSE
);
4719 setting_set_to_default(pset
);
4720 setting_game_set(pset
, TRUE
);
4722 setting_action(pset
);
4724 } settings_iterate_end
;
4726 settings_list_update();
4729 /********************************************************************
4730 Reset all settings iff they are changeable.
4731 *********************************************************************/
4732 void settings_reset(void)
4734 settings_iterate(SSET_ALL
, pset
) {
4735 if (setting_is_changeable(pset
, NULL
, NULL
, 0)) {
4736 setting_set_to_default(pset
);
4737 setting_action(pset
);
4739 } settings_iterate_end
;
4742 /**************************************************************************
4743 Update stuff every turn that is related to this code module. Run this
4745 **************************************************************************/
4746 void settings_turn(void)
4748 /* Nothing at the moment. */
4751 /**************************************************************************
4752 Deinitialize stuff related to this code module.
4753 **************************************************************************/
4754 void settings_free(void)
4756 settings_iterate(SSET_ALL
, pset
) {
4757 setting_game_free(pset
);
4758 } settings_iterate_end
;
4760 settings_list_free();
4763 /****************************************************************************
4764 Returns the total number of settings.
4765 ****************************************************************************/
4766 int settings_number(void)
4768 return SETTINGS_NUM
;
4771 /****************************************************************************
4772 Tell the client about just one server setting. Call this after a setting
4774 ****************************************************************************/
4775 void send_server_setting(struct conn_list
*dest
, const struct setting
*pset
)
4778 dest
= game
.est_connections
;
4781 #define PACKET_COMMON_INIT(packet, pset, pconn) \
4782 memset(&packet, 0, sizeof(packet)); \
4783 packet.id = setting_number(pset); \
4784 packet.is_visible = setting_is_visible(pset, pconn); \
4785 packet.is_changeable = setting_is_changeable(pset, pconn, NULL, 0); \
4786 packet.initial_setting = game.info.is_new_game;
4788 switch (setting_type(pset
)) {
4791 struct packet_server_setting_bool packet
;
4793 conn_list_iterate(dest
, pconn
) {
4794 PACKET_COMMON_INIT(packet
, pset
, pconn
);
4795 if (packet
.is_visible
) {
4796 packet
.val
= *pset
->boolean
.pvalue
;
4797 packet
.default_val
= pset
->boolean
.default_value
;
4799 send_packet_server_setting_bool(pconn
, &packet
);
4800 } conn_list_iterate_end
;
4805 struct packet_server_setting_int packet
;
4807 conn_list_iterate(dest
, pconn
) {
4808 PACKET_COMMON_INIT(packet
, pset
, pconn
);
4809 if (packet
.is_visible
) {
4810 packet
.val
= *pset
->integer
.pvalue
;
4811 packet
.default_val
= pset
->integer
.default_value
;
4812 packet
.min_val
= pset
->integer
.min_value
;
4813 packet
.max_val
= pset
->integer
.max_value
;
4815 send_packet_server_setting_int(pconn
, &packet
);
4816 } conn_list_iterate_end
;
4821 struct packet_server_setting_str packet
;
4823 conn_list_iterate(dest
, pconn
) {
4824 PACKET_COMMON_INIT(packet
, pset
, pconn
);
4825 if (packet
.is_visible
) {
4826 sz_strlcpy(packet
.val
, pset
->string
.value
);
4827 sz_strlcpy(packet
.default_val
, pset
->string
.default_value
);
4829 send_packet_server_setting_str(pconn
, &packet
);
4830 } conn_list_iterate_end
;
4835 struct packet_server_setting_enum packet
;
4836 const struct sset_val_name
*val_name
;
4839 conn_list_iterate(dest
, pconn
) {
4840 PACKET_COMMON_INIT(packet
, pset
, pconn
);
4841 if (packet
.is_visible
) {
4842 packet
.val
= read_enum_value(pset
);
4843 packet
.default_val
= pset
->enumerator
.default_value
;
4844 for (i
= 0; (val_name
= pset
->enumerator
.name(i
)); i
++) {
4845 sz_strlcpy(packet
.support_names
[i
], val_name
->support
);
4846 /* Send untranslated string */
4847 sz_strlcpy(packet
.pretty_names
[i
], val_name
->pretty
);
4849 packet
.values_num
= i
;
4850 fc_assert(i
<= ARRAY_SIZE(packet
.support_names
));
4851 fc_assert(i
<= ARRAY_SIZE(packet
.pretty_names
));
4853 send_packet_server_setting_enum(pconn
, &packet
);
4854 } conn_list_iterate_end
;
4859 struct packet_server_setting_bitwise packet
;
4860 const struct sset_val_name
*val_name
;
4863 conn_list_iterate(dest
, pconn
) {
4864 PACKET_COMMON_INIT(packet
, pset
, pconn
);
4865 if (packet
.is_visible
) {
4866 packet
.val
= *pset
->bitwise
.pvalue
;
4867 packet
.default_val
= pset
->bitwise
.default_value
;
4868 for (i
= 0; (val_name
= pset
->bitwise
.name(i
)); i
++) {
4869 sz_strlcpy(packet
.support_names
[i
], val_name
->support
);
4870 /* Send untranslated string */
4871 sz_strlcpy(packet
.pretty_names
[i
], val_name
->pretty
);
4873 packet
.bits_num
= i
;
4874 fc_assert(i
<= ARRAY_SIZE(packet
.support_names
));
4875 fc_assert(i
<= ARRAY_SIZE(packet
.pretty_names
));
4877 send_packet_server_setting_bitwise(pconn
, &packet
);
4878 } conn_list_iterate_end
;
4883 fc_assert(setting_type(pset
) != SST_COUNT
);
4890 /****************************************************************************
4891 Tell the client about all server settings.
4892 ****************************************************************************/
4893 void send_server_settings(struct conn_list
*dest
)
4895 settings_iterate(SSET_ALL
, pset
) {
4896 send_server_setting(dest
, pset
);
4897 } settings_iterate_end
;
4900 /***************************************************************************
4901 Send the server settings that got a different visibility or changability
4902 after a connection access level change. Usually called when the access
4903 level of the user changes.
4904 ***************************************************************************/
4905 void send_server_access_level_settings(struct conn_list
*dest
,
4906 enum cmdlevel old_level
,
4907 enum cmdlevel new_level
)
4909 enum cmdlevel min_level
;
4910 enum cmdlevel max_level
;
4912 if (old_level
== new_level
) {
4916 if (old_level
< new_level
) {
4917 min_level
= old_level
;
4918 max_level
= new_level
;
4920 min_level
= new_level
;
4921 max_level
= old_level
;
4924 settings_iterate(SSET_ALL
, pset
) {
4925 if ((pset
->access_level_read
>= min_level
4926 && pset
->access_level_read
<= max_level
)
4927 || (pset
->access_level_write
>= min_level
4928 && pset
->access_level_write
<= max_level
)) {
4929 send_server_setting(dest
, pset
);
4931 } settings_iterate_end
;
4934 /****************************************************************************
4935 Tell the client about all server settings.
4936 ****************************************************************************/
4937 void send_server_setting_control(struct connection
*pconn
)
4939 struct packet_server_setting_control control
;
4940 struct packet_server_setting_const setting
;
4943 control
.settings_num
= SETTINGS_NUM
;
4945 /* Fill in the category strings. */
4946 fc_assert(SSET_NUM_CATEGORIES
<= ARRAY_SIZE(control
.category_names
));
4947 control
.categories_num
= SSET_NUM_CATEGORIES
;
4948 for (i
= 0; i
< SSET_NUM_CATEGORIES
; i
++) {
4949 /* Send untranslated name */
4950 sz_strlcpy(control
.category_names
[i
], sset_category_name(i
));
4953 /* Send off the control packet. */
4954 send_packet_server_setting_control(pconn
, &control
);
4956 /* Send the constant and common part of the settings. */
4957 settings_iterate(SSET_ALL
, pset
) {
4958 setting
.id
= setting_number(pset
);
4959 sz_strlcpy(setting
.name
, setting_name(pset
));
4960 /* Send untranslated strings to client */
4961 sz_strlcpy(setting
.short_help
, setting_short_help(pset
));
4962 sz_strlcpy(setting
.extra_help
, setting_extra_help(pset
, TRUE
));
4963 setting
.category
= pset
->scategory
;
4965 send_packet_server_setting_const(pconn
, &setting
);
4966 } settings_iterate_end
;
4969 /*****************************************************************************
4970 Initialise sorted settings.
4971 *****************************************************************************/
4972 static void settings_list_init(void)
4974 struct setting
*pset
;
4977 fc_assert_ret(setting_sorted
.init
== FALSE
);
4979 /* Do it for all values of enum sset_level. */
4980 for (i
= 0; i
< OLEVELS_NUM
; i
++) {
4981 setting_sorted
.level
[i
] = setting_list_new();
4984 for (i
= 0; (pset
= setting_by_number(i
)); i
++) {
4985 /* Add the setting to the list of all settings. */
4986 setting_list_append(setting_sorted
.level
[SSET_ALL
], pset
);
4988 switch (setting_level(pset
)) {
4990 /* No setting should be in this level. */
4991 fc_assert_msg(setting_level(pset
) != SSET_NONE
,
4992 "No setting level defined for '%s'.", setting_name(pset
));
4995 /* Done above - list of all settings. */
4998 setting_list_append(setting_sorted
.level
[SSET_VITAL
], pset
);
5000 case SSET_SITUATIONAL
:
5001 setting_list_append(setting_sorted
.level
[SSET_SITUATIONAL
], pset
);
5004 setting_list_append(setting_sorted
.level
[SSET_RARE
], pset
);
5008 /* This is done in settings_list_update. */
5011 /* No setting should be in this level. */
5012 fc_assert_msg(setting_level(pset
) != OLEVELS_NUM
,
5013 "Invalid setting level for '%s' (%s).",
5014 setting_name(pset
), sset_level_name(setting_level(pset
)));
5019 /* Sort the lists. */
5020 for (i
= 0; i
< OLEVELS_NUM
; i
++) {
5021 setting_list_sort(setting_sorted
.level
[i
], settings_list_cmp
);
5024 setting_sorted
.init
= TRUE
;
5027 /*****************************************************************************
5028 Update sorted settings (changed and locked values).
5029 *****************************************************************************/
5030 void settings_list_update(void)
5032 struct setting
*pset
;
5035 fc_assert_ret(setting_sorted
.init
== TRUE
);
5037 /* Clear the lists for changed and locked values. */
5038 setting_list_clear(setting_sorted
.level
[SSET_CHANGED
]);
5039 setting_list_clear(setting_sorted
.level
[SSET_LOCKED
]);
5042 for (i
= 0; (pset
= setting_by_number(i
)); i
++) {
5043 if (setting_non_default(pset
)) {
5044 setting_list_append(setting_sorted
.level
[SSET_CHANGED
], pset
);
5046 if (setting_locked(pset
)) {
5047 setting_list_append(setting_sorted
.level
[SSET_LOCKED
], pset
);
5052 setting_list_sort(setting_sorted
.level
[SSET_CHANGED
], settings_list_cmp
);
5053 setting_list_sort(setting_sorted
.level
[SSET_LOCKED
], settings_list_cmp
);
5056 /*****************************************************************************
5057 Update sorted settings (changed and locked values).
5058 *****************************************************************************/
5059 int settings_list_cmp(const struct setting
*const *ppset1
,
5060 const struct setting
*const *ppset2
)
5062 const struct setting
*pset1
= *ppset1
;
5063 const struct setting
*pset2
= *ppset2
;
5065 return fc_strcasecmp(setting_name(pset1
), setting_name(pset2
));
5068 /*****************************************************************************
5069 Get a settings list of a certain level. Call settings_list_update() before
5070 if something was changed.
5071 *****************************************************************************/
5072 struct setting_list
*settings_list_get(enum sset_level level
)
5074 fc_assert_ret_val(setting_sorted
.init
== TRUE
, NULL
);
5075 fc_assert_ret_val(setting_sorted
.level
[level
] != NULL
, NULL
);
5076 fc_assert_ret_val(sset_level_is_valid(level
), NULL
);
5078 return setting_sorted
.level
[level
];
5081 /*****************************************************************************
5082 Free sorted settings.
5083 *****************************************************************************/
5084 static void settings_list_free(void)
5088 fc_assert_ret(setting_sorted
.init
== TRUE
);
5090 /* Free the lists. */
5091 for (i
= 0; i
< OLEVELS_NUM
; i
++) {
5092 setting_list_destroy(setting_sorted
.level
[i
]);
5095 setting_sorted
.init
= FALSE
;
5098 /*****************************************************************************
5099 Mark setting changed
5100 *****************************************************************************/
5101 void setting_changed(struct setting
*pset
)
5103 pset
->setdef
= SETDEF_CHANGED
;
5106 /*****************************************************************************
5107 Is the setting in changed state, or the default
5108 *****************************************************************************/
5109 enum setting_default_level
setting_get_setdef(struct setting
*pset
)
5111 return pset
->setdef
;
5114 /*****************************************************************************
5115 Compatibility function. In the very old times there was no concept of
5116 'default' value outside setting initialization, all values were handled
5117 like we now want to handle non-default ones.
5118 *****************************************************************************/
5119 void settings_consider_all_changed(void)
5121 settings_iterate(SSET_ALL
, pset
) {
5122 pset
->setdef
= SETDEF_CHANGED
;
5123 } settings_iterate_end
;