diff --git a/android/Images.PolicyIcons/PolicyBranchIcons/Autocracy.png b/android/Images.PolicyIcons/PolicyBranchIcons/Autocracy.png new file mode 100644 index 0000000000..2e0800a911 Binary files /dev/null and b/android/Images.PolicyIcons/PolicyBranchIcons/Autocracy.png differ diff --git a/android/Images.PolicyIcons/PolicyBranchIcons/Commerce.png b/android/Images.PolicyIcons/PolicyBranchIcons/Commerce.png new file mode 100644 index 0000000000..34056f81e3 Binary files /dev/null and b/android/Images.PolicyIcons/PolicyBranchIcons/Commerce.png differ diff --git a/android/Images.PolicyIcons/PolicyBranchIcons/Freedom.png b/android/Images.PolicyIcons/PolicyBranchIcons/Freedom.png new file mode 100644 index 0000000000..56398899e2 Binary files /dev/null and b/android/Images.PolicyIcons/PolicyBranchIcons/Freedom.png differ diff --git a/android/Images.PolicyIcons/PolicyBranchIcons/Honor.png b/android/Images.PolicyIcons/PolicyBranchIcons/Honor.png new file mode 100644 index 0000000000..03688b1f13 Binary files /dev/null and b/android/Images.PolicyIcons/PolicyBranchIcons/Honor.png differ diff --git a/android/Images.PolicyIcons/PolicyBranchIcons/Liberty.png b/android/Images.PolicyIcons/PolicyBranchIcons/Liberty.png new file mode 100644 index 0000000000..3130214904 Binary files /dev/null and b/android/Images.PolicyIcons/PolicyBranchIcons/Liberty.png differ diff --git a/android/Images.PolicyIcons/PolicyBranchIcons/Order.png b/android/Images.PolicyIcons/PolicyBranchIcons/Order.png new file mode 100644 index 0000000000..11dfa8e294 Binary files /dev/null and b/android/Images.PolicyIcons/PolicyBranchIcons/Order.png differ diff --git a/android/Images.PolicyIcons/PolicyBranchIcons/Patronage.png b/android/Images.PolicyIcons/PolicyBranchIcons/Patronage.png new file mode 100644 index 0000000000..1e46cb33e9 Binary files /dev/null and b/android/Images.PolicyIcons/PolicyBranchIcons/Patronage.png differ diff --git a/android/Images.PolicyIcons/PolicyBranchIcons/Piety.png b/android/Images.PolicyIcons/PolicyBranchIcons/Piety.png new file mode 100644 index 0000000000..6883237923 Binary files /dev/null and b/android/Images.PolicyIcons/PolicyBranchIcons/Piety.png differ diff --git a/android/Images.PolicyIcons/PolicyBranchIcons/Rationalism.png b/android/Images.PolicyIcons/PolicyBranchIcons/Rationalism.png new file mode 100644 index 0000000000..07d7c7a6dc Binary files /dev/null and b/android/Images.PolicyIcons/PolicyBranchIcons/Rationalism.png differ diff --git a/android/Images.PolicyIcons/PolicyBranchIcons/Tradition.png b/android/Images.PolicyIcons/PolicyBranchIcons/Tradition.png new file mode 100644 index 0000000000..ad591cc6c2 Binary files /dev/null and b/android/Images.PolicyIcons/PolicyBranchIcons/Tradition.png differ diff --git a/android/Images.Skin/Skins/Minimal/roundedEdgeRectangle-small.9.png b/android/Images.Skin/Skins/Minimal/roundedEdgeRectangle-small.9.png new file mode 100644 index 0000000000..a470804426 Binary files /dev/null and b/android/Images.Skin/Skins/Minimal/roundedEdgeRectangle-small.9.png differ diff --git a/android/Images/OtherIcons/LockSmall.png b/android/Images/OtherIcons/LockSmall.png new file mode 100644 index 0000000000..906fdd8302 Binary files /dev/null and b/android/Images/OtherIcons/LockSmall.png differ diff --git a/android/assets/PolicyIcons.atlas b/android/assets/PolicyIcons.atlas index bce3d41598..8737a6fce7 100644 --- a/android/assets/PolicyIcons.atlas +++ b/android/assets/PolicyIcons.atlas @@ -4,6 +4,69 @@ size: 2048, 128 format: RGBA8888 filter: MipMapLinearLinear, MipMapLinearLinear 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 rotate: false xy: 4, 62 @@ -20,337 +83,344 @@ PolicyIcons/Aristocracy index: -1 PolicyIcons/Citizenship rotate: false - xy: 62, 62 + xy: 62, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Civil Society rotate: false - xy: 62, 4 + xy: 120, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Collective Rule rotate: false - xy: 120, 62 + xy: 120, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Communism +PolicyBranchIcons/Freedom rotate: false xy: 120, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Constitution - rotate: false - xy: 178, 62 - size: 50, 50 - orig: 50, 50 - offset: 0, 0 - index: -1 -PolicyIcons/Cultural Diplomacy +PolicyIcons/Communism rotate: false xy: 178, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 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 xy: 236, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Discipline +PolicyIcons/Cultural Diplomacy rotate: false xy: 236, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Educated Elite +PolicyIcons/Democracy rotate: false xy: 294, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Fascism +PolicyIcons/Discipline rotate: false xy: 294, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Free Religion +PolicyIcons/Educated Elite rotate: false xy: 352, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Free Speech +PolicyIcons/Fascism rotate: false xy: 352, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Free Thought +PolicyIcons/Free Religion rotate: false xy: 410, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Humanism +PolicyIcons/Free Speech rotate: false xy: 410, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Landed Elite +PolicyIcons/Free Thought rotate: false xy: 468, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Legalism - rotate: false - xy: 468, 4 - size: 50, 50 - orig: 50, 50 - offset: 0, 0 - index: -1 -PolicyIcons/Mandate Of Heaven +PolicyIcons/Humanism rotate: false xy: 526, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Mercantilism +PolicyIcons/Landed Elite rotate: false xy: 526, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Merchant Navy +PolicyIcons/Legalism rotate: false xy: 584, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Meritocracy - rotate: false - xy: 584, 4 - size: 50, 50 - orig: 50, 50 - offset: 0, 0 - index: -1 -PolicyIcons/Militarism +PolicyIcons/Mandate Of Heaven rotate: false xy: 642, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Military Caste +PolicyIcons/Mercantilism rotate: false xy: 642, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Military Tradition +PolicyIcons/Merchant Navy rotate: false xy: 700, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Monarchy +PolicyIcons/Meritocracy rotate: false xy: 700, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Nationalism +PolicyIcons/Militarism rotate: false xy: 758, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Naval Tradition +PolicyIcons/Military Caste rotate: false xy: 758, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Oligarchy +PolicyIcons/Monarchy rotate: false xy: 816, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Organized Religion +PolicyIcons/Nationalism rotate: false xy: 816, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Philantropy +PolicyIcons/Naval Tradition rotate: false xy: 874, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Planned Economy +PolicyIcons/Oligarchy rotate: false xy: 874, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Police State +PolicyIcons/Organized Religion rotate: false xy: 932, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Populism - rotate: false - xy: 932, 4 - size: 50, 50 - orig: 50, 50 - offset: 0, 0 - index: -1 -PolicyIcons/Professional Army +PolicyIcons/Philantropy rotate: false xy: 990, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Protectionism - rotate: false - xy: 990, 4 - size: 50, 50 - orig: 50, 50 - offset: 0, 0 - index: -1 -PolicyIcons/Reformation +PolicyIcons/Planned Economy rotate: false xy: 1048, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Representation +PolicyIcons/Police State rotate: false xy: 1048, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Republic +PolicyIcons/Populism rotate: false xy: 1106, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Scholasticism +PolicyIcons/Professional Army rotate: false xy: 1106, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Scientific Revolution +PolicyIcons/Protectionism rotate: false xy: 1164, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Secularism - rotate: false - xy: 1164, 4 - size: 50, 50 - orig: 50, 50 - offset: 0, 0 - index: -1 -PolicyIcons/Socialism +PolicyIcons/Reformation rotate: false xy: 1222, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Sovereignty +PolicyIcons/Representation rotate: false xy: 1222, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Theocracy +PolicyIcons/Republic rotate: false xy: 1280, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Total War +PolicyIcons/Scholasticism rotate: false xy: 1280, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Trade Unions +PolicyIcons/Scientific Revolution rotate: false xy: 1338, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/United Front +PolicyIcons/Secularism rotate: false xy: 1338, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Universal Suffrage +PolicyIcons/Socialism rotate: false xy: 1396, 62 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 -PolicyIcons/Warrior Code +PolicyIcons/Sovereignty rotate: false xy: 1396, 4 size: 50, 50 orig: 50, 50 offset: 0, 0 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 diff --git a/android/assets/PolicyIcons.png b/android/assets/PolicyIcons.png index 8a20ff1784..75fbaf4083 100644 Binary files a/android/assets/PolicyIcons.png and b/android/assets/PolicyIcons.png differ diff --git a/android/assets/Skin.atlas b/android/assets/Skin.atlas index 5234b2dd8f..c397eef4c0 100644 --- a/android/assets/Skin.atlas +++ b/android/assets/Skin.atlas @@ -1,12 +1,12 @@ Skin.png -size: 256, 64 +size: 128, 128 format: RGBA8888 filter: Linear, Linear repeat: none Skins/Minimal/checkbox rotate: false - xy: 199, 23 + xy: 52, 16 size: 31, 31 split: 0, 0, 0, 0 orig: 31, 31 @@ -14,7 +14,7 @@ Skins/Minimal/checkbox index: -1 Skins/Minimal/checkbox-pressed rotate: false - xy: 160, 23 + xy: 64, 55 size: 31, 31 split: 0, 0, 0, 0 orig: 31, 31 @@ -22,7 +22,7 @@ Skins/Minimal/checkbox-pressed index: -1 Skins/Minimal/rectangleWithOutline rotate: false - xy: 64, 13 + xy: 112, 121 size: 3, 3 split: 0, 0, 0, 0 orig: 3, 3 @@ -30,16 +30,25 @@ Skins/Minimal/rectangleWithOutline index: -1 Skins/Minimal/roundedEdgeRectangle rotate: false - xy: 4, 4 + xy: 4, 74 size: 52, 50 split: 19, 20, 19, 21 pad: 12, 13, 7, 7 orig: 52, 50 offset: 0, 0 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 rotate: false - xy: 112, 24 + xy: 64, 94 size: 40, 30 split: 7, 9, 7, 7 orig: 40, 30 @@ -47,7 +56,7 @@ Skins/Minimal/select-box index: -1 Skins/Minimal/select-box-pressed rotate: false - xy: 64, 24 + xy: 4, 36 size: 40, 30 split: 7, 9, 7, 7 orig: 40, 30 diff --git a/android/assets/Skin.png b/android/assets/Skin.png index 752f40e73e..37a6026475 100644 Binary files a/android/assets/Skin.png and b/android/assets/Skin.png differ diff --git a/android/assets/game.atlas b/android/assets/game.atlas index c63a423869..b2c900cd00 100644 --- a/android/assets/game.atlas +++ b/android/assets/game.atlas @@ -111,21 +111,21 @@ EmojiIcons/Happiness index: -1 EmojiIcons/Production rotate: false - xy: 588, 720 + xy: 646, 720 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 EmojiIcons/Science rotate: false - xy: 762, 720 + xy: 896, 805 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 EmojiIcons/Turn rotate: false - xy: 1868, 1546 + xy: 1270, 962 size: 50, 50 orig: 50, 50 offset: 0, 0 @@ -370,35 +370,56 @@ ImprovementIcons/Trading post index: -1 NotificationIcons/EnhanceReligion rotate: false - xy: 190, 716 + xy: 1927, 1828 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 NotificationIcons/FoundPantheon rotate: false - xy: 190, 716 + xy: 1927, 1828 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 NotificationIcons/FoundReligion rotate: false - xy: 190, 716 + xy: 1927, 1828 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 NotificationIcons/ReformReligion rotate: false - xy: 190, 716 + xy: 1927, 1828 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 StatIcons/Faith 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 orig: 100, 100 offset: 0, 0 @@ -503,7 +524,7 @@ OtherIcons/Banner index: -1 OtherIcons/Camera rotate: false - xy: 1270, 987 + xy: 1328, 1045 size: 25, 25 orig: 25, 25 offset: 0, 0 @@ -634,27 +655,6 @@ OtherIcons/Load orig: 100, 100 offset: 0, 0 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 rotate: false xy: 730, 1642 @@ -662,6 +662,13 @@ OtherIcons/Lock orig: 100, 100 offset: 0, 0 index: -1 +OtherIcons/LockSmall + rotate: false + xy: 530, 720 + size: 50, 50 + orig: 50, 50 + offset: 0, 0 + index: -1 OtherIcons/MapEditor rotate: false xy: 622, 1426 @@ -692,7 +699,7 @@ OtherIcons/Multiplayer index: -1 OtherIcons/Nations rotate: false - xy: 530, 720 + xy: 588, 720 size: 50, 50 orig: 50, 50 offset: 0, 0 @@ -930,7 +937,7 @@ UnitActionIcons/Swap index: -1 OtherIcons/Terrains rotate: false - xy: 1868, 1604 + xy: 1868, 1546 size: 50, 50 orig: 50, 50 offset: 0, 0 @@ -1308,14 +1315,14 @@ StatIcons/Population index: -1 StatIcons/Range rotate: false - xy: 646, 720 + xy: 704, 720 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 StatIcons/RangedStrength rotate: false - xy: 704, 720 + xy: 762, 720 size: 50, 50 orig: 50, 50 offset: 0, 0 @@ -1343,7 +1350,7 @@ StatIcons/Specialist index: -1 StatIcons/Strength rotate: false - xy: 1868, 1662 + xy: 1868, 1604 size: 50, 50 orig: 50, 50 offset: 0, 0 @@ -1392,14 +1399,14 @@ UnitActionIcons/Repair index: -1 UnitActionIcons/EnhanceReligion rotate: false - xy: 1927, 1828 + xy: 190, 716 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitActionIcons/FoundReligion rotate: false - xy: 1927, 1828 + xy: 190, 716 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -1483,7 +1490,7 @@ UnitActionIcons/SetUp index: -1 UnitActionIcons/ShowMore rotate: false - xy: 896, 805 + xy: 1868, 1662 size: 50, 50 orig: 50, 50 offset: 0, 0 diff --git a/android/assets/game.png b/android/assets/game.png index 6bc23e34f9..79b18b4d53 100644 Binary files a/android/assets/game.png and b/android/assets/game.png differ diff --git a/android/assets/jsons/Civ V - Gods & Kings/Policies.json b/android/assets/jsons/Civ V - Gods & Kings/Policies.json index 7ad0ccd461..03f19304db 100644 --- a/android/assets/jsons/Civ V - Gods & Kings/Policies.json +++ b/android/assets/jsons/Civ V - Gods & Kings/Policies.json @@ -437,7 +437,7 @@ "[+1 Happiness] from every [Public School]" ], "row": 1, - "column": 5 + "column": 4 }, { "name": "Free Thought", @@ -447,21 +447,21 @@ ], "requires": ["Secularism"], "row": 2, - "column": 1 + "column": 2 }, { "name": "Sovereignty", "uniques": ["[+1 Gold] from all [Science] buildings"], "requires": ["Humanism"], "row": 2, - "column": 5 + "column": 4 }, { "name": "Scientific Revolution", "uniques": ["Science gained from research agreements [+50]%"], "requires": ["Free Thought"], "row": 3, - "column": 1 + "column": 2 }, { "name": "Rationalism Complete", @@ -555,13 +555,13 @@ "name": "Populism", "uniques": ["[+25]% Strength "], "row": 1, - "column": 1 + "column": 2 }, { "name": "Militarism", "uniques": ["[Gold] cost of purchasing [All] units [-33]%"], "row": 1, - "column": 5 + "column": 4 }, { "name": "Fascism", @@ -571,7 +571,7 @@ ], "requires": ["Populism", "Militarism"], "row": 2, - "column": 3 + "column": 2 }, { "name": "Police State", @@ -582,7 +582,7 @@ // There are also some uniques regarding espoinage, which as of this writing is not yet implemented "requires": ["Militarism"], "row": 2, - "column": 5 + "column": 4 }, { "name": "Total War", @@ -592,7 +592,7 @@ ], "requires": ["Police State", "Fascism"], "row": 3, - "column": 4 + "column": 3 }, { "name": "Autocracy Complete", diff --git a/android/assets/jsons/Civ V - Vanilla/Policies.json b/android/assets/jsons/Civ V - Vanilla/Policies.json index ccb26ce5da..3d8091149d 100644 --- a/android/assets/jsons/Civ V - Vanilla/Policies.json +++ b/android/assets/jsons/Civ V - Vanilla/Policies.json @@ -440,7 +440,7 @@ "[+1 Happiness] from every [Public School]" ], "row": 1, - "column": 5 + "column": 4 }, { "name": "Free Thought", @@ -450,21 +450,21 @@ ], "requires": ["Secularism"], "row": 2, - "column": 1 + "column": 2 }, { "name": "Sovereignty", "uniques": ["[+15]% [Science] "], "requires": ["Humanism"], "row": 2, - "column": 5 + "column": 4 }, { "name": "Scientific Revolution", "uniques": ["[2] Free Technologies"], "requires": ["Free Thought"], "row": 3, - "column": 1 + "column": 2 }, { "name": "Rationalism Complete", @@ -555,13 +555,13 @@ "name": "Populism", "uniques": ["[+25]% Strength "], "row": 1, - "column": 1 + "column": 2 }, { "name": "Militarism", "uniques": ["[Gold] cost of purchasing [All] units [-33]%"], "row": 1, - "column": 5 + "column": 4 }, { "name": "Fascism", @@ -570,7 +570,7 @@ ], "requires": ["Populism", "Militarism"], "row": 2, - "column": 3 + "column": 2 }, { "name": "Police State", @@ -580,7 +580,7 @@ ], "requires": ["Militarism"], "row": 2, - "column": 5 + "column": 4 }, { "name": "Total War", @@ -590,7 +590,7 @@ ], "requires": ["Police State", "Fascism"], "row": 3, - "column": 4 + "column": 3 }, { "name": "Autocracy Complete", diff --git a/android/assets/jsons/translations/template.properties b/android/assets/jsons/translations/template.properties index 862dbed59d..3e3c7778ef 100644 --- a/android/assets/jsons/translations/template.properties +++ b/android/assets/jsons/translations/template.properties @@ -1426,12 +1426,19 @@ Unit type = # Policies + +Adopt = +Completed = +On adoption = +On completion = +Cannot be adopted together with = Adopt policy = Adopt free policy = Unlocked at = Gain 2 free technologies = All policies adopted = Policy branch: [branchName] = +Are you sure you want to adopt [branchName]? = # Religions diff --git a/core/src/com/unciv/models/ruleset/Policy.kt b/core/src/com/unciv/models/ruleset/Policy.kt index 27939ef445..6887934836 100644 --- a/core/src/com/unciv/models/ruleset/Policy.kt +++ b/core/src/com/unciv/models/ruleset/Policy.kt @@ -1,7 +1,9 @@ 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.UniqueTarget +import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.translations.tr import com.unciv.ui.civilopedia.FormattedLine @@ -31,17 +33,13 @@ open class Policy : RulesetObject() { /** Used in PolicyPickerScreen to display Policy properties */ fun getDescription(): String { - val policyText = ArrayList() - policyText += name - policyText += uniques - - if (policyBranchType != PolicyBranchType.BranchComplete) { - policyText += if (requires!!.isNotEmpty()) - "Requires [" + requires!!.joinToString { it.tr() } + "]" - else - "{Unlocked at} {${branch.era}}" - } - return policyText.joinToString("\n") { it.tr() } + var text = uniques + .filter { !it.contains(UniqueType.OnlyAvailableWhen.text) } + .joinToString("\n", transform = { "• $it".tr() }) + if (policyBranchType != PolicyBranchType.BranchStart + && policyBranchType != PolicyBranchType.BranchComplete) + text = name + "\n" + text + return text } override fun makeLink() = "Policy/$name" diff --git a/core/src/com/unciv/models/skins/SkinStrings.kt b/core/src/com/unciv/models/skins/SkinStrings.kt index 47696bf052..6e1d0b659f 100644 --- a/core/src/com/unciv/models/skins/SkinStrings.kt +++ b/core/src/com/unciv/models/skins/SkinStrings.kt @@ -10,6 +10,7 @@ class SkinStrings(skin: String = UncivGame.Current.settings.skin) { val skinConfig = SkinCache[skin] ?: SkinConfig() // Default shapes must always end with "Shape" so the UiElementDocsWriter can identify them + val roundedEdgeRectangleSmallShape = skinLocation + "roundedEdgeRectangle-small" val roundedEdgeRectangleShape = skinLocation + "roundedEdgeRectangle" val rectangleWithOutlineShape = skinLocation + "rectangleWithOutline" val selectBoxShape = skinLocation + "select-box" diff --git a/core/src/com/unciv/ui/pickerscreens/PolicyPickerScreen.kt b/core/src/com/unciv/ui/pickerscreens/PolicyPickerScreen.kt index b236739deb..9d33e97335 100644 --- a/core/src/com/unciv/ui/pickerscreens/PolicyPickerScreen.kt +++ b/core/src/com/unciv/ui/pickerscreens/PolicyPickerScreen.kt @@ -1,8 +1,13 @@ package com.unciv.ui.pickerscreens 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.Cell +import com.badlogic.gdx.scenes.scene2d.ui.Image import com.badlogic.gdx.scenes.scene2d.ui.Table +import com.badlogic.gdx.utils.Align import com.unciv.UncivGame import com.unciv.logic.civilization.CivilizationInfo 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.PolicyBranchType 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.ui.images.ImageGetter +import com.unciv.ui.popup.ConfirmPopup 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.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.enable import com.unciv.ui.utils.extensions.onClick 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 java.lang.Integer.max +import kotlin.math.abs 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) : PickerScreen(), RecreateOnResize { + internal val viewingCiv: CivilizationInfo = civInfo - private var pickedPolicy: Policy? = null + + private var policyNameToButton = HashMap() + private var selectedPolicyButton: PolicyButton? = null init { val policies = viewingCiv.policies @@ -49,15 +186,15 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo closeButton.disable() rightSideButton.onClick(UncivSound.Policy) { - val policy = pickedPolicy!! + val policy = selectedPolicyButton!!.policy // 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) // 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() } else { val policyScreen = PolicyPickerScreen(worldScreen) @@ -97,18 +234,29 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo // Actually create and distribute the policy branches var wrapper = Table() 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) 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.addSeparator() + topTable.addSeparator().pad(0f, 10f) 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) @@ -116,7 +264,7 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo // total padding, or up to where the axis is centered, whichever is smaller splitPane.pack() // packs topTable but also ensures scrollPane.maxXY is calculated if (topTable.height > scrollPane.height) { - val vScroll = min(15f, scrollPane.maxY / 2) + val vScroll = min(0f, scrollPane.maxY / 2) scrollPane.scrollY = vScroll } if (topTable.width > scrollPane.width) { @@ -126,31 +274,25 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo scrollPane.updateVisualScroll() } - private fun policyIsPickable(policy: Policy):Boolean { - 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(button: PolicyButton) { - private fun pickPolicy(policy: Policy) { - if (!policyIsPickable(policy)) { + val policy = button.policy + + rightSideButton.isVisible = !viewingCiv.policies.isAdopted(policy.name) + if (!policy.isPickable()) { rightSideButton.disable() } else { rightSideButton.enable() } - if (viewingCiv.gameInfo.gameParameters.godMode && pickedPolicy == policy + if (viewingCiv.gameInfo.gameParameters.godMode && selectedPolicyButton?.policy == policy && viewingCiv.policies.isAdoptable(policy)) { viewingCiv.policies.adopt(policy) game.replaceCurrentScreen(PolicyPickerScreen(worldScreen)) } - pickedPolicy = policy + + selectedPolicyButton?.isSelected = false + selectedPolicyButton = button + selectedPolicyButton?.isSelected = true descriptionLabel.setText(policy.getDescription()) } @@ -160,55 +302,342 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo * @param branch the policy branch to display * @return a [Table], with outer padding _zero_ */ - private fun getBranchGroup(branch: PolicyBranch): Table { - val branchGroup = Table() - branchGroup.row() - branchGroup.add(getPolicyButton(branch, false)) - .minWidth(160f).padBottom(15f).row() + private fun getBranchGroup(branch: PolicyBranch): Group { - var currentRow = 1 - var currentColumn = 1 - val branchTable = Table() - for (policy in branch.policies) { - if (policy.policyBranchType == PolicyBranchType.BranchComplete) continue - if (policy.row > currentRow) { - branchTable.row().pad(2.5f) - currentRow++ - currentColumn = 1 - } - if (policy.column > currentColumn) { - branchTable.add().colspan(policy.column - currentColumn) // empty space - } - branchTable.add(getPolicyButton(policy, true)).colspan(2) - currentColumn = policy.column + 2 + // Calculate preferred size + val maxCol = max(5, branch.policies.maxOf { it.column }) + val maxRow = branch.policies.maxOf { it.row } + + val prefWidth = Sizes.paddingHorizontal*2 + Sizes.iconSize*maxCol - (Sizes.iconSize-Sizes.paddingBetweenHor)*(maxCol-1)/2 + val prefHeight = Sizes.paddingVertical*2 + Sizes.iconSize*maxRow + Sizes.paddingBetweenVer*(maxRow - 1) + + // Main table + val colorBg = if (branch.isAdopted()) Colors.branchAdopted else Colors.branchNotAdopted + val branchGroup = BorderedTable(innerColor = colorBg) + + // Header + val header = getBranchHeader(branch) + branchGroup.add(header).growX().row() + + // 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() + 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. - branchGroup.add(getPolicyButton(branch.policies.last(), false)).padTop(15f) + // Top button + 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).clearActor() + ((header.cells[0].actor as Table).cells[0] as Cell).setActor(ImageGetter. + getImage("OtherIcons/BackArrow").apply { rotation = rotate}.toGroup(10f)) + } // Ensure dimensions are calculated branchGroup.pack() return branchGroup } - private fun getPolicyButton(policy: Policy, image: Boolean): Button { - var policyButton = Button(skin) - if (image) { - val policyImage = ImageGetter.getImage("PolicyIcons/" + policy.name) - policyButton.add(policyImage).size(30f) - } else { - policyButton = policy.name.toTextButton() + + + private fun drawLines(branch: PolicyBranch) { + + for (policy in branch.policies) { + + 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) } - policyButton.pack() - return policyButton + val lineColor = Color.WHITE + val lineSize = 2f + + 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) diff --git a/core/src/com/unciv/ui/utils/BorderedTable.kt b/core/src/com/unciv/ui/utils/BorderedTable.kt new file mode 100644 index 0000000000..6650b34f7f --- /dev/null +++ b/core/src/com/unciv/ui/utils/BorderedTable.kt @@ -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) + + } +}