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()
addConstructionPickerScrollpane(city)
addCurrentConstructionTable(city)
pack()
}
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 cityConstructions = city.cityConstructions
val regularBuildings = VerticalGroup().space(10f)
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)}) {
units.addActor(getProductionButton(unit.name,
unit.name + "\r\n" + cityConstructions.turnsToConstruction(unit.name) + " {turns}".tr(),
unit.getDescription(true), "Train [${unit.name}]".tr()))
}
for (building in GameBasics.Buildings.values) {
if (!building.isBuildable(cityConstructions) && building.name!=cityConstructions.currentConstruction) continue
val productionTextButton = getProductionButton(building.name,
building.name + "\r\n" + cityConstructions.turnsToConstruction(building.name) + " {turns}".tr(),
building.getDescription(true, city.civInfo.policies.getAdoptedPolicies()),
"Build [${building.name}]".tr())
if (building.isWonder)
wonders.addActor(productionTextButton)
else
regularBuildings.addActor(productionTextButton)
}
for(specialConstruction in SpecialConstruction.getSpecialConstructions().filter { it.isBuildable(cityConstructions) }){
specials.addActor(getProductionButton(specialConstruction.name, "Produce [${specialConstruction.name}]".tr(),
specialConstruction.description, "Produce [${specialConstruction.name}]".tr()))
}
val constructionPickerTable = Table() val constructionPickerTable = Table()
constructionPickerTable.add(ExpanderTab("Units".tr(),skin).apply { this.innerTable.add(units) }).row() constructionPickerTable.background = ImageGetter.getBackground(Color.BLACK)
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 units = ArrayList<Table>()
add(scrollPane).height(cityScreen.stage.height/2).row() for (unit in GameBasics.Units.values.filter { it.isBuildable(cityConstructions) })
units += getProductionButton(unit.name,
unit.name + "\r\n" + cityConstructions.turnsToConstruction(unit.name) + " {turns}".tr())
val buildingPickButton = Button(CameraStageBaseScreen.skin) constructionPickerTable.addCategory("Units",units)
val buildingText = city.cityConstructions.getCityProductionTextForCityButton()
buildingPickButton.add(ImageGetter.getConstructionImage(city.cityConstructions.currentConstruction)) val buildableWonders = ArrayList<Table>()
.size(30f).pad(5f) val buildableBuildings = ArrayList<Table>()
buildingPickButton.add(Label(buildingText , CameraStageBaseScreen.skin).setFontColor(Color.WHITE)) for (building in GameBasics.Buildings.values) {
buildingPickButton.onClick { if (!building.isBuildable(cityConstructions) && building.name != cityConstructions.currentConstruction) continue
UnCivGame.Current.screen = ConstructionPickerScreen(city) val productionTextButton = getProductionButton(building.name,
cityScreen.dispose() building.name + "\r\n" + cityConstructions.turnsToConstruction(building.name) + " {turns}".tr())
if (building.isWonder)
buildableWonders += productionTextButton
else
buildableBuildings += productionTextButton
} }
buildingPickButton.pack()
add(buildingPickButton).colspan(2).pad(10f) constructionPickerTable.addCategory("Wonders",buildableWonders)
.size(buildingPickButton.width * buttonScale, buildingPickButton.height * buttonScale) constructionPickerTable.addCategory("Buildings",buildableBuildings)
val specialConstructions = ArrayList<Table>()
for (specialConstruction in SpecialConstruction.getSpecialConstructions().filter { it.isBuildable(cityConstructions) }) {
specialConstructions += getProductionButton(specialConstruction.name,
"Produce [${specialConstruction.name}]".tr())
}
constructionPickerTable.addCategory("Other",specialConstructions)
// https://forums.civfanatics.com/threads/rush-buying-formula.393892/ val scrollPane = ScrollPane(constructionPickerTable, skin)
// This is to keep the same amount of scrolling on the construction picker scroll between refresh()es
if(constructionScrollPane!=null){
scrollPane.layout()
scrollPane.scrollY = constructionScrollPane!!.scrollY
scrollPane.updateVisualScroll()
}
constructionScrollPane = scrollPane
add(scrollPane).height(stage.height / 3).minWidth(stage.width/4).row()
}
private fun addCurrentConstructionTable(city: CityInfo) {
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
} }