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
*/
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(entry in getCivResources())
hashMap[entry.resource.name] = entry.amount

View file

@ -98,8 +98,7 @@ class CityScreen(internal val city: CityInfo): CameraStageBaseScreen() {
updateAnnexAndRazeCityButton()
updateTileGroups()
if (city.getCenterTile().getTilesAtDistance(4).any())
displayTutorial(Tutorial.CityRange)
displayTutorial(Tutorial.CityRange) { city.getCenterTile().getTilesAtDistance(4).any() }
}
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")
fun showTutorial(tutorial: Tutorial) {
if (!UncivGame.Current.settings.showTutorials) return
if (UncivGame.Current.settings.tutorialsShown.contains(tutorial.name)) return
tutorialQueue.add(tutorial)
showTutorialIfNeeded()
}

View file

@ -62,7 +62,12 @@ open class CameraStageBaseScreen : Screen {
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 {
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()
displayTutorial(Tutorial.Introduction)
if (!UncivGame.Current.settings.tutorialsShown.contains("_EnemyCityNeedsConqueringWithMeleeUnit")) {
for (enemyCity in viewingCiv.diplomacy.values.filter { it.diplomaticStatus == DiplomaticStatus.War }
.map { it.otherCiv() }.flatMap { it.cities }) {
if (enemyCity.health == 1 && enemyCity.getCenterTile().getTilesInDistance(2)
.any { it.getUnits().any { unit -> unit.civInfo == viewingCiv} })
displayTutorial(Tutorial.EnemyCityNeedsConqueringWithMeleeUnit)
}
displayTutorial(Tutorial.EnemyCityNeedsConqueringWithMeleeUnit) {
// diplomacy is a HashMap, cities a List - so sequences should help
// .flatMap { it.getUnits().asSequence() } is not a good idea because getUnits constructs an ArrayList dynamically
viewingCiv.diplomacy.values.asSequence()
.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)
displayTutorial(Tutorial.AfterConquering) { viewingCiv.cities.any{it.hasJustBeenConquered} }
if (gameInfo.getCurrentPlayerCivilization().getCivUnits().any { it.health < 100 })
displayTutorial(Tutorial.InjuredUnits)
displayTutorial(Tutorial.InjuredUnits) { gameInfo.getCurrentPlayerCivilization().getCivUnits().any { it.health < 100 } }
if (gameInfo.getCurrentPlayerCivilization().getCivUnits().any { it.name == Constants.worker })
displayTutorial(Tutorial.Workers)
displayTutorial(Tutorial.Workers) { gameInfo.getCurrentPlayerCivilization().getCivUnits().any { it.name == Constants.worker } }
}
private fun updateDiplomacyButton(civInfo: CivilizationInfo) {
@ -540,30 +547,25 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() {
}
private fun showTutorialsOnNextTurn(){
val shownTutorials = UncivGame.Current.settings.tutorialsShown
displayTutorial(Tutorial.SlowStart)
if("_BarbarianEncountered" !in shownTutorials
&& viewingCiv.viewableTiles.any { it.getUnits().any { unit -> unit.civInfo.isBarbarian() } })
displayTutorial(Tutorial.BarbarianEncountered)
if(viewingCiv.cities.size > 2) displayTutorial(Tutorial.RoadsAndRailroads)
if(viewingCiv.getHappiness() < 5) displayTutorial(Tutorial.Happiness)
if(viewingCiv.getHappiness() < 0) displayTutorial(Tutorial.Unhappiness)
if(viewingCiv.goldenAges.isGoldenAge()) displayTutorial(Tutorial.GoldenAge)
if(gameInfo.turns >= 50 && UncivGame.Current.settings.checkForDueUnits) displayTutorial(Tutorial.IdleUnits)
if(gameInfo.turns >= 100) displayTutorial(Tutorial.ContactMe)
val resources = viewingCiv.getCivResources()
if(resources.any { it.resource.resourceType==ResourceType.Luxury }) displayTutorial(Tutorial.LuxuryResource)
if(resources.any { it.resource.resourceType==ResourceType.Strategic}) displayTutorial(Tutorial.StrategicResource)
if("Enemy_City" !in shownTutorials
&& viewingCiv.getKnownCivs().filter { viewingCiv.isAtWarWith(it) }
.flatMap { it.cities }.any { viewingCiv.exploredTiles.contains(it.location) })
displayTutorial(Tutorial.EnemyCity)
if(viewingCiv.containsBuildingUnique("Enables construction of Spaceship parts"))
displayTutorial(Tutorial.ApolloProgram)
if(viewingCiv.getCivUnits().any { it.type == UnitType.Siege })
displayTutorial(Tutorial.SiegeUnits)
if(viewingCiv.tech.getTechUniques().contains("Enables embarkation for land units"))
displayTutorial(Tutorial.Embarking)
displayTutorial(Tutorial.BarbarianEncountered) { viewingCiv.viewableTiles.any { it.getUnits().any { unit -> unit.civInfo.isBarbarian() } } }
displayTutorial(Tutorial.RoadsAndRailroads) { viewingCiv.cities.size > 2 }
displayTutorial(Tutorial.Happiness) { viewingCiv.getHappiness() < 5 }
displayTutorial(Tutorial.Unhappiness) { viewingCiv.getHappiness() < 0 }
displayTutorial(Tutorial.GoldenAge) { viewingCiv.goldenAges.isGoldenAge() }
displayTutorial(Tutorial.IdleUnits) { gameInfo.turns >= 50 && UncivGame.Current.settings.checkForDueUnits }
displayTutorial(Tutorial.ContactMe) { gameInfo.turns >= 100 }
val resources = viewingCiv.detailedCivResources.asSequence().filter { it.origin == "All" } // Avoid full list copy
val test = viewingCiv.getCivResources()
displayTutorial(Tutorial.LuxuryResource) { resources.any { it.resource.resourceType==ResourceType.Luxury } }
displayTutorial(Tutorial.StrategicResource) { resources.any { it.resource.resourceType==ResourceType.Strategic} }
displayTutorial(Tutorial.EnemyCity) {
viewingCiv.getKnownCivs().asSequence().filter { viewingCiv.isAtWarWith(it) }
.flatMap { it.cities.asSequence() }.any { viewingCiv.exploredTiles.contains(it.location) }
}
displayTutorial(Tutorial.ApolloProgram) { viewingCiv.containsBuildingUnique("Enables construction of Spaceship parts") }
displayTutorial(Tutorial.SiegeUnits) { viewingCiv.getCivUnits().any { it.type == UnitType.Siege } }
displayTutorial(Tutorial.Embarking) { viewingCiv.tech.getTechUniques().contains("Enables embarkation for land units") }
}
private fun backButtonAndESCHandler() {