mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-28 22:37:02 -04:00
Code reorganization - separated variables, pure functions and state-changing functions in all main logic classes
This commit is contained in:
parent
749ff90fe0
commit
1957c4ca80
@ -21,8 +21,8 @@ android {
|
|||||||
applicationId "com.unciv.game"
|
applicationId "com.unciv.game"
|
||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
targetSdkVersion 26
|
targetSdkVersion 26
|
||||||
versionCode 121
|
versionCode 122
|
||||||
versionName "2.7.8"
|
versionName "2.7.9"
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
|
@ -20,7 +20,6 @@ class UnCivGame : Game() {
|
|||||||
*/
|
*/
|
||||||
val viewEntireMapForDebug = false
|
val viewEntireMapForDebug = false
|
||||||
|
|
||||||
|
|
||||||
lateinit var worldScreen: WorldScreen
|
lateinit var worldScreen: WorldScreen
|
||||||
|
|
||||||
override fun create() {
|
override fun create() {
|
||||||
@ -72,9 +71,7 @@ class UnCivGame : Game() {
|
|||||||
setWorldScreen()
|
setWorldScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
lateinit var Current: UnCivGame
|
lateinit var Current: UnCivGame
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -11,16 +11,28 @@ import com.unciv.models.gamebasics.GameBasics
|
|||||||
import com.unciv.ui.utils.getRandom
|
import com.unciv.ui.utils.getRandom
|
||||||
|
|
||||||
class GameInfo {
|
class GameInfo {
|
||||||
|
@Transient var tilesToCities = HashMap<TileInfo,CityInfo>()
|
||||||
|
|
||||||
var notifications = mutableListOf<Notification>()
|
var notifications = mutableListOf<Notification>()
|
||||||
@Deprecated("As of 2.6.9") var tutorial = mutableListOf<String>()
|
@Deprecated("As of 2.6.9") var tutorial = mutableListOf<String>()
|
||||||
var civilizations = mutableListOf<CivilizationInfo>()
|
var civilizations = mutableListOf<CivilizationInfo>()
|
||||||
var tileMap: TileMap = TileMap()
|
var tileMap: TileMap = TileMap()
|
||||||
var turns = 0
|
var turns = 0
|
||||||
@Transient var tilesToCities = HashMap<TileInfo,CityInfo>()
|
|
||||||
|
|
||||||
|
//region pure functions
|
||||||
|
fun clone():GameInfo{
|
||||||
|
val toReturn = GameInfo()
|
||||||
|
toReturn.civilizations.addAll(civilizations.map { it.clone() })
|
||||||
|
toReturn.tileMap=tileMap.clone()
|
||||||
|
toReturn.notifications.addAll(notifications)
|
||||||
|
toReturn.turns=turns
|
||||||
|
toReturn.setTransients()
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
fun getPlayerCivilization(): CivilizationInfo = civilizations[0]
|
fun getPlayerCivilization(): CivilizationInfo = civilizations[0]
|
||||||
fun getBarbarianCivilization(): CivilizationInfo = civilizations[1]
|
fun getBarbarianCivilization(): CivilizationInfo = civilizations[1]
|
||||||
|
//endregion
|
||||||
|
|
||||||
fun nextTurn() {
|
fun nextTurn() {
|
||||||
notifications.clear()
|
notifications.clear()
|
||||||
@ -98,15 +110,5 @@ class GameInfo {
|
|||||||
for (tile in city.getTiles()) tilesToCities.put(tile,city)
|
for (tile in city.getTiles()) tilesToCities.put(tile,city)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clone():GameInfo{
|
|
||||||
val toReturn = GameInfo()
|
|
||||||
toReturn.civilizations.addAll(civilizations.map { it.clone() })
|
|
||||||
toReturn.tileMap=tileMap.clone()
|
|
||||||
toReturn.notifications.addAll(notifications)
|
|
||||||
toReturn.turns=turns
|
|
||||||
toReturn.setTransients()
|
|
||||||
return toReturn
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,14 @@ class CityConstructions {
|
|||||||
private val inProgressConstructions = HashMap<String, Int>()
|
private val inProgressConstructions = HashMap<String, Int>()
|
||||||
var currentConstruction: String = "Monument" // default starting building!
|
var currentConstruction: String = "Monument" // default starting building!
|
||||||
|
|
||||||
|
//region pure functions
|
||||||
|
fun clone(): CityConstructions {
|
||||||
|
val toReturn = CityConstructions()
|
||||||
|
toReturn.currentConstruction=currentConstruction
|
||||||
|
toReturn.builtBuildings.addAll(builtBuildings)
|
||||||
|
toReturn.inProgressConstructions.putAll(inProgressConstructions)
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
internal fun getBuildableBuildings(): List<Building> = GameBasics.Buildings.values
|
internal fun getBuildableBuildings(): List<Building> = GameBasics.Buildings.values
|
||||||
.filter { it.isBuildable(this) }
|
.filter { it.isBuildable(this) }
|
||||||
@ -24,7 +32,6 @@ class CityConstructions {
|
|||||||
fun getConstructableUnits() = GameBasics.Units.values
|
fun getConstructableUnits() = GameBasics.Units.values
|
||||||
.filter { it.isBuildable(this) }
|
.filter { it.isBuildable(this) }
|
||||||
|
|
||||||
// Library and public school unique (not actualy unique, though...hmm)
|
|
||||||
fun getStats(): Stats {
|
fun getStats(): Stats {
|
||||||
val stats = Stats()
|
val stats = Stats()
|
||||||
for (building in getBuiltBuildings())
|
for (building in getBuiltBuildings())
|
||||||
@ -58,7 +65,7 @@ class CityConstructions {
|
|||||||
|
|
||||||
fun getAmountConstructedText(): String =
|
fun getAmountConstructedText(): String =
|
||||||
if (SpecialConstruction.getSpecialConstructions().any { it.name== currentConstruction}) ""
|
if (SpecialConstruction.getSpecialConstructions().any { it.name== currentConstruction}) ""
|
||||||
else " (" + workDone(currentConstruction) + "/" +
|
else " (" + getWorkDone(currentConstruction) + "/" +
|
||||||
getCurrentConstruction().getProductionCost(cityInfo.civInfo.policies.adoptedPolicies) + ")"
|
getCurrentConstruction().getProductionCost(cityInfo.civInfo.policies.adoptedPolicies) + ")"
|
||||||
|
|
||||||
fun getCurrentConstruction(): IConstruction = getConstruction(currentConstruction)
|
fun getCurrentConstruction(): IConstruction = getConstruction(currentConstruction)
|
||||||
@ -82,6 +89,26 @@ class CityConstructions {
|
|||||||
|
|
||||||
internal fun getBuiltBuildings(): List<Building> = builtBuildings.map { GameBasics.Buildings[it]!! }
|
internal fun getBuiltBuildings(): List<Building> = builtBuildings.map { GameBasics.Buildings[it]!! }
|
||||||
|
|
||||||
|
|
||||||
|
private fun getWorkDone(constructionName: String): Int {
|
||||||
|
if (inProgressConstructions.containsKey(constructionName)) return inProgressConstructions[constructionName]!!
|
||||||
|
else return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fun turnsToConstruction(constructionName: String): Int {
|
||||||
|
val productionCost = getConstruction(constructionName).getProductionCost(cityInfo.civInfo.policies.adoptedPolicies)
|
||||||
|
|
||||||
|
val workLeft = (productionCost - getWorkDone(constructionName)).toFloat() // needs to be float so that we get the cieling properly ;)
|
||||||
|
|
||||||
|
val cityStats = cityInfo.cityStats.currentCityStats
|
||||||
|
var production = Math.round(cityStats.production)
|
||||||
|
if (constructionName == Settler) production += cityStats.food.toInt()
|
||||||
|
|
||||||
|
return Math.ceil((workLeft / production.toDouble())).toInt()
|
||||||
|
}
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region state0changing functions
|
||||||
fun addConstruction(constructionToAdd: Int) {
|
fun addConstruction(constructionToAdd: Int) {
|
||||||
if (!inProgressConstructions.containsKey(currentConstruction)) inProgressConstructions[currentConstruction] = 0
|
if (!inProgressConstructions.containsKey(currentConstruction)) inProgressConstructions[currentConstruction] = 0
|
||||||
inProgressConstructions[currentConstruction] = inProgressConstructions[currentConstruction]!! + constructionToAdd
|
inProgressConstructions[currentConstruction] = inProgressConstructions[currentConstruction]!! + constructionToAdd
|
||||||
@ -126,23 +153,6 @@ class CityConstructions {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun workDone(constructionName: String): Int {
|
|
||||||
if (inProgressConstructions.containsKey(constructionName)) return inProgressConstructions[constructionName]!!
|
|
||||||
else return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
fun turnsToConstruction(constructionName: String): Int {
|
|
||||||
val productionCost = getConstruction(constructionName).getProductionCost(cityInfo.civInfo.policies.adoptedPolicies)
|
|
||||||
|
|
||||||
val workLeft = (productionCost - workDone(constructionName)).toFloat() // needs to be float so that we get the cieling properly ;)
|
|
||||||
|
|
||||||
val cityStats = cityInfo.cityStats.currentCityStats
|
|
||||||
var production = Math.round(cityStats.production)
|
|
||||||
if (constructionName == Settler) production += cityStats.food.toInt()
|
|
||||||
|
|
||||||
return Math.ceil((workLeft / production.toDouble())).toInt()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun purchaseBuilding(buildingName: String) {
|
fun purchaseBuilding(buildingName: String) {
|
||||||
cityInfo.civInfo.gold -= getConstruction(buildingName).getGoldCost(cityInfo.civInfo.policies.adoptedPolicies)
|
cityInfo.civInfo.gold -= getConstruction(buildingName).getGoldCost(cityInfo.civInfo.policies.adoptedPolicies)
|
||||||
getConstruction(buildingName).postBuildEvent(this)
|
getConstruction(buildingName).postBuildEvent(this)
|
||||||
@ -161,21 +171,14 @@ class CityConstructions {
|
|||||||
Automation().chooseNextConstruction(this)
|
Automation().chooseNextConstruction(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun chooseNextConstruction() {
|
||||||
|
Automation().chooseNextConstruction(this)
|
||||||
|
}
|
||||||
|
//endregion
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
internal const val Worker = "Worker"
|
internal const val Worker = "Worker"
|
||||||
internal const val Settler = "Settler"
|
internal const val Settler = "Settler"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun chooseNextConstruction() {
|
|
||||||
Automation().chooseNextConstruction(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun clone(): CityConstructions {
|
|
||||||
val toReturn = CityConstructions()
|
|
||||||
toReturn.currentConstruction=currentConstruction
|
|
||||||
toReturn.builtBuildings.addAll(builtBuildings)
|
|
||||||
toReturn.inProgressConstructions.putAll(inProgressConstructions)
|
|
||||||
return toReturn
|
|
||||||
}
|
|
||||||
|
|
||||||
} // for json parsing, we need to have a default constructor
|
} // for json parsing, we need to have a default constructor
|
@ -5,14 +5,15 @@ import com.unciv.logic.automation.Automation
|
|||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
|
|
||||||
class CityExpansionManager {
|
class CityExpansionManager {
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
lateinit var cityInfo: CityInfo
|
lateinit var cityInfo: CityInfo
|
||||||
var cultureStored: Int = 0
|
var cultureStored: Int = 0
|
||||||
|
|
||||||
fun reset() {
|
|
||||||
cityInfo.tiles.clear()
|
fun clone(): CityExpansionManager {
|
||||||
cityInfo.getCenterTile().getTilesInDistance(1).forEach { takeOwnership(it) }
|
val toReturn = CityExpansionManager()
|
||||||
|
toReturn.cultureStored=cultureStored
|
||||||
|
return toReturn
|
||||||
}
|
}
|
||||||
|
|
||||||
// This one has conflicting sources -
|
// This one has conflicting sources -
|
||||||
@ -29,6 +30,26 @@ class CityExpansionManager {
|
|||||||
return Math.round(cultureToNextTile).toInt()
|
return Math.round(cultureToNextTile).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun getNewTile(): TileInfo? {
|
||||||
|
for (i in 2..5) {
|
||||||
|
val tiles = cityInfo.getCenterTile().getTilesInDistance(i).filter {
|
||||||
|
it.getOwner() != cityInfo.civInfo
|
||||||
|
&& it.getTilesInDistance(1).none { tile->tile.isCityCenter() } // This SHOULD stop cities from grabbing tiles surrounding a city
|
||||||
|
}
|
||||||
|
if (tiles.isEmpty()) continue
|
||||||
|
val chosenTile = tiles.maxBy { Automation().rankTile(it,cityInfo.civInfo) }
|
||||||
|
return chosenTile
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
//region state-changing functions
|
||||||
|
fun reset() {
|
||||||
|
cityInfo.tiles.clear()
|
||||||
|
cityInfo.getCenterTile().getTilesInDistance(1).forEach { takeOwnership(it) }
|
||||||
|
}
|
||||||
|
|
||||||
private fun addNewTileWithCulture() {
|
private fun addNewTileWithCulture() {
|
||||||
cultureStored -= getCultureToNextTile()
|
cultureStored -= getCultureToNextTile()
|
||||||
|
|
||||||
@ -48,18 +69,6 @@ class CityExpansionManager {
|
|||||||
unit.movementAlgs().teleportToClosestMoveableTile()
|
unit.movementAlgs().teleportToClosestMoveableTile()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getNewTile(): TileInfo? {
|
|
||||||
for (i in 2..5) {
|
|
||||||
val tiles = cityInfo.getCenterTile().getTilesInDistance(i).filter {
|
|
||||||
it.getOwner() != cityInfo.civInfo
|
|
||||||
&& it.getTilesInDistance(1).none { tile->tile.isCityCenter() } // This SHOULD stop cities from grabbing tiles surrounding a city
|
|
||||||
}
|
|
||||||
if (tiles.isEmpty()) continue
|
|
||||||
val chosenTile = tiles.maxBy { Automation().rankTile(it,cityInfo.civInfo) }
|
|
||||||
return chosenTile
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
fun nextTurn(culture: Float) {
|
fun nextTurn(culture: Float) {
|
||||||
cultureStored += culture.toInt()
|
cultureStored += culture.toInt()
|
||||||
@ -68,11 +77,5 @@ class CityExpansionManager {
|
|||||||
cityInfo.civInfo.addNotification(cityInfo.name + " {has expanded its borders}!", cityInfo.location, Color.PURPLE)
|
cityInfo.civInfo.addNotification(cityInfo.name + " {has expanded its borders}!", cityInfo.location, Color.PURPLE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//endregion
|
||||||
fun clone(): CityExpansionManager {
|
|
||||||
val toReturn = CityExpansionManager()
|
|
||||||
toReturn.cultureStored=cultureStored
|
|
||||||
return toReturn
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -28,16 +28,63 @@ class CityInfo {
|
|||||||
var workedTiles = HashSet<Vector2>()
|
var workedTiles = HashSet<Vector2>()
|
||||||
var isBeingRazed = false
|
var isBeingRazed = false
|
||||||
|
|
||||||
|
|
||||||
|
constructor() // for json parsing, we need to have a default constructor
|
||||||
|
constructor(civInfo: CivilizationInfo, cityLocation: Vector2) {
|
||||||
|
this.civInfo = civInfo
|
||||||
|
setTransients()
|
||||||
|
|
||||||
|
// Since cities can be captures between civilizations,
|
||||||
|
// we need to check which other cities exist globally and name accordingly
|
||||||
|
val allExistingCityNames = civInfo.gameInfo.civilizations.flatMap { it.cities }.map { it.name }.toHashSet()
|
||||||
|
val probablyName = civInfo.getNation().cities.firstOrNull { !allExistingCityNames.contains(it) }
|
||||||
|
if(probablyName!=null) name=probablyName
|
||||||
|
else name = civInfo.getNation().cities.map { "New $it" }.first { !allExistingCityNames.contains(it) }
|
||||||
|
|
||||||
|
this.location = cityLocation
|
||||||
|
civInfo.cities.add(this)
|
||||||
|
if(civInfo == civInfo.gameInfo.getPlayerCivilization())
|
||||||
|
civInfo.addNotification("$name {has been founded}!", cityLocation, Color.PURPLE)
|
||||||
|
if (civInfo.policies.isAdopted("Legalism") && civInfo.cities.size <= 4) cityConstructions.addCultureBuilding()
|
||||||
|
if (civInfo.cities.size == 1) {
|
||||||
|
cityConstructions.builtBuildings.add("Palace")
|
||||||
|
cityConstructions.currentConstruction = "Worker" // Default for first city only!
|
||||||
|
}
|
||||||
|
|
||||||
|
expansion.reset()
|
||||||
|
civInfo.gameInfo.updateTilesToCities()
|
||||||
|
|
||||||
|
val tile = getCenterTile()
|
||||||
|
tile.roadStatus = RoadStatus.Railroad
|
||||||
|
if (listOf("Forest", "Jungle", "Marsh").contains(tile.terrainFeature))
|
||||||
|
tile.terrainFeature = null
|
||||||
|
|
||||||
|
population.autoAssignPopulation()
|
||||||
|
cityStats.update()
|
||||||
|
}
|
||||||
|
|
||||||
|
//region pure functions
|
||||||
|
fun clone(): CityInfo {
|
||||||
|
val toReturn = CityInfo()
|
||||||
|
toReturn.population = population.clone()
|
||||||
|
toReturn.health=health
|
||||||
|
toReturn.name=name
|
||||||
|
toReturn.tiles.addAll(tiles)
|
||||||
|
toReturn.workedTiles.addAll(workedTiles)
|
||||||
|
toReturn.cityConstructions=cityConstructions.clone()
|
||||||
|
toReturn.expansion = expansion.clone()
|
||||||
|
toReturn.isBeingRazed=isBeingRazed
|
||||||
|
toReturn.location=location
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
internal val tileMap: TileMap
|
internal val tileMap: TileMap
|
||||||
get() = civInfo.gameInfo.tileMap
|
get() = civInfo.gameInfo.tileMap
|
||||||
|
|
||||||
fun getCenterTile(): TileInfo = tileMap[location]
|
fun getCenterTile(): TileInfo = tileMap[location]
|
||||||
fun getTiles(): List<TileInfo> = tiles.map { tileMap[it] }
|
fun getTiles(): List<TileInfo> = tiles.map { tileMap[it] }
|
||||||
|
|
||||||
fun getTilesInRange(): List<TileInfo> = getCenterTile().getTilesInDistance( 3)
|
fun getTilesInRange(): List<TileInfo> = getCenterTile().getTilesInDistance( 3)
|
||||||
|
|
||||||
|
|
||||||
// Remove resources required by buildings
|
|
||||||
fun getCityResources(): Counter<TileResource> {
|
fun getCityResources(): Counter<TileResource> {
|
||||||
val cityResources = Counter<TileResource>()
|
val cityResources = Counter<TileResource>()
|
||||||
|
|
||||||
@ -77,42 +124,16 @@ class CityInfo {
|
|||||||
return greatPersonPoints
|
return greatPersonPoints
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() // for json parsing, we need to have a default constructor
|
fun isCapital() = cityConstructions.isBuilt("Palace")
|
||||||
|
|
||||||
|
internal fun getMaxHealth(): Int {
|
||||||
constructor(civInfo: CivilizationInfo, cityLocation: Vector2) {
|
return 200 + cityConstructions.getBuiltBuildings().sumBy { it.cityHealth }
|
||||||
this.civInfo = civInfo
|
|
||||||
setTransients()
|
|
||||||
|
|
||||||
// Since cities can be captures between civilizations,
|
|
||||||
// we need to check which other cities exist globally and name accordingly
|
|
||||||
val allExistingCityNames = civInfo.gameInfo.civilizations.flatMap { it.cities }.map { it.name }.toHashSet()
|
|
||||||
val probablyName = civInfo.getNation().cities.firstOrNull { !allExistingCityNames.contains(it) }
|
|
||||||
if(probablyName!=null) name=probablyName
|
|
||||||
else name = civInfo.getNation().cities.map { "New $it" }.first { !allExistingCityNames.contains(it) }
|
|
||||||
|
|
||||||
this.location = cityLocation
|
|
||||||
civInfo.cities.add(this)
|
|
||||||
if(civInfo == civInfo.gameInfo.getPlayerCivilization())
|
|
||||||
civInfo.addNotification("$name {has been founded}!", cityLocation, Color.PURPLE)
|
|
||||||
if (civInfo.policies.isAdopted("Legalism") && civInfo.cities.size <= 4) cityConstructions.addCultureBuilding()
|
|
||||||
if (civInfo.cities.size == 1) {
|
|
||||||
cityConstructions.builtBuildings.add("Palace")
|
|
||||||
cityConstructions.currentConstruction = "Worker" // Default for first city only!
|
|
||||||
}
|
|
||||||
|
|
||||||
expansion.reset()
|
|
||||||
civInfo.gameInfo.updateTilesToCities()
|
|
||||||
|
|
||||||
val tile = getCenterTile()
|
|
||||||
tile.roadStatus = RoadStatus.Railroad
|
|
||||||
if (listOf("Forest", "Jungle", "Marsh").contains(tile.terrainFeature))
|
|
||||||
tile.terrainFeature = null
|
|
||||||
|
|
||||||
population.autoAssignPopulation()
|
|
||||||
cityStats.update()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {return name} // for debug
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region state-changing functions
|
||||||
fun setTransients() {
|
fun setTransients() {
|
||||||
population.cityInfo = this
|
population.cityInfo = this
|
||||||
expansion.cityInfo = this
|
expansion.cityInfo = this
|
||||||
@ -120,7 +141,6 @@ class CityInfo {
|
|||||||
cityConstructions.cityInfo = this
|
cityConstructions.cityInfo = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun endTurn() {
|
fun endTurn() {
|
||||||
val stats = cityStats.currentCityStats
|
val stats = cityStats.currentCityStats
|
||||||
if (cityConstructions.currentConstruction == CityConstructions.Settler && stats.food > 0) {
|
if (cityConstructions.currentConstruction == CityConstructions.Settler && stats.food > 0) {
|
||||||
@ -146,8 +166,6 @@ class CityInfo {
|
|||||||
population.unassignExtraPopulation()
|
population.unassignExtraPopulation()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isCapital() = cityConstructions.isBuilt("Palace")
|
|
||||||
|
|
||||||
fun moveToCiv(newCivInfo: CivilizationInfo){
|
fun moveToCiv(newCivInfo: CivilizationInfo){
|
||||||
civInfo.cities.remove(this)
|
civInfo.cities.remove(this)
|
||||||
newCivInfo.cities.add(this)
|
newCivInfo.cities.add(this)
|
||||||
@ -166,24 +184,5 @@ class CityInfo {
|
|||||||
|
|
||||||
civInfo.gameInfo.updateTilesToCities()
|
civInfo.gameInfo.updateTilesToCities()
|
||||||
}
|
}
|
||||||
|
//endregion
|
||||||
internal fun getMaxHealth(): Int {
|
|
||||||
return 200 + cityConstructions.getBuiltBuildings().sumBy { it.cityHealth }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {return name} // for debug
|
|
||||||
|
|
||||||
fun clone(): CityInfo {
|
|
||||||
val toReturn = CityInfo()
|
|
||||||
toReturn.population = population.clone()
|
|
||||||
toReturn.health=health
|
|
||||||
toReturn.name=name
|
|
||||||
toReturn.tiles.addAll(tiles)
|
|
||||||
toReturn.workedTiles.addAll(workedTiles)
|
|
||||||
toReturn.cityConstructions=cityConstructions.clone()
|
|
||||||
toReturn.expansion = expansion.clone()
|
|
||||||
toReturn.isBeingRazed=isBeingRazed
|
|
||||||
toReturn.location=location
|
|
||||||
return toReturn
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -19,6 +19,7 @@ class CityStats {
|
|||||||
@Transient
|
@Transient
|
||||||
lateinit var cityInfo: CityInfo
|
lateinit var cityInfo: CityInfo
|
||||||
|
|
||||||
|
//region pure fuctions
|
||||||
private fun getStatsFromTiles(): Stats {
|
private fun getStatsFromTiles(): Stats {
|
||||||
val stats = Stats()
|
val stats = Stats()
|
||||||
for (cell in cityInfo.getTilesInRange().filter { cityInfo.workedTiles.contains(it.position) || cityInfo.location == it.position })
|
for (cell in cityInfo.getTilesInRange().filter { cityInfo.workedTiles.contains(it.position) || cityInfo.location == it.position })
|
||||||
@ -38,7 +39,6 @@ class CityStats {
|
|||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getStatsFromProduction(production: Float): Stats {
|
private fun getStatsFromProduction(production: Float): Stats {
|
||||||
val stats = Stats()
|
val stats = Stats()
|
||||||
|
|
||||||
@ -54,7 +54,6 @@ class CityStats {
|
|||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getStatPercentBonusesFromRailroad(): Stats {
|
private fun getStatPercentBonusesFromRailroad(): Stats {
|
||||||
val stats = Stats()
|
val stats = Stats()
|
||||||
if (cityInfo.civInfo.tech.isResearched("Combustion")
|
if (cityInfo.civInfo.tech.isResearched("Combustion")
|
||||||
@ -178,7 +177,6 @@ class CityStats {
|
|||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getStatPercentBonusesFromWonders(): Stats {
|
private fun getStatPercentBonusesFromWonders(): Stats {
|
||||||
val stats = Stats()
|
val stats = Stats()
|
||||||
val civUniques = cityInfo.civInfo.getBuildingUniques()
|
val civUniques = cityInfo.civInfo.getBuildingUniques()
|
||||||
@ -208,6 +206,28 @@ class CityStats {
|
|||||||
return stats
|
return stats
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isConnectedToCapital(roadType: RoadStatus): Boolean {
|
||||||
|
if (cityInfo.civInfo.cities.count() < 2) return false// first city!
|
||||||
|
val capitalTile = cityInfo.civInfo.getCapital().getCenterTile()
|
||||||
|
val tilesReached = HashSet<TileInfo>()
|
||||||
|
var tilesToCheck: List<TileInfo> = listOf(cityInfo.getCenterTile())
|
||||||
|
while (tilesToCheck.isNotEmpty()) {
|
||||||
|
val newTiles = tilesToCheck
|
||||||
|
.flatMap { it.neighbors }.distinct()
|
||||||
|
.filter {
|
||||||
|
!tilesReached.contains(it) && !tilesToCheck.contains(it)
|
||||||
|
&& (roadType !== RoadStatus.Road || it.roadStatus !== RoadStatus.None)
|
||||||
|
&& (roadType !== RoadStatus.Railroad || it.roadStatus === roadType)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newTiles.contains(capitalTile)) return true
|
||||||
|
tilesReached.addAll(tilesToCheck)
|
||||||
|
tilesToCheck = newTiles
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
//endregion
|
||||||
|
|
||||||
fun update() {
|
fun update() {
|
||||||
baseStatList = LinkedHashMap<String, Stats>()
|
baseStatList = LinkedHashMap<String, Stats>()
|
||||||
val civInfo = cityInfo.civInfo
|
val civInfo = cityInfo.civInfo
|
||||||
@ -270,25 +290,4 @@ class CityStats {
|
|||||||
if(currentCityStats.production<1) currentCityStats.production=1f
|
if(currentCityStats.production<1) currentCityStats.production=1f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun isConnectedToCapital(roadType: RoadStatus): Boolean {
|
|
||||||
if (cityInfo.civInfo.cities.count() < 2) return false// first city!
|
|
||||||
val capitalTile = cityInfo.civInfo.getCapital().getCenterTile()
|
|
||||||
val tilesReached = HashSet<TileInfo>()
|
|
||||||
var tilesToCheck: List<TileInfo> = listOf(cityInfo.getCenterTile())
|
|
||||||
while (tilesToCheck.isNotEmpty()) {
|
|
||||||
val newTiles = tilesToCheck
|
|
||||||
.flatMap { it.neighbors }.distinct()
|
|
||||||
.filter {
|
|
||||||
!tilesReached.contains(it) && !tilesToCheck.contains(it)
|
|
||||||
&& (roadType !== RoadStatus.Road || it.roadStatus !== RoadStatus.None)
|
|
||||||
&& (roadType !== RoadStatus.Railroad || it.roadStatus === roadType)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newTiles.contains(capitalTile)) return true
|
|
||||||
tilesReached.addAll(tilesToCheck)
|
|
||||||
tilesToCheck = newTiles
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,14 +7,21 @@ import com.unciv.models.stats.Stats
|
|||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class PopulationManager {
|
class PopulationManager {
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
lateinit var cityInfo: CityInfo
|
lateinit var cityInfo: CityInfo
|
||||||
|
|
||||||
var population = 1
|
var population = 1
|
||||||
var foodStored = 0
|
var foodStored = 0
|
||||||
|
|
||||||
var buildingsSpecialists = HashMap<String, Stats>()
|
var buildingsSpecialists = HashMap<String, Stats>()
|
||||||
|
|
||||||
|
//region pure functions
|
||||||
|
fun clone(): PopulationManager {
|
||||||
|
val toReturn = PopulationManager()
|
||||||
|
toReturn.population=population
|
||||||
|
toReturn.foodStored=foodStored
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
fun getSpecialists(): Stats {
|
fun getSpecialists(): Stats {
|
||||||
val allSpecialists = Stats()
|
val allSpecialists = Stats()
|
||||||
for (stats in buildingsSpecialists.values)
|
for (stats in buildingsSpecialists.values)
|
||||||
@ -27,14 +34,11 @@ class PopulationManager {
|
|||||||
return (specialists.science + specialists.production + specialists.culture + specialists.gold).toInt()
|
return (specialists.science + specialists.production + specialists.culture + specialists.gold).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 1 is the city center
|
|
||||||
fun getFreePopulation(): Int {
|
fun getFreePopulation(): Int {
|
||||||
val workingPopulation = cityInfo.workedTiles.size
|
val workingPopulation = cityInfo.workedTiles.size
|
||||||
return population - workingPopulation - getNumberOfSpecialists()
|
return population - workingPopulation - getNumberOfSpecialists()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun getFoodToNextPopulation(): Int {
|
fun getFoodToNextPopulation(): Int {
|
||||||
// civ v math, civilization.wikia
|
// civ v math, civilization.wikia
|
||||||
var foodRequired = 15 + 6 * (population - 1) + Math.floor(Math.pow((population - 1).toDouble(), 1.8))
|
var foodRequired = 15 + 6 * (population - 1) + Math.floor(Math.pow((population - 1).toDouble(), 1.8))
|
||||||
@ -43,6 +47,7 @@ class PopulationManager {
|
|||||||
return foodRequired.toInt()
|
return foodRequired.toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
fun nextTurn(food: Float) {
|
fun nextTurn(food: Float) {
|
||||||
foodStored += food.roundToInt()
|
foodStored += food.roundToInt()
|
||||||
@ -89,11 +94,4 @@ class PopulationManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clone(): PopulationManager {
|
|
||||||
val toReturn = PopulationManager()
|
|
||||||
toReturn.population=population
|
|
||||||
toReturn.foodStored=foodStored
|
|
||||||
return toReturn
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -22,30 +22,51 @@ import kotlin.math.roundToInt
|
|||||||
|
|
||||||
|
|
||||||
class CivilizationInfo {
|
class CivilizationInfo {
|
||||||
|
@Transient lateinit var gameInfo: GameInfo
|
||||||
@Transient
|
|
||||||
lateinit var gameInfo: GameInfo
|
|
||||||
|
|
||||||
var gold = 0
|
var gold = 0
|
||||||
var happiness = 15
|
var happiness = 15
|
||||||
var difficulty = "Chieftain"
|
var difficulty = "Chieftain"
|
||||||
var civName = "Babylon"
|
var civName = "Babylon"
|
||||||
|
|
||||||
var tech = TechManager()
|
var tech = TechManager()
|
||||||
var policies = PolicyManager()
|
var policies = PolicyManager()
|
||||||
var goldenAges = GoldenAgeManager()
|
var goldenAges = GoldenAgeManager()
|
||||||
var greatPeople = GreatPersonManager()
|
var greatPeople = GreatPersonManager()
|
||||||
var scienceVictory = ScienceVictoryManager()
|
var scienceVictory = ScienceVictoryManager()
|
||||||
var diplomacy = HashMap<String,DiplomacyManager>()
|
var diplomacy = HashMap<String,DiplomacyManager>()
|
||||||
|
|
||||||
var cities = ArrayList<CityInfo>()
|
var cities = ArrayList<CityInfo>()
|
||||||
var exploredTiles = HashSet<Vector2>()
|
var exploredTiles = HashSet<Vector2>()
|
||||||
|
|
||||||
|
constructor()
|
||||||
|
|
||||||
|
constructor(civName: String, startingLocation: Vector2, gameInfo: GameInfo) {
|
||||||
|
this.civName = civName
|
||||||
|
this.gameInfo = gameInfo
|
||||||
|
tech.techsResearched.add("Agriculture")
|
||||||
|
this.placeUnitNearTile(startingLocation, "Settler")
|
||||||
|
this.placeUnitNearTile(startingLocation, "Scout")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clone(): CivilizationInfo {
|
||||||
|
val toReturn = CivilizationInfo()
|
||||||
|
toReturn.exploredTiles=exploredTiles.toHashSet()
|
||||||
|
toReturn.diplomacy.putAll(diplomacy.values.map { it.clone() }.associateBy { it.otherCivName })
|
||||||
|
toReturn.cities.addAll(cities.map { it.clone() })
|
||||||
|
toReturn.tech = tech.clone()
|
||||||
|
toReturn.difficulty=difficulty
|
||||||
|
toReturn.policies = policies.clone()
|
||||||
|
toReturn.happiness=happiness
|
||||||
|
toReturn.greatPeople=greatPeople.clone()
|
||||||
|
toReturn.gold = gold
|
||||||
|
toReturn.goldenAges = goldenAges.clone()
|
||||||
|
toReturn.civName=civName
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
|
//region pure functions
|
||||||
fun getDifficulty() = GameBasics.Difficulties[difficulty]!!
|
fun getDifficulty() = GameBasics.Difficulties[difficulty]!!
|
||||||
fun getNation() = GameBasics.Nations[civName]!!
|
fun getNation() = GameBasics.Nations[civName]!!
|
||||||
|
|
||||||
fun getCapital()=cities.first { it.isCapital() }
|
fun getCapital()=cities.first { it.isCapital() }
|
||||||
|
|
||||||
fun isPlayerCivilization() = gameInfo.getPlayerCivilization()==this
|
fun isPlayerCivilization() = gameInfo.getPlayerCivilization()==this
|
||||||
fun isBarbarianCivilization() = gameInfo.getBarbarianCivilization()==this
|
fun isBarbarianCivilization() = gameInfo.getBarbarianCivilization()==this
|
||||||
|
|
||||||
@ -118,7 +139,6 @@ class CivilizationInfo {
|
|||||||
return transportationUpkeep
|
return transportationUpkeep
|
||||||
}
|
}
|
||||||
|
|
||||||
// base happiness
|
|
||||||
fun getHappinessForNextTurn(): HashMap<String, Float> {
|
fun getHappinessForNextTurn(): HashMap<String, Float> {
|
||||||
val statMap = HashMap<String,Float>()
|
val statMap = HashMap<String,Float>()
|
||||||
statMap["Base happiness"] = getDifficulty().baseHappiness.toFloat()
|
statMap["Base happiness"] = getDifficulty().baseHappiness.toFloat()
|
||||||
@ -153,17 +173,56 @@ class CivilizationInfo {
|
|||||||
|
|
||||||
fun getBuildingUniques(): List<String> = cities.flatMap { it.cityConstructions.getBuiltBuildings().map { it.unique }.filterNotNull() }.distinct()
|
fun getBuildingUniques(): List<String> = cities.flatMap { it.cityConstructions.getBuiltBuildings().map { it.unique }.filterNotNull() }.distinct()
|
||||||
|
|
||||||
|
fun getCivUnits(): List<MapUnit> {
|
||||||
constructor()
|
return gameInfo.tileMap.values.flatMap { it.getUnits() }.filter { it.owner==civName }
|
||||||
|
|
||||||
constructor(civName: String, startingLocation: Vector2, gameInfo: GameInfo) {
|
|
||||||
this.civName = civName
|
|
||||||
this.gameInfo = gameInfo
|
|
||||||
tech.techsResearched.add("Agriculture")
|
|
||||||
this.placeUnitNearTile(startingLocation, "Settler")
|
|
||||||
this.placeUnitNearTile(startingLocation, "Scout")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getViewableTiles(): List<TileInfo> {
|
||||||
|
var viewablePositions = emptyList<TileInfo>()
|
||||||
|
viewablePositions += cities.flatMap { it.getTiles() }
|
||||||
|
.flatMap { it.neighbors } // tiles adjacent to city tiles
|
||||||
|
viewablePositions += getCivUnits()
|
||||||
|
.flatMap { it.getViewableTiles()} // Tiles within 2 tiles of units
|
||||||
|
viewablePositions.map { it.position }.filterNot { exploredTiles.contains(it) }.toCollection(exploredTiles)
|
||||||
|
|
||||||
|
val viewedCivs = viewablePositions
|
||||||
|
.flatMap { it.getUnits().map { u->u.civInfo }.union(listOf(it.getOwner())) }
|
||||||
|
.filterNotNull().filterNot { it==this || it.isBarbarianCivilization() }
|
||||||
|
|
||||||
|
for(otherCiv in viewedCivs)
|
||||||
|
if(!diplomacy.containsKey(otherCiv.civName)){
|
||||||
|
diplomacy[otherCiv.civName] = DiplomacyManager(this@CivilizationInfo,otherCiv.civName)
|
||||||
|
.apply { diplomaticStatus = DiplomaticStatus.Peace }
|
||||||
|
otherCiv.diplomacy[civName] = DiplomacyManager(otherCiv,civName)
|
||||||
|
.apply { diplomaticStatus = DiplomaticStatus.Peace }
|
||||||
|
addNotification("We have encountered [${otherCiv.civName}]!".tr(),null, Color.GOLD)
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewablePositions.distinct()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toString(): String {return civName} // for debug
|
||||||
|
|
||||||
|
fun isDefeated()= cities.isEmpty() && !getCivUnits().any{it.name=="Settler"}
|
||||||
|
fun getEra(): TechEra {
|
||||||
|
val maxEraOfTech = tech.techsResearched.map { GameBasics.Technologies[it]!! }
|
||||||
|
.map { it.era() }
|
||||||
|
.max()
|
||||||
|
if(maxEraOfTech!=null) return maxEraOfTech
|
||||||
|
else return TechEra.Ancient
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isAtWarWith(otherCiv:CivilizationInfo): Boolean {
|
||||||
|
if(otherCiv.isBarbarianCivilization() || isBarbarianCivilization()) return true
|
||||||
|
if(!diplomacy.containsKey(otherCiv.civName)) // not encountered yet
|
||||||
|
return false
|
||||||
|
return diplomacy[otherCiv.civName]!!.diplomaticStatus == DiplomaticStatus.War
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isAtWar() = diplomacy.values.any { it.diplomaticStatus==DiplomaticStatus.War && !it.otherCiv().isDefeated() }
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region state-changing functions
|
||||||
fun setTransients() {
|
fun setTransients() {
|
||||||
goldenAges.civInfo = this
|
goldenAges.civInfo = this
|
||||||
policies.civInfo = this
|
policies.civInfo = this
|
||||||
@ -185,11 +244,6 @@ class CivilizationInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addCity(location: Vector2) {
|
|
||||||
val newCity = CityInfo(this, location)
|
|
||||||
newCity.cityConstructions.chooseNextConstruction()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun endTurn() {
|
fun endTurn() {
|
||||||
val nextTurnStats = getStatsForNextTurn()
|
val nextTurnStats = getStatsForNextTurn()
|
||||||
|
|
||||||
@ -236,6 +290,17 @@ class CivilizationInfo {
|
|||||||
getCivUnits().forEach { it.startTurn() }
|
getCivUnits().forEach { it.startTurn() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun canEnterTiles(otherCiv: CivilizationInfo): Boolean {
|
||||||
|
if(otherCiv==this) return true
|
||||||
|
if(isAtWarWith(otherCiv)) return true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addNotification(text: String, location: Vector2?,color: Color) {
|
||||||
|
if(isPlayerCivilization())
|
||||||
|
gameInfo.notifications.add(Notification(text, location,color))
|
||||||
|
}
|
||||||
|
|
||||||
fun addGreatPerson(greatPerson: String) {
|
fun addGreatPerson(greatPerson: String) {
|
||||||
val randomCity = cities.getRandom()
|
val randomCity = cities.getRandom()
|
||||||
placeUnitNearTile(cities.getRandom().location, greatPerson)
|
placeUnitNearTile(cities.getRandom().location, greatPerson)
|
||||||
@ -246,78 +311,10 @@ class CivilizationInfo {
|
|||||||
return gameInfo.tileMap.placeUnitNearTile(location, unitName, this)
|
return gameInfo.tileMap.placeUnitNearTile(location, unitName, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCivUnits(): List<MapUnit> {
|
fun addCity(location: Vector2) {
|
||||||
return gameInfo.tileMap.values.flatMap { it.getUnits() }.filter { it.owner==civName }
|
val newCity = CityInfo(this, location)
|
||||||
|
newCity.cityConstructions.chooseNextConstruction()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getViewableTiles(): List<TileInfo> {
|
//endregion
|
||||||
var viewablePositions = emptyList<TileInfo>()
|
|
||||||
viewablePositions += cities.flatMap { it.getTiles() }
|
|
||||||
.flatMap { it.neighbors } // tiles adjacent to city tiles
|
|
||||||
viewablePositions += getCivUnits()
|
|
||||||
.flatMap { it.getViewableTiles()} // Tiles within 2 tiles of units
|
|
||||||
viewablePositions.map { it.position }.filterNot { exploredTiles.contains(it) }.toCollection(exploredTiles)
|
|
||||||
|
|
||||||
val viewedCivs = viewablePositions
|
|
||||||
.flatMap { it.getUnits().map { u->u.civInfo }.union(listOf(it.getOwner())) }
|
|
||||||
.filterNotNull().filterNot { it==this || it.isBarbarianCivilization() }
|
|
||||||
|
|
||||||
for(otherCiv in viewedCivs)
|
|
||||||
if(!diplomacy.containsKey(otherCiv.civName)){
|
|
||||||
diplomacy[otherCiv.civName] = DiplomacyManager(this@CivilizationInfo,otherCiv.civName)
|
|
||||||
.apply { diplomaticStatus = DiplomaticStatus.Peace }
|
|
||||||
otherCiv.diplomacy[civName] = DiplomacyManager(otherCiv,civName)
|
|
||||||
.apply { diplomaticStatus = DiplomaticStatus.Peace }
|
|
||||||
addNotification("We have encountered [${otherCiv.civName}]!".tr(),null, Color.GOLD)
|
|
||||||
}
|
|
||||||
|
|
||||||
return viewablePositions.distinct()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addNotification(text: String, location: Vector2?,color: Color) {
|
|
||||||
if(isPlayerCivilization())
|
|
||||||
gameInfo.notifications.add(Notification(text, location,color))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String {return civName} // for debug
|
|
||||||
|
|
||||||
fun isDefeated()= cities.isEmpty() && !getCivUnits().any{it.name=="Settler"}
|
|
||||||
fun getEra(): TechEra {
|
|
||||||
val maxEraOfTech = tech.techsResearched.map { GameBasics.Technologies[it]!! }
|
|
||||||
.map { it.era() }
|
|
||||||
.max()
|
|
||||||
if(maxEraOfTech!=null) return maxEraOfTech
|
|
||||||
else return TechEra.Ancient
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isAtWarWith(otherCiv:CivilizationInfo): Boolean {
|
|
||||||
if(otherCiv.isBarbarianCivilization() || isBarbarianCivilization()) return true
|
|
||||||
if(!diplomacy.containsKey(otherCiv.civName)) // not encountered yet
|
|
||||||
return false
|
|
||||||
return diplomacy[otherCiv.civName]!!.diplomaticStatus == DiplomaticStatus.War
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isAtWar() = diplomacy.values.any { it.diplomaticStatus==DiplomaticStatus.War && !it.otherCiv().isDefeated() }
|
|
||||||
|
|
||||||
fun canEnterTiles(otherCiv: CivilizationInfo): Boolean {
|
|
||||||
if(otherCiv==this) return true
|
|
||||||
if(isAtWarWith(otherCiv)) return true
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
fun clone(): CivilizationInfo {
|
|
||||||
val toReturn = CivilizationInfo()
|
|
||||||
toReturn.exploredTiles=exploredTiles.toHashSet()
|
|
||||||
toReturn.diplomacy.putAll(diplomacy.values.map { it.clone() }.associateBy { it.otherCivName })
|
|
||||||
toReturn.cities.addAll(cities.map { it.clone() })
|
|
||||||
toReturn.tech = tech.clone()
|
|
||||||
toReturn.difficulty=difficulty
|
|
||||||
toReturn.policies = policies.clone()
|
|
||||||
toReturn.happiness=happiness
|
|
||||||
toReturn.greatPeople=greatPeople.clone()
|
|
||||||
toReturn.gold = gold
|
|
||||||
toReturn.goldenAges = goldenAges.clone()
|
|
||||||
toReturn.civName=civName
|
|
||||||
return toReturn
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -16,13 +16,33 @@ enum class DiplomaticStatus{
|
|||||||
class DiplomacyManager() {
|
class DiplomacyManager() {
|
||||||
@Transient lateinit var civInfo: CivilizationInfo
|
@Transient lateinit var civInfo: CivilizationInfo
|
||||||
lateinit var otherCivName:String
|
lateinit var otherCivName:String
|
||||||
|
var trades = ArrayList<Trade>()
|
||||||
|
var diplomaticStatus = DiplomaticStatus.War
|
||||||
|
|
||||||
|
fun clone(): DiplomacyManager {
|
||||||
|
val toReturn = DiplomacyManager()
|
||||||
|
toReturn.otherCivName=otherCivName
|
||||||
|
toReturn.diplomaticStatus=diplomaticStatus
|
||||||
|
toReturn.trades.addAll(trades.map { it.clone() })
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
constructor(civilizationInfo: CivilizationInfo, OtherCivName:String) : this() {
|
constructor(civilizationInfo: CivilizationInfo, OtherCivName:String) : this() {
|
||||||
civInfo=civilizationInfo
|
civInfo=civilizationInfo
|
||||||
otherCivName=OtherCivName
|
otherCivName=OtherCivName
|
||||||
}
|
}
|
||||||
|
|
||||||
var trades = ArrayList<Trade>()
|
//region pure functions
|
||||||
|
fun turnsToPeaceTreaty(): Int {
|
||||||
|
for(trade in trades)
|
||||||
|
for(offer in trade.ourOffers)
|
||||||
|
if(offer.name=="Peace Treaty") return offer.duration
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fun canDeclareWar() = turnsToPeaceTreaty()==0
|
||||||
|
|
||||||
|
fun otherCiv() = civInfo.gameInfo.civilizations.first{it.civName==otherCivName}
|
||||||
|
|
||||||
fun goldPerTurn():Int{
|
fun goldPerTurn():Int{
|
||||||
var goldPerTurnForUs = 0
|
var goldPerTurnForUs = 0
|
||||||
@ -47,7 +67,9 @@ class DiplomacyManager() {
|
|||||||
}
|
}
|
||||||
return counter
|
return counter
|
||||||
}
|
}
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region state-changing functions
|
||||||
fun removeUntenebleTrades(){
|
fun removeUntenebleTrades(){
|
||||||
val negativeCivResources = civInfo.getCivResources().filter { it.value<0 }.map { it.key.name }
|
val negativeCivResources = civInfo.getCivResources().filter { it.value<0 }.map { it.key.name }
|
||||||
for(trade in trades.toList()) {
|
for(trade in trades.toList()) {
|
||||||
@ -77,28 +99,10 @@ class DiplomacyManager() {
|
|||||||
removeUntenebleTrades()
|
removeUntenebleTrades()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun otherCiv() = civInfo.gameInfo.civilizations.first{it.civName==otherCivName}
|
|
||||||
|
|
||||||
var diplomaticStatus = DiplomaticStatus.War
|
|
||||||
fun declareWar(){
|
fun declareWar(){
|
||||||
diplomaticStatus = DiplomaticStatus.War
|
diplomaticStatus = DiplomaticStatus.War
|
||||||
otherCiv().diplomacy[civInfo.civName]!!.diplomaticStatus = DiplomaticStatus.War
|
otherCiv().diplomacy[civInfo.civName]!!.diplomaticStatus = DiplomaticStatus.War
|
||||||
otherCiv().addNotification("[civName] has declared war on us!",null, Color.RED)
|
otherCiv().addNotification("[civName] has declared war on us!",null, Color.RED)
|
||||||
}
|
}
|
||||||
|
//endregion
|
||||||
fun turnsToPeaceTreaty(): Int {
|
|
||||||
for(trade in trades)
|
|
||||||
for(offer in trade.ourOffers)
|
|
||||||
if(offer.name=="Peace Treaty") return offer.duration
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
fun canDeclareWar() = turnsToPeaceTreaty()==0
|
|
||||||
fun clone(): DiplomacyManager {
|
|
||||||
val toReturn = DiplomacyManager()
|
|
||||||
toReturn.otherCivName=otherCivName
|
|
||||||
toReturn.diplomaticStatus=diplomaticStatus
|
|
||||||
toReturn.trades.addAll(trades.map { it.clone() })
|
|
||||||
return toReturn
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -10,6 +10,14 @@ class GoldenAgeManager{
|
|||||||
private var numberOfGoldenAges = 0
|
private var numberOfGoldenAges = 0
|
||||||
var turnsLeftForCurrentGoldenAge = 0
|
var turnsLeftForCurrentGoldenAge = 0
|
||||||
|
|
||||||
|
fun clone(): GoldenAgeManager {
|
||||||
|
val toReturn = GoldenAgeManager()
|
||||||
|
toReturn.numberOfGoldenAges=numberOfGoldenAges
|
||||||
|
toReturn.storedHappiness=storedHappiness
|
||||||
|
toReturn.turnsLeftForCurrentGoldenAge=turnsLeftForCurrentGoldenAge
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
fun isGoldenAge(): Boolean = turnsLeftForCurrentGoldenAge > 0
|
fun isGoldenAge(): Boolean = turnsLeftForCurrentGoldenAge > 0
|
||||||
|
|
||||||
fun happinessRequiredForNextGoldenAge(): Int {
|
fun happinessRequiredForNextGoldenAge(): Int {
|
||||||
@ -36,11 +44,4 @@ class GoldenAgeManager{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clone(): GoldenAgeManager {
|
|
||||||
val toReturn = GoldenAgeManager()
|
|
||||||
toReturn.numberOfGoldenAges=numberOfGoldenAges
|
|
||||||
toReturn.storedHappiness=storedHappiness
|
|
||||||
toReturn.turnsLeftForCurrentGoldenAge=turnsLeftForCurrentGoldenAge
|
|
||||||
return toReturn
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,14 @@ class GreatPersonManager {
|
|||||||
private var greatPersonPoints = Stats()
|
private var greatPersonPoints = Stats()
|
||||||
var freeGreatPeople=0
|
var freeGreatPeople=0
|
||||||
|
|
||||||
|
fun clone(): GreatPersonManager {
|
||||||
|
val toReturn = GreatPersonManager()
|
||||||
|
toReturn.freeGreatPeople=freeGreatPeople
|
||||||
|
toReturn.greatPersonPoints=greatPersonPoints.clone()
|
||||||
|
toReturn.pointsForNextGreatPerson=pointsForNextGreatPerson
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
fun getNewGreatPerson(): String? {
|
fun getNewGreatPerson(): String? {
|
||||||
var greatPerson: String? = null
|
var greatPerson: String? = null
|
||||||
when {
|
when {
|
||||||
@ -27,12 +35,5 @@ class GreatPersonManager {
|
|||||||
greatPersonPoints.add(greatPersonPoints)
|
greatPersonPoints.add(greatPersonPoints)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clone(): GreatPersonManager {
|
|
||||||
val toReturn = GreatPersonManager()
|
|
||||||
toReturn.freeGreatPeople=freeGreatPeople
|
|
||||||
toReturn.greatPersonPoints=greatPersonPoints.clone()
|
|
||||||
toReturn.pointsForNextGreatPerson=pointsForNextGreatPerson
|
|
||||||
return toReturn
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -28,14 +28,15 @@ class PolicyManager {
|
|||||||
return cost - (cost % 5)
|
return cost - (cost % 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun getAdoptedPolicies(): HashSet<String> = adoptedPolicies
|
fun getAdoptedPolicies(): HashSet<String> = adoptedPolicies
|
||||||
|
|
||||||
fun isAdopted(policyName: String): Boolean = adoptedPolicies.contains(policyName)
|
fun isAdopted(policyName: String): Boolean = adoptedPolicies.contains(policyName)
|
||||||
|
|
||||||
fun isAdoptable(policy: Policy) = !policy.name.endsWith("Complete")
|
fun isAdoptable(policy: Policy): Boolean {
|
||||||
&& getAdoptedPolicies().containsAll(policy.requires!!)
|
return (!policy.name.endsWith("Complete")
|
||||||
&& policy.getBranch().era <= civInfo.getEra()
|
&& getAdoptedPolicies().containsAll(policy.requires!!)
|
||||||
|
&& policy.getBranch().era <= civInfo.getEra())
|
||||||
|
}
|
||||||
|
|
||||||
fun canAdoptPolicy(): Boolean = freePolicies > 0 || storedCulture >= getCultureNeededForNextPolicy()
|
fun canAdoptPolicy(): Boolean = freePolicies > 0 || storedCulture >= getCultureNeededForNextPolicy()
|
||||||
|
|
||||||
|
@ -3,10 +3,16 @@ package com.unciv.logic.civilization
|
|||||||
import com.unciv.models.Counter
|
import com.unciv.models.Counter
|
||||||
|
|
||||||
class ScienceVictoryManager {
|
class ScienceVictoryManager {
|
||||||
|
|
||||||
var requiredParts = Counter<String>()
|
var requiredParts = Counter<String>()
|
||||||
var currentParts = Counter<String>()
|
var currentParts = Counter<String>()
|
||||||
|
|
||||||
|
init {
|
||||||
|
requiredParts.add("SS Booster", 3)
|
||||||
|
requiredParts.add("SS Cockpit", 1)
|
||||||
|
requiredParts.add("SS Engine", 1)
|
||||||
|
requiredParts.add("SS Statis Chamber", 1)
|
||||||
|
}
|
||||||
|
|
||||||
fun unconstructedParts(): Counter<String> {
|
fun unconstructedParts(): Counter<String> {
|
||||||
val counter = requiredParts.clone()
|
val counter = requiredParts.clone()
|
||||||
counter.remove(currentParts)
|
counter.remove(currentParts)
|
||||||
@ -14,11 +20,4 @@ class ScienceVictoryManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun hasWon() = requiredParts.equals(currentParts)
|
fun hasWon() = requiredParts.equals(currentParts)
|
||||||
|
|
||||||
init {
|
|
||||||
requiredParts.add("SS Booster", 3)
|
|
||||||
requiredParts.add("SS Cockpit", 1)
|
|
||||||
requiredParts.add("SS Engine", 1)
|
|
||||||
requiredParts.add("SS Statis Chamber", 1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,16 @@ class TechManager {
|
|||||||
var techsToResearch = ArrayList<String>()
|
var techsToResearch = ArrayList<String>()
|
||||||
private var techsInProgress = HashMap<String, Int>()
|
private var techsInProgress = HashMap<String, Int>()
|
||||||
|
|
||||||
|
//region state-changing functions
|
||||||
|
fun clone(): TechManager {
|
||||||
|
val toReturn = TechManager()
|
||||||
|
toReturn.techsResearched.addAll(techsResearched)
|
||||||
|
toReturn.freeTechs=freeTechs
|
||||||
|
toReturn.techsInProgress.putAll(techsInProgress)
|
||||||
|
toReturn.techsToResearch.addAll(techsToResearch)
|
||||||
|
return toReturn
|
||||||
|
}
|
||||||
|
|
||||||
private fun getCurrentTechnology(): Technology = GameBasics.Technologies[currentTechnology()]!!
|
private fun getCurrentTechnology(): Technology = GameBasics.Technologies[currentTechnology()]!!
|
||||||
|
|
||||||
fun costOfTech(techName: String): Int {
|
fun costOfTech(techName: String): Int {
|
||||||
@ -45,6 +55,7 @@ class TechManager {
|
|||||||
fun canBeResearched(TechName: String): Boolean {
|
fun canBeResearched(TechName: String): Boolean {
|
||||||
return GameBasics.Technologies[TechName]!!.prerequisites.all { isResearched(it) }
|
return GameBasics.Technologies[TechName]!!.prerequisites.all { isResearched(it) }
|
||||||
}
|
}
|
||||||
|
//endregion
|
||||||
|
|
||||||
fun nextTurn(scienceForNewTurn: Int) {
|
fun nextTurn(scienceForNewTurn: Int) {
|
||||||
val currentTechnology = currentTechnology()
|
val currentTechnology = currentTechnology()
|
||||||
@ -92,15 +103,6 @@ class TechManager {
|
|||||||
city.cityConstructions.currentConstruction = currentConstructionUnit.upgradesTo!!
|
city.cityConstructions.currentConstruction = currentConstructionUnit.upgradesTo!!
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun clone(): TechManager {
|
|
||||||
val toReturn = TechManager()
|
|
||||||
toReturn.techsResearched.addAll(techsResearched)
|
|
||||||
toReturn.freeTechs=freeTechs
|
|
||||||
toReturn.techsInProgress.putAll(techsInProgress)
|
|
||||||
toReturn.techsToResearch.addAll(techsToResearch)
|
|
||||||
return toReturn
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user