Rework of City Screen: new Great People list + misc changes (#8180)
* Rework of City Screen: new Great People list + misc changes * Added a bit of padding * Buildings are united under one tabs, GP font icons replaced by tinted UnitIcons * Fix color of separators * Big update to "Detailed stats" UI * Rebuild pngs Co-authored-by: tunerzinc@gmail.com <vfylfhby> Co-authored-by: Yair Morgenstern <yairm210@hotmail.com>
BIN
android/Images/EmojiIcons/Great Artist.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
android/Images/EmojiIcons/Great Engineer.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
android/Images/EmojiIcons/Great General.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
android/Images/EmojiIcons/Great Merchant.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
android/Images/EmojiIcons/Great Scientist.png
Normal file
After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 750 KiB After Width: | Height: | Size: 761 KiB |
@ -41,56 +41,91 @@ CityStateIcons/Religious
|
|||||||
index: -1
|
index: -1
|
||||||
EmojiIcons/Culture
|
EmojiIcons/Culture
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1270, 1122
|
xy: 1918, 1770
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
EmojiIcons/Faith
|
EmojiIcons/Faith
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1378, 1230
|
xy: 1270, 1020
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
EmojiIcons/Food
|
EmojiIcons/Food
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1486, 1344
|
xy: 1378, 1122
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
EmojiIcons/Gold
|
EmojiIcons/Gold
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1594, 1452
|
xy: 1486, 1230
|
||||||
|
size: 50, 50
|
||||||
|
orig: 50, 50
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
EmojiIcons/Great Artist
|
||||||
|
rotate: false
|
||||||
|
xy: 1594, 1338
|
||||||
|
size: 50, 50
|
||||||
|
orig: 50, 50
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
EmojiIcons/Great Engineer
|
||||||
|
rotate: false
|
||||||
|
xy: 1702, 1446
|
||||||
|
size: 50, 50
|
||||||
|
orig: 50, 50
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
EmojiIcons/Great General
|
||||||
|
rotate: false
|
||||||
|
xy: 356, 720
|
||||||
|
size: 50, 50
|
||||||
|
orig: 50, 50
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
EmojiIcons/Great Merchant
|
||||||
|
rotate: false
|
||||||
|
xy: 1004, 906
|
||||||
|
size: 50, 50
|
||||||
|
orig: 50, 50
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
EmojiIcons/Great Scientist
|
||||||
|
rotate: false
|
||||||
|
xy: 1810, 1604
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
EmojiIcons/Happiness
|
EmojiIcons/Happiness
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1702, 1554
|
xy: 1976, 1770
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
EmojiIcons/Production
|
EmojiIcons/Production
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 414, 720
|
xy: 588, 720
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
EmojiIcons/Science
|
EmojiIcons/Science
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 530, 720
|
xy: 762, 720
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
EmojiIcons/Turn
|
EmojiIcons/Turn
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 762, 720
|
xy: 1868, 1546
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -265,70 +300,70 @@ ImprovementIcons/Railroad
|
|||||||
index: -1
|
index: -1
|
||||||
ImprovementIcons/Remove Fallout
|
ImprovementIcons/Remove Fallout
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 250, 0
|
xy: 1054, 1504
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ImprovementIcons/Remove Forest
|
ImprovementIcons/Remove Forest
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 350, 0
|
xy: 1162, 1612
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ImprovementIcons/Remove Jungle
|
ImprovementIcons/Remove Jungle
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 350, 0
|
xy: 1162, 1612
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ImprovementIcons/Remove Marsh
|
ImprovementIcons/Remove Marsh
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 450, 0
|
xy: 838, 1187
|
||||||
size: 100, 100
|
size: 100, 99
|
||||||
orig: 100, 100
|
orig: 100, 99
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ImprovementIcons/Remove Railroad
|
ImprovementIcons/Remove Railroad
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 550, 0
|
xy: 946, 1288
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ImprovementIcons/Remove Road
|
ImprovementIcons/Remove Road
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 650, 0
|
xy: 1054, 1396
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ImprovementIcons/Repair
|
ImprovementIcons/Repair
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1270, 1720
|
xy: 1270, 1612
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ImprovementIcons/Road
|
ImprovementIcons/Road
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1162, 1504
|
xy: 1054, 1288
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ImprovementIcons/Terrace farm
|
ImprovementIcons/Terrace farm
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1378, 1396
|
xy: 1162, 1078
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ImprovementIcons/Trading post
|
ImprovementIcons/Trading post
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1594, 1618
|
xy: 1378, 1288
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -403,13 +438,6 @@ StatIcons/Science
|
|||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/ConvertScience
|
|
||||||
rotate: false
|
|
||||||
xy: 622, 886
|
|
||||||
size: 100, 100
|
|
||||||
orig: 100, 100
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
OtherIcons/AirSweep
|
OtherIcons/AirSweep
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 4, 369
|
xy: 4, 369
|
||||||
@ -433,28 +461,28 @@ OtherIcons/Aircraft
|
|||||||
index: -1
|
index: -1
|
||||||
OtherIcons/ArrowRight
|
OtherIcons/ArrowRight
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 838, 804
|
xy: 838, 805
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
NotificationIcons/MoveAutomatedUnits
|
NotificationIcons/MoveAutomatedUnits
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 838, 804
|
xy: 838, 805
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
NotificationIcons/NextUnit
|
NotificationIcons/NextUnit
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 838, 804
|
xy: 838, 805
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
StatIcons/Movement
|
StatIcons/Movement
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 838, 804
|
xy: 838, 805
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -475,7 +503,7 @@ OtherIcons/Banner
|
|||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Camera
|
OtherIcons/Camera
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 896, 829
|
xy: 1270, 987
|
||||||
size: 25, 25
|
size: 25, 25
|
||||||
orig: 25, 25
|
orig: 25, 25
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -517,7 +545,7 @@ OtherIcons/Cities
|
|||||||
index: -1
|
index: -1
|
||||||
OtherIcons/CityState
|
OtherIcons/CityState
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1162, 1014
|
xy: 1810, 1662
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -587,21 +615,14 @@ OtherIcons/Hexagon
|
|||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Improvements
|
OtherIcons/Improvements
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1918, 1770
|
xy: 1062, 906
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Unique
|
|
||||||
rotate: false
|
|
||||||
xy: 1921, 1655
|
|
||||||
size: 100, 100
|
|
||||||
orig: 100, 100
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
OtherIcons/Link
|
OtherIcons/Link
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1004, 906
|
xy: 472, 720
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -671,7 +692,7 @@ OtherIcons/Multiplayer
|
|||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Nations
|
OtherIcons/Nations
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1976, 1770
|
xy: 530, 720
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -783,140 +804,140 @@ OtherIcons/Quickstart
|
|||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Remove Heresy
|
OtherIcons/Remove Heresy
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1054, 1504
|
xy: 1270, 1720
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Resources
|
OtherIcons/Resources
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 946, 1288
|
xy: 838, 1079
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Resume
|
OtherIcons/Resume
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1054, 1396
|
xy: 946, 1180
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Search
|
OtherIcons/Search
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1378, 1720
|
xy: 1270, 1504
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/SecretOptions
|
OtherIcons/SecretOptions
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 838, 1078
|
xy: 1378, 1612
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Settings
|
OtherIcons/Settings
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1054, 1288
|
xy: 838, 971
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Shield
|
OtherIcons/Shield
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1270, 1504
|
xy: 1054, 1180
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Sleep
|
OtherIcons/Sleep
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 838, 970
|
xy: 1378, 1504
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
UnitActionIcons/Sleep
|
UnitActionIcons/Sleep
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 838, 970
|
xy: 1378, 1504
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Speaker
|
OtherIcons/Speaker
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 946, 1072
|
xy: 1486, 1612
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Spy
|
OtherIcons/Spy
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1270, 1396
|
xy: 946, 964
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Spy_White
|
OtherIcons/Spy_White
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1378, 1504
|
xy: 1054, 1072
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Star
|
OtherIcons/Star
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1486, 1618
|
xy: 1162, 1186
|
||||||
size: 100, 94
|
size: 100, 94
|
||||||
orig: 100, 94
|
orig: 100, 94
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Stop
|
OtherIcons/Stop
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1054, 1072
|
xy: 1594, 1612
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
UnitActionIcons/Stop
|
UnitActionIcons/Stop
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1054, 1072
|
xy: 1594, 1612
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
UnitActionIcons/StopMove
|
UnitActionIcons/StopMove
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1054, 1072
|
xy: 1594, 1612
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Swap
|
OtherIcons/Swap
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1270, 1288
|
xy: 1054, 964
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
UnitActionIcons/Swap
|
UnitActionIcons/Swap
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1270, 1288
|
xy: 1054, 964
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Terrains
|
OtherIcons/Terrains
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 704, 720
|
xy: 1868, 1604
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Timer
|
OtherIcons/Timer
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1486, 1510
|
xy: 1270, 1186
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -930,35 +951,42 @@ OtherIcons/Triangle
|
|||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Turn right
|
OtherIcons/Turn right
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1054, 964
|
xy: 1594, 1504
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Tyrannosaurus
|
OtherIcons/Tyrannosaurus
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1162, 1072
|
xy: 1702, 1612
|
||||||
|
size: 100, 100
|
||||||
|
orig: 100, 100
|
||||||
|
offset: 0, 0
|
||||||
|
index: -1
|
||||||
|
OtherIcons/Unique
|
||||||
|
rotate: false
|
||||||
|
xy: 1810, 1720
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Wait
|
OtherIcons/Wait
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1378, 1288
|
xy: 1270, 1078
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
UnitActionIcons/Wait
|
UnitActionIcons/Wait
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1378, 1288
|
xy: 1270, 1078
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/Wonders
|
OtherIcons/Wonders
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1810, 1720
|
xy: 1702, 1504
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -1133,84 +1161,84 @@ ResourceIcons/Porcelain
|
|||||||
index: -1
|
index: -1
|
||||||
ResourceIcons/Salt
|
ResourceIcons/Salt
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1270, 1612
|
xy: 1162, 1396
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ResourceIcons/Sheep
|
ResourceIcons/Sheep
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1162, 1396
|
xy: 946, 1072
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ResourceIcons/Silk
|
ResourceIcons/Silk
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1378, 1612
|
xy: 1162, 1288
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ResourceIcons/Silver
|
ResourceIcons/Silver
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1486, 1720
|
xy: 1270, 1396
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ResourceIcons/Spices
|
ResourceIcons/Spices
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1162, 1288
|
xy: 838, 863
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ResourceIcons/Stone
|
ResourceIcons/Stone
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 946, 964
|
xy: 1486, 1504
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ResourceIcons/Sugar
|
ResourceIcons/Sugar
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1162, 1180
|
xy: 1702, 1720
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ResourceIcons/Truffles
|
ResourceIcons/Truffles
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1702, 1720
|
xy: 1486, 1396
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ResourceIcons/Uranium
|
ResourceIcons/Uranium
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1270, 1180
|
xy: 1162, 970
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ResourceIcons/Whales
|
ResourceIcons/Whales
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1486, 1402
|
xy: 1378, 1180
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ResourceIcons/Wheat
|
ResourceIcons/Wheat
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1594, 1510
|
xy: 1486, 1288
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
ResourceIcons/Wine
|
ResourceIcons/Wine
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1702, 1612
|
xy: 1594, 1396
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -1250,20 +1278,6 @@ StatIcons/Gold
|
|||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
OtherIcons/ConvertGold
|
|
||||||
rotate: false
|
|
||||||
xy: 298, 1426
|
|
||||||
size: 100, 100
|
|
||||||
orig: 100, 100
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
OtherIcons/ConvertNothing
|
|
||||||
rotate: false
|
|
||||||
xy: 1923, 1545
|
|
||||||
size: 100, 100
|
|
||||||
orig: 100, 100
|
|
||||||
offset: 0, 0
|
|
||||||
index: -1
|
|
||||||
StatIcons/Happiness
|
StatIcons/Happiness
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 514, 1642
|
xy: 514, 1642
|
||||||
@ -1273,7 +1287,7 @@ StatIcons/Happiness
|
|||||||
index: -1
|
index: -1
|
||||||
StatIcons/InterceptRange
|
StatIcons/InterceptRange
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 356, 720
|
xy: 1810, 1546
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -1294,14 +1308,14 @@ StatIcons/Population
|
|||||||
index: -1
|
index: -1
|
||||||
StatIcons/Range
|
StatIcons/Range
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1062, 906
|
xy: 646, 720
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
StatIcons/RangedStrength
|
StatIcons/RangedStrength
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 472, 720
|
xy: 704, 720
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -1315,21 +1329,21 @@ StatIcons/ReligiousStrength
|
|||||||
index: -1
|
index: -1
|
||||||
StatIcons/Resistance
|
StatIcons/Resistance
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 838, 1186
|
xy: 1378, 1720
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
StatIcons/Specialist
|
StatIcons/Specialist
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1054, 1180
|
xy: 1594, 1720
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
StatIcons/Strength
|
StatIcons/Strength
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 646, 720
|
xy: 1868, 1662
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -1420,7 +1434,7 @@ UnitActionIcons/FoundCity
|
|||||||
index: -1
|
index: -1
|
||||||
UnitActionIcons/HideMore
|
UnitActionIcons/HideMore
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1810, 1662
|
xy: 414, 720
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
@ -1455,35 +1469,35 @@ UnitActionIcons/Upgrade
|
|||||||
index: -1
|
index: -1
|
||||||
UnitActionIcons/RemoveHeresy
|
UnitActionIcons/RemoveHeresy
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1162, 1612
|
xy: 1162, 1504
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
UnitActionIcons/SetUp
|
UnitActionIcons/SetUp
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 946, 1180
|
xy: 1486, 1720
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
UnitActionIcons/ShowMore
|
UnitActionIcons/ShowMore
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 588, 720
|
xy: 896, 805
|
||||||
size: 50, 50
|
size: 50, 50
|
||||||
orig: 50, 50
|
orig: 50, 50
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
UnitActionIcons/Star
|
UnitActionIcons/Star
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 1594, 1726
|
xy: 1270, 1294
|
||||||
size: 100, 94
|
size: 100, 94
|
||||||
orig: 100, 94
|
orig: 100, 94
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
index: -1
|
index: -1
|
||||||
UnitActionIcons/StartGoldenAge
|
UnitActionIcons/StartGoldenAge
|
||||||
rotate: false
|
rotate: false
|
||||||
xy: 838, 862
|
xy: 1378, 1396
|
||||||
size: 100, 100
|
size: 100, 100
|
||||||
orig: 100, 100
|
orig: 100, 100
|
||||||
offset: 0, 0
|
offset: 0, 0
|
||||||
|
Before Width: | Height: | Size: 520 KiB After Width: | Height: | Size: 579 KiB |
@ -24,6 +24,11 @@ class StatTreeNode {
|
|||||||
val children = LinkedHashMap<String, StatTreeNode>()
|
val children = LinkedHashMap<String, StatTreeNode>()
|
||||||
private var innerStats: Stats? = null
|
private var innerStats: Stats? = null
|
||||||
|
|
||||||
|
fun setInnerStat(stat: Stat, value: Float) {
|
||||||
|
if (innerStats == null) innerStats = Stats()
|
||||||
|
innerStats!![stat] = value
|
||||||
|
}
|
||||||
|
|
||||||
private fun addInnerStats(stats: Stats) {
|
private fun addInnerStats(stats: Stats) {
|
||||||
if (innerStats == null) innerStats = stats.clone() // Copy the stats instead of referencing them
|
if (innerStats == null) innerStats = stats.clone() // Copy the stats instead of referencing them
|
||||||
else innerStats!!.add(stats) // What happens if we add 2 stats to the same leaf?
|
else innerStats!!.add(stats) // What happens if we add 2 stats to the same leaf?
|
||||||
@ -48,6 +53,13 @@ class StatTreeNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun clone() : StatTreeNode {
|
||||||
|
val new = StatTreeNode()
|
||||||
|
new.innerStats = this.innerStats?.clone()
|
||||||
|
new.children.putAll(this.children)
|
||||||
|
return new
|
||||||
|
}
|
||||||
|
|
||||||
val totalStats: Stats
|
val totalStats: Stats
|
||||||
get() {
|
get() {
|
||||||
val toReturn = Stats()
|
val toReturn = Stats()
|
||||||
|
@ -82,6 +82,13 @@ class CityScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val detailedStatsButton = "Stats".toTextButton().apply {
|
||||||
|
labelCell.pad(10f)
|
||||||
|
onActivation {
|
||||||
|
DetailedStatsPopup(this@CityScreen).open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Holds City tiles group*/
|
/** Holds City tiles group*/
|
||||||
private var tileGroups = ArrayList<CityTileGroup>()
|
private var tileGroups = ArrayList<CityTileGroup>()
|
||||||
|
|
||||||
@ -127,6 +134,7 @@ class CityScreen(
|
|||||||
stage.addActor(tileTable)
|
stage.addActor(tileTable)
|
||||||
stage.addActor(cityPickerTable) // add late so it's top in Z-order and doesn't get covered in cramped portrait
|
stage.addActor(cityPickerTable) // add late so it's top in Z-order and doesn't get covered in cramped portrait
|
||||||
stage.addActor(exitCityButton)
|
stage.addActor(exitCityButton)
|
||||||
|
stage.addActor(detailedStatsButton)
|
||||||
update()
|
update()
|
||||||
|
|
||||||
globalShortcuts.add(Input.Keys.LEFT) { page(-1) }
|
globalShortcuts.add(Input.Keys.LEFT) { page(-1) }
|
||||||
@ -173,6 +181,8 @@ class CityScreen(
|
|||||||
cityStatsTable.update(statsHeight)
|
cityStatsTable.update(statsHeight)
|
||||||
cityStatsTable.setPosition(stage.width - posFromEdge, stage.height - posFromEdge, Align.topRight)
|
cityStatsTable.setPosition(stage.width - posFromEdge, stage.height - posFromEdge, Align.topRight)
|
||||||
|
|
||||||
|
detailedStatsButton.setPosition(cityStatsTable.x - detailedStatsButton.width, stage.height - 20f, Align.top)
|
||||||
|
|
||||||
// Top center: Annex/Raze button
|
// Top center: Annex/Raze button
|
||||||
updateAnnexAndRazeCityButton()
|
updateAnnexAndRazeCityButton()
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color
|
|||||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Cell
|
import com.badlogic.gdx.scenes.scene2d.ui.Cell
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Image
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
import com.badlogic.gdx.utils.Align
|
import com.badlogic.gdx.utils.Align
|
||||||
@ -25,12 +26,17 @@ import com.unciv.ui.utils.BaseScreen
|
|||||||
import com.unciv.ui.utils.ExpanderTab
|
import com.unciv.ui.utils.ExpanderTab
|
||||||
import com.unciv.ui.utils.Fonts
|
import com.unciv.ui.utils.Fonts
|
||||||
import com.unciv.ui.utils.extensions.addSeparator
|
import com.unciv.ui.utils.extensions.addSeparator
|
||||||
|
import com.unciv.ui.utils.extensions.center
|
||||||
import com.unciv.ui.utils.extensions.colorFromRGB
|
import com.unciv.ui.utils.extensions.colorFromRGB
|
||||||
import com.unciv.ui.utils.extensions.onClick
|
import com.unciv.ui.utils.extensions.onClick
|
||||||
|
import com.unciv.ui.utils.extensions.setSize
|
||||||
import com.unciv.ui.utils.extensions.surroundWithCircle
|
import com.unciv.ui.utils.extensions.surroundWithCircle
|
||||||
|
import com.unciv.ui.utils.extensions.toGroup
|
||||||
import com.unciv.ui.utils.extensions.toLabel
|
import com.unciv.ui.utils.extensions.toLabel
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
import kotlin.math.round
|
import kotlin.math.round
|
||||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||||
|
|
||||||
@ -103,15 +109,13 @@ class CityStatsTable(val cityScreen: CityScreen): Table() {
|
|||||||
|
|
||||||
// begin lowerTable
|
// begin lowerTable
|
||||||
addCitizenManagement()
|
addCitizenManagement()
|
||||||
|
addGreatPersonPointInfo(cityInfo)
|
||||||
if (!cityInfo.population.getMaxSpecialists().isEmpty()) {
|
if (!cityInfo.population.getMaxSpecialists().isEmpty()) {
|
||||||
addSpecialistInfo()
|
addSpecialistInfo()
|
||||||
}
|
}
|
||||||
if (cityInfo.religion.getNumberOfFollowers().isNotEmpty() && cityInfo.civInfo.gameInfo.isReligionEnabled())
|
if (cityInfo.religion.getNumberOfFollowers().isNotEmpty() && cityInfo.civInfo.gameInfo.isReligionEnabled())
|
||||||
addReligionInfo()
|
addReligionInfo()
|
||||||
|
|
||||||
|
|
||||||
addStatInfo()
|
|
||||||
addGreatPersonPointInfo(cityInfo)
|
|
||||||
addBuildingsInfo()
|
addBuildingsInfo()
|
||||||
|
|
||||||
upperTable.pack()
|
upperTable.pack()
|
||||||
@ -221,22 +225,40 @@ class CityStatsTable(val cityScreen: CityScreen): Table() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Buildings sorted alphabetically
|
||||||
|
wonders.sortBy { it.name }
|
||||||
|
specialistBuildings.sortBy { it.name }
|
||||||
|
otherBuildings.sortBy { it.name }
|
||||||
|
|
||||||
|
val totalTable = Table()
|
||||||
|
lowerTable.addCategory("Buildings", totalTable, false)
|
||||||
|
|
||||||
if (specialistBuildings.isNotEmpty()) {
|
if (specialistBuildings.isNotEmpty()) {
|
||||||
val specialistBuildingsTable = Table()
|
val specialistBuildingsTable = Table()
|
||||||
addCategory("Specialist Buildings", specialistBuildingsTable)
|
totalTable.add().row()
|
||||||
|
totalTable.addSeparator(color = Color.LIGHT_GRAY)
|
||||||
|
totalTable.add("Specialist Buildings".toLabel().apply { setAlignment(Align.center) }).growX()
|
||||||
|
totalTable.addSeparator(color = Color.LIGHT_GRAY)
|
||||||
for (building in specialistBuildings) addBuildingButton(building, specialistBuildingsTable)
|
for (building in specialistBuildings) addBuildingButton(building, specialistBuildingsTable)
|
||||||
|
totalTable.add(specialistBuildingsTable).growX().right().row()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wonders.isNotEmpty()) {
|
if (wonders.isNotEmpty()) {
|
||||||
val wondersTable = Table()
|
val wondersTable = Table()
|
||||||
addCategory("Wonders", wondersTable)
|
totalTable.addSeparator(color = Color.LIGHT_GRAY)
|
||||||
|
totalTable.add("Wonders".toLabel().apply { setAlignment(Align.center) }).growX()
|
||||||
|
totalTable.addSeparator(color = Color.LIGHT_GRAY)
|
||||||
for (building in wonders) addBuildingButton(building, wondersTable)
|
for (building in wonders) addBuildingButton(building, wondersTable)
|
||||||
|
totalTable.add(wondersTable).growX().right().row()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (otherBuildings.isNotEmpty()) {
|
if (otherBuildings.isNotEmpty()) {
|
||||||
val regularBuildingsTable = Table()
|
val regularBuildingsTable = Table()
|
||||||
addCategory("Buildings", regularBuildingsTable)
|
totalTable.addSeparator(color = Color.LIGHT_GRAY)
|
||||||
|
totalTable.add("Other".toLabel().apply { setAlignment(Align.center) }).growX()
|
||||||
|
totalTable.addSeparator(color = Color.LIGHT_GRAY)
|
||||||
for (building in otherBuildings) addBuildingButton(building, regularBuildingsTable)
|
for (building in otherBuildings) addBuildingButton(building, regularBuildingsTable)
|
||||||
|
totalTable.add(regularBuildingsTable).growX().right().row()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,166 +308,75 @@ class CityStatsTable(val cityScreen: CityScreen): Table() {
|
|||||||
cityScreen.update()
|
cityScreen.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
destinationTable.add(button).pad(1f).expandX().right().row()
|
destinationTable.add(button).pad(1f).padBottom(2f).padTop(2f).expandX().right().row()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addCategory(category: String, showHideTable: Table) {
|
private fun Table.addCategory(category: String, showHideTable: Table, startsOpened: Boolean = true, innerPadding: Float = 10f) : ExpanderTab {
|
||||||
val expanderTab = ExpanderTab(
|
val expanderTab = ExpanderTab(
|
||||||
title = category,
|
title = category,
|
||||||
fontSize = Constants.defaultFontSize,
|
fontSize = Constants.defaultFontSize,
|
||||||
persistenceID = "CityInfo.$category",
|
persistenceID = "CityInfo.$category",
|
||||||
|
startsOutOpened = startsOpened,
|
||||||
|
defaultPad = innerPadding,
|
||||||
onChange = { onContentResize() }
|
onChange = { onContentResize() }
|
||||||
) {
|
) {
|
||||||
it.add(showHideTable).fillX().right()
|
it.add(showHideTable).fillX().right()
|
||||||
}
|
}
|
||||||
lowerTable.add(expanderTab).growX().row()
|
add(expanderTab).growX().row()
|
||||||
|
return expanderTab
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun addGreatPersonPointInfo(cityInfo: CityInfo) {
|
||||||
|
|
||||||
private fun addStatsToHashmap(
|
val greatPeopleTable = Table()
|
||||||
statTreeNode: StatTreeNode,
|
|
||||||
hashMap: HashMap<String, Float>,
|
|
||||||
stat: Stat,
|
|
||||||
showDetails: Boolean,
|
|
||||||
indentation: Int = 0
|
|
||||||
) {
|
|
||||||
for ((name, child) in statTreeNode.children) {
|
|
||||||
val statAmount = child.totalStats[stat]
|
|
||||||
if (statAmount == 0f) continue
|
|
||||||
hashMap["- ".repeat(indentation) + name.tr()] = statAmount
|
|
||||||
if (showDetails) addStatsToHashmap(child, hashMap, stat, showDetails, indentation + 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Table.addStatInfo() {
|
|
||||||
val cityStats = cityScreen.city.cityStats
|
|
||||||
|
|
||||||
val showFaith = cityScreen.city.civInfo.gameInfo.isReligionEnabled()
|
|
||||||
for (stat in Stat.values()) {
|
|
||||||
if (stat == Stat.Faith && !showFaith) continue
|
|
||||||
val statValuesTable = Table()
|
|
||||||
statValuesTable.touchable = Touchable.enabled
|
|
||||||
addCategory(stat.name, statValuesTable)
|
|
||||||
|
|
||||||
updateStatValuesTable(stat, cityStats, statValuesTable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateStatValuesTable(
|
|
||||||
stat: Stat,
|
|
||||||
cityStats: CityStats,
|
|
||||||
statValuesTable: Table,
|
|
||||||
showDetails:Boolean = false
|
|
||||||
) {
|
|
||||||
statValuesTable.clear()
|
|
||||||
statValuesTable.defaults().pad(2f)
|
|
||||||
statValuesTable.onClick {
|
|
||||||
updateStatValuesTable(
|
|
||||||
stat,
|
|
||||||
cityStats,
|
|
||||||
statValuesTable,
|
|
||||||
!showDetails
|
|
||||||
)
|
|
||||||
onContentResize()
|
|
||||||
}
|
|
||||||
|
|
||||||
val relevantBaseStats = LinkedHashMap<String, Float>()
|
|
||||||
|
|
||||||
if (stat != Stat.Happiness)
|
|
||||||
addStatsToHashmap(cityStats.baseStatTree, relevantBaseStats, stat, showDetails)
|
|
||||||
else relevantBaseStats.putAll(cityStats.happinessList)
|
|
||||||
for (key in relevantBaseStats.keys.toList())
|
|
||||||
if (relevantBaseStats[key] == 0f) relevantBaseStats.remove(key)
|
|
||||||
|
|
||||||
if (relevantBaseStats.isEmpty()) return
|
|
||||||
|
|
||||||
statValuesTable.add("Base values".toLabel(fontSize = FONT_SIZE_STAT_INFO_HEADER)).pad(4f)
|
|
||||||
.colspan(2).row()
|
|
||||||
var sumOfAllBaseValues = 0f
|
|
||||||
for (entry in relevantBaseStats) {
|
|
||||||
val specificStatValue = entry.value
|
|
||||||
if (!entry.key.startsWith('-'))
|
|
||||||
sumOfAllBaseValues += specificStatValue
|
|
||||||
statValuesTable.add(entry.key.toLabel()).left()
|
|
||||||
statValuesTable.add(specificStatValue.toOneDecimalLabel()).row()
|
|
||||||
}
|
|
||||||
statValuesTable.addSeparator()
|
|
||||||
statValuesTable.add("Total".toLabel())
|
|
||||||
statValuesTable.add(sumOfAllBaseValues.toOneDecimalLabel()).row()
|
|
||||||
|
|
||||||
val relevantBonuses = LinkedHashMap<String, Float>()
|
|
||||||
addStatsToHashmap(cityStats.statPercentBonusTree, relevantBonuses, stat, showDetails)
|
|
||||||
|
|
||||||
val totalBonusStats = cityStats.statPercentBonusTree.totalStats
|
|
||||||
if (totalBonusStats[stat] != 0f) {
|
|
||||||
statValuesTable.add("Bonuses".toLabel(fontSize = FONT_SIZE_STAT_INFO_HEADER)).colspan(2)
|
|
||||||
.padTop(20f).row()
|
|
||||||
for ((source, bonusAmount) in relevantBonuses) {
|
|
||||||
statValuesTable.add(source.toLabel()).left()
|
|
||||||
statValuesTable.add(bonusAmount.toPercentLabel()).row() // negative bonus
|
|
||||||
}
|
|
||||||
statValuesTable.addSeparator()
|
|
||||||
statValuesTable.add("Total".toLabel())
|
|
||||||
statValuesTable.add(totalBonusStats[stat].toPercentLabel()).row() // negative bonus
|
|
||||||
|
|
||||||
|
|
||||||
statValuesTable.add("Final".toLabel(fontSize = FONT_SIZE_STAT_INFO_HEADER)).colspan(2)
|
|
||||||
.padTop(20f).row()
|
|
||||||
var finalTotal = 0f
|
|
||||||
for (entry in cityStats.finalStatList) {
|
|
||||||
val specificStatValue = entry.value[stat]
|
|
||||||
finalTotal += specificStatValue
|
|
||||||
if (specificStatValue == 0f) continue
|
|
||||||
statValuesTable.add(entry.key.toLabel())
|
|
||||||
statValuesTable.add(specificStatValue.toOneDecimalLabel()).row()
|
|
||||||
}
|
|
||||||
statValuesTable.addSeparator()
|
|
||||||
statValuesTable.add("Total".toLabel())
|
|
||||||
statValuesTable.add(finalTotal.toOneDecimalLabel()).row()
|
|
||||||
}
|
|
||||||
|
|
||||||
statValuesTable.pack()
|
|
||||||
|
|
||||||
if (stat != Stat.Happiness) {
|
|
||||||
val toggleButton = getToggleButton(showDetails)
|
|
||||||
statValuesTable.addActor(toggleButton)
|
|
||||||
toggleButton.setPosition(0f, statValuesTable.height, Align.topLeft)
|
|
||||||
}
|
|
||||||
|
|
||||||
statValuesTable.padBottom(4f)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getToggleButton(showDetails: Boolean): IconCircleGroup {
|
|
||||||
val label = (if (showDetails) "-" else "+").toLabel()
|
|
||||||
label.setAlignment(Align.center)
|
|
||||||
return label
|
|
||||||
.surroundWithCircle(25f, color = BaseScreen.skinStrings.skinConfig.baseColor)
|
|
||||||
.surroundWithCircle(27f, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Table.addGreatPersonPointInfo(cityInfo: CityInfo) {
|
|
||||||
val greatPersonPoints = cityInfo.getGreatPersonPointsForNextTurn()
|
val greatPersonPoints = cityInfo.getGreatPersonPointsForNextTurn()
|
||||||
val allGreatPersonNames = greatPersonPoints.asSequence().flatMap { it.value.keys }.distinct()
|
val allGreatPersonNames = greatPersonPoints.asSequence().flatMap { it.value.keys }.distinct()
|
||||||
|
|
||||||
|
if (allGreatPersonNames.none())
|
||||||
|
return
|
||||||
|
|
||||||
for (greatPersonName in allGreatPersonNames) {
|
for (greatPersonName in allGreatPersonNames) {
|
||||||
val expanderName = "[$greatPersonName] points"
|
|
||||||
val greatPersonTable = Table()
|
var gppPerTurn = 0
|
||||||
addCategory(expanderName, greatPersonTable)
|
|
||||||
for ((source, gppCounter) in greatPersonPoints) {
|
for ((_, gppCounter) in greatPersonPoints) {
|
||||||
val gppPointsFromSource = gppCounter[greatPersonName]!!
|
val gppPointsFromSource = gppCounter[greatPersonName]!!
|
||||||
if (gppPointsFromSource == 0) continue
|
if (gppPointsFromSource == 0) continue
|
||||||
greatPersonTable.add(source.toLabel()).padRight(10f)
|
gppPerTurn += gppPointsFromSource
|
||||||
greatPersonTable.add(gppPointsFromSource.toLabel()).row()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val info = Table()
|
||||||
|
|
||||||
|
info.add(ImageGetter.getUnitIcon(greatPersonName, Color.GOLD).toGroup(20f))
|
||||||
|
.left().padBottom(4f).padRight(5f)
|
||||||
|
info.add("$greatPersonName (+$gppPerTurn)".toLabel()).left().padBottom(4f).expandX().row()
|
||||||
|
|
||||||
|
val gppCurrent = cityInfo.civInfo.greatPeople.greatPersonPointsCounter[greatPersonName]
|
||||||
|
val gppNeeded = cityInfo.civInfo.greatPeople.pointsForNextGreatPerson
|
||||||
|
|
||||||
|
val percent = gppCurrent!! / gppNeeded.toFloat()
|
||||||
|
|
||||||
|
val progressBar = ImageGetter.ProgressBar(300f, 25f, false)
|
||||||
|
progressBar.setBackground(Color.BLACK.cpy().apply { a = 0.8f })
|
||||||
|
progressBar.setProgress(Color.ORANGE, percent)
|
||||||
|
progressBar.apply {
|
||||||
|
val bar = ImageGetter.getWhiteDot()
|
||||||
|
bar.color = Color.GRAY
|
||||||
|
bar.setSize(width+5f, height+5f)
|
||||||
|
bar.center(this)
|
||||||
|
addActor(bar)
|
||||||
|
bar.toBack()
|
||||||
|
}
|
||||||
|
progressBar.setLabel(Color.WHITE, "$gppCurrent/$gppNeeded", fontSize = 14)
|
||||||
|
|
||||||
|
info.add(progressBar).colspan(2).left().expandX().row()
|
||||||
|
|
||||||
|
greatPeopleTable.add(info).growX().top().padBottom(10f)
|
||||||
|
greatPeopleTable.add(ImageGetter.getPortraitImage(greatPersonName, 50f)).row()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
lowerTable.addCategory("Great People", greatPeopleTable)
|
||||||
private const val FONT_SIZE_STAT_INFO_HEADER = 22
|
|
||||||
|
|
||||||
private fun Float.toPercentLabel() =
|
|
||||||
"${if (this>0f) "+" else ""}${DecimalFormat("0.#").format(this)}%".toLabel()
|
|
||||||
private fun Float.toOneDecimalLabel() =
|
|
||||||
DecimalFormat("0.#").format(this).toLabel()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package com.unciv.ui.cityscreen
|
|||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.utils.Align
|
import com.badlogic.gdx.utils.Align
|
||||||
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.city.CityInfo
|
import com.unciv.logic.city.CityInfo
|
||||||
import com.unciv.logic.map.TileInfo
|
import com.unciv.logic.map.TileInfo
|
||||||
import com.unciv.ui.images.ImageGetter
|
import com.unciv.ui.images.ImageGetter
|
||||||
@ -46,11 +47,11 @@ class CityTileGroup(private val city: CityInfo, tileInfo: TileInfo, tileSetStrin
|
|||||||
when {
|
when {
|
||||||
tileInfo.getOwner() != city.civInfo -> { // outside of civ boundary
|
tileInfo.getOwner() != city.civInfo -> { // outside of civ boundary
|
||||||
dim(0.3f)
|
dim(0.3f)
|
||||||
yieldGroup.isVisible = true
|
yieldGroup.isVisible = UncivGame.Current.settings.showTileYields
|
||||||
}
|
}
|
||||||
|
|
||||||
tileInfo !in city.tilesInRange -> { // within city but not close enough to be workable
|
tileInfo !in city.tilesInRange -> { // within city but not close enough to be workable
|
||||||
yieldGroup.isVisible = true
|
yieldGroup.isVisible = UncivGame.Current.settings.showTileYields
|
||||||
dim(0.5f)
|
dim(0.5f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
273
core/src/com/unciv/ui/cityscreen/DetailedStatsPopup.kt
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
package com.unciv.ui.cityscreen
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.Stage
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
|
import com.badlogic.gdx.utils.Align
|
||||||
|
import com.unciv.logic.city.StatTreeNode
|
||||||
|
import com.unciv.models.stats.Stat
|
||||||
|
import com.unciv.models.stats.Stats
|
||||||
|
import com.unciv.models.translations.tr
|
||||||
|
import com.unciv.ui.images.IconCircleGroup
|
||||||
|
import com.unciv.ui.popup.Popup
|
||||||
|
import com.unciv.ui.utils.AutoScrollPane
|
||||||
|
import com.unciv.ui.utils.BaseScreen
|
||||||
|
import com.unciv.ui.utils.KeyCharAndCode
|
||||||
|
import com.unciv.ui.utils.extensions.addSeparator
|
||||||
|
import com.unciv.ui.utils.extensions.brighten
|
||||||
|
import com.unciv.ui.utils.extensions.darken
|
||||||
|
import com.unciv.ui.utils.extensions.onClick
|
||||||
|
import com.unciv.ui.utils.extensions.surroundWithCircle
|
||||||
|
import com.unciv.ui.utils.extensions.toLabel
|
||||||
|
import java.text.DecimalFormat
|
||||||
|
|
||||||
|
class DetailedStatsPopup(val cityScreen: CityScreen, stageToShowOn: Stage) : Popup(
|
||||||
|
stageToShowOn = stageToShowOn,
|
||||||
|
scrollable = false) {
|
||||||
|
|
||||||
|
constructor(screen: CityScreen) : this(screen, screen.stage)
|
||||||
|
|
||||||
|
private val totalTable = Table()
|
||||||
|
|
||||||
|
private var sourceHighlighted: String? = null
|
||||||
|
private var onlyWithStat: Stat? = null
|
||||||
|
private var isDetailed: Boolean = false
|
||||||
|
|
||||||
|
private val colorTotal: Color = Color.BLUE.brighten(0.5f)
|
||||||
|
private val colorSelector: Color = Color.GREEN.darken(0.5f)
|
||||||
|
|
||||||
|
init {
|
||||||
|
|
||||||
|
val scrollPane = AutoScrollPane(totalTable)
|
||||||
|
scrollPane.setOverscroll(false, false)
|
||||||
|
val scrollPaneCell = add(scrollPane)
|
||||||
|
scrollPaneCell.maxHeight(cityScreen.stage.height *3 / 4)
|
||||||
|
|
||||||
|
row()
|
||||||
|
addCloseButton("Cancel", KeyCharAndCode('n'))
|
||||||
|
update()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun update() {
|
||||||
|
|
||||||
|
totalTable.clear()
|
||||||
|
|
||||||
|
val cityStats = cityScreen.city.cityStats
|
||||||
|
val showFaith = cityScreen.city.civInfo.gameInfo.isReligionEnabled()
|
||||||
|
|
||||||
|
val stats = when {
|
||||||
|
onlyWithStat != null -> listOfNotNull(onlyWithStat)
|
||||||
|
!showFaith -> Stat.values().filter { it != Stat.Faith }
|
||||||
|
else -> Stat.values().toList()
|
||||||
|
}
|
||||||
|
|
||||||
|
totalTable.defaults().pad(3f).padLeft(0f).padRight(0f)
|
||||||
|
|
||||||
|
totalTable.add(getToggleButton(isDetailed).onClick {
|
||||||
|
isDetailed = !isDetailed
|
||||||
|
update() }).minWidth(150f).grow()
|
||||||
|
|
||||||
|
for (stat in stats) {
|
||||||
|
val label = (stat.character + " " + stat.name).toLabel()
|
||||||
|
label.onClick {
|
||||||
|
onlyWithStat = if (onlyWithStat == null) stat else null
|
||||||
|
update()
|
||||||
|
}
|
||||||
|
totalTable.add(wrapInTable(label, if (onlyWithStat == stat) colorSelector else null))
|
||||||
|
.minWidth(if (onlyWithStat == stat) 150f else 110f).grow()
|
||||||
|
}
|
||||||
|
totalTable.row()
|
||||||
|
|
||||||
|
totalTable.addSeparator().padBottom(2f)
|
||||||
|
totalTable.add("Base stats".toLabel().apply { setAlignment(Align.center) })
|
||||||
|
.colspan(totalTable.columns).padLeft(0f).padRight(0f).growX().row()
|
||||||
|
totalTable.addSeparator().padTop(2f)
|
||||||
|
traverseTree(totalTable, stats, cityStats.baseStatTree, mergeHappiness = true, percentage = false)
|
||||||
|
|
||||||
|
totalTable.addSeparator().padBottom(2f)
|
||||||
|
totalTable.add("Bonuses".toLabel().apply { setAlignment(Align.center) })
|
||||||
|
.colspan(totalTable.columns).padLeft(0f).padRight(0f).growX().row()
|
||||||
|
totalTable.addSeparator().padTop(2f)
|
||||||
|
traverseTree(totalTable, stats, cityStats.statPercentBonusTree, percentage = true)
|
||||||
|
|
||||||
|
totalTable.addSeparator().padBottom(2f)
|
||||||
|
totalTable.add("Final".toLabel().apply { setAlignment(Align.center) })
|
||||||
|
.colspan(totalTable.columns).padLeft(0f).padRight(0f).growX().row()
|
||||||
|
totalTable.addSeparator().padTop(2f)
|
||||||
|
|
||||||
|
val final = LinkedHashMap<Stat, Float>()
|
||||||
|
val map = cityStats.finalStatList.toSortedMap()
|
||||||
|
|
||||||
|
for ((key, value) in cityScreen.city.cityStats.happinessList) {
|
||||||
|
if (!map.containsKey(key)) {
|
||||||
|
map[key] = Stats()
|
||||||
|
map[key]!![Stat.Happiness] = value
|
||||||
|
} else if (map[key]!![Stat.Happiness] == 0f) {
|
||||||
|
map[key]!![Stat.Happiness] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((source, finalStats) in map) {
|
||||||
|
|
||||||
|
if (finalStats.all { it.value == 0f })
|
||||||
|
continue
|
||||||
|
|
||||||
|
if (onlyWithStat != null && finalStats[onlyWithStat!!] == 0f)
|
||||||
|
continue
|
||||||
|
|
||||||
|
val label = source.toLabel().apply {
|
||||||
|
setAlignment(Align.left)
|
||||||
|
onClick {
|
||||||
|
sourceHighlighted = if (sourceHighlighted == source) null else source
|
||||||
|
update()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var color: Color? = null
|
||||||
|
|
||||||
|
if (sourceHighlighted == source)
|
||||||
|
color = colorSelector
|
||||||
|
|
||||||
|
totalTable.add(wrapInTable(label, color, Align.left)).grow()
|
||||||
|
|
||||||
|
for (stat in stats) {
|
||||||
|
val value = finalStats[stat]
|
||||||
|
val cell = when (value) {
|
||||||
|
0f -> "-".toLabel()
|
||||||
|
else -> value.toOneDecimalLabel()
|
||||||
|
}
|
||||||
|
|
||||||
|
totalTable.add(wrapInTable(cell, color)).grow()
|
||||||
|
|
||||||
|
var f = final[stat]
|
||||||
|
if (f == null)
|
||||||
|
f = 0f
|
||||||
|
f += value
|
||||||
|
final[stat] = f
|
||||||
|
|
||||||
|
}
|
||||||
|
totalTable.row()
|
||||||
|
}
|
||||||
|
|
||||||
|
totalTable.add(wrapInTable("Total".toLabel(), colorTotal)).grow()
|
||||||
|
for (stat in stats) {
|
||||||
|
totalTable.add(wrapInTable(final[stat]?.toOneDecimalLabel(), colorTotal)).grow()
|
||||||
|
}
|
||||||
|
totalTable.row()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getToggleButton(showDetails: Boolean): IconCircleGroup {
|
||||||
|
val label = (if (showDetails) "-" else "+").toLabel()
|
||||||
|
label.setAlignment(Align.center)
|
||||||
|
return label
|
||||||
|
.surroundWithCircle(25f, color = BaseScreen.skinStrings.skinConfig.baseColor)
|
||||||
|
.surroundWithCircle(27f, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun traverseTree(
|
||||||
|
table: Table,
|
||||||
|
stats: List<Stat>,
|
||||||
|
statTreeNode: StatTreeNode,
|
||||||
|
mergeHappiness: Boolean = false,
|
||||||
|
percentage: Boolean = false,
|
||||||
|
indentation: Int = 0
|
||||||
|
) {
|
||||||
|
|
||||||
|
val total = LinkedHashMap<Stat, Float>()
|
||||||
|
val map = statTreeNode.children.toSortedMap()
|
||||||
|
|
||||||
|
if (mergeHappiness) {
|
||||||
|
for ((key, value) in cityScreen.city.cityStats.happinessList) {
|
||||||
|
if (!map.containsKey(key)) {
|
||||||
|
map[key] = StatTreeNode()
|
||||||
|
map[key]?.setInnerStat(Stat.Happiness, value)
|
||||||
|
} else if (map[key]!!.totalStats.happiness == 0f) {
|
||||||
|
map[key]?.setInnerStat(Stat.Happiness, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ((name, child) in map) {
|
||||||
|
|
||||||
|
val text = "- ".repeat(indentation) + name.tr()
|
||||||
|
|
||||||
|
if (child.totalStats.all { it.value == 0f }) {
|
||||||
|
table.row()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (onlyWithStat != null && child.totalStats[onlyWithStat!!] == 0f) {
|
||||||
|
table.row()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val label = text.toLabel().apply {
|
||||||
|
setAlignment(Align.left)
|
||||||
|
onClick {
|
||||||
|
sourceHighlighted = if (sourceHighlighted == text) null else text
|
||||||
|
update()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var color: Color? = null
|
||||||
|
|
||||||
|
if (sourceHighlighted == text)
|
||||||
|
color = colorSelector
|
||||||
|
|
||||||
|
table.add(wrapInTable(label, color, Align.left)).fill().left()
|
||||||
|
|
||||||
|
for (stat in stats) {
|
||||||
|
val value = child.totalStats[stat]
|
||||||
|
val cell = when {
|
||||||
|
value == 0f -> "-".toLabel()
|
||||||
|
percentage -> value.toPercentLabel()
|
||||||
|
else -> value.toOneDecimalLabel()
|
||||||
|
}
|
||||||
|
|
||||||
|
table.add(wrapInTable(cell, color)).grow()
|
||||||
|
|
||||||
|
if (indentation == 0) {
|
||||||
|
var current = total[stat]
|
||||||
|
if (current == null)
|
||||||
|
current = 0f
|
||||||
|
total[stat] = current + value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table.row()
|
||||||
|
if (isDetailed)
|
||||||
|
traverseTree(table, stats, child, percentage = percentage, indentation = indentation + 1)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indentation == 0) {
|
||||||
|
table.add(wrapInTable("Total".toLabel(), colorTotal)).grow()
|
||||||
|
for (stat in stats) {
|
||||||
|
if (percentage)
|
||||||
|
table.add(wrapInTable(total[stat]?.toPercentLabel(), colorTotal)).grow()
|
||||||
|
else
|
||||||
|
table.add(wrapInTable(total[stat]?.toOneDecimalLabel(), colorTotal)).grow()
|
||||||
|
}
|
||||||
|
table.row()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun wrapInTable(label: Label?, color: Color? = null, align: Int = Align.center) : Table {
|
||||||
|
val tbl = Table()
|
||||||
|
label?.setAlignment(align)
|
||||||
|
if (color != null)
|
||||||
|
tbl.background = BaseScreen.skinStrings.getUiBackground("General/Border", tintColor = color)
|
||||||
|
tbl.add(label).growX()
|
||||||
|
return tbl
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private fun Float.toPercentLabel() =
|
||||||
|
"${if (this>0f) "+" else ""}${DecimalFormat("0.#").format(this)}%".toLabel()
|
||||||
|
private fun Float.toOneDecimalLabel() =
|
||||||
|
DecimalFormat("0.#").format(this).toLabel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
package com.unciv.ui.cityscreen
|
package com.unciv.ui.cityscreen
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
@ -14,6 +15,7 @@ import com.unciv.ui.utils.extensions.addSeparatorVertical
|
|||||||
import com.unciv.ui.utils.extensions.darken
|
import com.unciv.ui.utils.extensions.darken
|
||||||
import com.unciv.ui.utils.extensions.onClick
|
import com.unciv.ui.utils.extensions.onClick
|
||||||
import com.unciv.ui.utils.extensions.surroundWithCircle
|
import com.unciv.ui.utils.extensions.surroundWithCircle
|
||||||
|
import com.unciv.ui.utils.extensions.toGroup
|
||||||
import com.unciv.ui.utils.extensions.toLabel
|
import com.unciv.ui.utils.extensions.toLabel
|
||||||
|
|
||||||
class SpecialistAllocationTable(val cityScreen: CityScreen) : Table(BaseScreen.skin) {
|
class SpecialistAllocationTable(val cityScreen: CityScreen) : Table(BaseScreen.skin) {
|
||||||
@ -104,13 +106,21 @@ class SpecialistAllocationTable(val cityScreen: CityScreen) : Table(BaseScreen.s
|
|||||||
|
|
||||||
|
|
||||||
private fun getSpecialistStatsTable(specialistName: String): Table {
|
private fun getSpecialistStatsTable(specialistName: String): Table {
|
||||||
val specialistStatTable = Table().apply { defaults().pad(5f) }
|
val specialistStatTable = Table().apply { defaults().padBottom(5f).padTop(5f) }
|
||||||
val specialistStats = cityInfo.cityStats.getStatsOfSpecialist(specialistName)
|
val specialistStats = cityInfo.cityStats.getStatsOfSpecialist(specialistName)
|
||||||
for ((key, value) in specialistStats) {
|
for ((key, value) in specialistStats) {
|
||||||
if (value == 0f) continue
|
if (value == 0f) continue
|
||||||
specialistStatTable.add(ImageGetter.getStatIcon(key.name)).size(20f)
|
specialistStatTable.add(value.toInt().toLabel())
|
||||||
specialistStatTable.add(value.toInt().toLabel()).padRight(10f)
|
specialistStatTable.add(ImageGetter.getStatIcon(key.name)).size(20f).padRight(10f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val specialist = cityInfo.getRuleset().specialists[specialistName]!!
|
||||||
|
|
||||||
|
for (s in specialist.greatPersonPoints) {
|
||||||
|
specialistStatTable.add(s.value.toLabel())
|
||||||
|
specialistStatTable.add(ImageGetter.getUnitIcon(s.key, Color.GOLD).toGroup(20f)).padRight(10f)
|
||||||
|
}
|
||||||
|
|
||||||
return specialistStatTable
|
return specialistStatTable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion
|
|||||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||||
import com.badlogic.gdx.scenes.scene2d.Group
|
import com.badlogic.gdx.scenes.scene2d.Group
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Image
|
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.Table
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable
|
import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable
|
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable
|
||||||
@ -385,23 +386,79 @@ object ImageGetter {
|
|||||||
.surroundWithThinCircle(techIconColor)
|
.surroundWithThinCircle(techIconColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getProgressBarVertical(width: Float, height: Float, percentComplete: Float, progressColor: Color, backgroundColor: Color): Group {
|
fun getProgressBarHorizontal(width: Float, height: Float, percentComplete: Float, progressColor: Color, backgroundColor: Color): Group {
|
||||||
return VerticalProgressBar(width, height)
|
return ProgressBar(width, height, false)
|
||||||
.addColor(backgroundColor, 1f)
|
.setBackground(backgroundColor)
|
||||||
.addColor(progressColor, percentComplete)
|
.setProgress(progressColor, percentComplete)
|
||||||
}
|
}
|
||||||
|
|
||||||
class VerticalProgressBar(width: Float, height: Float):Group() {
|
fun getProgressBarVertical(width: Float, height: Float, percentComplete: Float, progressColor: Color, backgroundColor: Color): Group {
|
||||||
|
return ProgressBar(width, height, true)
|
||||||
|
.setBackground(backgroundColor)
|
||||||
|
.setProgress(progressColor, percentComplete)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ProgressBar(width: Float, height: Float, val vertical: Boolean = true):Group() {
|
||||||
|
|
||||||
|
var primaryPercentage: Float = 0f
|
||||||
|
var secondaryPercentage: Float = 0f
|
||||||
|
|
||||||
|
var label: Label? = null
|
||||||
|
var background: Image? = null
|
||||||
|
var secondaryProgress: Image? = null
|
||||||
|
var primaryProgress: Image? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
setSize(width, height)
|
setSize(width, height)
|
||||||
isTransform = false
|
isTransform = false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addColor(color: Color, percentage: Float): VerticalProgressBar {
|
fun setLabel(color: Color, text: String, fontSize: Int = Constants.defaultFontSize) : ProgressBar {
|
||||||
val bar = getWhiteDot()
|
label = text.toLabel()
|
||||||
bar.color = color
|
label?.setAlignment(Align.center)
|
||||||
bar.setSize(width, height * max(min(percentage, 1f),0f)) //clamp between 0 and 1
|
label?.setFontColor(color)
|
||||||
addActor(bar)
|
label?.setFontSize(fontSize)
|
||||||
|
label?.toFront()
|
||||||
|
label?.center(this)
|
||||||
|
if (label != null)
|
||||||
|
addActor(label)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setBackground(color: Color): ProgressBar {
|
||||||
|
background = getWhiteDot()
|
||||||
|
background?.color = color
|
||||||
|
background?.setSize(width, height) //clamp between 0 and 1
|
||||||
|
background?.toBack()
|
||||||
|
background?.center(this)
|
||||||
|
if (background != null)
|
||||||
|
addActor(background)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setSemiProgress(color: Color, percentage: Float): ProgressBar {
|
||||||
|
secondaryPercentage = percentage
|
||||||
|
secondaryProgress = getWhiteDot()
|
||||||
|
secondaryProgress?.color = color
|
||||||
|
if (vertical)
|
||||||
|
secondaryProgress?.setSize(width, height * max(min(percentage, 1f),0f))
|
||||||
|
else
|
||||||
|
secondaryProgress?.setSize(width * max(min(percentage, 1f),0f), height)
|
||||||
|
if (secondaryProgress != null)
|
||||||
|
addActor(secondaryProgress)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setProgress(color: Color, percentage: Float): ProgressBar {
|
||||||
|
primaryPercentage = percentage
|
||||||
|
primaryProgress = getWhiteDot()
|
||||||
|
primaryProgress?.color = color
|
||||||
|
if (vertical)
|
||||||
|
primaryProgress?.setSize(width, height * max(min(percentage, 1f),0f))
|
||||||
|
else
|
||||||
|
primaryProgress?.setSize(width * max(min(percentage, 1f),0f), height)
|
||||||
|
if (primaryProgress != null)
|
||||||
|
addActor(primaryProgress)
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,10 +62,10 @@ class TechButton(techName:String, private val techManager: TechManager, isWorldS
|
|||||||
|
|
||||||
val percentComplete = (techCost - remainingTech) / techCost.toFloat()
|
val percentComplete = (techCost - remainingTech) / techCost.toFloat()
|
||||||
val percentWillBeComplete = (techCost - (remainingTech-techThisTurn)) / techCost.toFloat()
|
val percentWillBeComplete = (techCost - (remainingTech-techThisTurn)) / techCost.toFloat()
|
||||||
val progressBar = ImageGetter.VerticalProgressBar(2f, 50f)
|
val progressBar = ImageGetter.ProgressBar(2f, 50f, true)
|
||||||
.addColor(Color.WHITE, 1f)
|
.setBackground(Color.WHITE)
|
||||||
.addColor(Color.BLUE.brighten(0.3f), percentWillBeComplete)
|
.setSemiProgress(Color.BLUE.brighten(0.3f), percentWillBeComplete)
|
||||||
.addColor(Color.BLUE.darken(0.5f), percentComplete)
|
.setProgress(Color.BLUE.darken(0.5f), percentComplete)
|
||||||
add(progressBar.addBorder(1f, Color.GRAY)).pad(10f)
|
add(progressBar.addBorder(1f, Color.GRAY)).pad(10f)
|
||||||
}
|
}
|
||||||
rightSide.add(text).width(145f).top().left().padRight(15f)
|
rightSide.add(text).width(145f).top().left().padRight(15f)
|
||||||
|
@ -124,6 +124,11 @@ class NativeBitmapFontData(
|
|||||||
Fonts.culture -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("EmojiIcons/Culture").region)
|
Fonts.culture -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("EmojiIcons/Culture").region)
|
||||||
Fonts.faith -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("EmojiIcons/Faith").region)
|
Fonts.faith -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("EmojiIcons/Faith").region)
|
||||||
Fonts.happiness -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("EmojiIcons/Happiness").region)
|
Fonts.happiness -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("EmojiIcons/Happiness").region)
|
||||||
|
Fonts.greatArtist -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("EmojiIcons/Great Artist").region)
|
||||||
|
Fonts.greatEngineer -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("EmojiIcons/Great Engineer").region)
|
||||||
|
Fonts.greatGeneral -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("EmojiIcons/Great General").region)
|
||||||
|
Fonts.greatMerchant -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("EmojiIcons/Great Merchant").region)
|
||||||
|
Fonts.greatScientist -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable("EmojiIcons/Great Scientist").region)
|
||||||
MayaCalendar.tun -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable(MayaCalendar.tunIcon).region)
|
MayaCalendar.tun -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable(MayaCalendar.tunIcon).region)
|
||||||
MayaCalendar.katun -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable(MayaCalendar.katunIcon).region)
|
MayaCalendar.katun -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable(MayaCalendar.katunIcon).region)
|
||||||
MayaCalendar.baktun -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable(MayaCalendar.baktunIcon).region)
|
MayaCalendar.baktun -> Fonts.extractPixmapFromTextureRegion(ImageGetter.getDrawable(MayaCalendar.baktunIcon).region)
|
||||||
@ -231,4 +236,9 @@ object Fonts {
|
|||||||
const val culture = '♪' // U+266A 'eighth note' (🎵 U+1F3B5 'musical note')
|
const val culture = '♪' // U+266A 'eighth note' (🎵 U+1F3B5 'musical note')
|
||||||
const val happiness = '⌣' // U+2323 'smile' (😀 U+1F600 'grinning face')
|
const val happiness = '⌣' // U+2323 'smile' (😀 U+1F600 'grinning face')
|
||||||
const val faith = '☮' // U+262E 'peace symbol' (🕊 U+1F54A 'dove of peace')
|
const val faith = '☮' // U+262E 'peace symbol' (🕊 U+1F54A 'dove of peace')
|
||||||
|
const val greatArtist = '♬' // U+266C 'sixteenth note'
|
||||||
|
const val greatEngineer = '⚒' // U+2692 'hammer'
|
||||||
|
const val greatGeneral = '⛤' // U+26E4 'pentagram'
|
||||||
|
const val greatMerchant = '⚖' // U+2696 'scale'
|
||||||
|
const val greatScientist = '⚛' // U+269B 'atom'
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,9 @@ These shapes are used all over Unciv and can be replaced to make a lot of UI ele
|
|||||||
| CityScreen/ConstructionInfoTable/ | SelectedConstructionTable | null | |
|
| CityScreen/ConstructionInfoTable/ | SelectedConstructionTable | null | |
|
||||||
| CivilopediaScreen/ | EntryButton | null | |
|
| CivilopediaScreen/ | EntryButton | null | |
|
||||||
| General/ | Border | null | |
|
| General/ | Border | null | |
|
||||||
|
| General/ | Border | null | |
|
||||||
|
| General/ | Border | null | |
|
||||||
|
| General/ | Border | null | |
|
||||||
| General/ | ExpanderTab | null | |
|
| General/ | ExpanderTab | null | |
|
||||||
| General/ | HealthBar | null | |
|
| General/ | HealthBar | null | |
|
||||||
| General/ | TabbedPager | null | |
|
| General/ | TabbedPager | null | |
|
||||||
@ -87,8 +90,11 @@ These shapes are used all over Unciv and can be replaced to make a lot of UI ele
|
|||||||
| OverviewScreen/UnitOverviewTab/ | UnitSupplyTable | null | |
|
| OverviewScreen/UnitOverviewTab/ | UnitSupplyTable | null | |
|
||||||
| PlayerReadyScreen/ | Background | null | |
|
| PlayerReadyScreen/ | Background | null | |
|
||||||
| TechPickerScreen/ | Background | null | |
|
| TechPickerScreen/ | Background | null | |
|
||||||
|
| TechPickerScreen/ | Background | null | |
|
||||||
| TechPickerScreen/ | BottomTable | null | |
|
| TechPickerScreen/ | BottomTable | null | |
|
||||||
| TechPickerScreen/ | TechButton | roundedEdgeRectangle | |
|
| TechPickerScreen/ | TechButton | roundedEdgeRectangle | |
|
||||||
|
| TechPickerScreen/ | TechButton | roundedEdgeRectangle | |
|
||||||
|
| TechPickerScreen/ | TechButtonIconsOutline | rectangleWithOutline | |
|
||||||
| VictoryScreen/ | CivGroup | roundedEdgeRectangle | |
|
| VictoryScreen/ | CivGroup | roundedEdgeRectangle | |
|
||||||
| WorldScreen/ | AirUnitTable | null | |
|
| WorldScreen/ | AirUnitTable | null | |
|
||||||
| WorldScreen/ | BattleTable | null | |
|
| WorldScreen/ | BattleTable | null | |
|
||||||
|