Can now choose Era when starting a new game!

This commit is contained in:
Yair Morgenstern 2019-10-11 16:05:27 +03:00
parent e77fdd2993
commit 27dfae18de
5 changed files with 67 additions and 23 deletions

View file

@ -21,8 +21,8 @@ android {
applicationId "com.unciv.app" applicationId "com.unciv.app"
minSdkVersion 14 minSdkVersion 14
targetSdkVersion 29 targetSdkVersion 29
versionCode 307 versionCode 308
versionName "3.1.4-patch1" versionName "3.1.5"
} }
// Had to add this crap for Travis to build, it wanted to sign the app // Had to add this crap for Travis to build, it wanted to sign the app

View file

@ -10,8 +10,10 @@ import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.metadata.GameParameters import com.unciv.models.metadata.GameParameters
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.math.max
class GameStarter{ class GameStarter{
fun startNewGame(newGameParameters: GameParameters): GameInfo { fun startNewGame(newGameParameters: GameParameters): GameInfo {
val gameInfo = GameInfo() val gameInfo = GameInfo()
@ -21,6 +23,32 @@ class GameStarter{
gameInfo.difficulty = newGameParameters.difficulty gameInfo.difficulty = newGameParameters.difficulty
addCivilizations(newGameParameters, gameInfo)
gameInfo.setTransients() // needs to be before placeBarbarianUnit because it depends on the tilemap having its gameinfo set
// Add Civ Technologies
for (civInfo in gameInfo.civilizations.filter {!it.isBarbarian()}) {
if (!civInfo.isPlayerCivilization())
for (tech in gameInfo.getDifficulty().aiFreeTechs)
civInfo.tech.addTechnology(tech)
for (tech in GameBasics.Technologies.values
.filter { it.era() < newGameParameters.startingEra })
if (!civInfo.tech.isResearched(tech.name))
civInfo.tech.addTechnology(tech.name)
civInfo.popupAlerts.clear() // Since adding technologies generates popups...
}
// and only now do we add units for everyone, because otherwise both the gameInfo.setTransients() and the placeUnit will both add the unit to the civ's unit list!
addCivStartingUnits(gameInfo)
return gameInfo
}
private fun addCivilizations(newGameParameters: GameParameters, gameInfo: GameInfo) {
val availableCivNames = Stack<String>() val availableCivNames = Stack<String>()
availableCivNames.addAll(GameBasics.Nations.filter { !it.value.isCityState() }.keys.shuffled()) availableCivNames.addAll(GameBasics.Nations.filter { !it.value.isCityState() }.keys.shuffled())
availableCivNames.removeAll(newGameParameters.players.map { it.chosenCiv }) availableCivNames.removeAll(newGameParameters.players.map { it.chosenCiv })
@ -30,8 +58,8 @@ class GameStarter{
val barbarianCivilization = CivilizationInfo("Barbarians") val barbarianCivilization = CivilizationInfo("Barbarians")
gameInfo.civilizations.add(barbarianCivilization) gameInfo.civilizations.add(barbarianCivilization)
for(player in newGameParameters.players.sortedBy { it.chosenCiv=="Random" }) { for (player in newGameParameters.players.sortedBy { it.chosenCiv == "Random" }) {
val nationName = if(player.chosenCiv!="Random") player.chosenCiv val nationName = if (player.chosenCiv != "Random") player.chosenCiv
else availableCivNames.pop() else availableCivNames.pop()
val playerCiv = CivilizationInfo(nationName) val playerCiv = CivilizationInfo(nationName)
@ -42,8 +70,8 @@ class GameStarter{
val cityStatesWithStartingLocations = val cityStatesWithStartingLocations =
gameInfo.tileMap.values.filter { it.improvement!=null && it.improvement!!.startsWith("StartingLocation ") } gameInfo.tileMap.values.filter { it.improvement != null && it.improvement!!.startsWith("StartingLocation ") }
.map { it.improvement!!.replace("StartingLocation ","") } .map { it.improvement!!.replace("StartingLocation ", "") }
val availableCityStatesNames = Stack<String>() val availableCityStatesNames = Stack<String>()
// since we shuffle and then order by, we end up with all the city states with starting locations first in a random order, // since we shuffle and then order by, we end up with all the city states with starting locations first in a random order,
@ -55,39 +83,41 @@ class GameStarter{
val civ = CivilizationInfo(cityStateName) val civ = CivilizationInfo(cityStateName)
gameInfo.civilizations.add(civ) gameInfo.civilizations.add(civ)
} }
}
gameInfo.setTransients() // needs to be before placeBarbarianUnit because it depends on the tilemap having its gameinfo set private fun addCivStartingUnits(gameInfo: GameInfo) {
for (civInfo in gameInfo.civilizations.filter {!it.isBarbarian() && !it.isPlayerCivilization()}) {
for (tech in gameInfo.getDifficulty().aiFreeTechs)
civInfo.tech.addTechnology(tech)
}
// and only now do we add units for everyone, because otherwise both the gameInfo.setTransients() and the placeUnit will both add the unit to the civ's unit list!
val startingLocations = getStartingLocations( val startingLocations = getStartingLocations(
gameInfo.civilizations.filter { !it.isBarbarian() }, gameInfo.civilizations.filter { !it.isBarbarian() },
gameInfo.tileMap) gameInfo.tileMap)
// For later starting eras, or for civs like Polynesia with a different Warrior, we need different starting units
fun getWarriorEquivalent(civ: CivilizationInfo): String {
val availableMilitaryUnits = GameBasics.Units.values.filter {
it.isBuildable(civ)
&& it.unitType.isLandUnit()
&& !it.unitType.isCivilian()
}
return availableMilitaryUnits.maxBy { max(it.strength, it.rangedStrength) }!!.name
}
for (civ in gameInfo.civilizations.filter { !it.isBarbarian() }) { for (civ in gameInfo.civilizations.filter { !it.isBarbarian() }) {
val startingLocation = startingLocations[civ]!! val startingLocation = startingLocations[civ]!!
civ.placeUnitNearTile(startingLocation.position, Constants.settler) civ.placeUnitNearTile(startingLocation.position, Constants.settler)
civ.placeUnitNearTile(startingLocation.position, civ.getEquivalentUnit("Warrior").name) civ.placeUnitNearTile(startingLocation.position, getWarriorEquivalent(civ))
civ.placeUnitNearTile(startingLocation.position, "Scout") civ.placeUnitNearTile(startingLocation.position, "Scout")
if (!civ.isPlayerCivilization() && civ.isMajorCiv()) { if (!civ.isPlayerCivilization() && civ.isMajorCiv()) {
for (unit in gameInfo.getDifficulty().aiFreeUnits) { for (unit in gameInfo.getDifficulty().aiFreeUnits) {
civ.placeUnitNearTile(startingLocation.position, civ.getEquivalentUnit(unit).name) val unitToAdd = if (unit == "Warrior") getWarriorEquivalent(civ) else unit
civ.placeUnitNearTile(startingLocation.position, unitToAdd)
} }
} }
} }
return gameInfo
} }
fun getStartingLocations(civs:List<CivilizationInfo>,tileMap: TileMap): HashMap<CivilizationInfo, TileInfo> { private fun getStartingLocations(civs:List<CivilizationInfo>, tileMap: TileMap): HashMap<CivilizationInfo, TileInfo> {
var landTiles = tileMap.values var landTiles = tileMap.values
.filter { it.isLand && !it.getBaseTerrain().impassable } .filter { it.isLand && !it.getBaseTerrain().impassable }
@ -148,7 +178,7 @@ class GameStarter{
throw Exception("Didn't manage to get starting locations even with distance of 1?") throw Exception("Didn't manage to get starting locations even with distance of 1?")
} }
fun vectorIsAtLeastNTilesAwayFromEdge(vector: Vector2, n:Int, tileMap: TileMap): Boolean { private fun vectorIsAtLeastNTilesAwayFromEdge(vector: Vector2, n:Int, tileMap: TileMap): Boolean {
// Since all maps are HEXAGONAL, the easiest way of checking if a tile is n steps away from the // Since all maps are HEXAGONAL, the easiest way of checking if a tile is n steps away from the
// edge is checking the distance to the CENTER POINT // edge is checking the distance to the CENTER POINT
// Can't believe we used a dumb way of calculating this before! // Can't believe we used a dumb way of calculating this before!
@ -156,5 +186,4 @@ class GameStarter{
val distanceFromCenter = HexMath().getDistance(vector, Vector2.Zero) val distanceFromCenter = HexMath().getDistance(vector, Vector2.Zero)
return hexagonalRadius-distanceFromCenter >= n return hexagonalRadius-distanceFromCenter >= n
} }
} }

View file

@ -3,6 +3,7 @@ package com.unciv.models.metadata
import com.unciv.logic.civilization.PlayerType import com.unciv.logic.civilization.PlayerType
import com.unciv.logic.map.MapType import com.unciv.logic.map.MapType
import com.unciv.models.gamebasics.VictoryType import com.unciv.models.gamebasics.VictoryType
import com.unciv.models.gamebasics.tech.TechEra
class GameParameters { // Default values are the default new game class GameParameters { // Default values are the default new game
var difficulty = "Prince" var difficulty = "Prince"
@ -17,6 +18,7 @@ class GameParameters { // Default values are the default new game
var noBarbarians = false var noBarbarians = false
var mapFileName: String? = null var mapFileName: String? = null
var victoryTypes: ArrayList<VictoryType> = VictoryType.values().toCollection(ArrayList()) // By default, all victory types var victoryTypes: ArrayList<VictoryType> = VictoryType.values().toCollection(ArrayList()) // By default, all victory types
var startingEra = TechEra.Ancient
var isOnlineMultiplayer = false var isOnlineMultiplayer = false
} }

View file

@ -10,6 +10,7 @@ import com.unciv.logic.MapSaver
import com.unciv.logic.map.MapType import com.unciv.logic.map.MapType
import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.VictoryType import com.unciv.models.gamebasics.VictoryType
import com.unciv.models.gamebasics.tech.TechEra
import com.unciv.models.gamebasics.tr import com.unciv.models.gamebasics.tr
import com.unciv.models.metadata.GameParameters import com.unciv.models.metadata.GameParameters
import com.unciv.models.metadata.GameSpeed import com.unciv.models.metadata.GameSpeed
@ -22,11 +23,11 @@ class NewGameScreenOptionsTable(val newGameParameters: GameParameters, val onMul
addMapTypeSizeAndFile() addMapTypeSizeAndFile()
addDifficultySelectBox() addDifficultySelectBox()
addGameSpeedSelectBox() addGameSpeedSelectBox()
addEraSelectBox()
addCityStatesSelectBox() addCityStatesSelectBox()
addVictoryTypeCheckboxes() addVictoryTypeCheckboxes()
addBarbariansCheckbox() addBarbariansCheckbox()
addIsOnlineMultiplayerCheckbox() addIsOnlineMultiplayerCheckbox()
pack() pack()
@ -140,6 +141,17 @@ class NewGameScreenOptionsTable(val newGameParameters: GameParameters, val onMul
add(gameSpeedSelectBox).pad(10f).row() add(gameSpeedSelectBox).pad(10f).row()
} }
private fun addEraSelectBox() {
add("{Starting Era}:".tr())
val eraSelectBox = TranslatedSelectBox(TechEra.values().map { it.name }, newGameParameters.startingEra.name, CameraStageBaseScreen.skin)
eraSelectBox.addListener(object : ChangeListener() {
override fun changed(event: ChangeEvent?, actor: Actor?) {
newGameParameters.startingEra = TechEra.valueOf(eraSelectBox.selected.value)
}
})
add(eraSelectBox).pad(10f).row()
}
private fun addVictoryTypeCheckboxes() { private fun addVictoryTypeCheckboxes() {
add("{Victory conditions}:".tr()).colspan(2).row() add("{Victory conditions}:".tr()).colspan(2).row()

View file

@ -20,6 +20,7 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
* [Flag](https://thenounproject.com/search/?q=Flag&i=50114) By Melvin Poppelaars for Settler * [Flag](https://thenounproject.com/search/?q=Flag&i=50114) By Melvin Poppelaars for Settler
* [Eagle](https://thenounproject.com/search/?q=Eagle&i=1619932) By anggun for Scout * [Eagle](https://thenounproject.com/search/?q=Eagle&i=1619932) By anggun for Scout
* [Axe](https://thenounproject.com/search/?q=Axe&i=1688143) By ehab.abdullah for Warrior * [Axe](https://thenounproject.com/search/?q=Axe&i=1688143) By ehab.abdullah for Warrior
* [Haka](https://thenounproject.com/search/?q=haka&i=379655) By Josh for Maori Warrior
* [Spiked Club](https://thenounproject.com/search/?q=spiked%20club&i=831793) by Hamish * [Spiked Club](https://thenounproject.com/search/?q=spiked%20club&i=831793) by Hamish
* [Bow And Arrow](https://thenounproject.com/search/?q=Bow%20and%20Arrow&i=338261) By Viktor Ostrovsky for Archer * [Bow And Arrow](https://thenounproject.com/search/?q=Bow%20and%20Arrow&i=338261) By Viktor Ostrovsky for Archer
* [Bow](https://thenounproject.com/search/?q=bow&i=101736) By Arthur Shlain for Bowman * [Bow](https://thenounproject.com/search/?q=bow&i=101736) By Arthur Shlain for Bowman