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:
proteus-anguinus 2020-04-10 09:13:17 +02:00 committed by GitHub
parent 757fa7eeb7
commit 33da0e3a7f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 43 deletions

View file

@ -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

View file

@ -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() {

View file

@ -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()
} }

View file

@ -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"))

View file

@ -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() {