From 4d2b1a7de8cb5045f05088ff115157350e7b5d97 Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Tue, 22 Sep 2026 00:02:58 +0300
Subject: [PATCH 67/67] Tiledef: Add "owned" property

See RM #2172

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 client/packhand.c                | 1 +
 common/networking/packets.def    | 1 +
 common/tiledef.c                 | 5 +++++
 common/tiledef.h                 | 1 +
 data/alien/terrain.ruleset       | 2 ++
 data/civ1/terrain.ruleset        | 2 ++
 data/civ2/terrain.ruleset        | 2 ++
 data/civ2civ3/terrain.ruleset    | 2 ++
 data/classic/terrain.ruleset     | 2 ++
 data/goldkeep/terrain.ruleset    | 2 ++
 data/granularity/terrain.ruleset | 2 ++
 data/multiplayer/terrain.ruleset | 2 ++
 data/ruledit/comments-3.4.txt    | 2 ++
 data/sandbox/terrain.ruleset     | 2 ++
 data/stub/terrain.ruleset        | 2 ++
 server/ruleset/ruleload.c        | 3 +++
 tools/ruleutil/rulesave.c        | 3 +++
 17 files changed, 36 insertions(+)

diff --git a/client/packhand.c b/client/packhand.c
index 84f653460c..0bbc6eff0c 100644
--- a/client/packhand.c
+++ b/client/packhand.c
@@ -4548,6 +4548,7 @@ void handle_ruleset_tiledef(const struct packet_ruleset_tiledef *p)
   } extra_type_iterate_end;
 
   td->known = p->known;
+  td->owned = p->owned;
 }
 
 /************************************************************************//**
diff --git a/common/networking/packets.def b/common/networking/packets.def
index 779c29be45..1c35a69dbf 100644
--- a/common/networking/packets.def
+++ b/common/networking/packets.def
@@ -1964,6 +1964,7 @@ PACKET_RULESET_TILEDEF = 520; sc, lsend
 
   BV_EXTRAS extras;
   BOOL known;
+  BOOL owned;
 end
 
 /**************************************************************************
diff --git a/common/tiledef.c b/common/tiledef.c
index 550ef5baa0..a3b1b5e1dd 100644
--- a/common/tiledef.c
+++ b/common/tiledef.c
@@ -167,6 +167,11 @@ bool tile_matches_tiledef(const struct tiledef *td, const struct tile *ptile,
     return FALSE;
   }
 
+  if (td->owned && pplayer != nullptr
+      && tile_owner(ptile) != pplayer) {
+    return FALSE;
+  }
+
   return TRUE;
 }
 
diff --git a/common/tiledef.h b/common/tiledef.h
index 463d99b57d..753ebf7030 100644
--- a/common/tiledef.h
+++ b/common/tiledef.h
@@ -29,6 +29,7 @@ struct tiledef
   enum terrain_flag_id terr_flag;
   struct extra_type_list *extras;
   bool known;
+  bool owned;
 };
 
 void tiledefs_init(void);
diff --git a/data/alien/terrain.ruleset b/data/alien/terrain.ruleset
index 3e75085e6f..65518622c7 100644
--- a/data/alien/terrain.ruleset
+++ b/data/alien/terrain.ruleset
@@ -1565,5 +1565,7 @@ flags          = "River", "UnrestrictedInfra"
 ; extras               = List of extras that the tile must have
 ;                        to satisfy tiledef requirements.
 ; known                = Whether the target player must know the tile or not
+; owned                = Whether the tile must be within borders of
+;                        the target player or not
 ;
 ; */ <-- avoid gettext warnings
diff --git a/data/civ1/terrain.ruleset b/data/civ1/terrain.ruleset
index 7d01b977c8..11200d1524 100644
--- a/data/civ1/terrain.ruleset
+++ b/data/civ1/terrain.ruleset
@@ -1522,5 +1522,7 @@ flags          = "River", "UnrestrictedInfra"
 ; extras               = List of extras that the tile must have
 ;                        to satisfy tiledef requirements.
 ; known                = Whether the target player must know the tile or not
+; owned                = Whether the tile must be within borders of
+;                        the target player or not
 ;
 ; */ <-- avoid gettext warnings
diff --git a/data/civ2/terrain.ruleset b/data/civ2/terrain.ruleset
index f96475824b..c625717947 100644
--- a/data/civ2/terrain.ruleset
+++ b/data/civ2/terrain.ruleset
@@ -1824,5 +1824,7 @@ flags          = "River", "UnrestrictedInfra"
 ; extras               = List of extras that the tile must have
 ;                        to satisfy tiledef requirements.
 ; known                = Whether the target player must know the tile or not
+; owned                = Whether the tile must be within borders of
+;                        the target player or not
 ;
 ; */ <-- avoid gettext warnings
diff --git a/data/civ2civ3/terrain.ruleset b/data/civ2civ3/terrain.ruleset
index 3f5cc75bba..6ea7f3a9ec 100644
--- a/data/civ2civ3/terrain.ruleset
+++ b/data/civ2civ3/terrain.ruleset
@@ -2355,5 +2355,7 @@ gui_type       = "Other"
 ; extras               = List of extras that the tile must have
 ;                        to satisfy tiledef requirements.
 ; known                = Whether the target player must know the tile or not
+; owned                = Whether the tile must be within borders of
+;                        the target player or not
 ;
 ; */ <-- avoid gettext warnings
diff --git a/data/classic/terrain.ruleset b/data/classic/terrain.ruleset
index 6e04348314..f8f7d182c4 100644
--- a/data/classic/terrain.ruleset
+++ b/data/classic/terrain.ruleset
@@ -2123,5 +2123,7 @@ gui_type          = "Other"
 ; extras               = List of extras that the tile must have
 ;                        to satisfy tiledef requirements.
 ; known                = Whether the target player must know the tile or not
+; owned                = Whether the tile must be within borders of
+;                        the target player or not
 ;
 ; */ <-- avoid gettext warnings
diff --git a/data/goldkeep/terrain.ruleset b/data/goldkeep/terrain.ruleset
index dd8a6beda4..5a8728489a 100644
--- a/data/goldkeep/terrain.ruleset
+++ b/data/goldkeep/terrain.ruleset
@@ -2147,5 +2147,7 @@ gui_type       = "Other"
 ; extras               = List of extras that the tile must have
 ;                        to satisfy tiledef requirements.
 ; known                = Whether the target player must know the tile or not
+; owned                = Whether the tile must be within borders of
+;                        the target player or not
 ;
 ; */ <-- avoid gettext warnings
diff --git a/data/granularity/terrain.ruleset b/data/granularity/terrain.ruleset
index 5bae2cb5e6..93f68ff9aa 100644
--- a/data/granularity/terrain.ruleset
+++ b/data/granularity/terrain.ruleset
@@ -1041,5 +1041,7 @@ flags          = "River", "UnrestrictedInfra"
 ; extras               = List of extras that the tile must have
 ;                        to satisfy tiledef requirements.
 ; known                = Whether the target player must know the tile or not
+; owned                = Whether the tile must be within borders of
+;                        the target player or not
 ;
 ; */ <-- avoid gettext warnings
diff --git a/data/multiplayer/terrain.ruleset b/data/multiplayer/terrain.ruleset
index c8af7afca6..2bc692ebfc 100644
--- a/data/multiplayer/terrain.ruleset
+++ b/data/multiplayer/terrain.ruleset
@@ -2087,5 +2087,7 @@ gui_type       = "Other"
 ; extras               = List of extras that the tile must have
 ;                        to satisfy tiledef requirements.
 ; known                = Whether the target player must know the tile or not
+; owned                = Whether the tile must be within borders of
+;                        the target player or not
 ;
 ; */ <-- avoid gettext warnings
diff --git a/data/ruledit/comments-3.4.txt b/data/ruledit/comments-3.4.txt
index c068dfbc4c..01f675174f 100644
--- a/data/ruledit/comments-3.4.txt
+++ b/data/ruledit/comments-3.4.txt
@@ -754,6 +754,8 @@ tiledefs = "\
 ; extras               = List of extras that the tile must have\n\
 ;                        to satisfy tiledef requirements.\n\
 ; known                = Whether the target player must know the tile or not\n\
+; owned                = Whether the tile must be within borders of\n\
+;                        the target player or not\n\
 ;\n\
 ; */ <-- avoid gettext warnings\n\
 "
diff --git a/data/sandbox/terrain.ruleset b/data/sandbox/terrain.ruleset
index fccbe2972f..9af1932431 100644
--- a/data/sandbox/terrain.ruleset
+++ b/data/sandbox/terrain.ruleset
@@ -2472,6 +2472,8 @@ flags          = "River", "JumpFrom", "JumpTo"
 ; extras               = List of extras that the tile must have
 ;                        to satisfy tiledef requirements.
 ; known                = Whether the target player must know the tile or not
+; owned                = Whether the tile must be within borders of
+;                        the target player or not
 ;
 ; */ <-- avoid gettext warnings
 
diff --git a/data/stub/terrain.ruleset b/data/stub/terrain.ruleset
index a9e8f01cbf..0f1b5c531f 100644
--- a/data/stub/terrain.ruleset
+++ b/data/stub/terrain.ruleset
@@ -657,5 +657,7 @@ rmact_gfx_alt2 = "-"
 ; extras               = List of extras that the tile must have
 ;                        to satisfy tiledef requirements.
 ; known                = Whether the target player must know the tile or not
+; owned                = Whether the tile must be within borders of
+;                        the target player or not
 ;
 ; */ <-- avoid gettext warnings
diff --git a/server/ruleset/ruleload.c b/server/ruleset/ruleload.c
index fca376740f..7f611bff31 100644
--- a/server/ruleset/ruleload.c
+++ b/server/ruleset/ruleload.c
@@ -4353,6 +4353,8 @@ static bool load_ruleset_terrain(struct section_file *file,
         if (ok) {
           td->known = secfile_lookup_bool_default(file, FALSE,
                                                   "%s.known", section);
+          td->owned = secfile_lookup_bool_default(file, FALSE,
+                                                  "%s.owned", section);
         }
 
         if (!ok) {
@@ -8913,6 +8915,7 @@ static void send_ruleset_tiledefs(struct conn_list *dest)
     packet.extras = extras;
 
     packet.known = td->known;
+    packet.owned = td->owned;
 
     lsend_packet_ruleset_tiledef(dest, &packet);
   } tiledef_iterate_end;
diff --git a/tools/ruleutil/rulesave.c b/tools/ruleutil/rulesave.c
index 0b95d8e4f0..788dd59eb3 100644
--- a/tools/ruleutil/rulesave.c
+++ b/tools/ruleutil/rulesave.c
@@ -3169,6 +3169,9 @@ static bool save_terrain_ruleset(const char *filename, const char *name)
     if (td->known) {
       secfile_insert_bool(sfile, td->known, "%s.known", path);
     }
+    if (td->owned) {
+      secfile_insert_bool(sfile, td->owned, "%s.owned", path);
+    }
   } tiledef_iterate_end;
 
   return save_ruleset_file(sfile, filename);
-- 
2.53.0

