City construction picking now done through a scroll on the city screen, like in the original =D

Also resolved #417 on the way
This commit is contained in:
Yair Morgenstern 2019-01-19 23:43:28 +02:00
parent a371aedf23
commit 2ca894b05f
5 changed files with 137 additions and 77 deletions

View File

@ -156,6 +156,7 @@ class Building : NamedStats(), IConstruction{
} }
override fun getGoldCost(adoptedPolicies: HashSet<String>): Int { override fun getGoldCost(adoptedPolicies: HashSet<String>): Int {
// https://forums.civfanatics.com/threads/rush-buying-formula.393892/
var cost = Math.pow((30 * getProductionCost(adoptedPolicies)).toDouble(), 0.75) * (1 + hurryCostModifier / 100) var cost = Math.pow((30 * getProductionCost(adoptedPolicies)).toDouble(), 0.75) * (1 + hurryCostModifier / 100)
if (adoptedPolicies.contains("Mercantilism")) cost *= 0.75 if (adoptedPolicies.contains("Mercantilism")) cost *= 0.75
if (adoptedPolicies.contains("Patronage")) cost *= 0.5 if (adoptedPolicies.contains("Patronage")) cost *= 0.5

View File

@ -38,7 +38,7 @@ class CityScreen(internal val city: CityInfo) : CameraStageBaseScreen() {
tileTable.background = ImageGetter.getBackground(tableBackgroundColor) tileTable.background = ImageGetter.getBackground(tableBackgroundColor)
var buildingsTableContainer = Table() var buildingsTableContainer = Table()
buildingsTableContainer.pad(20f) buildingsTableContainer.pad(3f)
buildingsTableContainer.background = ImageGetter.getBackground(tableBackgroundColor) buildingsTableContainer.background = ImageGetter.getBackground(tableBackgroundColor)
cityInfoTable.update() cityInfoTable.update()
val buildingsScroll = ScrollPane(cityInfoTable) val buildingsScroll = ScrollPane(cityInfoTable)
@ -46,8 +46,8 @@ class CityScreen(internal val city: CityInfo) : CameraStageBaseScreen() {
.height(stage.height / 2) .height(stage.height / 2)
buildingsTableContainer = buildingsTableContainer.addBorder(2f, Color.WHITE) buildingsTableContainer = buildingsTableContainer.addBorder(2f, Color.WHITE)
buildingsTableContainer.setPosition(stage.width - buildingsTableContainer.width-20, buildingsTableContainer.setPosition(stage.width - buildingsTableContainer.width-5,
stage.height - buildingsTableContainer.height-20) stage.height - buildingsTableContainer.height-5)
//constructionsTable.background = ImageGetter.getBackground(tableBackgroundColor) //constructionsTable.background = ImageGetter.getBackground(tableBackgroundColor)
//val constructionsTableWithBorder = con //val constructionsTableWithBorder = con
@ -70,7 +70,7 @@ class CityScreen(internal val city: CityInfo) : CameraStageBaseScreen() {
topCityStatsTable.remove() topCityStatsTable.remove()
topCityStatsTable = getCityStatsTable() topCityStatsTable = getCityStatsTable()
topCityStatsTable.setPosition(20f, stage.height-20-topCityStatsTable.height) topCityStatsTable.setPosition(5f, stage.height-5-topCityStatsTable.height)
stage.addActor(topCityStatsTable) stage.addActor(topCityStatsTable)
if (city.getCenterTile().getTilesAtDistance(4).isNotEmpty()){ if (city.getCenterTile().getTilesAtDistance(4).isNotEmpty()){
@ -315,7 +315,7 @@ class CityScreen(internal val city: CityInfo) : CameraStageBaseScreen() {
} }
tileTable=tileTable.addBorder(2f, Color.WHITE) tileTable=tileTable.addBorder(2f, Color.WHITE)
tileTable.setPosition(stage.width - 10f - tileTable.width, 10f) tileTable.setPosition(stage.width - 5f - tileTable.width, 5f)
} }
companion object { companion object {

View File

@ -1,112 +1,171 @@
package com.unciv.ui.cityscreen package com.unciv.ui.cityscreen
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.* import com.badlogic.gdx.scenes.scene2d.Touchable
import com.unciv.UnCivGame import com.badlogic.gdx.scenes.scene2d.ui.Label
import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.badlogic.gdx.utils.Align
import com.unciv.logic.city.CityInfo
import com.unciv.logic.city.SpecialConstruction import com.unciv.logic.city.SpecialConstruction
import com.unciv.models.gamebasics.Building import com.unciv.models.gamebasics.Building
import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.tr import com.unciv.models.gamebasics.tr
import com.unciv.ui.pickerscreens.ConstructionPickerScreen import com.unciv.models.gamebasics.unit.BaseUnit
import com.unciv.ui.utils.* import com.unciv.ui.utils.*
class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScreen.skin){ class ConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBaseScreen.skin){
private fun getProductionButton(production: String, buttonText: String, var constructionScrollPane:ScrollPane?=null
description: String?, rightSideButtonText: String): Button {
val productionTextButton = Button(CameraStageBaseScreen.skin) private fun getProductionButton(construction: String, buttonText: String): Table {
productionTextButton.add(ImageGetter.getConstructionImage(production)).size(40f).padRight(5f) val pickProductionButton = Table()
productionTextButton.add(Label(buttonText, CameraStageBaseScreen.skin).setFontColor(Color.WHITE)) pickProductionButton.touchable = Touchable.enabled
productionTextButton.onClick { pickProductionButton.align(Align.left)
cityScreen.city.cityConstructions.currentConstruction = production pickProductionButton.pad(5f)
if(cityScreen.city.cityConstructions.currentConstruction==construction)
pickProductionButton.background = ImageGetter.getBackground(Color.GREEN.cpy().lerp(Color.BLACK,0.5f))
else
pickProductionButton.background = ImageGetter.getBackground(Color.BLACK)
pickProductionButton.add(ImageGetter.getConstructionImage(construction).surroundWithCircle(40f)).padRight(10f)
pickProductionButton.add(Label(buttonText, CameraStageBaseScreen.skin).setFontColor(Color.WHITE))
pickProductionButton.onClick {
cityScreen.city.cityConstructions.currentConstruction = construction
update() update()
} }
if(production==cityScreen.city.cityConstructions.currentConstruction) if(construction==cityScreen.city.cityConstructions.currentConstruction)
productionTextButton.color= Color.GREEN pickProductionButton.color= Color.GREEN
return productionTextButton return pickProductionButton
} }
fun update() { fun update() {
val city = cityScreen.city val city = cityScreen.city
val buttonScale = 0.9f pad(10f)
pad(20f)
columnDefaults(0).padRight(10f) columnDefaults(0).padRight(10f)
clear() clear()
val cityConstructions = city.cityConstructions addConstructionPickerScrollpane(city)
val regularBuildings = VerticalGroup().space(10f) addCurrentConstructionTable(city)
val wonders = VerticalGroup().space(10f)
val units = VerticalGroup().space(10f)
val specials = VerticalGroup().space(10f)
for (unit in GameBasics.Units.values.filter { it.isBuildable(cityConstructions)}) { pack()
units.addActor(getProductionButton(unit.name,
unit.name + "\r\n" + cityConstructions.turnsToConstruction(unit.name) + " {turns}".tr(),
unit.getDescription(true), "Train [${unit.name}]".tr()))
} }
private fun Table.addCategory(title:String,list:ArrayList<Table>){
if(list.isEmpty()) return
val titleTable = Table()
titleTable.background = ImageGetter.getBackground(ImageGetter.getBlue())
titleTable.add(Label(title.tr(),CameraStageBaseScreen.skin))
addSeparator()
add(titleTable).fill().row()
addSeparator()
for(table in list) {
add(table).fill().row()
if(table != list.last()) addSeparator()
}
}
private fun addConstructionPickerScrollpane(city: CityInfo) {
val cityConstructions = city.cityConstructions
val constructionPickerTable = Table()
constructionPickerTable.background = ImageGetter.getBackground(Color.BLACK)
val units = ArrayList<Table>()
for (unit in GameBasics.Units.values.filter { it.isBuildable(cityConstructions) })
units += getProductionButton(unit.name,
unit.name + "\r\n" + cityConstructions.turnsToConstruction(unit.name) + " {turns}".tr())
constructionPickerTable.addCategory("Units",units)
val buildableWonders = ArrayList<Table>()
val buildableBuildings = ArrayList<Table>()
for (building in GameBasics.Buildings.values) { for (building in GameBasics.Buildings.values) {
if (!building.isBuildable(cityConstructions) && building.name != cityConstructions.currentConstruction) continue if (!building.isBuildable(cityConstructions) && building.name != cityConstructions.currentConstruction) continue
val productionTextButton = getProductionButton(building.name, val productionTextButton = getProductionButton(building.name,
building.name + "\r\n" + cityConstructions.turnsToConstruction(building.name) + " {turns}".tr(), building.name + "\r\n" + cityConstructions.turnsToConstruction(building.name) + " {turns}".tr())
building.getDescription(true, city.civInfo.policies.getAdoptedPolicies()),
"Build [${building.name}]".tr())
if (building.isWonder) if (building.isWonder)
wonders.addActor(productionTextButton) buildableWonders += productionTextButton
else else
regularBuildings.addActor(productionTextButton) buildableBuildings += productionTextButton
} }
constructionPickerTable.addCategory("Wonders",buildableWonders)
constructionPickerTable.addCategory("Buildings",buildableBuildings)
val specialConstructions = ArrayList<Table>()
for (specialConstruction in SpecialConstruction.getSpecialConstructions().filter { it.isBuildable(cityConstructions) }) { for (specialConstruction in SpecialConstruction.getSpecialConstructions().filter { it.isBuildable(cityConstructions) }) {
specials.addActor(getProductionButton(specialConstruction.name, "Produce [${specialConstruction.name}]".tr(), specialConstructions += getProductionButton(specialConstruction.name,
specialConstruction.description, "Produce [${specialConstruction.name}]".tr())) "Produce [${specialConstruction.name}]".tr())
} }
constructionPickerTable.addCategory("Other",specialConstructions)
val constructionPickerTable = Table()
constructionPickerTable.add(ExpanderTab("Units".tr(),skin).apply { this.innerTable.add(units) }).row()
constructionPickerTable.add(ExpanderTab("Buildings".tr(),skin).apply { this.innerTable.add(regularBuildings) }).row()
constructionPickerTable.add(ExpanderTab("Wonders".tr(),skin).apply { this.innerTable.add(wonders) }).row()
constructionPickerTable.add(ExpanderTab("Special".tr(),skin).apply { this.innerTable.add(specials) }).row()
val scrollPane = ScrollPane(constructionPickerTable, skin) val scrollPane = ScrollPane(constructionPickerTable, skin)
add(scrollPane).height(cityScreen.stage.height/2).row()
val buildingPickButton = Button(CameraStageBaseScreen.skin) // This is to keep the same amount of scrolling on the construction picker scroll between refresh()es
val buildingText = city.cityConstructions.getCityProductionTextForCityButton() if(constructionScrollPane!=null){
buildingPickButton.add(ImageGetter.getConstructionImage(city.cityConstructions.currentConstruction)) scrollPane.layout()
.size(30f).pad(5f) scrollPane.scrollY = constructionScrollPane!!.scrollY
buildingPickButton.add(Label(buildingText , CameraStageBaseScreen.skin).setFontColor(Color.WHITE)) scrollPane.updateVisualScroll()
buildingPickButton.onClick {
UnCivGame.Current.screen = ConstructionPickerScreen(city)
cityScreen.dispose()
} }
buildingPickButton.pack() constructionScrollPane = scrollPane
add(buildingPickButton).colspan(2).pad(10f) add(scrollPane).height(stage.height / 3).minWidth(stage.width/4).row()
.size(buildingPickButton.width * buttonScale, buildingPickButton.height * buttonScale) }
private fun addCurrentConstructionTable(city: CityInfo) {
// https://forums.civfanatics.com/threads/rush-buying-formula.393892/
val construction = city.cityConstructions.getCurrentConstruction() val construction = city.cityConstructions.getCurrentConstruction()
row()
val purchaseConstructionButton: TextButton
if (construction !is SpecialConstruction && if (construction !is SpecialConstruction &&
!(construction is Building && construction.isWonder)) { !(construction is Building && construction.isWonder)) {
row()
val buildingGoldCost = construction.getGoldCost(city.civInfo.policies.getAdoptedPolicies()) val buildingGoldCost = construction.getGoldCost(city.civInfo.policies.getAdoptedPolicies())
val buildingBuyButton = TextButton("Buy for [$buildingGoldCost] gold".tr(), CameraStageBaseScreen.skin) purchaseConstructionButton = TextButton("Buy for [$buildingGoldCost] gold".tr(), CameraStageBaseScreen.skin)
buildingBuyButton.onClick("coin") { purchaseConstructionButton.onClick("coin") {
city.cityConstructions.purchaseBuilding(city.cityConstructions.currentConstruction) city.cityConstructions.purchaseBuilding(city.cityConstructions.currentConstruction)
update() update()
} }
if (buildingGoldCost > city.civInfo.gold) { if (buildingGoldCost > city.civInfo.gold) {
buildingBuyButton.disable() purchaseConstructionButton.disable()
} }
add(buildingBuyButton).colspan(2).pad(10f) } else {
.size(buildingBuyButton.width * buttonScale, buildingBuyButton.height * buttonScale) purchaseConstructionButton = TextButton("Buy", CameraStageBaseScreen.skin)
purchaseConstructionButton.disable()
}
add(purchaseConstructionButton).pad(10f).row()
val currentConstructionTable = Table()
currentConstructionTable.background = ImageGetter.getBackground(ImageGetter.getBlue().lerp(Color.BLACK,0.5f))
currentConstructionTable.pad(10f)
currentConstructionTable.add(ImageGetter.getConstructionImage(city.cityConstructions.currentConstruction))
.size(30f).pad(5f)
val buildingText = city.cityConstructions.getCityProductionTextForCityButton()
currentConstructionTable.add(Label(buildingText, CameraStageBaseScreen.skin).setFontColor(Color.WHITE)).row()
val currentConstruction = city.cityConstructions.getCurrentConstruction()
val description: String
if (currentConstruction is BaseUnit)
description = currentConstruction.getDescription(true)
else if (currentConstruction is Building)
description = currentConstruction.getDescription(true, city.civInfo.policies.adoptedPolicies)
else description = currentConstruction.description
val descriptionLabel = Label(description, CameraStageBaseScreen.skin)
descriptionLabel.setWrap(true)
descriptionLabel.width = stage.width / 4
val descriptionScroll = ScrollPane(descriptionLabel)
currentConstructionTable.add(descriptionScroll).colspan(2).width(stage.width / 4).height(stage.height / 8)
add(currentConstructionTable.addBorder(2f, Color.WHITE))
} }
setPosition(10f, 10f)
pack()
}
} }

View File

@ -22,7 +22,7 @@ class ExpanderTab(private val title:String,skin: Skin): Table(skin){
if(isOpen) close() if(isOpen) close()
else open() else open()
} }
add(toggle).row() add(toggle).fill().row()
tab.add(innerTable).pad(10f) tab.add(innerTable).pad(10f)
add(tab) add(tab)
} }

View File

@ -147,7 +147,7 @@ fun Actor.addBorder(size:Float,color:Color):Table{
val table = Table() val table = Table()
table.pad(size) table.pad(size)
table.background = ImageGetter.getBackground(color) table.background = ImageGetter.getBackground(color)
table.add(this) table.add(this).fill()
table.pack() table.pack()
return table return table
} }