Skip to content

Commit

Permalink
Fix tile yields for city centers
Browse files Browse the repository at this point in the history
This is primarily based on the english translation of this german wiki: https://wiki.civforum.de/wiki/Stadtfeldertrag_(Civ3)

#541
  • Loading branch information
TomWerner committed Feb 16, 2025
1 parent 404182c commit 5106d01
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 6 deletions.
14 changes: 14 additions & 0 deletions C7/Text/c7-static-map-save.json
Original file line number Diff line number Diff line change
Expand Up @@ -58113,6 +58113,7 @@
"allowCities": true,
"miningBonus": 1,
"irrigationBonus": 1,
"roadBonus": 1,
"defenseBonus": {
"description": "Desert",
"amount": 0.1
Expand All @@ -58128,6 +58129,7 @@
"allowCities": true,
"miningBonus": 1,
"irrigationBonus": 1,
"roadBonus": 1,
"defenseBonus": {
"description": "Plains",
"amount": 0.1
Expand All @@ -58143,6 +58145,7 @@
"allowCities": true,
"miningBonus": 1,
"irrigationBonus": 1,
"roadBonus": 1,
"defenseBonus": {
"description": "Grassland",
"amount": 0.1
Expand All @@ -58158,6 +58161,7 @@
"allowCities": true,
"miningBonus": 1,
"irrigationBonus": 0,
"roadBonus": 1,
"defenseBonus": {
"description": "Tundra",
"amount": 0.1
Expand All @@ -58173,6 +58177,7 @@
"allowCities": true,
"miningBonus": 0,
"irrigationBonus": 1,
"roadBonus": 1,
"defenseBonus": {
"description": "Flood Plain",
"amount": 0.1
Expand All @@ -58188,6 +58193,7 @@
"allowCities": true,
"miningBonus": 2,
"irrigationBonus": 0,
"roadBonus": 1,
"defenseBonus": {
"description": "Hills",
"amount": 0.5
Expand All @@ -58203,6 +58209,7 @@
"allowCities": false,
"miningBonus": 2,
"irrigationBonus": 0,
"roadBonus": 1,
"defenseBonus": {
"description": "Mountains",
"amount": 1
Expand All @@ -58218,6 +58225,7 @@
"allowCities": true,
"miningBonus": 0,
"irrigationBonus": 0,
"roadBonus": 1,
"defenseBonus": {
"description": "Forest",
"amount": 0.25
Expand All @@ -58233,6 +58241,7 @@
"allowCities": true,
"miningBonus": 0,
"irrigationBonus": 0,
"roadBonus": 1,
"defenseBonus": {
"description": "Jungle",
"amount": 0.25
Expand All @@ -58248,6 +58257,7 @@
"allowCities": false,
"miningBonus": 0,
"irrigationBonus": 0,
"roadBonus": 1,
"defenseBonus": {
"description": "Marsh",
"amount": 0.2
Expand All @@ -58263,6 +58273,7 @@
"allowCities": false,
"miningBonus": 0,
"irrigationBonus": 0,
"roadBonus": 0,
"defenseBonus": {
"description": "Volcano",
"amount": 0.8
Expand All @@ -58278,6 +58289,7 @@
"allowCities": false,
"miningBonus": 0,
"irrigationBonus": 0,
"roadBonus": 0,
"defenseBonus": {
"description": "Coast",
"amount": 0.1
Expand All @@ -58293,6 +58305,7 @@
"allowCities": false,
"miningBonus": 0,
"irrigationBonus": 0,
"roadBonus": 0,
"defenseBonus": {
"description": "Sea",
"amount": 0.1
Expand All @@ -58308,6 +58321,7 @@
"allowCities": false,
"miningBonus": 0,
"irrigationBonus": 0,
"roadBonus": 0,
"defenseBonus": {
"description": "Ocean",
"amount": 0.1
Expand Down
7 changes: 4 additions & 3 deletions C7GameData/City.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,24 +108,25 @@ public IProducible ComputeTurnProduction() {
}

public int CurrentFoodYield() {
int yield = 2; //city center min yield
int yield = location.foodYield(owner);
foreach (CityResident r in residents) {
yield += r.tileWorked.foodYield(owner);
}
return yield;
}

public int CurrentProductionYield() {
int yield = 1; //city center min yield
int yield = location.productionYield(owner);
foreach (CityResident r in residents) {
yield += r.tileWorked.productionYield(owner);
}
return yield;
}

public int CurrentCommerceYield() {
// TODO: Split this into science, entertainment, etc.

int yield = 3; //city center min yield
int yield = location.commerceYield(owner);
foreach (CityResident r in residents) {
yield += r.tileWorked.commerceYield(owner);
}
Expand Down
2 changes: 2 additions & 0 deletions C7GameData/TerrainType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class TerrainType {
public bool allowCities { get; set; } = true;
public int miningBonus { get; set; }
public int irrigationBonus { get; set; }
public int roadBonus { get; set; }
public StrengthBonus defenseBonus;

//some stuff about graphics would probably make sense, too
Expand Down Expand Up @@ -60,6 +61,7 @@ public static TerrainType ImportFromCiv3(int civ3Index, TERR civ3Terrain) {
amount = civ3Terrain.DefenseBonus / 100.0
};
c7Terrain.miningBonus = civ3Terrain.MiningBonus;
c7Terrain.roadBonus = civ3Terrain.RoadBonus;
c7Terrain.irrigationBonus = civ3Terrain.IrrigationBonus;
return c7Terrain;
}
Expand Down
75 changes: 72 additions & 3 deletions C7GameData/Tile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,34 +186,71 @@ public int rankDistanceTo(Tile other) {
return (int)Math.Round(Math.Sqrt(deltaX * deltaX + deltaY * deltaY) / 2);
}

// TODO: This is innacurate for city centers.
public int foodYield(Player player) {
int yield = overlayTerrainType.baseFoodProduction;
if (this.Resource != Resource.NONE && player.KnowsAboutResource(Resource)) {
yield += this.Resource.FoodBonus;
}

if (this.overlays.irrigation) {
yield += this.overlayTerrainType.irrigationBonus;
if (this.overlays.railroad) {
yield += 1;
}
}

if (HasCity) {
// All city centers have a food yield of 2, regardless of bonus
// food. See https://wiki.civforum.de/wiki/Stadtfeldertrag_(Civ3).
yield = 2;

// TODO: For agricultural civilizations, the city field produces
// a food yield of three food, but this is reduced to two by the
// despotism penalty, unless the city is located on a fresh
// water source or has already reached city size (≥ 7)
}

return yield;
}

// TODO: This is innacurate for city centers.
public int productionYield(Player player) {
int yield = overlayTerrainType.baseShieldProduction;
if (overlayTerrainType.Key == "grassland" && this.isBonusShield) {
yield++;
}

if (HasCity) {
// City centers always have 1 shield prior to any bonuses
// resources, regardless of the terrain.
// See https://wiki.civforum.de/wiki/Stadtfeldertrag_(Civ3).
yield = 1;

// There is a size bonus for larger cities.
if (cityAtTile.size >= 7 && cityAtTile.size < 13) {
yield += 1;
} else if (cityAtTile.size >= 13) {
yield += 2;

// TODO: +1 more for industrial civs.
}
}

// Bonus resources provide a boost in yield regardless of whether
// there is a city.
if (Resource != Resource.NONE && player.KnowsAboutResource(Resource)) {
yield += this.Resource.ShieldsBonus;
}

if (this.overlays.mine) {
yield += this.overlayTerrainType.miningBonus;
if (this.overlays.railroad) {
yield += 1;
}
}

return yield;
}

// TODO: This is innacurate for city centers.
public int commerceYield(Player player) {
int yield = overlayTerrainType.baseCommerceProduction;
if (this.Resource != Resource.NONE && player.KnowsAboutResource(Resource)) {
Expand All @@ -222,6 +259,38 @@ public int commerceYield(Player player) {
if (BordersRiver()) {
yield += 1;
}
if (overlays.road) {
yield += overlayTerrainType.roadBonus;
}

// See https://wiki.civforum.de/wiki/Stadtfeldertrag_(Civ3)
if (HasCity) {
int regularCityYield;
if (cityAtTile.size < 7) {
regularCityYield = 1;
} else if (cityAtTile.size < 13) {
regularCityYield = 2;
} else {
regularCityYield = 3;
}
if (BordersRiver()) {
regularCityYield += 1;
}
if (this.Resource != Resource.NONE && player.KnowsAboutResource(Resource)) {
regularCityYield += this.Resource.CommerceBonus;
}

int capitalCityYield = 0;
if (cityAtTile.IsCapital()) {
capitalCityYield = 4;
}

yield = Math.Max(regularCityYield, capitalCityYield);
}

// TODO: handle the commerce bonus for costal cities+seafaring
// TODO: handle the commerce bonus for commerial civs
// TODO: handle the commerce bonus from Republic/Democracy.
return yield;
}

Expand Down

0 comments on commit 5106d01

Please sign in to comment.