diff --git a/android/Images/StatIcons/Specialist.png b/android/Images/StatIcons/Specialist.png new file mode 100644 index 0000000000..7c57a59711 Binary files /dev/null and b/android/Images/StatIcons/Specialist.png differ diff --git a/android/assets/game.atlas b/android/assets/game.atlas index f0d0e5ff65..dee41876e1 100644 --- a/android/assets/game.atlas +++ b/android/assets/game.atlas @@ -391,126 +391,126 @@ BuildingIcons/Spaceship Factory index: -1 BuildingIcons/Stable rotate: false - xy: 1224, 707 + xy: 1122, 605 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Stadium rotate: false - xy: 1122, 605 + xy: 1020, 503 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Stock Exchange rotate: false - xy: 816, 299 + xy: 1632, 1013 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Stone Works rotate: false - xy: 1530, 911 + xy: 1428, 809 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Stonehenge rotate: false - xy: 1428, 809 + xy: 1326, 707 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Sydney Opera House rotate: false - xy: 918, 299 + xy: 1632, 911 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Taj Mahal rotate: false - xy: 1632, 911 + xy: 1530, 809 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Temple rotate: false - xy: 1530, 809 + xy: 1428, 707 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/The Great Library rotate: false - xy: 1428, 707 + xy: 1326, 605 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/The Great Lighthouse rotate: false - xy: 1326, 605 + xy: 1224, 503 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/The Louvre rotate: false - xy: 1224, 503 + xy: 1122, 401 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/The Oracle rotate: false - xy: 1122, 401 + xy: 1020, 299 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/The Pyramids rotate: false - xy: 1020, 299 + xy: 1632, 809 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Theatre rotate: false - xy: 1530, 707 + xy: 1428, 605 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/University rotate: false - xy: 1632, 707 + xy: 1530, 605 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Walls rotate: false - xy: 1428, 503 + xy: 1326, 401 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Windmill rotate: false - xy: 1530, 503 + xy: 1428, 401 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Workshop rotate: false - xy: 1530, 401 + xy: 1428, 299 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -692,7 +692,7 @@ ImprovementIcons/Road index: -1 ImprovementIcons/Trading post rotate: false - xy: 1326, 503 + xy: 1224, 401 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -769,14 +769,14 @@ OtherIcons/Sleep index: -1 OtherIcons/Star rotate: false - xy: 1530, 305 + xy: 1632, 305 size: 100, 94 orig: 100, 94 offset: 0, 0 index: -1 OtherIcons/Stop rotate: false - xy: 1326, 707 + xy: 1224, 605 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -811,133 +811,133 @@ PolicyIcons/Aristocracy index: -1 PolicyIcons/Citizenship rotate: false - xy: 1632, 350 + xy: 1734, 1215 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Civil Society rotate: false - xy: 1734, 1215 + xy: 1734, 1163 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Collective Rule rotate: false - xy: 1734, 1163 + xy: 1734, 1111 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Constitution rotate: false - xy: 1734, 1111 + xy: 1734, 1059 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Democracy rotate: false - xy: 1734, 1059 + xy: 1734, 1007 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Discipline rotate: false - xy: 1734, 1007 + xy: 1734, 955 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Entrepreneurship rotate: false - xy: 1734, 955 + xy: 1734, 903 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Facism rotate: false - xy: 1734, 903 + xy: 1734, 851 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Free Religion rotate: false - xy: 1734, 851 + xy: 1734, 799 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Free Speech rotate: false - xy: 1734, 799 + xy: 1734, 747 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Free Thought rotate: false - xy: 1734, 747 + xy: 1734, 695 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Humanism rotate: false - xy: 1734, 695 + xy: 1734, 643 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Landed Elite rotate: false - xy: 1734, 643 + xy: 1734, 591 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Legalism rotate: false - xy: 1734, 591 + xy: 1734, 539 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Mandate Of Heaven rotate: false - xy: 1734, 539 + xy: 1734, 487 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Mercantilism rotate: false - xy: 1734, 487 + xy: 1734, 435 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Meritocracy rotate: false - xy: 1734, 435 + xy: 1734, 383 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Militarism rotate: false - xy: 1892, 1237 + xy: 1734, 331 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Military Caste rotate: false - xy: 1684, 350 + xy: 1892, 1237 size: 50, 50 orig: 50, 50 offset: 0, 0 @@ -1231,49 +1231,49 @@ ResourceIcons/Silver index: -1 ResourceIcons/Spices rotate: false - xy: 1326, 809 + xy: 1224, 707 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Stone rotate: false - xy: 1632, 1013 + xy: 1530, 911 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Sugar rotate: false - xy: 1122, 503 + xy: 1020, 401 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Uranium rotate: false - xy: 1530, 605 + xy: 1428, 503 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Whales rotate: false - xy: 1224, 299 + xy: 1632, 605 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Wheat rotate: false - xy: 1632, 605 + xy: 1530, 503 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Wine rotate: false - xy: 1428, 401 + xy: 1326, 299 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -1362,9 +1362,16 @@ StatIcons/Science orig: 200, 200 offset: 0, 0 index: -1 +StatIcons/Specialist + rotate: false + xy: 1326, 809 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 StatIcons/Strength rotate: false - xy: 1224, 605 + xy: 1122, 503 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -1798,42 +1805,42 @@ TechIcons/Scientific Theory index: -1 TechIcons/Steam Power rotate: false - xy: 1020, 503 + xy: 918, 401 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Steel rotate: false - xy: 918, 401 + xy: 816, 299 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/The Wheel rotate: false - xy: 1632, 809 + xy: 1530, 707 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Theology rotate: false - xy: 1428, 605 + xy: 1326, 503 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Trapping rotate: false - xy: 1224, 401 + xy: 1122, 299 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Writing rotate: false - xy: 1428, 299 + xy: 1632, 401 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -2071,7 +2078,7 @@ UnitIcons/Musketeer index: -1 UnitIcons/Musketman rotate: false - xy: 1632, 402 + xy: 1530, 300 size: 100, 99 orig: 100, 99 offset: 0, 0 @@ -2113,14 +2120,14 @@ UnitIcons/Spearman index: -1 UnitIcons/Swordsman rotate: false - xy: 1020, 401 + xy: 918, 299 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Trebuchet rotate: false - xy: 1122, 299 + xy: 1632, 707 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -2134,21 +2141,21 @@ UnitIcons/Trireme index: -1 UnitIcons/Warrior rotate: false - xy: 1326, 401 + xy: 1224, 299 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Work Boats rotate: false - xy: 1326, 299 + xy: 1632, 503 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Worker rotate: false - xy: 1632, 503 + xy: 1530, 401 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -2267,175 +2274,175 @@ UnitPromotionIcons/Coastal_Raider_II_(Civ5) index: -1 UnitPromotionIcons/Coastal_Raider_I_(Civ5) rotate: false - xy: 1632, 328 + xy: 1734, 309 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Cover_II_(Civ5) rotate: false - xy: 1734, 413 + xy: 1786, 697 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Cover_I_(Civ5) rotate: false - xy: 1786, 697 + xy: 1838, 749 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Drill_III_(Civ5) rotate: false - xy: 1838, 749 + xy: 226, 1529 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Drill_II_(Civ5) rotate: false - xy: 226, 1529 + xy: 537, 1733 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Drill_I_(Civ5) rotate: false - xy: 537, 1733 + xy: 559, 1755 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Formation_II_(Civ5) rotate: false - xy: 559, 1755 + xy: 2005, 1987 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Formation_I_(Civ5) rotate: false - xy: 2005, 1987 + xy: 1875, 1857 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Indirect_Fire_(Civ5) rotate: false - xy: 1875, 1857 + xy: 1863, 1705 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Logistics_(Civ5) rotate: false - xy: 1863, 1705 + xy: 1885, 1727 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/March_(Civ5) rotate: false - xy: 1885, 1727 + xy: 356, 1263 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Mobility_(Civ5) rotate: false - xy: 356, 1263 + xy: 430, 243 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Range_(Civ5) rotate: false - xy: 430, 243 + xy: 1965, 1653 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Scouting_III_(Civ5) rotate: false - xy: 1965, 1653 + xy: 1987, 1675 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Scouting_II_(Civ5) rotate: false - xy: 1987, 1675 + xy: 1863, 1551 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Scouting_I_(Civ5) rotate: false - xy: 1863, 1551 + xy: 512, 141 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Sentry_(Civ5) rotate: false - xy: 512, 141 + xy: 573, 39 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Shock_III_(Civ5) rotate: false - xy: 573, 39 + xy: 486, 1393 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Shock_II_(Civ5) rotate: false - xy: 486, 1393 + xy: 634, 277 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Shock_I_(Civ5) rotate: false - xy: 634, 277 + xy: 1756, 309 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Siege_(Civ5) rotate: false - xy: 1632, 306 + xy: 1786, 675 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Targeting_III_(Civ5) rotate: false - xy: 1654, 328 + xy: 1808, 697 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Targeting_II_(Civ5) rotate: false - xy: 1756, 413 + xy: 1838, 727 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Targeting_I_(Civ5) rotate: false - xy: 1786, 675 + xy: 1860, 749 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Volley_(Civ5) rotate: false - xy: 1808, 697 + xy: 248, 1529 size: 20, 20 orig: 20, 20 offset: 0, 0 diff --git a/android/assets/game.png b/android/assets/game.png index f37b38d207..3d6e6c7eea 100644 Binary files a/android/assets/game.png and b/android/assets/game.png differ diff --git a/core/src/com/unciv/logic/city/CityConstructions.kt b/core/src/com/unciv/logic/city/CityConstructions.kt index c017bb2a6a..3df65e9d6f 100644 --- a/core/src/com/unciv/logic/city/CityConstructions.kt +++ b/core/src/com/unciv/logic/city/CityConstructions.kt @@ -112,7 +112,7 @@ class CityConstructions { } //endregion - //region state0changing functions + //region state changing functions fun addConstruction(constructionToAdd: Int) { if (!inProgressConstructions.containsKey(currentConstruction)) inProgressConstructions[currentConstruction] = 0 inProgressConstructions[currentConstruction] = inProgressConstructions[currentConstruction]!! + constructionToAdd diff --git a/core/src/com/unciv/logic/city/CityInfo.kt b/core/src/com/unciv/logic/city/CityInfo.kt index e53c4010a7..0714f18ff1 100644 --- a/core/src/com/unciv/logic/city/CityInfo.kt +++ b/core/src/com/unciv/logic/city/CityInfo.kt @@ -124,7 +124,7 @@ class CityInfo { fun getBuildingUniques(): List = cityConstructions.getBuiltBuildings().flatMap { it.uniques } fun getGreatPersonPoints(): Stats { - var greatPersonPoints = population.getSpecialists().times(3f) + var greatPersonPoints = population.specialists.times(3f) for (building in cityConstructions.getBuiltBuildings()) if (building.greatPersonPoints != null) diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index 84bd77f9f5..2b265122ac 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -139,18 +139,20 @@ class CityStats { return newHappinessList } + fun getStatsOfSpecialist(stat:Stat, policies: HashSet): Stats { + val stats = Stats() + if(stat==Stat.Culture||stat==Stat.Science) stats.add(stat,3f) + else stats.add(stat,2f) // science and gold specialists + + if (policies.contains("Commerce Complete")) stats.gold += 1 + if (policies.contains("Secularism")) stats.science += 2 + return stats + } + private fun getStatsFromSpecialists(specialists: Stats, policies: HashSet): Stats { val stats = Stats() - - // Specialists - stats.culture += specialists.culture * 3 - stats.production += specialists.production * 2 - stats.science += specialists.science * 3 - stats.gold += specialists.gold * 2 - val numOfSpecialists = cityInfo.population.getNumberOfSpecialists() - if (policies.contains("Commerce Complete")) stats.gold += numOfSpecialists.toFloat() - if (policies.contains("Secularism")) stats.science += (numOfSpecialists * 2).toFloat() - + for(entry in specialists.toHashMap().filter { it.value>0 }) + stats.add(getStatsOfSpecialist(entry.key,policies)*entry.value) return stats } @@ -242,7 +244,7 @@ class CityStats { newBaseStatList["Population"] = Stats().add(Stat.Science, cityInfo.population.population.toFloat()) .add(Stat.Production, cityInfo.population.getFreePopulation().toFloat()) newBaseStatList["Tile yields"] = getStatsFromTiles() - newBaseStatList["Specialists"] = getStatsFromSpecialists(cityInfo.population.getSpecialists(), civInfo.policies.adoptedPolicies) + newBaseStatList["Specialists"] = getStatsFromSpecialists(cityInfo.population.specialists, civInfo.policies.adoptedPolicies) newBaseStatList["Trade routes"] = getStatsFromTradeRoute() newBaseStatList["Buildings"] = cityInfo.cityConstructions.getStats() newBaseStatList["Policies"] = getStatsFromPolicies(civInfo.policies.adoptedPolicies) diff --git a/core/src/com/unciv/logic/city/PopulationManager.kt b/core/src/com/unciv/logic/city/PopulationManager.kt index 8135ceb6a1..1a37b24ffd 100644 --- a/core/src/com/unciv/logic/city/PopulationManager.kt +++ b/core/src/com/unciv/logic/city/PopulationManager.kt @@ -12,7 +12,9 @@ class PopulationManager { var population = 1 var foodStored = 0 - var buildingsSpecialists = HashMap() + + val specialists = Stats() + //var buildingsSpecialists = HashMap() //region pure functions fun clone(): PopulationManager { @@ -22,15 +24,15 @@ class PopulationManager { return toReturn } - fun getSpecialists(): Stats { - val allSpecialists = Stats() - for (stats in buildingsSpecialists.values) - allSpecialists.add(stats) - return allSpecialists - } +// fun getSpecialists(): Stats { +// val allSpecialists = Stats() +// for (stats in buildingsSpecialists.values) +// allSpecialists.add(stats) +// return allSpecialists +// } fun getNumberOfSpecialists(): Int { - val specialists = getSpecialists() + //val specialists = getSpecialists() return (specialists.science + specialists.production + specialists.culture + specialists.gold).toInt() } @@ -93,6 +95,20 @@ class PopulationManager { .minBy { Automation().rankTile(it, cityInfo.civInfo) }!! cityInfo.workedTiles.remove(lowestRankedWorkedTile.position) } + + // unassign specialists that cannot be (e.g. the city was captured and one of the specialist buildings was destroyed) + val maxSpecialists = getMaxSpecialists().toHashMap() + val specialistsHashmap = specialists.toHashMap() + for(entry in maxSpecialists) + if(specialistsHashmap[entry.key]!!>entry.value) + specialists.add(entry.key,specialistsHashmap[entry.key]!!-maxSpecialists[entry.key]!!) + } + + fun getMaxSpecialists(): Stats { + val maximumSpecialists = Stats() + for (building in cityInfo.cityConstructions.getBuiltBuildings().filter { it.specialistSlots!=null }) + maximumSpecialists.add(building.specialistSlots!!) + return maximumSpecialists } } \ No newline at end of file diff --git a/core/src/com/unciv/ui/EmpireOverviewScreen.kt b/core/src/com/unciv/ui/EmpireOverviewScreen.kt index b0823092e7..3803f454f8 100644 --- a/core/src/com/unciv/ui/EmpireOverviewScreen.kt +++ b/core/src/com/unciv/ui/EmpireOverviewScreen.kt @@ -107,7 +107,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){ private fun getHappinessTable(): Table { val happinessTable = Table(skin) happinessTable.defaults().pad(5f) - happinessTable.add(Label("Happiness".tr(), skin).setFont(24)).colspan(2).row() + happinessTable.add(Label("Happiness".tr(), skin).setFontSize(24)).colspan(2).row() for (entry in civInfo.getHappinessForNextTurn()) { happinessTable.add(entry.key.tr()) happinessTable.add(entry.value.toString()).row() @@ -121,7 +121,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){ private fun getGoldTable(): Table { val goldTable = Table(skin) goldTable.defaults().pad(5f) - goldTable.add(Label("Gold".tr(), skin).setFont(24)).colspan(2).row() + goldTable.add(Label("Gold".tr(), skin).setFontSize(24)).colspan(2).row() var total=0f for (entry in civInfo.getStatMapForNextTurn()) { if(entry.value.gold==0f) continue @@ -142,7 +142,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){ val cityInfoTableIcons = Table(skin) cityInfoTableIcons.defaults().pad(padding).align(Align.center) - cityInfoTableIcons.add(Label("Cities".tr(), skin).setFont(24)).colspan(8).align(Align.center).row() + cityInfoTableIcons.add(Label("Cities".tr(), skin).setFontSize(24)).colspan(8).align(Align.center).row() cityInfoTableIcons.add() cityInfoTableIcons.add(ImageGetter.getStatIcon("Population")).size(iconSize) cityInfoTableIcons.add(ImageGetter.getStatIcon("Food")).size(iconSize) diff --git a/core/src/com/unciv/ui/cityscreen/BuildingsTable.kt b/core/src/com/unciv/ui/cityscreen/BuildingsTable.kt index 0ae5b87716..377e8421ca 100644 --- a/core/src/com/unciv/ui/cityscreen/BuildingsTable.kt +++ b/core/src/com/unciv/ui/cityscreen/BuildingsTable.kt @@ -1,19 +1,46 @@ package com.unciv.ui.cityscreen import com.badlogic.gdx.graphics.Color -import com.badlogic.gdx.scenes.scene2d.ui.Image -import com.badlogic.gdx.scenes.scene2d.ui.Label -import com.badlogic.gdx.scenes.scene2d.ui.Table +import com.badlogic.gdx.scenes.scene2d.ui.* +import com.badlogic.gdx.utils.Align +import com.unciv.logic.city.CityInfo import com.unciv.models.gamebasics.Building import com.unciv.models.stats.Stat import com.unciv.models.stats.Stats -import com.unciv.ui.utils.CameraStageBaseScreen -import com.unciv.ui.utils.ImageGetter.getImage -import com.unciv.ui.utils.onClick -import com.unciv.ui.utils.setFont +import com.unciv.ui.utils.* +class ExpanderTab(private val title:String,skin: Skin):Table(skin){ + private val toggle = Table(skin) // the show/hide toggler + private val tab = Table() // what holds the information to be shown/hidden + val innerTable=Table() // the information itself + + init{ + toggle.defaults().pad(10f) + toggle.background(ImageGetter.getBackground(ImageGetter.getBlue())) + toggle.add("+ $title").apply { actor.setFontSize(24) } + toggle.onClick { + toggle.clearChildren() + if(tab.isVisible) { + toggle.add("- $title").apply { actor.setFontSize(24) } + tab.clear() + } + else { + toggle.add("+ $title").apply { actor.setFontSize(24) } + tab.add(innerTable) + } + tab.isVisible=!tab.isVisible + } + add(toggle).row() + tab.add(innerTable) + add(tab) + } +} + class BuildingsTable(private val cityScreen: CityScreen) : Table() { + init { + defaults().pad(10f) + } internal fun update() { clear() @@ -31,69 +58,109 @@ class BuildingsTable(private val cityScreen: CityScreen) : Table() { } } - fun createLabel(text:String): Label { - val label = Label(text, skin) - label.setFont(20) - label.color = Color.GREEN - return label - } - if (!wonders.isEmpty()) { - - add(createLabel("Wonders")).pad(5f).row() + val wondersExpander = ExpanderTab("Wonders",skin) for (building in wonders) - add(Label(building.name, skin)).pad(5f).row() + wondersExpander.innerTable.add(Label(building.name, skin)).pad(5f).align(Align.left).row() + add(wondersExpander).row() } if (!specialistBuildings.isEmpty()) { - add(createLabel("Specialist Buildings")).pad(5f).row() + val specialistBuildingsExpander = ExpanderTab("Specialist Buildings",skin) for (building in specialistBuildings) { - add(Label(building.name, skin)).pad(5f) - val specialists = Table() - specialists.row().size(20f).pad(5f) - if (!cityInfo.population.buildingsSpecialists.containsKey(building.name)) - cityInfo.population.buildingsSpecialists[building.name] = Stats() - val currentBuildingSpecialists = cityInfo.population.buildingsSpecialists[building.name]!!.toHashMap() - for(stat in Stat.values()){ - for (i in 1..(currentBuildingSpecialists[stat]!!).toInt()) { - specialists.add(getSpecialistIcon( - "StatIcons/${stat}Specialist.png", building.name, - currentBuildingSpecialists[stat]!! > i, stat)) - } - } + specialistBuildingsExpander.innerTable.add(Label(building.name, skin)).pad(5f) + val specialistIcons = Table() + specialistIcons.row().size(20f).pad(5f) + for(stat in building.specialistSlots!!.toHashMap()) + for(i in 0 until stat.value.toInt()) + specialistIcons.add(getSpecialistIcon(stat.key)).size(20f) - add(specialists).row() + specialistBuildingsExpander.innerTable.add(specialistIcons).row() } + add(specialistBuildingsExpander).row() + + // specialist allocation + addSpecialistAllocation(skin, specialistBuildings, cityInfo) } if (!others.isEmpty()) { - add(createLabel("Buildings")).pad(5f).row() + val buildingsExpanderTab = ExpanderTab("Buildings",skin) for (building in others) - add(Label(building.name, skin)).pad(5f).row() + buildingsExpanderTab.innerTable.add(Label(building.name, skin)).pad(5f).row() + add(buildingsExpanderTab).row() } pack() } + private fun addSpecialistAllocation(skin: Skin, specialistBuildings: MutableList, cityInfo: CityInfo) { + val specialistAllocationExpander = ExpanderTab("Specialist allocation", skin) + specialistAllocationExpander.innerTable.defaults().pad(5f) - private fun getSpecialistIcon(imageName: String, building: String, isFilled: Boolean, stat: Stat): Image { - val specialist = getImage(imageName) - specialist.setSize(50f, 50f) - if (!isFilled) specialist.color = Color.GRAY - specialist.onClick( { - val cityInfo = cityScreen.city - when { - isFilled -> cityInfo.population.buildingsSpecialists[building]!!.add(stat,-1f) //unassign - cityInfo.population.getFreePopulation() == 0 -> return@onClick - else -> { - if (!cityInfo.population.buildingsSpecialists.containsKey(building)) - cityInfo.population.buildingsSpecialists[building] = Stats() - cityInfo.population.buildingsSpecialists[building]!!.add(stat,1f) //assign!} + + val currentSpecialists = cityInfo.population.specialists.toHashMap() + val maximumSpecialists = cityInfo.population.getMaxSpecialists() + + for (entry in maximumSpecialists.toHashMap()) { + if (entry.value == 0f) continue + val stat = entry.key + // these two are conflictingly named compared to above... + val assignedSpecialists = currentSpecialists[entry.key]!!.toInt() + val maxSpecialists = entry.value.toInt() + if (assignedSpecialists > 0) { + val unassignButton = TextButton("-", skin) + unassignButton.label.setFontSize(24) + unassignButton.onClick { + cityInfo.population.specialists.add(entry.key, -1f) + cityInfo.cityStats.update() + cityScreen.update() } - } + specialistAllocationExpander.innerTable.add(unassignButton) + } else specialistAllocationExpander.innerTable.add() - cityInfo.cityStats.update() - cityScreen.update() - }) + val specialistTable = Table() + for (i in 1..maxSpecialists) { + val icon = getSpecialistIcon(stat, i <= assignedSpecialists) + specialistTable.add(icon).size(30f) + } + specialistAllocationExpander.innerTable.add(specialistTable) + if (assignedSpecialists < maxSpecialists) { + val assignButton = TextButton("+", skin) + assignButton.label.setFontSize(24) + assignButton.onClick { + cityInfo.population.specialists.add(entry.key, +1f) + cityInfo.cityStats.update() + cityScreen.update() + } + if (cityInfo.population.getFreePopulation() == 0) assignButton.disable() + specialistAllocationExpander.innerTable.add(assignButton) + } else specialistAllocationExpander.innerTable.add() + + specialistAllocationExpander.innerTable.row() + + val specialistStatTable = Table().apply { defaults().pad(5f) } + val specialistStats = cityInfo.cityStats.getStatsOfSpecialist(stat, cityInfo.civInfo.policies.adoptedPolicies).toHashMap() + for (entry in specialistStats) { + if (entry.value == 0f) continue + specialistStatTable.add(ImageGetter.getStatIcon(entry.key.toString())).size(20f) + specialistStatTable.add(Label(entry.value.toInt().toString(), skin)).padRight(10f) + } + specialistAllocationExpander.innerTable.add() + specialistAllocationExpander.innerTable.add(specialistStatTable).row() + } + add(specialistAllocationExpander).row() + } + + + private fun getSpecialistIcon(stat: Stat, isFilled: Boolean =true): Image { + val specialist = ImageGetter.getImage("StatIcons/Specialist") + if (!isFilled) specialist.color = Color.GRAY + else specialist.color=when(stat){ + Stat.Production -> Color.BROWN + Stat.Gold -> Color.GOLD + Stat.Science -> Color.BLUE + Stat.Culture -> Color.PURPLE + else -> Color.WHITE + } return specialist } diff --git a/core/src/com/unciv/ui/cityscreen/CityScreen.kt b/core/src/com/unciv/ui/cityscreen/CityScreen.kt index 29f14f0493..d855dba048 100644 --- a/core/src/com/unciv/ui/cityscreen/CityScreen.kt +++ b/core/src/com/unciv/ui/cityscreen/CityScreen.kt @@ -140,7 +140,7 @@ class CityScreen(internal val city: CityInfo) : CameraStageBaseScreen() { } val currentCityLabel = Label(city.name+" ("+city.population.population+")", CameraStageBaseScreen.skin) - currentCityLabel.setFont(25) + currentCityLabel.setFontSize(25) cityPickerTable.add(currentCityLabel) diff --git a/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt b/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt index aab32032ea..84e40c4324 100644 --- a/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt +++ b/core/src/com/unciv/ui/cityscreen/CityStatsTable.kt @@ -24,7 +24,7 @@ class CityStatsTable(val cityScreen: CityScreen) : Table(){ val cityStatsHeader = Label("City Stats", CameraStageBaseScreen.skin) - cityStatsHeader.setFont(15) + cityStatsHeader.setFontSize(15) add(cityStatsHeader).colspan(2).pad(10f) row() diff --git a/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt b/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt index 215f9b1efe..793c1ca431 100644 --- a/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt +++ b/core/src/com/unciv/ui/tilegroups/WorldTileGroup.kt @@ -154,7 +154,7 @@ class WorldTileGroup(tileInfo: TileInfo) : TileGroup(tileInfo) { val turnsToConstruction = cityConstructions.turnsToConstruction(cityConstructions.currentConstruction) val label = Label(turnsToConstruction.toString(),CameraStageBaseScreen.skin) label.setFontColor(secondaryColor) - label.setFont(10) + label.setFontSize(10) label.pack() group.addActor(label) diff --git a/core/src/com/unciv/ui/trade/DiplomacyScreen.kt b/core/src/com/unciv/ui/trade/DiplomacyScreen.kt index 5e2362d68f..87c7c96443 100644 --- a/core/src/com/unciv/ui/trade/DiplomacyScreen.kt +++ b/core/src/com/unciv/ui/trade/DiplomacyScreen.kt @@ -41,7 +41,7 @@ class DiplomacyScreen():CameraStageBaseScreen(){ civTable.defaults().pad(10f) val peaceWarStatus = civDiplomacy.diplomaticStatus.toString() civTable.add(Label(civ.civName.tr() + " ({$peaceWarStatus})".tr(), skin) - .apply { setFont(22); setFontColor(civ.getNation().getSecondaryColor()) }).row() + .apply { setFontSize(22); setFontColor(civ.getNation().getSecondaryColor()) }).row() val tradeButton = TextButton("Trade".tr(), skin) tradeButton.onClick { diff --git a/core/src/com/unciv/ui/utils/CameraStageBaseScreen.kt b/core/src/com/unciv/ui/utils/CameraStageBaseScreen.kt index 3e32dd3171..0613b66015 100644 --- a/core/src/com/unciv/ui/utils/CameraStageBaseScreen.kt +++ b/core/src/com/unciv/ui/utils/CameraStageBaseScreen.kt @@ -175,7 +175,7 @@ fun getFont(size: Int): BitmapFont { return font } -fun Label.setFont(size:Int): Label { +fun Label.setFontSize(size:Int): Label { style = Label.LabelStyle(style) style.font = getFont(size) style = style // because we need it to call the SetStyle function. Yuk, I know. diff --git a/core/src/com/unciv/ui/worldscreen/NotificationsScroll.kt b/core/src/com/unciv/ui/worldscreen/NotificationsScroll.kt index 11a0dda313..ce1bf521ed 100644 --- a/core/src/com/unciv/ui/worldscreen/NotificationsScroll.kt +++ b/core/src/com/unciv/ui/worldscreen/NotificationsScroll.kt @@ -19,7 +19,7 @@ class NotificationsScroll(internal val worldScreen: WorldScreen) : ScrollPane(nu notificationsTable.clearChildren() for (notification in notifications) { val label = Label(notification.text.tr(), CameraStageBaseScreen.skin).setFontColor(Color.BLACK) - .setFont(14) + .setFontSize(14) val minitable = Table() minitable.add(ImageGetter.getImage("OtherIcons/Circle.png") diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt index f46285d48a..eea2fb9c76 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt @@ -174,7 +174,7 @@ class WorldScreen : CameraStageBaseScreen() { if (civInfo.tech.currentTechnology() == null) { val buttonPic = Table().apply { background = ImageGetter.getDrawable("OtherIcons/civTableBackground.png").tint(colorFromRGB(7, 46, 43)); defaults().pad(10f) } - buttonPic.add(Label("{Pick a tech}!".tr(), skin).setFontColor(Color.WHITE).setFont(22)) + buttonPic.add(Label("{Pick a tech}!".tr(), skin).setFontColor(Color.WHITE).setFontSize(22)) techButton.add(buttonPic) } else { diff --git a/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt b/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt index c0eb55ca5c..3fee95a153 100644 --- a/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt +++ b/core/src/com/unciv/ui/worldscreen/bottombar/BattleTable.kt @@ -74,8 +74,8 @@ class BattleTable(val worldScreen: WorldScreen): Table() { else listOf() for(i in 0..max(attackerModifiers.size,defenderModifiers.size)){ - if (attackerModifiers.size > i) add(attackerModifiers[i]).actor.setFont(14) else add() - if (defenderModifiers.size > i) add(defenderModifiers[i]).actor.setFont(14) else add() + if (attackerModifiers.size > i) add(attackerModifiers[i]).actor.setFontSize(14) else add() + if (defenderModifiers.size > i) add(defenderModifiers[i]).actor.setFontSize(14) else add() row().pad(2f) }