diff --git a/C7/Text/c7-static-map-save.json b/C7/Text/c7-static-map-save.json index 55d0f1b4..d072c3b9 100644 --- a/C7/Text/c7-static-map-save.json +++ b/C7/Text/c7-static-map-save.json @@ -58113,6 +58113,7 @@ "allowCities": true, "miningBonus": 1, "irrigationBonus": 1, + "roadBonus": 1, "defenseBonus": { "description": "Desert", "amount": 0.1 @@ -58128,6 +58129,7 @@ "allowCities": true, "miningBonus": 1, "irrigationBonus": 1, + "roadBonus": 1, "defenseBonus": { "description": "Plains", "amount": 0.1 @@ -58143,6 +58145,7 @@ "allowCities": true, "miningBonus": 1, "irrigationBonus": 1, + "roadBonus": 1, "defenseBonus": { "description": "Grassland", "amount": 0.1 @@ -58158,6 +58161,7 @@ "allowCities": true, "miningBonus": 1, "irrigationBonus": 0, + "roadBonus": 1, "defenseBonus": { "description": "Tundra", "amount": 0.1 @@ -58173,6 +58177,7 @@ "allowCities": true, "miningBonus": 0, "irrigationBonus": 1, + "roadBonus": 1, "defenseBonus": { "description": "Flood Plain", "amount": 0.1 @@ -58188,6 +58193,7 @@ "allowCities": true, "miningBonus": 2, "irrigationBonus": 0, + "roadBonus": 1, "defenseBonus": { "description": "Hills", "amount": 0.5 @@ -58203,6 +58209,7 @@ "allowCities": false, "miningBonus": 2, "irrigationBonus": 0, + "roadBonus": 1, "defenseBonus": { "description": "Mountains", "amount": 1 @@ -58218,6 +58225,7 @@ "allowCities": true, "miningBonus": 0, "irrigationBonus": 0, + "roadBonus": 1, "defenseBonus": { "description": "Forest", "amount": 0.25 @@ -58233,6 +58241,7 @@ "allowCities": true, "miningBonus": 0, "irrigationBonus": 0, + "roadBonus": 1, "defenseBonus": { "description": "Jungle", "amount": 0.25 @@ -58248,6 +58257,7 @@ "allowCities": false, "miningBonus": 0, "irrigationBonus": 0, + "roadBonus": 1, "defenseBonus": { "description": "Marsh", "amount": 0.2 @@ -58263,6 +58273,7 @@ "allowCities": false, "miningBonus": 0, "irrigationBonus": 0, + "roadBonus": 0, "defenseBonus": { "description": "Volcano", "amount": 0.8 @@ -58278,6 +58289,7 @@ "allowCities": false, "miningBonus": 0, "irrigationBonus": 0, + "roadBonus": 0, "defenseBonus": { "description": "Coast", "amount": 0.1 @@ -58293,6 +58305,7 @@ "allowCities": false, "miningBonus": 0, "irrigationBonus": 0, + "roadBonus": 0, "defenseBonus": { "description": "Sea", "amount": 0.1 @@ -58308,6 +58321,7 @@ "allowCities": false, "miningBonus": 0, "irrigationBonus": 0, + "roadBonus": 0, "defenseBonus": { "description": "Ocean", "amount": 0.1 diff --git a/C7GameData/City.cs b/C7GameData/City.cs index 880ebda5..e2de1e67 100644 --- a/C7GameData/City.cs +++ b/C7GameData/City.cs @@ -108,7 +108,7 @@ 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); } @@ -116,16 +116,17 @@ public int CurrentFoodYield() { } 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); } diff --git a/C7GameData/TerrainType.cs b/C7GameData/TerrainType.cs index 3daf7c0a..6ac774de 100644 --- a/C7GameData/TerrainType.cs +++ b/C7GameData/TerrainType.cs @@ -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 @@ -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; } diff --git a/C7GameData/Tile.cs b/C7GameData/Tile.cs index d4a3668f..2fbc3b29 100644 --- a/C7GameData/Tile.cs +++ b/C7GameData/Tile.cs @@ -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)) { @@ -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; }