Farms near freshwater (#3063)

* Farms near freshwater
* Farm now has unique "Can also be built on tiles adjacent to fresh water"
https://civilization.fandom.com/wiki/Farm_(Civ5)
Even snow: https://www.reddit.com/r/civ/comments/11qtko/farms_on_snow/
Hill+Farm, Snow+Farm, Tundra+Farm sprites by THE BUCKETEER and Ravignir from discord
* fields improvingTech and improvingTechStats converted into uniques
e.g.:
"[+1 Production] once [Scientific Theory] is discovered"
"[+1 Food] on [fresh water] tiles once [Civil Service] is discovered"
"[+1 Food] on [non-fresh water] tiles once [Fertilizer] is discovered"

* ai will build trading posts and farms in snow and tundra if it has no better tiles to work on

* "Provides a one-time Production bonus to the closest city when cut down" unique for forest

* update template.properties
This commit is contained in:
HadeanLake 2020-09-02 19:49:29 +03:00 committed by GitHub
parent 64d12a5d2f
commit 8f75368b99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 328 additions and 267 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 932 B

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 881 KiB

After

Width:  |  Height:  |  Size: 882 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 495 KiB

After

Width:  |  Height:  |  Size: 496 KiB

View file

@ -87,7 +87,8 @@
"unbuildable": true,
"defenceBonus": 0.25,
"occursOn": ["Tundra","Plains","Grassland","Hill"],
"rough": true
"rough": true,
"uniques": ["Provides a one-time Production bonus to the closest city when cut down"]
},
{
"name": "Jungle",

View file

@ -6,8 +6,7 @@
"food": 1,
"turnsToBuild": 7,
"techRequired": "Agriculture",
"improvingTech": "Fertilizer",
"improvingTechStats": {"food": 1}
"uniques": ["Can also be built on tiles adjacent to fresh water", "[+1 Food] on [fresh water] tiles once [Civil Service] is discovered", "[+1 Food] on [non-fresh water] tiles once [Fertilizer] is discovered"],
},
{
"name": "Lumber mill",
@ -15,8 +14,7 @@
"production": 1,
"turnsToBuild": 7,
"techRequired": "Construction",
"improvingTech": "Steam Power",
"improvingTechStats": {"production": 1}
"uniques": ["[+1 Production] once [Scientific Theory] is discovered"]
},
{
"name": "Mine",
@ -24,8 +22,7 @@
"production": 1,
"turnsToBuild": 7,
"techRequired": "Mining",
"improvingTech": "Chemistry",
"improvingTechStats": {"production": 1}
"uniques": ["[+1 Production] once [Chemistry] is discovered"]
},
{
"name": "Trading post",
@ -33,8 +30,7 @@
"gold": 1,
"turnsToBuild": 7,
"techRequired": "Guilds",
"improvingTech": "Economics",
"improvingTechStats": {"gold": 1}
"uniques": ["[+1 Gold] once [Economics] is discovered"]
},
// Resource-specific
@ -43,8 +39,7 @@
"resourceTerrainAllow": ["Forest"],
"turnsToBuild": 7,
"techRequired": "Trapping",
"improvingTech": "Economics",
"improvingTechStats": {"gold": 1}
"uniques": ["[+1 Gold] once [Economics] is discovered"]
},
{
"name": "Oil well",
@ -55,31 +50,27 @@
"name": "Pasture",
"turnsToBuild": 8,
"techRequired": "Animal Husbandry",
"improvingTech": "Fertilizer",
"improvingTechStats": {"food": 1}
"uniques": ["[+1 Food] once [Fertilizer] is discovered"]
},
{
"name": "Plantation",
"turnsToBuild": 6,
"gold": 1,
"techRequired": "Calendar",
"improvingTech": "Fertilizer",
"improvingTechStats": {"food": 1}
"uniques": ["[+1 Food] once [Fertilizer] is discovered"]
},
{
"name": "Quarry",
"turnsToBuild": 8,
"techRequired": "Masonry",
"improvingTech": "Chemistry",
"improvingTechStats": {"production": 1}
"uniques": ["[+1 Production] once [Chemistry] is discovered"]
},
{
"name": "Fishing Boats",
"terrainsCanBeBuiltOn": ["Coast"],
"food": 1,
"techRequired": "Sailing",
"improvingTech": "Compass",
"improvingTechStats": {"gold": 1}
"uniques": ["[+1 Gold] once [Compass] is discovered"]
},
// Military improvement
@ -110,28 +101,28 @@
"name": "Remove Forest",
"turnsToBuild": 4,
"terrainsCanBeBuiltOn": ["Forest"],
"techRequired": "Mining"
"techRequired": "Mining",
"uniques": ["Can be built outside your borders"]
},
{
"name": "Remove Jungle",
"turnsToBuild": 7,
"terrainsCanBeBuiltOn": ["Jungle"],
"techRequired": "Bronze Working"
"techRequired": "Bronze Working",
"uniques": ["Can be built outside your borders"]
},
{
"name": "Remove Fallout",
"turnsToBuild": 8,
"terrainsCanBeBuiltOn": ["Fallout"],
"techRequired": "Atomic Theory"
"techRequired": "Atomic Theory",
"uniques": ["Can be built outside your borders"]
},
{
"name": "Remove Marsh",
"turnsToBuild": 6,
"terrainsCanBeBuiltOn": ["Marsh"],
"techRequired": "Bronze Working"
"techRequired": "Bronze Working",
"uniques": ["Can be built outside your borders"]
},
@ -148,34 +139,30 @@
},
{
"name": "Cancel improvement order",
"uniques": ["Can be built outside your borders"]
},
// Great Person improvements
{
"name": "Academy",
"science": 8,
"uniques": ["Great Improvement"],
"improvingTech": "Scientific Theory",
"improvingTechStats": {"science": 2}
"uniques": ["Great Improvement", "[+2 Science] once [Scientific Theory] is discovered"]
// in Gods & Kings academy will also have "[+2 Science] once [Atomic Theory] is discovered"
},
{
"name": "Landmark",
"culture": 6,
"uniques": ["Great Improvement"],
"uniques": ["Great Improvement"]
},
{
"name": "Manufactory",
"production": 4,
"improvingTech": "Chemistry",
"uniques": ["Great Improvement"],
"improvingTechStats": {"production": 1}
"uniques": ["Great Improvement", "[+1 Production] once [Chemistry] is discovered"]
},
{
"name": "Customs house",
"gold": 4,
"improvingTech": "Economics",
"uniques": ["Great Improvement"],
"improvingTechStats": {"gold": 1}
"uniques": ["Great Improvement", "[+1 Gold] once [Economics] is discovered"]
},
{
"name": "Citadel",
@ -190,8 +177,7 @@
"turnsToBuild": 4,
"uniques": ["[+1 Culture] for each adjacent [Moai]", "Can only be built on Coastal tiles"],
"techRequired": "Construction",
"improvingTech": "Flight",
"improvingTechStats": {"gold": 1}
"uniques": ["[+1 Gold] once [Flight] is discovered"]
},
{
"name": "Terrace farm",
@ -199,10 +185,8 @@
"terrainsCanBeBuiltOn": ["Hill"],
"food": 1,
"turnsToBuild": 7,
"uniques": ["[+1 Food] for each adjacent [Mountain]", "Cannot be built on bonus resource"],
"techRequired": "Construction",
"improvingTech": "Fertilizer",
"improvingTechStats": {"food":1}
"uniques": ["[+1 Food] for each adjacent [Mountain]", "Cannot be built on bonus resource", "[+1 Food] on [fresh water] tiles once [Civil Service] is discovered", "[+1 Food] on [non-fresh water] tiles once [Fertilizer] is discovered"],
"techRequired": "Construction"
},
{ "name": "Ancient ruins" },

View file

@ -434,6 +434,7 @@ Our proposed trade request is no longer relevant! =
[defender] withdrew from a [attacker] =
[building] has provided [amount] Gold! =
[civName] has stolen your territory! =
Clearing a [forest] has created [amount] Production for [cityName] =
# World Screen UI
@ -599,6 +600,8 @@ vs [unitType] =
Terrain =
Tile =
Missing resource =
[stats] on [tileType] tiles =
from improvements: =
Hurry Research =
@ -630,6 +633,8 @@ Water =
# For [stats] from [Water resource] tiles in this city
Water resource =
River =
fresh water =
non-fresh water =
Wonders =
Base values =

View file

@ -208,7 +208,9 @@ class WorkerAutomation(val unit: MapUnit) {
tile.terrainFeature == Constants.forest -> "Lumber mill"
tile.baseTerrain == Constants.hill -> "Mine"
tile.baseTerrain in listOf(Constants.grassland,Constants.desert,Constants.plains) -> "Farm"
tile.baseTerrain == Constants.tundra -> Constants.tradingPost
tile.baseTerrain in listOf(Constants.tundra, Constants.snow)
&& tile.isAdjacentToFreshwater -> "Farm"
tile.baseTerrain in listOf(Constants.tundra, Constants.snow) -> Constants.tradingPost
else -> null
}
if (improvementString == null) return null

View file

@ -372,7 +372,7 @@ class MapUnit {
private fun workOnImprovement() {
val tile = getTile()
tile.turnsToImprovement -= 1
if (tile.turnsToImprovement != 0 && !civInfo.gameInfo.gameParameters.godMode) return
if (tile.turnsToImprovement != 0) return
if (civInfo.isCurrentPlayer())
UncivGame.Current.settings.addCompletedTutorialTask("Construct an improvement")
@ -387,7 +387,12 @@ class MapUnit {
}
if (tile.improvementInProgress == "Remove Road" || tile.improvementInProgress == "Remove Railroad")
tile.roadStatus = RoadStatus.None
else tile.terrainFeature = null
else {
if (tile.tileMap.gameInfo.ruleSet.terrains[tile.terrainFeature]!!.uniques
.contains("Provides a one-time Production bonus to the closest city when cut down"))
tryProvideProductionToClosestCity()
tile.terrainFeature = null
}
}
tile.improvementInProgress == "Road" -> tile.roadStatus = RoadStatus.Road
tile.improvementInProgress == "Railroad" -> tile.roadStatus = RoadStatus.Railroad
@ -399,6 +404,21 @@ class MapUnit {
tile.improvementInProgress = null
}
private fun tryProvideProductionToClosestCity()
{
val tile = getTile()
val closestCity = civInfo.cities.minBy { it.getCenterTile().aerialDistanceTo(tile) }
if (closestCity == null) return
val distance = closestCity.getCenterTile().aerialDistanceTo(tile)
var productionPointsToAdd = if (distance == 1) 20 else 20 - (distance - 2) * 5
if (tile.owningCity == null || tile.owningCity!!.civInfo != civInfo ) productionPointsToAdd = productionPointsToAdd * 2 / 3
if (productionPointsToAdd > 0) {
closestCity.cityConstructions.addProductionPoints(productionPointsToAdd)
civInfo.addNotification("Clearing a [${tile.terrainFeature}] has created [$productionPointsToAdd] Production for [${closestCity.name}]", closestCity.location, Color.BROWN)
}
}
private fun heal() {
if (isEmbarked()) return // embarked units can't heal
var amountToHealBy = rankTileForHealing(getTile())

View file

@ -243,16 +243,24 @@ open class TileInfo {
if (hasViewableResource(observingCiv) && getTileResource().improvement == improvement.name)
stats.add(getTileResource().improvementStats!!.clone()) // resource-specific improvement
// As of 3.10.5 This is to be deprecated and converted to "[stats] once [tech] is discovered" - keeping it here to that mods with this can still work for now
if (improvement.improvingTech != null && observingCiv.tech.isResearched(improvement.improvingTech!!))
stats.add(improvement.improvingTechStats!!) // eg Chemistry for mines
for (unique in improvement.uniqueObjects) if (unique.placeholderText == "[] once [] is discovered"
&& observingCiv.tech.isResearched(unique.params[1])) stats.add(Stats.parse(unique.params[0]))
if(city!=null) {
val cityWideUniques = city.cityConstructions.builtBuildingUniqueMap.getUniques("[] from [] tiles in this city")
val civWideUniques = city.civInfo.getMatchingUniques("[] from every []")
for (unique in cityWideUniques + civWideUniques) {
val improvementUniques = improvement.uniqueObjects.filter { it.placeholderText == "[] on [] tiles once [] is discovered"
&& observingCiv.tech.isResearched(it.params[2]) }
for (unique in cityWideUniques + civWideUniques + improvementUniques) {
if (improvement.name == unique.params[1]
|| (unique.params[1] == "Great Improvement" && improvement.isGreatImprovement()))
|| (unique.params[1] == "Great Improvement" && improvement.isGreatImprovement())
|| (unique.params[1] == "fresh water" && isAdjacentToFreshwater)
|| (unique.params[1] == "non-fresh water" && !isAdjacentToFreshwater)
)
stats.add(Stats.parse(unique.params[0]))
}
}
@ -293,6 +301,8 @@ open class TileInfo {
improvement.name == "Remove Railroad" && this.roadStatus == RoadStatus.Railroad -> true
improvement.name == Constants.cancelImprovementOrder && this.improvementInProgress != null -> true
topTerrain.unbuildable && (topTerrain.name !in improvement.resourceTerrainAllow) -> false
improvement.hasUnique("Can also be built on tiles adjacent to fresh water")
&& isAdjacentToFreshwater -> true
"Can only be built on Coastal tiles" in improvement.uniques && isCoastalTile() -> true
else -> hasViewableResource(civInfo) && getTileResource().improvement == improvement.name
}
@ -431,7 +441,7 @@ open class TileInfo {
fun startWorkingOnImprovement(improvement: TileImprovement, civInfo: CivilizationInfo) {
improvementInProgress = improvement.name
turnsToImprovement = improvement.getTurnsToBuild(civInfo)
turnsToImprovement = if (civInfo.gameInfo.gameParameters.godMode) 1 else improvement.getTurnsToBuild(civInfo)
}
fun stopWorkingOnImprovement() {

View file

@ -24,6 +24,19 @@ class Technology {
val lineList = ArrayList<String>() // more readable than StringBuilder, with same performance for our use-case
for (unique in uniques) lineList += unique.tr()
val mapOfImprovedImprovements = HashMap<String, ArrayList<String>>()
for (improvement in ruleset.tileImprovements.values) for ( unique in improvement.uniqueObjects
.filter { it.placeholderText in setOf("[] once [] is discovered", "[] on [] tiles once [] is discovered")
&& it.params.last() == name }) {
val key = if (unique.params.size == 2 ) unique.params[0] else "[${unique.params[0]}] on [${unique.params[1]}] tiles"
if (!mapOfImprovedImprovements.containsKey(key)) mapOfImprovedImprovements[key] = ArrayList()
mapOfImprovedImprovements[key]!!.add(improvement.name)
}
for ( improvements in mapOfImprovedImprovements) {
val impimpString = improvements.key.tr() + " from improvements: ".tr() + improvements.value.joinToString(", ") { it.tr() }
lineList += impimpString
}
val improvedImprovements = ruleset.tileImprovements.values
.filter { it.improvingTech == name }.groupBy { it.improvingTechStats.toString() }
for (improvement in improvedImprovements) {

View file

@ -19,7 +19,9 @@ class TileImprovement : NamedStats() {
var techRequired: String? = null
@Deprecated("Deprecated as of 3.10.5. Use [stats] once [tech] is discovered unique instead")
var improvingTech: String? = null
@Deprecated("Deprecated as of 3.10.5. Use [stats] once [tech] is discovered unique instead")
var improvingTechStats: Stats? = null
var uniqueTo:String? = null
var uniques = ArrayList<String>()

View file

@ -539,6 +539,8 @@ class TileEditorOptionsTable(val mapEditorScreen: MapEditorScreen): Table(Camera
-> if (topTerrain.unbuildable && improvement.isGreatImprovement())
tileInfo.terrainFeature = null
topTerrain.unbuildable -> tileInfo.improvement = null // forbid on unbuildable feature
improvement.hasUnique("Can also be built on tiles adjacent to fresh water")
&& tileInfo.isAdjacentToFreshwater -> Unit // allow farms on tiles adjacent to fresh water
"Can only be built on Coastal tiles" in improvement.uniques && tileInfo.isCoastalTile()
-> Unit // allow Moai where appropriate
else -> tileInfo.improvement = null

View file

@ -54,7 +54,8 @@ class TechButton(techName:String, private val techManager: TechManager, isWorldS
techEnabledIcons.add(ImageGetter.getConstructionImage(building.name).surroundWithCircle(techIconSize))
for (improvement in gameBasics.tileImprovements.values
.filter { it.techRequired == techName || it.improvingTech == techName }
.filter { it.techRequired == techName || it.uniqueObjects.any { u -> u.params.contains(techName) }
|| it.improvingTech == techName }
.filter { it.uniqueTo==null || it.uniqueTo==civName }) {
if (improvement.name.startsWith("Remove"))
techEnabledIcons.add(ImageGetter.getImage("OtherIcons/Stop")).size(techIconSize)