From affb1b965d61efbc2a455baada8869c574078757 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Thu, 1 May 2025 17:34:24 +0300
Subject: [PATCH 29/29] Load access_unit for access_area from the ruleset

See RM #1333

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 common/accessarea.c             |  8 ++++++++
 common/accessarea.h             |  1 +
 data/alien/game.ruleset         |  6 ++++++
 data/civ1/game.ruleset          |  6 ++++++
 data/civ2/game.ruleset          |  6 ++++++
 data/civ2civ3/game.ruleset      |  6 ++++++
 data/classic/game.ruleset       |  6 ++++++
 data/goldkeep/game.ruleset      |  6 ++++++
 data/granularity/game.ruleset   |  6 ++++++
 data/multiplayer/game.ruleset   |  6 ++++++
 data/sandbox/game.ruleset       |  6 ++++++
 data/stub/game.ruleset          |  6 ++++++
 data/webperimental/game.ruleset |  6 ++++++
 server/ruleset/ruleload.c       | 20 ++++++++++++++++++--
 tools/ruleutil/rulesave.c       | 10 ++++++++++
 15 files changed, 103 insertions(+), 2 deletions(-)

diff --git a/common/accessarea.c b/common/accessarea.c
index 1ee9a75e98..7388c90fe4 100644
--- a/common/accessarea.c
+++ b/common/accessarea.c
@@ -66,6 +66,14 @@ void access_info_close(void)
   }
 }
 
+/*********************************************************************//**
+  Get access_unit of the access_info
+*************************************************************************/
+const struct unit_type *access_info_access_unit(void)
+{
+  return ainfo.access_unit;
+}
+
 /*********************************************************************//**
   Free access area list.
   @param alist List to clear
diff --git a/common/accessarea.h b/common/accessarea.h
index 827358b01d..7a6419ad72 100644
--- a/common/accessarea.h
+++ b/common/accessarea.h
@@ -38,6 +38,7 @@ struct access_area {
 
 void access_info_init(const struct unit_type *aunit);
 void access_info_close(void);
+const struct unit_type *access_info_access_unit(void);
 
 void access_areas_refresh(struct civ_map *nmap, struct player *plr);
 
diff --git a/data/alien/game.ruleset b/data/alien/game.ruleset
index 4054f81f2d..a453315e35 100644
--- a/data/alien/game.ruleset
+++ b/data/alien/game.ruleset
@@ -574,6 +574,12 @@ name             = _("Commodities")
 replace_priority = 1
 
 
+[aarea]
+; Unit type to use to determine access areas. Access area is the area this unit
+; can access (move to)
+access_unit = ""
+
+
 ; /* <-- avoid gettext warnings
 ;
 ; Clause types
diff --git a/data/civ1/game.ruleset b/data/civ1/game.ruleset
index cdd64e8fc1..32716f3576 100644
--- a/data/civ1/game.ruleset
+++ b/data/civ1/game.ruleset
@@ -607,6 +607,12 @@ replace_priority = 1
 flags            = "Bidirectional"
 
 
+[aarea]
+; Unit type to use to determine access areas. Access area is the area this unit
+; can access (move to)
+access_unit = ""
+
+
 ; /* <-- avoid gettext warnings
 ;
 ; Clause types
diff --git a/data/civ2/game.ruleset b/data/civ2/game.ruleset
index 5baf5258ba..1c2a74a3ea 100644
--- a/data/civ2/game.ruleset
+++ b/data/civ2/game.ruleset
@@ -538,6 +538,12 @@ replace_priority = 1
 flags            = "Bidirectional"
 
 
+[aarea]
+; Unit type to use to determine access areas. Access area is the area this unit
+; can access (move to)
+access_unit = ""
+
+
 ; /* <-- avoid gettext warnings
 ;
 ; Clause types
diff --git a/data/civ2civ3/game.ruleset b/data/civ2civ3/game.ruleset
index cd06bd04f1..5155847e40 100644
--- a/data/civ2civ3/game.ruleset
+++ b/data/civ2civ3/game.ruleset
@@ -634,6 +634,12 @@ reveal_trade_partner = FALSE
 ; "Arrival" - Goods are chosen when trade route is established, when unit arrives to destination
 goods_selection = "Leaving"
 
+[aarea]
+; Unit type to use to determine access areas. Access area is the area this unit
+; can access (move to)
+access_unit = ""
+
+
 ; /* <-- avoid gettext warnings
 ;
 ; Goods types:
diff --git a/data/classic/game.ruleset b/data/classic/game.ruleset
index 97345e10b0..06cc8466ff 100644
--- a/data/classic/game.ruleset
+++ b/data/classic/game.ruleset
@@ -589,6 +589,12 @@ name             = _("Goods")
 replace_priority = 1
 
 
+[aarea]
+; Unit type to use to determine access areas. Access area is the area this unit
+; can access (move to)
+access_unit = ""
+
+
 ; /* <-- avoid gettext warnings
 ;
 ; Clause types
diff --git a/data/goldkeep/game.ruleset b/data/goldkeep/game.ruleset
index c003c2e077..8fbfcca069 100644
--- a/data/goldkeep/game.ruleset
+++ b/data/goldkeep/game.ruleset
@@ -607,6 +607,12 @@ name             = _("Goods")
 replace_priority = 1
 
 
+[aarea]
+; Unit type to use to determine access areas. Access area is the area this unit
+; can access (move to)
+access_unit = ""
+
+
 ; /* <-- avoid gettext warnings
 ;
 ; Clause types
diff --git a/data/granularity/game.ruleset b/data/granularity/game.ruleset
index c9eabaf3d1..d99f2ebd0b 100644
--- a/data/granularity/game.ruleset
+++ b/data/granularity/game.ruleset
@@ -561,6 +561,12 @@ name             = _("Goods")
 replace_priority = 1
 
 
+[aarea]
+; Unit type to use to determine access areas. Access area is the area this unit
+; can access (move to)
+access_unit = ""
+
+
 ; /* <-- avoid gettext warnings
 ;
 ; Clause types
diff --git a/data/multiplayer/game.ruleset b/data/multiplayer/game.ruleset
index b3661e7fb3..37422a918a 100644
--- a/data/multiplayer/game.ruleset
+++ b/data/multiplayer/game.ruleset
@@ -601,6 +601,12 @@ type = "Vision"
 [clause_embassy]
 type = "Embassy"
 
+[aarea]
+; Unit type to use to determine access areas. Access area is the area this unit
+; can access (move to)
+access_unit = ""
+
+
 ; /* <-- avoid gettext warnings
 ;Counter types
 ;
diff --git a/data/sandbox/game.ruleset b/data/sandbox/game.ruleset
index 64657068e1..b2b7c3dce0 100644
--- a/data/sandbox/game.ruleset
+++ b/data/sandbox/game.ruleset
@@ -752,6 +752,12 @@ to_pct           = 150
 flags            = "Depletes"
 
 
+[aarea]
+; Unit type to use to determine access areas. Access area is the area this unit
+; can access (move to)
+access_unit = ""
+
+
 ; /* <-- avoid gettext warnings
 ;
 ; Clause types
diff --git a/data/stub/game.ruleset b/data/stub/game.ruleset
index 8806f2f61b..36281cc0b8 100644
--- a/data/stub/game.ruleset
+++ b/data/stub/game.ruleset
@@ -549,6 +549,12 @@ name             = _("Goods")
 replace_priority = 1
 
 
+[aarea]
+; Unit type to use to determine access areas. Access area is the area this unit
+; can access (move to)
+access_unit = ""
+
+
 ; /* <-- avoid gettext warnings
 ;
 ; Clause types
diff --git a/data/webperimental/game.ruleset b/data/webperimental/game.ruleset
index 776a225d45..d03299ac22 100644
--- a/data/webperimental/game.ruleset
+++ b/data/webperimental/game.ruleset
@@ -593,6 +593,12 @@ name             = _("Goods")
 replace_priority = 1
 
 
+[aarea]
+; Unit type to use to determine access areas. Access area is the area this unit
+; can access (move to)
+access_unit = ""
+
+
 ; /* <-- avoid gettext warnings
 ;
 ; Clause types
diff --git a/server/ruleset/ruleload.c b/server/ruleset/ruleload.c
index ccddcb2e6d..e9e220408c 100644
--- a/server/ruleset/ruleload.c
+++ b/server/ruleset/ruleload.c
@@ -7386,6 +7386,24 @@ static bool load_ruleset_game(struct section_file *file, bool act,
     section_list_destroy(sec);
   }
 
+  if (ok) {
+    const char *uname = secfile_lookup_str_default(file, nullptr,
+                                                   "aarea.access_unit");
+    const struct unit_type *access_unit = nullptr;
+
+    if (uname != nullptr && uname[0] != '\0') {
+      access_unit = unit_type_by_rule_name(uname);
+
+      if (access_unit == nullptr) {
+        ruleset_error(nullptr, LOG_ERROR, "%s: access unit %s unknown.",
+                      filename, uname);
+        ok = FALSE;
+      }
+    }
+
+    access_info_init(access_unit);
+  }
+
   if (ok) {
     sec = secfile_sections_by_name_prefix(file, CLAUSE_SECTION_PREFIX);
 
@@ -9435,8 +9453,6 @@ static bool load_rulesetdir(const char *rsdir, bool compat_mode,
     } unit_type_iterate_end;
     city_production_caravan_shields_init();
 
-    access_info_init(nullptr);
-
     /* Build advisors unit class cache corresponding to loaded rulesets */
     adv_units_ruleset_init();
     CALL_FUNC_EACH_AI(units_ruleset_init);
diff --git a/tools/ruleutil/rulesave.c b/tools/ruleutil/rulesave.c
index 7b4bea363b..3e7a155176 100644
--- a/tools/ruleutil/rulesave.c
+++ b/tools/ruleutil/rulesave.c
@@ -21,6 +21,7 @@
 #include "string_vector.h"
 
 /* common */
+#include "accessarea.h"
 #include "achievements.h"
 #include "counters.h"
 #include "game.h"
@@ -1802,6 +1803,15 @@ static bool save_game_ruleset(const char *filename, const char *name)
     save_strvec(sfile, pgood->helptext, path, "helptext");
   } goods_type_re_active_iterate_end;
 
+  {
+    const struct unit_type *access_unit = access_info_access_unit();
+
+    if (access_unit != nullptr) {
+      secfile_insert_str(sfile, utype_rule_name(access_unit),
+                         "aarea.access_unit");
+    }
+  }
+
   /* Clauses */
   comment_clauses(sfile);
 
-- 
2.47.2

