From 889581de070ad1f2a0376f6d960c47e8cdc02916 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Thu, 7 May 2026 04:31:05 +0300
Subject: [PATCH 36/36] Savegame: Fix PLRF_FIRST_CITY / cities currently > 0
 inconsistency

See RM #2018

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 server/savegame/savegame2.c | 15 +++++++++++++--
 server/savegame/savegame3.c | 15 +++++++++++++--
 2 files changed, 26 insertions(+), 4 deletions(-)

diff --git a/server/savegame/savegame2.c b/server/savegame/savegame2.c
index bf9214016f..92705d8517 100644
--- a/server/savegame/savegame2.c
+++ b/server/savegame/savegame2.c
@@ -5605,7 +5605,7 @@ static void sg_load_sanitycheck(struct loaddata *loading)
     } unit_list_iterate_safe_end;
   } players_iterate_end;
 
-  /* Fix stacking issues.  We don't rely on the savegame preserving
+  /* Fix stacking issues. We don't rely on the savegame preserving
    * alliance invariants (old savegames often did not) so if there are any
    * unallied units on the same tile we just bounce them. */
   players_iterate(pplayer) {
@@ -5645,7 +5645,7 @@ static void sg_load_sanitycheck(struct loaddata *loading)
   /* Check worked tiles map */
 #ifdef FREECIV_DEBUG
   if (loading->worked_tiles != NULL) {
-    /* check the entire map for unused worked tiles */
+    /* Check the entire map for unused worked tiles */
     whole_map_iterate(&(wld.map), ptile) {
       if (loading->worked_tiles[ptile->index] != -1) {
         log_error("[city id: %d] Unused worked tile at (%d, %d).",
@@ -5696,6 +5696,17 @@ static void sg_load_sanitycheck(struct loaddata *loading)
     player_limit_to_max_rates(pplayer);
   } players_iterate_end;
 
+  /* Check initial city sanity */
+  players_iterate(pplayer) {
+    if (!player_has_flag(pplayer, PLRF_FIRST_CITY)
+        && city_list_size(pplayer->cities) > 0) {
+      log_sg(_("%s inconsistency: Has never had their first city, "
+               "but has cities this very moment. Fixing."),
+             player_name(pplayer));
+      BV_SET(pplayer->flags, PLRF_FIRST_CITY);
+    }
+  } players_iterate_end;
+
   if (0 == strlen(server.game_identifier)
       || !is_base64url(server.game_identifier)) {
     /* This uses fc_rand(), so random state has to be initialized before. */
diff --git a/server/savegame/savegame3.c b/server/savegame/savegame3.c
index da6d287594..a4b7a57c57 100644
--- a/server/savegame/savegame3.c
+++ b/server/savegame/savegame3.c
@@ -8142,7 +8142,7 @@ static void sg_load_sanitycheck(struct loaddata *loading)
     } unit_list_iterate_safe_end;
   } players_iterate_end;
 
-  /* Fix stacking issues.  We don't rely on the savegame preserving
+  /* Fix stacking issues. We don't rely on the savegame preserving
    * alliance invariants (old savegames often did not) so if there are any
    * unallied units on the same tile we just bounce them. */
   players_iterate(pplayer) {
@@ -8182,7 +8182,7 @@ static void sg_load_sanitycheck(struct loaddata *loading)
   /* Check worked tiles map */
 #ifdef FREECIV_DEBUG
   if (loading->worked_tiles != NULL) {
-    /* check the entire map for unused worked tiles */
+    /* Check the entire map for unused worked tiles */
     whole_map_iterate(&(wld.map), ptile) {
       if (loading->worked_tiles[ptile->index] != -1) {
         log_error("[city id: %d] Unused worked tile at (%d, %d).",
@@ -8252,6 +8252,17 @@ static void sg_load_sanitycheck(struct loaddata *loading)
     player_limit_to_max_rates(pplayer);
   } players_iterate_end;
 
+  /* Check initial city sanity */
+  players_iterate(pplayer) {
+    if (!player_has_flag(pplayer, PLRF_FIRST_CITY)
+        && city_list_size(pplayer->cities) > 0) {
+      log_sg(_("%s inconsistency: Has never had their first city, "
+               "but has cities this very moment. Fixing."),
+             player_name(pplayer));
+      BV_SET(pplayer->flags, PLRF_FIRST_CITY);
+    }
+  } players_iterate_end;
+
   if (0 == strlen(server.game_identifier)
       || !is_base64url(server.game_identifier)) {
     /* This uses fc_rand(), so random state has to be initialized before. */
-- 
2.53.0

