Big rework of Policy Picker UI, added new ninepatch RoundedEdgeRectangleSmall (#8218)

Co-authored-by: tunerzinc@gmail.com <vfylfhby>
This commit is contained in:
vegeta1k95 2022-12-24 18:17:00 +01:00 committed by GitHub
parent 1fdbea0a45
commit 78c4f6de68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 786 additions and 221 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

View File

@ -4,6 +4,69 @@ size: 2048, 128
format: RGBA8888 format: RGBA8888
filter: MipMapLinearLinear, MipMapLinearLinear filter: MipMapLinearLinear, MipMapLinearLinear
repeat: none repeat: none
PolicyBranchIcons/Autocracy
rotate: false
xy: 62, 62
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyBranchIcons/Commerce
rotate: false
xy: 178, 62
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyBranchIcons/Honor
rotate: false
xy: 468, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/Military Tradition
rotate: false
xy: 468, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyBranchIcons/Liberty
rotate: false
xy: 584, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyBranchIcons/Patronage
rotate: false
xy: 932, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyBranchIcons/Piety
rotate: false
xy: 990, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyBranchIcons/Rationalism
rotate: false
xy: 1164, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyBranchIcons/Tradition
rotate: false
xy: 1512, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/Aesthetics PolicyIcons/Aesthetics
rotate: false rotate: false
xy: 4, 62 xy: 4, 62
@ -20,337 +83,344 @@ PolicyIcons/Aristocracy
index: -1 index: -1
PolicyIcons/Citizenship PolicyIcons/Citizenship
rotate: false rotate: false
xy: 62, 62 xy: 62, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Civil Society PolicyIcons/Civil Society
rotate: false rotate: false
xy: 62, 4 xy: 120, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Collective Rule PolicyIcons/Collective Rule
rotate: false rotate: false
xy: 120, 62 xy: 120, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Communism PolicyBranchIcons/Freedom
rotate: false rotate: false
xy: 120, 4 xy: 120, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Constitution PolicyIcons/Communism
rotate: false
xy: 178, 62
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/Cultural Diplomacy
rotate: false rotate: false
xy: 178, 4 xy: 178, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Democracy PolicyBranchIcons/Order
rotate: false
xy: 178, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/Constitution
rotate: false rotate: false
xy: 236, 62 xy: 236, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Discipline PolicyIcons/Cultural Diplomacy
rotate: false rotate: false
xy: 236, 4 xy: 236, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Educated Elite PolicyIcons/Democracy
rotate: false rotate: false
xy: 294, 62 xy: 294, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Fascism PolicyIcons/Discipline
rotate: false rotate: false
xy: 294, 4 xy: 294, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Free Religion PolicyIcons/Educated Elite
rotate: false rotate: false
xy: 352, 62 xy: 352, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Free Speech PolicyIcons/Fascism
rotate: false rotate: false
xy: 352, 4 xy: 352, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Free Thought PolicyIcons/Free Religion
rotate: false rotate: false
xy: 410, 62 xy: 410, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Humanism PolicyIcons/Free Speech
rotate: false rotate: false
xy: 410, 4 xy: 410, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Landed Elite PolicyIcons/Free Thought
rotate: false rotate: false
xy: 468, 62 xy: 468, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Legalism PolicyIcons/Humanism
rotate: false
xy: 468, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/Mandate Of Heaven
rotate: false rotate: false
xy: 526, 62 xy: 526, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Mercantilism PolicyIcons/Landed Elite
rotate: false rotate: false
xy: 526, 4 xy: 526, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Merchant Navy PolicyIcons/Legalism
rotate: false rotate: false
xy: 584, 62 xy: 584, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Meritocracy PolicyIcons/Mandate Of Heaven
rotate: false
xy: 584, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/Militarism
rotate: false rotate: false
xy: 642, 62 xy: 642, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Military Caste PolicyIcons/Mercantilism
rotate: false rotate: false
xy: 642, 4 xy: 642, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Military Tradition PolicyIcons/Merchant Navy
rotate: false rotate: false
xy: 700, 62 xy: 700, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Monarchy PolicyIcons/Meritocracy
rotate: false rotate: false
xy: 700, 4 xy: 700, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Nationalism PolicyIcons/Militarism
rotate: false rotate: false
xy: 758, 62 xy: 758, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Naval Tradition PolicyIcons/Military Caste
rotate: false rotate: false
xy: 758, 4 xy: 758, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Oligarchy PolicyIcons/Monarchy
rotate: false rotate: false
xy: 816, 62 xy: 816, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Organized Religion PolicyIcons/Nationalism
rotate: false rotate: false
xy: 816, 4 xy: 816, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Philantropy PolicyIcons/Naval Tradition
rotate: false rotate: false
xy: 874, 62 xy: 874, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Planned Economy PolicyIcons/Oligarchy
rotate: false rotate: false
xy: 874, 4 xy: 874, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Police State PolicyIcons/Organized Religion
rotate: false rotate: false
xy: 932, 62 xy: 932, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Populism PolicyIcons/Philantropy
rotate: false
xy: 932, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/Professional Army
rotate: false rotate: false
xy: 990, 62 xy: 990, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Protectionism PolicyIcons/Planned Economy
rotate: false
xy: 990, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/Reformation
rotate: false rotate: false
xy: 1048, 62 xy: 1048, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Representation PolicyIcons/Police State
rotate: false rotate: false
xy: 1048, 4 xy: 1048, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Republic PolicyIcons/Populism
rotate: false rotate: false
xy: 1106, 62 xy: 1106, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Scholasticism PolicyIcons/Professional Army
rotate: false rotate: false
xy: 1106, 4 xy: 1106, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Scientific Revolution PolicyIcons/Protectionism
rotate: false rotate: false
xy: 1164, 62 xy: 1164, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Secularism PolicyIcons/Reformation
rotate: false
xy: 1164, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/Socialism
rotate: false rotate: false
xy: 1222, 62 xy: 1222, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Sovereignty PolicyIcons/Representation
rotate: false rotate: false
xy: 1222, 4 xy: 1222, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Theocracy PolicyIcons/Republic
rotate: false rotate: false
xy: 1280, 62 xy: 1280, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Total War PolicyIcons/Scholasticism
rotate: false rotate: false
xy: 1280, 4 xy: 1280, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Trade Unions PolicyIcons/Scientific Revolution
rotate: false rotate: false
xy: 1338, 62 xy: 1338, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/United Front PolicyIcons/Secularism
rotate: false rotate: false
xy: 1338, 4 xy: 1338, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Universal Suffrage PolicyIcons/Socialism
rotate: false rotate: false
xy: 1396, 62 xy: 1396, 62
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Warrior Code PolicyIcons/Sovereignty
rotate: false rotate: false
xy: 1396, 4 xy: 1396, 4
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
PolicyIcons/Theocracy
rotate: false
xy: 1454, 62
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/Total War
rotate: false
xy: 1454, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/Trade Unions
rotate: false
xy: 1512, 62
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/United Front
rotate: false
xy: 1570, 62
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/Universal Suffrage
rotate: false
xy: 1570, 4
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
PolicyIcons/Warrior Code
rotate: false
xy: 1628, 62
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 92 KiB

View File

@ -1,12 +1,12 @@
Skin.png Skin.png
size: 256, 64 size: 128, 128
format: RGBA8888 format: RGBA8888
filter: Linear, Linear filter: Linear, Linear
repeat: none repeat: none
Skins/Minimal/checkbox Skins/Minimal/checkbox
rotate: false rotate: false
xy: 199, 23 xy: 52, 16
size: 31, 31 size: 31, 31
split: 0, 0, 0, 0 split: 0, 0, 0, 0
orig: 31, 31 orig: 31, 31
@ -14,7 +14,7 @@ Skins/Minimal/checkbox
index: -1 index: -1
Skins/Minimal/checkbox-pressed Skins/Minimal/checkbox-pressed
rotate: false rotate: false
xy: 160, 23 xy: 64, 55
size: 31, 31 size: 31, 31
split: 0, 0, 0, 0 split: 0, 0, 0, 0
orig: 31, 31 orig: 31, 31
@ -22,7 +22,7 @@ Skins/Minimal/checkbox-pressed
index: -1 index: -1
Skins/Minimal/rectangleWithOutline Skins/Minimal/rectangleWithOutline
rotate: false rotate: false
xy: 64, 13 xy: 112, 121
size: 3, 3 size: 3, 3
split: 0, 0, 0, 0 split: 0, 0, 0, 0
orig: 3, 3 orig: 3, 3
@ -30,16 +30,25 @@ Skins/Minimal/rectangleWithOutline
index: -1 index: -1
Skins/Minimal/roundedEdgeRectangle Skins/Minimal/roundedEdgeRectangle
rotate: false rotate: false
xy: 4, 4 xy: 4, 74
size: 52, 50 size: 52, 50
split: 19, 20, 19, 21 split: 19, 20, 19, 21
pad: 12, 13, 7, 7 pad: 12, 13, 7, 7
orig: 52, 50 orig: 52, 50
offset: 0, 0 offset: 0, 0
index: -1 index: -1
Skins/Minimal/roundedEdgeRectangle-small
rotate: false
xy: 4, 4
size: 24, 24
split: 10, 10, 10, 10
pad: 10, 10, 2, 2
orig: 24, 24
offset: 0, 0
index: -1
Skins/Minimal/select-box Skins/Minimal/select-box
rotate: false rotate: false
xy: 112, 24 xy: 64, 94
size: 40, 30 size: 40, 30
split: 7, 9, 7, 7 split: 7, 9, 7, 7
orig: 40, 30 orig: 40, 30
@ -47,7 +56,7 @@ Skins/Minimal/select-box
index: -1 index: -1
Skins/Minimal/select-box-pressed Skins/Minimal/select-box-pressed
rotate: false rotate: false
xy: 64, 24 xy: 4, 36
size: 40, 30 size: 40, 30
split: 7, 9, 7, 7 split: 7, 9, 7, 7
orig: 40, 30 orig: 40, 30

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -111,21 +111,21 @@ EmojiIcons/Happiness
index: -1 index: -1
EmojiIcons/Production EmojiIcons/Production
rotate: false rotate: false
xy: 588, 720 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
EmojiIcons/Science EmojiIcons/Science
rotate: false rotate: false
xy: 762, 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
EmojiIcons/Turn EmojiIcons/Turn
rotate: false rotate: false
xy: 1868, 1546 xy: 1270, 962
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
@ -370,35 +370,56 @@ ImprovementIcons/Trading post
index: -1 index: -1
NotificationIcons/EnhanceReligion NotificationIcons/EnhanceReligion
rotate: false rotate: false
xy: 190, 716 xy: 1927, 1828
size: 100, 100 size: 100, 100
orig: 100, 100 orig: 100, 100
offset: 0, 0 offset: 0, 0
index: -1 index: -1
NotificationIcons/FoundPantheon NotificationIcons/FoundPantheon
rotate: false rotate: false
xy: 190, 716 xy: 1927, 1828
size: 100, 100 size: 100, 100
orig: 100, 100 orig: 100, 100
offset: 0, 0 offset: 0, 0
index: -1 index: -1
NotificationIcons/FoundReligion NotificationIcons/FoundReligion
rotate: false rotate: false
xy: 190, 716 xy: 1927, 1828
size: 100, 100 size: 100, 100
orig: 100, 100 orig: 100, 100
offset: 0, 0 offset: 0, 0
index: -1 index: -1
NotificationIcons/ReformReligion NotificationIcons/ReformReligion
rotate: false rotate: false
xy: 190, 716 xy: 1927, 1828
size: 100, 100 size: 100, 100
orig: 100, 100 orig: 100, 100
offset: 0, 0 offset: 0, 0
index: -1 index: -1
StatIcons/Faith StatIcons/Faith
rotate: false rotate: false
xy: 190, 716 xy: 1927, 1828
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
NotificationIcons/Loading
rotate: false
xy: 622, 1534
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
NotificationIcons/Working
rotate: false
xy: 622, 1534
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
OtherIcons/Loading
rotate: false
xy: 622, 1534
size: 100, 100 size: 100, 100
orig: 100, 100 orig: 100, 100
offset: 0, 0 offset: 0, 0
@ -503,7 +524,7 @@ OtherIcons/Banner
index: -1 index: -1
OtherIcons/Camera OtherIcons/Camera
rotate: false rotate: false
xy: 1270, 987 xy: 1328, 1045
size: 25, 25 size: 25, 25
orig: 25, 25 orig: 25, 25
offset: 0, 0 offset: 0, 0
@ -634,27 +655,6 @@ OtherIcons/Load
orig: 100, 100 orig: 100, 100
offset: 0, 0 offset: 0, 0
index: -1 index: -1
OtherIcons/Loading
rotate: false
xy: 622, 1534
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
NotificationIcons/Loading
rotate: false
xy: 622, 1534
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
NotificationIcons/Working
rotate: false
xy: 622, 1534
size: 100, 100
orig: 100, 100
offset: 0, 0
index: -1
OtherIcons/Lock OtherIcons/Lock
rotate: false rotate: false
xy: 730, 1642 xy: 730, 1642
@ -662,6 +662,13 @@ OtherIcons/Lock
orig: 100, 100 orig: 100, 100
offset: 0, 0 offset: 0, 0
index: -1 index: -1
OtherIcons/LockSmall
rotate: false
xy: 530, 720
size: 50, 50
orig: 50, 50
offset: 0, 0
index: -1
OtherIcons/MapEditor OtherIcons/MapEditor
rotate: false rotate: false
xy: 622, 1426 xy: 622, 1426
@ -692,7 +699,7 @@ OtherIcons/Multiplayer
index: -1 index: -1
OtherIcons/Nations OtherIcons/Nations
rotate: false rotate: false
xy: 530, 720 xy: 588, 720
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
@ -930,7 +937,7 @@ UnitActionIcons/Swap
index: -1 index: -1
OtherIcons/Terrains OtherIcons/Terrains
rotate: false rotate: false
xy: 1868, 1604 xy: 1868, 1546
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
@ -1308,14 +1315,14 @@ StatIcons/Population
index: -1 index: -1
StatIcons/Range StatIcons/Range
rotate: false rotate: false
xy: 646, 720 xy: 704, 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: 704, 720 xy: 762, 720
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
@ -1343,7 +1350,7 @@ StatIcons/Specialist
index: -1 index: -1
StatIcons/Strength StatIcons/Strength
rotate: false rotate: false
xy: 1868, 1662 xy: 1868, 1604
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0
@ -1392,14 +1399,14 @@ UnitActionIcons/Repair
index: -1 index: -1
UnitActionIcons/EnhanceReligion UnitActionIcons/EnhanceReligion
rotate: false rotate: false
xy: 1927, 1828 xy: 190, 716
size: 100, 100 size: 100, 100
orig: 100, 100 orig: 100, 100
offset: 0, 0 offset: 0, 0
index: -1 index: -1
UnitActionIcons/FoundReligion UnitActionIcons/FoundReligion
rotate: false rotate: false
xy: 1927, 1828 xy: 190, 716
size: 100, 100 size: 100, 100
orig: 100, 100 orig: 100, 100
offset: 0, 0 offset: 0, 0
@ -1483,7 +1490,7 @@ UnitActionIcons/SetUp
index: -1 index: -1
UnitActionIcons/ShowMore UnitActionIcons/ShowMore
rotate: false rotate: false
xy: 896, 805 xy: 1868, 1662
size: 50, 50 size: 50, 50
orig: 50, 50 orig: 50, 50
offset: 0, 0 offset: 0, 0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 579 KiB

After

Width:  |  Height:  |  Size: 580 KiB

View File

@ -437,7 +437,7 @@
"[+1 Happiness] from every [Public School]" "[+1 Happiness] from every [Public School]"
], ],
"row": 1, "row": 1,
"column": 5 "column": 4
}, },
{ {
"name": "Free Thought", "name": "Free Thought",
@ -447,21 +447,21 @@
], ],
"requires": ["Secularism"], "requires": ["Secularism"],
"row": 2, "row": 2,
"column": 1 "column": 2
}, },
{ {
"name": "Sovereignty", "name": "Sovereignty",
"uniques": ["[+1 Gold] from all [Science] buildings"], "uniques": ["[+1 Gold] from all [Science] buildings"],
"requires": ["Humanism"], "requires": ["Humanism"],
"row": 2, "row": 2,
"column": 5 "column": 4
}, },
{ {
"name": "Scientific Revolution", "name": "Scientific Revolution",
"uniques": ["Science gained from research agreements [+50]%"], "uniques": ["Science gained from research agreements [+50]%"],
"requires": ["Free Thought"], "requires": ["Free Thought"],
"row": 3, "row": 3,
"column": 1 "column": 2
}, },
{ {
"name": "Rationalism Complete", "name": "Rationalism Complete",
@ -555,13 +555,13 @@
"name": "Populism", "name": "Populism",
"uniques": ["[+25]% Strength <for [Wounded] units>"], "uniques": ["[+25]% Strength <for [Wounded] units>"],
"row": 1, "row": 1,
"column": 1 "column": 2
}, },
{ {
"name": "Militarism", "name": "Militarism",
"uniques": ["[Gold] cost of purchasing [All] units [-33]%"], "uniques": ["[Gold] cost of purchasing [All] units [-33]%"],
"row": 1, "row": 1,
"column": 5 "column": 4
}, },
{ {
"name": "Fascism", "name": "Fascism",
@ -571,7 +571,7 @@
], ],
"requires": ["Populism", "Militarism"], "requires": ["Populism", "Militarism"],
"row": 2, "row": 2,
"column": 3 "column": 2
}, },
{ {
"name": "Police State", "name": "Police State",
@ -582,7 +582,7 @@
// There are also some uniques regarding espoinage, which as of this writing is not yet implemented // There are also some uniques regarding espoinage, which as of this writing is not yet implemented
"requires": ["Militarism"], "requires": ["Militarism"],
"row": 2, "row": 2,
"column": 5 "column": 4
}, },
{ {
"name": "Total War", "name": "Total War",
@ -592,7 +592,7 @@
], ],
"requires": ["Police State", "Fascism"], "requires": ["Police State", "Fascism"],
"row": 3, "row": 3,
"column": 4 "column": 3
}, },
{ {
"name": "Autocracy Complete", "name": "Autocracy Complete",

View File

@ -440,7 +440,7 @@
"[+1 Happiness] from every [Public School]" "[+1 Happiness] from every [Public School]"
], ],
"row": 1, "row": 1,
"column": 5 "column": 4
}, },
{ {
"name": "Free Thought", "name": "Free Thought",
@ -450,21 +450,21 @@
], ],
"requires": ["Secularism"], "requires": ["Secularism"],
"row": 2, "row": 2,
"column": 1 "column": 2
}, },
{ {
"name": "Sovereignty", "name": "Sovereignty",
"uniques": ["[+15]% [Science] <while the empire is happy>"], "uniques": ["[+15]% [Science] <while the empire is happy>"],
"requires": ["Humanism"], "requires": ["Humanism"],
"row": 2, "row": 2,
"column": 5 "column": 4
}, },
{ {
"name": "Scientific Revolution", "name": "Scientific Revolution",
"uniques": ["[2] Free Technologies"], "uniques": ["[2] Free Technologies"],
"requires": ["Free Thought"], "requires": ["Free Thought"],
"row": 3, "row": 3,
"column": 1 "column": 2
}, },
{ {
"name": "Rationalism Complete", "name": "Rationalism Complete",
@ -555,13 +555,13 @@
"name": "Populism", "name": "Populism",
"uniques": ["[+25]% Strength <for [Wounded] units>"], "uniques": ["[+25]% Strength <for [Wounded] units>"],
"row": 1, "row": 1,
"column": 1 "column": 2
}, },
{ {
"name": "Militarism", "name": "Militarism",
"uniques": ["[Gold] cost of purchasing [All] units [-33]%"], "uniques": ["[Gold] cost of purchasing [All] units [-33]%"],
"row": 1, "row": 1,
"column": 5 "column": 4
}, },
{ {
"name": "Fascism", "name": "Fascism",
@ -570,7 +570,7 @@
], ],
"requires": ["Populism", "Militarism"], "requires": ["Populism", "Militarism"],
"row": 2, "row": 2,
"column": 3 "column": 2
}, },
{ {
"name": "Police State", "name": "Police State",
@ -580,7 +580,7 @@
], ],
"requires": ["Militarism"], "requires": ["Militarism"],
"row": 2, "row": 2,
"column": 5 "column": 4
}, },
{ {
"name": "Total War", "name": "Total War",
@ -590,7 +590,7 @@
], ],
"requires": ["Police State", "Fascism"], "requires": ["Police State", "Fascism"],
"row": 3, "row": 3,
"column": 4 "column": 3
}, },
{ {
"name": "Autocracy Complete", "name": "Autocracy Complete",

View File

@ -1426,12 +1426,19 @@ Unit type =
# Policies # Policies
Adopt =
Completed =
On adoption =
On completion =
Cannot be adopted together with =
Adopt policy = Adopt policy =
Adopt free policy = Adopt free policy =
Unlocked at = Unlocked at =
Gain 2 free technologies = Gain 2 free technologies =
All policies adopted = All policies adopted =
Policy branch: [branchName] = Policy branch: [branchName] =
Are you sure you want to adopt [branchName]? =
# Religions # Religions

View File

@ -1,7 +1,9 @@
package com.unciv.models.ruleset package com.unciv.models.ruleset
import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.unique.UniqueFlag import com.unciv.models.ruleset.unique.UniqueFlag
import com.unciv.models.ruleset.unique.UniqueTarget import com.unciv.models.ruleset.unique.UniqueTarget
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import com.unciv.ui.civilopedia.FormattedLine import com.unciv.ui.civilopedia.FormattedLine
@ -31,17 +33,13 @@ open class Policy : RulesetObject() {
/** Used in PolicyPickerScreen to display Policy properties */ /** Used in PolicyPickerScreen to display Policy properties */
fun getDescription(): String { fun getDescription(): String {
val policyText = ArrayList<String>() var text = uniques
policyText += name .filter { !it.contains(UniqueType.OnlyAvailableWhen.text) }
policyText += uniques .joinToString("\n", transform = { "$it".tr() })
if (policyBranchType != PolicyBranchType.BranchStart
if (policyBranchType != PolicyBranchType.BranchComplete) { && policyBranchType != PolicyBranchType.BranchComplete)
policyText += if (requires!!.isNotEmpty()) text = name + "\n" + text
"Requires [" + requires!!.joinToString { it.tr() } + "]" return text
else
"{Unlocked at} {${branch.era}}"
}
return policyText.joinToString("\n") { it.tr() }
} }
override fun makeLink() = "Policy/$name" override fun makeLink() = "Policy/$name"

View File

@ -10,6 +10,7 @@ class SkinStrings(skin: String = UncivGame.Current.settings.skin) {
val skinConfig = SkinCache[skin] ?: SkinConfig() val skinConfig = SkinCache[skin] ?: SkinConfig()
// Default shapes must always end with "Shape" so the UiElementDocsWriter can identify them // Default shapes must always end with "Shape" so the UiElementDocsWriter can identify them
val roundedEdgeRectangleSmallShape = skinLocation + "roundedEdgeRectangle-small"
val roundedEdgeRectangleShape = skinLocation + "roundedEdgeRectangle" val roundedEdgeRectangleShape = skinLocation + "roundedEdgeRectangle"
val rectangleWithOutlineShape = skinLocation + "rectangleWithOutline" val rectangleWithOutlineShape = skinLocation + "rectangleWithOutline"
val selectBoxShape = skinLocation + "select-box" val selectBoxShape = skinLocation + "select-box"

View File

@ -1,8 +1,13 @@
package com.unciv.ui.pickerscreens package com.unciv.ui.pickerscreens
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.Group
import com.badlogic.gdx.scenes.scene2d.ui.Button import com.badlogic.gdx.scenes.scene2d.ui.Button
import com.badlogic.gdx.scenes.scene2d.ui.Cell
import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Align
import com.unciv.UncivGame import com.unciv.UncivGame
import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.models.TutorialTrigger import com.unciv.models.TutorialTrigger
@ -10,25 +15,157 @@ import com.unciv.models.UncivSound
import com.unciv.models.ruleset.Policy import com.unciv.models.ruleset.Policy
import com.unciv.models.ruleset.Policy.PolicyBranchType import com.unciv.models.ruleset.Policy.PolicyBranchType
import com.unciv.models.ruleset.PolicyBranch import com.unciv.models.ruleset.PolicyBranch
import com.unciv.models.ruleset.unique.Unique
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import com.unciv.ui.images.ImageGetter import com.unciv.ui.images.ImageGetter
import com.unciv.ui.popup.ConfirmPopup
import com.unciv.ui.utils.BaseScreen import com.unciv.ui.utils.BaseScreen
import com.unciv.ui.utils.KeyCharAndCode import com.unciv.ui.utils.BorderedTable
import com.unciv.ui.utils.RecreateOnResize import com.unciv.ui.utils.RecreateOnResize
import com.unciv.ui.utils.extensions.addSeparator import com.unciv.ui.utils.extensions.addSeparator
import com.unciv.ui.utils.extensions.brighten
import com.unciv.ui.utils.extensions.center
import com.unciv.ui.utils.extensions.colorFromRGB
import com.unciv.ui.utils.extensions.darken
import com.unciv.ui.utils.extensions.disable import com.unciv.ui.utils.extensions.disable
import com.unciv.ui.utils.extensions.enable import com.unciv.ui.utils.extensions.enable
import com.unciv.ui.utils.extensions.onClick import com.unciv.ui.utils.extensions.onClick
import com.unciv.ui.utils.extensions.pad import com.unciv.ui.utils.extensions.pad
import com.unciv.ui.utils.extensions.toTextButton import com.unciv.ui.utils.extensions.toGroup
import com.unciv.ui.utils.extensions.toLabel
import com.unciv.ui.worldscreen.WorldScreen import com.unciv.ui.worldscreen.WorldScreen
import java.lang.Integer.max
import kotlin.math.abs
import kotlin.math.min import kotlin.math.min
object Colors {
val policyPickable = colorFromRGB(47,67,92).darken(0.3f)
val policyNotPickable = colorFromRGB(20, 20, 20)
val policySelected = colorFromRGB(37,87,82)
val branchCompleted = colorFromRGB(255, 205, 0)
val branchNotAdopted = colorFromRGB(10,90,130).darken(0.5f)
val branchAdopted = colorFromRGB(100, 90, 10).darken(0.5f)
}
object Sizes {
val paddingVertical = 10f
val paddingHorizontal = 20f
val paddingBetweenHor = 10f
val paddingBetweenVer = 20f
val iconSize = 50f
}
fun Policy.isAdopted() : Boolean {
val worldScreen = UncivGame.Current.worldScreen ?: return false
val viewingCiv = worldScreen.viewingCiv
return viewingCiv.policies.isAdopted(this.name)
}
fun Policy.isPickable() : Boolean {
val worldScreen = UncivGame.Current.worldScreen ?: return false
val viewingCiv = worldScreen.viewingCiv
if (!worldScreen.isPlayersTurn
|| worldScreen.viewingCiv.isSpectator() // viewingCiv var points to selectedCiv in case of spectator
|| viewingCiv.isDefeated()
|| viewingCiv.policies.isAdopted(this.name)
|| this.policyBranchType == PolicyBranchType.BranchComplete
|| !viewingCiv.policies.isAdoptable(this)
|| !viewingCiv.policies.canAdoptPolicy()
)
return false
return true
}
class PolicyButton(val policy: Policy, size: Float = 30f) : BorderedTable(
style = BaseScreen.skinStrings.roundedEdgeRectangleSmallShape,
borderSize = 2f
) {
val icon = ImageGetter.getImage("PolicyIcons/" + policy.name)
val highlight = ImageGetter.getImage("UnitFlagIcons/UnitFlagSelection")
var isSelected = false
set(value) {
field = value
updateState()
}
init {
icon.setSize(size*0.7f, size*0.7f)
highlight.setSize(size*1.35f, size*1.35f)
addActor(icon)
add(highlight).center()
updateState()
pack()
width = size
height = size
icon.toFront()
icon.center(this)
highlight.toBack()
highlight.isVisible = false
highlight.center(this)
}
fun onClick(function: () -> Unit): PolicyButton {
(this as Actor).onClick(function = {
function()
updateState()
})
return this
}
fun updateState() {
val worldScreen = UncivGame.Current.worldScreen ?: return
val viewingCiv = worldScreen.viewingCiv
val isPickable = policy.isPickable()
val isAdopted = viewingCiv.policies.isAdopted(policy.name)
highlight.isVisible = isSelected
when {
isSelected && isPickable -> {
setBackgroundColor(Colors.policySelected)
}
isPickable -> {
setBackgroundColor(Colors.policyPickable)
}
isAdopted -> {
icon.color = Color.GOLD
setBackgroundColor(colorFromRGB(10,90,100).darken(0.8f))
}
else -> {
icon.color.a = 0.2f
setBackgroundColor(Colors.policyNotPickable)
}
}
}
}
class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo = worldScreen.viewingCiv) class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo = worldScreen.viewingCiv)
: PickerScreen(), RecreateOnResize { : PickerScreen(), RecreateOnResize {
internal val viewingCiv: CivilizationInfo = civInfo internal val viewingCiv: CivilizationInfo = civInfo
private var pickedPolicy: Policy? = null
private var policyNameToButton = HashMap<String, BorderedTable>()
private var selectedPolicyButton: PolicyButton? = null
init { init {
val policies = viewingCiv.policies val policies = viewingCiv.policies
@ -49,15 +186,15 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo
closeButton.disable() closeButton.disable()
rightSideButton.onClick(UncivSound.Policy) { rightSideButton.onClick(UncivSound.Policy) {
val policy = pickedPolicy!! val policy = selectedPolicyButton!!.policy
// Evil people clicking on buttons too fast to confuse the screen - #4977 // Evil people clicking on buttons too fast to confuse the screen - #4977
if (!policyIsPickable(policy)) return@onClick if (!policy.isPickable()) return@onClick
viewingCiv.policies.adopt(policy) viewingCiv.policies.adopt(policy)
// If we've moved to another screen in the meantime (great person pick, victory screen) ignore this // If we've moved to another screen in the meantime (great person pick, victory screen) ignore this
if (game.screen !is PolicyPickerScreen || !policies.canAdoptPolicy()) { if (game.screen !is PolicyPickerScreen) {
game.popScreen() game.popScreen()
} else { } else {
val policyScreen = PolicyPickerScreen(worldScreen) val policyScreen = PolicyPickerScreen(worldScreen)
@ -97,18 +234,29 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo
// Actually create and distribute the policy branches // Actually create and distribute the policy branches
var wrapper = Table() var wrapper = Table()
var wrapperWidth = 0f // Either pack() each round or cumulate separately var wrapperWidth = 0f // Either pack() each round or cumulate separately
for ( (index, branch) in branches.values.withIndex()) {
var leftToRight = true
var index = 0
var switchOnIndex = rowChangeCount
while (index < branches.size) {
val branch = branches.values.elementAt(index)
val branchGroup = getBranchGroup(branch) val branchGroup = getBranchGroup(branch)
wrapperWidth += branchGroup.width + 20f // 20 is the horizontal padding in wrapper.add wrapperWidth += branchGroup.width + 20f // 20 is the horizontal padding in wrapper.add
if (index > 0 && index % rowChangeCount == 0 || wrapperWidth > rowChangeWidth) { if (index > 0 && index == switchOnIndex || wrapperWidth > rowChangeWidth) {
index += rowChangeCount - if (leftToRight) 1 else - 2
switchOnIndex -= if (leftToRight) 1 else rowChangeCount - 2
leftToRight = !leftToRight
topTable.add(wrapper).pad(5f,10f) topTable.add(wrapper).pad(5f,10f)
topTable.addSeparator() topTable.addSeparator().pad(0f, 10f)
wrapper = Table() wrapper = Table()
wrapperWidth = branchGroup.width wrapperWidth = 0f
continue
} }
wrapper.add(branchGroup).pad(10f) wrapper.add(branchGroup).growY().growX()
index += if (leftToRight) 1 else -1
} }
topTable.add(wrapper).pad(5f,10f) topTable.add(wrapper).pad(5f,10f)
@ -116,7 +264,7 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo
// total padding, or up to where the axis is centered, whichever is smaller // total padding, or up to where the axis is centered, whichever is smaller
splitPane.pack() // packs topTable but also ensures scrollPane.maxXY is calculated splitPane.pack() // packs topTable but also ensures scrollPane.maxXY is calculated
if (topTable.height > scrollPane.height) { if (topTable.height > scrollPane.height) {
val vScroll = min(15f, scrollPane.maxY / 2) val vScroll = min(0f, scrollPane.maxY / 2)
scrollPane.scrollY = vScroll scrollPane.scrollY = vScroll
} }
if (topTable.width > scrollPane.width) { if (topTable.width > scrollPane.width) {
@ -126,31 +274,25 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo
scrollPane.updateVisualScroll() scrollPane.updateVisualScroll()
} }
private fun policyIsPickable(policy: Policy):Boolean { private fun pickPolicy(button: PolicyButton) {
if (!worldScreen.isPlayersTurn
|| worldScreen.viewingCiv.isSpectator() // viewingCiv var points to selectedCiv in case of spectator
|| viewingCiv.isDefeated()
|| viewingCiv.policies.isAdopted(policy.name)
|| policy.policyBranchType == PolicyBranchType.BranchComplete
|| !viewingCiv.policies.isAdoptable(policy)
|| !viewingCiv.policies.canAdoptPolicy()
)
return false
return true
}
private fun pickPolicy(policy: Policy) { val policy = button.policy
if (!policyIsPickable(policy)) {
rightSideButton.isVisible = !viewingCiv.policies.isAdopted(policy.name)
if (!policy.isPickable()) {
rightSideButton.disable() rightSideButton.disable()
} else { } else {
rightSideButton.enable() rightSideButton.enable()
} }
if (viewingCiv.gameInfo.gameParameters.godMode && pickedPolicy == policy if (viewingCiv.gameInfo.gameParameters.godMode && selectedPolicyButton?.policy == policy
&& viewingCiv.policies.isAdoptable(policy)) { && viewingCiv.policies.isAdoptable(policy)) {
viewingCiv.policies.adopt(policy) viewingCiv.policies.adopt(policy)
game.replaceCurrentScreen(PolicyPickerScreen(worldScreen)) game.replaceCurrentScreen(PolicyPickerScreen(worldScreen))
} }
pickedPolicy = policy
selectedPolicyButton?.isSelected = false
selectedPolicyButton = button
selectedPolicyButton?.isSelected = true
descriptionLabel.setText(policy.getDescription()) descriptionLabel.setText(policy.getDescription())
} }
@ -160,55 +302,342 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo
* @param branch the policy branch to display * @param branch the policy branch to display
* @return a [Table], with outer padding _zero_ * @return a [Table], with outer padding _zero_
*/ */
private fun getBranchGroup(branch: PolicyBranch): Table { private fun getBranchGroup(branch: PolicyBranch): Group {
val branchGroup = Table()
branchGroup.row()
branchGroup.add(getPolicyButton(branch, false))
.minWidth(160f).padBottom(15f).row()
var currentRow = 1 // Calculate preferred size
var currentColumn = 1 val maxCol = max(5, branch.policies.maxOf { it.column })
val branchTable = Table() val maxRow = branch.policies.maxOf { it.row }
for (policy in branch.policies) {
if (policy.policyBranchType == PolicyBranchType.BranchComplete) continue val prefWidth = Sizes.paddingHorizontal*2 + Sizes.iconSize*maxCol - (Sizes.iconSize-Sizes.paddingBetweenHor)*(maxCol-1)/2
if (policy.row > currentRow) { val prefHeight = Sizes.paddingVertical*2 + Sizes.iconSize*maxRow + Sizes.paddingBetweenVer*(maxRow - 1)
branchTable.row().pad(2.5f)
currentRow++ // Main table
currentColumn = 1 val colorBg = if (branch.isAdopted()) Colors.branchAdopted else Colors.branchNotAdopted
} val branchGroup = BorderedTable(innerColor = colorBg)
if (policy.column > currentColumn) {
branchTable.add().colspan(policy.column - currentColumn) // empty space // Header
} val header = getBranchHeader(branch)
branchTable.add(getPolicyButton(policy, true)).colspan(2) branchGroup.add(header).growX().row()
currentColumn = policy.column + 2
// Description
val onAdoption = branch.getDescription()
val onCompletion = branch.policies.last().getDescription()
var text = ""
if (viewingCiv.gameInfo.ruleSet.eras[branch.era]!!.eraNumber > viewingCiv.getEraNumber())
text += "{Unlocked at} {${branch.era}}" + "\n\n"
text += "{On adoption}:" + "\n\n" + onAdoption + "\n\n" +
"{On completion}:" + "\n\n" + onCompletion
val labelTable = Table()
val label = text.toLabel(fontSize = 13)
label.setFillParent(false)
label.setAlignment(Align.topLeft)
label.wrap = true
labelTable.add(label).pad(7f,20f, 10f, 20f).grow().row()
val exclusive = ArrayList<String>()
branch.uniqueMap[UniqueType.OnlyAvailableWhen.text]?.forEach {
it.conditionals.forEach { exclusive += it.params }
} }
branchGroup.add(branchTable).height(150f).row() if (exclusive.isNotEmpty()) {
val forbidden = ("{Cannot be adopted together with} " + exclusive.joinToString()).toLabel(Color.RED, 13)
forbidden.setFillParent(false)
forbidden.setAlignment(Align.topLeft)
forbidden.wrap = true
labelTable.add(forbidden).pad(0f, 20f, 17f, 20f).grow()
}
// Add the finisher button. // Top button
branchGroup.add(getPolicyButton(branch.policies.last(), false)).padTop(15f) val topBtn = getTopButton(branch)
val topBtnCell = branchGroup.add(topBtn).growX().pad(10f, 10f, 0f, 10f)
topBtnCell.row()
// Main grid
val group = Group()
group.width = prefWidth
group.height = prefHeight
// Calculate grid points coordinates
val startX = Sizes.paddingHorizontal
val endX = prefWidth - Sizes.paddingHorizontal - Sizes.iconSize
val deltaX = (endX - startX)/(maxCol - 1)
val startY = prefHeight - Sizes.paddingVertical - Sizes.iconSize
val endY = Sizes.paddingVertical
val deltaY = (startY - endY)/(maxRow - 1)
val coords = Array(maxRow+1) { Array(maxCol+1) {Pair(0f,0f)}}
var row = 1
var col: Int
var posX: Float
var posY = startY
while (row <= maxRow) {
col = 1
posX = startX
while (col <= maxCol) {
coords[row][col] = Pair(posX, posY)
col += 1
posX += deltaX
}
row += 1
posY -= deltaY
}
// Create policy buttons at calculated coordinates
for (policy in branch.policies) {
if (policy.policyBranchType == PolicyBranchType.BranchComplete)
continue
val button = getPolicyButton(policy, size = Sizes.iconSize)
group.addActor(button)
val policyX = coords[policy.row][policy.column].first
val policyY = coords[policy.row][policy.column].second
button.x = policyX
button.y = policyY
policyNameToButton[policy.name] = button
}
// Draw connecting lines
drawLines(branch)
val groupCell = branchGroup.add(group).minWidth(prefWidth).expandY().top()
branchGroup.row()
// Setup header clicks
header.onClick {
val newActor = if (groupCell.actor == group) labelTable else group
val rotate = if (groupCell.actor == group) -90f else 90f
if (groupCell.actor == group)
topBtnCell.clearActor()
else
topBtnCell.setActor(topBtn)
groupCell.clearActor()
groupCell.setActor(newActor)
((header.cells[0].actor as Table).cells[0] as Cell<Actor>).clearActor()
((header.cells[0].actor as Table).cells[0] as Cell<Actor>).setActor(ImageGetter.
getImage("OtherIcons/BackArrow").apply { rotation = rotate}.toGroup(10f))
}
// Ensure dimensions are calculated // Ensure dimensions are calculated
branchGroup.pack() branchGroup.pack()
return branchGroup return branchGroup
} }
private fun getPolicyButton(policy: Policy, image: Boolean): Button {
var policyButton = Button(skin)
if (image) { private fun drawLines(branch: PolicyBranch) {
val policyImage = ImageGetter.getImage("PolicyIcons/" + policy.name)
policyButton.add(policyImage).size(30f) for (policy in branch.policies) {
} else {
policyButton = policy.name.toTextButton() if (policy.policyBranchType == PolicyBranchType.BranchComplete)
continue
if (policy.requires == null)
continue
val policyButton = policyNameToButton[policy.name]
val group = policyButton!!.parent
for (prereqName in policy.requires!!) {
if (prereqName == branch.name)
continue
val prereqButton = policyNameToButton[prereqName]
drawLine(group,
// Top center
policyButton.x+policyButton.width/2,
policyButton.y+policyButton.height,
// Bottom center
prereqButton!!.x + prereqButton.width/2,
prereqButton.y)
}
} }
if (viewingCiv.policies.isAdopted(policy.name)) policyButton.color = Color.GREEN // existing }
else if (!viewingCiv.policies.isAdoptable(policy)) policyButton.color = Color.GRAY // non-available
private fun drawLine(group: Group, policyX: Float, policyY: Float, prereqX: Float, prereqY:Float) {
policyButton.onClick { pickPolicy(policy) } val lineColor = Color.WHITE
policyButton.pack() val lineSize = 2f
return policyButton
if (policyX != prereqX) {
val r = 3f
val deltaX = policyX - prereqX // can be > 0 or < 0
val deltaY = prereqY - policyY // always > 0
val bendingY = Sizes.paddingBetweenVer / 2
// Top line
val line = ImageGetter.getWhiteDot().apply {
width = lineSize
height = deltaY - bendingY - r
x = prereqX - width / 2
y = prereqY - height
}
// Bottom line
val line1 = ImageGetter.getWhiteDot().apply {
width = lineSize
height = bendingY - r
x = policyX - width / 2
y = policyY
}
// Middle line
val line2 = ImageGetter.getWhiteDot().apply {
width = abs(deltaX) - 2*r
height = lineSize
x = policyX + (if (deltaX > 0f) -width - r else r)
y = policyY + bendingY - lineSize/2
}
val line3: Image? // Top -> Middle
val line4: Image? // Bottom -> Middle
if (deltaX < 0) {
line3 = ImageGetter.getLine(line2.x + line2.width - lineSize/2, line2.y + lineSize/2,
line.x + lineSize/2, line.y + lineSize/2, lineSize)
line4 = ImageGetter.getLine(line2.x, line2.y + lineSize/2,
line1.x + lineSize/2, line1.y + line1.height, lineSize)
} else {
line3 = ImageGetter.getLine(line2.x, line2.y + line2.height/2,
line.x + lineSize/2, line.y, lineSize)
line4 = ImageGetter.getLine(line2.x + line2.width - lineSize/2, line2.y + lineSize/2,
line1.x + lineSize/2, line1.y + line1.height - lineSize/2, lineSize)
}
line.color = lineColor
line1.color = lineColor
line2.color = lineColor
line3.color = lineColor
line4.color = lineColor
group.addActor(line)
group.addActor(line1)
group.addActor(line2)
group.addActor(line3)
group.addActor(line4)
} else {
val line = ImageGetter.getWhiteDot().apply {
width = lineSize
height = prereqY - policyY
x = policyX - width / 2
y = policyY
}
line.color = lineColor
group.addActor(line)
}
}
private fun getBranchHeader(branch: PolicyBranch): Table {
val header = BorderedTable(innerColor = colorFromRGB(47,90,92), borderSize = 5f)
header.pad(5f)
val table = Table()
val iconPath = "PolicyBranchIcons/" + branch.name
val icon = if (ImageGetter.imageExists(iconPath)) ImageGetter.getImage(iconPath).apply {
setOrigin(Align.center)
setOrigin(25f, 25f)
align = Align.center
}.toGroup(15f) else null
val expandIcon = ImageGetter.getImage("OtherIcons/BackArrow").apply { rotation = 90f }.toGroup(10f)
table.add(expandIcon).minWidth(15f).expandX().left()
table.add(branch.name.uppercase().toLabel(fontSize = 14).apply { setAlignment(Align.center) }).center()
table.add(icon).expandX().left().padLeft(5f)
header.add(table).minWidth(150f).growX()
header.pack()
return header
}
private fun getTopButton(branch: PolicyBranch): Table {
val policy: Policy
val text: String
val lockIcon = ImageGetter.getImage("OtherIcons/LockSmall")
.apply { color = Color.WHITE }.toGroup(15f)
lockIcon.isVisible = false
if (viewingCiv.policies.isAdopted(branch.name)) {
policy = branch.policies.last()
text = "Completed"
} else if (viewingCiv.gameInfo.ruleSet.eras[branch.era]!!.eraNumber > viewingCiv.getEraNumber()) {
policy = branch
text = branch.era
} else {
policy = branch
text = "Adopt"
}
val label = text.toLabel(fontSize = 14)
label.setAlignment(Align.center)
val color = when {
policy.isPickable() -> Colors.policyPickable
viewingCiv.policies.isAdopted(policy.name) -> {
label.color = colorFromRGB(150, 70, 40)
Colors.branchCompleted
}
else -> {
lockIcon.isVisible = true
label.color.a = 0.5f
Colors.policyNotPickable}
}
val table = BorderedTable(style = skinStrings.roundedEdgeRectangleSmallShape, innerColor = color, borderSize = 2f)
table.add(label).minHeight(30f).minWidth(150f).growX()
table.addActor(lockIcon)
table.onClick(function = {})
table.onClick {
if (policy.isPickable())
ConfirmPopup(
this,
"Are you sure you want to adopt [${branch.name}]?",
"Adopt", true, action = {
viewingCiv.policies.adopt(policy, false)
val policyScreen = PolicyPickerScreen(worldScreen)
policyScreen.scrollPane.scrollPercentX = scrollPane.scrollPercentX
policyScreen.scrollPane.scrollPercentY = scrollPane.scrollPercentY
policyScreen.scrollPane.updateVisualScroll()
game.replaceCurrentScreen(policyScreen)
}
).open(force = true)
}
table.pack()
lockIcon.setPosition(table.width, table.height / 2 - lockIcon.height/2)
return table
}
private fun getPolicyButton(policy: Policy, size: Float = 30f): BorderedTable {
val button = PolicyButton(policy, size = size)
button.onClick { pickPolicy(button = button) }
return button
} }
override fun recreate(): BaseScreen = PolicyPickerScreen(worldScreen, viewingCiv) override fun recreate(): BaseScreen = PolicyPickerScreen(worldScreen, viewingCiv)

View File

@ -0,0 +1,44 @@
package com.unciv.ui.utils
import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.Image
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.unciv.ui.utils.extensions.center
open class BorderedTable(
val style: String = BaseScreen.skinStrings.rectangleWithOutlineShape,
val innerColor: Color = Color.BLACK,
val borderSize: Float = 5f
) : Table() {
private var bgBorder: Image = Image(BaseScreen.skinStrings.getUiBackground("", style, Color.WHITE))
private var bgInner: Image = Image(BaseScreen.skinStrings.getUiBackground("", style, innerColor))
init {
this.addActor(bgBorder)
this.addActor(bgInner)
bgInner.toBack()
bgBorder.toBack()
}
fun setBackgroundColor(color: Color) {
bgInner.remove()
bgInner = Image(BaseScreen.skinStrings.getUiBackground("", style, color))
addActor(bgInner)
bgInner.zIndex = bgBorder.zIndex + 1
sizeChanged()
}
override fun sizeChanged() {
super.sizeChanged()
bgBorder.setSize(width + borderSize, height + borderSize)
bgInner.setSize(width, height)
bgBorder.center(this)
bgInner.center(this)
}
}