diff --git a/android/assets/game.atlas b/android/assets/game.atlas index 18b434c3ff..9171167ee2 100644 --- a/android/assets/game.atlas +++ b/android/assets/game.atlas @@ -326,303 +326,310 @@ BuildingIcons/Monument orig: 100, 100 offset: 0, 0 index: -1 -BuildingIcons/Museum +BuildingIcons/Mughal Fort rotate: false xy: 1224, 1030 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 +BuildingIcons/Museum + rotate: false + xy: 1020, 826 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 BuildingIcons/National College rotate: false - xy: 1326, 1030 + xy: 1122, 826 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Neuschwanstein rotate: false - xy: 1224, 928 + xy: 1224, 826 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Notre Dame rotate: false - xy: 1224, 826 + xy: 1326, 928 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Nuclear Plant rotate: false - xy: 1326, 826 + xy: 1428, 948 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Observatory rotate: false - xy: 1530, 948 + xy: 1428, 846 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Opera House rotate: false - xy: 1632, 932 + xy: 1734, 926 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Oxford University rotate: false - xy: 1836, 926 + xy: 1734, 824 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Palace rotate: false - xy: 1734, 824 + xy: 1836, 824 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Paper Maker rotate: false - xy: 1938, 926 + xy: 1938, 824 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Pentagon rotate: false - xy: 1530, 744 + xy: 1632, 729 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Porcelain Tower rotate: false - xy: 592, 622 + xy: 796, 724 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Public School rotate: false - xy: 898, 724 + xy: 796, 622 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Research Lab rotate: false - xy: 1102, 622 + xy: 1306, 724 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/SS Booster rotate: false - xy: 1816, 620 + xy: 1918, 620 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/SS Cockpit rotate: false - xy: 1918, 620 + xy: 1408, 540 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/SS Engine rotate: false - xy: 1408, 540 + xy: 1510, 540 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/SS Stasis Chamber rotate: false - xy: 1510, 540 + xy: 1612, 525 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Seaport rotate: false - xy: 642, 520 + xy: 540, 418 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Sistine Chapel rotate: false - xy: 642, 316 + xy: 744, 418 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Solar Plant rotate: false - xy: 948, 520 + xy: 540, 112 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Spaceship Factory rotate: false - xy: 540, 112 + xy: 642, 214 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Stable rotate: false - xy: 1050, 520 + xy: 642, 112 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Stadium rotate: false - xy: 642, 112 + xy: 744, 214 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Statue of Liberty rotate: false - xy: 744, 214 + xy: 846, 316 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Stock Exchange rotate: false - xy: 1152, 520 + xy: 744, 112 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Stone Works rotate: false - xy: 846, 214 + xy: 948, 316 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Stonehenge rotate: false - xy: 948, 316 + xy: 1050, 418 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Sydney Opera House rotate: false - xy: 1050, 316 + xy: 1152, 418 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Taj Mahal rotate: false - xy: 1152, 418 + xy: 948, 112 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Temple rotate: false - xy: 1050, 214 + xy: 1152, 316 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Terracotta Army rotate: false - xy: 1152, 316 + xy: 1254, 418 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/The Great Library rotate: false - xy: 1254, 418 + xy: 1050, 112 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/The Great Lighthouse rotate: false - xy: 1050, 112 + xy: 1152, 214 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/The Louvre rotate: false - xy: 1152, 214 + xy: 1254, 316 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/The Oracle rotate: false - xy: 1254, 316 + xy: 1152, 112 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/The Pyramids rotate: false - xy: 1152, 112 + xy: 1254, 214 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Theatre rotate: false - xy: 1254, 112 + xy: 540, 10 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/University rotate: false - xy: 948, 10 + xy: 1050, 10 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Walls rotate: false - xy: 1152, 10 + xy: 1254, 10 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Walls of Babylon rotate: false - xy: 1254, 10 + xy: 1356, 438 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Windmill rotate: false - xy: 1458, 336 + xy: 1458, 234 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 BuildingIcons/Workshop rotate: false - xy: 1458, 132 + xy: 1560, 423 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -776,70 +783,70 @@ ImprovementIcons/Mine index: -1 ImprovementIcons/Oil well rotate: false - xy: 1530, 846 + xy: 1632, 932 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ImprovementIcons/Plantation rotate: false - xy: 490, 622 + xy: 694, 724 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ImprovementIcons/Quarry rotate: false - xy: 796, 622 + xy: 1000, 724 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ImprovementIcons/Railroad rotate: false - xy: 898, 622 + xy: 1102, 724 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TileSets/Default/Railroad rotate: false - xy: 898, 622 + xy: 1102, 724 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TileSets/FantasyHex/Railroad rotate: false - xy: 898, 622 + xy: 1102, 724 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TileSets/ThorfMaps/Railroad rotate: false - xy: 898, 622 + xy: 1102, 724 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ImprovementIcons/Road rotate: false - xy: 1408, 642 + xy: 1510, 642 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ImprovementIcons/Trading post rotate: false - xy: 642, 10 + xy: 744, 10 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 OtherIcons/BackArrow rotate: false - xy: 1560, 488 + xy: 1662, 473 size: 50, 50 orig: 50, 50 offset: 0, 0 @@ -923,35 +930,35 @@ OtherIcons/MenuIcon index: -1 OtherIcons/Pentagon rotate: false - xy: 1632, 729 + xy: 1734, 722 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 OtherIcons/Pillage rotate: false - xy: 592, 724 + xy: 490, 622 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 OtherIcons/Shield rotate: false - xy: 540, 316 + xy: 642, 418 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 OtherIcons/Sleep rotate: false - xy: 744, 418 + xy: 948, 520 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 OtherIcons/Stop rotate: false - xy: 1050, 418 + xy: 1254, 520 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -1014,252 +1021,252 @@ PolicyIcons/Constitution index: -1 PolicyIcons/Democracy rotate: false - xy: 1560, 436 + xy: 1560, 269 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Discipline rotate: false - xy: 1612, 473 + xy: 1662, 421 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 StatIcons/Strength rotate: false - xy: 1612, 473 + xy: 1662, 421 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Entrepreneurship rotate: false - xy: 1560, 384 + xy: 1714, 466 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Facism rotate: false - xy: 1612, 421 + xy: 1560, 217 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Free Religion rotate: false - xy: 1560, 332 + xy: 1662, 369 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Free Speech rotate: false - xy: 1612, 369 + xy: 1714, 414 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Free Thought rotate: false - xy: 1560, 280 + xy: 1766, 466 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Humanism rotate: false - xy: 1612, 317 + xy: 1560, 165 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Landed Elite rotate: false - xy: 1560, 228 + xy: 1766, 414 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Legalism rotate: false - xy: 1612, 265 + xy: 1818, 466 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Mandate Of Heaven rotate: false - xy: 1560, 176 + xy: 1560, 113 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Mercantilism rotate: false - xy: 1612, 213 + xy: 1818, 414 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Meritocracy rotate: false - xy: 1560, 124 + xy: 1870, 466 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Militarism rotate: false - xy: 1612, 161 + xy: 1560, 61 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Military Caste rotate: false - xy: 1560, 72 + xy: 1870, 414 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Military Tradition rotate: false - xy: 1612, 109 + xy: 1922, 466 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Monarchy rotate: false - xy: 1966, 1588 + xy: 1922, 414 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Oligarchy rotate: false - xy: 1966, 1484 + xy: 1612, 217 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Organized Religion rotate: false - xy: 1966, 1432 + xy: 1612, 165 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Patronage rotate: false - xy: 1966, 1380 + xy: 1612, 113 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Police State rotate: false - xy: 1966, 1328 + xy: 1612, 61 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Populism rotate: false - xy: 1966, 1276 + xy: 1974, 466 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Professional Army rotate: false - xy: 1966, 1224 + xy: 1974, 414 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Protectionism rotate: false - xy: 1966, 1172 + xy: 1966, 1588 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Reformation rotate: false - xy: 1966, 1068 + xy: 1966, 1484 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Representation rotate: false - xy: 1664, 436 + xy: 1966, 1432 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Republic rotate: false - xy: 1664, 384 + xy: 1966, 1380 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Scientific Revolution rotate: false - xy: 1664, 332 + xy: 1966, 1328 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Secularism rotate: false - xy: 1664, 280 + xy: 1966, 1276 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Sovereignty rotate: false - xy: 1664, 228 + xy: 1966, 1224 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Theocracy rotate: false - xy: 1664, 176 + xy: 1966, 1172 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Total War rotate: false - xy: 1664, 124 + xy: 1966, 1120 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Trade Unions rotate: false - xy: 1716, 466 + xy: 1966, 1068 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Universal Suffrage rotate: false - xy: 1716, 414 + xy: 1984, 362 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 PolicyIcons/Warrior Code rotate: false - xy: 1768, 466 + xy: 1664, 280 size: 50, 50 orig: 50, 50 offset: 0, 0 @@ -1378,84 +1385,84 @@ ResourceIcons/Marble index: -1 ResourceIcons/Oil rotate: false - xy: 1428, 846 + xy: 1530, 846 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Pearls rotate: false - xy: 1428, 744 + xy: 1530, 744 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Sheep rotate: false - xy: 744, 520 + xy: 540, 316 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Silk rotate: false - xy: 846, 520 + xy: 540, 214 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Silver rotate: false - xy: 540, 214 + xy: 642, 316 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Spices rotate: false - xy: 846, 418 + xy: 1050, 520 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Stone rotate: false - xy: 744, 112 + xy: 846, 214 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Sugar rotate: false - xy: 846, 112 + xy: 948, 214 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Uranium rotate: false - xy: 1050, 10 + xy: 1152, 10 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Whales rotate: false - xy: 1356, 336 + xy: 1458, 336 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Wheat rotate: false - xy: 1356, 234 + xy: 1356, 132 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 ResourceIcons/Wine rotate: false - xy: 1356, 132 + xy: 1356, 30 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -1518,7 +1525,7 @@ StatIcons/Malcontent index: -1 StatIcons/Movement rotate: false - xy: 1966, 1536 + xy: 1612, 269 size: 50, 50 orig: 50, 50 offset: 0, 0 @@ -1539,14 +1546,14 @@ StatIcons/Production index: -1 StatIcons/RangedStrength rotate: false - xy: 1966, 1120 + xy: 1966, 1536 size: 50, 50 orig: 50, 50 offset: 0, 0 index: -1 StatIcons/Resistance rotate: false - xy: 1306, 724 + xy: 1204, 622 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -1560,7 +1567,7 @@ StatIcons/Science index: -1 StatIcons/Specialist rotate: false - xy: 744, 316 + xy: 846, 418 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -1896,189 +1903,189 @@ TechIcons/Mining index: -1 TechIcons/Nanotechnology rotate: false - xy: 1122, 928 + xy: 1326, 1030 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Navigation rotate: false - xy: 1122, 826 + xy: 1224, 928 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Nuclear Fission rotate: false - xy: 1326, 928 + xy: 1326, 826 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Optics rotate: false - xy: 1734, 926 + xy: 1836, 926 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Particle Physics rotate: false - xy: 1938, 824 + xy: 1428, 744 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Pharmaceuticals rotate: false - xy: 1734, 722 + xy: 1836, 722 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Philosophy rotate: false - xy: 1836, 722 + xy: 1938, 722 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Physics rotate: false - xy: 1938, 722 + xy: 490, 724 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Plastics rotate: false - xy: 694, 724 + xy: 592, 622 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Pottery rotate: false - xy: 796, 724 + xy: 694, 622 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Printing Press rotate: false - xy: 694, 622 + xy: 898, 724 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Radio rotate: false - xy: 1000, 724 + xy: 898, 622 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Railroad rotate: false - xy: 1102, 724 + xy: 1000, 622 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Refrigeration rotate: false - xy: 1000, 622 + xy: 1204, 724 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Replaceable Parts rotate: false - xy: 1204, 724 + xy: 1102, 622 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Rifling rotate: false - xy: 1306, 622 + xy: 1408, 642 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Robotics rotate: false - xy: 1510, 642 + xy: 1612, 627 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Rocketry rotate: false - xy: 1714, 620 + xy: 1816, 620 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Sailing rotate: false - xy: 1612, 525 + xy: 1714, 518 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Satellites rotate: false - xy: 1816, 518 + xy: 1918, 518 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Scientific Theory rotate: false - xy: 1918, 518 + xy: 540, 520 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Steam Power rotate: false - xy: 846, 316 + xy: 948, 418 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Steel rotate: false - xy: 948, 418 + xy: 1152, 520 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/The Wheel rotate: false - xy: 1254, 214 + xy: 1254, 112 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Theology rotate: false - xy: 540, 10 + xy: 642, 10 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Trapping rotate: false - xy: 744, 10 + xy: 846, 10 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TechIcons/Writing rotate: false - xy: 1458, 30 + xy: 1560, 321 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -2204,14 +2211,14 @@ TileSets/Default/MountainOverlay index: -1 TileSets/Default/OasisOverlay rotate: false - xy: 1428, 948 + xy: 1530, 948 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 TileSets/ThorfMaps/OasisOverlay rotate: false - xy: 1428, 948 + xy: 1530, 948 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -2239,21 +2246,21 @@ TileSets/ThorfMaps/road index: -1 TileSets/FantasyHex/City rotate: false - xy: 1612, 72 + xy: 1662, 332 size: 32, 35 orig: 32, 35 offset: 0, 0 index: -1 TileSets/FantasyHex/Grassland+City rotate: false - xy: 1612, 72 + xy: 1662, 332 size: 32, 35 orig: 32, 35 offset: 0, 0 index: -1 TileSets/FantasyHex/Hill+City rotate: false - xy: 1612, 72 + xy: 1662, 332 size: 32, 35 orig: 32, 35 offset: 0, 0 @@ -2281,21 +2288,21 @@ TileSets/FantasyHex/Desert+City index: -1 TileSets/FantasyHex/Desert+Flood plains rotate: false - xy: 70, 8 + xy: 1664, 110 size: 32, 28 orig: 32, 28 offset: 0, 0 index: -1 TileSets/FantasyHex/Desert+Oasis rotate: false - xy: 1716, 260 + xy: 1664, 80 size: 32, 28 orig: 32, 28 offset: 0, 0 index: -1 TileSets/FantasyHex/Grassland rotate: false - xy: 1716, 230 + xy: 1696, 332 size: 32, 28 orig: 32, 28 offset: 0, 0 @@ -2323,7 +2330,7 @@ TileSets/FantasyHex/Grassland+Marsh index: -1 TileSets/FantasyHex/Hill rotate: false - xy: 1982, 484 + xy: 70, 4 size: 32, 32 orig: 32, 32 offset: 0, 0 @@ -2337,7 +2344,7 @@ TileSets/FantasyHex/Hill+Forest index: -1 TileSets/FantasyHex/Lakes rotate: false - xy: 1716, 200 + xy: 1730, 338 size: 32, 28 orig: 32, 28 offset: 0, 0 @@ -2351,112 +2358,112 @@ TileSets/FantasyHex/Mountain index: -1 TileSets/FantasyHex/Ocean rotate: false - xy: 1716, 170 + xy: 1764, 338 size: 32, 28 orig: 32, 28 offset: 0, 0 index: -1 TileSets/FantasyHex/Plains rotate: false - xy: 1716, 140 + xy: 1798, 338 size: 32, 28 orig: 32, 28 offset: 0, 0 index: -1 TileSets/FantasyHex/Plains+City rotate: false - xy: 1646, 72 + xy: 1966, 1031 size: 32, 35 orig: 32, 35 offset: 0, 0 index: -1 TileSets/FantasyHex/Plains+Forest rotate: false - xy: 490, 549 + xy: 1664, 208 size: 32, 33 orig: 32, 33 offset: 0, 0 index: -1 TileSets/FantasyHex/Plains+Jungle rotate: false - xy: 1966, 1031 + xy: 490, 547 size: 32, 35 orig: 32, 35 offset: 0, 0 index: -1 TileSets/FantasyHex/Tundra rotate: false - xy: 1768, 432 + xy: 1664, 174 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 TileSets/FantasyHex/Tundra+City rotate: false - xy: 1664, 488 + xy: 1664, 243 size: 32, 35 orig: 32, 35 offset: 0, 0 index: -1 TileSets/FantasyHex/Tundra+Forest rotate: false - xy: 1716, 290 + xy: 1664, 140 size: 32, 32 orig: 32, 32 offset: 0, 0 index: -1 TileSets/ThorfMaps/Coast rotate: false - xy: 1977, 1950 + xy: 1714, 368 size: 52, 44 orig: 52, 44 offset: 0, 0 index: -1 TileSets/ThorfMaps/Desert rotate: false - xy: 1560, 26 + xy: 1768, 368 size: 52, 44 orig: 52, 44 offset: 0, 0 index: -1 TileSets/ThorfMaps/Grassland rotate: false - xy: 1614, 26 + xy: 1822, 368 size: 52, 44 orig: 52, 44 offset: 0, 0 index: -1 TileSets/ThorfMaps/Hill rotate: false - xy: 1716, 369 + xy: 1560, 16 size: 52, 43 orig: 52, 43 offset: 0, 0 index: -1 TileSets/ThorfMaps/Mountain rotate: false - xy: 1820, 472 + xy: 1876, 368 size: 52, 44 orig: 52, 44 offset: 0, 0 index: -1 TileSets/ThorfMaps/Ocean rotate: false - xy: 1716, 324 + xy: 1614, 16 size: 52, 43 orig: 52, 43 offset: 0, 0 index: -1 TileSets/ThorfMaps/Plains rotate: false - xy: 1874, 472 + xy: 1977, 1950 size: 52, 44 orig: 52, 44 offset: 0, 0 index: -1 TileSets/ThorfMaps/Tundra rotate: false - xy: 1928, 472 + xy: 1930, 368 size: 52, 44 orig: 52, 44 offset: 0, 0 @@ -2764,7 +2771,7 @@ UnitIcons/Modern Armor index: -1 UnitIcons/Musketeer rotate: false - xy: 1020, 826 + xy: 1122, 928 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -2778,91 +2785,91 @@ UnitIcons/Musketman index: -1 UnitIcons/Panzer rotate: false - xy: 1836, 824 + xy: 1938, 926 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Pikeman rotate: false - xy: 490, 724 + xy: 592, 724 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Rifleman rotate: false - xy: 1204, 622 + xy: 1306, 622 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Rocket Artillery rotate: false - xy: 1612, 627 + xy: 1714, 620 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Samurai rotate: false - xy: 1714, 518 + xy: 1816, 518 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Scout rotate: false - xy: 540, 520 + xy: 642, 520 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Settler rotate: false - xy: 540, 418 + xy: 744, 520 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Ship of the Line rotate: false - xy: 642, 418 + xy: 846, 520 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Spearman rotate: false - xy: 642, 214 + xy: 744, 316 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Submarine rotate: false - xy: 1254, 520 + xy: 846, 112 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Swordsman rotate: false - xy: 948, 214 + xy: 1050, 316 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Tank rotate: false - xy: 948, 112 + xy: 1050, 214 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Trebuchet rotate: false - xy: 846, 10 + xy: 948, 10 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -2876,28 +2883,35 @@ UnitIcons/Trireme index: -1 UnitIcons/War Chariot rotate: false - xy: 1356, 438 + xy: 1458, 438 + size: 100, 100 + orig: 100, 100 + offset: 0, 0 + index: -1 +UnitIcons/War Elephant + rotate: false + xy: 1356, 336 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Warrior rotate: false - xy: 1458, 438 + xy: 1356, 234 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Work Boats rotate: false - xy: 1458, 234 + xy: 1458, 132 size: 100, 100 orig: 100, 100 offset: 0, 0 index: -1 UnitIcons/Worker rotate: false - xy: 1356, 30 + xy: 1458, 30 size: 100, 100 orig: 100, 100 offset: 0, 0 @@ -2995,245 +3009,245 @@ UnitPromotionIcons/Bombardment_I_(Civ5) index: -1 UnitPromotionIcons/Charge_(Civ5) rotate: false - xy: 1428, 1088 + xy: 1832, 346 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Coastal_Raider_III_(Civ5) rotate: false - xy: 460, 782 + xy: 1428, 1088 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Coastal_Raider_II_(Civ5) rotate: false - xy: 2015, 1769 + xy: 460, 782 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Coastal_Raider_I_(Civ5) rotate: false - xy: 1428, 1066 + xy: 2015, 1769 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Cover_II_(Civ5) rotate: false - xy: 2015, 1747 + xy: 1854, 346 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Cover_I_(Civ5) rotate: false - xy: 2020, 700 + xy: 1428, 1066 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Drill_III_(Civ5) rotate: false - xy: 2020, 678 + xy: 2015, 1747 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Drill_II_(Civ5) rotate: false - xy: 2020, 656 + xy: 1876, 346 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Drill_I_(Civ5) rotate: false - xy: 2020, 634 + xy: 1898, 346 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Formation_II_(Civ5) rotate: false - xy: 2020, 612 + xy: 1920, 346 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Formation_I_(Civ5) rotate: false - xy: 2020, 590 + xy: 1942, 346 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Heal_Instantly_(Civ5) rotate: false - xy: 2020, 568 + xy: 2020, 700 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Indirect_Fire_(Civ5) rotate: false - xy: 2020, 546 + xy: 2020, 678 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Logistics_(Civ5) rotate: false - xy: 2020, 524 + xy: 2020, 656 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/March_(Civ5) rotate: false - xy: 1356, 8 + xy: 2020, 634 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Medic_(Civ5) rotate: false - xy: 1378, 8 + xy: 2020, 612 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Medic_II_(Civ5) rotate: false - xy: 1378, 8 + xy: 2020, 612 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Mobility_(Civ5) rotate: false - xy: 1400, 8 + xy: 2020, 590 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Range_(Civ5) rotate: false - xy: 1422, 8 + xy: 2020, 568 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Scouting_III_(Civ5) rotate: false - xy: 1444, 8 + xy: 2020, 546 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Scouting_II_(Civ5) rotate: false - xy: 1466, 8 + xy: 2020, 524 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Scouting_I_(Civ5) rotate: false - xy: 1488, 8 + xy: 2026, 502 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Sentry_(Civ5) rotate: false - xy: 1510, 8 + xy: 2026, 480 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Shock_III_(Civ5) rotate: false - xy: 1532, 8 + xy: 2026, 458 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Shock_II_(Civ5) rotate: false - xy: 1750, 302 + xy: 2026, 436 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Shock_I_(Civ5) rotate: false - xy: 1750, 280 + xy: 2026, 414 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Siege_(Civ5) rotate: false - xy: 1750, 258 + xy: 1356, 8 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Targeting_III_(Civ5) rotate: false - xy: 1750, 236 + xy: 1378, 8 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Targeting_II_(Civ5) rotate: false - xy: 1750, 214 + xy: 1400, 8 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Targeting_I_(Civ5) rotate: false - xy: 1750, 192 + xy: 1422, 8 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Volley_(Civ5) rotate: false - xy: 1750, 170 + xy: 1444, 8 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Wolfpack_III_(Civ5) rotate: false - xy: 1750, 148 + xy: 1466, 8 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Wolfpack_II_(Civ5) rotate: false - xy: 2000, 1046 + xy: 1488, 8 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Wolfpack_I_(Civ5) rotate: false - xy: 1802, 444 + xy: 1510, 8 size: 20, 20 orig: 20, 20 offset: 0, 0 index: -1 UnitPromotionIcons/Woodsman_(Civ5) rotate: false - xy: 442, 752 + xy: 1532, 8 size: 20, 20 orig: 20, 20 offset: 0, 0 diff --git a/android/assets/game.png b/android/assets/game.png index 2104b7d94a..338d0f3f69 100644 Binary files a/android/assets/game.png and b/android/assets/game.png differ diff --git a/android/assets/jsons/Translations/Other.json b/android/assets/jsons/Translations/Other.json index 8ca10f1258..19d14d384c 100644 --- a/android/assets/jsons/Translations/Other.json +++ b/android/assets/jsons/Translations/Other.json @@ -227,6 +227,10 @@ Japanese:"自動化を停止" } + "Construct road": { + "German": "Straße bauen" + } + "Fortify":{ Italian:"Fortifica" Russian:"Укрепить" @@ -258,7 +262,7 @@ Romanian:"Dormi" Simplified_Chinese:"休眠" Portuguese:"Dormir" - German:"Schlafen legen" + German:"Schlafen" French:"Dormir" Japanese:"睡眠" Russian:"Спать" @@ -266,6 +270,10 @@ Spanish:"Dormir" } + "Moving": { + "German": "Bewegen" + } + "Set up":{ // For siege units Italian:"Monta" Russian:"Подготовится" diff --git a/core/src/com/unciv/logic/automation/WorkerAutomation.kt b/core/src/com/unciv/logic/automation/WorkerAutomation.kt index 7167720e12..4784e98326 100644 --- a/core/src/com/unciv/logic/automation/WorkerAutomation.kt +++ b/core/src/com/unciv/logic/automation/WorkerAutomation.kt @@ -49,23 +49,20 @@ class WorkerAutomation(val unit: MapUnit) { - fun tryConnectingCities():Boolean{ // returns whether we actually did anything - val techEnablingRailroad = GameBasics.TileImprovements["Railroad"]!!.techRequired!! - val canBuildRailroad = unit.civInfo.tech.isResearched(techEnablingRailroad) + fun tryConnectingCities():Boolean { // returns whether we actually did anything - val targetRoadName = if (canBuildRailroad) "Railroad" else "Road" - val targetStatus = if (canBuildRailroad) RoadStatus.Railroad else RoadStatus.Road + val targetRoad = unit.civInfo.tech.getBestRoadAvailable() val citiesThatNeedConnecting = unit.civInfo.cities .filter { it.population.population>3 && !it.isCapital() - && !it.cityStats.isConnectedToCapital(targetStatus) } + && !it.cityStats.isConnectedToCapital(targetRoad) } if(citiesThatNeedConnecting.isEmpty()) return false // do nothing. val citiesThatNeedConnectingBfs = citiesThatNeedConnecting .map { city -> BFS(city.getCenterTile()){it.isLand && unit.canPassThrough(it)} } .toMutableList() - val connectedCities = unit.civInfo.cities.filter { it.isCapital() || it.cityStats.isConnectedToCapital(targetStatus) } + val connectedCities = unit.civInfo.cities.filter { it.isCapital() || it.cityStats.isConnectedToCapital(targetRoad) } .map { it.getCenterTile() } while(citiesThatNeedConnectingBfs.any()){ @@ -78,7 +75,7 @@ class WorkerAutomation(val unit: MapUnit) { for(city in connectedCities) if(bfs.tilesToCheck.contains(city)) { // we have a winner! val pathToCity = bfs.getPathTo(city) - val roadableTiles = pathToCity.filter { it.roadStatus < targetStatus } + val roadableTiles = pathToCity.filter { it.roadStatus < targetRoad } val tileToConstructRoadOn :TileInfo if(unit.currentTile in roadableTiles) tileToConstructRoadOn = unit.currentTile else{ @@ -88,8 +85,8 @@ class WorkerAutomation(val unit: MapUnit) { unit.movementAlgs().headTowards(tileToConstructRoadOn) } if(unit.currentMovement>0 && unit.currentTile==tileToConstructRoadOn - && unit.currentTile.improvementInProgress!=targetRoadName) - tileToConstructRoadOn.startWorkingOnImprovement(GameBasics.TileImprovements[targetRoadName]!!,unit.civInfo) + && unit.currentTile.improvementInProgress!=targetRoad.name) + tileToConstructRoadOn.startWorkingOnImprovement(targetRoad.improvement()!!,unit.civInfo) return true } } diff --git a/core/src/com/unciv/logic/civilization/TechManager.kt b/core/src/com/unciv/logic/civilization/TechManager.kt index f356231495..1630794b58 100644 --- a/core/src/com/unciv/logic/civilization/TechManager.kt +++ b/core/src/com/unciv/logic/civilization/TechManager.kt @@ -2,6 +2,7 @@ package com.unciv.logic.civilization import com.badlogic.gdx.graphics.Color +import com.unciv.logic.map.RoadStatus import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.tech.Technology import com.unciv.models.gamebasics.tr @@ -196,4 +197,13 @@ class TechManager { if(researchedTechUniques.contains("Enables embarked units to enter ocean tiles")) embarkedUnitsCanEnterOcean=true if(researchedTechUniques.contains("Improves movement speed on roads")) movementSpeedOnRoadsImproved = true } + + fun getBestRoadAvailable(): RoadStatus { + if (!isResearched(RoadStatus.Road.improvement()!!.techRequired!!)) return RoadStatus.None + + val techEnablingRailroad = RoadStatus.Railroad.improvement()!!.techRequired!! + val canBuildRailroad = isResearched(techEnablingRailroad) + + return if (canBuildRailroad) RoadStatus.Railroad else RoadStatus.Road + } } \ No newline at end of file diff --git a/core/src/com/unciv/logic/map/BFS.kt b/core/src/com/unciv/logic/map/BFS.kt index c3b2309776..f087559196 100644 --- a/core/src/com/unciv/logic/map/BFS.kt +++ b/core/src/com/unciv/logic/map/BFS.kt @@ -18,9 +18,10 @@ class BFS(val startingPoint: TileInfo, val predicate : (TileInfo) -> Boolean){ nextStep() } - fun stepUntilDestination(destination: TileInfo){ + fun stepUntilDestination(destination: TileInfo): BFS { while(!tilesReached.containsKey(destination) && tilesToCheck.isNotEmpty()) nextStep() + return this } fun nextStep(){ @@ -39,8 +40,10 @@ class BFS(val startingPoint: TileInfo, val predicate : (TileInfo) -> Boolean){ path.add(destination) var currentNode = destination while(currentNode != startingPoint){ - currentNode = tilesReached[currentNode]!! - path.add(currentNode) + tilesReached[currentNode]?.let { + currentNode = it + path.add(currentNode) + } ?: return ArrayList() // destination is not in our path } return path } diff --git a/core/src/com/unciv/logic/map/MapUnit.kt b/core/src/com/unciv/logic/map/MapUnit.kt index e491d0c6cf..08ab28767a 100644 --- a/core/src/com/unciv/logic/map/MapUnit.kt +++ b/core/src/com/unciv/logic/map/MapUnit.kt @@ -6,6 +6,8 @@ import com.unciv.Constants import com.unciv.logic.automation.UnitAutomation import com.unciv.logic.automation.WorkerAutomation import com.unciv.logic.civilization.CivilizationInfo +import com.unciv.logic.map.action.MapUnitAction +import com.unciv.logic.map.action.StringAction import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.tech.TechEra import com.unciv.models.gamebasics.tile.TerrainType @@ -16,6 +18,7 @@ import java.util.* import kotlin.collections.ArrayList class MapUnit { + @Transient lateinit var civInfo: CivilizationInfo @Transient lateinit var baseUnit: BaseUnit @Transient internal lateinit var currentTile :TileInfo @@ -32,7 +35,15 @@ class MapUnit { lateinit var name: String var currentMovement: Float = 0f var health:Int = 100 - var action: String? = null // work, automation, fortifying, I dunno what. + + var mapUnitAction : MapUnitAction? = null + + var action: String? // work, automation, fortifying, I dunno what. + // getter and setter for compatibility: make sure string-based actions still work + get() = (mapUnitAction as? StringAction)?.action ?: mapUnitAction?.let { "" } // null if no action is assigned. + set(value) { mapUnitAction = value?.let{ StringAction(this, value) } } // wrap traditional string-encoded actions into StringAction + + var attacksThisTurn = 0 var promotions = UnitPromotions() var due: Boolean = true @@ -169,7 +180,8 @@ class MapUnit { } /** - * Designates whether we can walk to the tile - without attacking + * Designates whether we can enter the tile - without attacking + * DOES NOT designate whether we can reach that tile in the current turn */ fun canMoveTo(tile: TileInfo): Boolean { if(!canPassThrough(tile)) return false @@ -275,6 +287,7 @@ class MapUnit { //region state-changing functions fun setTransients(){ promotions.unit=this + mapUnitAction?.unit = this baseUnit=GameBasics.Units[name]!! updateUniques() } @@ -292,10 +305,13 @@ class MapUnit { val enemyUnitsInWalkingDistance = getDistanceToTiles().keys .filter { it.militaryUnit!=null && civInfo.isAtWarWith(it.militaryUnit!!.civInfo)} if(enemyUnitsInWalkingDistance.isNotEmpty()) { - if (action != null && action!!.startsWith("moveTo")) action=null + if (mapUnitAction?.shouldStopOnEnemyInSight()==true) + mapUnitAction=null return // Don't you dare move. } + mapUnitAction?.doPreTurnAction() + if (action != null && action!!.startsWith("moveTo")) { val destination = action!!.replace("moveTo ", "").split(",").dropLastWhile { it.isEmpty() }.toTypedArray() val destinationVector = Vector2(Integer.parseInt(destination[0]).toFloat(), Integer.parseInt(destination[1]).toFloat()) @@ -368,22 +384,19 @@ class MapUnit { } } - /** - * @return The tile that we reached this turn - */ fun moveToTile(otherTile: TileInfo) { if(otherTile==getTile()) return // already here! val distanceToTiles = getDistanceToTiles() - class YouCantGetThereFromHereException : Exception() + class YouCantGetThereFromHereException(msg: String) : Exception(msg) if (!distanceToTiles.containsKey(otherTile)) + throw YouCantGetThereFromHereException("$this can't get from ${currentTile.position} to ${otherTile.position}.") - throw YouCantGetThereFromHereException() - - class CantEnterThisTileException : Exception() + class CantEnterThisTileException(msg: String) : Exception(msg) if(!canMoveTo(otherTile)) - throw CantEnterThisTileException() - if(otherTile.isCityCenter() && otherTile.getOwner()!=civInfo) throw Exception("This is an enemy city, you can't go here!") + throw CantEnterThisTileException("$this can't enter $otherTile") + if(otherTile.isCityCenter() && otherTile.getOwner()!=civInfo) + throw Exception("This is an enemy city, you can't go here!") currentMovement -= distanceToTiles[otherTile]!! if (currentMovement < 0.1) currentMovement = 0f // silly floats which are "almost zero" diff --git a/core/src/com/unciv/logic/map/RoadStatus.kt b/core/src/com/unciv/logic/map/RoadStatus.kt index 5d42a4719f..774eef4a6b 100644 --- a/core/src/com/unciv/logic/map/RoadStatus.kt +++ b/core/src/com/unciv/logic/map/RoadStatus.kt @@ -1,7 +1,18 @@ package com.unciv.logic.map +import com.unciv.models.gamebasics.GameBasics + +/** + * You can use RoadStatus.name to identify [Road] and [Railroad] + * in string-based identification, as done in [improvement]. + */ enum class RoadStatus { + None, Road, - Railroad + Railroad; + + /** returns null for [None] */ + fun improvement() = GameBasics.TileImprovements[this.name] + } diff --git a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt index a1cb746301..50ecd8684a 100644 --- a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt +++ b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt @@ -137,7 +137,7 @@ class UnitMovementAlgorithms(val unit:MapUnit) { */ fun headTowards(destination: TileInfo): TileInfo { val currentTile = unit.getTile() - if(currentTile==destination) return currentTile + if (currentTile == destination) return currentTile val distanceToTiles = unit.getDistanceToTiles() @@ -152,7 +152,7 @@ class UnitMovementAlgorithms(val unit:MapUnit) { return currentTile val reachableDestinationNeighbors = destinationNeighbors - .filter { distanceToTiles.containsKey(it) && unit.canMoveTo(it)} + .filter { distanceToTiles.containsKey(it) && unit.canMoveTo(it) } if (reachableDestinationNeighbors.isEmpty()) // We can't get closer... return currentTile @@ -160,8 +160,8 @@ class UnitMovementAlgorithms(val unit:MapUnit) { } } else { // If the tile is far away, we need to build a path how to get there, and then take the first step val path = getShortestPath(destination) - class UnreachableDestinationException:Exception() - if(path.isEmpty()) throw UnreachableDestinationException() + class UnreachableDestinationException : Exception() + if (path.isEmpty()) throw UnreachableDestinationException() destinationTileThisTurn = path.first() } diff --git a/core/src/com/unciv/logic/map/action/BuildLongRoadAction.kt b/core/src/com/unciv/logic/map/action/BuildLongRoadAction.kt new file mode 100644 index 0000000000..9a9cf45131 --- /dev/null +++ b/core/src/com/unciv/logic/map/action/BuildLongRoadAction.kt @@ -0,0 +1,103 @@ +package com.unciv.logic.map.action + +import com.badlogic.gdx.graphics.Color +import com.unciv.logic.map.BFS +import com.unciv.logic.map.MapUnit +import com.unciv.logic.map.RoadStatus +import com.unciv.logic.map.TileInfo + +class BuildLongRoadAction( + mapUnit: MapUnit = MapUnit(), + val target: TileInfo = TileInfo() +) : MapUnitAction(mapUnit) { + + override fun name(): String = "Build Long Road" + + override fun shouldStopOnEnemyInSight(): Boolean = true + + override fun isAvailable(): Boolean + = unit.hasUnique("Can build improvements on tiles") + && getPath(target).isNotEmpty() + && unit.civInfo.tech.getBestRoadAvailable() != RoadStatus.None + + override fun doPreTurnAction() { + + // we're working! + if (unit.currentTile.improvementInProgress != null) + return + + if (startWorkingOnRoad()) + return + + + // we reached our target? And road is finished? + if (unit.currentTile.position == target.position + && isRoadFinished(unit.currentTile)) { + unit.action = null + return + } + + // move one step forward - and start building + if (stepForward(target)) { + startWorkingOnRoad() + } else if (unit.currentMovement > 1f) { + unit.civInfo.addNotification("[${unit.name}] canceled building road: can't move forward.", unit.currentTile.position, Color.GRAY) + unit.action = null + return + } + + } + + // because the unit is building a road, we need to use a shortest path that is + // independent of movement costs, but should respect impassable terrain like water and enemy territory + private fun stepForward(destination: TileInfo): Boolean { + var success = false + val tilesUnitCanCurrentlyReach = unit.getDistanceToTiles().keys + for (step in getPath(destination).drop(1)) { + if(step !in tilesUnitCanCurrentlyReach) return false // we're out of tiles in reachable distance, no need to check any further + + if (unit.currentMovement > 0f) { + if(unit.canMoveTo(step)) { + unit.moveToTile(step) + success = true + // if there is a road already, take multiple steps, otherwise this is where we're going to build a road + if (!isRoadFinished(step)) return true + } + else if(!isRoadFinished(step)){ + unit.civInfo.addNotification("[${unit.name}] skipped building road. It can't move here.", step.position, Color.GRAY) + } + // worker moves on even if the current step is blocked + } else break + } + return success + } + + private fun isRoadFinished(tile: TileInfo): Boolean { + return tile.roadStatus >= unit.civInfo.tech.getBestRoadAvailable() + } + + private fun getPath(destination: TileInfo): List { + // BFS is not very efficient + return BFS(unit.currentTile) { isRoadableTile(it) } + .stepUntilDestination(destination) + .getPathTo(destination).reversed() + } + + private fun isRoadableTile(it: TileInfo) = it.isLand && unit.canPassThrough(it) + + private fun startWorkingOnRoad(): Boolean { + val tile = unit.currentTile + if (unit.currentMovement > 0 && isRoadableTile(tile)) { + val roadToBuild = unit.civInfo.tech.getBestRoadAvailable() + roadToBuild.improvement()?.let { improvement -> + if (tile.roadStatus < roadToBuild && tile.improvementInProgress != improvement.name) { + tile.startWorkingOnImprovement(improvement, unit.civInfo) + return true + } + } + } + return false + } + + +} \ No newline at end of file diff --git a/core/src/com/unciv/logic/map/action/MapUnitAction.kt b/core/src/com/unciv/logic/map/action/MapUnitAction.kt new file mode 100644 index 0000000000..fe2d08c2ef --- /dev/null +++ b/core/src/com/unciv/logic/map/action/MapUnitAction.kt @@ -0,0 +1,15 @@ +package com.unciv.logic.map.action + +import com.unciv.logic.map.MapUnit + +open class MapUnitAction( + @Transient var unit: MapUnit = MapUnit() +) { + open fun name(): String = "" + /** return true if this action is possible in the given conditions */ + open fun isAvailable(): Boolean = true + open fun doPreTurnAction() {} + open fun shouldStopOnEnemyInSight(): Boolean = false +} + + diff --git a/core/src/com/unciv/logic/map/action/StringAction.kt b/core/src/com/unciv/logic/map/action/StringAction.kt new file mode 100644 index 0000000000..08b767f323 --- /dev/null +++ b/core/src/com/unciv/logic/map/action/StringAction.kt @@ -0,0 +1,27 @@ +package com.unciv.logic.map.action + +import com.unciv.logic.map.MapUnit + +/** + * this class represents all actions that are identified by string only. + * this is the traditional way of handling actions in UnCiv: by coding relevant information + * into a string. This class is here to maintain compatibility to that method, preventing from a huge + * refactoring going on here. + */ +class StringAction( + unit: MapUnit = MapUnit(), + val action: String = "" // traditional string-encoded action like "moveTo x,y" +) : MapUnitAction(unit) { + + override fun shouldStopOnEnemyInSight(): Boolean = action.startsWith("moveTo") + + override fun name(): String { + return when { + // translate string-encoded actions to user-readable names + action.startsWith("moveTo") -> "Moving" + else -> action + } + } + + +} \ No newline at end of file diff --git a/core/src/com/unciv/ui/EmpireOverviewScreen.kt b/core/src/com/unciv/ui/EmpireOverviewScreen.kt index cb6e4eef90..69eb6751d1 100644 --- a/core/src/com/unciv/ui/EmpireOverviewScreen.kt +++ b/core/src/com/unciv/ui/EmpireOverviewScreen.kt @@ -103,7 +103,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){ generalTable.add(createOffersTable(otherCiv, trade.theirOffers, trade.ourOffers.size)) return generalTable } - + private fun createOffersTable(civ: CivilizationInfo, offersList: TradeOffersList, numberOfOtherSidesOffers: Int): Table { val table = Table() table.defaults().pad(10f) @@ -259,6 +259,7 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){ fun getUnitTable(): Table { val table=Table(skin).apply { defaults().pad(5f) } table.add("Name".tr()) + table.add("Action".tr()) table.add("Strength".tr()) table.add("Ranged strength".tr()) table.add("Movement".tr()) @@ -274,6 +275,8 @@ class EmpireOverviewScreen : CameraStageBaseScreen(){ UnCivGame.Current.worldScreen.tileMapHolder.setCenterPosition(unit.currentTile.position) } table.add(button).left() + val mapUnitAction = unit.mapUnitAction + if (mapUnitAction != null) table.add(mapUnitAction.name().tr()) else table.add() if(baseUnit.strength>0) table.add(baseUnit.strength.toString()) else table.add() if(baseUnit.rangedStrength>0) table.add(baseUnit.rangedStrength.toString()) else table.add() table.add(DecimalFormat("0.#").format(unit.currentMovement)+"/"+unit.getMaxMovement()) diff --git a/core/src/com/unciv/ui/pickerscreens/GreatPersonPickerScreen.kt b/core/src/com/unciv/ui/pickerscreens/GreatPersonPickerScreen.kt index f243914d10..783846d88e 100644 --- a/core/src/com/unciv/ui/pickerscreens/GreatPersonPickerScreen.kt +++ b/core/src/com/unciv/ui/pickerscreens/GreatPersonPickerScreen.kt @@ -30,7 +30,7 @@ class GreatPersonPickerScreen : PickerScreen() { pick("Get " +unit.name) descriptionLabel.setText(unit.uniques.joinToString()) } - topTable.add(button).pad(10f) + topTable.add(button).pad(10f).row() } rightSideButton.onClick("choir") { diff --git a/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt b/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt index 81eafc251a..b9a07fb587 100644 --- a/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt +++ b/core/src/com/unciv/ui/worldscreen/TileMapHolder.kt @@ -20,6 +20,7 @@ import com.unciv.logic.map.TileMap import com.unciv.models.gamebasics.unit.UnitType import com.unciv.ui.tilegroups.WorldTileGroup import com.unciv.ui.utils.* +import com.unciv.ui.worldscreen.unit.UnitContextMenu import kotlin.concurrent.thread class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: TileMap) : ScrollPane(null) { @@ -41,7 +42,15 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: val allTiles = TileGroupMap(daTileGroups,worldScreen.stage.width) for(tileGroup in tileGroups.values){ - tileGroup.onClick{ onTileClicked(tileGroup.tileInfo)} + tileGroup.addListener (object: ActorGestureListener() { + override fun tap(event: InputEvent?, x: Float, y: Float, count: Int, button: Int) { + onTileClicked(tileGroup.tileInfo) + } + override fun longPress(actor: Actor?, x: Float, y: Float): Boolean { + return onTileLongClicked(tileGroup.tileInfo) + } + + }) } actor = allTiles @@ -77,7 +86,7 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: private fun onTileClicked(tileInfo: TileInfo) { worldScreen.displayTutorials("TileClicked") - if (unitActionOverlay != null) unitActionOverlay!!.remove() + unitActionOverlay?.remove() selectedTile = tileInfo val selectedUnit = worldScreen.bottomBar.unitTable.selectedUnit @@ -121,7 +130,7 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: } else { // add "move to" button val moveHereButtonDto = MoveHereButtonDto(selectedUnit, tileInfo, turnsToGetThere) - addMoveHereButtonToTile(moveHereButtonDto, tileGroups[moveHereButtonDto.tileInfo]!!) + addMoveHereButtonToTile(moveHereButtonDto) } worldScreen.shouldUpdate = true } @@ -130,7 +139,7 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: } - private fun addMoveHereButtonToTile(dto: MoveHereButtonDto, tileGroup: WorldTileGroup) { + private fun addMoveHereButtonToTile(dto: MoveHereButtonDto) { val size = 60f val moveHereButton = Group().apply { width = size;height = size; } moveHereButton.addActor(ImageGetter.getCircle().apply { width = size; height = size }) @@ -147,48 +156,45 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: moveHereButton.addActor(unitIcon) if (dto.unit.currentMovement > 0) - moveHereButton.onClick(""){onMoveButtonClick(dto)} - - else moveHereButton.color.a = 0.5f - addOverlayOnTileGroup(tileGroup, moveHereButton) - moveHereButton.y += tileGroup.height - unitActionOverlay = moveHereButton - } - - private fun onMoveButtonClick(dto: MoveHereButtonDto) { - // this can take a long time, because of the unit-to-tile calculation needed, so we put it in a different thread - thread { - if (dto.unit.movementAlgs().canReach(dto.tileInfo)) { - try { - // Because this is darned concurrent (as it MUST be to avoid ANRs), - // there are edge cases where the canReach is true, - // but until it reaches the headTowards the board has changed and so the headTowards fails. - // I can't think of any way to avoid this, - // but it's so rare and edge-case-y that ignoring its failure is actually acceptable, hence the empty catch - dto.unit.movementAlgs().headTowards(dto.tileInfo) - Sounds.play("whoosh") - if (dto.unit.currentTile != dto.tileInfo) - dto.unit.action = "moveTo " + dto.tileInfo.position.x.toInt() + "," + dto.tileInfo.position.y.toInt() - if(dto.unit.currentMovement>0){ - worldScreen.bottomBar.unitTable.selectedUnit=dto.unit - } - } catch (e: Exception) { - } + moveHereButton.onClick(""){ + UnitContextMenu(this, dto.unit, dto.tileInfo).onMoveButtonClick() } - // we don't update it directly because we're on a different thread; instead, we tell it to update itself - worldScreen.shouldUpdate = true - - removeUnitActionOverlay=true - } + else moveHereButton.color.a = 0.5f + addOverlayOnTileGroup(dto.tileInfo, moveHereButton) } - private fun addOverlayOnTileGroup(group:WorldTileGroup, actor: Actor) { + + + fun onTileLongClicked(tileInfo: TileInfo): Boolean { + + unitActionOverlay?.remove() + selectedTile = tileInfo + val selectedUnit = worldScreen.bottomBar.unitTable.selectedUnit + worldScreen.bottomBar.unitTable.tileSelected(tileInfo) + worldScreen.shouldUpdate = true + + if (selectedUnit != null) { + addOverlayOnTileGroup(tileInfo, UnitContextMenu(this, selectedUnit, tileInfo)) + return true + } + + return false + } + + private fun addOverlayOnTileGroup(tileInfo: TileInfo, actor: Actor) { + + val group = tileGroups[tileInfo]!! + actor.center(group) actor.x+=group.x actor.y+=group.y group.parent.addActor(actor) actor.toFront() + + actor.y += actor.height + unitActionOverlay = actor + } internal fun updateTiles(civInfo: CivilizationInfo) { @@ -216,20 +222,23 @@ class TileMapHolder(internal val worldScreen: WorldScreen, internal val tileMap: tileGroup.showCircle(Color.RED) // Display ALL viewable enemies with a red circle so that users don't need to go "hunting" for enemy units } - if (worldScreen.bottomBar.unitTable.selectedCity!=null){ - val city = worldScreen.bottomBar.unitTable.selectedCity!! - updateTilegroupsForSelectedCity(city, playerViewableTilePositions) - } else if(worldScreen.bottomBar.unitTable.selectedUnit!=null){ - val unit = worldScreen.bottomBar.unitTable.selectedUnit!! - updateTilegroupsForSelectedUnit(unit, playerViewableTilePositions) - } - else if(unitActionOverlay!=null){ - unitActionOverlay!!.remove() - unitActionOverlay=null + val unitTable = worldScreen.bottomBar.unitTable + when { + unitTable.selectedCity!=null -> { + val city = unitTable.selectedCity!! + updateTilegroupsForSelectedCity(city, playerViewableTilePositions) + } + unitTable.selectedUnit!=null -> { + val unit = unitTable.selectedUnit!! + updateTilegroupsForSelectedUnit(unit, playerViewableTilePositions) + } + unitActionOverlay!=null -> { + unitActionOverlay!!.remove() + unitActionOverlay=null + } } - if(selectedTile!=null) - tileGroups[selectedTile!!]!!.showCircle(Color.WHITE) + tileGroups[selectedTile]?.showCircle(Color.WHITE) } private fun updateTilegroupsForSelectedUnit(unit: MapUnit, playerViewableTilePositions: HashSet) { diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt index 5e69d56717..6da39d4a20 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt @@ -246,8 +246,6 @@ class WorldScreen : CameraStageBaseScreen() { return@onClick } - bottomBar.unitTable.currentlyExecutingAction = null - Gdx.input.inputProcessor = null // remove input processing - nothing will be clicked! nextTurnButton.disable() nextTurnButton.setText("Working...".tr()) diff --git a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt index 4ab1721f8c..80aad0f255 100644 --- a/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt +++ b/core/src/com/unciv/ui/worldscreen/unit/UnitActions.kt @@ -34,7 +34,6 @@ class UnitActions { if(unit.action!=null && unit.action!!.startsWith("moveTo")) { actionList += UnitAction("Stop movement", true) { - unitTable.currentlyExecutingAction = null unit.action = null } } @@ -146,7 +145,6 @@ class UnitActions { unit.civInfo.addCity(tile.position) tile.improvement = null - unitTable.currentlyExecutingAction = null // In case the settler was in the middle of doing something and we then founded a city with it unit.destroy() }.sound("chimes") } diff --git a/core/src/com/unciv/ui/worldscreen/unit/UnitContextMenu.kt b/core/src/com/unciv/ui/worldscreen/unit/UnitContextMenu.kt new file mode 100644 index 0000000000..973145cf5b --- /dev/null +++ b/core/src/com/unciv/ui/worldscreen/unit/UnitContextMenu.kt @@ -0,0 +1,85 @@ +package com.unciv.ui.worldscreen.unit + +import com.badlogic.gdx.scenes.scene2d.Actor +import com.badlogic.gdx.scenes.scene2d.ui.Button +import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup +import com.unciv.logic.map.MapUnit +import com.unciv.logic.map.TileInfo +import com.unciv.ui.utils.CameraStageBaseScreen +import com.unciv.ui.utils.ImageGetter +import com.unciv.ui.utils.Sounds +import com.unciv.ui.utils.onClick +import com.unciv.ui.worldscreen.TileMapHolder +import com.unciv.logic.map.action.BuildLongRoadAction +import com.unciv.logic.map.action.MapUnitAction +import kotlin.concurrent.thread + +class UnitContextMenu(val tileMapHolder: TileMapHolder, val selectedUnit: MapUnit, val targetTile: TileInfo) : VerticalGroup() { + + init { + + space(10f) + + addButton(ImageGetter.getStatIcon("Movement"), "Move unit") { + onMoveButtonClick() + } + + addButton( + ImageGetter.getImprovementIcon("Road"), + "Construct road", + BuildLongRoadAction(selectedUnit, targetTile) + ) + + pack() + + } + + fun addButton(icon: Actor, label: String, action: MapUnitAction) { + if (action.isAvailable()) { + addButton(icon, label) { + selectedUnit.mapUnitAction = action + selectedUnit.mapUnitAction?.doPreTurnAction() + tileMapHolder.removeUnitActionOverlay = true + tileMapHolder.worldScreen.shouldUpdate = true + } + } + } + + fun addButton(icon: Actor, label: String, action: () -> Unit) { + val skin = CameraStageBaseScreen.skin + val button = Button(skin) + button.add(icon).size(20f).padRight(10f) + button.add(label) + addActor(button) + button.onClick { action() } + } + + fun onMoveButtonClick() { + // this can take a long time, because of the unit-to-tile calculation needed, so we put it in a different thread + thread { + if (selectedUnit.movementAlgs().canReach(targetTile)) { + try { + // Because this is darned concurrent (as it MUST be to avoid ANRs), + // there are edge cases where the canReach is true, + // but until it reaches the headTowards the board has changed and so the headTowards fails. + // I can't think of any way to avoid this, + // but it's so rare and edge-case-y that ignoring its failure is actually acceptable, hence the empty catch + selectedUnit.movementAlgs().headTowards(targetTile) + Sounds.play("whoosh") + if (selectedUnit.currentTile != targetTile) + selectedUnit.action = "moveTo " + targetTile.position.x.toInt() + "," + targetTile.position.y.toInt() + if(selectedUnit.currentMovement>0){ + tileMapHolder.worldScreen.bottomBar.unitTable.selectedUnit=selectedUnit + } + } catch (e: Exception) { + } + } + + // we don't update it directly because we're on a different thread; instead, we tell it to update itself + tileMapHolder.worldScreen.shouldUpdate = true + + tileMapHolder.removeUnitActionOverlay=true + } + } + +} \ No newline at end of file diff --git a/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt b/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt index 4d7a689cff..dbeac8e6d0 100644 --- a/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt +++ b/core/src/com/unciv/ui/worldscreen/unit/UnitTable.kt @@ -22,8 +22,6 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){ private val unitDescriptionTable = Table(CameraStageBaseScreen.skin) var selectedUnit : MapUnit? = null var selectedCity : CityInfo? = null - var currentlyExecutingAction : String? = null - var lastSelectedCityButton : Boolean = false val deselectUnitButton = Table() val helpUnitButton = Table() @@ -88,12 +86,10 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){ if (selectedUnit!!.civInfo != worldScreen.currentPlayerCiv) { // The unit that was selected, was captured. It exists but is no longer ours. selectedUnit = null selectedCity = null - currentlyExecutingAction = null selectedUnitHasChanged = true } else if (selectedUnit!! !in selectedUnit!!.getTile().getUnits()) { // The unit that was there no longer exists} selectedUnit = null selectedCity = null - currentlyExecutingAction = null selectedUnitHasChanged = true } } @@ -190,20 +186,7 @@ class UnitTable(val worldScreen: WorldScreen) : Table(){ fun tileSelected(selectedTile: TileInfo) { val previouslySelectedUnit = selectedUnit - if(currentlyExecutingAction=="moveTo"){ - if(selectedUnit!!.movementAlgs() - .getShortestPath(selectedTile).isEmpty()) - return // can't reach there with the selected unit, watcha want me to do? - - val reachedTile = selectedUnit!!.movementAlgs().headTowards(selectedTile) - - selectedUnit!!.action=null // Disable any prior action (automation, fortification...) - if(reachedTile!=selectedTile) // Didn't get all the way there - selectedUnit!!.action = "moveTo " + selectedTile.position.x.toInt() + "," + selectedTile.position.y.toInt() - currentlyExecutingAction = null - } - - else if(selectedTile.militaryUnit!=null && selectedTile.militaryUnit!!.civInfo == worldScreen.currentPlayerCiv + if(selectedTile.militaryUnit!=null && selectedTile.militaryUnit!!.civInfo == worldScreen.currentPlayerCiv && selectedUnit!=selectedTile.militaryUnit && (selectedTile.civilianUnit==null || selectedUnit!=selectedTile.civilianUnit)){ selectedUnit = selectedTile.militaryUnit diff --git a/desktop/src/com/unciv/app/desktop/DesktopLauncher.java b/desktop/src/com/unciv/app/desktop/DesktopLauncher.java index 402744a21d..0a7af1d2d6 100644 --- a/desktop/src/com/unciv/app/desktop/DesktopLauncher.java +++ b/desktop/src/com/unciv/app/desktop/DesktopLauncher.java @@ -17,7 +17,7 @@ class DesktopLauncher { // This is so they don't look all pixelated settings.filterMag = Texture.TextureFilter.MipMapLinearLinear; settings.filterMin = Texture.TextureFilter.MipMapLinearLinear; - TexturePacker.process(settings, "../images", ".", "game"); + TexturePacker.process(settings, "../Images", ".", "game"); LwjglApplicationConfiguration config = new LwjglApplicationConfiguration(); new LwjglApplication(new UnCivGame("Desktop"), config);