Optimize conditional tutorials (#2378)
* Bring Incas into the main game (also changes slinger withdraw ability to inheritable) * Update Nations.json * Optimize-Tutorial-Conditions: Measure 'Before' * Optimize-Tutorial-Conditions: Deferred tests * Optimize-Tutorial-Conditions: Remove instrumentation
This commit is contained in:
parent
757fa7eeb7
commit
33da0e3a7f
5 changed files with 46 additions and 43 deletions
|
@ -167,7 +167,7 @@ class CivilizationInfo {
|
||||||
* Returns a dictionary of ALL resource names, and the amount that the civ has of each
|
* Returns a dictionary of ALL resource names, and the amount that the civ has of each
|
||||||
*/
|
*/
|
||||||
fun getCivResourcesByName():HashMap<String,Int> {
|
fun getCivResourcesByName():HashMap<String,Int> {
|
||||||
val hashMap = HashMap<String,Int>()
|
val hashMap = HashMap<String,Int>(gameInfo.ruleSet.tileResources.size)
|
||||||
for(resource in gameInfo.ruleSet.tileResources.keys) hashMap[resource]=0
|
for(resource in gameInfo.ruleSet.tileResources.keys) hashMap[resource]=0
|
||||||
for(entry in getCivResources())
|
for(entry in getCivResources())
|
||||||
hashMap[entry.resource.name] = entry.amount
|
hashMap[entry.resource.name] = entry.amount
|
||||||
|
|
|
@ -98,8 +98,7 @@ class CityScreen(internal val city: CityInfo): CameraStageBaseScreen() {
|
||||||
updateAnnexAndRazeCityButton()
|
updateAnnexAndRazeCityButton()
|
||||||
updateTileGroups()
|
updateTileGroups()
|
||||||
|
|
||||||
if (city.getCenterTile().getTilesAtDistance(4).any())
|
displayTutorial(Tutorial.CityRange) { city.getCenterTile().getTilesAtDistance(4).any() }
|
||||||
displayTutorial(Tutorial.CityRange)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateTileGroups() {
|
private fun updateTileGroups() {
|
||||||
|
|
|
@ -15,9 +15,6 @@ class TutorialController(screen: CameraStageBaseScreen) {
|
||||||
private val tutorials = JsonParser().getFromJson(LinkedHashMap<String, Array<String>>().javaClass, "jsons/Tutorials.json")
|
private val tutorials = JsonParser().getFromJson(LinkedHashMap<String, Array<String>>().javaClass, "jsons/Tutorials.json")
|
||||||
|
|
||||||
fun showTutorial(tutorial: Tutorial) {
|
fun showTutorial(tutorial: Tutorial) {
|
||||||
if (!UncivGame.Current.settings.showTutorials) return
|
|
||||||
if (UncivGame.Current.settings.tutorialsShown.contains(tutorial.name)) return
|
|
||||||
|
|
||||||
tutorialQueue.add(tutorial)
|
tutorialQueue.add(tutorial)
|
||||||
showTutorialIfNeeded()
|
showTutorialIfNeeded()
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,12 @@ open class CameraStageBaseScreen : Screen {
|
||||||
|
|
||||||
override fun dispose() {}
|
override fun dispose() {}
|
||||||
|
|
||||||
fun displayTutorial(tutorial: Tutorial) = tutorialController.showTutorial(tutorial)
|
fun displayTutorial( tutorial: Tutorial, test: (()->Boolean)? = null ) {
|
||||||
|
if (!game.settings.showTutorials) return
|
||||||
|
if (game.settings.tutorialsShown.contains(tutorial.name)) return
|
||||||
|
if (test != null && !test()) return
|
||||||
|
tutorialController.showTutorial(tutorial)
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
var skin = Skin(Gdx.files.internal("skin/flat-earth-ui.json"))
|
var skin = Skin(Gdx.files.internal("skin/flat-earth-ui.json"))
|
||||||
|
|
|
@ -324,22 +324,29 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
||||||
UncivGame.Current.crashController.showDialogIfNeeded()
|
UncivGame.Current.crashController.showDialogIfNeeded()
|
||||||
|
|
||||||
displayTutorial(Tutorial.Introduction)
|
displayTutorial(Tutorial.Introduction)
|
||||||
if (!UncivGame.Current.settings.tutorialsShown.contains("_EnemyCityNeedsConqueringWithMeleeUnit")) {
|
|
||||||
for (enemyCity in viewingCiv.diplomacy.values.filter { it.diplomaticStatus == DiplomaticStatus.War }
|
displayTutorial(Tutorial.EnemyCityNeedsConqueringWithMeleeUnit) {
|
||||||
.map { it.otherCiv() }.flatMap { it.cities }) {
|
// diplomacy is a HashMap, cities a List - so sequences should help
|
||||||
if (enemyCity.health == 1 && enemyCity.getCenterTile().getTilesInDistance(2)
|
// .flatMap { it.getUnits().asSequence() } is not a good idea because getUnits constructs an ArrayList dynamically
|
||||||
.any { it.getUnits().any { unit -> unit.civInfo == viewingCiv} })
|
viewingCiv.diplomacy.values.asSequence()
|
||||||
displayTutorial(Tutorial.EnemyCityNeedsConqueringWithMeleeUnit)
|
.filter { it.diplomaticStatus == DiplomaticStatus.War }
|
||||||
}
|
.map { it.otherCiv() }
|
||||||
|
// we're now lazily enumerating over CivilizationInfo's we're at war with
|
||||||
|
.flatMap { it.cities.asSequence() }
|
||||||
|
// ... all *their* cities
|
||||||
|
.filter { it.health == 1 }
|
||||||
|
// ... those ripe for conquering
|
||||||
|
.flatMap { it.getCenterTile().getTilesInDistance(2).asSequence() }
|
||||||
|
// ... all tiles around those in range of an average melee unit
|
||||||
|
// -> and now we look for a unit that could do the conquering because it's ours
|
||||||
|
// no matter whether civilian, air or ranged, tell user he needs melee
|
||||||
|
.any { it.getUnits().any { unit -> unit.civInfo == viewingCiv} }
|
||||||
}
|
}
|
||||||
if(viewingCiv.cities.any { it.hasJustBeenConquered })
|
displayTutorial(Tutorial.AfterConquering) { viewingCiv.cities.any{it.hasJustBeenConquered} }
|
||||||
displayTutorial(Tutorial.AfterConquering)
|
|
||||||
|
|
||||||
if (gameInfo.getCurrentPlayerCivilization().getCivUnits().any { it.health < 100 })
|
displayTutorial(Tutorial.InjuredUnits) { gameInfo.getCurrentPlayerCivilization().getCivUnits().any { it.health < 100 } }
|
||||||
displayTutorial(Tutorial.InjuredUnits)
|
|
||||||
|
|
||||||
if (gameInfo.getCurrentPlayerCivilization().getCivUnits().any { it.name == Constants.worker })
|
displayTutorial(Tutorial.Workers) { gameInfo.getCurrentPlayerCivilization().getCivUnits().any { it.name == Constants.worker } }
|
||||||
displayTutorial(Tutorial.Workers)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateDiplomacyButton(civInfo: CivilizationInfo) {
|
private fun updateDiplomacyButton(civInfo: CivilizationInfo) {
|
||||||
|
@ -540,30 +547,25 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showTutorialsOnNextTurn(){
|
private fun showTutorialsOnNextTurn(){
|
||||||
val shownTutorials = UncivGame.Current.settings.tutorialsShown
|
|
||||||
displayTutorial(Tutorial.SlowStart)
|
displayTutorial(Tutorial.SlowStart)
|
||||||
if("_BarbarianEncountered" !in shownTutorials
|
displayTutorial(Tutorial.BarbarianEncountered) { viewingCiv.viewableTiles.any { it.getUnits().any { unit -> unit.civInfo.isBarbarian() } } }
|
||||||
&& viewingCiv.viewableTiles.any { it.getUnits().any { unit -> unit.civInfo.isBarbarian() } })
|
displayTutorial(Tutorial.RoadsAndRailroads) { viewingCiv.cities.size > 2 }
|
||||||
displayTutorial(Tutorial.BarbarianEncountered)
|
displayTutorial(Tutorial.Happiness) { viewingCiv.getHappiness() < 5 }
|
||||||
if(viewingCiv.cities.size > 2) displayTutorial(Tutorial.RoadsAndRailroads)
|
displayTutorial(Tutorial.Unhappiness) { viewingCiv.getHappiness() < 0 }
|
||||||
if(viewingCiv.getHappiness() < 5) displayTutorial(Tutorial.Happiness)
|
displayTutorial(Tutorial.GoldenAge) { viewingCiv.goldenAges.isGoldenAge() }
|
||||||
if(viewingCiv.getHappiness() < 0) displayTutorial(Tutorial.Unhappiness)
|
displayTutorial(Tutorial.IdleUnits) { gameInfo.turns >= 50 && UncivGame.Current.settings.checkForDueUnits }
|
||||||
if(viewingCiv.goldenAges.isGoldenAge()) displayTutorial(Tutorial.GoldenAge)
|
displayTutorial(Tutorial.ContactMe) { gameInfo.turns >= 100 }
|
||||||
if(gameInfo.turns >= 50 && UncivGame.Current.settings.checkForDueUnits) displayTutorial(Tutorial.IdleUnits)
|
val resources = viewingCiv.detailedCivResources.asSequence().filter { it.origin == "All" } // Avoid full list copy
|
||||||
if(gameInfo.turns >= 100) displayTutorial(Tutorial.ContactMe)
|
val test = viewingCiv.getCivResources()
|
||||||
val resources = viewingCiv.getCivResources()
|
displayTutorial(Tutorial.LuxuryResource) { resources.any { it.resource.resourceType==ResourceType.Luxury } }
|
||||||
if(resources.any { it.resource.resourceType==ResourceType.Luxury }) displayTutorial(Tutorial.LuxuryResource)
|
displayTutorial(Tutorial.StrategicResource) { resources.any { it.resource.resourceType==ResourceType.Strategic} }
|
||||||
if(resources.any { it.resource.resourceType==ResourceType.Strategic}) displayTutorial(Tutorial.StrategicResource)
|
displayTutorial(Tutorial.EnemyCity) {
|
||||||
if("Enemy_City" !in shownTutorials
|
viewingCiv.getKnownCivs().asSequence().filter { viewingCiv.isAtWarWith(it) }
|
||||||
&& viewingCiv.getKnownCivs().filter { viewingCiv.isAtWarWith(it) }
|
.flatMap { it.cities.asSequence() }.any { viewingCiv.exploredTiles.contains(it.location) }
|
||||||
.flatMap { it.cities }.any { viewingCiv.exploredTiles.contains(it.location) })
|
}
|
||||||
displayTutorial(Tutorial.EnemyCity)
|
displayTutorial(Tutorial.ApolloProgram) { viewingCiv.containsBuildingUnique("Enables construction of Spaceship parts") }
|
||||||
if(viewingCiv.containsBuildingUnique("Enables construction of Spaceship parts"))
|
displayTutorial(Tutorial.SiegeUnits) { viewingCiv.getCivUnits().any { it.type == UnitType.Siege } }
|
||||||
displayTutorial(Tutorial.ApolloProgram)
|
displayTutorial(Tutorial.Embarking) { viewingCiv.tech.getTechUniques().contains("Enables embarkation for land units") }
|
||||||
if(viewingCiv.getCivUnits().any { it.type == UnitType.Siege })
|
|
||||||
displayTutorial(Tutorial.SiegeUnits)
|
|
||||||
if(viewingCiv.tech.getTechUniques().contains("Enables embarkation for land units"))
|
|
||||||
displayTutorial(Tutorial.Embarking)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun backButtonAndESCHandler() {
|
private fun backButtonAndESCHandler() {
|
||||||
|
|
Loading…
Reference in a new issue