mirror of
https://github.com/yairm210/Unciv.git
synced 2025-03-09 04:09:35 +07:00
G&K Neutral Tile Road Maintenance (#8138)
* Redo * New parameterized and actually used Road Unique * Remove unneeded * Update CURRENT_COMPATIBILITY_NUMBER since adding new serialization data * Make neutralRoads for CivilizationInfo.kt Transient
This commit is contained in:
parent
8d0acd0647
commit
bc483e8984
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "Global uniques",
|
||||
"name": "Global uniques",
|
||||
"uniques": [
|
||||
"[-75]% growth [in all cities] <when between [-10] and [0] Happiness>",
|
||||
"Nullifies Growth [in all cities] <when below [-10] Happiness>",
|
||||
@ -7,19 +7,19 @@
|
||||
"[-33]% Strength <for [All] units> <when below [-10] Happiness>",
|
||||
"Cannot build [Settler] units <when below [-10] Happiness>",
|
||||
"Rebel units may spawn <when below [-20] Happiness>"
|
||||
|
||||
|
||||
// TODO: Implement the uniques below
|
||||
// "[+20]% [Culture] [in all cities] <during a golden age>",
|
||||
// "[+20]% [Production] [in all cities] <during a golden age>",
|
||||
|
||||
|
||||
// "[+10]% growth [in all cities] <during We Love The King Day>",
|
||||
|
||||
|
||||
// "Nullifies All Yield <while is in resistance>",
|
||||
|
||||
|
||||
// "[-25]% [Science] [in pupetted cities]" -- Imo cityFilters should ideally become conditionals anyway
|
||||
// "[-25]% [Culture] [in pupetted cities]"
|
||||
|
||||
|
||||
// "[+20]% [Production] [in cities connected via railroad]"
|
||||
// something something unit supply
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -108,8 +108,7 @@
|
||||
"terrainsCanBeBuiltOn": ["Land"],
|
||||
"turnsToBuild": 4,
|
||||
"techRequired": "The Wheel",
|
||||
// "Costs [1] gold per turn when in your territory" does nothing and is only to inform the user
|
||||
"uniques": ["Can be built outside your borders", "Costs [1] gold per turn when in your territory"],
|
||||
"uniques": ["Can be built outside your borders", "Costs [1] [Gold] per turn"],
|
||||
"shortcutKey": "R",
|
||||
"civilopediaText": [
|
||||
{"text":"Reduces movement cost to ½ if the other tile also has a Road or Railroad"},
|
||||
@ -122,7 +121,7 @@
|
||||
"terrainsCanBeBuiltOn": ["Land"],
|
||||
"turnsToBuild": 4,
|
||||
"techRequired": "Railroads",
|
||||
"uniques": ["Can be built outside your borders", "Costs [2] gold per turn when in your territory"],
|
||||
"uniques": ["Can be built outside your borders", "Costs [2] [Gold] per turn"],
|
||||
"shortcutKey": "R",
|
||||
"civilopediaText": [{"text":"Reduces movement cost to ⅒ if the other tile also has a Railroad"}]
|
||||
},
|
||||
|
@ -108,8 +108,7 @@
|
||||
"terrainsCanBeBuiltOn": ["Land"],
|
||||
"turnsToBuild": 4,
|
||||
"techRequired": "The Wheel",
|
||||
// "Costs [1] gold per turn when in your territory" does nothing and is only to inform the user
|
||||
"uniques": ["Can be built outside your borders", "Costs [1] gold per turn when in your territory"],
|
||||
"uniques": ["Can be built outside your borders", "Costs [1] [Gold] per turn when in your territory"],
|
||||
"shortcutKey": "R",
|
||||
"civilopediaText": [
|
||||
{"text":"Reduces movement cost to ½ if the other tile also has a Road or Railroad"},
|
||||
@ -122,7 +121,7 @@
|
||||
"terrainsCanBeBuiltOn": ["Land"],
|
||||
"turnsToBuild": 4,
|
||||
"techRequired": "Railroads",
|
||||
"uniques": ["Can be built outside your borders", "Costs [2] gold per turn when in your territory"],
|
||||
"uniques": ["Can be built outside your borders", "Costs [2] [Gold] per turn when in your territory"],
|
||||
"shortcutKey": "R",
|
||||
"civilopediaText": [{"text":"Reduces movement cost to ⅒ if the other tile also has a Railroad"}]
|
||||
},
|
||||
|
@ -66,7 +66,7 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
|
||||
companion object {
|
||||
/** The current compatibility version of [GameInfo]. This number is incremented whenever changes are made to the save file structure that guarantee that
|
||||
* previous versions of the game will not be able to load or play a game normally. */
|
||||
const val CURRENT_COMPATIBILITY_NUMBER = 2
|
||||
const val CURRENT_COMPATIBILITY_NUMBER = 3
|
||||
|
||||
val CURRENT_COMPATIBILITY_VERSION = CompatibilityVersion(CURRENT_COMPATIBILITY_NUMBER, UncivGame.VERSION)
|
||||
|
||||
@ -498,6 +498,7 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
|
||||
civInfo.thingsToFocusOnForVictory =
|
||||
civInfo.getPreferredVictoryTypeObject()?.getThingsToFocus(civInfo) ?: setOf()
|
||||
}
|
||||
tileMap.setNeutralTransients() // has to happen after civInfo.setTransients() sets owningCity
|
||||
|
||||
convertFortify()
|
||||
|
||||
|
@ -73,8 +73,8 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
||||
return cost.toInt()
|
||||
}
|
||||
|
||||
private fun getTransportationUpkeep(): Int {
|
||||
var transportationUpkeep = 0f
|
||||
private fun getTransportationUpkeep(): Stats {
|
||||
val transportationUpkeep = Stats()
|
||||
// we no longer use .flatMap, because there are a lot of tiles and keeping them all in a list
|
||||
// just to go over them once is a waste of memory - there are low-end phones who don't have much ram
|
||||
|
||||
@ -88,14 +88,38 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
||||
if (tile.isCityCenter()) continue
|
||||
if (tile.getUnpillagedRoad() == RoadStatus.None) continue // Cheap checks before pricey checks
|
||||
if (ignoredTileTypes.any { tile.matchesFilter(it, civInfo) }) continue
|
||||
|
||||
transportationUpkeep += tile.getUnpillagedRoad().upkeep
|
||||
val road = tile.getUnpillagedRoadImprovement()
|
||||
if (road!!.hasUnique(UniqueType.ImprovementMaintenance, StateForConditionals(civInfo, tile = tile))) {
|
||||
for(unique in road.getMatchingUniques(UniqueType.ImprovementMaintenance)) {
|
||||
transportationUpkeep.add(Stat.valueOf(unique.params[1]), unique.params[0].toFloat())
|
||||
}
|
||||
}
|
||||
if (road.hasUnique(UniqueType.ImprovementAllMaintenance, StateForConditionals(civInfo, tile = tile))) {
|
||||
for(unique in road.getMatchingUniques(UniqueType.ImprovementAllMaintenance)) {
|
||||
transportationUpkeep.add(Stat.valueOf(unique.params[1]), unique.params[0].toFloat())
|
||||
}
|
||||
}
|
||||
// backwards compatible
|
||||
if (road.hasUnique(UniqueType.OldImprovementMaintenance, StateForConditionals(civInfo, tile = tile))) {
|
||||
transportationUpkeep.add(Stat.Gold, tile.getUnpillagedRoad().upkeep.toFloat())
|
||||
}
|
||||
}
|
||||
}
|
||||
// tabulate neutral roads
|
||||
for (position in civInfo.neutralRoads) {
|
||||
val tile = civInfo.gameInfo.tileMap[position]
|
||||
if (tile.getUnpillagedRoad() == RoadStatus.None) continue // Cheap checks before pricey checks
|
||||
val road = tile.getUnpillagedRoadImprovement()
|
||||
if (road!!.hasUnique(UniqueType.ImprovementAllMaintenance, StateForConditionals(civInfo, tile = tile))) {
|
||||
for(unique in road.getMatchingUniques(UniqueType.ImprovementAllMaintenance)) {
|
||||
transportationUpkeep.add(Stat.valueOf(unique.params[1]), unique.params[0].toFloat())
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unique in civInfo.getMatchingUniques(UniqueType.RoadMaintenance))
|
||||
transportationUpkeep *= unique.params[0].toPercent()
|
||||
transportationUpkeep.times(unique.params[0].toPercent())
|
||||
|
||||
return transportationUpkeep.toInt()
|
||||
return transportationUpkeep
|
||||
}
|
||||
|
||||
fun getUnitSupply(): Int {
|
||||
@ -156,7 +180,7 @@ class CivInfoStats(val civInfo: CivilizationInfo) {
|
||||
}
|
||||
}
|
||||
|
||||
statMap["Transportation upkeep"] = Stats(gold = -getTransportationUpkeep().toFloat())
|
||||
statMap["Transportation upkeep"] = getTransportationUpkeep() * -1
|
||||
statMap["Unit upkeep"] = Stats(gold = -getUnitMaintenance().toFloat())
|
||||
|
||||
|
||||
|
@ -145,6 +145,9 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
|
||||
@Transient
|
||||
var thingsToFocusOnForVictory = setOf<Victory.Focus>()
|
||||
|
||||
@Transient
|
||||
var neutralRoads = HashSet<Vector2>()
|
||||
|
||||
var playerType = PlayerType.AI
|
||||
|
||||
/** Used in online multiplayer for human players */
|
||||
@ -280,6 +283,7 @@ class CivilizationInfo : IsPartOfGameInfoSerialization {
|
||||
toReturn.diplomacy[diplomacyManager.otherCivName] = diplomacyManager
|
||||
toReturn.proximity.putAll(proximity)
|
||||
toReturn.cities = cities.map { it.clone() }
|
||||
toReturn.neutralRoads = neutralRoads
|
||||
|
||||
// This is the only thing that is NOT switched out, which makes it a source of ConcurrentModification errors.
|
||||
// Cloning it by-pointer is a horrific move, since the serialization would go over it ANYWAY and still lead to concurrency problems.
|
||||
|
@ -44,10 +44,20 @@ open class TileInfo : IsPartOfGameInfoSerialization {
|
||||
private set
|
||||
|
||||
fun setOwningCity(city:CityInfo?){
|
||||
if (city != null) {
|
||||
if (roadStatus != RoadStatus.None && roadOwner != "") {
|
||||
// remove previous neutral tile owner
|
||||
getRoadOwner()!!.neutralRoads.remove(this.position)
|
||||
}
|
||||
roadOwner = city.civInfo.civName // only when taking control, otherwise last owner
|
||||
} else {
|
||||
if (roadStatus != RoadStatus.None && owningCity != null) {
|
||||
// previous tile owner still owns road, add to tracker
|
||||
owningCity!!.civInfo.neutralRoads.add(this.position)
|
||||
}
|
||||
}
|
||||
owningCity = city
|
||||
isCityCenterInternal = getCity()?.location == position
|
||||
if (city != null) // only when taking control, otherwise last owner
|
||||
roadOwner = city.civInfo.civName
|
||||
}
|
||||
|
||||
@Transient
|
||||
@ -272,6 +282,10 @@ open class TileInfo : IsPartOfGameInfoSerialization {
|
||||
else
|
||||
roadStatus
|
||||
}
|
||||
fun getUnpillagedRoadImprovement(): TileImprovement? {
|
||||
return if (getUnpillagedRoad() == RoadStatus.None) null
|
||||
else ruleset.tileImprovements[getUnpillagedRoad().name]
|
||||
}
|
||||
|
||||
fun changeImprovement(improvementStr: String?) {
|
||||
improvementIsPillaged = false
|
||||
@ -282,16 +296,20 @@ open class TileInfo : IsPartOfGameInfoSerialization {
|
||||
fun addRoad(roadType: RoadStatus, unitCivInfo: CivilizationInfo) {
|
||||
roadStatus = roadType
|
||||
roadIsPillaged = false
|
||||
roadOwner = if (getOwner() == null)
|
||||
unitCivInfo.civName // neutral tile, use building unit
|
||||
else
|
||||
getOwner()!!.civName
|
||||
if (getOwner() == null) {
|
||||
roadOwner = unitCivInfo.civName // neutral tile, use building unit
|
||||
unitCivInfo.neutralRoads.add(this.position)
|
||||
} else {
|
||||
roadOwner = getOwner()!!.civName
|
||||
}
|
||||
}
|
||||
|
||||
// function handling when removing a road from the tile
|
||||
fun removeRoad() {
|
||||
roadStatus = RoadStatus.None
|
||||
roadIsPillaged = false
|
||||
if (owningCity == null)
|
||||
getRoadOwner()!!.neutralRoads.remove(this.position)
|
||||
}
|
||||
|
||||
fun getShownImprovement(viewingCiv: CivilizationInfo?): String? {
|
||||
@ -1165,6 +1183,7 @@ open class TileInfo : IsPartOfGameInfoSerialization {
|
||||
fun setTransients() {
|
||||
setTerrainTransients()
|
||||
setUnitTransients(true)
|
||||
setOwnerTransients()
|
||||
}
|
||||
|
||||
fun setTerrainTransients() {
|
||||
@ -1194,6 +1213,11 @@ open class TileInfo : IsPartOfGameInfoSerialization {
|
||||
}
|
||||
}
|
||||
|
||||
fun setOwnerTransients() {
|
||||
if (owningCity == null && roadOwner != "")
|
||||
getRoadOwner()!!.neutralRoads.add(this.position)
|
||||
}
|
||||
|
||||
fun stripUnits() {
|
||||
for (unit in this.getUnits()) removeUnit(unit)
|
||||
}
|
||||
|
@ -459,6 +459,14 @@ class TileMap : IsPartOfGameInfoSerialization {
|
||||
}
|
||||
}
|
||||
|
||||
/** Initialize based on TileInfo which Civ has neutral tile roads
|
||||
*/
|
||||
fun setNeutralTransients() {
|
||||
for (tileInfo in values) {
|
||||
tileInfo.setOwnerTransients()
|
||||
}
|
||||
}
|
||||
|
||||
fun removeMissingTerrainModReferences(ruleSet: Ruleset) {
|
||||
for (tile in this.values) {
|
||||
for (terrainFeature in tile.terrainFeatures.filter { !ruleSet.terrains.containsKey(it) })
|
||||
|
@ -565,7 +565,10 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags:
|
||||
RemovesFeaturesIfBuilt("Removes removable features when built", UniqueTarget.Improvement),
|
||||
|
||||
DefensiveBonus("Gives a defensive bonus of [relativeAmount]%", UniqueTarget.Improvement),
|
||||
ImprovementMaintenance("Costs [amount] gold per turn when in your territory", UniqueTarget.Improvement), // Unused
|
||||
ImprovementMaintenance("Costs [amount] [stat] per turn when in your territory", UniqueTarget.Improvement), // Roads
|
||||
ImprovementAllMaintenance("Costs [amount] [stat] per turn", UniqueTarget.Improvement), // Roads
|
||||
//@Deprecated("as of 4.3.9", ReplaceWith("Costs [amount] [stats] per turn when in your territory"), DeprecationLevel.ERROR)
|
||||
OldImprovementMaintenance("Costs [amount] gold per turn when in your territory", UniqueTarget.Improvement), // unused
|
||||
DamagesAdjacentEnemyUnits("Adjacent enemy units ending their turn take [amount] damage", UniqueTarget.Improvement),
|
||||
TakeOverTilesAroundWhenBuilt("Constructing it will take over the tiles around it and assign them to your closest city", UniqueTarget.Improvement),
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user