From 0b4c7fd2631ea571bcced5ee9fde618beeaf51ea Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Sat, 9 Apr 2022 07:54:20 +0300 Subject: [PATCH 04/39] Add ailevel server setting Requested by Jacob Nevins See osdn #44105 Signed-off-by: Marko Lindqvist --- common/fc_types.h | 37 +++++++++------- fc_version | 2 +- server/savegame/savecompat.c | 84 ++++++++++++++++++++++++++++++++++-- server/savegame/savegame2.c | 20 --------- server/savegame/savegame3.c | 19 -------- server/settings.c | 34 +++++++++++++++ 6 files changed, 136 insertions(+), 60 deletions(-) diff --git a/common/fc_types.h b/common/fc_types.h index d88ffb6c68..cf0306b3a1 100644 --- a/common/fc_types.h +++ b/common/fc_types.h @@ -467,24 +467,29 @@ const char *ai_level_name_update_cb(const char *old); /* Used in the network protocol. */ /* server/commands.c must match these */ #define SPECENUM_NAME ai_level -#define SPECENUM_VALUE0 AI_LEVEL_AWAY -#define SPECENUM_VALUE0NAME N_("Away") -#define SPECENUM_VALUE1 AI_LEVEL_RESTRICTED -#define SPECENUM_VALUE1NAME N_("Restricted") -#define SPECENUM_VALUE2 AI_LEVEL_NOVICE -#define SPECENUM_VALUE2NAME N_("Novice") -#define SPECENUM_VALUE3 AI_LEVEL_EASY -#define SPECENUM_VALUE3NAME N_("Easy") -#define SPECENUM_VALUE4 AI_LEVEL_NORMAL -#define SPECENUM_VALUE4NAME N_("Normal") -#define SPECENUM_VALUE5 AI_LEVEL_HARD -#define SPECENUM_VALUE5NAME N_("Hard") -#define SPECENUM_VALUE6 AI_LEVEL_CHEATING -#define SPECENUM_VALUE6NAME N_("Cheating") +#define SPECENUM_VALUE0 AI_LEVEL_RESTRICTED +#define SPECENUM_VALUE0NAME N_("Restricted") +#define SPECENUM_VALUE1 AI_LEVEL_NOVICE +#define SPECENUM_VALUE1NAME N_("Novice") +#define SPECENUM_VALUE2 AI_LEVEL_EASY +#define SPECENUM_VALUE2NAME N_("Easy") +#define SPECENUM_VALUE3 AI_LEVEL_NORMAL +#define SPECENUM_VALUE3NAME N_("Normal") +#define SPECENUM_VALUE4 AI_LEVEL_HARD +#define SPECENUM_VALUE4NAME N_("Hard") +#define SPECENUM_VALUE5 AI_LEVEL_CHEATING +#define SPECENUM_VALUE5NAME N_("Cheating") #ifdef FREECIV_DEBUG -#define SPECENUM_VALUE7 AI_LEVEL_EXPERIMENTAL -#define SPECENUM_VALUE7NAME N_("Experimental") +#define SPECENUM_VALUE6 AI_LEVEL_EXPERIMENTAL +#define SPECENUM_VALUE6NAME N_("Experimental") +/* Away must be the last, so ailevel_name() can terminate list + * of level names before it. */ +#define SPECENUM_VALUE7 AI_LEVEL_AWAY +#define SPECENUM_VALUE7NAME N_("Away") +#else /* FREECIV_DEBUG */ +#define SPECENUM_VALUE6 AI_LEVEL_AWAY +#define SPECENUM_VALUE6NAME N_("Away") #endif /* FREECIV_DEBUG */ #define SPECENUM_COUNT AI_LEVEL_COUNT diff --git a/fc_version b/fc_version index 85004eddf2..4993b56db8 100755 --- a/fc_version +++ b/fc_version @@ -56,7 +56,7 @@ DEFAULT_FOLLOW_TAG=S3_2 # - No new mandatory capabilities can be added to the release branch; doing # so would break network capability of supposedly "compatible" releases. # -NETWORK_CAPSTRING="+Freeciv.Devel-3.2-2022.Apr.08" +NETWORK_CAPSTRING="+Freeciv.Devel-3.2-2022.Apr.09" FREECIV_DISTRIBUTOR="" diff --git a/server/savegame/savecompat.c b/server/savegame/savecompat.c index f39f3730d0..57f19d2c22 100644 --- a/server/savegame/savecompat.c +++ b/server/savegame/savecompat.c @@ -1890,6 +1890,8 @@ static void compat_load_030200(struct loaddata *loading, { int i; int count; + int set_count; + bool gamestart_valid = FALSE; /* Check status and return if not OK (sg_success != TRUE). */ sg_check_ret(); @@ -1898,10 +1900,8 @@ static void compat_load_030200(struct loaddata *loading, /* Server setting migration. */ { - int set_count; - if (secfile_lookup_int(loading->file, &set_count, "settings.set_count")) { - bool gamestart_valid + gamestart_valid = secfile_lookup_bool_default(loading->file, FALSE, "settings.gamestart_valid"); @@ -1964,6 +1964,38 @@ static void compat_load_030200(struct loaddata *loading, } } + { + /* Turn old AI level field to a setting. */ + const char *level; + enum ai_level lvl; + + level = secfile_lookup_str_default(loading->file, NULL, "game.level"); + if (level != NULL && !fc_strcasecmp("Handicapped", level)) { + /* Up to freeciv-3.1 Restricted AI level was known as Handicapped */ + lvl = AI_LEVEL_RESTRICTED; + } else { + lvl = ai_level_by_name(level, fc_strcasecmp); + } + + if (!ai_level_is_valid(lvl)) { + log_sg("Invalid AI level \"%s\". " + "Changed to \"%s\".", level, + ai_level_name(GAME_HARDCODED_DEFAULT_SKILL_LEVEL)); + lvl = GAME_HARDCODED_DEFAULT_SKILL_LEVEL; + } + + secfile_insert_str(loading->file, "ailevel", "settings.set%d.name", set_count); + secfile_insert_enum(loading->file, lvl, ai_level, "settings.set%d.value", set_count); + + if (gamestart_valid) { + secfile_insert_enum(loading->file, lvl, ai_level, "settings.set%d.gamestart", + set_count); + } + + set_count++; + secfile_replace_int(loading->file, set_count, "settings.set_count"); + } + /* Older savegames had a bug that got_tech_multi was not saved. * Insert the entry to such savegames */ @@ -2306,10 +2338,13 @@ static void compat_load_dev(struct loaddata *loading) if (game_version < 3019200) { /* Before version number bump to 3.1.92 */ int set_count; + bool gamestart_valid = FALSE; + bool al_set_already = FALSE; + const char *level; if (secfile_lookup_int(loading->file, &set_count, "settings.set_count")) { int i; - bool gamestart_valid + gamestart_valid = secfile_lookup_bool_default(loading->file, FALSE, "settings.gamestart_valid"); @@ -2368,10 +2403,51 @@ static void compat_load_dev(struct loaddata *loading) #endif } } + } else if (!fc_strcasecmp("ailevel", name)) { + al_set_already = TRUE; } } } + if (!al_set_already) { + level = secfile_lookup_str_default(loading->file, NULL, "game.level"); + if (level == NULL) { + /* Assume that this was a new format savegame after all, + * setting just has not been explicitly saved for containing default value. */ + al_set_already = TRUE; + } + } + + if (!al_set_already) { + /* Turn old AI level field to a setting. */ + enum ai_level lvl; + + if (level != NULL && !fc_strcasecmp("Handicapped", level)) { + /* Up to freeciv-3.1 Restricted AI level was known as Handicapped */ + lvl = AI_LEVEL_RESTRICTED; + } else { + lvl = ai_level_by_name(level, fc_strcasecmp); + } + + if (!ai_level_is_valid(lvl)) { + log_sg("Invalid AI level \"%s\". " + "Changed to \"%s\".", level, + ai_level_name(GAME_HARDCODED_DEFAULT_SKILL_LEVEL)); + lvl = GAME_HARDCODED_DEFAULT_SKILL_LEVEL; + } + + secfile_insert_str(loading->file, "ailevel", "settings.set%d.name", set_count); + secfile_insert_enum(loading->file, lvl, ai_level, "settings.set%d.value", set_count); + + if (gamestart_valid) { + secfile_insert_enum(loading->file, lvl, ai_level, "settings.set%d.gamestart", + set_count); + } + + set_count++; + secfile_replace_int(loading->file, set_count, "settings.set_count"); + } + { int action_count; diff --git a/server/savegame/savegame2.c b/server/savegame/savegame2.c index 113e7b44ed..a888483667 100644 --- a/server/savegame/savegame2.c +++ b/server/savegame/savegame2.c @@ -1504,7 +1504,6 @@ static void sg_load_game(struct loaddata *loading) { int game_version; const char *string; - const char *level; int i; /* Check status and return if not OK (sg_success != TRUE). */ @@ -1554,25 +1553,6 @@ static void sg_load_game(struct loaddata *loading) * so that we can generate new game_identifier, if needed. * See sq_load_sanitycheck(). */ - level = secfile_lookup_str_default(loading->file, NULL, - "game.level"); - if (level != NULL) { - if (!fc_strcasecmp("Handicapped", level)) { - /* Up to freeciv-3.1 Restricted AI level was known as Handicapped */ - game.info.skill_level = AI_LEVEL_RESTRICTED; - } else { - game.info.skill_level = ai_level_by_name(level, fc_strcasecmp); - } - } else { - game.info.skill_level = ai_level_invalid(); - } - - if (!ai_level_is_valid(game.info.skill_level)) { - game.info.skill_level - = ai_level_convert(secfile_lookup_int_default(loading->file, - GAME_HARDCODED_DEFAULT_SKILL_LEVEL, - "game.skill_level")); - } game.info.phase_mode = secfile_lookup_int_default(loading->file, GAME_DEFAULT_PHASE_MODE, "game.phase_mode"); diff --git a/server/savegame/savegame3.c b/server/savegame/savegame3.c index 366f2c6073..056da26157 100644 --- a/server/savegame/savegame3.c +++ b/server/savegame/savegame3.c @@ -1958,7 +1958,6 @@ static void sg_load_ruledata(struct loaddata *loading) static void sg_load_game(struct loaddata *loading) { const char *str; - const char *level; int i; /* Check status and return if not OK (sg_success != TRUE). */ @@ -2004,22 +2003,6 @@ static void sg_load_game(struct loaddata *loading) * so that we can generate new game_identifier, if needed. * See sq_load_sanitycheck(). */ - level = secfile_lookup_str_default(loading->file, NULL, - "game.level"); - if (level != NULL && !fc_strcasecmp("Handicapped", level)) { - /* Up to freeciv-3.1 Restricted AI level was known as Handicapped */ - game.info.skill_level = AI_LEVEL_RESTRICTED; - } else { - game.info.skill_level = ai_level_by_name(level, fc_strcasecmp); - } - - if (!ai_level_is_valid(game.info.skill_level)) { - log_sg("Invalid AI level \"%s\". " - "Changed to \"%s\".", level, - ai_level_name(GAME_HARDCODED_DEFAULT_SKILL_LEVEL)); - game.info.skill_level = GAME_HARDCODED_DEFAULT_SKILL_LEVEL; - } - str = secfile_lookup_str_default(loading->file, NULL, "game.phase_mode"); if (str != NULL) { @@ -2175,8 +2158,6 @@ static void sg_save_game(struct savedata *saving) secfile_insert_str(saving->file, server.game_identifier, "game.id"); secfile_insert_str(saving->file, srvarg.serverid, "game.serverid"); - secfile_insert_str(saving->file, ai_level_name(game.info.skill_level), - "game.level"); secfile_insert_str(saving->file, phase_mode_type_name(game.info.phase_mode), "game.phase_mode"); diff --git a/server/settings.c b/server/settings.c index 1394243fad..b219ddf8e6 100644 --- a/server/settings.c +++ b/server/settings.c @@ -578,6 +578,32 @@ compresstype_name(enum fz_method compresstype) return NULL; } +/************************************************************************//** + AI level names accessor. +****************************************************************************/ +static const struct sset_val_name * +ailevel_name(enum ai_level lvl) +{ + const char *lvlname; + + if (lvl >= AI_LEVEL_AWAY) { + return NULL; + } + + lvlname = ai_level_name(lvl); + + if (lvlname != NULL) { + static struct sset_val_name name[AI_LEVEL_COUNT]; + + name[lvl].support = lvlname; + name[lvl].pretty = ai_level_translated_name(lvl); + + return &name[lvl]; + } + + return NULL; +} + /************************************************************************//** Names accessor for boolean settings (disable/enable). ****************************************************************************/ @@ -3124,6 +3150,14 @@ static struct setting settings[] = { "automatically generated meta server message."), NULL, metamessage_action, GAME_DEFAULT_USER_META_MESSAGE) + GEN_ENUM("ailevel", game.info.skill_level, + SSET_META, SSET_INTERNAL, SSET_VITAL, ALLOW_NONE, ALLOW_CTRL, + N_("Level of new AIs"), + N_("Difficulty level of any AI players to be created now on. " + "Changing value of this setting does not affect " + "existing players."), NULL, NULL, NULL, + ailevel_name, GAME_DEFAULT_SKILL_LEVEL) + GEN_STRING_NRS("aitype", game.server.default_ai_type_name, SSET_META, SSET_INTERNAL, SSET_RARE, ALLOW_HACK, ALLOW_HACK, N_("Default AI type"), -- 2.35.1