diff --git a/android/assets/jsons/Units.json b/android/assets/jsons/Units.json index ba6793682d..3724b8d03c 100644 --- a/android/assets/jsons/Units.json +++ b/android/assets/jsons/Units.json @@ -44,28 +44,28 @@ }, { name:"Great Artist", - description: "Can start an 8-turn golden age or construcct a landmark (+5 culture)", + description: "Can start an 8-turn golden age or construct a Landmark (+6 culture)", unbuildable:true, unitType:"Civilian", movement:2 }, { name:"Great Scientist", - description: "Can discover a technology, or construct an academy (+4 science(", + description: "Can discover a technology, or construct an Academy (+4 science)", unbuildable:true, unitType:"Civilian", movement:2 }, { name:"Great Merchant", - description: "Can undertake a trade mission, giving a large sum of gold, or construct a ?", + description: "Can undertake a trade mission, giving a large sum of gold, or construct a Customs House (+4 gold)", unbuildable:true, unitType:"Civilian", movement:2 }, { name:"Great Engineer", - description: "Can speed up construction of a wonder, or construct a refinery, giving +? production?", + description: "Can speed up construction of a wonder, or construct a Manufactory (+4 production)", unbuildable:true, unitType:"Civilian", movement:2 diff --git a/core/src/com/unciv/UnCivGame.kt b/core/src/com/unciv/UnCivGame.kt index dacca61fdf..0fe92c5f80 100644 --- a/core/src/com/unciv/UnCivGame.kt +++ b/core/src/com/unciv/UnCivGame.kt @@ -73,6 +73,7 @@ class UnCivGame : Game() { worldScreen = WorldScreen() setWorldScreen() + } fun setWorldScreen() { diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index c80b0a5002..9bc608700a 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -1,5 +1,6 @@ package com.unciv.logic +import com.unciv.UnCivGame import com.unciv.logic.automation.Automation import com.unciv.logic.city.CityInfo import com.unciv.logic.civilization.CivilizationInfo @@ -7,6 +8,7 @@ import com.unciv.logic.civilization.Notification import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileMap import com.unciv.models.gamebasics.GameBasics +import com.unciv.ui.VictoryScreen import com.unciv.ui.utils.getRandom class GameInfo { diff --git a/core/src/com/unciv/logic/automation/UnitAutomation.kt b/core/src/com/unciv/logic/automation/UnitAutomation.kt index a880b8b763..335b158136 100644 --- a/core/src/com/unciv/logic/automation/UnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/UnitAutomation.kt @@ -11,6 +11,27 @@ import com.unciv.ui.worldscreen.unit.UnitActions class UnitAutomation{ + fun healUnit(unit:MapUnit) { + // If we're low on health then heal + // todo: go to a more defensible place if there is one + val tilesInDistance = unit.getDistanceToTiles().keys + val unitTile = unit.getTile() + + // Go to friendly tile if within distance - better healing! + val friendlyTile = tilesInDistance.firstOrNull { it.getOwner()?.civName == unit.owner && it.unit == null } + if (unitTile.getOwner()?.civName != unit.owner && friendlyTile != null) { + unit.moveToTile(friendlyTile) + return + } + + // Or at least get out of enemy territory yaknow + val neutralTile = tilesInDistance.firstOrNull { it.getOwner() == null && it.unit == null } + if (unitTile.getOwner()?.civName != unit.owner && unitTile.getOwner() != null && neutralTile != null) { + unit.moveToTile(neutralTile) + return + } + } + fun automateUnitMoves(unit: MapUnit) { if (unit.name == "Settler") { @@ -23,30 +44,12 @@ class UnitAutomation{ return } + if(unit.name.startsWith("Great")) return // DON'T MOVE A MUSCLE - fun healUnit() { - // If we're low on health then heal - // todo: go to a more defensible place if there is one - val tilesInDistance = unit.getDistanceToTiles().keys - val unitTile = unit.getTile() - - // Go to friendly tile if within distance - better healing! - val friendlyTile = tilesInDistance.firstOrNull { it.getOwner()?.civName == unit.owner && it.unit == null } - if (unitTile.getOwner()?.civName != unit.owner && friendlyTile != null) { - unit.moveToTile(friendlyTile) - return - } - - // Or at least get out of enemy territory yaknow - val neutralTile = tilesInDistance.firstOrNull { it.getOwner() == null && it.unit == null } - if (unitTile.getOwner()?.civName != unit.owner && unitTile.getOwner() != null && neutralTile != null) { - unit.moveToTile(neutralTile) - return - } - } + if(unit.getTile().isCityCenter()) return // It's always good to have a unit in the city center if (unit.health < 50) { - healUnit() + healUnit(unit) return } // do nothing but heal @@ -76,7 +79,7 @@ class UnitAutomation{ } if (unit.health < 80) { - healUnit() + healUnit(unit) return } // do nothing but heal until 80 health @@ -95,7 +98,7 @@ class UnitAutomation{ } if (unit.health < 100) { - healUnit() + healUnit(unit) return } diff --git a/core/src/com/unciv/logic/civilization/PolicyManager.kt b/core/src/com/unciv/logic/civilization/PolicyManager.kt index c5ce625af2..a055385c64 100644 --- a/core/src/com/unciv/logic/civilization/PolicyManager.kt +++ b/core/src/com/unciv/logic/civilization/PolicyManager.kt @@ -3,7 +3,9 @@ package com.unciv.logic.civilization import com.unciv.UnCivGame import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.Policy +import com.unciv.ui.VictoryScreen import com.unciv.ui.pickerscreens.GreatPersonPickerScreen +import com.unciv.ui.utils.getRandom class PolicyManager { @@ -34,26 +36,30 @@ class PolicyManager { fun isAdopted(policyName: String): Boolean = adoptedPolicies.contains(policyName) - fun isAdoptable(policy: Policy) = getAdoptedPolicies().containsAll(policy.requires!!) + fun isAdoptable(policy: Policy) = !policy.name.endsWith("Complete") + && getAdoptedPolicies().containsAll(policy.requires!!) - fun canAdoptPolicy(): Boolean = freePolicies>0 || storedCulture >= getCultureNeededForNextPolicy() + fun canAdoptPolicy(): Boolean = freePolicies > 0 || storedCulture >= getCultureNeededForNextPolicy() - fun adopt(policy: Policy, branchCompletion: Boolean =false) { - if (freePolicies > 0) - freePolicies-- - else - storedCulture -= getCultureNeededForNextPolicy() + fun adopt(policy: Policy, branchCompletion: Boolean = false) { + + if(!branchCompletion) { + if (freePolicies > 0) freePolicies-- + else storedCulture -= getCultureNeededForNextPolicy() + } adoptedPolicies.add(policy.name) - if(!branchCompletion) { + if (!branchCompletion) { val branch = GameBasics.PolicyBranches[policy.branch]!! if (branch.policies.count { isAdopted(it.name) } == branch.policies.size - 1) { // All done apart from branch completion adopt(branch.policies.last(), true) // add branch completion! } + } else { + UnCivGame.Current.screen = VictoryScreen() } - when(policy.name ) { + when (policy.name) { "Collective Rule" -> civInfo.placeUnitNearTile(civInfo.capital.location, "Settler") "Citizenship" -> civInfo.placeUnitNearTile(civInfo.capital.location, "Worker") "Representation", "Reformation" -> civInfo.goldenAges.enterGoldenAge() @@ -62,7 +68,10 @@ class PolicyManager { for (city in civInfo.cities.subList(0, Math.min(4, civInfo.cities.size))) city.cityConstructions.addCultureBuilding() "Free Religion" -> freePolicies++ - "Liberty Complete" -> UnCivGame.Current.screen = GreatPersonPickerScreen() + "Liberty Complete" -> { + if (civInfo.isPlayerCivilization()) UnCivGame.Current.screen = GreatPersonPickerScreen() // screw the victory screen! + else civInfo.addGreatPerson(GameBasics.Units.keys.filter { it.startsWith("Great") }.getRandom()) + } } for (cityInfo in civInfo.cities) @@ -75,4 +84,4 @@ class PolicyManager { if (!couldAdoptPolicyBefore && canAdoptPolicy()) shouldOpenPolicyPicker = true } -} +} \ No newline at end of file diff --git a/core/src/com/unciv/logic/civilization/ScienceVictoryManager.kt b/core/src/com/unciv/logic/civilization/ScienceVictoryManager.kt index ed7c91a04a..2c21a32c57 100644 --- a/core/src/com/unciv/logic/civilization/ScienceVictoryManager.kt +++ b/core/src/com/unciv/logic/civilization/ScienceVictoryManager.kt @@ -13,6 +13,8 @@ class ScienceVictoryManager { return counter } + fun hasWon() = requiredParts.equals(currentParts) + init { requiredParts.add("SS Booster", 3) requiredParts.add("SS Cockpit", 1) diff --git a/core/src/com/unciv/models/gamebasics/Building.kt b/core/src/com/unciv/models/gamebasics/Building.kt index ac928c04b0..b1038f68b3 100644 --- a/core/src/com/unciv/models/gamebasics/Building.kt +++ b/core/src/com/unciv/models/gamebasics/Building.kt @@ -5,7 +5,6 @@ import com.unciv.logic.city.CityConstructions import com.unciv.logic.city.IConstruction import com.unciv.models.stats.NamedStats import com.unciv.models.stats.Stats -import com.unciv.ui.ScienceVictoryScreen import com.unciv.ui.VictoryScreen import com.unciv.ui.pickerscreens.PolicyPickerScreen @@ -171,9 +170,7 @@ class Building : NamedStats(), IConstruction, ICivilopedia { if (unique == "SpaceshipPart") { civInfo.scienceVictory.currentParts.add(name, 1) - UnCivGame.Current.screen = ScienceVictoryScreen(civInfo) - if (civInfo.scienceVictory.unconstructedParts().isEmpty()) - UnCivGame.Current.screen = VictoryScreen() + UnCivGame.Current.screen = VictoryScreen() return } construction.builtBuildings.add(name) @@ -181,7 +178,7 @@ class Building : NamedStats(), IConstruction, ICivilopedia { if (providesFreeBuilding != null && !construction.builtBuildings.contains(providesFreeBuilding!!)) construction.builtBuildings.add(providesFreeBuilding!!) when (unique) { - "ApolloProgram" -> UnCivGame.Current.screen = ScienceVictoryScreen(civInfo) + "ApolloProgram" -> UnCivGame.Current.screen = VictoryScreen() "EmpireEntersGoldenAge" -> civInfo.goldenAges.enterGoldenAge() "FreeGreatArtistAppears" -> civInfo.addGreatPerson("Great Artist") "WorkerConstruction" -> { diff --git a/core/src/com/unciv/ui/ScienceVictoryScreen.kt b/core/src/com/unciv/ui/ScienceVictoryScreen.kt deleted file mode 100644 index 1b832881da..0000000000 --- a/core/src/com/unciv/ui/ScienceVictoryScreen.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.unciv.ui - -import com.badlogic.gdx.graphics.Color -import com.badlogic.gdx.scenes.scene2d.Touchable -import com.badlogic.gdx.scenes.scene2d.ui.TextButton -import com.unciv.logic.civilization.CivilizationInfo -import com.unciv.models.linq.Counter -import com.unciv.ui.pickerscreens.PickerScreen -import com.unciv.ui.utils.CameraStageBaseScreen - -class ScienceVictoryScreen(internal val civInfo: CivilizationInfo) : PickerScreen() { - - init { - val scienceVictory = civInfo.scienceVictory - val builtSpaceshipParts = scienceVictory.currentParts.clone() - - for (key in scienceVictory.requiredParts.keys) - // can't take the keyset because we would be modifying it! - for (i in 0 until scienceVictory.requiredParts[key]!!) - addPartButton(key, builtSpaceshipParts) - - rightSideButton.isVisible = false - - if (!civInfo.buildingUniques.contains("ApolloProgram")) - descriptionLabel.setText("You must build the Apollo Program before you can build spaceship parts!") - else - descriptionLabel.setText("Apollo program is built - you may construct spaceship parts in your cities!") - displayTutorials("ScienceVictoryScreenEntered") - } - - private fun addPartButton(partName: String, parts: Counter) { - topTable.row() - val button = TextButton(partName, CameraStageBaseScreen.skin) - button.touchable = Touchable.disabled - if (!civInfo.buildingUniques.contains("ApolloProgram")) - button.color = Color.GRAY - else if (parts[partName]!! > 0) { - button.color = Color.GREEN - parts.add(partName, -1) - } - topTable.add(button).pad(10f) - } -} - - diff --git a/core/src/com/unciv/ui/VictoryScreen.kt b/core/src/com/unciv/ui/VictoryScreen.kt index 691a15be00..ab849b363a 100644 --- a/core/src/com/unciv/ui/VictoryScreen.kt +++ b/core/src/com/unciv/ui/VictoryScreen.kt @@ -1,30 +1,80 @@ package com.unciv.ui -import com.badlogic.gdx.scenes.scene2d.ui.Label +import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.TextButton +import com.unciv.UnCivGame +import com.unciv.models.gamebasics.GameBasics import com.unciv.ui.cityscreen.addClickListener -import com.unciv.ui.utils.CameraStageBaseScreen +import com.unciv.ui.pickerscreens.PickerScreen + +class VictoryScreen : PickerScreen() { + + val civInfo = UnCivGame.Current.gameInfo.getPlayerCivilization() -class VictoryScreen : CameraStageBaseScreen() { init { + topTable.skin=skin + topTable.defaults().pad(10f) + topTable.add("Science victory") + topTable.add("Cultural victory") + topTable.row() + topTable.add(scienceVictoryColumn()) + topTable.add(culturalVictoryColumn()) + topTable.row() + topTable.add("Complete all the spaceship parts to win!") + topTable.add("Complete 4 policy branches to win!") - val table = Table() - val label = Label("A resounding victory!", CameraStageBaseScreen.skin) - label.setFontScale(2f) + rightSideButton.isVisible=false - table.add(label).pad(20f).row() + if(civInfo.scienceVictory.hasWon()){ + rightSideButton.setText("Start new game") + rightSideButton.isVisible=true + closeButton.isVisible=false + descriptionLabel.setText("You have won a scientific victory!") + } - val newGameButton = TextButton("New game!", CameraStageBaseScreen.skin) - newGameButton.addClickListener { game.startNewGame() } - table.add(newGameButton).pad(20f).row() + if(civInfo.policies.adoptedPolicies.count{it.endsWith("Complete")} > 3){ + descriptionLabel.setText("You have won a cultural victory!") + } + } + fun won(){ + rightSideButton.setText("Start new game") + rightSideButton.isVisible=true + closeButton.isVisible=false + rightSideButton.addClickListener { UnCivGame.Current.startNewGame(true) } + } - table.pack() - table.setPosition((stage.width - table.width) / 2, (stage.height - table.height) / 2) + fun scienceVictoryColumn():Table{ + val t = Table() + t.defaults().pad(5f) + t.add(getMilestone("Built Apollo Program",civInfo.buildingUniques.contains("ApolloProgram"))).row() - stage.addActor(table) + val scienceVictory = civInfo.scienceVictory + + for (key in scienceVictory.requiredParts.keys) + for (i in 0 until scienceVictory.requiredParts[key]!!) + t.add(getMilestone(key, scienceVictory.currentParts[key]!! > i)).row() //(key, builtSpaceshipParts) + + return t + } + + fun culturalVictoryColumn():Table{ + val t=Table() + t.defaults().pad(5f) + for(branch in GameBasics.PolicyBranches.values) { + val finisher = branch.policies.last().name + t.add(getMilestone(finisher, civInfo.policies.isAdopted(finisher))).row() + } + return t + } + + fun getMilestone(text:String, achieved:Boolean): TextButton { + val TB = TextButton(text,skin) + if(achieved) TB.setColor(Color.GREEN) + else TB.setColor(Color.GRAY) + return TB } -} +} \ No newline at end of file diff --git a/core/src/com/unciv/ui/pickerscreens/GreatPersonPickerScreen.kt b/core/src/com/unciv/ui/pickerscreens/GreatPersonPickerScreen.kt index baaa934b3e..157861cbd7 100644 --- a/core/src/com/unciv/ui/pickerscreens/GreatPersonPickerScreen.kt +++ b/core/src/com/unciv/ui/pickerscreens/GreatPersonPickerScreen.kt @@ -1,7 +1,7 @@ package com.unciv.ui.pickerscreens import com.badlogic.gdx.scenes.scene2d.ui.TextButton -import com.unciv.logic.civilization.CivilizationInfo +import com.unciv.UnCivGame import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.Unit import com.unciv.ui.cityscreen.addClickListener @@ -9,22 +9,24 @@ import com.unciv.ui.utils.CameraStageBaseScreen class GreatPersonPickerScreen : PickerScreen() { private var theChosenOne: Unit? = null - internal var civInfo: CivilizationInfo? = null init { + closeButton.isVisible=false rightSideButton.setText("Choose a free great person") - for (unit in GameBasics.Units.values) { - if (!unit.name.startsWith("Great")) continue + for (unit in GameBasics.Units.values.filter { it.name.startsWith("Great") }) { val button = TextButton(unit.name, CameraStageBaseScreen.skin) button.addClickListener { theChosenOne = unit - pick(unit.name) + pick("Get " +unit.name) + descriptionLabel.setText(unit.description) } topTable.add(button).pad(10f) } rightSideButton.addClickListener { - civInfo!!.placeUnitNearTile(civInfo!!.cities[0].location, theChosenOne!!.name) + val civInfo = UnCivGame.Current.gameInfo.getPlayerCivilization() + civInfo.placeUnitNearTile(civInfo.cities[0].location, theChosenOne!!.name) + UnCivGame.Current.setWorldScreen() } } diff --git a/core/src/com/unciv/ui/pickerscreens/PolicyPickerScreen.kt b/core/src/com/unciv/ui/pickerscreens/PolicyPickerScreen.kt index 71dd0c41c6..9c2a5a8a45 100644 --- a/core/src/com/unciv/ui/pickerscreens/PolicyPickerScreen.kt +++ b/core/src/com/unciv/ui/pickerscreens/PolicyPickerScreen.kt @@ -42,7 +42,9 @@ class PolicyPickerScreen(internal val civInfo: CivilizationInfo) : PickerScreen( rightSideButton.addClickListener { civInfo.policies.adopt(pickedPolicy!!) - game.screen = PolicyPickerScreen(civInfo) + + // If we've mmoved to another screen in the meantime (great person pick, victory screen) ignore this + if(game.screen is PolicyPickerScreen) game.screen = PolicyPickerScreen(civInfo) } diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreenOptionsTable.kt b/core/src/com/unciv/ui/worldscreen/WorldScreenOptionsTable.kt index f6bdee7951..9e6aac26dc 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreenOptionsTable.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreenOptionsTable.kt @@ -7,7 +7,7 @@ import com.unciv.logic.civilization.CivilizationInfo import com.unciv.ui.CivilopediaScreen import com.unciv.ui.LoadScreen import com.unciv.ui.SaveScreen -import com.unciv.ui.ScienceVictoryScreen +import com.unciv.ui.VictoryScreen import com.unciv.ui.cityscreen.addClickListener import com.unciv.ui.pickerscreens.PolicyPickerScreen import com.unciv.ui.utils.CameraStageBaseScreen @@ -28,35 +28,35 @@ class WorldScreenOptionsTable internal constructor(worldScreen: WorldScreen, pri } add(openCivilopediaButton).pad(10f).row() - val LoadGameButton = TextButton("Load game", CameraStageBaseScreen.skin) - LoadGameButton .addClickListener { + val loadGameButton = TextButton("Load game", CameraStageBaseScreen.skin) + loadGameButton .addClickListener { worldScreen.game.screen = LoadScreen() isVisible=false } - add(LoadGameButton ).pad(10f).row() + add(loadGameButton ).pad(10f).row() - val SaveGameButton = TextButton("Save game", CameraStageBaseScreen.skin) - SaveGameButton .addClickListener { + val saveGameButton = TextButton("Save game", CameraStageBaseScreen.skin) + saveGameButton .addClickListener { worldScreen.game.screen = SaveScreen() isVisible=false } - add(SaveGameButton ).pad(10f).row() - val StartNewGameButton = TextButton("Start new game", CameraStageBaseScreen.skin) - StartNewGameButton.addClickListener { worldScreen.game.startNewGame(true) } - add(StartNewGameButton).pad(10f).row() + add(saveGameButton ).pad(10f).row() + val startNewGameButton = TextButton("Start new game", CameraStageBaseScreen.skin) + startNewGameButton.addClickListener { worldScreen.game.startNewGame(true) } + add(startNewGameButton).pad(10f).row() - val OpenScienceVictoryScreen = TextButton("Science victory status", CameraStageBaseScreen.skin) - OpenScienceVictoryScreen.addClickListener { - worldScreen.game.screen = ScienceVictoryScreen(this@WorldScreenOptionsTable.civInfo) + val openVictoryScreen = TextButton("Victory status", CameraStageBaseScreen.skin) + openVictoryScreen.addClickListener { + worldScreen.game.screen = VictoryScreen() } - add(OpenScienceVictoryScreen).pad(10f).row() + add(openVictoryScreen).pad(10f).row() - val OpenPolicyPickerScreen = TextButton("Social Policies", CameraStageBaseScreen.skin) - OpenPolicyPickerScreen.addClickListener { + val openPolicyPickerScreen = TextButton("Social Policies", CameraStageBaseScreen.skin) + openPolicyPickerScreen.addClickListener { worldScreen.game.screen = PolicyPickerScreen(this@WorldScreenOptionsTable.civInfo) } - add(OpenPolicyPickerScreen).pad(10f).row() + add(openPolicyPickerScreen).pad(10f).row() val closeButton = TextButton("Close", CameraStageBaseScreen.skin) closeButton.addClickListener { isVisible = false }