Skip to content

Commit b6c6b79

Browse files
committed
Check after resolving an ownership conflict that the tile is not an ocean tile with a rank larger than 2
1 parent fd13815 commit b6c6b79

File tree

1 file changed

+32
-28
lines changed

1 file changed

+32
-28
lines changed

C7Engine/C7GameData/GameData.cs

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ public void UpdateTileOwners() {
133133
foreach (Tile t in city.GetTilesWithinBorders()) {
134134
// If another city has claim to this tile, we need to resolve
135135
// that conflict.
136-
if (t.owningCity != null) {
137-
t.owningCity = ResolveTileOwnershipConflict(t.owningCity, city, t);
136+
if (t.owningCity != null && ResolveTileOwnershipConflict(t.owningCity, city, t, out City winnerCity)) {
137+
t.owningCity = winnerCity;
138138
t.owningCity.owner.tileKnowledge.AddTilesToKnown(t, recomputeActiveTiles);
139139
continue;
140140
}
@@ -150,26 +150,29 @@ public void UpdateTileOwners() {
150150

151151
foreach (Tile t in player.tileKnowledge.knownTiles.Where(t => t.owningCity == null && t.GetEdgeNeighbors().Any(e => e.owningCity != null)).ToList()) {
152152
// Law VII
153-
if (t.neighbors.TryGetValue(TileDirection.NORTHWEST, out Tile tnw)
154-
&& t.neighbors.TryGetValue(TileDirection.SOUTHEAST, out Tile tse)
155-
&& tnw.owningCity != null && tse.owningCity != null
156-
&& tnw.owningCity.owner == tse.owningCity.owner) {
157-
t.owningCity = ResolveTileOwnershipConflict(tnw.owningCity, tse.owningCity, t);
158-
t.owningCity.owner.tileKnowledge.AddTilesToKnown(t);
159-
continue;
160-
}
153+
TryResolveOpposingNeighbors(t, TileDirection.NORTHWEST, TileDirection.SOUTHEAST);
154+
if (t.owningCity != null) continue;
161155
// Law VIII
162-
if (t.neighbors.TryGetValue(TileDirection.NORTHEAST, out Tile tne)
163-
&& t.neighbors.TryGetValue(TileDirection.SOUTHWEST, out Tile tsw)
164-
&& tne.owningCity != null && tsw.owningCity != null
165-
&& tne.owningCity.owner == tsw.owningCity.owner) {
166-
t.owningCity = ResolveTileOwnershipConflict(tne.owningCity, tsw.owningCity, t);
167-
t.owningCity.owner.tileKnowledge.AddTilesToKnown(t);
168-
}
156+
TryResolveOpposingNeighbors(t, TileDirection.NORTHEAST, TileDirection.SOUTHWEST);
169157
}
170158
}
171159
}
172160

161+
private void TryResolveOpposingNeighbors(Tile t, TileDirection dirA, TileDirection dirB) {
162+
if (!t.neighbors.TryGetValue(dirA, out Tile a) || !t.neighbors.TryGetValue(dirB, out Tile b)) return;
163+
if (a.owningCity == null || b.owningCity == null) return;
164+
if (a.owningCity.owner != b.owningCity.owner) return;
165+
if (!ResolveTileOwnershipConflict(a.owningCity, b.owningCity, t, out City winnerCity)) return;
166+
167+
// Law II
168+
if (t.baseTerrainType.Key == "ocean" && t.rankDistanceTo(winnerCity.location) > 2) {
169+
t.owningCity = null;
170+
return;
171+
}
172+
t.owningCity = winnerCity;
173+
winnerCity.owner.tileKnowledge.AddTilesToKnown(t);
174+
}
175+
173176
public void UpdateTileOwnersOnCityDestruction(City city) {
174177
city.location.owningCity = null;
175178

@@ -275,26 +278,27 @@ public void InvalidateCachedTradeNetwork() {
275278
}
276279

277280
// Rules taken from https://forums.civfanatics.com/threads/the-eight-laws-of-border-dynamics.106882/
278-
private City ResolveTileOwnershipConflict(City a, City b, Tile t) {
279-
if (a.Equals(b)) return a;
281+
private bool ResolveTileOwnershipConflict(City a, City b, Tile t, out City owner) {
282+
owner = null;
283+
if (a.Equals(b)) { owner = a; return true; }
280284

281285
int aRank = a.location.rankDistanceTo(t);
282286
int bRank = b.location.rankDistanceTo(t);
283287

284288
// Law I
285289
// Cities can claim tiles of rank n+1, where n is the city's expansion level
286-
if (a.GetBorderExpansionLevel() + 1 < aRank && b.GetBorderExpansionLevel() + 1 >= bRank) return b;
287-
if (b.GetBorderExpansionLevel() + 1 < bRank && a.GetBorderExpansionLevel() + 1 >= aRank) return a;
290+
if (a.GetBorderExpansionLevel() + 1 < aRank && b.GetBorderExpansionLevel() + 1 >= bRank) { owner = b; return true; }
291+
if (b.GetBorderExpansionLevel() + 1 < bRank && a.GetBorderExpansionLevel() + 1 >= aRank) { owner = a; return true; }
288292

289293
// Law III
290294
// The city with the lowest rank claim gets the tile.
291-
if (aRank > bRank) return b;
292-
if (aRank < bRank) return a;
295+
if (aRank > bRank) { owner = b; return true; }
296+
if (aRank < bRank) { owner = a; return true; }
293297

294298
// Law IV
295299
// If the ranks are equal, the city with more culture gets the tile.
296-
if (a.GetCulture() + a.GetCulturePerTurn() < b.GetCulture() + b.GetCulturePerTurn()) return b;
297-
if (a.GetCulture() + a.GetCulturePerTurn() > b.GetCulture() + b.GetCulturePerTurn()) return a;
300+
if (a.GetCulture() + a.GetCulturePerTurn() < b.GetCulture() + b.GetCulturePerTurn()) { owner = b; return true; }
301+
if (a.GetCulture() + a.GetCulturePerTurn() > b.GetCulture() + b.GetCulturePerTurn()) { owner = a; return true; }
298302

299303
// Law V
300304
// If the cultures are equal the oldest city gets the tile.
@@ -309,9 +313,9 @@ private City ResolveTileOwnershipConflict(City a, City b, Tile t) {
309313
for (int r = aRank - 1; r <= aRank; r++) {
310314
if (r <= 0) continue;
311315
Tile winner = t.FindInRing(r, tile => tile.HasCity && (tile.cityAtTile == a || tile.cityAtTile == b), false);
312-
if (winner != null) {
313-
return winner.owningCity;
314-
}
316+
if (winner == null) continue;
317+
owner = winner.owningCity;
318+
return true;
315319
}
316320

317321
// should never happen, if it does some part of the algorithm has gone wrong

0 commit comments

Comments
 (0)