mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-04 15:27:50 +07:00
AI construction choices now better and change between peacetime and wartime.
AIs now declare war on each other if they think they can defeat the other side (Returned movement alg. to the way it was because the new way didn't allow ais to find enemy units, added comment)
This commit is contained in:
BIN
android/assets/FlagIcons/Spanish.png
Normal file
BIN
android/assets/FlagIcons/Spanish.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.8 KiB |
@ -21,8 +21,8 @@ android {
|
||||
applicationId "com.unciv.game"
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 26
|
||||
versionCode 112
|
||||
versionName "2.7.1"
|
||||
versionCode 114
|
||||
versionName "2.7.3"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
|
@ -6,7 +6,6 @@ import com.badlogic.gdx.utils.Json
|
||||
import com.unciv.logic.GameInfo
|
||||
import com.unciv.logic.GameSaver
|
||||
import com.unciv.models.gamebasics.GameBasics
|
||||
import com.unciv.ui.LanguagePickerScreen
|
||||
import com.unciv.ui.worldscreen.WorldScreen
|
||||
|
||||
class UnCivGame : Game() {
|
||||
@ -18,7 +17,7 @@ class UnCivGame : Game() {
|
||||
* This exists so that when debugging we can see the entire map.
|
||||
* Remember to turn this to false before commit and upload!
|
||||
*/
|
||||
val viewEntireMapForDebug = false
|
||||
val viewEntireMapForDebug = true
|
||||
|
||||
|
||||
lateinit var worldScreen: WorldScreen
|
||||
@ -34,7 +33,7 @@ class UnCivGame : Game() {
|
||||
startNewGame()
|
||||
}
|
||||
}
|
||||
else screen=LanguagePickerScreen() //startNewGame()
|
||||
else startNewGame() // screen=LanguagePickerScreen() disabled because of people's negative reviews =(
|
||||
}
|
||||
|
||||
fun loadGame(gameInfo:GameInfo){
|
||||
|
@ -5,7 +5,6 @@ import com.unciv.logic.battle.CityCombatant
|
||||
import com.unciv.logic.city.CityConstructions
|
||||
import com.unciv.logic.city.CityInfo
|
||||
import com.unciv.logic.civilization.CivilizationInfo
|
||||
import com.unciv.logic.civilization.DiplomaticStatus
|
||||
import com.unciv.logic.map.MapUnit
|
||||
import com.unciv.logic.map.TileInfo
|
||||
import com.unciv.logic.trade.TradeLogic
|
||||
@ -77,7 +76,7 @@ class Automation {
|
||||
|
||||
// Declare war?
|
||||
if(civInfo.cities.isNotEmpty() && civInfo.diplomacy.isNotEmpty()
|
||||
&& civInfo.diplomacy.values.none { it.diplomaticStatus==DiplomaticStatus.War }) {
|
||||
&& !civInfo.isAtWar()) {
|
||||
|
||||
val enemyCivsByDistanceToOurs = civInfo.diplomacy.values.map { it.otherCiv() }
|
||||
.filterNot { it == civInfo || it.cities.isEmpty() || !civInfo.diplomacy[it.civName]!!.canDeclareWar() }
|
||||
@ -94,6 +93,7 @@ class Automation {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val rangedUnits = mutableListOf<MapUnit>()
|
||||
val meleeUnits = mutableListOf<MapUnit>()
|
||||
val civilianUnits = mutableListOf<MapUnit>()
|
||||
@ -142,11 +142,11 @@ class Automation {
|
||||
private fun trainCombatUnit(city: CityInfo) {
|
||||
val combatUnits = city.cityConstructions.getConstructableUnits().filter { it.unitType != UnitType.Civilian }
|
||||
val chosenUnit: BaseUnit
|
||||
if(city.civInfo.cities.any { it.getCenterTile().militaryUnit==null}
|
||||
if(!city.civInfo.isAtWar() && city.civInfo.cities.any { it.getCenterTile().militaryUnit==null}
|
||||
&& combatUnits.any { it.unitType== UnitType.Ranged }) // this is for city defence so get an archery unit if we can
|
||||
chosenUnit = combatUnits.filter { it.unitType== UnitType.Ranged }.maxBy { it.cost }!!
|
||||
|
||||
else{ // randomize type of unit and takee the most expensive of its kind
|
||||
else{ // randomize type of unit and take the most expensive of its kind
|
||||
val chosenUnitType = combatUnits.map { it.unitType }.distinct().filterNot{it==UnitType.Scout}.getRandom()
|
||||
chosenUnit = combatUnits.filter { it.unitType==chosenUnitType }.maxBy { it.cost }!!
|
||||
}
|
||||
@ -157,7 +157,7 @@ class Automation {
|
||||
|
||||
fun chooseNextConstruction(cityConstructions: CityConstructions) {
|
||||
cityConstructions.run {
|
||||
currentConstruction="" // This is so that if we're currently in the middle of building a wonder,
|
||||
//currentConstruction="" // This is so that if we're currently in the middle of building a wonder,
|
||||
// buildableWonders will still contain it
|
||||
|
||||
val buildableNotWonders = getBuildableBuildings().filterNot { it.isWonder }
|
||||
@ -169,13 +169,16 @@ class Automation {
|
||||
val cities = cityInfo.civInfo.cities.size
|
||||
|
||||
val goldBuildings = buildableNotWonders.filter { it.gold>0 }
|
||||
val zeroMaintainanceBuildings = buildableNotWonders.filter { it.maintenance == 0 }
|
||||
val wartimeBuildings = buildableNotWonders.filter { it.xpForNewUnits>0 || it.cityStrength>0 }.sortedBy { it.maintenance }
|
||||
val zeroMaintainanceBuildings = buildableNotWonders.filter { it.maintenance == 0 && it !in wartimeBuildings }
|
||||
val isAtWar = cityInfo.civInfo.isAtWar()
|
||||
|
||||
when {
|
||||
buildableNotWonders.isNotEmpty() // if the civ is in the gold red-zone, build markets or somesuch
|
||||
&& cityInfo.civInfo.getStatsForNextTurn().gold <0
|
||||
&& goldBuildings.isNotEmpty()
|
||||
-> currentConstruction = goldBuildings.first().name
|
||||
currentConstruction!="" -> return
|
||||
buildableNotWonders.any { it.name=="Monument"} -> currentConstruction = "Monument"
|
||||
buildableNotWonders.any { it.name=="Granary"} -> currentConstruction = "Granary"
|
||||
buildableNotWonders.any { it.name=="Library"} -> currentConstruction = "Library"
|
||||
@ -183,10 +186,12 @@ class Automation {
|
||||
militaryUnits==0 -> trainCombatUnit(cityInfo)
|
||||
workers==0 -> currentConstruction = CityConstructions.Worker
|
||||
zeroMaintainanceBuildings.isNotEmpty() -> currentConstruction = zeroMaintainanceBuildings.getRandom().name
|
||||
buildableWonders.isNotEmpty() -> currentConstruction = buildableWonders.getRandom().name
|
||||
buildableNotWonders.isNotEmpty() -> currentConstruction = buildableNotWonders.minBy { it.maintenance }!!.name
|
||||
militaryUnits<cities -> trainCombatUnit(cityInfo)
|
||||
isAtWar && militaryUnits<cities -> trainCombatUnit(cityInfo)
|
||||
isAtWar && wartimeBuildings.isNotEmpty() -> currentConstruction = wartimeBuildings.getRandom().name
|
||||
workers<cities/2 -> currentConstruction = CityConstructions.Worker
|
||||
militaryUnits<cities -> trainCombatUnit(cityInfo)
|
||||
buildableNotWonders.isNotEmpty() -> currentConstruction = buildableNotWonders.minBy { it.maintenance }!!.name
|
||||
buildableWonders.isNotEmpty() -> currentConstruction = buildableWonders.getRandom().name
|
||||
else -> trainCombatUnit(cityInfo)
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,7 @@ class CityConstructions {
|
||||
currentConstruction = "lie"
|
||||
if (!construction.isBuildable(this)) {
|
||||
// We can't build this building anymore! (Wonder has been built / resource is gone / etc.)
|
||||
currentConstruction=""
|
||||
cityInfo.civInfo.addNotification("Cannot continue work on [$saveCurrentConstruction]", cityInfo.location, Color.BROWN)
|
||||
Automation().chooseNextConstruction(this)
|
||||
construction = getConstruction(currentConstruction)
|
||||
@ -119,6 +120,7 @@ class CityConstructions {
|
||||
else
|
||||
cityInfo.civInfo.addNotification("{$currentConstruction} {has been built in} " + cityInfo.name, cityInfo.location, Color.BROWN)
|
||||
|
||||
currentConstruction=""
|
||||
Automation().chooseNextConstruction(this)
|
||||
}
|
||||
|
||||
|
@ -298,6 +298,8 @@ class CivilizationInfo {
|
||||
return diplomacy[otherCiv.civName]!!.diplomaticStatus == DiplomaticStatus.War
|
||||
}
|
||||
|
||||
fun isAtWar() = diplomacy.values.any { it.diplomaticStatus==DiplomaticStatus.War }
|
||||
|
||||
fun canEnterTiles(otherCiv: CivilizationInfo): Boolean {
|
||||
if(otherCiv==this) return true
|
||||
if(isAtWarWith(otherCiv)) return true
|
||||
|
@ -42,7 +42,10 @@ class UnitMovementAlgorithms(val unit:MapUnit) {
|
||||
|| (neighbor.getUnits().isNotEmpty() && neighbor.getUnits().first().civInfo!=unit.civInfo) // Enemy unit
|
||||
|| (isOwnedByEnemy && !unit.civInfo.canEnterTiles(neighborOwner!!))
|
||||
)
|
||||
continue // Can't go here!
|
||||
totalDistanceToTile = unitMovement // Can't go here.
|
||||
// The reason that we don't just "return" is so that when calculating how to reach an enemy,
|
||||
// You need to assume his tile is reachable, otherwise all movement algs on reaching enemy
|
||||
// cities and units goes kaput.
|
||||
|
||||
else {
|
||||
val distanceBetweenTiles = getMovementCostBetweenAdjacentTiles(tileToCheck, neighbor)
|
||||
|
@ -53,6 +53,7 @@ class LanguagePickerScreen: PickerScreen(){
|
||||
topTable.add(Label(
|
||||
"Please note that translations are a " +
|
||||
"community-based work in progress and are INCOMPLETE! \n" +
|
||||
"The percentage shown is how much of the language is translated in-game.\n" +
|
||||
"If you want to help translating the game " +
|
||||
"into your language, contact me!",skin)).pad(10f).row()
|
||||
|
||||
|
@ -45,7 +45,7 @@ class NewGameScreen: PickerScreen(){
|
||||
|
||||
|
||||
table.add("{Difficulty}:".tr())
|
||||
val difficultySelectBox = TranslatedSelectBox(GameBasics.Difficulties.keys, "Chieftain", skin)
|
||||
val difficultySelectBox = TranslatedSelectBox(GameBasics.Difficulties.keys, "Prince", skin)
|
||||
table.add(difficultySelectBox).pad(10f).row()
|
||||
|
||||
|
||||
|
@ -103,7 +103,8 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap:
|
||||
tileGroups[unit.getTile()]!!.addWhiteHaloAroundUnit(unit)
|
||||
|
||||
for(tile: TileInfo in unit.getDistanceToTiles().keys)
|
||||
tileGroups[tile]!!.showCircle(colorFromRGB(0, 120, 215))
|
||||
if(unit.canMoveTo(tile))
|
||||
tileGroups[tile]!!.showCircle(colorFromRGB(0, 120, 215))
|
||||
|
||||
val unitType = unit.getBaseUnit().unitType
|
||||
val attackableTiles: List<TileInfo> = when{
|
||||
|
Reference in New Issue
Block a user